Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:
 "This series contain:
   - new i2c video drivers: ml86v7667 (video decoder),
                            ths8200 (video encoder)
   - a new video driver for EasyCap cards based on Fushicai USBTV007
   - Improved support for OF and embedded systems, with V4L2 async
     initialization and a better support for clocks
   - API cleanups on the ioctls used by the v4l2 debug tool
   - Lots of cleanups
   - As usual, several driver improvements and new cards additions
   - Revert two changesets that change the minimal symbol rate for
     stv0399, as request by Manu
   - Update MAINTAINERS and other files to point to my new e-mail"

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (378 commits)
  MAINTAINERS & ABI: Update to point to my new email
  [media] stb0899: restore minimal rate to 5Mbauds
  [media] exynos4-is: Correct colorspace handling at FIMC-LITE
  [media] exynos4-is: Set valid initial format on FIMC.n subdevs
  [media] exynos4-is: Set valid initial format on FIMC-IS-ISP subdev pads
  [media] exynos4-is: Fix format propagation on FIMC-IS-ISP subdev
  [media] exynos4-is: Set valid initial format at FIMC-LITE
  [media] exynos4-is: Fix format propagation on FIMC-LITE.n subdevs
  [media] MAINTAINERS: Update S5P/Exynos FIMC driver entry
  [media] Documentation: Update driver's directory in video4linux/fimc.txt
  [media] exynos4-is: Change fimc-is firmware file names
  [media] exynos4-is: Add support for Exynos5250 MIPI-CSIS
  [media] exynos4-is: Add Exynos5250 SoC support to fimc-lite driver
  [media] exynos4-is: Drop drvdata handling in fimc-lite for non-dt platforms
  [media] media: i2c: tvp514x: remove manual setting of subdev name
  [media] media: i2c: tvp7002: remove manual setting of subdev name
  [media] mem2mem: set missing v4l2_dev pointer
  [media] wl128x: add missing struct v4l2_device
  [media] tvp514x: Fix init seqeunce
  [media] saa7134: Fix sparse warnings by adding __user annotation
  ...
diff --git a/Documentation/ABI/testing/sysfs-devices-edac b/Documentation/ABI/testing/sysfs-devices-edac
index 30ee78a..6568e00 100644
--- a/Documentation/ABI/testing/sysfs-devices-edac
+++ b/Documentation/ABI/testing/sysfs-devices-edac
@@ -77,7 +77,7 @@
 
 What:		/sys/devices/system/edac/mc/mc*/max_location
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file displays the information about the last
 		available memory slot in this memory controller. It is used by
@@ -85,7 +85,7 @@
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/size
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file will display the size of dimm or rank.
 		For dimm*/size, this is the size, in MB of the DIMM memory
@@ -96,14 +96,14 @@
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_dev_type
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file will display what type of DRAM device is
 		being utilized on this DIMM (x1, x2, x4, x8, ...).
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_edac_mode
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file will display what type of Error detection
 		and correction is being utilized. For example: S4ECD4ED would
@@ -111,7 +111,7 @@
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_label
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This control file allows this DIMM to have a label assigned
 		to it. With this label in the module, when errors occur
@@ -126,14 +126,14 @@
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_location
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file will display the location (csrow/channel,
 		branch/channel/slot or channel/slot) of the dimm or rank.
 
 What:		/sys/devices/system/edac/mc/mc*/(dimm|rank)*/dimm_mem_type
 Date:		April 2012
-Contact:	Mauro Carvalho Chehab <mchehab@redhat.com>
+Contact:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 		linux-edac@vger.kernel.org
 Description:	This attribute file will display what type of memory is
 		currently on this csrow. Normally, either buffered or
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index f43542a..0c7195e 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2254,7 +2254,7 @@
       <orderedlist>
 	<listitem>
 	  <para>The <constant>VIDIOC_G_CHIP_IDENT</constant> ioctl was renamed
-to <constant>VIDIOC_G_CHIP_IDENT_OLD</constant> and &VIDIOC-DBG-G-CHIP-IDENT;
+to <constant>VIDIOC_G_CHIP_IDENT_OLD</constant> and <constant>VIDIOC_DBG_G_CHIP_IDENT</constant>
 was introduced in its place. The old struct <structname>v4l2_chip_ident</structname>
 was renamed to <structname id="v4l2-chip-ident-old">v4l2_chip_ident_old</structname>.</para>
 	</listitem>
@@ -2513,6 +2513,16 @@
       </orderedlist>
     </section>
 
+    <section>
+      <title>V4L2 in Linux 3.11</title>
+      <orderedlist>
+        <listitem>
+	  <para>Remove obsolete <constant>VIDIOC_DBG_G_CHIP_IDENT</constant> ioctl.
+	  </para>
+        </listitem>
+      </orderedlist>
+    </section>
+
     <section id="other">
       <title>Relation of V4L2 to other Linux multimedia APIs</title>
 
@@ -2596,7 +2606,7 @@
 ioctls.</para>
         </listitem>
         <listitem>
-	  <para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
+	  <para>&VIDIOC-DBG-G-CHIP-INFO; ioctl.</para>
         </listitem>
         <listitem>
 	  <para>&VIDIOC-ENUM-DV-TIMINGS;, &VIDIOC-QUERY-DV-TIMINGS; and
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index bfe823d..8469fe1 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -141,6 +141,14 @@
 applications. -->
 
       <revision>
+	<revnumber>3.11</revnumber>
+	<date>2013-05-26</date>
+	<authorinitials>hv</authorinitials>
+	<revremark>Remove obsolete VIDIOC_DBG_G_CHIP_IDENT ioctl.
+	</revremark>
+      </revision>
+
+      <revision>
 	<revnumber>3.10</revnumber>
 	<date>2013-03-25</date>
 	<authorinitials>hv</authorinitials>
@@ -493,7 +501,7 @@
 </partinfo>
 
 <title>Video for Linux Two API Specification</title>
- <subtitle>Revision 3.10</subtitle>
+ <subtitle>Revision 3.11</subtitle>
 
   <chapter id="common">
     &sub-common;
@@ -547,7 +555,6 @@
     <!-- All ioctls go here. -->
     &sub-create-bufs;
     &sub-cropcap;
-    &sub-dbg-g-chip-ident;
     &sub-dbg-g-chip-info;
     &sub-dbg-g-register;
     &sub-decoder-cmd;
diff --git a/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-ident.xml b/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-ident.xml
deleted file mode 100644
index 921e185..0000000
--- a/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-ident.xml
+++ /dev/null
@@ -1,271 +0,0 @@
-<refentry id="vidioc-dbg-g-chip-ident">
-  <refmeta>
-    <refentrytitle>ioctl VIDIOC_DBG_G_CHIP_IDENT</refentrytitle>
-    &manvol;
-  </refmeta>
-
-  <refnamediv>
-    <refname>VIDIOC_DBG_G_CHIP_IDENT</refname>
-    <refpurpose>Identify the chips on a TV card</refpurpose>
-  </refnamediv>
-
-  <refsynopsisdiv>
-    <funcsynopsis>
-      <funcprototype>
-	<funcdef>int <function>ioctl</function></funcdef>
-	<paramdef>int <parameter>fd</parameter></paramdef>
-	<paramdef>int <parameter>request</parameter></paramdef>
-	<paramdef>struct v4l2_dbg_chip_ident
-*<parameter>argp</parameter></paramdef>
-      </funcprototype>
-    </funcsynopsis>
-  </refsynopsisdiv>
-
-  <refsect1>
-    <title>Arguments</title>
-
-    <variablelist>
-      <varlistentry>
-	<term><parameter>fd</parameter></term>
-	<listitem>
-	  <para>&fd;</para>
-	</listitem>
-      </varlistentry>
-      <varlistentry>
-	<term><parameter>request</parameter></term>
-	<listitem>
-	  <para>VIDIOC_DBG_G_CHIP_IDENT</para>
-	</listitem>
-      </varlistentry>
-      <varlistentry>
-	<term><parameter>argp</parameter></term>
-	<listitem>
-	  <para></para>
-	</listitem>
-      </varlistentry>
-    </variablelist>
-  </refsect1>
-
-  <refsect1>
-    <title>Description</title>
-
-    <note>
-      <title>Experimental</title>
-
-      <para>This is an <link
-linkend="experimental">experimental</link> interface and may change in
-the future.</para>
-    </note>
-
-    <para>For driver debugging purposes this ioctl allows test
-applications to query the driver about the chips present on the TV
-card. Regular applications must not use it. When you found a chip
-specific bug, please contact the linux-media mailing list (&v4l-ml;)
-so it can be fixed.</para>
-
-    <para>To query the driver applications must initialize the
-<structfield>match.type</structfield> and
-<structfield>match.addr</structfield> or <structfield>match.name</structfield>
-fields of a &v4l2-dbg-chip-ident;
-and call <constant>VIDIOC_DBG_G_CHIP_IDENT</constant> with a pointer to
-this structure. On success the driver stores information about the
-selected chip in the <structfield>ident</structfield> and
-<structfield>revision</structfield> fields. On failure the structure
-remains unchanged.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_HOST</constant>,
-<structfield>match.addr</structfield> selects the nth non-&i2c; chip
-on the TV card. You can enumerate all chips by starting at zero and
-incrementing <structfield>match.addr</structfield> by one until
-<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.
-The number zero always selects the host chip, &eg; the chip connected
-to the PCI or USB bus.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
-<structfield>match.name</structfield> contains the I2C driver name.
-For instance
-<constant>"saa7127"</constant> will match any chip
-supported by the saa7127 driver, regardless of its &i2c; bus address.
-When multiple chips supported by the same driver are present, the
-ioctl will return <constant>V4L2_IDENT_AMBIGUOUS</constant> in the
-<structfield>ident</structfield> field.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
-<structfield>match.addr</structfield> selects a chip by its 7 bit
-&i2c; bus address.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_AC97</constant>,
-<structfield>match.addr</structfield> selects the nth AC97 chip
-on the TV card. You can enumerate all chips by starting at zero and
-incrementing <structfield>match.addr</structfield> by one until
-<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.</para>
-
-    <para>On success, the <structfield>ident</structfield> field will
-contain a chip ID from the Linux
-<filename>media/v4l2-chip-ident.h</filename> header file, and the
-<structfield>revision</structfield> field will contain a driver
-specific value, or zero if no particular revision is associated with
-this chip.</para>
-
-    <para>When the driver could not identify the selected chip,
-<structfield>ident</structfield> will contain
-<constant>V4L2_IDENT_UNKNOWN</constant>. When no chip matched
-the ioctl will succeed but the
-<structfield>ident</structfield> field will contain
-<constant>V4L2_IDENT_NONE</constant>. If multiple chips matched,
-<structfield>ident</structfield> will contain
-<constant>V4L2_IDENT_AMBIGUOUS</constant>. In all these cases the
-<structfield>revision</structfield> field remains unchanged.</para>
-
-    <para>This ioctl is optional, not all drivers may support it. It
-was introduced in Linux 2.6.21, but the API was changed to the
-one described here in 2.6.29.</para>
-
-    <para>We recommended the <application>v4l2-dbg</application>
-utility over calling this ioctl directly. It is available from the
-LinuxTV v4l-dvb repository; see <ulink
-url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
-access instructions.</para>
-
-    <!-- Note for convenience vidioc-dbg-g-register.sgml
-	 contains a duplicate of this table. -->
-    <table pgwide="1" frame="none" id="ident-v4l2-dbg-match">
-      <title>struct <structname>v4l2_dbg_match</structname></title>
-      <tgroup cols="4">
-	&cs-ustr;
-	<tbody valign="top">
-	  <row>
-	    <entry>__u32</entry>
-	    <entry><structfield>type</structfield></entry>
-	    <entry>See <xref linkend="ident-chip-match-types" /> for a list of
-possible types.</entry>
-	  </row>
-	  <row>
-	    <entry>union</entry>
-	    <entry>(anonymous)</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry>__u32</entry>
-	    <entry><structfield>addr</structfield></entry>
-	    <entry>Match a chip by this number, interpreted according
-to the <structfield>type</structfield> field.</entry>
-	  </row>
-	  <row>
-	    <entry></entry>
-	    <entry>char</entry>
-	    <entry><structfield>name[32]</structfield></entry>
-	    <entry>Match a chip by this name, interpreted according
-to the <structfield>type</structfield> field.</entry>
-	  </row>
-	</tbody>
-      </tgroup>
-    </table>
-
-    <table pgwide="1" frame="none" id="v4l2-dbg-chip-ident">
-      <title>struct <structname>v4l2_dbg_chip_ident</structname></title>
-      <tgroup cols="3">
-	&cs-str;
-	<tbody valign="top">
-	  <row>
-	    <entry>struct v4l2_dbg_match</entry>
-	    <entry><structfield>match</structfield></entry>
-	    <entry>How to match the chip, see <xref linkend="ident-v4l2-dbg-match" />.</entry>
-	  </row>
-	  <row>
-	    <entry>__u32</entry>
-	    <entry><structfield>ident</structfield></entry>
-	    <entry>A chip identifier as defined in the Linux
-<filename>media/v4l2-chip-ident.h</filename> header file, or one of
-the values from <xref linkend="chip-ids" />.</entry>
-	  </row>
-	  <row>
-	    <entry>__u32</entry>
-	    <entry><structfield>revision</structfield></entry>
-	    <entry>A chip revision, chip and driver specific.</entry>
-	  </row>
-	</tbody>
-      </tgroup>
-    </table>
-
-    <!-- Note for convenience vidioc-dbg-g-register.sgml
-	 contains a duplicate of this table. -->
-    <table pgwide="1" frame="none" id="ident-chip-match-types">
-      <title>Chip Match Types</title>
-      <tgroup cols="3">
-	&cs-def;
-	<tbody valign="top">
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_BRIDGE</constant></entry>
-	    <entry>0</entry>
-	    <entry>Match the nth chip on the card, zero for the
-	    bridge chip. Does not match sub-devices.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
-	    <entry>1</entry>
-	    <entry>Match an &i2c; chip by its driver name.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
-	    <entry>2</entry>
-	    <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
-	    <entry>3</entry>
-	    <entry>Match the nth anciliary AC97 chip.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
-	    <entry>4</entry>
-	    <entry>Match the nth sub-device. Can't be used with this ioctl.</entry>
-	  </row>
-	</tbody>
-      </tgroup>
-    </table>
-
-    <!-- This is an anonymous enum in media/v4l2-chip-ident.h. -->
-    <table pgwide="1" frame="none" id="chip-ids">
-      <title>Chip Identifiers</title>
-      <tgroup cols="3">
-	&cs-def;
-	<tbody valign="top">
-	  <row>
-	    <entry><constant>V4L2_IDENT_NONE</constant></entry>
-	    <entry>0</entry>
-	    <entry>No chip matched.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_IDENT_AMBIGUOUS</constant></entry>
-	    <entry>1</entry>
-	    <entry>Multiple chips matched.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_IDENT_UNKNOWN</constant></entry>
-	    <entry>2</entry>
-	    <entry>A chip is present at this address, but the driver
-could not identify it.</entry>
-	  </row>
-	</tbody>
-      </tgroup>
-    </table>
-  </refsect1>
-
-  <refsect1>
-    &return-value;
-
-    <variablelist>
-      <varlistentry>
-	<term><errorcode>EINVAL</errorcode></term>
-	<listitem>
-	  <para>The <structfield>match_type</structfield> is invalid.</para>
-	</listitem>
-      </varlistentry>
-     </variablelist>
-  </refsect1>
-</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml b/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml
index e1cece6..4c4603c 100644
--- a/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-dbg-g-chip-info.xml
@@ -73,8 +73,7 @@
 and call <constant>VIDIOC_DBG_G_CHIP_INFO</constant> with a pointer to
 this structure. On success the driver stores information about the
 selected chip in the <structfield>name</structfield> and
-<structfield>flags</structfield> fields. On failure the structure
-remains unchanged.</para>
+<structfield>flags</structfield> fields.</para>
 
     <para>When <structfield>match.type</structfield> is
 <constant>V4L2_CHIP_MATCH_BRIDGE</constant>,
@@ -132,7 +131,7 @@
 	    <entry>char</entry>
 	    <entry><structfield>name[32]</structfield></entry>
 	    <entry>Match a chip by this name, interpreted according
-to the <structfield>type</structfield> field.</entry>
+to the <structfield>type</structfield> field. Currently unused.</entry>
 	  </row>
 	</tbody>
       </tgroup>
@@ -183,21 +182,6 @@
 	    bridge chip. Does not match sub-devices.</entry>
 	  </row>
 	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
-	    <entry>1</entry>
-	    <entry>Match an &i2c; chip by its driver name. Can't be used with this ioctl.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
-	    <entry>2</entry>
-	    <entry>Match a chip by its 7 bit &i2c; bus address. Can't be used with this ioctl.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
-	    <entry>3</entry>
-	    <entry>Match the nth anciliary AC97 chip. Can't be used with this ioctl.</entry>
-	  </row>
-	  <row>
 	    <entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
 	    <entry>4</entry>
 	    <entry>Match the nth sub-device.</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml b/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml
index d13bac9..3d038e7 100644
--- a/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-dbg-g-register.xml
@@ -76,7 +76,7 @@
 to enable these ioctls.</para>
 
     <para>To write a register applications must initialize all fields
-of a &v4l2-dbg-register; and call
+of a &v4l2-dbg-register; except for <structfield>size</structfield> and call
 <constant>VIDIOC_DBG_S_REGISTER</constant> with a pointer to this
 structure. The <structfield>match.type</structfield> and
 <structfield>match.addr</structfield> or <structfield>match.name</structfield>
@@ -91,8 +91,8 @@
 <structfield>reg</structfield> fields, and call
 <constant>VIDIOC_DBG_G_REGISTER</constant> with a pointer to this
 structure. On success the driver stores the register value in the
-<structfield>val</structfield> field. On failure the structure remains
-unchanged.</para>
+<structfield>val</structfield> field and the size (in bytes) of the
+value in <structfield>size</structfield>.</para>
 
     <para>When <structfield>match.type</structfield> is
 <constant>V4L2_CHIP_MATCH_BRIDGE</constant>,
@@ -102,39 +102,9 @@
 present with the &VIDIOC-DBG-G-CHIP-INFO; ioctl.</para>
 
     <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
-<structfield>match.name</structfield> contains the I2C driver name.
-For instance
-<constant>"saa7127"</constant> will match any chip
-supported by the saa7127 driver, regardless of its &i2c; bus address.
-When multiple chips supported by the same driver are present, the
-effect of these ioctls is undefined. Again with the
-&VIDIOC-DBG-G-CHIP-INFO; ioctl you can find out which &i2c; chips are
-present.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
-<structfield>match.addr</structfield> selects a chip by its 7 bit &i2c;
-bus address.</para>
-
-    <para>When <structfield>match.type</structfield> is
-<constant>V4L2_CHIP_MATCH_AC97</constant>,
-<structfield>match.addr</structfield> selects the nth AC97 chip
-on the TV card.</para>
-
-    <para>When <structfield>match.type</structfield> is
 <constant>V4L2_CHIP_MATCH_SUBDEV</constant>,
 <structfield>match.addr</structfield> selects the nth sub-device.</para>
 
-    <note>
-      <title>Success not guaranteed</title>
-
-      <para>Due to a flaw in the Linux &i2c; bus driver these ioctls may
-return successfully without actually reading or writing a register. To
-catch the most likely failure we recommend a &VIDIOC-DBG-G-CHIP-INFO;
-call confirming the presence of the selected &i2c; chip.</para>
-    </note>
-
     <para>These ioctls are optional, not all drivers may support them.
 However when a driver supports these ioctls it must also support
 &VIDIOC-DBG-G-CHIP-INFO;. Conversely it may support
@@ -150,7 +120,7 @@
 url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
 access instructions.</para>
 
-    <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
+    <!-- Note for convenience vidioc-dbg-g-chip-info.sgml
 	 contains a duplicate of this table. -->
     <table pgwide="1" frame="none" id="v4l2-dbg-match">
       <title>struct <structname>v4l2_dbg_match</structname></title>
@@ -160,7 +130,7 @@
 	  <row>
 	    <entry>__u32</entry>
 	    <entry><structfield>type</structfield></entry>
-	    <entry>See <xref linkend="ident-chip-match-types" /> for a list of
+	    <entry>See <xref linkend="chip-match-types" /> for a list of
 possible types.</entry>
 	  </row>
 	  <row>
@@ -179,7 +149,7 @@
 	    <entry>char</entry>
 	    <entry><structfield>name[32]</structfield></entry>
 	    <entry>Match a chip by this name, interpreted according
-to the <structfield>type</structfield> field.</entry>
+to the <structfield>type</structfield> field. Currently unused.</entry>
 	  </row>
 	</tbody>
       </tgroup>
@@ -199,6 +169,11 @@
 	    <entry>How to match the chip, see <xref linkend="v4l2-dbg-match" />.</entry>
 	  </row>
 	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>size</structfield></entry>
+	    <entry>The register size in bytes.</entry>
+	  </row>
+	  <row>
 	    <entry>__u64</entry>
 	    <entry><structfield>reg</structfield></entry>
 	    <entry>A register number.</entry>
@@ -213,7 +188,7 @@
       </tgroup>
     </table>
 
-    <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
+    <!-- Note for convenience vidioc-dbg-g-chip-info.sgml
 	 contains a duplicate of this table. -->
     <table pgwide="1" frame="none" id="chip-match-types">
       <title>Chip Match Types</title>
@@ -227,21 +202,6 @@
 	    bridge chip. Does not match sub-devices.</entry>
 	  </row>
 	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
-	    <entry>1</entry>
-	    <entry>Match an &i2c; chip by its driver name.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
-	    <entry>2</entry>
-	    <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
-	  </row>
-	  <row>
-	    <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
-	    <entry>3</entry>
-	    <entry>Match the nth anciliary AC97 chip.</entry>
-	  </row>
-	  <row>
 	    <entry><constant>V4L2_CHIP_MATCH_SUBDEV</constant></entry>
 	    <entry>4</entry>
 	    <entry>Match the nth sub-device.</entry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-querystd.xml b/Documentation/DocBook/media/v4l/vidioc-querystd.xml
index fe80a18..2223485 100644
--- a/Documentation/DocBook/media/v4l/vidioc-querystd.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-querystd.xml
@@ -54,7 +54,8 @@
 VIDIOC_QUERYSTD</constant> with a pointer to a &v4l2-std-id; type. The
 driver stores here a set of candidates, this can be a single flag or a
 set of supported standards if for example the hardware can only
-distinguish between 50 and 60 Hz systems. When detection is not
+distinguish between 50 and 60 Hz systems. If no signal was detected,
+then the driver will return V4L2_STD_UNKNOWN. When detection is not
 possible or fails, the set must contain all standards supported by the
 current video input or output.</para>
 
diff --git a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt
index de9f6b7..0bf6fb7 100644
--- a/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt
+++ b/Documentation/devicetree/bindings/media/exynos-fimc-lite.txt
@@ -2,8 +2,10 @@
 
 Required properties:
 
-- compatible	: should be "samsung,exynos4212-fimc-lite" for Exynos4212 and
-		  Exynos4412 SoCs;
+- compatible	: should be one of:
+		  "samsung,exynos4212-fimc-lite" for Exynos4212/4412 SoCs,
+		  "samsung,exynos5250-fimc-lite" for Exynos5250 compatible
+		   devices;
 - reg		: physical base address and size of the device memory mapped
 		  registers;
 - interrupts	: should contain FIMC-LITE interrupt;
diff --git a/Documentation/devicetree/bindings/media/i2c/mt9p031.txt b/Documentation/devicetree/bindings/media/i2c/mt9p031.txt
new file mode 100644
index 0000000..cb60443
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/mt9p031.txt
@@ -0,0 +1,40 @@
+* Aptina 1/2.5-Inch 5Mp CMOS Digital Image Sensor
+
+The Aptina MT9P031 is a 1/2.5-inch CMOS active pixel digital image sensor with
+an active array size of 2592H x 1944V. It is programmable through a simple
+two-wire serial interface.
+
+Required Properties:
+- compatible: value should be either one among the following
+	(a) "aptina,mt9p031" for mt9p031 sensor
+	(b) "aptina,mt9p031m" for mt9p031m sensor
+
+- input-clock-frequency: Input clock frequency.
+
+- pixel-clock-frequency: Pixel clock frequency.
+
+Optional Properties:
+- reset-gpios: Chip reset GPIO
+
+For further reading on port node refer to
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+Example:
+
+	i2c0@1c22000 {
+		...
+		...
+		mt9p031@5d {
+			compatible = "aptina,mt9p031";
+			reg = <0x5d>;
+			reset-gpios = <&gpio3 30 0>;
+
+			port {
+				mt9p031_1: endpoint {
+					input-clock-frequency = <6000000>;
+					pixel-clock-frequency = <96000000>;
+				};
+			};
+		};
+		...
+	};
diff --git a/Documentation/devicetree/bindings/media/i2c/tvp514x.txt b/Documentation/devicetree/bindings/media/i2c/tvp514x.txt
new file mode 100644
index 0000000..46752cc
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/tvp514x.txt
@@ -0,0 +1,44 @@
+* Texas Instruments TVP514x video decoder
+
+The TVP5146/TVP5146m2/TVP5147/TVP5147m1 device is high quality, single-chip
+digital video decoder that digitizes and decodes all popular baseband analog
+video formats into digital video component. The tvp514x decoder supports analog-
+to-digital (A/D) conversion of component RGB and YPbPr signals as well as A/D
+conversion and decoding of NTSC, PAL and SECAM composite and S-video into
+component YCbCr.
+
+Required Properties :
+- compatible : value should be either one among the following
+	(a) "ti,tvp5146" for tvp5146 decoder.
+	(b) "ti,tvp5146m2" for tvp5146m2 decoder.
+	(c) "ti,tvp5147" for tvp5147 decoder.
+	(d) "ti,tvp5147m1" for tvp5147m1 decoder.
+
+- hsync-active: HSYNC Polarity configuration for endpoint.
+
+- vsync-active: VSYNC Polarity configuration for endpoint.
+
+- pclk-sample: Clock polarity of the endpoint.
+
+For further reading on port node refer to Documentation/devicetree/bindings/
+media/video-interfaces.txt.
+
+Example:
+
+	i2c0@1c22000 {
+		...
+		...
+		tvp514x@5c {
+			compatible = "ti,tvp5146";
+			reg = <0x5c>;
+
+			port {
+				tvp514x_1: endpoint {
+					hsync-active = <1>;
+					vsync-active = <1>;
+					pclk-sample = <0>;
+				};
+			};
+		};
+		...
+	};
diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt
index 51c776b..96312f6 100644
--- a/Documentation/devicetree/bindings/media/samsung-fimc.txt
+++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt
@@ -127,22 +127,22 @@
 				};
 			};
 		};
-	};
 
-	/* MIPI CSI-2 bus IF sensor */
-	s5c73m3: sensor@0x1a {
-		compatible = "samsung,s5c73m3";
-		reg = <0x1a>;
-		vddio-supply = <...>;
+		/* MIPI CSI-2 bus IF sensor */
+		s5c73m3: sensor@0x1a {
+			compatible = "samsung,s5c73m3";
+			reg = <0x1a>;
+			vddio-supply = <...>;
 
-		clock-frequency = <24000000>;
-		clocks = <...>;
-		clock-names = "mclk";
+			clock-frequency = <24000000>;
+			clocks = <...>;
+			clock-names = "mclk";
 
-		port {
-			s5c73m3_1: endpoint {
-				data-lanes = <1 2 3 4>;
-				remote-endpoint = <&csis0_ep>;
+			port {
+				s5c73m3_1: endpoint {
+					data-lanes = <1 2 3 4>;
+					remote-endpoint = <&csis0_ep>;
+				};
 			};
 		};
 	};
diff --git a/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt b/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt
index 5f8e28e..be45f0b 100644
--- a/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt
+++ b/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt
@@ -5,8 +5,8 @@
 
 - compatible	  : "samsung,s5pv210-csis" for S5PV210 (S5PC110),
 		    "samsung,exynos4210-csis" for Exynos4210 (S5PC210),
-		    "samsung,exynos4212-csis" for Exynos4212/Exynos4412
-		    SoC series;
+		    "samsung,exynos4212-csis" for Exynos4212/Exynos4412,
+		    "samsung,exynos5250-csis" for Exynos5250;
 - reg		  : offset and length of the register set for the device;
 - interrupts      : should contain MIPI CSIS interrupt; the format of the
 		    interrupt specifier depends on the interrupt controller;
diff --git a/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt b/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt
new file mode 100644
index 0000000..1ce4e46
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/sh_mobile_ceu.txt
@@ -0,0 +1,18 @@
+Bindings, specific for the sh_mobile_ceu_camera.c driver:
+ - compatible: Should be "renesas,sh-mobile-ceu"
+ - reg: register base and size
+ - interrupts: the interrupt number
+ - interrupt-parent: the interrupt controller
+ - renesas,max-width: maximum image width, supported on this SoC
+ - renesas,max-height: maximum image height, supported on this SoC
+
+Example:
+
+ceu0: ceu@0xfe910000 {
+	compatible = "renesas,sh-mobile-ceu";
+	reg = <0xfe910000 0xa0>;
+	interrupt-parent = <&intcs>;
+	interrupts = <0x880>;
+	renesas,max-width = <8188>;
+	renesas,max-height = <8188>;
+};
diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index eeced24..f552a75 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -265,7 +265,7 @@
 	media_entity_find_link(struct media_pad *source,
 			       struct media_pad *sink);
 
-	media_entity_remote_source(struct media_pad *pad);
+	media_entity_remote_pad(struct media_pad *pad);
 
 Refer to the kerneldoc documentation for more information.
 
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 581f666..f144750 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -160,3 +160,6 @@
 159 -> ProVideo PV183                                      [1830:1540,1831:1540,1832:1540,1833:1540,1834:1540,1835:1540,1836:1540,1837:1540]
 160 -> Tongwei Video Technology TD-3116                    [f200:3116]
 161 -> Aposonic W-DVR                                      [0279:0228]
+162 -> Adlink MPG24
+163 -> Bt848 Capture 14MHz
+164 -> CyberVision CV06 (SV)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index b3ad683..8df17d0 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -190,3 +190,4 @@
 189 -> Kworld PC150-U                           [17de:a134]
 190 -> Asus My Cinema PS3-100                   [1043:48cd]
 191 -> Hawell HW-9004V1
+192 -> AverMedia AverTV Satellite Hybrid+FM A706 [1461:2055]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index 5b83a3f..ac88621 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -86,6 +86,6 @@
 tuner=86 - Tena TNF5337 MFD
 tuner=87 - Xceive 4000 tuner
 tuner=88 - Xceive 5000C tuner
-tuner=89 - Sony PAL+SECAM (BTF-PG472Z)
-tuner=90 - Sony NTSC-M-JP (BTF-PK467Z)
-tuner=91 - Sony NTSC-M (BTF-PB463Z)
+tuner=89 - Sony BTF-PG472Z PAL/SECAM
+tuner=90 - Sony BTF-PK467Z NTSC-M-JP
+tuner=91 - Sony BTF-PB463Z NTSC-M
diff --git a/Documentation/video4linux/fimc.txt b/Documentation/video4linux/fimc.txt
index 25f4d34..e51f1b5 100644
--- a/Documentation/video4linux/fimc.txt
+++ b/Documentation/video4linux/fimc.txt
@@ -1,6 +1,6 @@
 Samsung S5P/EXYNOS4 FIMC driver
 
-Copyright (C) 2012 Samsung Electronics Co., Ltd.
+Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
 ---------------------------------------------------------------------------
 
 The FIMC (Fully Interactive Mobile Camera) device available in Samsung
@@ -10,7 +10,7 @@
 path.  There are multiple FIMC instances in the SoCs (up to 4), having
 slightly different capabilities, like pixel alignment constraints, rotator
 availability, LCD writeback support, etc. The driver is located at
-drivers/media/platform/s5p-fimc directory.
+drivers/media/platform/exynos4-is directory.
 
 1. Supported SoCs
 =================
@@ -36,21 +36,21 @@
 =====================
 
 - media device driver
-  drivers/media/platform/s5p-fimc/fimc-mdevice.[ch]
+  drivers/media/platform/exynos4-is/media-dev.[ch]
 
  - camera capture video device driver
-  drivers/media/platform/s5p-fimc/fimc-capture.c
+  drivers/media/platform/exynos4-is/fimc-capture.c
 
  - MIPI-CSI2 receiver subdev
-  drivers/media/platform/s5p-fimc/mipi-csis.[ch]
+  drivers/media/platform/exynos4-is/mipi-csis.[ch]
 
  - video post-processor (mem-to-mem)
-  drivers/media/platform/s5p-fimc/fimc-core.c
+  drivers/media/platform/exynos4-is/fimc-core.c
 
  - common files
-  drivers/media/platform/s5p-fimc/fimc-core.h
-  drivers/media/platform/s5p-fimc/fimc-reg.h
-  drivers/media/platform/s5p-fimc/regs-fimc.h
+  drivers/media/platform/exynos4-is/fimc-core.h
+  drivers/media/platform/exynos4-is/fimc-reg.h
+  drivers/media/platform/exynos4-is/regs-fimc.h
 
 4. User space interfaces
 ========================
@@ -143,7 +143,8 @@
 6. Platform support
 ===================
 
-The machine code (plat-s5p and arch/arm/mach-*) must select following options
+The machine code (arch/arm/plat-samsung and arch/arm/mach-*) must select
+following options:
 
 CONFIG_S5P_DEV_FIMC0       mandatory
 CONFIG_S5P_DEV_FIMC1  \
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index a300b28..6c4866b 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -246,7 +246,6 @@
 It looks like this:
 
 struct v4l2_subdev_core_ops {
-	int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
 	int (*log_status)(struct v4l2_subdev *sd);
 	int (*init)(struct v4l2_subdev *sd, u32 val);
 	...
@@ -326,8 +325,27 @@
 sink of the link. Subdev drivers are also free to use this function to
 perform the checks mentioned above in addition to their own checks.
 
-A device (bridge) driver needs to register the v4l2_subdev with the
-v4l2_device:
+There are currently two ways to register subdevices with the V4L2 core. The
+first (traditional) possibility is to have subdevices registered by bridge
+drivers. This can be done when the bridge driver has the complete information
+about subdevices connected to it and knows exactly when to register them. This
+is typically the case for internal subdevices, like video data processing units
+within SoCs or complex PCI(e) boards, camera sensors in USB cameras or connected
+to SoCs, which pass information about them to bridge drivers, usually in their
+platform data.
+
+There are however also situations where subdevices have to be registered
+asynchronously to bridge devices. An example of such a configuration is a Device
+Tree based system where information about subdevices is made available to the
+system independently from the bridge devices, e.g. when subdevices are defined
+in DT as I2C device nodes. The API used in this second case is described further
+below.
+
+Using one or the other registration method only affects the probing process, the
+run-time bridge-subdevice interaction is in both cases the same.
+
+In the synchronous case a device (bridge) driver needs to register the
+v4l2_subdev with the v4l2_device:
 
 	int err = v4l2_device_register_subdev(v4l2_dev, sd);
 
@@ -346,24 +364,24 @@
 
 You can call an ops function either directly:
 
-	err = sd->ops->core->g_chip_ident(sd, &chip);
+	err = sd->ops->core->g_std(sd, &norm);
 
 but it is better and easier to use this macro:
 
-	err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
+	err = v4l2_subdev_call(sd, core, g_std, &norm);
 
 The macro will to the right NULL pointer checks and returns -ENODEV if subdev
-is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_chip_ident is
-NULL, or the actual result of the subdev->ops->core->g_chip_ident ops.
+is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_std is
+NULL, or the actual result of the subdev->ops->core->g_std ops.
 
 It is also possible to call all or a subset of the sub-devices:
 
-	v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip);
+	v4l2_device_call_all(v4l2_dev, 0, core, g_std, &norm);
 
 Any subdev that does not support this ops is skipped and error results are
 ignored. If you want to check for errors use this:
 
-	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip);
+	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_std, &norm);
 
 Any error except -ENOIOCTLCMD will exit the loop with that error. If no
 errors (except -ENOIOCTLCMD) occurred, then 0 is returned.
@@ -394,6 +412,30 @@
 up the device, but once the subdev is registered it is completely transparent.
 
 
+In the asynchronous case subdevice probing can be invoked independently of the
+bridge driver availability. The subdevice driver then has to verify whether all
+the requirements for a successful probing are satisfied. This can include a
+check for a master clock availability. If any of the conditions aren't satisfied
+the driver might decide to return -EPROBE_DEFER to request further reprobing
+attempts. Once all conditions are met the subdevice shall be registered using
+the v4l2_async_register_subdev() function. Unregistration is performed using
+the v4l2_async_unregister_subdev() call. Subdevices registered this way are
+stored in a global list of subdevices, ready to be picked up by bridge drivers.
+
+Bridge drivers in turn have to register a notifier object with an array of
+subdevice descriptors that the bridge device needs for its operation. This is
+performed using the v4l2_async_notifier_register() call. To unregister the
+notifier the driver has to call v4l2_async_notifier_unregister(). The former of
+the two functions takes two arguments: a pointer to struct v4l2_device and a
+pointer to struct v4l2_async_notifier. The latter contains a pointer to an array
+of pointers to subdevice descriptors of type struct v4l2_async_subdev type. The
+V4L2 core will then use these descriptors to match asynchronously registered
+subdevices to them. If a match is detected the .bound() notifier callback is
+called. After all subdevices have been located the .complete() callback is
+called. When a subdevice is removed from the system the .unbind() method is
+called. All three callbacks are optional.
+
+
 V4L2 sub-device userspace API
 -----------------------------
 
@@ -575,9 +617,13 @@
 The default video_device_release() callback just calls kfree to free the
 allocated memory.
 
+There is also a video_device_release_empty() function that does nothing
+(is empty) and can be used if the struct is embedded and there is nothing
+to do when it is released.
+
 You should also set these fields:
 
-- v4l2_dev: set to the v4l2_device parent device.
+- v4l2_dev: must be set to the v4l2_device parent device.
 
 - name: set to something descriptive and unique.
 
@@ -614,15 +660,16 @@
   If you want to have a separate priority state per (group of) device node(s),
   then you can point it to your own struct v4l2_prio_state.
 
-- parent: you only set this if v4l2_device was registered with NULL as
+- dev_parent: you only set this if v4l2_device was registered with NULL as
   the parent device struct. This only happens in cases where one hardware
   device has multiple PCI devices that all share the same v4l2_device core.
 
   The cx88 driver is an example of this: one core v4l2_device struct, but
-  it is used by both an raw video PCI device (cx8800) and a MPEG PCI device
-  (cx8802). Since the v4l2_device cannot be associated with a particular
-  PCI device it is setup without a parent device. But when the struct
-  video_device is setup you do know which parent PCI device to use.
+  it is used by both a raw video PCI device (cx8800) and a MPEG PCI device
+  (cx8802). Since the v4l2_device cannot be associated with two PCI devices
+  at the same time it is setup without a parent device. But when the struct
+  video_device is initialized you *do* know which parent PCI device to use and
+  so you set dev_device to the correct PCI device.
 
 - flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
   handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
@@ -1061,3 +1108,29 @@
 
 An example on how the V4L2 events may be used can be found in the OMAP
 3 ISP driver (drivers/media/platform/omap3isp).
+
+
+V4L2 clocks
+-----------
+
+Many subdevices, like camera sensors, TV decoders and encoders, need a clock
+signal to be supplied by the system. Often this clock is supplied by the
+respective bridge device. The Linux kernel provides a Common Clock Framework for
+this purpose. However, it is not (yet) available on all architectures. Besides,
+the nature of the multi-functional (clock, data + synchronisation, I2C control)
+connection of subdevices to the system might impose special requirements on the
+clock API usage. E.g. V4L2 has to support clock provider driver unregistration
+while a subdevice driver is holding a reference to the clock. For these reasons
+a V4L2 clock helper API has been developed and is provided to bridge and
+subdevice drivers.
+
+The API consists of two parts: two functions to register and unregister a V4L2
+clock source: v4l2_clk_register() and v4l2_clk_unregister() and calls to control
+a clock object, similar to the respective generic clock API calls:
+v4l2_clk_get(), v4l2_clk_put(), v4l2_clk_enable(), v4l2_clk_disable(),
+v4l2_clk_get_rate(), and v4l2_clk_set_rate(). Clock suppliers have to provide
+clock operations that will be called when clock users invoke respective API
+methods.
+
+It is expected that once the CCF becomes available on all relevant
+architectures this API will be removed.
diff --git a/Documentation/zh_CN/video4linux/v4l2-framework.txt b/Documentation/zh_CN/video4linux/v4l2-framework.txt
index 44c1d93..0da95db 100644
--- a/Documentation/zh_CN/video4linux/v4l2-framework.txt
+++ b/Documentation/zh_CN/video4linux/v4l2-framework.txt
@@ -247,7 +247,6 @@
 这些结构体定义如下:
 
 struct v4l2_subdev_core_ops {
-	int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
 	int (*log_status)(struct v4l2_subdev *sd);
 	int (*init)(struct v4l2_subdev *sd, u32 val);
 	...
@@ -337,24 +336,24 @@
 
 注册之设备后,可通过以下方式直接调用其操作函数:
 
-	err = sd->ops->core->g_chip_ident(sd, &chip);
+	err = sd->ops->core->g_std(sd, &norm);
 
 但使用如下宏会比较容易且合适:
 
-	err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
+	err = v4l2_subdev_call(sd, core, g_std, &norm);
 
 这个宏将会做 NULL 指针检查,如果 subdev 为 NULL,则返回-ENODEV;如果
-subdev->core 或 subdev->core->g_chip_ident 为 NULL,则返回 -ENOIOCTLCMD;
-否则将返回 subdev->ops->core->g_chip_ident ops 调用的实际结果。
+subdev->core 或 subdev->core->g_std 为 NULL,则返回 -ENOIOCTLCMD;
+否则将返回 subdev->ops->core->g_std ops 调用的实际结果。
 
 有时也可能同时调用所有或一系列子设备的某个操作函数:
 
-	v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip);
+	v4l2_device_call_all(v4l2_dev, 0, core, g_std, &norm);
 
 任何不支持此操作的子设备都会被跳过,并忽略错误返回值。但如果你需要
 检查出错码,则可使用如下函数:
 
-	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip);
+	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_std, &norm);
 
 除 -ENOIOCTLCMD 外的任何错误都会跳出循环并返回错误值。如果(除 -ENOIOCTLCMD
 外)没有错误发生,则返回 0。
diff --git a/MAINTAINERS b/MAINTAINERS
index 9d771d9..b41a9fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1165,15 +1165,6 @@
 S:	Maintained
 F:	drivers/media/platform/s5p-g2d/
 
-ARM/SAMSUNG S5P SERIES FIMC SUPPORT
-M:	Kyungmin Park <kyungmin.park@samsung.com>
-M:	Sylwester Nawrocki <s.nawrocki@samsung.com>
-L:	linux-arm-kernel@lists.infradead.org
-L:	linux-media@vger.kernel.org
-S:	Maintained
-F:	arch/arm/plat-samsung/include/plat/*fimc*
-F:	drivers/media/platform/s5p-fimc/
-
 ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
 M:	Kyungmin Park <kyungmin.park@samsung.com>
 M:	Kamil Debski <k.debski@samsung.com>
@@ -1595,7 +1586,7 @@
 F:	net/ax25/
 
 AZ6007 DVB DRIVER
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
@@ -1880,7 +1871,7 @@
 F:	fs/btrfs/
 
 BTTV VIDEO4LINUX DRIVER
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
@@ -2368,7 +2359,7 @@
 F:	include/media/cx2341x*
 
 CX88 VIDEO4LINUX DRIVER
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
@@ -2990,7 +2981,7 @@
 F:	drivers/edac/e7xxx_edac.c
 
 EDAC-GHES
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-edac@vger.kernel.org
 W:	bluesmoke.sourceforge.net
 S:	Maintained
@@ -3018,21 +3009,21 @@
 F:	drivers/edac/i5000_edac.c
 
 EDAC-I5400
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-edac@vger.kernel.org
 W:	bluesmoke.sourceforge.net
 S:	Maintained
 F:	drivers/edac/i5400_edac.c
 
 EDAC-I7300
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-edac@vger.kernel.org
 W:	bluesmoke.sourceforge.net
 S:	Maintained
 F:	drivers/edac/i7300_edac.c
 
 EDAC-I7CORE
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-edac@vger.kernel.org
 W:	bluesmoke.sourceforge.net
 S:	Maintained
@@ -3061,7 +3052,7 @@
 F:	drivers/edac/r82600_edac.c
 
 EDAC-SBRIDGE
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-edac@vger.kernel.org
 W:	bluesmoke.sourceforge.net
 S:	Maintained
@@ -3121,7 +3112,7 @@
 F:	drivers/net/ethernet/ibm/ehea/
 
 EM28XX VIDEO4LINUX DRIVER
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
@@ -5317,7 +5308,7 @@
 F:	drivers/media/radio/radio-maxiradio*
 
 MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 P:	LinuxTV.org Project
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
@@ -7013,7 +7004,7 @@
 F:	drivers/media/i2c/saa6588*
 
 SAA7134 VIDEO4LINUX DRIVER
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
@@ -7058,6 +7049,15 @@
 F:	drivers/rtc/rtc-sec.c
 F:	include/linux/mfd/samsung/
 
+SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS
+M:	Kyungmin Park <kyungmin.park@samsung.com>
+M:	Sylwester Nawrocki <s.nawrocki@samsung.com>
+L:	linux-media@vger.kernel.org
+Q:	https://patchwork.linuxtv.org/project/linux-media/list/
+S:	Supported
+F:	drivers/media/platform/exynos4-is/
+F:	include/media/s5p_fimc.h
+
 SAMSUNG S3C24XX/S3C64XX SOC SERIES CAMIF DRIVER
 M:	Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
 L:	linux-media@vger.kernel.org
@@ -7375,7 +7375,7 @@
 F:	drivers/media/radio/radio-si4713.h
 
 SIANO DVB DRIVER
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
@@ -8080,7 +8080,7 @@
 F:	drivers/media/i2c/tda9840*
 
 TEA5761 TUNER DRIVER
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
@@ -8088,7 +8088,7 @@
 F:	drivers/media/tuners/tea5761.*
 
 TEA5767 TUNER DRIVER
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
@@ -8327,7 +8327,7 @@
 F:	mm/shmem.c
 
 TM6000 VIDEO4LINUX DRIVER
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
@@ -9184,7 +9184,7 @@
 F:	arch/x86/kernel/cpu/mcheck/*
 
 XC2028/3028 TUNER DRIVER
-M:	Mauro Carvalho Chehab <mchehab@redhat.com>
+M:	Mauro Carvalho Chehab <m.chehab@samsung.com>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 T:	git git://linuxtv.org/media_tree.git
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index fd38c8d..afbc439 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -509,7 +509,6 @@
 	.ch_1 = 3,
 	.ch_2 = 3,
 	.ch_3 = 3,
-	.init_enable = 1,
 };
 
 static struct amp_config_info vpbe_amp = {
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index 08fe897..6687ba7 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -680,10 +680,7 @@
 	d = debugfs_create_file(name, S_IRUGO, dma_buf_debugfs_dir,
 			write, &dma_buf_debug_fops);
 
-	if (IS_ERR(d))
-		return PTR_ERR(d);
-
-	return 0;
+	return PTR_RET(d);
 }
 #else
 static inline int dma_buf_init_debugfs(void)
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
index fe907f2..3077949 100644
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ b/drivers/media/common/saa7146/saa7146_video.c
@@ -1,7 +1,6 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <media/saa7146_vv.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-ctrls.h>
 #include <linux/module.h>
@@ -988,26 +987,6 @@
 	return err;
 }
 
-static int vidioc_g_chip_ident(struct file *file, void *__fh,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct saa7146_fh *fh = __fh;
-	struct saa7146_dev *dev = fh->dev;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
-		if (v4l2_chip_match_host(&chip->match))
-			chip->ident = V4L2_IDENT_SAA7146;
-		return 0;
-	}
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-	    chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-	return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
-			core, g_chip_ident, chip);
-}
-
 const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
 	.vidioc_querycap             = vidioc_querycap,
 	.vidioc_enum_fmt_vid_cap     = vidioc_enum_fmt_vid_cap,
@@ -1018,7 +997,6 @@
 	.vidioc_g_fmt_vid_overlay    = vidioc_g_fmt_vid_overlay,
 	.vidioc_try_fmt_vid_overlay  = vidioc_try_fmt_vid_overlay,
 	.vidioc_s_fmt_vid_overlay    = vidioc_s_fmt_vid_overlay,
-	.vidioc_g_chip_ident         = vidioc_g_chip_ident,
 
 	.vidioc_overlay 	     = vidioc_overlay,
 	.vidioc_g_fbuf  	     = vidioc_g_fbuf,
@@ -1039,7 +1017,6 @@
 const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = {
 	.vidioc_querycap             = vidioc_querycap,
 	.vidioc_g_fmt_vbi_cap        = vidioc_g_fmt_vbi_cap,
-	.vidioc_g_chip_ident         = vidioc_g_chip_ident,
 
 	.vidioc_reqbufs              = vidioc_reqbufs,
 	.vidioc_querybuf             = vidioc_querybuf,
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
index 45ac9ee..a142f79 100644
--- a/drivers/media/common/siano/smscoreapi.c
+++ b/drivers/media/common/siano/smscoreapi.c
@@ -1154,7 +1154,7 @@
 
 	char *fw_filename = smscore_get_fw_filename(coredev, mode);
 	if (!fw_filename) {
-		sms_info("mode %d not supported on this device", mode);
+		sms_err("mode %d not supported on this device", mode);
 		return -ENOENT;
 	}
 	sms_debug("Firmware name: %s", fw_filename);
@@ -1165,23 +1165,24 @@
 
 	rc = request_firmware(&fw, fw_filename, coredev->device);
 	if (rc < 0) {
-		sms_info("failed to open \"%s\"", fw_filename);
+		sms_err("failed to open firmware file \"%s\"", fw_filename);
 		return rc;
 	}
 	sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size);
 	fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
 			 GFP_KERNEL | GFP_DMA);
 	if (!fw_buf) {
-		sms_info("failed to allocate firmware buffer");
-		return -ENOMEM;
-	}
-	memcpy(fw_buf, fw->data, fw->size);
-	fw_buf_size = fw->size;
+		sms_err("failed to allocate firmware buffer");
+		rc = -ENOMEM;
+	} else {
+		memcpy(fw_buf, fw->data, fw->size);
+		fw_buf_size = fw->size;
 
-	rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
-		smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
-		: loadfirmware_handler(coredev->context, fw_buf,
-		fw_buf_size);
+		rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
+			smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
+			: loadfirmware_handler(coredev->context, fw_buf,
+			fw_buf_size);
+	}
 
 	kfree(fw_buf);
 	release_firmware(fw);
diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c
index 297f1b2..0862622 100644
--- a/drivers/media/common/siano/smsdvb-main.c
+++ b/drivers/media/common/siano/smsdvb-main.c
@@ -140,6 +140,7 @@
 	case DEVICE_MODE_ISDBT:
 	case DEVICE_MODE_ISDBT_BDA:
 		n_layers = 4;
+		break;
 	default:
 		n_layers = 1;
 	}
diff --git a/drivers/media/common/tveeprom.c b/drivers/media/common/tveeprom.c
index cc1e172..c7dace6 100644
--- a/drivers/media/common/tveeprom.c
+++ b/drivers/media/common/tveeprom.c
@@ -40,7 +40,6 @@
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
 MODULE_AUTHOR("John Klar");
@@ -67,13 +66,10 @@
  * The Hauppauge eeprom uses an 8bit field to determine which
  * tuner formats the tuner supports.
  */
-static struct HAUPPAUGE_TUNER_FMT
-{
+static const struct {
 	int	id;
-	char *name;
-}
-hauppauge_tuner_fmt[] =
-{
+	const char * const name;
+} hauppauge_tuner_fmt[] = {
 	{ V4L2_STD_UNKNOWN,                   " UNKNOWN" },
 	{ V4L2_STD_UNKNOWN,                   " FM" },
 	{ V4L2_STD_B|V4L2_STD_GH,             " PAL(B/G)" },
@@ -88,13 +84,10 @@
    supplying this information. Note that many tuners where only used for
    testing and never made it to the outside world. So you will only see
    a subset in actual produced cards. */
-static struct HAUPPAUGE_TUNER
-{
+static const struct {
 	int  id;
-	char *name;
-}
-hauppauge_tuner[] =
-{
+	const char * const name;
+} hauppauge_tuner[] = {
 	/* 0-9 */
 	{ TUNER_ABSENT,			"None" },
 	{ TUNER_ABSENT,			"External" },
@@ -298,69 +291,66 @@
 	{ TUNER_ABSENT,                 "NXP 18272S"},
 };
 
-/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
+/* Use TVEEPROM_AUDPROC_INTERNAL for those audio 'chips' that are
  * internal to a video chip, i.e. not a separate audio chip. */
-static struct HAUPPAUGE_AUDIOIC
-{
+static const struct {
 	u32   id;
-	char *name;
-}
-audioIC[] =
-{
+	const char * const name;
+} audio_ic[] = {
 	/* 0-4 */
-	{ V4L2_IDENT_NONE,      "None"      },
-	{ V4L2_IDENT_UNKNOWN,   "TEA6300"   },
-	{ V4L2_IDENT_UNKNOWN,   "TEA6320"   },
-	{ V4L2_IDENT_UNKNOWN,   "TDA9850"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3400C"  },
+	{ TVEEPROM_AUDPROC_NONE,  "None"      },
+	{ TVEEPROM_AUDPROC_OTHER, "TEA6300"   },
+	{ TVEEPROM_AUDPROC_OTHER, "TEA6320"   },
+	{ TVEEPROM_AUDPROC_OTHER, "TDA9850"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3400C"  },
 	/* 5-9 */
-	{ V4L2_IDENT_MSPX4XX,   "MSP3410D"  },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3415"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3430"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3438"   },
-	{ V4L2_IDENT_UNKNOWN,   "CS5331"    },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3410D"  },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3415"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3430"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3438"   },
+	{ TVEEPROM_AUDPROC_OTHER, "CS5331"    },
 	/* 10-14 */
-	{ V4L2_IDENT_MSPX4XX,   "MSP3435"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3440"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3445"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3411"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3416"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3435"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3440"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3445"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3411"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3416"   },
 	/* 15-19 */
-	{ V4L2_IDENT_MSPX4XX,   "MSP3425"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3451"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP3418"   },
-	{ V4L2_IDENT_UNKNOWN,   "Type 0x12" },
-	{ V4L2_IDENT_UNKNOWN,   "OKI7716"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3425"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3451"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP3418"   },
+	{ TVEEPROM_AUDPROC_OTHER, "Type 0x12" },
+	{ TVEEPROM_AUDPROC_OTHER, "OKI7716"   },
 	/* 20-24 */
-	{ V4L2_IDENT_MSPX4XX,   "MSP4410"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4420"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4440"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4450"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4408"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4410"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4420"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4440"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4450"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4408"   },
 	/* 25-29 */
-	{ V4L2_IDENT_MSPX4XX,   "MSP4418"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4428"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4448"   },
-	{ V4L2_IDENT_MSPX4XX,   "MSP4458"   },
-	{ V4L2_IDENT_MSPX4XX,   "Type 0x1d" },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4418"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4428"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4448"   },
+	{ TVEEPROM_AUDPROC_MSP,   "MSP4458"   },
+	{ TVEEPROM_AUDPROC_MSP,   "Type 0x1d" },
 	/* 30-34 */
-	{ V4L2_IDENT_AMBIGUOUS, "CX880"     },
-	{ V4L2_IDENT_AMBIGUOUS, "CX881"     },
-	{ V4L2_IDENT_AMBIGUOUS, "CX883"     },
-	{ V4L2_IDENT_AMBIGUOUS, "CX882"     },
-	{ V4L2_IDENT_AMBIGUOUS, "CX25840"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX880"     },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX881"     },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX883"     },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX882"     },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX25840"   },
 	/* 35-39 */
-	{ V4L2_IDENT_AMBIGUOUS, "CX25841"   },
-	{ V4L2_IDENT_AMBIGUOUS, "CX25842"   },
-	{ V4L2_IDENT_AMBIGUOUS, "CX25843"   },
-	{ V4L2_IDENT_AMBIGUOUS, "CX23418"   },
-	{ V4L2_IDENT_AMBIGUOUS, "CX23885"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX25841"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX25842"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX25843"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX23418"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX23885"   },
 	/* 40-44 */
-	{ V4L2_IDENT_AMBIGUOUS, "CX23888"   },
-	{ V4L2_IDENT_AMBIGUOUS, "SAA7131"   },
-	{ V4L2_IDENT_AMBIGUOUS, "CX23887"   },
-	{ V4L2_IDENT_AMBIGUOUS, "SAA7164"   },
-	{ V4L2_IDENT_AMBIGUOUS, "AU8522"    },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX23888"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "SAA7131"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "CX23887"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "SAA7164"   },
+	{ TVEEPROM_AUDPROC_INTERNAL, "AU8522"    },
 };
 
 /* This list is supplied by Hauppauge. Thanks! */
@@ -453,11 +443,11 @@
 	int i, j, len, done, beenhere, tag, start;
 
 	int tuner1 = 0, t_format1 = 0, audioic = -1;
-	char *t_name1 = NULL;
+	const char *t_name1 = NULL;
 	const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
 
 	int tuner2 = 0, t_format2 = 0;
-	char *t_name2 = NULL;
+	const char *t_name2 = NULL;
 	const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
 
 	memset(tvee, 0, sizeof(*tvee));
@@ -545,10 +535,10 @@
 			to indicate 4052 mux was removed in favor of using MSP
 			inputs directly. */
 			audioic = eeprom_data[i+2] & 0x7f;
-			if (audioic < ARRAY_SIZE(audioIC))
-				tvee->audio_processor = audioIC[audioic].id;
+			if (audioic < ARRAY_SIZE(audio_ic))
+				tvee->audio_processor = audio_ic[audioic].id;
 			else
-				tvee->audio_processor = V4L2_IDENT_UNKNOWN;
+				tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
 			break;
 
 		/* case 0x03: tag 'EEInfo' */
@@ -578,10 +568,10 @@
 			to indicate 4052 mux was removed in favor of using MSP
 			inputs directly. */
 			audioic = eeprom_data[i+1] & 0x7f;
-			if (audioic < ARRAY_SIZE(audioIC))
-				tvee->audio_processor = audioIC[audioic].id;
+			if (audioic < ARRAY_SIZE(audio_ic))
+				tvee->audio_processor = audio_ic[audioic].id;
 			else
-				tvee->audio_processor = V4L2_IDENT_UNKNOWN;
+				tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
 
 			break;
 
@@ -726,11 +716,11 @@
 			t_fmt_name2[6], t_fmt_name2[7], t_format2);
 	if (audioic < 0) {
 		tveeprom_info("audio processor is unknown (no idx)\n");
-		tvee->audio_processor = V4L2_IDENT_UNKNOWN;
+		tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
 	} else {
-		if (audioic < ARRAY_SIZE(audioIC))
+		if (audioic < ARRAY_SIZE(audio_ic))
 			tveeprom_info("audio processor is %s (idx %d)\n",
-					audioIC[audioic].name, audioic);
+					audio_ic[audioic].name, audioic);
 		else
 			tveeprom_info("audio processor is unknown (idx %d)\n",
 								audioic);
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index a1a3a51..0b4616b 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -377,10 +377,8 @@
 		ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
 					      buffer2_len);
 	}
-	if (ret < 0) {
-		dvb_ringbuffer_flush(&dmxdevfilter->buffer);
+	if (ret < 0)
 		dmxdevfilter->buffer.error = ret;
-	}
 	if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
 		dmxdevfilter->state = DMXDEV_STATE_DONE;
 	spin_unlock(&dmxdevfilter->dev->lock);
@@ -416,10 +414,8 @@
 	ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
 	if (ret == buffer1_len)
 		ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
-	if (ret < 0) {
-		dvb_ringbuffer_flush(buffer);
+	if (ret < 0)
 		buffer->error = ret;
-	}
 	spin_unlock(&dmxdevfilter->dev->lock);
 	wake_up(&buffer->queue);
 	return 0;
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/drivers/media/dvb-core/dvb-usb-ids.h
index 335a8f4..886da16 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/drivers/media/dvb-core/dvb-usb-ids.h
@@ -367,4 +367,6 @@
 #define USB_PID_TECHNISAT_USB2_HDCI_V2			0x0002
 #define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2		0x0004
 #define USB_PID_TECHNISAT_USB2_DVB_S2			0x0500
+#define USB_PID_CPYTO_REDI_PC50A			0xa803
+#define USB_PID_CTVDIGDUAL_V2				0xe410
 #endif
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c
index 2099f21..23a0d05 100644
--- a/drivers/media/dvb-frontends/au8522_decoder.c
+++ b/drivers/media/dvb-frontends/au8522_decoder.c
@@ -35,7 +35,6 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-device.h>
 #include "au8522.h"
 #include "au8522_priv.h"
@@ -524,13 +523,8 @@
 static int au8522_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct au8522_state *state = to_state(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = au8522_readreg(state, reg->reg & 0xffff);
 	return 0;
 }
@@ -538,13 +532,8 @@
 static int au8522_s_register(struct v4l2_subdev *sd,
 			     const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct au8522_state *state = to_state(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	au8522_writereg(state, reg->reg, reg->val & 0xff);
 	return 0;
 }
@@ -636,20 +625,10 @@
 	return 0;
 }
 
-static int au8522_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *chip)
-{
-	struct au8522_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops au8522_core_ops = {
 	.log_status = v4l2_ctrl_subdev_log_status,
-	.g_chip_ident = au8522_g_chip_ident,
 	.reset = au8522_reset,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = au8522_g_register,
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index a54182d..9053614 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -3406,7 +3406,7 @@
 {
 	struct dib8000_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
-	int l, i, active, time, ret, time_slave = FE_CALLBACK_TIME_NEVER;
+	int l, i, active, time, time_slave = FE_CALLBACK_TIME_NEVER;
 	u8 exit_condition, index_frontend;
 	u32 delay, callback_time;
 
@@ -3553,7 +3553,7 @@
 		}
 	}
 
-	return ret;
+	return 0;
 }
 
 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
diff --git a/drivers/media/dvb-frontends/drxk.h b/drivers/media/dvb-frontends/drxk.h
index e666718..f22eb9f 100644
--- a/drivers/media/dvb-frontends/drxk.h
+++ b/drivers/media/dvb-frontends/drxk.h
@@ -8,7 +8,7 @@
 /**
  * struct drxk_config - Configure the initial parameters for DRX-K
  *
- * @adr:		I2C Address of the DRX-K
+ * @adr:		I2C address of the DRX-K
  * @parallel_ts:	True means that the device uses parallel TS,
  * 			Serial otherwise.
  * @dynamic_clk:	True means that the clock will be dynamically
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index ec24d71..082014d 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -21,6 +21,8 @@
  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -34,35 +36,36 @@
 #include "dvb_frontend.h"
 #include "drxk.h"
 #include "drxk_hard.h"
+#include "dvb_math.h"
 
-static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
-static int PowerDownQAM(struct drxk_state *state);
-static int SetDVBTStandard(struct drxk_state *state,
-			   enum OperationMode oMode);
-static int SetQAMStandard(struct drxk_state *state,
-			  enum OperationMode oMode);
-static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
-		  s32 tunerFreqOffset);
-static int SetDVBTStandard(struct drxk_state *state,
-			   enum OperationMode oMode);
-static int DVBTStart(struct drxk_state *state);
-static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
-		   s32 tunerFreqOffset);
-static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
-static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
-static int SwitchAntennaToQAM(struct drxk_state *state);
-static int SwitchAntennaToDVBT(struct drxk_state *state);
+static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
+static int power_down_qam(struct drxk_state *state);
+static int set_dvbt_standard(struct drxk_state *state,
+			   enum operation_mode o_mode);
+static int set_qam_standard(struct drxk_state *state,
+			  enum operation_mode o_mode);
+static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
+		  s32 tuner_freq_offset);
+static int set_dvbt_standard(struct drxk_state *state,
+			   enum operation_mode o_mode);
+static int dvbt_start(struct drxk_state *state);
+static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
+		   s32 tuner_freq_offset);
+static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status);
+static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status);
+static int switch_antenna_to_qam(struct drxk_state *state);
+static int switch_antenna_to_dvbt(struct drxk_state *state);
 
-static bool IsDVBT(struct drxk_state *state)
+static bool is_dvbt(struct drxk_state *state)
 {
-	return state->m_OperationMode == OM_DVBT;
+	return state->m_operation_mode == OM_DVBT;
 }
 
-static bool IsQAM(struct drxk_state *state)
+static bool is_qam(struct drxk_state *state)
 {
-	return state->m_OperationMode == OM_QAM_ITU_A ||
-	    state->m_OperationMode == OM_QAM_ITU_B ||
-	    state->m_OperationMode == OM_QAM_ITU_C;
+	return state->m_operation_mode == OM_QAM_ITU_A ||
+	    state->m_operation_mode == OM_QAM_ITU_B ||
+	    state->m_operation_mode == OM_QAM_ITU_C;
 }
 
 #define NOA1ROM 0
@@ -165,7 +168,7 @@
 
 #define dprintk(level, fmt, arg...) do {			\
 if (debug >= level)						\
-	printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg);	\
+	pr_debug(fmt, ##arg);					\
 } while (0)
 
 
@@ -186,8 +189,10 @@
 	u32 R0 = 0;
 
 	R0 = (a % c) << 4;	/* 32-28 == 4 shifts possible at max */
-	Q1 = a / c;		/* integer part, only the 4 least significant bits
-				   will be visible in the result */
+	Q1 = a / c;		/*
+				 * integer part, only the 4 least significant
+				 * bits will be visible in the result
+				 */
 
 	/* division using radix 16, 7 nibbles in the result */
 	for (i = 0; i < 7; i++) {
@@ -201,98 +206,9 @@
 	return Q1;
 }
 
-static u32 Log10Times100(u32 x)
+static inline u32 log10times100(u32 value)
 {
-	static const u8 scale = 15;
-	static const u8 indexWidth = 5;
-	u8 i = 0;
-	u32 y = 0;
-	u32 d = 0;
-	u32 k = 0;
-	u32 r = 0;
-	/*
-	   log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
-	   0 <= n < ((1<<INDEXWIDTH)+1)
-	 */
-
-	static const u32 log2lut[] = {
-		0,		/* 0.000000 */
-		290941,		/* 290941.300628 */
-		573196,		/* 573196.476418 */
-		847269,		/* 847269.179851 */
-		1113620,	/* 1113620.489452 */
-		1372674,	/* 1372673.576986 */
-		1624818,	/* 1624817.752104 */
-		1870412,	/* 1870411.981536 */
-		2109788,	/* 2109787.962654 */
-		2343253,	/* 2343252.817465 */
-		2571091,	/* 2571091.461923 */
-		2793569,	/* 2793568.696416 */
-		3010931,	/* 3010931.055901 */
-		3223408,	/* 3223408.452106 */
-		3431216,	/* 3431215.635215 */
-		3634553,	/* 3634553.498355 */
-		3833610,	/* 3833610.244726 */
-		4028562,	/* 4028562.434393 */
-		4219576,	/* 4219575.925308 */
-		4406807,	/* 4406806.721144 */
-		4590402,	/* 4590401.736809 */
-		4770499,	/* 4770499.491025 */
-		4947231,	/* 4947230.734179 */
-		5120719,	/* 5120719.018555 */
-		5291081,	/* 5291081.217197 */
-		5458428,	/* 5458427.996830 */
-		5622864,	/* 5622864.249668 */
-		5784489,	/* 5784489.488298 */
-		5943398,	/* 5943398.207380 */
-		6099680,	/* 6099680.215452 */
-		6253421,	/* 6253420.939751 */
-		6404702,	/* 6404701.706649 */
-		6553600,	/* 6553600.000000 */
-	};
-
-
-	if (x == 0)
-		return 0;
-
-	/* Scale x (normalize) */
-	/* computing y in log(x/y) = log(x) - log(y) */
-	if ((x & ((0xffffffff) << (scale + 1))) == 0) {
-		for (k = scale; k > 0; k--) {
-			if (x & (((u32) 1) << scale))
-				break;
-			x <<= 1;
-		}
-	} else {
-		for (k = scale; k < 31; k++) {
-			if ((x & (((u32) (-1)) << (scale + 1))) == 0)
-				break;
-			x >>= 1;
-		}
-	}
-	/*
-	   Now x has binary point between bit[scale] and bit[scale-1]
-	   and 1.0 <= x < 2.0 */
-
-	/* correction for divison: log(x) = log(x/y)+log(y) */
-	y = k * ((((u32) 1) << scale) * 200);
-
-	/* remove integer part */
-	x &= ((((u32) 1) << scale) - 1);
-	/* get index */
-	i = (u8) (x >> (scale - indexWidth));
-	/* compute delta (x - a) */
-	d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
-	/* compute log, multiplication (d* (..)) must be within range ! */
-	y += log2lut[i] +
-	    ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
-	/* Conver to log10() */
-	y /= 108853;		/* (log2(10) << scale) */
-	r = (y >> 1);
-	/* rounding */
-	if (y & ((u32) 1))
-		r++;
-	return r;
+	return (100L * intlog10(value)) >> 24;
 }
 
 /****************************************************************************/
@@ -344,15 +260,15 @@
 	if (debug > 2) {
 		int i;
 		for (i = 0; i < len; i++)
-			printk(KERN_CONT " %02x", data[i]);
-		printk(KERN_CONT "\n");
+			pr_cont(" %02x", data[i]);
+		pr_cont("\n");
 	}
 	status = drxk_i2c_transfer(state, &msg, 1);
 	if (status >= 0 && status != 1)
 		status = -EIO;
 
 	if (status < 0)
-		printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
+		pr_err("i2c write error at addr 0x%02x\n", adr);
 
 	return status;
 }
@@ -371,22 +287,22 @@
 	status = drxk_i2c_transfer(state, msgs, 2);
 	if (status != 2) {
 		if (debug > 2)
-			printk(KERN_CONT ": ERROR!\n");
+			pr_cont(": ERROR!\n");
 		if (status >= 0)
 			status = -EIO;
 
-		printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
+		pr_err("i2c read error at addr 0x%02x\n", adr);
 		return status;
 	}
 	if (debug > 2) {
 		int i;
 		dprintk(2, ": read from");
 		for (i = 0; i < len; i++)
-			printk(KERN_CONT " %02x", msg[i]);
-		printk(KERN_CONT ", value = ");
+			pr_cont(" %02x", msg[i]);
+		pr_cont(", value = ");
 		for (i = 0; i < alen; i++)
-			printk(KERN_CONT " %02x", answ[i]);
-		printk(KERN_CONT "\n");
+			pr_cont(" %02x", answ[i]);
+		pr_cont("\n");
 	}
 	return 0;
 }
@@ -520,55 +436,55 @@
 	return write32_flags(state, reg, data, 0);
 }
 
-static int write_block(struct drxk_state *state, u32 Address,
-		      const int BlockSize, const u8 pBlock[])
+static int write_block(struct drxk_state *state, u32 address,
+		      const int block_size, const u8 p_block[])
 {
-	int status = 0, BlkSize = BlockSize;
-	u8 Flags = 0;
+	int status = 0, blk_size = block_size;
+	u8 flags = 0;
 
 	if (state->single_master)
-		Flags |= 0xC0;
+		flags |= 0xC0;
 
-	while (BlkSize > 0) {
-		int Chunk = BlkSize > state->m_ChunkSize ?
-		    state->m_ChunkSize : BlkSize;
-		u8 *AdrBuf = &state->Chunk[0];
-		u32 AdrLength = 0;
+	while (blk_size > 0) {
+		int chunk = blk_size > state->m_chunk_size ?
+		    state->m_chunk_size : blk_size;
+		u8 *adr_buf = &state->chunk[0];
+		u32 adr_length = 0;
 
-		if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
-			AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
-			AdrBuf[1] = ((Address >> 16) & 0xFF);
-			AdrBuf[2] = ((Address >> 24) & 0xFF);
-			AdrBuf[3] = ((Address >> 7) & 0xFF);
-			AdrBuf[2] |= Flags;
-			AdrLength = 4;
-			if (Chunk == state->m_ChunkSize)
-				Chunk -= 2;
+		if (DRXDAP_FASI_LONG_FORMAT(address) || (flags != 0)) {
+			adr_buf[0] = (((address << 1) & 0xFF) | 0x01);
+			adr_buf[1] = ((address >> 16) & 0xFF);
+			adr_buf[2] = ((address >> 24) & 0xFF);
+			adr_buf[3] = ((address >> 7) & 0xFF);
+			adr_buf[2] |= flags;
+			adr_length = 4;
+			if (chunk == state->m_chunk_size)
+				chunk -= 2;
 		} else {
-			AdrBuf[0] = ((Address << 1) & 0xFF);
-			AdrBuf[1] = (((Address >> 16) & 0x0F) |
-				     ((Address >> 18) & 0xF0));
-			AdrLength = 2;
+			adr_buf[0] = ((address << 1) & 0xFF);
+			adr_buf[1] = (((address >> 16) & 0x0F) |
+				     ((address >> 18) & 0xF0));
+			adr_length = 2;
 		}
-		memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
-		dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
+		memcpy(&state->chunk[adr_length], p_block, chunk);
+		dprintk(2, "(0x%08x, 0x%02x)\n", address, flags);
 		if (debug > 1) {
 			int i;
-			if (pBlock)
-				for (i = 0; i < Chunk; i++)
-					printk(KERN_CONT " %02x", pBlock[i]);
-			printk(KERN_CONT "\n");
+			if (p_block)
+				for (i = 0; i < chunk; i++)
+					pr_cont(" %02x", p_block[i]);
+			pr_cont("\n");
 		}
 		status = i2c_write(state, state->demod_address,
-				   &state->Chunk[0], Chunk + AdrLength);
+				   &state->chunk[0], chunk + adr_length);
 		if (status < 0) {
-			printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
-			       __func__, Address);
+			pr_err("%s: i2c write error at addr 0x%02x\n",
+			       __func__, address);
 			break;
 		}
-		pBlock += Chunk;
-		Address += (Chunk >> 1);
-		BlkSize -= Chunk;
+		p_block += chunk;
+		address += (chunk >> 1);
+		blk_size -= chunk;
 	}
 	return status;
 }
@@ -577,11 +493,11 @@
 #define DRXK_MAX_RETRIES_POWERUP 20
 #endif
 
-static int PowerUpDevice(struct drxk_state *state)
+static int power_up_device(struct drxk_state *state)
 {
 	int status;
 	u8 data = 0;
-	u16 retryCount = 0;
+	u16 retry_count = 0;
 
 	dprintk(1, "\n");
 
@@ -591,15 +507,15 @@
 			data = 0;
 			status = i2c_write(state, state->demod_address,
 					   &data, 1);
-			msleep(10);
-			retryCount++;
+			usleep_range(10000, 11000);
+			retry_count++;
 			if (status < 0)
 				continue;
 			status = i2c_read1(state, state->demod_address,
 					   &data);
 		} while (status < 0 &&
-			 (retryCount < DRXK_MAX_RETRIES_POWERUP));
-		if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
+			 (retry_count < DRXK_MAX_RETRIES_POWERUP));
+		if (status < 0 && retry_count >= DRXK_MAX_RETRIES_POWERUP)
 			goto error;
 	}
 
@@ -615,11 +531,11 @@
 	if (status < 0)
 		goto error;
 
-	state->m_currentPowerMode = DRX_POWER_UP;
+	state->m_current_power_mode = DRX_POWER_UP;
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -631,106 +547,106 @@
 	 * FIXME: most (all?) of the values bellow should be moved into
 	 * struct drxk_config, as they are probably board-specific
 	 */
-	u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
-	u32 ulVSBIfAgcOutputLevel = 0;
-	u32 ulVSBIfAgcMinLevel = 0;
-	u32 ulVSBIfAgcMaxLevel = 0x7FFF;
-	u32 ulVSBIfAgcSpeed = 3;
+	u32 ul_vsb_if_agc_mode = DRXK_AGC_CTRL_AUTO;
+	u32 ul_vsb_if_agc_output_level = 0;
+	u32 ul_vsb_if_agc_min_level = 0;
+	u32 ul_vsb_if_agc_max_level = 0x7FFF;
+	u32 ul_vsb_if_agc_speed = 3;
 
-	u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
-	u32 ulVSBRfAgcOutputLevel = 0;
-	u32 ulVSBRfAgcMinLevel = 0;
-	u32 ulVSBRfAgcMaxLevel = 0x7FFF;
-	u32 ulVSBRfAgcSpeed = 3;
-	u32 ulVSBRfAgcTop = 9500;
-	u32 ulVSBRfAgcCutOffCurrent = 4000;
+	u32 ul_vsb_rf_agc_mode = DRXK_AGC_CTRL_AUTO;
+	u32 ul_vsb_rf_agc_output_level = 0;
+	u32 ul_vsb_rf_agc_min_level = 0;
+	u32 ul_vsb_rf_agc_max_level = 0x7FFF;
+	u32 ul_vsb_rf_agc_speed = 3;
+	u32 ul_vsb_rf_agc_top = 9500;
+	u32 ul_vsb_rf_agc_cut_off_current = 4000;
 
-	u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
-	u32 ulATVIfAgcOutputLevel = 0;
-	u32 ulATVIfAgcMinLevel = 0;
-	u32 ulATVIfAgcMaxLevel = 0;
-	u32 ulATVIfAgcSpeed = 3;
+	u32 ul_atv_if_agc_mode = DRXK_AGC_CTRL_AUTO;
+	u32 ul_atv_if_agc_output_level = 0;
+	u32 ul_atv_if_agc_min_level = 0;
+	u32 ul_atv_if_agc_max_level = 0;
+	u32 ul_atv_if_agc_speed = 3;
 
-	u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
-	u32 ulATVRfAgcOutputLevel = 0;
-	u32 ulATVRfAgcMinLevel = 0;
-	u32 ulATVRfAgcMaxLevel = 0;
-	u32 ulATVRfAgcTop = 9500;
-	u32 ulATVRfAgcCutOffCurrent = 4000;
-	u32 ulATVRfAgcSpeed = 3;
+	u32 ul_atv_rf_agc_mode = DRXK_AGC_CTRL_OFF;
+	u32 ul_atv_rf_agc_output_level = 0;
+	u32 ul_atv_rf_agc_min_level = 0;
+	u32 ul_atv_rf_agc_max_level = 0;
+	u32 ul_atv_rf_agc_top = 9500;
+	u32 ul_atv_rf_agc_cut_off_current = 4000;
+	u32 ul_atv_rf_agc_speed = 3;
 
 	u32 ulQual83 = DEFAULT_MER_83;
 	u32 ulQual93 = DEFAULT_MER_93;
 
-	u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
-	u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
+	u32 ul_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
+	u32 ul_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
 
 	/* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
 	/* io_pad_cfg_mode output mode is drive always */
 	/* io_pad_cfg_drive is set to power 2 (23 mA) */
-	u32 ulGPIOCfg = 0x0113;
-	u32 ulInvertTSClock = 0;
-	u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
-	u32 ulDVBTBitrate = 50000000;
-	u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
+	u32 ul_gpio_cfg = 0x0113;
+	u32 ul_invert_ts_clock = 0;
+	u32 ul_ts_data_strength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
+	u32 ul_dvbt_bitrate = 50000000;
+	u32 ul_dvbc_bitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
 
-	u32 ulInsertRSByte = 0;
+	u32 ul_insert_rs_byte = 0;
 
-	u32 ulRfMirror = 1;
-	u32 ulPowerDown = 0;
+	u32 ul_rf_mirror = 1;
+	u32 ul_power_down = 0;
 
 	dprintk(1, "\n");
 
-	state->m_hasLNA = false;
-	state->m_hasDVBT = false;
-	state->m_hasDVBC = false;
-	state->m_hasATV = false;
-	state->m_hasOOB = false;
-	state->m_hasAudio = false;
+	state->m_has_lna = false;
+	state->m_has_dvbt = false;
+	state->m_has_dvbc = false;
+	state->m_has_atv = false;
+	state->m_has_oob = false;
+	state->m_has_audio = false;
 
-	if (!state->m_ChunkSize)
-		state->m_ChunkSize = 124;
+	if (!state->m_chunk_size)
+		state->m_chunk_size = 124;
 
-	state->m_oscClockFreq = 0;
-	state->m_smartAntInverted = false;
-	state->m_bPDownOpenBridge = false;
+	state->m_osc_clock_freq = 0;
+	state->m_smart_ant_inverted = false;
+	state->m_b_p_down_open_bridge = false;
 
 	/* real system clock frequency in kHz */
-	state->m_sysClockFreq = 151875;
+	state->m_sys_clock_freq = 151875;
 	/* Timing div, 250ns/Psys */
 	/* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
-	state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
+	state->m_hi_cfg_timing_div = ((state->m_sys_clock_freq / 1000) *
 				   HI_I2C_DELAY) / 1000;
 	/* Clipping */
-	if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
-		state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
-	state->m_HICfgWakeUpKey = (state->demod_address << 1);
+	if (state->m_hi_cfg_timing_div > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
+		state->m_hi_cfg_timing_div = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
+	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
 	/* port/bridge/power down ctrl */
-	state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
+	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
 
-	state->m_bPowerDown = (ulPowerDown != 0);
+	state->m_b_power_down = (ul_power_down != 0);
 
-	state->m_DRXK_A3_PATCH_CODE = false;
+	state->m_drxk_a3_patch_code = false;
 
 	/* Init AGC and PGA parameters */
 	/* VSB IF */
-	state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
-	state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
-	state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
-	state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
-	state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
-	state->m_vsbPgaCfg = 140;
+	state->m_vsb_if_agc_cfg.ctrl_mode = ul_vsb_if_agc_mode;
+	state->m_vsb_if_agc_cfg.output_level = ul_vsb_if_agc_output_level;
+	state->m_vsb_if_agc_cfg.min_output_level = ul_vsb_if_agc_min_level;
+	state->m_vsb_if_agc_cfg.max_output_level = ul_vsb_if_agc_max_level;
+	state->m_vsb_if_agc_cfg.speed = ul_vsb_if_agc_speed;
+	state->m_vsb_pga_cfg = 140;
 
 	/* VSB RF */
-	state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
-	state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
-	state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
-	state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
-	state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
-	state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
-	state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
-	state->m_vsbPreSawCfg.reference = 0x07;
-	state->m_vsbPreSawCfg.usePreSaw = true;
+	state->m_vsb_rf_agc_cfg.ctrl_mode = ul_vsb_rf_agc_mode;
+	state->m_vsb_rf_agc_cfg.output_level = ul_vsb_rf_agc_output_level;
+	state->m_vsb_rf_agc_cfg.min_output_level = ul_vsb_rf_agc_min_level;
+	state->m_vsb_rf_agc_cfg.max_output_level = ul_vsb_rf_agc_max_level;
+	state->m_vsb_rf_agc_cfg.speed = ul_vsb_rf_agc_speed;
+	state->m_vsb_rf_agc_cfg.top = ul_vsb_rf_agc_top;
+	state->m_vsb_rf_agc_cfg.cut_off_current = ul_vsb_rf_agc_cut_off_current;
+	state->m_vsb_pre_saw_cfg.reference = 0x07;
+	state->m_vsb_pre_saw_cfg.use_pre_saw = true;
 
 	state->m_Quality83percent = DEFAULT_MER_83;
 	state->m_Quality93percent = DEFAULT_MER_93;
@@ -740,127 +656,127 @@
 	}
 
 	/* ATV IF */
-	state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
-	state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
-	state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
-	state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
-	state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
+	state->m_atv_if_agc_cfg.ctrl_mode = ul_atv_if_agc_mode;
+	state->m_atv_if_agc_cfg.output_level = ul_atv_if_agc_output_level;
+	state->m_atv_if_agc_cfg.min_output_level = ul_atv_if_agc_min_level;
+	state->m_atv_if_agc_cfg.max_output_level = ul_atv_if_agc_max_level;
+	state->m_atv_if_agc_cfg.speed = ul_atv_if_agc_speed;
 
 	/* ATV RF */
-	state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
-	state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
-	state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
-	state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
-	state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
-	state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
-	state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
-	state->m_atvPreSawCfg.reference = 0x04;
-	state->m_atvPreSawCfg.usePreSaw = true;
+	state->m_atv_rf_agc_cfg.ctrl_mode = ul_atv_rf_agc_mode;
+	state->m_atv_rf_agc_cfg.output_level = ul_atv_rf_agc_output_level;
+	state->m_atv_rf_agc_cfg.min_output_level = ul_atv_rf_agc_min_level;
+	state->m_atv_rf_agc_cfg.max_output_level = ul_atv_rf_agc_max_level;
+	state->m_atv_rf_agc_cfg.speed = ul_atv_rf_agc_speed;
+	state->m_atv_rf_agc_cfg.top = ul_atv_rf_agc_top;
+	state->m_atv_rf_agc_cfg.cut_off_current = ul_atv_rf_agc_cut_off_current;
+	state->m_atv_pre_saw_cfg.reference = 0x04;
+	state->m_atv_pre_saw_cfg.use_pre_saw = true;
 
 
 	/* DVBT RF */
-	state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
-	state->m_dvbtRfAgcCfg.outputLevel = 0;
-	state->m_dvbtRfAgcCfg.minOutputLevel = 0;
-	state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
-	state->m_dvbtRfAgcCfg.top = 0x2100;
-	state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
-	state->m_dvbtRfAgcCfg.speed = 1;
+	state->m_dvbt_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
+	state->m_dvbt_rf_agc_cfg.output_level = 0;
+	state->m_dvbt_rf_agc_cfg.min_output_level = 0;
+	state->m_dvbt_rf_agc_cfg.max_output_level = 0xFFFF;
+	state->m_dvbt_rf_agc_cfg.top = 0x2100;
+	state->m_dvbt_rf_agc_cfg.cut_off_current = 4000;
+	state->m_dvbt_rf_agc_cfg.speed = 1;
 
 
 	/* DVBT IF */
-	state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
-	state->m_dvbtIfAgcCfg.outputLevel = 0;
-	state->m_dvbtIfAgcCfg.minOutputLevel = 0;
-	state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
-	state->m_dvbtIfAgcCfg.top = 13424;
-	state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
-	state->m_dvbtIfAgcCfg.speed = 3;
-	state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
-	state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
+	state->m_dvbt_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
+	state->m_dvbt_if_agc_cfg.output_level = 0;
+	state->m_dvbt_if_agc_cfg.min_output_level = 0;
+	state->m_dvbt_if_agc_cfg.max_output_level = 9000;
+	state->m_dvbt_if_agc_cfg.top = 13424;
+	state->m_dvbt_if_agc_cfg.cut_off_current = 0;
+	state->m_dvbt_if_agc_cfg.speed = 3;
+	state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay = 30;
+	state->m_dvbt_if_agc_cfg.ingain_tgt_max = 30000;
 	/* state->m_dvbtPgaCfg = 140; */
 
-	state->m_dvbtPreSawCfg.reference = 4;
-	state->m_dvbtPreSawCfg.usePreSaw = false;
+	state->m_dvbt_pre_saw_cfg.reference = 4;
+	state->m_dvbt_pre_saw_cfg.use_pre_saw = false;
 
 	/* QAM RF */
-	state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
-	state->m_qamRfAgcCfg.outputLevel = 0;
-	state->m_qamRfAgcCfg.minOutputLevel = 6023;
-	state->m_qamRfAgcCfg.maxOutputLevel = 27000;
-	state->m_qamRfAgcCfg.top = 0x2380;
-	state->m_qamRfAgcCfg.cutOffCurrent = 4000;
-	state->m_qamRfAgcCfg.speed = 3;
+	state->m_qam_rf_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_OFF;
+	state->m_qam_rf_agc_cfg.output_level = 0;
+	state->m_qam_rf_agc_cfg.min_output_level = 6023;
+	state->m_qam_rf_agc_cfg.max_output_level = 27000;
+	state->m_qam_rf_agc_cfg.top = 0x2380;
+	state->m_qam_rf_agc_cfg.cut_off_current = 4000;
+	state->m_qam_rf_agc_cfg.speed = 3;
 
 	/* QAM IF */
-	state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
-	state->m_qamIfAgcCfg.outputLevel = 0;
-	state->m_qamIfAgcCfg.minOutputLevel = 0;
-	state->m_qamIfAgcCfg.maxOutputLevel = 9000;
-	state->m_qamIfAgcCfg.top = 0x0511;
-	state->m_qamIfAgcCfg.cutOffCurrent = 0;
-	state->m_qamIfAgcCfg.speed = 3;
-	state->m_qamIfAgcCfg.IngainTgtMax = 5119;
-	state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
+	state->m_qam_if_agc_cfg.ctrl_mode = DRXK_AGC_CTRL_AUTO;
+	state->m_qam_if_agc_cfg.output_level = 0;
+	state->m_qam_if_agc_cfg.min_output_level = 0;
+	state->m_qam_if_agc_cfg.max_output_level = 9000;
+	state->m_qam_if_agc_cfg.top = 0x0511;
+	state->m_qam_if_agc_cfg.cut_off_current = 0;
+	state->m_qam_if_agc_cfg.speed = 3;
+	state->m_qam_if_agc_cfg.ingain_tgt_max = 5119;
+	state->m_qam_if_agc_cfg.fast_clip_ctrl_delay = 50;
 
-	state->m_qamPgaCfg = 140;
-	state->m_qamPreSawCfg.reference = 4;
-	state->m_qamPreSawCfg.usePreSaw = false;
+	state->m_qam_pga_cfg = 140;
+	state->m_qam_pre_saw_cfg.reference = 4;
+	state->m_qam_pre_saw_cfg.use_pre_saw = false;
 
-	state->m_OperationMode = OM_NONE;
-	state->m_DrxkState = DRXK_UNINITIALIZED;
+	state->m_operation_mode = OM_NONE;
+	state->m_drxk_state = DRXK_UNINITIALIZED;
 
 	/* MPEG output configuration */
-	state->m_enableMPEGOutput = true;	/* If TRUE; enable MPEG ouput */
-	state->m_insertRSByte = false;	/* If TRUE; insert RS byte */
-	state->m_invertDATA = false;	/* If TRUE; invert DATA signals */
-	state->m_invertERR = false;	/* If TRUE; invert ERR signal */
-	state->m_invertSTR = false;	/* If TRUE; invert STR signals */
-	state->m_invertVAL = false;	/* If TRUE; invert VAL signals */
-	state->m_invertCLK = (ulInvertTSClock != 0);	/* If TRUE; invert CLK signals */
+	state->m_enable_mpeg_output = true;	/* If TRUE; enable MPEG ouput */
+	state->m_insert_rs_byte = false;	/* If TRUE; insert RS byte */
+	state->m_invert_data = false;	/* If TRUE; invert DATA signals */
+	state->m_invert_err = false;	/* If TRUE; invert ERR signal */
+	state->m_invert_str = false;	/* If TRUE; invert STR signals */
+	state->m_invert_val = false;	/* If TRUE; invert VAL signals */
+	state->m_invert_clk = (ul_invert_ts_clock != 0);	/* If TRUE; invert CLK signals */
 
 	/* If TRUE; static MPEG clockrate will be used;
 	   otherwise clockrate will adapt to the bitrate of the TS */
 
-	state->m_DVBTBitrate = ulDVBTBitrate;
-	state->m_DVBCBitrate = ulDVBCBitrate;
+	state->m_dvbt_bitrate = ul_dvbt_bitrate;
+	state->m_dvbc_bitrate = ul_dvbc_bitrate;
 
-	state->m_TSDataStrength = (ulTSDataStrength & 0x07);
+	state->m_ts_data_strength = (ul_ts_data_strength & 0x07);
 
 	/* Maximum bitrate in b/s in case static clockrate is selected */
-	state->m_mpegTsStaticBitrate = 19392658;
-	state->m_disableTEIhandling = false;
+	state->m_mpeg_ts_static_bitrate = 19392658;
+	state->m_disable_te_ihandling = false;
 
-	if (ulInsertRSByte)
-		state->m_insertRSByte = true;
+	if (ul_insert_rs_byte)
+		state->m_insert_rs_byte = true;
 
-	state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
-	if (ulMpegLockTimeOut < 10000)
-		state->m_MpegLockTimeOut = ulMpegLockTimeOut;
-	state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
-	if (ulDemodLockTimeOut < 10000)
-		state->m_DemodLockTimeOut = ulDemodLockTimeOut;
+	state->m_mpeg_lock_time_out = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
+	if (ul_mpeg_lock_time_out < 10000)
+		state->m_mpeg_lock_time_out = ul_mpeg_lock_time_out;
+	state->m_demod_lock_time_out = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
+	if (ul_demod_lock_time_out < 10000)
+		state->m_demod_lock_time_out = ul_demod_lock_time_out;
 
 	/* QAM defaults */
-	state->m_Constellation = DRX_CONSTELLATION_AUTO;
-	state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
-	state->m_fecRsPlen = 204 * 8;	/* fecRsPlen  annex A */
-	state->m_fecRsPrescale = 1;
+	state->m_constellation = DRX_CONSTELLATION_AUTO;
+	state->m_qam_interleave_mode = DRXK_QAM_I12_J17;
+	state->m_fec_rs_plen = 204 * 8;	/* fecRsPlen  annex A */
+	state->m_fec_rs_prescale = 1;
 
-	state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
-	state->m_agcFastClipCtrlDelay = 0;
+	state->m_sqi_speed = DRXK_DVBT_SQI_SPEED_MEDIUM;
+	state->m_agcfast_clip_ctrl_delay = 0;
 
-	state->m_GPIOCfg = (ulGPIOCfg);
+	state->m_gpio_cfg = ul_gpio_cfg;
 
-	state->m_bPowerDown = false;
-	state->m_currentPowerMode = DRX_POWER_DOWN;
+	state->m_b_power_down = false;
+	state->m_current_power_mode = DRX_POWER_DOWN;
 
-	state->m_rfmirror = (ulRfMirror == 0);
-	state->m_IfAgcPol = false;
+	state->m_rfmirror = (ul_rf_mirror == 0);
+	state->m_if_agc_pol = false;
 	return 0;
 }
 
-static int DRXX_Open(struct drxk_state *state)
+static int drxx_open(struct drxk_state *state)
 {
 	int status = 0;
 	u32 jtag = 0;
@@ -869,7 +785,8 @@
 
 	dprintk(1, "\n");
 	/* stop lock indicator process */
-	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+	status = write16(state, SCU_RAM_GPIO__A,
+			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 	if (status < 0)
 		goto error;
 	/* Check device id */
@@ -888,14 +805,14 @@
 	status = write16(state, SIO_TOP_COMM_KEY__A, key);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int GetDeviceCapabilities(struct drxk_state *state)
+static int get_device_capabilities(struct drxk_state *state)
 {
-	u16 sioPdrOhwCfg = 0;
-	u32 sioTopJtagidLo = 0;
+	u16 sio_pdr_ohw_cfg = 0;
+	u32 sio_top_jtagid_lo = 0;
 	int status;
 	const char *spin = "";
 
@@ -903,197 +820,196 @@
 
 	/* driver 0.9.0 */
 	/* stop lock indicator process */
-	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+	status = write16(state, SCU_RAM_GPIO__A,
+			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 	if (status < 0)
 		goto error;
 	status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
 	if (status < 0)
 		goto error;
-	status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
+	status = read16(state, SIO_PDR_OHW_CFG__A, &sio_pdr_ohw_cfg);
 	if (status < 0)
 		goto error;
 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
 	if (status < 0)
 		goto error;
 
-	switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
+	switch ((sio_pdr_ohw_cfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
 	case 0:
 		/* ignore (bypass ?) */
 		break;
 	case 1:
 		/* 27 MHz */
-		state->m_oscClockFreq = 27000;
+		state->m_osc_clock_freq = 27000;
 		break;
 	case 2:
 		/* 20.25 MHz */
-		state->m_oscClockFreq = 20250;
+		state->m_osc_clock_freq = 20250;
 		break;
 	case 3:
 		/* 4 MHz */
-		state->m_oscClockFreq = 20250;
+		state->m_osc_clock_freq = 20250;
 		break;
 	default:
-		printk(KERN_ERR "drxk: Clock Frequency is unknown\n");
+		pr_err("Clock Frequency is unknown\n");
 		return -EINVAL;
 	}
 	/*
 		Determine device capabilities
 		Based on pinning v14
 		*/
-	status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
+	status = read32(state, SIO_TOP_JTAGID_LO__A, &sio_top_jtagid_lo);
 	if (status < 0)
 		goto error;
 
-	printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo);
+	pr_info("status = 0x%08x\n", sio_top_jtagid_lo);
 
 	/* driver 0.9.0 */
-	switch ((sioTopJtagidLo >> 29) & 0xF) {
+	switch ((sio_top_jtagid_lo >> 29) & 0xF) {
 	case 0:
-		state->m_deviceSpin = DRXK_SPIN_A1;
+		state->m_device_spin = DRXK_SPIN_A1;
 		spin = "A1";
 		break;
 	case 2:
-		state->m_deviceSpin = DRXK_SPIN_A2;
+		state->m_device_spin = DRXK_SPIN_A2;
 		spin = "A2";
 		break;
 	case 3:
-		state->m_deviceSpin = DRXK_SPIN_A3;
+		state->m_device_spin = DRXK_SPIN_A3;
 		spin = "A3";
 		break;
 	default:
-		state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
+		state->m_device_spin = DRXK_SPIN_UNKNOWN;
 		status = -EINVAL;
-		printk(KERN_ERR "drxk: Spin %d unknown\n",
-		       (sioTopJtagidLo >> 29) & 0xF);
+		pr_err("Spin %d unknown\n", (sio_top_jtagid_lo >> 29) & 0xF);
 		goto error2;
 	}
-	switch ((sioTopJtagidLo >> 12) & 0xFF) {
+	switch ((sio_top_jtagid_lo >> 12) & 0xFF) {
 	case 0x13:
 		/* typeId = DRX3913K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = false;
-		state->m_hasAudio = false;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = true;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = false;
-		state->m_hasGPIO1 = false;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = false;
+		state->m_has_audio = false;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = true;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = false;
+		state->m_has_gpio1 = false;
+		state->m_has_irqn = false;
 		break;
 	case 0x15:
 		/* typeId = DRX3915K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = false;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = false;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = false;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = false;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x16:
 		/* typeId = DRX3916K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = false;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = false;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = false;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = false;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x18:
 		/* typeId = DRX3918K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = true;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = false;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = true;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = false;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x21:
 		/* typeId = DRX3921K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = true;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = true;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = true;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = true;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x23:
 		/* typeId = DRX3923K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = true;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = true;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = true;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = true;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x25:
 		/* typeId = DRX3925K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = true;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = true;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = true;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = true;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	case 0x26:
 		/* typeId = DRX3926K_TYPE_ID */
-		state->m_hasLNA = false;
-		state->m_hasOOB = false;
-		state->m_hasATV = true;
-		state->m_hasAudio = false;
-		state->m_hasDVBT = true;
-		state->m_hasDVBC = true;
-		state->m_hasSAWSW = true;
-		state->m_hasGPIO2 = true;
-		state->m_hasGPIO1 = true;
-		state->m_hasIRQN = false;
+		state->m_has_lna = false;
+		state->m_has_oob = false;
+		state->m_has_atv = true;
+		state->m_has_audio = false;
+		state->m_has_dvbt = true;
+		state->m_has_dvbc = true;
+		state->m_has_sawsw = true;
+		state->m_has_gpio2 = true;
+		state->m_has_gpio1 = true;
+		state->m_has_irqn = false;
 		break;
 	default:
-		printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
-			((sioTopJtagidLo >> 12) & 0xFF));
+		pr_err("DeviceID 0x%02x not supported\n",
+			((sio_top_jtagid_lo >> 12) & 0xFF));
 		status = -EINVAL;
 		goto error2;
 	}
 
-	printk(KERN_INFO
-	       "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
-	       ((sioTopJtagidLo >> 12) & 0xFF), spin,
-	       state->m_oscClockFreq / 1000,
-	       state->m_oscClockFreq % 1000);
+	pr_info("detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
+	       ((sio_top_jtagid_lo >> 12) & 0xFF), spin,
+	       state->m_osc_clock_freq / 1000,
+	       state->m_osc_clock_freq % 1000);
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 error2:
 	return status;
 }
 
-static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
+static int hi_command(struct drxk_state *state, u16 cmd, u16 *p_result)
 {
 	int status;
 	bool powerdown_cmd;
@@ -1105,37 +1021,37 @@
 	if (status < 0)
 		goto error;
 	if (cmd == SIO_HI_RA_RAM_CMD_RESET)
-		msleep(1);
+		usleep_range(1000, 2000);
 
 	powerdown_cmd =
 	    (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
-		    ((state->m_HICfgCtrl) &
+		    ((state->m_hi_cfg_ctrl) &
 		     SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
 		    SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
 	if (powerdown_cmd == false) {
 		/* Wait until command rdy */
-		u32 retryCount = 0;
-		u16 waitCmd;
+		u32 retry_count = 0;
+		u16 wait_cmd;
 
 		do {
-			msleep(1);
-			retryCount += 1;
+			usleep_range(1000, 2000);
+			retry_count += 1;
 			status = read16(state, SIO_HI_RA_RAM_CMD__A,
-					  &waitCmd);
-		} while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
-			 && (waitCmd != 0));
+					  &wait_cmd);
+		} while ((status < 0) && (retry_count < DRXK_MAX_RETRIES)
+			 && (wait_cmd != 0));
 		if (status < 0)
 			goto error;
-		status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
+		status = read16(state, SIO_HI_RA_RAM_RES__A, p_result);
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
-static int HI_CfgCommand(struct drxk_state *state)
+static int hi_cfg_command(struct drxk_state *state)
 {
 	int status;
 
@@ -1143,61 +1059,68 @@
 
 	mutex_lock(&state->mutex);
 
-	status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
+	status = write16(state, SIO_HI_RA_RAM_PAR_6__A,
+			 state->m_hi_cfg_timeout);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
+	status = write16(state, SIO_HI_RA_RAM_PAR_5__A,
+			 state->m_hi_cfg_ctrl);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
+	status = write16(state, SIO_HI_RA_RAM_PAR_4__A,
+			 state->m_hi_cfg_wake_up_key);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
+	status = write16(state, SIO_HI_RA_RAM_PAR_3__A,
+			 state->m_hi_cfg_bridge_delay);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
+	status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
+			 state->m_hi_cfg_timing_div);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
+	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
+			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
 	if (status < 0)
 		goto error;
-	status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
+	status = hi_command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
 	if (status < 0)
 		goto error;
 
-	state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
+	state->m_hi_cfg_ctrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
 error:
 	mutex_unlock(&state->mutex);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int InitHI(struct drxk_state *state)
+static int init_hi(struct drxk_state *state)
 {
 	dprintk(1, "\n");
 
-	state->m_HICfgWakeUpKey = (state->demod_address << 1);
-	state->m_HICfgTimeout = 0x96FF;
+	state->m_hi_cfg_wake_up_key = (state->demod_address << 1);
+	state->m_hi_cfg_timeout = 0x96FF;
 	/* port/bridge/power down ctrl */
-	state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
+	state->m_hi_cfg_ctrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
 
-	return HI_CfgCommand(state);
+	return hi_cfg_command(state);
 }
 
-static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
+static int mpegts_configure_pins(struct drxk_state *state, bool mpeg_enable)
 {
 	int status = -1;
-	u16 sioPdrMclkCfg = 0;
-	u16 sioPdrMdxCfg = 0;
+	u16 sio_pdr_mclk_cfg = 0;
+	u16 sio_pdr_mdx_cfg = 0;
 	u16 err_cfg = 0;
 
 	dprintk(1, ": mpeg %s, %s mode\n",
-		mpegEnable ? "enable" : "disable",
-		state->m_enableParallel ? "parallel" : "serial");
+		mpeg_enable ? "enable" : "disable",
+		state->m_enable_parallel ? "parallel" : "serial");
 
 	/* stop lock indicator process */
-	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+	status = write16(state, SCU_RAM_GPIO__A,
+			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 	if (status < 0)
 		goto error;
 
@@ -1206,7 +1129,7 @@
 	if (status < 0)
 		goto error;
 
-	if (mpegEnable == false) {
+	if (mpeg_enable == false) {
 		/*  Set MPEG TS pads to inputmode */
 		status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
 		if (status < 0)
@@ -1246,19 +1169,19 @@
 			goto error;
 	} else {
 		/* Enable MPEG output */
-		sioPdrMdxCfg =
-			((state->m_TSDataStrength <<
+		sio_pdr_mdx_cfg =
+			((state->m_ts_data_strength <<
 			SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
-		sioPdrMclkCfg = ((state->m_TSClockkStrength <<
+		sio_pdr_mclk_cfg = ((state->m_ts_clockk_strength <<
 					SIO_PDR_MCLK_CFG_DRIVE__B) |
 					0x0003);
 
-		status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
+		status = write16(state, SIO_PDR_MSTRT_CFG__A, sio_pdr_mdx_cfg);
 		if (status < 0)
 			goto error;
 
 		if (state->enable_merr_cfg)
-			err_cfg = sioPdrMdxCfg;
+			err_cfg = sio_pdr_mdx_cfg;
 
 		status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
 		if (status < 0)
@@ -1267,31 +1190,38 @@
 		if (status < 0)
 			goto error;
 
-		if (state->m_enableParallel == true) {
+		if (state->m_enable_parallel == true) {
 			/* paralel -> enable MD1 to MD7 */
-			status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD1_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD2_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD3_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD4_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD5_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD6_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
-			status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
+			status = write16(state, SIO_PDR_MD7_CFG__A,
+					 sio_pdr_mdx_cfg);
 			if (status < 0)
 				goto error;
 		} else {
-			sioPdrMdxCfg = ((state->m_TSDataStrength <<
+			sio_pdr_mdx_cfg = ((state->m_ts_data_strength <<
 						SIO_PDR_MD0_CFG_DRIVE__B)
 					| 0x0003);
 			/* serial -> disable MD1 to MD7 */
@@ -1317,10 +1247,10 @@
 			if (status < 0)
 				goto error;
 		}
-		status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
+		status = write16(state, SIO_PDR_MCLK_CFG__A, sio_pdr_mclk_cfg);
 		if (status < 0)
 			goto error;
-		status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
+		status = write16(state, SIO_PDR_MD0_CFG__A, sio_pdr_mdx_cfg);
 		if (status < 0)
 			goto error;
 	}
@@ -1332,21 +1262,21 @@
 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int MPEGTSDisable(struct drxk_state *state)
+static int mpegts_disable(struct drxk_state *state)
 {
 	dprintk(1, "\n");
 
-	return MPEGTSConfigurePins(state, false);
+	return mpegts_configure_pins(state, false);
 }
 
-static int BLChainCmd(struct drxk_state *state,
-		      u16 romOffset, u16 nrOfElements, u32 timeOut)
+static int bl_chain_cmd(struct drxk_state *state,
+		      u16 rom_offset, u16 nr_of_elements, u32 time_out)
 {
-	u16 blStatus = 0;
+	u16 bl_status = 0;
 	int status;
 	unsigned long end;
 
@@ -1355,46 +1285,46 @@
 	status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
+	status = write16(state, SIO_BL_CHAIN_ADDR__A, rom_offset);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
+	status = write16(state, SIO_BL_CHAIN_LEN__A, nr_of_elements);
 	if (status < 0)
 		goto error;
 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
 	if (status < 0)
 		goto error;
 
-	end = jiffies + msecs_to_jiffies(timeOut);
+	end = jiffies + msecs_to_jiffies(time_out);
 	do {
-		msleep(1);
-		status = read16(state, SIO_BL_STATUS__A, &blStatus);
+		usleep_range(1000, 2000);
+		status = read16(state, SIO_BL_STATUS__A, &bl_status);
 		if (status < 0)
 			goto error;
-	} while ((blStatus == 0x1) &&
+	} while ((bl_status == 0x1) &&
 			((time_is_after_jiffies(end))));
 
-	if (blStatus == 0x1) {
-		printk(KERN_ERR "drxk: SIO not ready\n");
+	if (bl_status == 0x1) {
+		pr_err("SIO not ready\n");
 		status = -EINVAL;
 		goto error2;
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 error2:
 	mutex_unlock(&state->mutex);
 	return status;
 }
 
 
-static int DownloadMicrocode(struct drxk_state *state,
-			     const u8 pMCImage[], u32 Length)
+static int download_microcode(struct drxk_state *state,
+			     const u8 p_mc_image[], u32 length)
 {
-	const u8 *pSrc = pMCImage;
-	u32 Address;
-	u16 nBlocks;
-	u16 BlockSize;
+	const u8 *p_src = p_mc_image;
+	u32 address;
+	u16 n_blocks;
+	u16 block_size;
 	u32 offset = 0;
 	u32 i;
 	int status = 0;
@@ -1404,130 +1334,131 @@
 	/* down the drain (we don't care about MAGIC_WORD) */
 #if 0
 	/* For future reference */
-	Drain = (pSrc[0] << 8) | pSrc[1];
+	drain = (p_src[0] << 8) | p_src[1];
 #endif
-	pSrc += sizeof(u16);
+	p_src += sizeof(u16);
 	offset += sizeof(u16);
-	nBlocks = (pSrc[0] << 8) | pSrc[1];
-	pSrc += sizeof(u16);
+	n_blocks = (p_src[0] << 8) | p_src[1];
+	p_src += sizeof(u16);
 	offset += sizeof(u16);
 
-	for (i = 0; i < nBlocks; i += 1) {
-		Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
-		    (pSrc[2] << 8) | pSrc[3];
-		pSrc += sizeof(u32);
+	for (i = 0; i < n_blocks; i += 1) {
+		address = (p_src[0] << 24) | (p_src[1] << 16) |
+		    (p_src[2] << 8) | p_src[3];
+		p_src += sizeof(u32);
 		offset += sizeof(u32);
 
-		BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
-		pSrc += sizeof(u16);
+		block_size = ((p_src[0] << 8) | p_src[1]) * sizeof(u16);
+		p_src += sizeof(u16);
 		offset += sizeof(u16);
 
 #if 0
 		/* For future reference */
-		Flags = (pSrc[0] << 8) | pSrc[1];
+		flags = (p_src[0] << 8) | p_src[1];
 #endif
-		pSrc += sizeof(u16);
+		p_src += sizeof(u16);
 		offset += sizeof(u16);
 
 #if 0
 		/* For future reference */
-		BlockCRC = (pSrc[0] << 8) | pSrc[1];
+		block_crc = (p_src[0] << 8) | p_src[1];
 #endif
-		pSrc += sizeof(u16);
+		p_src += sizeof(u16);
 		offset += sizeof(u16);
 
-		if (offset + BlockSize > Length) {
-			printk(KERN_ERR "drxk: Firmware is corrupted.\n");
+		if (offset + block_size > length) {
+			pr_err("Firmware is corrupted.\n");
 			return -EINVAL;
 		}
 
-		status = write_block(state, Address, BlockSize, pSrc);
+		status = write_block(state, address, block_size, p_src);
 		if (status < 0) {
-			printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
+			pr_err("Error %d while loading firmware\n", status);
 			break;
 		}
-		pSrc += BlockSize;
-		offset += BlockSize;
+		p_src += block_size;
+		offset += block_size;
 	}
 	return status;
 }
 
-static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
+static int dvbt_enable_ofdm_token_ring(struct drxk_state *state, bool enable)
 {
 	int status;
 	u16 data = 0;
-	u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
-	u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
+	u16 desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
+	u16 desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
 	unsigned long end;
 
 	dprintk(1, "\n");
 
 	if (enable == false) {
-		desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
-		desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
+		desired_ctrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
+		desired_status = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
 	}
 
 	status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
-	if (status >= 0 && data == desiredStatus) {
+	if (status >= 0 && data == desired_status) {
 		/* tokenring already has correct status */
 		return status;
 	}
 	/* Disable/enable dvbt tokenring bridge   */
-	status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
+	status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desired_ctrl);
 
 	end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
 	do {
 		status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
-		if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
+		if ((status >= 0 && data == desired_status)
+		    || time_is_after_jiffies(end))
 			break;
-		msleep(1);
+		usleep_range(1000, 2000);
 	} while (1);
-	if (data != desiredStatus) {
-		printk(KERN_ERR "drxk: SIO not ready\n");
+	if (data != desired_status) {
+		pr_err("SIO not ready\n");
 		return -EINVAL;
 	}
 	return status;
 }
 
-static int MPEGTSStop(struct drxk_state *state)
+static int mpegts_stop(struct drxk_state *state)
 {
 	int status = 0;
-	u16 fecOcSncMode = 0;
-	u16 fecOcIprMode = 0;
+	u16 fec_oc_snc_mode = 0;
+	u16 fec_oc_ipr_mode = 0;
 
 	dprintk(1, "\n");
 
 	/* Gracefull shutdown (byte boundaries) */
-	status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
+	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
 	if (status < 0)
 		goto error;
-	fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
-	status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
+	fec_oc_snc_mode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
+	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
 	if (status < 0)
 		goto error;
 
 	/* Suppress MCLK during absence of data */
-	status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
+	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_ipr_mode);
 	if (status < 0)
 		goto error;
-	fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
-	status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
+	fec_oc_ipr_mode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
+	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_ipr_mode);
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
 static int scu_command(struct drxk_state *state,
-		       u16 cmd, u8 parameterLen,
-		       u16 *parameter, u8 resultLen, u16 *result)
+		       u16 cmd, u8 parameter_len,
+		       u16 *parameter, u8 result_len, u16 *result)
 {
 #if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
 #error DRXK register mapping no longer compatible with this routine!
 #endif
-	u16 curCmd = 0;
+	u16 cur_cmd = 0;
 	int status = -EINVAL;
 	unsigned long end;
 	u8 buffer[34];
@@ -1537,9 +1468,9 @@
 
 	dprintk(1, "\n");
 
-	if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
-	    ((resultLen > 0) && (result == NULL))) {
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+	if ((cmd == 0) || ((parameter_len > 0) && (parameter == NULL)) ||
+	    ((result_len > 0) && (result == NULL))) {
+		pr_err("Error %d on %s\n", status, __func__);
 		return status;
 	}
 
@@ -1547,7 +1478,7 @@
 
 	/* assume that the command register is ready
 		since it is checked afterwards */
-	for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
+	for (ii = parameter_len - 1; ii >= 0; ii -= 1) {
 		buffer[cnt++] = (parameter[ii] & 0xFF);
 		buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
 	}
@@ -1555,27 +1486,28 @@
 	buffer[cnt++] = ((cmd >> 8) & 0xFF);
 
 	write_block(state, SCU_RAM_PARAM_0__A -
-			(parameterLen - 1), cnt, buffer);
+			(parameter_len - 1), cnt, buffer);
 	/* Wait until SCU has processed command */
 	end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
 	do {
-		msleep(1);
-		status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
+		usleep_range(1000, 2000);
+		status = read16(state, SCU_RAM_COMMAND__A, &cur_cmd);
 		if (status < 0)
 			goto error;
-	} while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
-	if (curCmd != DRX_SCU_READY) {
-		printk(KERN_ERR "drxk: SCU not ready\n");
+	} while (!(cur_cmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
+	if (cur_cmd != DRX_SCU_READY) {
+		pr_err("SCU not ready\n");
 		status = -EIO;
 		goto error2;
 	}
 	/* read results */
-	if ((resultLen > 0) && (result != NULL)) {
+	if ((result_len > 0) && (result != NULL)) {
 		s16 err;
 		int ii;
 
-		for (ii = resultLen - 1; ii >= 0; ii -= 1) {
-			status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
+		for (ii = result_len - 1; ii >= 0; ii -= 1) {
+			status = read16(state, SCU_RAM_PARAM_0__A - ii,
+					&result[ii]);
 			if (status < 0)
 				goto error;
 		}
@@ -1603,7 +1535,7 @@
 			sprintf(errname, "ERROR: %d\n", err);
 			p = errname;
 		}
-		printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
+		pr_err("%s while sending cmd 0x%04x with params:", p, cmd);
 		print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
 		status = -EINVAL;
 		goto error2;
@@ -1611,13 +1543,13 @@
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 error2:
 	mutex_unlock(&state->mutex);
 	return status;
 }
 
-static int SetIqmAf(struct drxk_state *state, bool active)
+static int set_iqm_af(struct drxk_state *state, bool active)
 {
 	u16 data = 0;
 	int status;
@@ -1647,14 +1579,14 @@
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
+static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode)
 {
 	int status = 0;
-	u16 sioCcPwdMode = 0;
+	u16 sio_cc_pwd_mode = 0;
 
 	dprintk(1, "\n");
 
@@ -1664,19 +1596,19 @@
 
 	switch (*mode) {
 	case DRX_POWER_UP:
-		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
+		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_NONE;
 		break;
 	case DRXK_POWER_DOWN_OFDM:
-		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
+		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OFDM;
 		break;
 	case DRXK_POWER_DOWN_CORE:
-		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
+		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
 		break;
 	case DRXK_POWER_DOWN_PLL:
-		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
+		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_PLL;
 		break;
 	case DRX_POWER_DOWN:
-		sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
+		sio_cc_pwd_mode = SIO_CC_PWD_MODE_LEVEL_OSC;
 		break;
 	default:
 		/* Unknow sleep mode */
@@ -1684,15 +1616,15 @@
 	}
 
 	/* If already in requested power mode, do nothing */
-	if (state->m_currentPowerMode == *mode)
+	if (state->m_current_power_mode == *mode)
 		return 0;
 
 	/* For next steps make sure to start from DRX_POWER_UP mode */
-	if (state->m_currentPowerMode != DRX_POWER_UP) {
-		status = PowerUpDevice(state);
+	if (state->m_current_power_mode != DRX_POWER_UP) {
+		status = power_up_device(state);
 		if (status < 0)
 			goto error;
-		status = DVBTEnableOFDMTokenRing(state, true);
+		status = dvbt_enable_ofdm_token_ring(state, true);
 		if (status < 0)
 			goto error;
 	}
@@ -1709,31 +1641,31 @@
 		/* Power down device */
 		/* stop all comm_exec */
 		/* Stop and power down previous standard */
-		switch (state->m_OperationMode) {
+		switch (state->m_operation_mode) {
 		case OM_DVBT:
-			status = MPEGTSStop(state);
+			status = mpegts_stop(state);
 			if (status < 0)
 				goto error;
-			status = PowerDownDVBT(state, false);
+			status = power_down_dvbt(state, false);
 			if (status < 0)
 				goto error;
 			break;
 		case OM_QAM_ITU_A:
 		case OM_QAM_ITU_C:
-			status = MPEGTSStop(state);
+			status = mpegts_stop(state);
 			if (status < 0)
 				goto error;
-			status = PowerDownQAM(state);
+			status = power_down_qam(state);
 			if (status < 0)
 				goto error;
 			break;
 		default:
 			break;
 		}
-		status = DVBTEnableOFDMTokenRing(state, false);
+		status = dvbt_enable_ofdm_token_ring(state, false);
 		if (status < 0)
 			goto error;
-		status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
+		status = write16(state, SIO_CC_PWD_MODE__A, sio_cc_pwd_mode);
 		if (status < 0)
 			goto error;
 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
@@ -1741,26 +1673,26 @@
 			goto error;
 
 		if (*mode != DRXK_POWER_DOWN_OFDM) {
-			state->m_HICfgCtrl |=
+			state->m_hi_cfg_ctrl |=
 				SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
-			status = HI_CfgCommand(state);
+			status = hi_cfg_command(state);
 			if (status < 0)
 				goto error;
 		}
 	}
-	state->m_currentPowerMode = *mode;
+	state->m_current_power_mode = *mode;
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
-static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
+static int power_down_dvbt(struct drxk_state *state, bool set_power_mode)
 {
-	enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
-	u16 cmdResult = 0;
+	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
+	u16 cmd_result = 0;
 	u16 data = 0;
 	int status;
 
@@ -1771,11 +1703,17 @@
 		goto error;
 	if (data == SCU_COMM_EXEC_ACTIVE) {
 		/* Send OFDM stop command */
-		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+		status = scu_command(state,
+				     SCU_RAM_COMMAND_STANDARD_OFDM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
+				     0, NULL, 1, &cmd_result);
 		if (status < 0)
 			goto error;
 		/* Send OFDM reset command */
-		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+		status = scu_command(state,
+				     SCU_RAM_COMMAND_STANDARD_OFDM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
+				     0, NULL, 1, &cmd_result);
 		if (status < 0)
 			goto error;
 	}
@@ -1792,24 +1730,24 @@
 		goto error;
 
 	/* powerdown AFE                   */
-	status = SetIqmAf(state, false);
+	status = set_iqm_af(state, false);
 	if (status < 0)
 		goto error;
 
 	/* powerdown to OFDM mode          */
-	if (setPowerMode) {
-		status = CtrlPowerMode(state, &powerMode);
+	if (set_power_mode) {
+		status = ctrl_power_mode(state, &power_mode);
 		if (status < 0)
 			goto error;
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetOperationMode(struct drxk_state *state,
-			    enum OperationMode oMode)
+static int setoperation_mode(struct drxk_state *state,
+			    enum operation_mode o_mode)
 {
 	int status = 0;
 
@@ -1821,36 +1759,37 @@
 	 */
 
 	/* disable HW lock indicator */
-	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+	status = write16(state, SCU_RAM_GPIO__A,
+			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 	if (status < 0)
 		goto error;
 
 	/* Device is already at the required mode */
-	if (state->m_OperationMode == oMode)
+	if (state->m_operation_mode == o_mode)
 		return 0;
 
-	switch (state->m_OperationMode) {
+	switch (state->m_operation_mode) {
 		/* OM_NONE was added for start up */
 	case OM_NONE:
 		break;
 	case OM_DVBT:
-		status = MPEGTSStop(state);
+		status = mpegts_stop(state);
 		if (status < 0)
 			goto error;
-		status = PowerDownDVBT(state, true);
+		status = power_down_dvbt(state, true);
 		if (status < 0)
 			goto error;
-		state->m_OperationMode = OM_NONE;
+		state->m_operation_mode = OM_NONE;
 		break;
 	case OM_QAM_ITU_A:	/* fallthrough */
 	case OM_QAM_ITU_C:
-		status = MPEGTSStop(state);
+		status = mpegts_stop(state);
 		if (status < 0)
 			goto error;
-		status = PowerDownQAM(state);
+		status = power_down_qam(state);
 		if (status < 0)
 			goto error;
-		state->m_OperationMode = OM_NONE;
+		state->m_operation_mode = OM_NONE;
 		break;
 	case OM_QAM_ITU_B:
 	default:
@@ -1861,20 +1800,20 @@
 	/*
 		Power up new standard
 		*/
-	switch (oMode) {
+	switch (o_mode) {
 	case OM_DVBT:
 		dprintk(1, ": DVB-T\n");
-		state->m_OperationMode = oMode;
-		status = SetDVBTStandard(state, oMode);
+		state->m_operation_mode = o_mode;
+		status = set_dvbt_standard(state, o_mode);
 		if (status < 0)
 			goto error;
 		break;
 	case OM_QAM_ITU_A:	/* fallthrough */
 	case OM_QAM_ITU_C:
 		dprintk(1, ": DVB-C Annex %c\n",
-			(state->m_OperationMode == OM_QAM_ITU_A) ? 'A' : 'C');
-		state->m_OperationMode = oMode;
-		status = SetQAMStandard(state, oMode);
+			(state->m_operation_mode == OM_QAM_ITU_A) ? 'A' : 'C');
+		state->m_operation_mode = o_mode;
+		status = set_qam_standard(state, o_mode);
 		if (status < 0)
 			goto error;
 		break;
@@ -1884,121 +1823,121 @@
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int Start(struct drxk_state *state, s32 offsetFreq,
-		 s32 IntermediateFrequency)
+static int start(struct drxk_state *state, s32 offset_freq,
+		 s32 intermediate_frequency)
 {
 	int status = -EINVAL;
 
-	u16 IFreqkHz;
-	s32 OffsetkHz = offsetFreq / 1000;
+	u16 i_freqk_hz;
+	s32 offsetk_hz = offset_freq / 1000;
 
 	dprintk(1, "\n");
-	if (state->m_DrxkState != DRXK_STOPPED &&
-		state->m_DrxkState != DRXK_DTV_STARTED)
+	if (state->m_drxk_state != DRXK_STOPPED &&
+		state->m_drxk_state != DRXK_DTV_STARTED)
 		goto error;
 
-	state->m_bMirrorFreqSpect = (state->props.inversion == INVERSION_ON);
+	state->m_b_mirror_freq_spect = (state->props.inversion == INVERSION_ON);
 
-	if (IntermediateFrequency < 0) {
-		state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
-		IntermediateFrequency = -IntermediateFrequency;
+	if (intermediate_frequency < 0) {
+		state->m_b_mirror_freq_spect = !state->m_b_mirror_freq_spect;
+		intermediate_frequency = -intermediate_frequency;
 	}
 
-	switch (state->m_OperationMode) {
+	switch (state->m_operation_mode) {
 	case OM_QAM_ITU_A:
 	case OM_QAM_ITU_C:
-		IFreqkHz = (IntermediateFrequency / 1000);
-		status = SetQAM(state, IFreqkHz, OffsetkHz);
+		i_freqk_hz = (intermediate_frequency / 1000);
+		status = set_qam(state, i_freqk_hz, offsetk_hz);
 		if (status < 0)
 			goto error;
-		state->m_DrxkState = DRXK_DTV_STARTED;
+		state->m_drxk_state = DRXK_DTV_STARTED;
 		break;
 	case OM_DVBT:
-		IFreqkHz = (IntermediateFrequency / 1000);
-		status = MPEGTSStop(state);
+		i_freqk_hz = (intermediate_frequency / 1000);
+		status = mpegts_stop(state);
 		if (status < 0)
 			goto error;
-		status = SetDVBT(state, IFreqkHz, OffsetkHz);
+		status = set_dvbt(state, i_freqk_hz, offsetk_hz);
 		if (status < 0)
 			goto error;
-		status = DVBTStart(state);
+		status = dvbt_start(state);
 		if (status < 0)
 			goto error;
-		state->m_DrxkState = DRXK_DTV_STARTED;
+		state->m_drxk_state = DRXK_DTV_STARTED;
 		break;
 	default:
 		break;
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int ShutDown(struct drxk_state *state)
+static int shut_down(struct drxk_state *state)
 {
 	dprintk(1, "\n");
 
-	MPEGTSStop(state);
+	mpegts_stop(state);
 	return 0;
 }
 
-static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus)
+static int get_lock_status(struct drxk_state *state, u32 *p_lock_status)
 {
 	int status = -EINVAL;
 
 	dprintk(1, "\n");
 
-	if (pLockStatus == NULL)
+	if (p_lock_status == NULL)
 		goto error;
 
-	*pLockStatus = NOT_LOCKED;
+	*p_lock_status = NOT_LOCKED;
 
 	/* define the SCU command code */
-	switch (state->m_OperationMode) {
+	switch (state->m_operation_mode) {
 	case OM_QAM_ITU_A:
 	case OM_QAM_ITU_B:
 	case OM_QAM_ITU_C:
-		status = GetQAMLockStatus(state, pLockStatus);
+		status = get_qam_lock_status(state, p_lock_status);
 		break;
 	case OM_DVBT:
-		status = GetDVBTLockStatus(state, pLockStatus);
+		status = get_dvbt_lock_status(state, p_lock_status);
 		break;
 	default:
 		break;
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int MPEGTSStart(struct drxk_state *state)
+static int mpegts_start(struct drxk_state *state)
 {
 	int status;
 
-	u16 fecOcSncMode = 0;
+	u16 fec_oc_snc_mode = 0;
 
 	/* Allow OC to sync again */
-	status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
+	status = read16(state, FEC_OC_SNC_MODE__A, &fec_oc_snc_mode);
 	if (status < 0)
 		goto error;
-	fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
-	status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
+	fec_oc_snc_mode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
+	status = write16(state, FEC_OC_SNC_MODE__A, fec_oc_snc_mode);
 	if (status < 0)
 		goto error;
 	status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int MPEGTSDtoInit(struct drxk_state *state)
+static int mpegts_dto_init(struct drxk_state *state)
 {
 	int status;
 
@@ -2040,68 +1979,68 @@
 	status = write16(state, FEC_OC_SNC_HWM__A, 12);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
-static int MPEGTSDtoSetup(struct drxk_state *state,
-			  enum OperationMode oMode)
+static int mpegts_dto_setup(struct drxk_state *state,
+			  enum operation_mode o_mode)
 {
 	int status;
 
-	u16 fecOcRegMode = 0;	/* FEC_OC_MODE       register value */
-	u16 fecOcRegIprMode = 0;	/* FEC_OC_IPR_MODE   register value */
-	u16 fecOcDtoMode = 0;	/* FEC_OC_IPR_INVERT register value */
-	u16 fecOcFctMode = 0;	/* FEC_OC_IPR_INVERT register value */
-	u16 fecOcDtoPeriod = 2;	/* FEC_OC_IPR_INVERT register value */
-	u16 fecOcDtoBurstLen = 188;	/* FEC_OC_IPR_INVERT register value */
-	u32 fecOcRcnCtlRate = 0;	/* FEC_OC_IPR_INVERT register value */
-	u16 fecOcTmdMode = 0;
-	u16 fecOcTmdIntUpdRate = 0;
-	u32 maxBitRate = 0;
-	bool staticCLK = false;
+	u16 fec_oc_reg_mode = 0;	/* FEC_OC_MODE       register value */
+	u16 fec_oc_reg_ipr_mode = 0;	/* FEC_OC_IPR_MODE   register value */
+	u16 fec_oc_dto_mode = 0;	/* FEC_OC_IPR_INVERT register value */
+	u16 fec_oc_fct_mode = 0;	/* FEC_OC_IPR_INVERT register value */
+	u16 fec_oc_dto_period = 2;	/* FEC_OC_IPR_INVERT register value */
+	u16 fec_oc_dto_burst_len = 188;	/* FEC_OC_IPR_INVERT register value */
+	u32 fec_oc_rcn_ctl_rate = 0;	/* FEC_OC_IPR_INVERT register value */
+	u16 fec_oc_tmd_mode = 0;
+	u16 fec_oc_tmd_int_upd_rate = 0;
+	u32 max_bit_rate = 0;
+	bool static_clk = false;
 
 	dprintk(1, "\n");
 
 	/* Check insertion of the Reed-Solomon parity bytes */
-	status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
+	status = read16(state, FEC_OC_MODE__A, &fec_oc_reg_mode);
 	if (status < 0)
 		goto error;
-	status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
+	status = read16(state, FEC_OC_IPR_MODE__A, &fec_oc_reg_ipr_mode);
 	if (status < 0)
 		goto error;
-	fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
-	fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
-	if (state->m_insertRSByte == true) {
+	fec_oc_reg_mode &= (~FEC_OC_MODE_PARITY__M);
+	fec_oc_reg_ipr_mode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
+	if (state->m_insert_rs_byte == true) {
 		/* enable parity symbol forward */
-		fecOcRegMode |= FEC_OC_MODE_PARITY__M;
+		fec_oc_reg_mode |= FEC_OC_MODE_PARITY__M;
 		/* MVAL disable during parity bytes */
-		fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
+		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
 		/* TS burst length to 204 */
-		fecOcDtoBurstLen = 204;
+		fec_oc_dto_burst_len = 204;
 	}
 
 	/* Check serial or parrallel output */
-	fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
-	if (state->m_enableParallel == false) {
+	fec_oc_reg_ipr_mode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
+	if (state->m_enable_parallel == false) {
 		/* MPEG data output is serial -> set ipr_mode[0] */
-		fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
+		fec_oc_reg_ipr_mode |= FEC_OC_IPR_MODE_SERIAL__M;
 	}
 
-	switch (oMode) {
+	switch (o_mode) {
 	case OM_DVBT:
-		maxBitRate = state->m_DVBTBitrate;
-		fecOcTmdMode = 3;
-		fecOcRcnCtlRate = 0xC00000;
-		staticCLK = state->m_DVBTStaticCLK;
+		max_bit_rate = state->m_dvbt_bitrate;
+		fec_oc_tmd_mode = 3;
+		fec_oc_rcn_ctl_rate = 0xC00000;
+		static_clk = state->m_dvbt_static_clk;
 		break;
 	case OM_QAM_ITU_A:	/* fallthrough */
 	case OM_QAM_ITU_C:
-		fecOcTmdMode = 0x0004;
-		fecOcRcnCtlRate = 0xD2B4EE;	/* good for >63 Mb/s */
-		maxBitRate = state->m_DVBCBitrate;
-		staticCLK = state->m_DVBCStaticCLK;
+		fec_oc_tmd_mode = 0x0004;
+		fec_oc_rcn_ctl_rate = 0xD2B4EE;	/* good for >63 Mb/s */
+		max_bit_rate = state->m_dvbc_bitrate;
+		static_clk = state->m_dvbc_static_clk;
 		break;
 	default:
 		status = -EINVAL;
@@ -2110,83 +2049,84 @@
 		goto error;
 
 	/* Configure DTO's */
-	if (staticCLK) {
-		u32 bitRate = 0;
+	if (static_clk) {
+		u32 bit_rate = 0;
 
 		/* Rational DTO for MCLK source (static MCLK rate),
 			Dynamic DTO for optimal grouping
 			(avoid intra-packet gaps),
 			DTO offset enable to sync TS burst with MSTRT */
-		fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
+		fec_oc_dto_mode = (FEC_OC_DTO_MODE_DYNAMIC__M |
 				FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
-		fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
+		fec_oc_fct_mode = (FEC_OC_FCT_MODE_RAT_ENA__M |
 				FEC_OC_FCT_MODE_VIRT_ENA__M);
 
 		/* Check user defined bitrate */
-		bitRate = maxBitRate;
-		if (bitRate > 75900000UL) {	/* max is 75.9 Mb/s */
-			bitRate = 75900000UL;
+		bit_rate = max_bit_rate;
+		if (bit_rate > 75900000UL) {	/* max is 75.9 Mb/s */
+			bit_rate = 75900000UL;
 		}
 		/* Rational DTO period:
 			dto_period = (Fsys / bitrate) - 2
 
-			Result should be floored,
+			result should be floored,
 			to make sure >= requested bitrate
 			*/
-		fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
-						* 1000) / bitRate);
-		if (fecOcDtoPeriod <= 2)
-			fecOcDtoPeriod = 0;
+		fec_oc_dto_period = (u16) (((state->m_sys_clock_freq)
+						* 1000) / bit_rate);
+		if (fec_oc_dto_period <= 2)
+			fec_oc_dto_period = 0;
 		else
-			fecOcDtoPeriod -= 2;
-		fecOcTmdIntUpdRate = 8;
+			fec_oc_dto_period -= 2;
+		fec_oc_tmd_int_upd_rate = 8;
 	} else {
-		/* (commonAttr->staticCLK == false) => dynamic mode */
-		fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
-		fecOcFctMode = FEC_OC_FCT_MODE__PRE;
-		fecOcTmdIntUpdRate = 5;
+		/* (commonAttr->static_clk == false) => dynamic mode */
+		fec_oc_dto_mode = FEC_OC_DTO_MODE_DYNAMIC__M;
+		fec_oc_fct_mode = FEC_OC_FCT_MODE__PRE;
+		fec_oc_tmd_int_upd_rate = 5;
 	}
 
 	/* Write appropriate registers with requested configuration */
-	status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
+	status = write16(state, FEC_OC_DTO_BURST_LEN__A, fec_oc_dto_burst_len);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
+	status = write16(state, FEC_OC_DTO_PERIOD__A, fec_oc_dto_period);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
+	status = write16(state, FEC_OC_DTO_MODE__A, fec_oc_dto_mode);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
+	status = write16(state, FEC_OC_FCT_MODE__A, fec_oc_fct_mode);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
+	status = write16(state, FEC_OC_MODE__A, fec_oc_reg_mode);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
+	status = write16(state, FEC_OC_IPR_MODE__A, fec_oc_reg_ipr_mode);
 	if (status < 0)
 		goto error;
 
 	/* Rate integration settings */
-	status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
+	status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fec_oc_rcn_ctl_rate);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
+	status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A,
+			 fec_oc_tmd_int_upd_rate);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
+	status = write16(state, FEC_OC_TMD_MODE__A, fec_oc_tmd_mode);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int MPEGTSConfigurePolarity(struct drxk_state *state)
+static int mpegts_configure_polarity(struct drxk_state *state)
 {
-	u16 fecOcRegIprInvert = 0;
+	u16 fec_oc_reg_ipr_invert = 0;
 
 	/* Data mask for the output data byte */
-	u16 InvertDataMask =
+	u16 invert_data_mask =
 	    FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
 	    FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
 	    FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
@@ -2195,40 +2135,40 @@
 	dprintk(1, "\n");
 
 	/* Control selective inversion of output bits */
-	fecOcRegIprInvert &= (~(InvertDataMask));
-	if (state->m_invertDATA == true)
-		fecOcRegIprInvert |= InvertDataMask;
-	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
-	if (state->m_invertERR == true)
-		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
-	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
-	if (state->m_invertSTR == true)
-		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
-	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
-	if (state->m_invertVAL == true)
-		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
-	fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
-	if (state->m_invertCLK == true)
-		fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
+	fec_oc_reg_ipr_invert &= (~(invert_data_mask));
+	if (state->m_invert_data == true)
+		fec_oc_reg_ipr_invert |= invert_data_mask;
+	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MERR__M));
+	if (state->m_invert_err == true)
+		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MERR__M;
+	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
+	if (state->m_invert_str == true)
+		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MSTRT__M;
+	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
+	if (state->m_invert_val == true)
+		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MVAL__M;
+	fec_oc_reg_ipr_invert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
+	if (state->m_invert_clk == true)
+		fec_oc_reg_ipr_invert |= FEC_OC_IPR_INVERT_MCLK__M;
 
-	return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
+	return write16(state, FEC_OC_IPR_INVERT__A, fec_oc_reg_ipr_invert);
 }
 
 #define   SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
 
-static int SetAgcRf(struct drxk_state *state,
-		    struct SCfgAgc *pAgcCfg, bool isDTV)
+static int set_agc_rf(struct drxk_state *state,
+		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
 {
 	int status = -EINVAL;
 	u16 data = 0;
-	struct SCfgAgc *pIfAgcSettings;
+	struct s_cfg_agc *p_if_agc_settings;
 
 	dprintk(1, "\n");
 
-	if (pAgcCfg == NULL)
+	if (p_agc_cfg == NULL)
 		goto error;
 
-	switch (pAgcCfg->ctrlMode) {
+	switch (p_agc_cfg->ctrl_mode) {
 	case DRXK_AGC_CTRL_AUTO:
 		/* Enable RF AGC DAC */
 		status = read16(state, IQM_AF_STDBY__A, &data);
@@ -2246,7 +2186,7 @@
 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
 
 		/* Polarity */
-		if (state->m_RfAgcPol)
+		if (state->m_rf_agc_pol)
 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
 		else
 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
@@ -2260,7 +2200,7 @@
 			goto error;
 
 		data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
-		data |= (~(pAgcCfg->speed <<
+		data |= (~(p_agc_cfg->speed <<
 				SCU_RAM_AGC_KI_RED_RAGC_RED__B)
 				& SCU_RAM_AGC_KI_RED_RAGC_RED__M);
 
@@ -2268,30 +2208,34 @@
 		if (status < 0)
 			goto error;
 
-		if (IsDVBT(state))
-			pIfAgcSettings = &state->m_dvbtIfAgcCfg;
-		else if (IsQAM(state))
-			pIfAgcSettings = &state->m_qamIfAgcCfg;
+		if (is_dvbt(state))
+			p_if_agc_settings = &state->m_dvbt_if_agc_cfg;
+		else if (is_qam(state))
+			p_if_agc_settings = &state->m_qam_if_agc_cfg;
 		else
-			pIfAgcSettings = &state->m_atvIfAgcCfg;
-		if (pIfAgcSettings == NULL) {
+			p_if_agc_settings = &state->m_atv_if_agc_cfg;
+		if (p_if_agc_settings == NULL) {
 			status = -EINVAL;
 			goto error;
 		}
 
 		/* Set TOP, only if IF-AGC is in AUTO mode */
-		if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
-			status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
+		if (p_if_agc_settings->ctrl_mode == DRXK_AGC_CTRL_AUTO)
+			status = write16(state,
+					 SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+					 p_agc_cfg->top);
 			if (status < 0)
 				goto error;
 
 		/* Cut-Off current */
-		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
+		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A,
+				 p_agc_cfg->cut_off_current);
 		if (status < 0)
 			goto error;
 
 		/* Max. output level */
-		status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
+		status = write16(state, SCU_RAM_AGC_RF_MAX__A,
+				 p_agc_cfg->max_output_level);
 		if (status < 0)
 			goto error;
 
@@ -2312,7 +2256,7 @@
 		if (status < 0)
 			goto error;
 		data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
-		if (state->m_RfAgcPol)
+		if (state->m_rf_agc_pol)
 			data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
 		else
 			data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
@@ -2326,7 +2270,8 @@
 			goto error;
 
 		/* Write value to output pin */
-		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
+		status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A,
+				 p_agc_cfg->output_level);
 		if (status < 0)
 			goto error;
 		break;
@@ -2357,22 +2302,22 @@
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
 #define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
 
-static int SetAgcIf(struct drxk_state *state,
-		    struct SCfgAgc *pAgcCfg, bool isDTV)
+static int set_agc_if(struct drxk_state *state,
+		    struct s_cfg_agc *p_agc_cfg, bool is_dtv)
 {
 	u16 data = 0;
 	int status = 0;
-	struct SCfgAgc *pRfAgcSettings;
+	struct s_cfg_agc *p_rf_agc_settings;
 
 	dprintk(1, "\n");
 
-	switch (pAgcCfg->ctrlMode) {
+	switch (p_agc_cfg->ctrl_mode) {
 	case DRXK_AGC_CTRL_AUTO:
 
 		/* Enable IF AGC DAC */
@@ -2392,7 +2337,7 @@
 		data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
 
 		/* Polarity */
-		if (state->m_IfAgcPol)
+		if (state->m_if_agc_pol)
 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
 		else
 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
@@ -2405,7 +2350,7 @@
 		if (status < 0)
 			goto error;
 		data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
-		data |= (~(pAgcCfg->speed <<
+		data |= (~(p_agc_cfg->speed <<
 				SCU_RAM_AGC_KI_RED_IAGC_RED__B)
 				& SCU_RAM_AGC_KI_RED_IAGC_RED__M);
 
@@ -2413,14 +2358,15 @@
 		if (status < 0)
 			goto error;
 
-		if (IsQAM(state))
-			pRfAgcSettings = &state->m_qamRfAgcCfg;
+		if (is_qam(state))
+			p_rf_agc_settings = &state->m_qam_rf_agc_cfg;
 		else
-			pRfAgcSettings = &state->m_atvRfAgcCfg;
-		if (pRfAgcSettings == NULL)
+			p_rf_agc_settings = &state->m_atv_rf_agc_cfg;
+		if (p_rf_agc_settings == NULL)
 			return -1;
 		/* Restore TOP */
-		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
+		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+				 p_rf_agc_settings->top);
 		if (status < 0)
 			goto error;
 		break;
@@ -2444,7 +2390,7 @@
 		data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
 
 		/* Polarity */
-		if (state->m_IfAgcPol)
+		if (state->m_if_agc_pol)
 			data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
 		else
 			data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
@@ -2453,7 +2399,8 @@
 			goto error;
 
 		/* Write value to output pin */
-		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
+		status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+				 p_agc_cfg->output_level);
 		if (status < 0)
 			goto error;
 		break;
@@ -2478,176 +2425,181 @@
 		if (status < 0)
 			goto error;
 		break;
-	}		/* switch (agcSettingsIf->ctrlMode) */
+	}		/* switch (agcSettingsIf->ctrl_mode) */
 
 	/* always set the top to support
 		configurations without if-loop */
-	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
+	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, p_agc_cfg->top);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int GetQAMSignalToNoise(struct drxk_state *state,
-			       s32 *pSignalToNoise)
+static int get_qam_signal_to_noise(struct drxk_state *state,
+			       s32 *p_signal_to_noise)
 {
 	int status = 0;
-	u16 qamSlErrPower = 0;	/* accum. error between
+	u16 qam_sl_err_power = 0;	/* accum. error between
 					raw and sliced symbols */
-	u32 qamSlSigPower = 0;	/* used for MER, depends of
+	u32 qam_sl_sig_power = 0;	/* used for MER, depends of
 					QAM modulation */
-	u32 qamSlMer = 0;	/* QAM MER */
+	u32 qam_sl_mer = 0;	/* QAM MER */
 
 	dprintk(1, "\n");
 
 	/* MER calculation */
 
 	/* get the register value needed for MER */
-	status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
+	status = read16(state, QAM_SL_ERR_POWER__A, &qam_sl_err_power);
 	if (status < 0) {
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 		return -EINVAL;
 	}
 
 	switch (state->props.modulation) {
 	case QAM_16:
-		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
+		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
 		break;
 	case QAM_32:
-		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
+		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
 		break;
 	case QAM_64:
-		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
+		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
 		break;
 	case QAM_128:
-		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
+		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
 		break;
 	default:
 	case QAM_256:
-		qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
+		qam_sl_sig_power = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
 		break;
 	}
 
-	if (qamSlErrPower > 0) {
-		qamSlMer = Log10Times100(qamSlSigPower) -
-			Log10Times100((u32) qamSlErrPower);
+	if (qam_sl_err_power > 0) {
+		qam_sl_mer = log10times100(qam_sl_sig_power) -
+			log10times100((u32) qam_sl_err_power);
 	}
-	*pSignalToNoise = qamSlMer;
+	*p_signal_to_noise = qam_sl_mer;
 
 	return status;
 }
 
-static int GetDVBTSignalToNoise(struct drxk_state *state,
-				s32 *pSignalToNoise)
+static int get_dvbt_signal_to_noise(struct drxk_state *state,
+				s32 *p_signal_to_noise)
 {
 	int status;
-	u16 regData = 0;
-	u32 EqRegTdSqrErrI = 0;
-	u32 EqRegTdSqrErrQ = 0;
-	u16 EqRegTdSqrErrExp = 0;
-	u16 EqRegTdTpsPwrOfs = 0;
-	u16 EqRegTdReqSmbCnt = 0;
-	u32 tpsCnt = 0;
-	u32 SqrErrIQ = 0;
+	u16 reg_data = 0;
+	u32 eq_reg_td_sqr_err_i = 0;
+	u32 eq_reg_td_sqr_err_q = 0;
+	u16 eq_reg_td_sqr_err_exp = 0;
+	u16 eq_reg_td_tps_pwr_ofs = 0;
+	u16 eq_reg_td_req_smb_cnt = 0;
+	u32 tps_cnt = 0;
+	u32 sqr_err_iq = 0;
 	u32 a = 0;
 	u32 b = 0;
 	u32 c = 0;
-	u32 iMER = 0;
-	u16 transmissionParams = 0;
+	u32 i_mer = 0;
+	u16 transmission_params = 0;
 
 	dprintk(1, "\n");
 
-	status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
+	status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A,
+			&eq_reg_td_tps_pwr_ofs);
 	if (status < 0)
 		goto error;
-	status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
+	status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A,
+			&eq_reg_td_req_smb_cnt);
 	if (status < 0)
 		goto error;
-	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
+	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A,
+			&eq_reg_td_sqr_err_exp);
 	if (status < 0)
 		goto error;
-	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
+	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A,
+			&reg_data);
 	if (status < 0)
 		goto error;
 	/* Extend SQR_ERR_I operational range */
-	EqRegTdSqrErrI = (u32) regData;
-	if ((EqRegTdSqrErrExp > 11) &&
-		(EqRegTdSqrErrI < 0x00000FFFUL)) {
-		EqRegTdSqrErrI += 0x00010000UL;
+	eq_reg_td_sqr_err_i = (u32) reg_data;
+	if ((eq_reg_td_sqr_err_exp > 11) &&
+		(eq_reg_td_sqr_err_i < 0x00000FFFUL)) {
+		eq_reg_td_sqr_err_i += 0x00010000UL;
 	}
-	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
+	status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &reg_data);
 	if (status < 0)
 		goto error;
 	/* Extend SQR_ERR_Q operational range */
-	EqRegTdSqrErrQ = (u32) regData;
-	if ((EqRegTdSqrErrExp > 11) &&
-		(EqRegTdSqrErrQ < 0x00000FFFUL))
-		EqRegTdSqrErrQ += 0x00010000UL;
+	eq_reg_td_sqr_err_q = (u32) reg_data;
+	if ((eq_reg_td_sqr_err_exp > 11) &&
+		(eq_reg_td_sqr_err_q < 0x00000FFFUL))
+		eq_reg_td_sqr_err_q += 0x00010000UL;
 
-	status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
+	status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A,
+			&transmission_params);
 	if (status < 0)
 		goto error;
 
 	/* Check input data for MER */
 
 	/* MER calculation (in 0.1 dB) without math.h */
-	if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
-		iMER = 0;
-	else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
+	if ((eq_reg_td_tps_pwr_ofs == 0) || (eq_reg_td_req_smb_cnt == 0))
+		i_mer = 0;
+	else if ((eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) == 0) {
 		/* No error at all, this must be the HW reset value
 			* Apparently no first measurement yet
 			* Set MER to 0.0 */
-		iMER = 0;
+		i_mer = 0;
 	} else {
-		SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
-			EqRegTdSqrErrExp;
-		if ((transmissionParams &
+		sqr_err_iq = (eq_reg_td_sqr_err_i + eq_reg_td_sqr_err_q) <<
+			eq_reg_td_sqr_err_exp;
+		if ((transmission_params &
 			OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
 			== OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
-			tpsCnt = 17;
+			tps_cnt = 17;
 		else
-			tpsCnt = 68;
+			tps_cnt = 68;
 
 		/* IMER = 100 * log10 (x)
-			where x = (EqRegTdTpsPwrOfs^2 *
-			EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
+			where x = (eq_reg_td_tps_pwr_ofs^2 *
+			eq_reg_td_req_smb_cnt * tps_cnt)/sqr_err_iq
 
 			=> IMER = a + b -c
-			where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
-			b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
-			c = 100 * log10 (SqrErrIQ)
+			where a = 100 * log10 (eq_reg_td_tps_pwr_ofs^2)
+			b = 100 * log10 (eq_reg_td_req_smb_cnt * tps_cnt)
+			c = 100 * log10 (sqr_err_iq)
 			*/
 
 		/* log(x) x = 9bits * 9bits->18 bits  */
-		a = Log10Times100(EqRegTdTpsPwrOfs *
-					EqRegTdTpsPwrOfs);
+		a = log10times100(eq_reg_td_tps_pwr_ofs *
+					eq_reg_td_tps_pwr_ofs);
 		/* log(x) x = 16bits * 7bits->23 bits  */
-		b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
+		b = log10times100(eq_reg_td_req_smb_cnt * tps_cnt);
 		/* log(x) x = (16bits + 16bits) << 15 ->32 bits  */
-		c = Log10Times100(SqrErrIQ);
+		c = log10times100(sqr_err_iq);
 
-		iMER = a + b - c;
+		i_mer = a + b - c;
 	}
-	*pSignalToNoise = iMER;
+	*p_signal_to_noise = i_mer;
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
+static int get_signal_to_noise(struct drxk_state *state, s32 *p_signal_to_noise)
 {
 	dprintk(1, "\n");
 
-	*pSignalToNoise = 0;
-	switch (state->m_OperationMode) {
+	*p_signal_to_noise = 0;
+	switch (state->m_operation_mode) {
 	case OM_DVBT:
-		return GetDVBTSignalToNoise(state, pSignalToNoise);
+		return get_dvbt_signal_to_noise(state, p_signal_to_noise);
 	case OM_QAM_ITU_A:
 	case OM_QAM_ITU_C:
-		return GetQAMSignalToNoise(state, pSignalToNoise);
+		return get_qam_signal_to_noise(state, p_signal_to_noise);
 	default:
 		break;
 	}
@@ -2655,7 +2607,7 @@
 }
 
 #if 0
-static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
+static int get_dvbt_quality(struct drxk_state *state, s32 *p_quality)
 {
 	/* SNR Values for quasi errorfree reception rom Nordig 2.2 */
 	int status = 0;
@@ -2680,102 +2632,104 @@
 		225,		/* 64-QAM 7/8 */
 	};
 
-	*pQuality = 0;
+	*p_quality = 0;
 
 	do {
-		s32 SignalToNoise = 0;
-		u16 Constellation = 0;
-		u16 CodeRate = 0;
-		u32 SignalToNoiseRel;
-		u32 BERQuality;
+		s32 signal_to_noise = 0;
+		u16 constellation = 0;
+		u16 code_rate = 0;
+		u32 signal_to_noise_rel;
+		u32 ber_quality;
 
-		status = GetDVBTSignalToNoise(state, &SignalToNoise);
+		status = get_dvbt_signal_to_noise(state, &signal_to_noise);
 		if (status < 0)
 			break;
-		status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
+		status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A,
+				&constellation);
 		if (status < 0)
 			break;
-		Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
+		constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
 
-		status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
+		status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A,
+				&code_rate);
 		if (status < 0)
 			break;
-		CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
+		code_rate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
 
-		if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
-		    CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
+		if (constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
+		    code_rate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
 			break;
-		SignalToNoiseRel = SignalToNoise -
-		    QE_SN[Constellation * 5 + CodeRate];
-		BERQuality = 100;
+		signal_to_noise_rel = signal_to_noise -
+		    QE_SN[constellation * 5 + code_rate];
+		ber_quality = 100;
 
-		if (SignalToNoiseRel < -70)
-			*pQuality = 0;
-		else if (SignalToNoiseRel < 30)
-			*pQuality = ((SignalToNoiseRel + 70) *
-				     BERQuality) / 100;
+		if (signal_to_noise_rel < -70)
+			*p_quality = 0;
+		else if (signal_to_noise_rel < 30)
+			*p_quality = ((signal_to_noise_rel + 70) *
+				     ber_quality) / 100;
 		else
-			*pQuality = BERQuality;
+			*p_quality = ber_quality;
 	} while (0);
 	return 0;
 };
 
-static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
+static int get_dvbc_quality(struct drxk_state *state, s32 *p_quality)
 {
 	int status = 0;
-	*pQuality = 0;
+	*p_quality = 0;
 
 	dprintk(1, "\n");
 
 	do {
-		u32 SignalToNoise = 0;
-		u32 BERQuality = 100;
-		u32 SignalToNoiseRel = 0;
+		u32 signal_to_noise = 0;
+		u32 ber_quality = 100;
+		u32 signal_to_noise_rel = 0;
 
-		status = GetQAMSignalToNoise(state, &SignalToNoise);
+		status = get_qam_signal_to_noise(state, &signal_to_noise);
 		if (status < 0)
 			break;
 
 		switch (state->props.modulation) {
 		case QAM_16:
-			SignalToNoiseRel = SignalToNoise - 200;
+			signal_to_noise_rel = signal_to_noise - 200;
 			break;
 		case QAM_32:
-			SignalToNoiseRel = SignalToNoise - 230;
+			signal_to_noise_rel = signal_to_noise - 230;
 			break;	/* Not in NorDig */
 		case QAM_64:
-			SignalToNoiseRel = SignalToNoise - 260;
+			signal_to_noise_rel = signal_to_noise - 260;
 			break;
 		case QAM_128:
-			SignalToNoiseRel = SignalToNoise - 290;
+			signal_to_noise_rel = signal_to_noise - 290;
 			break;
 		default:
 		case QAM_256:
-			SignalToNoiseRel = SignalToNoise - 320;
+			signal_to_noise_rel = signal_to_noise - 320;
 			break;
 		}
 
-		if (SignalToNoiseRel < -70)
-			*pQuality = 0;
-		else if (SignalToNoiseRel < 30)
-			*pQuality = ((SignalToNoiseRel + 70) *
-				     BERQuality) / 100;
+		if (signal_to_noise_rel < -70)
+			*p_quality = 0;
+		else if (signal_to_noise_rel < 30)
+			*p_quality = ((signal_to_noise_rel + 70) *
+				     ber_quality) / 100;
 		else
-			*pQuality = BERQuality;
+			*p_quality = ber_quality;
 	} while (0);
 
 	return status;
 }
 
-static int GetQuality(struct drxk_state *state, s32 *pQuality)
+static int get_quality(struct drxk_state *state, s32 *p_quality)
 {
 	dprintk(1, "\n");
 
-	switch (state->m_OperationMode) {
+	switch (state->m_operation_mode) {
 	case OM_DVBT:
-		return GetDVBTQuality(state, pQuality);
+		return get_dvbt_quality(state, p_quality);
 	case OM_QAM_ITU_A:
-		return GetDVBCQuality(state, pQuality);
+		return get_dvbc_quality(state, p_quality);
 	default:
 		break;
 	}
@@ -2797,65 +2751,68 @@
 #define DRXDAP_FASI_ADDR2BANK(addr)   (((addr) >> 16) & 0x3F)
 #define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
 
-static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
+static int ConfigureI2CBridge(struct drxk_state *state, bool b_enable_bridge)
 {
 	int status = -EINVAL;
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return 0;
-	if (state->m_DrxkState == DRXK_POWERED_DOWN)
+	if (state->m_drxk_state == DRXK_POWERED_DOWN)
 		goto error;
 
 	if (state->no_i2c_bridge)
 		return 0;
 
-	status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
+	status = write16(state, SIO_HI_RA_RAM_PAR_1__A,
+			 SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
 	if (status < 0)
 		goto error;
-	if (bEnableBridge) {
-		status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
+	if (b_enable_bridge) {
+		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
+				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
 		if (status < 0)
 			goto error;
 	} else {
-		status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
+		status = write16(state, SIO_HI_RA_RAM_PAR_2__A,
+				 SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
 		if (status < 0)
 			goto error;
 	}
 
-	status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
+	status = hi_command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetPreSaw(struct drxk_state *state,
-		     struct SCfgPreSaw *pPreSawCfg)
+static int set_pre_saw(struct drxk_state *state,
+		     struct s_cfg_pre_saw *p_pre_saw_cfg)
 {
 	int status = -EINVAL;
 
 	dprintk(1, "\n");
 
-	if ((pPreSawCfg == NULL)
-	    || (pPreSawCfg->reference > IQM_AF_PDREF__M))
+	if ((p_pre_saw_cfg == NULL)
+	    || (p_pre_saw_cfg->reference > IQM_AF_PDREF__M))
 		goto error;
 
-	status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
+	status = write16(state, IQM_AF_PDREF__A, p_pre_saw_cfg->reference);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
-		       u16 romOffset, u16 nrOfElements, u32 timeOut)
+static int bl_direct_cmd(struct drxk_state *state, u32 target_addr,
+		       u16 rom_offset, u16 nr_of_elements, u32 time_out)
 {
-	u16 blStatus = 0;
-	u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
-	u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
+	u16 bl_status = 0;
+	u16 offset = (u16) ((target_addr >> 0) & 0x00FFFF);
+	u16 blockbank = (u16) ((target_addr >> 16) & 0x000FFF);
 	int status;
 	unsigned long end;
 
@@ -2871,44 +2828,44 @@
 	status = write16(state, SIO_BL_TGT_ADDR__A, offset);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
+	status = write16(state, SIO_BL_SRC_ADDR__A, rom_offset);
 	if (status < 0)
 		goto error;
-	status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
+	status = write16(state, SIO_BL_SRC_LEN__A, nr_of_elements);
 	if (status < 0)
 		goto error;
 	status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
 	if (status < 0)
 		goto error;
 
-	end = jiffies + msecs_to_jiffies(timeOut);
+	end = jiffies + msecs_to_jiffies(time_out);
 	do {
-		status = read16(state, SIO_BL_STATUS__A, &blStatus);
+		status = read16(state, SIO_BL_STATUS__A, &bl_status);
 		if (status < 0)
 			goto error;
-	} while ((blStatus == 0x1) && time_is_after_jiffies(end));
-	if (blStatus == 0x1) {
-		printk(KERN_ERR "drxk: SIO not ready\n");
+	} while ((bl_status == 0x1) && time_is_after_jiffies(end));
+	if (bl_status == 0x1) {
+		pr_err("SIO not ready\n");
 		status = -EINVAL;
 		goto error2;
 	}
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 error2:
 	mutex_unlock(&state->mutex);
 	return status;
 
 }
 
-static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
+static int adc_sync_measurement(struct drxk_state *state, u16 *count)
 {
 	u16 data = 0;
 	int status;
 
 	dprintk(1, "\n");
 
-	/* Start measurement */
+	/* start measurement */
 	status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
 	if (status < 0)
 		goto error;
@@ -2935,42 +2892,42 @@
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int ADCSynchronization(struct drxk_state *state)
+static int adc_synchronization(struct drxk_state *state)
 {
 	u16 count = 0;
 	int status;
 
 	dprintk(1, "\n");
 
-	status = ADCSyncMeasurement(state, &count);
+	status = adc_sync_measurement(state, &count);
 	if (status < 0)
 		goto error;
 
 	if (count == 1) {
 		/* Try sampling on a diffrent edge */
-		u16 clkNeg = 0;
+		u16 clk_neg = 0;
 
-		status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
+		status = read16(state, IQM_AF_CLKNEG__A, &clk_neg);
 		if (status < 0)
 			goto error;
-		if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
+		if ((clk_neg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
 			IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
-			clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
-			clkNeg |=
+			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
+			clk_neg |=
 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
 		} else {
-			clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
-			clkNeg |=
+			clk_neg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
+			clk_neg |=
 				IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
 		}
-		status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
+		status = write16(state, IQM_AF_CLKNEG__A, clk_neg);
 		if (status < 0)
 			goto error;
-		status = ADCSyncMeasurement(state, &count);
+		status = adc_sync_measurement(state, &count);
 		if (status < 0)
 			goto error;
 	}
@@ -2979,25 +2936,25 @@
 		status = -EINVAL;
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetFrequencyShifter(struct drxk_state *state,
-			       u16 intermediateFreqkHz,
-			       s32 tunerFreqOffset, bool isDTV)
+static int set_frequency_shifter(struct drxk_state *state,
+			       u16 intermediate_freqk_hz,
+			       s32 tuner_freq_offset, bool is_dtv)
 {
-	bool selectPosImage = false;
-	u32 rfFreqResidual = tunerFreqOffset;
-	u32 fmFrequencyShift = 0;
-	bool tunerMirror = !state->m_bMirrorFreqSpect;
-	u32 adcFreq;
-	bool adcFlip;
+	bool select_pos_image = false;
+	u32 rf_freq_residual = tuner_freq_offset;
+	u32 fm_frequency_shift = 0;
+	bool tuner_mirror = !state->m_b_mirror_freq_spect;
+	u32 adc_freq;
+	bool adc_flip;
 	int status;
-	u32 ifFreqActual;
-	u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
-	u32 frequencyShift;
-	bool imageToSelect;
+	u32 if_freq_actual;
+	u32 sampling_frequency = (u32) (state->m_sys_clock_freq / 3);
+	u32 frequency_shift;
+	bool image_to_select;
 
 	dprintk(1, "\n");
 
@@ -3005,121 +2962,125 @@
 	   Program frequency shifter
 	   No need to account for mirroring on RF
 	 */
-	if (isDTV) {
-		if ((state->m_OperationMode == OM_QAM_ITU_A) ||
-		    (state->m_OperationMode == OM_QAM_ITU_C) ||
-		    (state->m_OperationMode == OM_DVBT))
-			selectPosImage = true;
+	if (is_dtv) {
+		if ((state->m_operation_mode == OM_QAM_ITU_A) ||
+		    (state->m_operation_mode == OM_QAM_ITU_C) ||
+		    (state->m_operation_mode == OM_DVBT))
+			select_pos_image = true;
 		else
-			selectPosImage = false;
+			select_pos_image = false;
 	}
-	if (tunerMirror)
+	if (tuner_mirror)
 		/* tuner doesn't mirror */
-		ifFreqActual = intermediateFreqkHz +
-		    rfFreqResidual + fmFrequencyShift;
+		if_freq_actual = intermediate_freqk_hz +
+		    rf_freq_residual + fm_frequency_shift;
 	else
 		/* tuner mirrors */
-		ifFreqActual = intermediateFreqkHz -
-		    rfFreqResidual - fmFrequencyShift;
-	if (ifFreqActual > samplingFrequency / 2) {
+		if_freq_actual = intermediate_freqk_hz -
+		    rf_freq_residual - fm_frequency_shift;
+	if (if_freq_actual > sampling_frequency / 2) {
 		/* adc mirrors */
-		adcFreq = samplingFrequency - ifFreqActual;
-		adcFlip = true;
+		adc_freq = sampling_frequency - if_freq_actual;
+		adc_flip = true;
 	} else {
 		/* adc doesn't mirror */
-		adcFreq = ifFreqActual;
-		adcFlip = false;
+		adc_freq = if_freq_actual;
+		adc_flip = false;
 	}
 
-	frequencyShift = adcFreq;
-	imageToSelect = state->m_rfmirror ^ tunerMirror ^
-	    adcFlip ^ selectPosImage;
-	state->m_IqmFsRateOfs =
-	    Frac28a((frequencyShift), samplingFrequency);
+	frequency_shift = adc_freq;
+	image_to_select = state->m_rfmirror ^ tuner_mirror ^
+	    adc_flip ^ select_pos_image;
+	state->m_iqm_fs_rate_ofs =
+	    Frac28a((frequency_shift), sampling_frequency);
 
-	if (imageToSelect)
-		state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
+	if (image_to_select)
+		state->m_iqm_fs_rate_ofs = ~state->m_iqm_fs_rate_ofs + 1;
 
 	/* Program frequency shifter with tuner offset compensation */
-	/* frequencyShift += tunerFreqOffset; TODO */
+	/* frequency_shift += tuner_freq_offset; TODO */
 	status = write32(state, IQM_FS_RATE_OFS_LO__A,
-			 state->m_IqmFsRateOfs);
+			 state->m_iqm_fs_rate_ofs);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int InitAGC(struct drxk_state *state, bool isDTV)
+static int init_agc(struct drxk_state *state, bool is_dtv)
 {
-	u16 ingainTgt = 0;
-	u16 ingainTgtMin = 0;
-	u16 ingainTgtMax = 0;
-	u16 clpCyclen = 0;
-	u16 clpSumMin = 0;
-	u16 clpDirTo = 0;
-	u16 snsSumMin = 0;
-	u16 snsSumMax = 0;
-	u16 clpSumMax = 0;
-	u16 snsDirTo = 0;
-	u16 kiInnergainMin = 0;
-	u16 ifIaccuHiTgt = 0;
-	u16 ifIaccuHiTgtMin = 0;
-	u16 ifIaccuHiTgtMax = 0;
+	u16 ingain_tgt = 0;
+	u16 ingain_tgt_min = 0;
+	u16 ingain_tgt_max = 0;
+	u16 clp_cyclen = 0;
+	u16 clp_sum_min = 0;
+	u16 clp_dir_to = 0;
+	u16 sns_sum_min = 0;
+	u16 sns_sum_max = 0;
+	u16 clp_sum_max = 0;
+	u16 sns_dir_to = 0;
+	u16 ki_innergain_min = 0;
+	u16 if_iaccu_hi_tgt = 0;
+	u16 if_iaccu_hi_tgt_min = 0;
+	u16 if_iaccu_hi_tgt_max = 0;
 	u16 data = 0;
-	u16 fastClpCtrlDelay = 0;
-	u16 clpCtrlMode = 0;
+	u16 fast_clp_ctrl_delay = 0;
+	u16 clp_ctrl_mode = 0;
 	int status = 0;
 
 	dprintk(1, "\n");
 
 	/* Common settings */
-	snsSumMax = 1023;
-	ifIaccuHiTgtMin = 2047;
-	clpCyclen = 500;
-	clpSumMax = 1023;
+	sns_sum_max = 1023;
+	if_iaccu_hi_tgt_min = 2047;
+	clp_cyclen = 500;
+	clp_sum_max = 1023;
 
 	/* AGCInit() not available for DVBT; init done in microcode */
-	if (!IsQAM(state)) {
-		printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
+	if (!is_qam(state)) {
+		pr_err("%s: mode %d is not DVB-C\n",
+		       __func__, state->m_operation_mode);
 		return -EINVAL;
 	}
 
 	/* FIXME: Analog TV AGC require different settings */
 
 	/* Standard specific settings */
-	clpSumMin = 8;
-	clpDirTo = (u16) -9;
-	clpCtrlMode = 0;
-	snsSumMin = 8;
-	snsDirTo = (u16) -9;
-	kiInnergainMin = (u16) -1030;
-	ifIaccuHiTgtMax = 0x2380;
-	ifIaccuHiTgt = 0x2380;
-	ingainTgtMin = 0x0511;
-	ingainTgt = 0x0511;
-	ingainTgtMax = 5119;
-	fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
+	clp_sum_min = 8;
+	clp_dir_to = (u16) -9;
+	clp_ctrl_mode = 0;
+	sns_sum_min = 8;
+	sns_dir_to = (u16) -9;
+	ki_innergain_min = (u16) -1030;
+	if_iaccu_hi_tgt_max = 0x2380;
+	if_iaccu_hi_tgt = 0x2380;
+	ingain_tgt_min = 0x0511;
+	ingain_tgt = 0x0511;
+	ingain_tgt_max = 5119;
+	fast_clp_ctrl_delay = state->m_qam_if_agc_cfg.fast_clip_ctrl_delay;
 
-	status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
+	status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
+			 fast_clp_ctrl_delay);
 	if (status < 0)
 		goto error;
 
-	status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
+	status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clp_ctrl_mode);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
+	status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingain_tgt);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
+	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingain_tgt_min);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
+	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingain_tgt_max);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
+	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A,
+			 if_iaccu_hi_tgt_min);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
+	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A,
+			 if_iaccu_hi_tgt_max);
 	if (status < 0)
 		goto error;
 	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
@@ -3134,20 +3095,22 @@
 	status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
+	status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clp_sum_max);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
+	status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, sns_sum_max);
 	if (status < 0)
 		goto error;
 
-	status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
+	status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A,
+			 ki_innergain_min);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
+	status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A,
+			 if_iaccu_hi_tgt);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
+	status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clp_cyclen);
 	if (status < 0)
 		goto error;
 
@@ -3164,16 +3127,16 @@
 	status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
+	status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clp_sum_min);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
+	status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, sns_sum_min);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
+	status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clp_dir_to);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
+	status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, sns_dir_to);
 	if (status < 0)
 		goto error;
 	status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
@@ -3233,38 +3196,39 @@
 	status = write16(state, SCU_RAM_AGC_KI__A, data);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
+static int dvbtqam_get_acc_pkt_err(struct drxk_state *state, u16 *packet_err)
 {
 	int status;
 
 	dprintk(1, "\n");
-	if (packetErr == NULL)
+	if (packet_err == NULL)
 		status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
 	else
-		status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
+		status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A,
+				packet_err);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int DVBTScCommand(struct drxk_state *state,
+static int dvbt_sc_command(struct drxk_state *state,
 			 u16 cmd, u16 subcmd,
 			 u16 param0, u16 param1, u16 param2,
 			 u16 param3, u16 param4)
 {
-	u16 curCmd = 0;
-	u16 errCode = 0;
-	u16 retryCnt = 0;
-	u16 scExec = 0;
+	u16 cur_cmd = 0;
+	u16 err_code = 0;
+	u16 retry_cnt = 0;
+	u16 sc_exec = 0;
 	int status;
 
 	dprintk(1, "\n");
-	status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
-	if (scExec != 1) {
+	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_exec);
+	if (sc_exec != 1) {
 		/* SC is not running */
 		status = -EINVAL;
 	}
@@ -3272,13 +3236,13 @@
 		goto error;
 
 	/* Wait until sc is ready to receive command */
-	retryCnt = 0;
+	retry_cnt = 0;
 	do {
-		msleep(1);
-		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
-		retryCnt++;
-	} while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
-	if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
+		usleep_range(1000, 2000);
+		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
+		retry_cnt++;
+	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
+	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
 		goto error;
 
 	/* Write sub-command */
@@ -3324,18 +3288,18 @@
 		goto error;
 
 	/* Wait until sc is ready processing command */
-	retryCnt = 0;
+	retry_cnt = 0;
 	do {
-		msleep(1);
-		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
-		retryCnt++;
-	} while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
-	if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
+		usleep_range(1000, 2000);
+		status = read16(state, OFDM_SC_RA_RAM_CMD__A, &cur_cmd);
+		retry_cnt++;
+	} while ((cur_cmd != 0) && (retry_cnt < DRXK_MAX_RETRIES));
+	if (retry_cnt >= DRXK_MAX_RETRIES && (status < 0))
 		goto error;
 
 	/* Check for illegal cmd */
-	status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
-	if (errCode == 0xFFFF) {
+	status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &err_code);
+	if (err_code == 0xFFFF) {
 		/* illegal command */
 		status = -EINVAL;
 	}
@@ -3367,23 +3331,23 @@
 	}			/* switch (cmd->cmd) */
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int PowerUpDVBT(struct drxk_state *state)
+static int power_up_dvbt(struct drxk_state *state)
 {
-	enum DRXPowerMode powerMode = DRX_POWER_UP;
+	enum drx_power_mode power_mode = DRX_POWER_UP;
 	int status;
 
 	dprintk(1, "\n");
-	status = CtrlPowerMode(state, &powerMode);
+	status = ctrl_power_mode(state, &power_mode);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
+static int dvbt_ctrl_set_inc_enable(struct drxk_state *state, bool *enabled)
 {
 	int status;
 
@@ -3393,12 +3357,12 @@
 	else
 		status = write16(state, IQM_CF_BYPASSDET__A, 1);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
 #define DEFAULT_FR_THRES_8K     4000
-static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
+static int dvbt_ctrl_set_fr_enable(struct drxk_state *state, bool *enabled)
 {
 
 	int status;
@@ -3413,13 +3377,13 @@
 		status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
 	}
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
-static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
-				    struct DRXKCfgDvbtEchoThres_t *echoThres)
+static int dvbt_ctrl_set_echo_threshold(struct drxk_state *state,
+				struct drxk_cfg_dvbt_echo_thres_t *echo_thres)
 {
 	u16 data = 0;
 	int status;
@@ -3429,16 +3393,16 @@
 	if (status < 0)
 		goto error;
 
-	switch (echoThres->fftMode) {
+	switch (echo_thres->fft_mode) {
 	case DRX_FFTMODE_2K:
 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
-		data |= ((echoThres->threshold <<
+		data |= ((echo_thres->threshold <<
 			OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
 			& (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
 		break;
 	case DRX_FFTMODE_8K:
 		data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
-		data |= ((echoThres->threshold <<
+		data |= ((echo_thres->threshold <<
 			OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
 			& (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
 		break;
@@ -3449,12 +3413,12 @@
 	status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
-			       enum DRXKCfgDvbtSqiSpeed *speed)
+static int dvbt_ctrl_set_sqi_speed(struct drxk_state *state,
+			       enum drxk_cfg_dvbt_sqi_speed *speed)
 {
 	int status = -EINVAL;
 
@@ -3472,7 +3436,7 @@
 			   (u16) *speed);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -3486,32 +3450,33 @@
 * Called in DVBTSetStandard
 *
 */
-static int DVBTActivatePresets(struct drxk_state *state)
+static int dvbt_activate_presets(struct drxk_state *state)
 {
 	int status;
 	bool setincenable = false;
 	bool setfrenable = true;
 
-	struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
-	struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
+	struct drxk_cfg_dvbt_echo_thres_t echo_thres2k = { 0, DRX_FFTMODE_2K };
+	struct drxk_cfg_dvbt_echo_thres_t echo_thres8k = { 0, DRX_FFTMODE_8K };
 
 	dprintk(1, "\n");
-	status = DVBTCtrlSetIncEnable(state, &setincenable);
+	status = dvbt_ctrl_set_inc_enable(state, &setincenable);
 	if (status < 0)
 		goto error;
-	status = DVBTCtrlSetFrEnable(state, &setfrenable);
+	status = dvbt_ctrl_set_fr_enable(state, &setfrenable);
 	if (status < 0)
 		goto error;
-	status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
+	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres2k);
 	if (status < 0)
 		goto error;
-	status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
+	status = dvbt_ctrl_set_echo_threshold(state, &echo_thres8k);
 	if (status < 0)
 		goto error;
-	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
+	status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A,
+			 state->m_dvbt_if_agc_cfg.ingain_tgt_max);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -3525,25 +3490,30 @@
 * For ROM code channel filter taps are loaded from the bootloader. For microcode
 * the DVB-T taps from the drxk_filters.h are used.
 */
-static int SetDVBTStandard(struct drxk_state *state,
-			   enum OperationMode oMode)
+static int set_dvbt_standard(struct drxk_state *state,
+			   enum operation_mode o_mode)
 {
-	u16 cmdResult = 0;
+	u16 cmd_result = 0;
 	u16 data = 0;
 	int status;
 
 	dprintk(1, "\n");
 
-	PowerUpDVBT(state);
+	power_up_dvbt(state);
 	/* added antenna switch */
-	SwitchAntennaToDVBT(state);
+	switch_antenna_to_dvbt(state);
 	/* send OFDM reset command */
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+	status = scu_command(state,
+			     SCU_RAM_COMMAND_STANDARD_OFDM
+			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
+			     0, NULL, 1, &cmd_result);
 	if (status < 0)
 		goto error;
 
 	/* send OFDM setenv command */
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
+	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
+			     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
+			     0, NULL, 1, &cmd_result);
 	if (status < 0)
 		goto error;
 
@@ -3575,7 +3545,7 @@
 	status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
 	if (status < 0)
 		goto error;
-	status = SetIqmAf(state, true);
+	status = set_iqm_af(state, true);
 	if (status < 0)
 		goto error;
 
@@ -3597,7 +3567,7 @@
 	status = write16(state, IQM_RC_STRETCH__A, 16);
 	if (status < 0)
 		goto error;
-	status = write16(state, IQM_CF_OUT_ENA__A, 0x4);	/* enable output 2 */
+	status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
 	if (status < 0)
 		goto error;
 	status = write16(state, IQM_CF_DS_ENA__A, 0x4);	/* decimate output 2 */
@@ -3618,7 +3588,8 @@
 	if (status < 0)
 		goto error;
 
-	status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+	status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT,
+			      DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
 	if (status < 0)
 		goto error;
 
@@ -3637,10 +3608,10 @@
 		goto error;
 
 	/* IQM will not be reset from here, sync ADC and update/init AGC */
-	status = ADCSynchronization(state);
+	status = adc_synchronization(state);
 	if (status < 0)
 		goto error;
-	status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
+	status = set_pre_saw(state, &state->m_dvbt_pre_saw_cfg);
 	if (status < 0)
 		goto error;
 
@@ -3649,10 +3620,10 @@
 	if (status < 0)
 		goto error;
 
-	status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
+	status = set_agc_rf(state, &state->m_dvbt_rf_agc_cfg, true);
 	if (status < 0)
 		goto error;
-	status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
+	status = set_agc_if(state, &state->m_dvbt_if_agc_cfg, true);
 	if (status < 0)
 		goto error;
 
@@ -3670,9 +3641,10 @@
 	if (status < 0)
 		goto error;
 
-	if (!state->m_DRXK_A3_ROM_CODE) {
-		/* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay  */
-		status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
+	if (!state->m_drxk_a3_rom_code) {
+		/* AGCInit() is not done for DVBT, so set agcfast_clip_ctrl_delay  */
+		status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A,
+				 state->m_dvbt_if_agc_cfg.fast_clip_ctrl_delay);
 		if (status < 0)
 			goto error;
 	}
@@ -3707,41 +3679,43 @@
 		goto error;
 
 	/* Setup MPEG bus */
-	status = MPEGTSDtoSetup(state, OM_DVBT);
+	status = mpegts_dto_setup(state, OM_DVBT);
 	if (status < 0)
 		goto error;
 	/* Set DVBT Presets */
-	status = DVBTActivatePresets(state);
+	status = dvbt_activate_presets(state);
 	if (status < 0)
 		goto error;
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
 /*============================================================================*/
 /**
-* \brief Start dvbt demodulating for channel.
+* \brief start dvbt demodulating for channel.
 * \param demod instance of demodulator.
 * \return DRXStatus_t.
 */
-static int DVBTStart(struct drxk_state *state)
+static int dvbt_start(struct drxk_state *state)
 {
 	u16 param1;
 	int status;
-	/* DRXKOfdmScCmd_t scCmd; */
+	/* drxk_ofdm_sc_cmd_t scCmd; */
 
 	dprintk(1, "\n");
-	/* Start correct processes to get in lock */
+	/* start correct processes to get in lock */
 	/* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
 	param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
-	status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
+	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0,
+				 OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1,
+				 0, 0, 0);
 	if (status < 0)
 		goto error;
-	/* Start FEC OC */
-	status = MPEGTSStart(state);
+	/* start FEC OC */
+	status = mpegts_start(state);
 	if (status < 0)
 		goto error;
 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
@@ -3749,7 +3723,7 @@
 		goto error;
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -3762,20 +3736,23 @@
 * \return DRXStatus_t.
 * // original DVBTSetChannel()
 */
-static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
-		   s32 tunerFreqOffset)
+static int set_dvbt(struct drxk_state *state, u16 intermediate_freqk_hz,
+		   s32 tuner_freq_offset)
 {
-	u16 cmdResult = 0;
-	u16 transmissionParams = 0;
-	u16 operationMode = 0;
-	u32 iqmRcRateOfs = 0;
+	u16 cmd_result = 0;
+	u16 transmission_params = 0;
+	u16 operation_mode = 0;
+	u32 iqm_rc_rate_ofs = 0;
 	u32 bandwidth = 0;
 	u16 param1;
 	int status;
 
-	dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
+	dprintk(1, "IF =%d, TFO = %d\n",
+		intermediate_freqk_hz, tuner_freq_offset);
 
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
+			    | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
+			    0, NULL, 1, &cmd_result);
 	if (status < 0)
 		goto error;
 
@@ -3798,19 +3775,19 @@
 	if (status < 0)
 		goto error;
 
-	/*== Write channel settings to device =====================================*/
+	/*== Write channel settings to device ================================*/
 
 	/* mode */
 	switch (state->props.transmission_mode) {
 	case TRANSMISSION_MODE_AUTO:
 	default:
-		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
+		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
 		/* fall through , try first guess DRX_FFTMODE_8K */
 	case TRANSMISSION_MODE_8K:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
 		break;
 	case TRANSMISSION_MODE_2K:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
 		break;
 	}
 
@@ -3818,19 +3795,19 @@
 	switch (state->props.guard_interval) {
 	default:
 	case GUARD_INTERVAL_AUTO:
-		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
+		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
 		/* fall through , try first guess DRX_GUARD_1DIV4 */
 	case GUARD_INTERVAL_1_4:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
 		break;
 	case GUARD_INTERVAL_1_32:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
 		break;
 	case GUARD_INTERVAL_1_16:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
 		break;
 	case GUARD_INTERVAL_1_8:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
 		break;
 	}
 
@@ -3839,18 +3816,18 @@
 	case HIERARCHY_AUTO:
 	case HIERARCHY_NONE:
 	default:
-		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
+		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
 		/* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
-		/* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
+		/* transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
 		/* break; */
 	case HIERARCHY_1:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
 		break;
 	case HIERARCHY_2:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
 		break;
 	case HIERARCHY_4:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
 		break;
 	}
 
@@ -3859,16 +3836,16 @@
 	switch (state->props.modulation) {
 	case QAM_AUTO:
 	default:
-		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
+		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
 		/* fall through , try first guess DRX_CONSTELLATION_QAM64 */
 	case QAM_64:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
 		break;
 	case QPSK:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
 		break;
 	case QAM_16:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
 		break;
 	}
 #if 0
@@ -3876,13 +3853,13 @@
 	/* Priority (only for hierarchical channels) */
 	switch (channel->priority) {
 	case DRX_PRIORITY_LOW:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
-		WR16(devAddr, OFDM_EC_SB_PRIOR__A,
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
+		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
 			OFDM_EC_SB_PRIOR_LO);
 		break;
 	case DRX_PRIORITY_HIGH:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
-		WR16(devAddr, OFDM_EC_SB_PRIOR__A,
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
+		WR16(dev_addr, OFDM_EC_SB_PRIOR__A,
 			OFDM_EC_SB_PRIOR_HI));
 		break;
 	case DRX_PRIORITY_UNKNOWN:	/* fall through */
@@ -3892,7 +3869,7 @@
 	}
 #else
 	/* Set Priorty high */
-	transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
+	transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
 	status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
 	if (status < 0)
 		goto error;
@@ -3902,90 +3879,111 @@
 	switch (state->props.code_rate_HP) {
 	case FEC_AUTO:
 	default:
-		operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
+		operation_mode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
 		/* fall through , try first guess DRX_CODERATE_2DIV3 */
 	case FEC_2_3:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
 		break;
 	case FEC_1_2:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
 		break;
 	case FEC_3_4:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
 		break;
 	case FEC_5_6:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
 		break;
 	case FEC_7_8:
-		transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
+		transmission_params |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
 		break;
 	}
 
-	/* SAW filter selection: normaly not necesarry, but if wanted
-		the application can select a SAW filter via the driver by using UIOs */
+	/*
+	 * SAW filter selection: normaly not necesarry, but if wanted
+	 * the application can select a SAW filter via the driver by
+	 * using UIOs
+	 */
+
 	/* First determine real bandwidth (Hz) */
 	/* Also set delay for impulse noise cruncher */
-	/* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
-		by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
-		functions */
+	/*
+	 * Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is
+	 * changed by SC for fix for some 8K,1/8 guard but is restored by
+	 * InitEC and ResetEC functions
+	 */
 	switch (state->props.bandwidth_hz) {
 	case 0:
 		state->props.bandwidth_hz = 8000000;
 		/* fall though */
 	case 8000000:
 		bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
-		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
+		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
+				 3052);
 		if (status < 0)
 			goto error;
 		/* cochannel protection for PAL 8 MHz */
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
+				 7);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
+				 7);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
+				 7);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
+				 1);
 		if (status < 0)
 			goto error;
 		break;
 	case 7000000:
 		bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
-		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
+		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
+				 3491);
 		if (status < 0)
 			goto error;
 		/* cochannel protection for PAL 7 MHz */
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
+				 8);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
+				 8);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
+				 4);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
+				 1);
 		if (status < 0)
 			goto error;
 		break;
 	case 6000000:
 		bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
-		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
+		status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A,
+				 4073);
 		if (status < 0)
 			goto error;
 		/* cochannel protection for NTSC 6 MHz */
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A,
+				 19);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A,
+				 19);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A,
+				 14);
 		if (status < 0)
 			goto error;
-		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
+		status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A,
+				 1);
 		if (status < 0)
 			goto error;
 		break;
@@ -3994,46 +3992,50 @@
 		goto error;
 	}
 
-	if (iqmRcRateOfs == 0) {
+	if (iqm_rc_rate_ofs == 0) {
 		/* Now compute IQM_RC_RATE_OFS
 			(((SysFreq/BandWidth)/2)/2) -1) * 2^23)
 			=>
 			((SysFreq / BandWidth) * (2^21)) - (2^23)
 			*/
 		/* (SysFreq / BandWidth) * (2^28)  */
-		/* assert (MAX(sysClk)/MIN(bandwidth) < 16)
-			=> assert(MAX(sysClk) < 16*MIN(bandwidth))
-			=> assert(109714272 > 48000000) = true so Frac 28 can be used  */
-		iqmRcRateOfs = Frac28a((u32)
-					((state->m_sysClockFreq *
+		/*
+		 * assert (MAX(sysClk)/MIN(bandwidth) < 16)
+		 *	=> assert(MAX(sysClk) < 16*MIN(bandwidth))
+		 *	=> assert(109714272 > 48000000) = true
+		 * so Frac 28 can be used
+		 */
+		iqm_rc_rate_ofs = Frac28a((u32)
+					((state->m_sys_clock_freq *
 						1000) / 3), bandwidth);
-		/* (SysFreq / BandWidth) * (2^21), rounding before truncating  */
-		if ((iqmRcRateOfs & 0x7fL) >= 0x40)
-			iqmRcRateOfs += 0x80L;
-		iqmRcRateOfs = iqmRcRateOfs >> 7;
+		/* (SysFreq / BandWidth) * (2^21), rounding before truncating */
+		if ((iqm_rc_rate_ofs & 0x7fL) >= 0x40)
+			iqm_rc_rate_ofs += 0x80L;
+		iqm_rc_rate_ofs = iqm_rc_rate_ofs >> 7;
 		/* ((SysFreq / BandWidth) * (2^21)) - (2^23)  */
-		iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
+		iqm_rc_rate_ofs = iqm_rc_rate_ofs - (1 << 23);
 	}
 
-	iqmRcRateOfs &=
+	iqm_rc_rate_ofs &=
 		((((u32) IQM_RC_RATE_OFS_HI__M) <<
 		IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
-	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
+	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate_ofs);
 	if (status < 0)
 		goto error;
 
 	/* Bandwidth setting done */
 
 #if 0
-	status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
+	status = dvbt_set_frequency_shift(demod, channel, tuner_offset);
 	if (status < 0)
 		goto error;
 #endif
-	status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
+	status = set_frequency_shifter(state, intermediate_freqk_hz,
+				       tuner_freq_offset, true);
 	if (status < 0)
 		goto error;
 
-	/*== Start SC, write channel settings to SC ===============================*/
+	/*== start SC, write channel settings to SC ==========================*/
 
 	/* Activate SCU to enable SCU commands */
 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
@@ -4049,7 +4051,9 @@
 		goto error;
 
 
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
+	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM
+			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
+			     0, NULL, 1, &cmd_result);
 	if (status < 0)
 		goto error;
 
@@ -4059,16 +4063,16 @@
 			OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
 			OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
 			OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
-	status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
-				0, transmissionParams, param1, 0, 0, 0);
+	status = dvbt_sc_command(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
+				0, transmission_params, param1, 0, 0, 0);
 	if (status < 0)
 		goto error;
 
-	if (!state->m_DRXK_A3_ROM_CODE)
-		status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
+	if (!state->m_drxk_a3_rom_code)
+		status = dvbt_ctrl_set_sqi_speed(state, &state->m_sqi_speed);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -4083,7 +4087,7 @@
 * \return DRXStatus_t.
 *
 */
-static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
+static int get_dvbt_lock_status(struct drxk_state *state, u32 *p_lock_status)
 {
 	int status;
 	const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
@@ -4091,58 +4095,58 @@
 	const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
 	const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
 
-	u16 ScRaRamLock = 0;
-	u16 ScCommExec = 0;
+	u16 sc_ra_ram_lock = 0;
+	u16 sc_comm_exec = 0;
 
 	dprintk(1, "\n");
 
-	*pLockStatus = NOT_LOCKED;
+	*p_lock_status = NOT_LOCKED;
 	/* driver 0.9.0 */
 	/* Check if SC is running */
-	status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
+	status = read16(state, OFDM_SC_COMM_EXEC__A, &sc_comm_exec);
 	if (status < 0)
 		goto end;
-	if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
+	if (sc_comm_exec == OFDM_SC_COMM_EXEC_STOP)
 		goto end;
 
-	status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
+	status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &sc_ra_ram_lock);
 	if (status < 0)
 		goto end;
 
-	if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
-		*pLockStatus = MPEG_LOCK;
-	else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
-		*pLockStatus = FEC_LOCK;
-	else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
-		*pLockStatus = DEMOD_LOCK;
-	else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
-		*pLockStatus = NEVER_LOCK;
+	if ((sc_ra_ram_lock & mpeg_lock_mask) == mpeg_lock_mask)
+		*p_lock_status = MPEG_LOCK;
+	else if ((sc_ra_ram_lock & fec_lock_mask) == fec_lock_mask)
+		*p_lock_status = FEC_LOCK;
+	else if ((sc_ra_ram_lock & demod_lock_mask) == demod_lock_mask)
+		*p_lock_status = DEMOD_LOCK;
+	else if (sc_ra_ram_lock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
+		*p_lock_status = NEVER_LOCK;
 end:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
-static int PowerUpQAM(struct drxk_state *state)
+static int power_up_qam(struct drxk_state *state)
 {
-	enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
+	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
 	int status;
 
 	dprintk(1, "\n");
-	status = CtrlPowerMode(state, &powerMode);
+	status = ctrl_power_mode(state, &power_mode);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
 
 
 /** Power Down QAM */
-static int PowerDownQAM(struct drxk_state *state)
+static int power_down_qam(struct drxk_state *state)
 {
 	u16 data = 0;
-	u16 cmdResult;
+	u16 cmd_result;
 	int status = 0;
 
 	dprintk(1, "\n");
@@ -4158,16 +4162,18 @@
 		status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
 		if (status < 0)
 			goto error;
-		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
+		status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_STOP,
+				     0, NULL, 1, &cmd_result);
 		if (status < 0)
 			goto error;
 	}
 	/* powerdown AFE                   */
-	status = SetIqmAf(state, false);
+	status = set_iqm_af(state, false);
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -4185,20 +4191,20 @@
 *  The implementation does not check this.
 *
 */
-static int SetQAMMeasurement(struct drxk_state *state,
-			     enum EDrxkConstellation modulation,
-			     u32 symbolRate)
+static int set_qam_measurement(struct drxk_state *state,
+			     enum e_drxk_constellation modulation,
+			     u32 symbol_rate)
 {
-	u32 fecBitsDesired = 0;	/* BER accounting period */
-	u32 fecRsPeriodTotal = 0;	/* Total period */
-	u16 fecRsPrescale = 0;	/* ReedSolomon Measurement Prescale */
-	u16 fecRsPeriod = 0;	/* Value for corresponding I2C register */
+	u32 fec_bits_desired = 0;	/* BER accounting period */
+	u32 fec_rs_period_total = 0;	/* Total period */
+	u16 fec_rs_prescale = 0;	/* ReedSolomon Measurement Prescale */
+	u16 fec_rs_period = 0;	/* Value for corresponding I2C register */
 	int status = 0;
 
 	dprintk(1, "\n");
 
-	fecRsPrescale = 1;
-	/* fecBitsDesired = symbolRate [kHz] *
+	fec_rs_prescale = 1;
+	/* fec_bits_desired = symbol_rate [kHz] *
 		FrameLenght [ms] *
 		(modulation + 1) *
 		SyncLoss (== 1) *
@@ -4206,19 +4212,19 @@
 		*/
 	switch (modulation) {
 	case DRX_CONSTELLATION_QAM16:
-		fecBitsDesired = 4 * symbolRate;
+		fec_bits_desired = 4 * symbol_rate;
 		break;
 	case DRX_CONSTELLATION_QAM32:
-		fecBitsDesired = 5 * symbolRate;
+		fec_bits_desired = 5 * symbol_rate;
 		break;
 	case DRX_CONSTELLATION_QAM64:
-		fecBitsDesired = 6 * symbolRate;
+		fec_bits_desired = 6 * symbol_rate;
 		break;
 	case DRX_CONSTELLATION_QAM128:
-		fecBitsDesired = 7 * symbolRate;
+		fec_bits_desired = 7 * symbol_rate;
 		break;
 	case DRX_CONSTELLATION_QAM256:
-		fecBitsDesired = 8 * symbolRate;
+		fec_bits_desired = 8 * symbol_rate;
 		break;
 	default:
 		status = -EINVAL;
@@ -4226,40 +4232,41 @@
 	if (status < 0)
 		goto error;
 
-	fecBitsDesired /= 1000;	/* symbolRate [Hz] -> symbolRate [kHz]  */
-	fecBitsDesired *= 500;	/* meas. period [ms] */
+	fec_bits_desired /= 1000;	/* symbol_rate [Hz] -> symbol_rate [kHz] */
+	fec_bits_desired *= 500;	/* meas. period [ms] */
 
 	/* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
-	/* fecRsPeriodTotal = fecBitsDesired / 1632 */
-	fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1;	/* roughly ceil */
+	/* fec_rs_period_total = fec_bits_desired / 1632 */
+	fec_rs_period_total = (fec_bits_desired / 1632UL) + 1;	/* roughly ceil */
 
-	/* fecRsPeriodTotal =  fecRsPrescale * fecRsPeriod  */
-	fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
-	if (fecRsPrescale == 0) {
+	/* fec_rs_period_total =  fec_rs_prescale * fec_rs_period  */
+	fec_rs_prescale = 1 + (u16) (fec_rs_period_total >> 16);
+	if (fec_rs_prescale == 0) {
 		/* Divide by zero (though impossible) */
 		status = -EINVAL;
 		if (status < 0)
 			goto error;
 	}
-	fecRsPeriod =
-		((u16) fecRsPeriodTotal +
-		(fecRsPrescale >> 1)) / fecRsPrescale;
+	fec_rs_period =
+		((u16) fec_rs_period_total +
+		(fec_rs_prescale >> 1)) / fec_rs_prescale;
 
 	/* write corresponding registers */
-	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
+	status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fec_rs_period);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
+	status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A,
+			 fec_rs_prescale);
 	if (status < 0)
 		goto error;
-	status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
+	status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fec_rs_period);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetQAM16(struct drxk_state *state)
+static int set_qam16(struct drxk_state *state)
 {
 	int status = 0;
 
@@ -4315,7 +4322,8 @@
 		goto error;
 
 	/* QAM Slicer Settings */
-	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
+	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+			 DRXK_QAM_SL_SIG_POWER_QAM16);
 	if (status < 0)
 		goto error;
 
@@ -4441,7 +4449,7 @@
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -4452,7 +4460,7 @@
 * \param demod instance of demod.
 * \return DRXStatus_t.
 */
-static int SetQAM32(struct drxk_state *state)
+static int set_qam32(struct drxk_state *state)
 {
 	int status = 0;
 
@@ -4511,7 +4519,8 @@
 
 	/* QAM Slicer Settings */
 
-	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
+	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+			 DRXK_QAM_SL_SIG_POWER_QAM32);
 	if (status < 0)
 		goto error;
 
@@ -4636,7 +4645,7 @@
 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -4647,7 +4656,7 @@
 * \param demod instance of demod.
 * \return DRXStatus_t.
 */
-static int SetQAM64(struct drxk_state *state)
+static int set_qam64(struct drxk_state *state)
 {
 	int status = 0;
 
@@ -4704,7 +4713,8 @@
 		goto error;
 
 	/* QAM Slicer Settings */
-	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
+	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+			 DRXK_QAM_SL_SIG_POWER_QAM64);
 	if (status < 0)
 		goto error;
 
@@ -4829,7 +4839,7 @@
 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -4841,7 +4851,7 @@
 * \param demod: instance of demod.
 * \return DRXStatus_t.
 */
-static int SetQAM128(struct drxk_state *state)
+static int set_qam128(struct drxk_state *state)
 {
 	int status = 0;
 
@@ -4900,7 +4910,8 @@
 
 	/* QAM Slicer Settings */
 
-	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
+	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+			 DRXK_QAM_SL_SIG_POWER_QAM128);
 	if (status < 0)
 		goto error;
 
@@ -5025,7 +5036,7 @@
 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -5037,7 +5048,7 @@
 * \param demod: instance of demod.
 * \return DRXStatus_t.
 */
-static int SetQAM256(struct drxk_state *state)
+static int set_qam256(struct drxk_state *state)
 {
 	int status = 0;
 
@@ -5095,7 +5106,8 @@
 
 	/* QAM Slicer Settings */
 
-	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
+	status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A,
+			 DRXK_QAM_SL_SIG_POWER_QAM256);
 	if (status < 0)
 		goto error;
 
@@ -5220,7 +5232,7 @@
 	status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -5232,10 +5244,10 @@
 * \param channel: pointer to channel data.
 * \return DRXStatus_t.
 */
-static int QAMResetQAM(struct drxk_state *state)
+static int qam_reset_qam(struct drxk_state *state)
 {
 	int status;
-	u16 cmdResult;
+	u16 cmd_result;
 
 	dprintk(1, "\n");
 	/* Stop QAM comstate->m_exec */
@@ -5243,10 +5255,12 @@
 	if (status < 0)
 		goto error;
 
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
+	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
+			     | SCU_RAM_COMMAND_CMD_DEMOD_RESET,
+			     0, NULL, 1, &cmd_result);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -5258,18 +5272,18 @@
 * \param channel: pointer to channel data.
 * \return DRXStatus_t.
 */
-static int QAMSetSymbolrate(struct drxk_state *state)
+static int qam_set_symbolrate(struct drxk_state *state)
 {
-	u32 adcFrequency = 0;
-	u32 symbFreq = 0;
-	u32 iqmRcRate = 0;
+	u32 adc_frequency = 0;
+	u32 symb_freq = 0;
+	u32 iqm_rc_rate = 0;
 	u16 ratesel = 0;
-	u32 lcSymbRate = 0;
+	u32 lc_symb_rate = 0;
 	int status;
 
 	dprintk(1, "\n");
 	/* Select & calculate correct IQM rate */
-	adcFrequency = (state->m_sysClockFreq * 1000) / 3;
+	adc_frequency = (state->m_sys_clock_freq * 1000) / 3;
 	ratesel = 0;
 	/* printk(KERN_DEBUG "drxk: SR %d\n", state->props.symbol_rate); */
 	if (state->props.symbol_rate <= 1188750)
@@ -5285,38 +5299,38 @@
 	/*
 		IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
 		*/
-	symbFreq = state->props.symbol_rate * (1 << ratesel);
-	if (symbFreq == 0) {
+	symb_freq = state->props.symbol_rate * (1 << ratesel);
+	if (symb_freq == 0) {
 		/* Divide by zero */
 		status = -EINVAL;
 		goto error;
 	}
-	iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
-		(Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
+	iqm_rc_rate = (adc_frequency / symb_freq) * (1 << 21) +
+		(Frac28a((adc_frequency % symb_freq), symb_freq) >> 7) -
 		(1 << 23);
-	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
+	status = write32(state, IQM_RC_RATE_OFS_LO__A, iqm_rc_rate);
 	if (status < 0)
 		goto error;
-	state->m_iqmRcRate = iqmRcRate;
+	state->m_iqm_rc_rate = iqm_rc_rate;
 	/*
-		LcSymbFreq = round (.125 *  symbolrate / adcFreq * (1<<15))
+		LcSymbFreq = round (.125 *  symbolrate / adc_freq * (1<<15))
 		*/
-	symbFreq = state->props.symbol_rate;
-	if (adcFrequency == 0) {
+	symb_freq = state->props.symbol_rate;
+	if (adc_frequency == 0) {
 		/* Divide by zero */
 		status = -EINVAL;
 		goto error;
 	}
-	lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
-		(Frac28a((symbFreq % adcFrequency), adcFrequency) >>
+	lc_symb_rate = (symb_freq / adc_frequency) * (1 << 12) +
+		(Frac28a((symb_freq % adc_frequency), adc_frequency) >>
 		16);
-	if (lcSymbRate > 511)
-		lcSymbRate = 511;
-	status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
+	if (lc_symb_rate > 511)
+		lc_symb_rate = 511;
+	status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lc_symb_rate);
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
@@ -5329,34 +5343,36 @@
 * \return DRXStatus_t.
 */
 
-static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
+static int get_qam_lock_status(struct drxk_state *state, u32 *p_lock_status)
 {
 	int status;
-	u16 Result[2] = { 0, 0 };
+	u16 result[2] = { 0, 0 };
 
 	dprintk(1, "\n");
-	*pLockStatus = NOT_LOCKED;
+	*p_lock_status = NOT_LOCKED;
 	status = scu_command(state,
 			SCU_RAM_COMMAND_STANDARD_QAM |
 			SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
-			Result);
+			result);
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
-	if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
+	if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
 		/* 0x0000 NOT LOCKED */
-	} else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
+	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
 		/* 0x4000 DEMOD LOCKED */
-		*pLockStatus = DEMOD_LOCK;
-	} else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
+		*p_lock_status = DEMOD_LOCK;
+	} else if (result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
 		/* 0x8000 DEMOD + FEC LOCKED (system lock) */
-		*pLockStatus = MPEG_LOCK;
+		*p_lock_status = MPEG_LOCK;
 	} else {
 		/* 0xC000 NEVER LOCKED */
 		/* (system will never be able to lock to the signal) */
-		/* TODO: check this, intermediate & standard specific lock states are not
-		   taken into account here */
-		*pLockStatus = NEVER_LOCK;
+		/*
+		 * TODO: check this, intermediate & standard specific lock
+		 * states are not taken into account here
+		 */
+		*p_lock_status = NEVER_LOCK;
 	}
 	return status;
 }
@@ -5368,68 +5384,70 @@
 #define QAM_LOCKRANGE__M      0x10
 #define QAM_LOCKRANGE_NORMAL  0x10
 
-static int QAMDemodulatorCommand(struct drxk_state *state,
-				 int numberOfParameters)
+static int qam_demodulator_command(struct drxk_state *state,
+				 int number_of_parameters)
 {
 	int status;
-	u16 cmdResult;
-	u16 setParamParameters[4] = { 0, 0, 0, 0 };
+	u16 cmd_result;
+	u16 set_param_parameters[4] = { 0, 0, 0, 0 };
 
-	setParamParameters[0] = state->m_Constellation;	/* modulation     */
-	setParamParameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */
+	set_param_parameters[0] = state->m_constellation;	/* modulation     */
+	set_param_parameters[1] = DRXK_QAM_I12_J17;	/* interleave mode   */
 
-	if (numberOfParameters == 2) {
-		u16 setEnvParameters[1] = { 0 };
+	if (number_of_parameters == 2) {
+		u16 set_env_parameters[1] = { 0 };
 
-		if (state->m_OperationMode == OM_QAM_ITU_C)
-			setEnvParameters[0] = QAM_TOP_ANNEX_C;
+		if (state->m_operation_mode == OM_QAM_ITU_C)
+			set_env_parameters[0] = QAM_TOP_ANNEX_C;
 		else
-			setEnvParameters[0] = QAM_TOP_ANNEX_A;
+			set_env_parameters[0] = QAM_TOP_ANNEX_A;
 
 		status = scu_command(state,
-				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
-				     1, setEnvParameters, 1, &cmdResult);
+				     SCU_RAM_COMMAND_STANDARD_QAM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
+				     1, set_env_parameters, 1, &cmd_result);
 		if (status < 0)
 			goto error;
 
 		status = scu_command(state,
-				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
-				     numberOfParameters, setParamParameters,
-				     1, &cmdResult);
-	} else if (numberOfParameters == 4) {
-		if (state->m_OperationMode == OM_QAM_ITU_C)
-			setParamParameters[2] = QAM_TOP_ANNEX_C;
+				     SCU_RAM_COMMAND_STANDARD_QAM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
+				     number_of_parameters, set_param_parameters,
+				     1, &cmd_result);
+	} else if (number_of_parameters == 4) {
+		if (state->m_operation_mode == OM_QAM_ITU_C)
+			set_param_parameters[2] = QAM_TOP_ANNEX_C;
 		else
-			setParamParameters[2] = QAM_TOP_ANNEX_A;
+			set_param_parameters[2] = QAM_TOP_ANNEX_A;
 
-		setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
+		set_param_parameters[3] |= (QAM_MIRROR_AUTO_ON);
 		/* Env parameters */
 		/* check for LOCKRANGE Extented */
-		/* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
+		/* set_param_parameters[3] |= QAM_LOCKRANGE_NORMAL; */
 
 		status = scu_command(state,
-				     SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
-				     numberOfParameters, setParamParameters,
-				     1, &cmdResult);
+				     SCU_RAM_COMMAND_STANDARD_QAM
+				     | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
+				     number_of_parameters, set_param_parameters,
+				     1, &cmd_result);
 	} else {
-		printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
-			"count %d\n", numberOfParameters);
+		pr_warn("Unknown QAM demodulator parameter count %d\n",
+			number_of_parameters);
 		status = -EINVAL;
 	}
 
 error:
 	if (status < 0)
-		printk(KERN_WARNING "drxk: Warning %d on %s\n",
-		       status, __func__);
+		pr_warn("Warning %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
-		  s32 tunerFreqOffset)
+static int set_qam(struct drxk_state *state, u16 intermediate_freqk_hz,
+		  s32 tuner_freq_offset)
 {
 	int status;
-	u16 cmdResult;
-	int qamDemodParamCount = state->qam_demod_parameter_count;
+	u16 cmd_result;
+	int qam_demod_param_count = state->qam_demod_parameter_count;
 
 	dprintk(1, "\n");
 	/*
@@ -5444,7 +5462,7 @@
 	status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
 	if (status < 0)
 		goto error;
-	status = QAMResetQAM(state);
+	status = qam_reset_qam(state);
 	if (status < 0)
 		goto error;
 
@@ -5453,27 +5471,27 @@
 	 *	-set params; resets IQM,QAM,FEC HW; initializes some
 	 *       SCU variables
 	 */
-	status = QAMSetSymbolrate(state);
+	status = qam_set_symbolrate(state);
 	if (status < 0)
 		goto error;
 
 	/* Set params */
 	switch (state->props.modulation) {
 	case QAM_256:
-		state->m_Constellation = DRX_CONSTELLATION_QAM256;
+		state->m_constellation = DRX_CONSTELLATION_QAM256;
 		break;
 	case QAM_AUTO:
 	case QAM_64:
-		state->m_Constellation = DRX_CONSTELLATION_QAM64;
+		state->m_constellation = DRX_CONSTELLATION_QAM64;
 		break;
 	case QAM_16:
-		state->m_Constellation = DRX_CONSTELLATION_QAM16;
+		state->m_constellation = DRX_CONSTELLATION_QAM16;
 		break;
 	case QAM_32:
-		state->m_Constellation = DRX_CONSTELLATION_QAM32;
+		state->m_constellation = DRX_CONSTELLATION_QAM32;
 		break;
 	case QAM_128:
-		state->m_Constellation = DRX_CONSTELLATION_QAM128;
+		state->m_constellation = DRX_CONSTELLATION_QAM128;
 		break;
 	default:
 		status = -EINVAL;
@@ -5486,8 +5504,8 @@
 	 * the correct command. */
 	if (state->qam_demod_parameter_count == 4
 		|| !state->qam_demod_parameter_count) {
-		qamDemodParamCount = 4;
-		status = QAMDemodulatorCommand(state, qamDemodParamCount);
+		qam_demod_param_count = 4;
+		status = qam_demodulator_command(state, qam_demod_param_count);
 	}
 
 	/* Use the 2-parameter command if it was requested or if we're
@@ -5495,27 +5513,27 @@
 	 * failed. */
 	if (state->qam_demod_parameter_count == 2
 		|| (!state->qam_demod_parameter_count && status < 0)) {
-		qamDemodParamCount = 2;
-		status = QAMDemodulatorCommand(state, qamDemodParamCount);
+		qam_demod_param_count = 2;
+		status = qam_demodulator_command(state, qam_demod_param_count);
 	}
 
 	if (status < 0) {
-		dprintk(1, "Could not set demodulator parameters. Make "
-			"sure qam_demod_parameter_count (%d) is correct for "
-			"your firmware (%s).\n",
+		dprintk(1, "Could not set demodulator parameters.\n");
+		dprintk(1,
+			"Make sure qam_demod_parameter_count (%d) is correct for your firmware (%s).\n",
 			state->qam_demod_parameter_count,
 			state->microcode_name);
 		goto error;
 	} else if (!state->qam_demod_parameter_count) {
-		dprintk(1, "Auto-probing the correct QAM demodulator command "
-			"parameters was successful - using %d parameters.\n",
-			qamDemodParamCount);
+		dprintk(1,
+			"Auto-probing the QAM command parameters was successful - using %d parameters.\n",
+			qam_demod_param_count);
 
 		/*
 		 * One of our commands was successful. We don't need to
 		 * auto-probe anymore, now that we got the correct command.
 		 */
-		state->qam_demod_parameter_count = qamDemodParamCount;
+		state->qam_demod_parameter_count = qam_demod_param_count;
 	}
 
 	/*
@@ -5523,16 +5541,18 @@
 	 * signal setup modulation independent registers
 	 */
 #if 0
-	status = SetFrequency(channel, tunerFreqOffset));
+	status = set_frequency(channel, tuner_freq_offset));
 	if (status < 0)
 		goto error;
 #endif
-	status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
+	status = set_frequency_shifter(state, intermediate_freqk_hz,
+				       tuner_freq_offset, true);
 	if (status < 0)
 		goto error;
 
 	/* Setup BER measurement */
-	status = SetQAMMeasurement(state, state->m_Constellation, state->props.symbol_rate);
+	status = set_qam_measurement(state, state->m_constellation,
+				     state->props.symbol_rate);
 	if (status < 0)
 		goto error;
 
@@ -5605,7 +5625,8 @@
 		goto error;
 
 	/* Mirroring, QAM-block starting point not inverted */
-	status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
+	status = write16(state, QAM_SY_SP_INV__A,
+			 QAM_SY_SP_INV_SPECTRUM_INV_DIS);
 	if (status < 0)
 		goto error;
 
@@ -5617,20 +5638,20 @@
 	/* STEP 4: modulation specific setup */
 	switch (state->props.modulation) {
 	case QAM_16:
-		status = SetQAM16(state);
+		status = set_qam16(state);
 		break;
 	case QAM_32:
-		status = SetQAM32(state);
+		status = set_qam32(state);
 		break;
 	case QAM_AUTO:
 	case QAM_64:
-		status = SetQAM64(state);
+		status = set_qam64(state);
 		break;
 	case QAM_128:
-		status = SetQAM128(state);
+		status = set_qam128(state);
 		break;
 	case QAM_256:
-		status = SetQAM256(state);
+		status = set_qam256(state);
 		break;
 	default:
 		status = -EINVAL;
@@ -5647,12 +5668,12 @@
 	/* Re-configure MPEG output, requires knowledge of channel bitrate */
 	/* extAttr->currentChannel.modulation = channel->modulation; */
 	/* extAttr->currentChannel.symbolrate    = channel->symbolrate; */
-	status = MPEGTSDtoSetup(state, state->m_OperationMode);
+	status = mpegts_dto_setup(state, state->m_operation_mode);
 	if (status < 0)
 		goto error;
 
-	/* Start processes */
-	status = MPEGTSStart(state);
+	/* start processes */
+	status = mpegts_start(state);
 	if (status < 0)
 		goto error;
 	status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
@@ -5666,7 +5687,9 @@
 		goto error;
 
 	/* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
-	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
+	status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM
+			     | SCU_RAM_COMMAND_CMD_DEMOD_START,
+			     0, NULL, 1, &cmd_result);
 	if (status < 0)
 		goto error;
 
@@ -5675,12 +5698,12 @@
 
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SetQAMStandard(struct drxk_state *state,
-			  enum OperationMode oMode)
+static int set_qam_standard(struct drxk_state *state,
+			  enum operation_mode o_mode)
 {
 	int status;
 #ifdef DRXK_QAM_TAPS
@@ -5692,14 +5715,14 @@
 	dprintk(1, "\n");
 
 	/* added antenna switch */
-	SwitchAntennaToQAM(state);
+	switch_antenna_to_qam(state);
 
 	/* Ensure correct power-up mode */
-	status = PowerUpQAM(state);
+	status = power_up_qam(state);
 	if (status < 0)
 		goto error;
 	/* Reset QAM block */
-	status = QAMResetQAM(state);
+	status = qam_reset_qam(state);
 	if (status < 0)
 		goto error;
 
@@ -5714,15 +5737,24 @@
 
 	/* Upload IQM Channel Filter settings by
 		boot loader from ROM table */
-	switch (oMode) {
+	switch (o_mode) {
 	case OM_QAM_ITU_A:
-		status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+		status = bl_chain_cmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A,
+				      DRXK_BLCC_NR_ELEMENTS_TAPS,
+			DRXK_BLC_TIMEOUT);
 		break;
 	case OM_QAM_ITU_C:
-		status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+		status = bl_direct_cmd(state, IQM_CF_TAP_RE0__A,
+				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
+				       DRXK_BLDC_NR_ELEMENTS_TAPS,
+				       DRXK_BLC_TIMEOUT);
 		if (status < 0)
 			goto error;
-		status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
+		status = bl_direct_cmd(state,
+				       IQM_CF_TAP_IM0__A,
+				       DRXK_BL_ROM_OFFSET_TAPS_ITU_C,
+				       DRXK_BLDC_NR_ELEMENTS_TAPS,
+				       DRXK_BLC_TIMEOUT);
 		break;
 	default:
 		status = -EINVAL;
@@ -5730,13 +5762,14 @@
 	if (status < 0)
 		goto error;
 
-	status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
+	status = write16(state, IQM_CF_OUT_ENA__A, 1 << IQM_CF_OUT_ENA_QAM__B);
 	if (status < 0)
 		goto error;
 	status = write16(state, IQM_CF_SYMMETRIC__A, 0);
 	if (status < 0)
 		goto error;
-	status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
+	status = write16(state, IQM_CF_MIDTAP__A,
+		     ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
 	if (status < 0)
 		goto error;
 
@@ -5793,7 +5826,7 @@
 		goto error;
 
 	/* turn on IQMAF. Must be done before setAgc**() */
-	status = SetIqmAf(state, true);
+	status = set_iqm_af(state, true);
 	if (status < 0)
 		goto error;
 	status = write16(state, IQM_AF_START_LOCK__A, 0x01);
@@ -5801,7 +5834,7 @@
 		goto error;
 
 	/* IQM will not be reset from here, sync ADC and update/init AGC */
-	status = ADCSynchronization(state);
+	status = adc_synchronization(state);
 	if (status < 0)
 		goto error;
 
@@ -5818,18 +5851,18 @@
 	/* No more resets of the IQM, current standard correctly set =>
 		now AGCs can be configured. */
 
-	status = InitAGC(state, true);
+	status = init_agc(state, true);
 	if (status < 0)
 		goto error;
-	status = SetPreSaw(state, &(state->m_qamPreSawCfg));
+	status = set_pre_saw(state, &(state->m_qam_pre_saw_cfg));
 	if (status < 0)
 		goto error;
 
 	/* Configure AGC's */
-	status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
+	status = set_agc_rf(state, &(state->m_qam_rf_agc_cfg), true);
 	if (status < 0)
 		goto error;
-	status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
+	status = set_agc_if(state, &(state->m_qam_if_agc_cfg), true);
 	if (status < 0)
 		goto error;
 
@@ -5837,18 +5870,19 @@
 	status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int WriteGPIO(struct drxk_state *state)
+static int write_gpio(struct drxk_state *state)
 {
 	int status;
 	u16 value = 0;
 
 	dprintk(1, "\n");
 	/* stop lock indicator process */
-	status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+	status = write16(state, SCU_RAM_GPIO__A,
+			 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 	if (status < 0)
 		goto error;
 
@@ -5857,10 +5891,11 @@
 	if (status < 0)
 		goto error;
 
-	if (state->m_hasSAWSW) {
-		if (state->UIO_mask & 0x0001) { /* UIO-1 */
+	if (state->m_has_sawsw) {
+		if (state->uio_mask & 0x0001) { /* UIO-1 */
 			/* write to io pad configuration register - output mode */
-			status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
+			status = write16(state, SIO_PDR_SMA_TX_CFG__A,
+					 state->m_gpio_cfg);
 			if (status < 0)
 				goto error;
 
@@ -5868,7 +5903,7 @@
 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
 			if (status < 0)
 				goto error;
-			if ((state->m_GPIO & 0x0001) == 0)
+			if ((state->m_gpio & 0x0001) == 0)
 				value &= 0x7FFF;	/* write zero to 15th bit - 1st UIO */
 			else
 				value |= 0x8000;	/* write one to 15th bit - 1st UIO */
@@ -5877,9 +5912,10 @@
 			if (status < 0)
 				goto error;
 		}
-		if (state->UIO_mask & 0x0002) { /* UIO-2 */
+		if (state->uio_mask & 0x0002) { /* UIO-2 */
 			/* write to io pad configuration register - output mode */
-			status = write16(state, SIO_PDR_SMA_RX_CFG__A, state->m_GPIOCfg);
+			status = write16(state, SIO_PDR_SMA_RX_CFG__A,
+					 state->m_gpio_cfg);
 			if (status < 0)
 				goto error;
 
@@ -5887,7 +5923,7 @@
 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
 			if (status < 0)
 				goto error;
-			if ((state->m_GPIO & 0x0002) == 0)
+			if ((state->m_gpio & 0x0002) == 0)
 				value &= 0xBFFF;	/* write zero to 14th bit - 2st UIO */
 			else
 				value |= 0x4000;	/* write one to 14th bit - 2st UIO */
@@ -5896,9 +5932,10 @@
 			if (status < 0)
 				goto error;
 		}
-		if (state->UIO_mask & 0x0004) { /* UIO-3 */
+		if (state->uio_mask & 0x0004) { /* UIO-3 */
 			/* write to io pad configuration register - output mode */
-			status = write16(state, SIO_PDR_GPIO_CFG__A, state->m_GPIOCfg);
+			status = write16(state, SIO_PDR_GPIO_CFG__A,
+					 state->m_gpio_cfg);
 			if (status < 0)
 				goto error;
 
@@ -5906,7 +5943,7 @@
 			status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
 			if (status < 0)
 				goto error;
-			if ((state->m_GPIO & 0x0004) == 0)
+			if ((state->m_gpio & 0x0004) == 0)
 				value &= 0xFFFB;            /* write zero to 2nd bit - 3rd UIO */
 			else
 				value |= 0x0004;            /* write one to 2nd bit - 3rd UIO */
@@ -5920,11 +5957,11 @@
 	status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SwitchAntennaToQAM(struct drxk_state *state)
+static int switch_antenna_to_qam(struct drxk_state *state)
 {
 	int status = 0;
 	bool gpio_state;
@@ -5934,22 +5971,22 @@
 	if (!state->antenna_gpio)
 		return 0;
 
-	gpio_state = state->m_GPIO & state->antenna_gpio;
+	gpio_state = state->m_gpio & state->antenna_gpio;
 
 	if (state->antenna_dvbt ^ gpio_state) {
 		/* Antenna is on DVB-T mode. Switch */
 		if (state->antenna_dvbt)
-			state->m_GPIO &= ~state->antenna_gpio;
+			state->m_gpio &= ~state->antenna_gpio;
 		else
-			state->m_GPIO |= state->antenna_gpio;
-		status = WriteGPIO(state);
+			state->m_gpio |= state->antenna_gpio;
+		status = write_gpio(state);
 	}
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
-static int SwitchAntennaToDVBT(struct drxk_state *state)
+static int switch_antenna_to_dvbt(struct drxk_state *state)
 {
 	int status = 0;
 	bool gpio_state;
@@ -5959,23 +5996,23 @@
 	if (!state->antenna_gpio)
 		return 0;
 
-	gpio_state = state->m_GPIO & state->antenna_gpio;
+	gpio_state = state->m_gpio & state->antenna_gpio;
 
 	if (!(state->antenna_dvbt ^ gpio_state)) {
 		/* Antenna is on DVB-C mode. Switch */
 		if (state->antenna_dvbt)
-			state->m_GPIO |= state->antenna_gpio;
+			state->m_gpio |= state->antenna_gpio;
 		else
-			state->m_GPIO &= ~state->antenna_gpio;
-		status = WriteGPIO(state);
+			state->m_gpio &= ~state->antenna_gpio;
+		status = write_gpio(state);
 	}
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	return status;
 }
 
 
-static int PowerDownDevice(struct drxk_state *state)
+static int power_down_device(struct drxk_state *state)
 {
 	/* Power down to requested mode */
 	/* Backup some register settings */
@@ -5986,28 +6023,29 @@
 	int status;
 
 	dprintk(1, "\n");
-	if (state->m_bPDownOpenBridge) {
+	if (state->m_b_p_down_open_bridge) {
 		/* Open I2C bridge before power down of DRXK */
 		status = ConfigureI2CBridge(state, true);
 		if (status < 0)
 			goto error;
 	}
 	/* driver 0.9.0 */
-	status = DVBTEnableOFDMTokenRing(state, false);
+	status = dvbt_enable_ofdm_token_ring(state, false);
 	if (status < 0)
 		goto error;
 
-	status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
+	status = write16(state, SIO_CC_PWD_MODE__A,
+			 SIO_CC_PWD_MODE_LEVEL_CLOCK);
 	if (status < 0)
 		goto error;
 	status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
 	if (status < 0)
 		goto error;
-	state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
-	status = HI_CfgCommand(state);
+	state->m_hi_cfg_ctrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
+	status = hi_cfg_command(state);
 error:
 	if (status < 0)
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 
 	return status;
 }
@@ -6015,50 +6053,56 @@
 static int init_drxk(struct drxk_state *state)
 {
 	int status = 0, n = 0;
-	enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
-	u16 driverVersion;
+	enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM;
+	u16 driver_version;
 
 	dprintk(1, "\n");
-	if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
+	if ((state->m_drxk_state == DRXK_UNINITIALIZED)) {
 		drxk_i2c_lock(state);
-		status = PowerUpDevice(state);
+		status = power_up_device(state);
 		if (status < 0)
 			goto error;
-		status = DRXX_Open(state);
+		status = drxx_open(state);
 		if (status < 0)
 			goto error;
 		/* Soft reset of OFDM-, sys- and osc-clockdomain */
-		status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
+		status = write16(state, SIO_CC_SOFT_RST__A,
+				 SIO_CC_SOFT_RST_OFDM__M
+				 | SIO_CC_SOFT_RST_SYS__M
+				 | SIO_CC_SOFT_RST_OSC__M);
 		if (status < 0)
 			goto error;
 		status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
 		if (status < 0)
 			goto error;
-		/* TODO is this needed, if yes how much delay in worst case scenario */
-		msleep(1);
-		state->m_DRXK_A3_PATCH_CODE = true;
-		status = GetDeviceCapabilities(state);
+		/*
+		 * TODO is this needed? If yes, how much delay in
+		 * worst case scenario
+		 */
+		usleep_range(1000, 2000);
+		state->m_drxk_a3_patch_code = true;
+		status = get_device_capabilities(state);
 		if (status < 0)
 			goto error;
 
 		/* Bridge delay, uses oscilator clock */
 		/* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
 		/* SDA brdige delay */
-		state->m_HICfgBridgeDelay =
-			(u16) ((state->m_oscClockFreq / 1000) *
+		state->m_hi_cfg_bridge_delay =
+			(u16) ((state->m_osc_clock_freq / 1000) *
 				HI_I2C_BRIDGE_DELAY) / 1000;
 		/* Clipping */
-		if (state->m_HICfgBridgeDelay >
+		if (state->m_hi_cfg_bridge_delay >
 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
-			state->m_HICfgBridgeDelay =
+			state->m_hi_cfg_bridge_delay =
 				SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
 		}
 		/* SCL bridge delay, same as SDA for now */
-		state->m_HICfgBridgeDelay +=
-			state->m_HICfgBridgeDelay <<
+		state->m_hi_cfg_bridge_delay +=
+			state->m_hi_cfg_bridge_delay <<
 			SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
 
-		status = InitHI(state);
+		status = init_hi(state);
 		if (status < 0)
 			goto error;
 		/* disable various processes */
@@ -6067,13 +6111,14 @@
 			&& !(state->m_DRXK_A2_ROM_CODE))
 #endif
 		{
-			status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
+			status = write16(state, SCU_RAM_GPIO__A,
+					 SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
 			if (status < 0)
 				goto error;
 		}
 
 		/* disable MPEG port */
-		status = MPEGTSDisable(state);
+		status = mpegts_disable(state);
 		if (status < 0)
 			goto error;
 
@@ -6086,27 +6131,30 @@
 			goto error;
 
 		/* enable token-ring bus through OFDM block for possible ucode upload */
-		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
+		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
+				 SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
 		if (status < 0)
 			goto error;
 
 		/* include boot loader section */
-		status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
+		status = write16(state, SIO_BL_COMM_EXEC__A,
+				 SIO_BL_COMM_EXEC_ACTIVE);
 		if (status < 0)
 			goto error;
-		status = BLChainCmd(state, 0, 6, 100);
+		status = bl_chain_cmd(state, 0, 6, 100);
 		if (status < 0)
 			goto error;
 
 		if (state->fw) {
-			status = DownloadMicrocode(state, state->fw->data,
+			status = download_microcode(state, state->fw->data,
 						   state->fw->size);
 			if (status < 0)
 				goto error;
 		}
 
 		/* disable token-ring bus through OFDM block for possible ucode upload */
-		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
+		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A,
+				 SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
 		if (status < 0)
 			goto error;
 
@@ -6114,14 +6162,14 @@
 		status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
 		if (status < 0)
 			goto error;
-		status = DRXX_Open(state);
+		status = drxx_open(state);
 		if (status < 0)
 			goto error;
 		/* added for test */
 		msleep(30);
 
-		powerMode = DRXK_POWER_DOWN_OFDM;
-		status = CtrlPowerMode(state, &powerMode);
+		power_mode = DRXK_POWER_DOWN_OFDM;
+		status = ctrl_power_mode(state, &power_mode);
 		if (status < 0)
 			goto error;
 
@@ -6131,33 +6179,38 @@
 			Not using SCU command interface for SCU register access since no
 			microcode may be present.
 			*/
-		driverVersion =
+		driver_version =
 			(((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
 			(((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
 			((DRXK_VERSION_MAJOR % 10) << 4) +
 			(DRXK_VERSION_MINOR % 10);
-		status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
+		status = write16(state, SCU_RAM_DRIVER_VER_HI__A,
+				 driver_version);
 		if (status < 0)
 			goto error;
-		driverVersion =
+		driver_version =
 			(((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
 			(((DRXK_VERSION_PATCH / 100) % 10) << 8) +
 			(((DRXK_VERSION_PATCH / 10) % 10) << 4) +
 			(DRXK_VERSION_PATCH % 10);
-		status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
+		status = write16(state, SCU_RAM_DRIVER_VER_LO__A,
+				 driver_version);
 		if (status < 0)
 			goto error;
 
-		printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
+		pr_info("DRXK driver version %d.%d.%d\n",
 			DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
 			DRXK_VERSION_PATCH);
 
-		/* Dirty fix of default values for ROM/PATCH microcode
-			Dirty because this fix makes it impossible to setup suitable values
-			before calling DRX_Open. This solution requires changes to RF AGC speed
-			to be done via the CTRL function after calling DRX_Open */
+		/*
+		 * Dirty fix of default values for ROM/PATCH microcode
+		 * Dirty because this fix makes it impossible to setup
+		 * suitable values before calling DRX_Open. This solution
+		 * requires changes to RF AGC speed to be done via the CTRL
+		 * function after calling DRX_Open
+		 */
 
-		/* m_dvbtRfAgcCfg.speed = 3; */
+		/* m_dvbt_rf_agc_cfg.speed = 3; */
 
 		/* Reset driver debug flags to 0 */
 		status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
@@ -6170,42 +6223,42 @@
 		if (status < 0)
 			goto error;
 		/* MPEGTS functions are still the same */
-		status = MPEGTSDtoInit(state);
+		status = mpegts_dto_init(state);
 		if (status < 0)
 			goto error;
-		status = MPEGTSStop(state);
+		status = mpegts_stop(state);
 		if (status < 0)
 			goto error;
-		status = MPEGTSConfigurePolarity(state);
+		status = mpegts_configure_polarity(state);
 		if (status < 0)
 			goto error;
-		status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
+		status = mpegts_configure_pins(state, state->m_enable_mpeg_output);
 		if (status < 0)
 			goto error;
 		/* added: configure GPIO */
-		status = WriteGPIO(state);
+		status = write_gpio(state);
 		if (status < 0)
 			goto error;
 
-		state->m_DrxkState = DRXK_STOPPED;
+		state->m_drxk_state = DRXK_STOPPED;
 
-		if (state->m_bPowerDown) {
-			status = PowerDownDevice(state);
+		if (state->m_b_power_down) {
+			status = power_down_device(state);
 			if (status < 0)
 				goto error;
-			state->m_DrxkState = DRXK_POWERED_DOWN;
+			state->m_drxk_state = DRXK_POWERED_DOWN;
 		} else
-			state->m_DrxkState = DRXK_STOPPED;
+			state->m_drxk_state = DRXK_STOPPED;
 
 		/* Initialize the supported delivery systems */
 		n = 0;
-		if (state->m_hasDVBC) {
+		if (state->m_has_dvbc) {
 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
 			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
 			strlcat(state->frontend.ops.info.name, " DVB-C",
 				sizeof(state->frontend.ops.info.name));
 		}
-		if (state->m_hasDVBT) {
+		if (state->m_has_dvbt) {
 			state->frontend.ops.delsys[n++] = SYS_DVBT;
 			strlcat(state->frontend.ops.info.name, " DVB-T",
 				sizeof(state->frontend.ops.info.name));
@@ -6214,9 +6267,9 @@
 	}
 error:
 	if (status < 0) {
-		state->m_DrxkState = DRXK_NO_DEV;
+		state->m_drxk_state = DRXK_NO_DEV;
 		drxk_i2c_unlock(state);
-		printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
+		pr_err("Error %d on %s\n", status, __func__);
 	}
 
 	return status;
@@ -6229,11 +6282,9 @@
 
 	dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
 	if (!fw) {
-		printk(KERN_ERR
-		       "drxk: Could not load firmware file %s.\n",
+		pr_err("Could not load firmware file %s.\n",
 			state->microcode_name);
-		printk(KERN_INFO
-		       "drxk: Copy %s to your hotplug directory!\n",
+		pr_info("Copy %s to your hotplug directory!\n",
 			state->microcode_name);
 		state->microcode_name = NULL;
 
@@ -6270,12 +6321,12 @@
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return 0;
 
-	ShutDown(state);
+	shut_down(state);
 	return 0;
 }
 
@@ -6285,7 +6336,7 @@
 
 	dprintk(1, ": %s\n", enable ? "enable" : "disable");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
 
 	return ConfigureI2CBridge(state, enable ? true : false);
@@ -6300,15 +6351,14 @@
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
 
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
 	if (!fe->ops.tuner_ops.get_if_frequency) {
-		printk(KERN_ERR
-		       "drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
+		pr_err("Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
 		return -EINVAL;
 	}
 
@@ -6323,22 +6373,23 @@
 	state->props = *p;
 
 	if (old_delsys != delsys) {
-		ShutDown(state);
+		shut_down(state);
 		switch (delsys) {
 		case SYS_DVBC_ANNEX_A:
 		case SYS_DVBC_ANNEX_C:
-			if (!state->m_hasDVBC)
+			if (!state->m_has_dvbc)
 				return -EINVAL;
-			state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ? true : false;
+			state->m_itut_annex_c = (delsys == SYS_DVBC_ANNEX_C) ?
+						true : false;
 			if (state->m_itut_annex_c)
-				SetOperationMode(state, OM_QAM_ITU_C);
+				setoperation_mode(state, OM_QAM_ITU_C);
 			else
-				SetOperationMode(state, OM_QAM_ITU_A);
+				setoperation_mode(state, OM_QAM_ITU_A);
 			break;
 		case SYS_DVBT:
-			if (!state->m_hasDVBT)
+			if (!state->m_has_dvbt)
 				return -EINVAL;
-			SetOperationMode(state, OM_DVBT);
+			setoperation_mode(state, OM_DVBT);
 			break;
 		default:
 			return -EINVAL;
@@ -6346,7 +6397,7 @@
 	}
 
 	fe->ops.tuner_ops.get_if_frequency(fe, &IF);
-	Start(state, 0, IF);
+	start(state, 0, IF);
 
 	/* After set_frontend, stats aren't avaliable */
 	p->strength.stat[0].scale = FE_SCALE_RELATIVE;
@@ -6366,31 +6417,31 @@
 static int get_strength(struct drxk_state *state, u64 *strength)
 {
 	int status;
-	struct SCfgAgc   rfAgc, ifAgc;
-	u32          totalGain  = 0;
+	struct s_cfg_agc   rf_agc, if_agc;
+	u32          total_gain  = 0;
 	u32          atten      = 0;
-	u32          agcRange   = 0;
+	u32          agc_range   = 0;
 	u16            scu_lvl  = 0;
 	u16            scu_coc  = 0;
 	/* FIXME: those are part of the tuner presets */
-	u16 tunerRfGain         = 50; /* Default value on az6007 driver */
-	u16 tunerIfGain         = 40; /* Default value on az6007 driver */
+	u16 tuner_rf_gain         = 50; /* Default value on az6007 driver */
+	u16 tuner_if_gain         = 40; /* Default value on az6007 driver */
 
 	*strength = 0;
 
-	if (IsDVBT(state)) {
-		rfAgc = state->m_dvbtRfAgcCfg;
-		ifAgc = state->m_dvbtIfAgcCfg;
-	} else if (IsQAM(state)) {
-		rfAgc = state->m_qamRfAgcCfg;
-		ifAgc = state->m_qamIfAgcCfg;
+	if (is_dvbt(state)) {
+		rf_agc = state->m_dvbt_rf_agc_cfg;
+		if_agc = state->m_dvbt_if_agc_cfg;
+	} else if (is_qam(state)) {
+		rf_agc = state->m_qam_rf_agc_cfg;
+		if_agc = state->m_qam_if_agc_cfg;
 	} else {
-		rfAgc = state->m_atvRfAgcCfg;
-		ifAgc = state->m_atvIfAgcCfg;
+		rf_agc = state->m_atv_rf_agc_cfg;
+		if_agc = state->m_atv_if_agc_cfg;
 	}
 
-	if (rfAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
-		/* SCU outputLevel */
+	if (rf_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
+		/* SCU output_level */
 		status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
 		if (status < 0)
 			return status;
@@ -6401,54 +6452,54 @@
 			return status;
 
 		if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
-			rfAgc.outputLevel = scu_lvl + scu_coc;
+			rf_agc.output_level = scu_lvl + scu_coc;
 		else
-			rfAgc.outputLevel = 0xffff;
+			rf_agc.output_level = 0xffff;
 
 		/* Take RF gain into account */
-		totalGain += tunerRfGain;
+		total_gain += tuner_rf_gain;
 
 		/* clip output value */
-		if (rfAgc.outputLevel < rfAgc.minOutputLevel)
-			rfAgc.outputLevel = rfAgc.minOutputLevel;
-		if (rfAgc.outputLevel > rfAgc.maxOutputLevel)
-			rfAgc.outputLevel = rfAgc.maxOutputLevel;
+		if (rf_agc.output_level < rf_agc.min_output_level)
+			rf_agc.output_level = rf_agc.min_output_level;
+		if (rf_agc.output_level > rf_agc.max_output_level)
+			rf_agc.output_level = rf_agc.max_output_level;
 
-		agcRange = (u32) (rfAgc.maxOutputLevel - rfAgc.minOutputLevel);
-		if (agcRange > 0) {
+		agc_range = (u32) (rf_agc.max_output_level - rf_agc.min_output_level);
+		if (agc_range > 0) {
 			atten += 100UL *
-				((u32)(tunerRfGain)) *
-				((u32)(rfAgc.outputLevel - rfAgc.minOutputLevel))
-				/ agcRange;
+				((u32)(tuner_rf_gain)) *
+				((u32)(rf_agc.output_level - rf_agc.min_output_level))
+				/ agc_range;
 		}
 	}
 
-	if (ifAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
+	if (if_agc.ctrl_mode == DRXK_AGC_CTRL_AUTO) {
 		status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
-				&ifAgc.outputLevel);
+				&if_agc.output_level);
 		if (status < 0)
 			return status;
 
 		status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
-				&ifAgc.top);
+				&if_agc.top);
 		if (status < 0)
 			return status;
 
 		/* Take IF gain into account */
-		totalGain += (u32) tunerIfGain;
+		total_gain += (u32) tuner_if_gain;
 
 		/* clip output value */
-		if (ifAgc.outputLevel < ifAgc.minOutputLevel)
-			ifAgc.outputLevel = ifAgc.minOutputLevel;
-		if (ifAgc.outputLevel > ifAgc.maxOutputLevel)
-			ifAgc.outputLevel = ifAgc.maxOutputLevel;
+		if (if_agc.output_level < if_agc.min_output_level)
+			if_agc.output_level = if_agc.min_output_level;
+		if (if_agc.output_level > if_agc.max_output_level)
+			if_agc.output_level = if_agc.max_output_level;
 
-		agcRange  = (u32) (ifAgc.maxOutputLevel - ifAgc.minOutputLevel);
-		if (agcRange > 0) {
+		agc_range  = (u32)(if_agc.max_output_level - if_agc.min_output_level);
+		if (agc_range > 0) {
 			atten += 100UL *
-				((u32)(tunerIfGain)) *
-				((u32)(ifAgc.outputLevel - ifAgc.minOutputLevel))
-				/ agcRange;
+				((u32)(tuner_if_gain)) *
+				((u32)(if_agc.output_level - if_agc.min_output_level))
+				/ agc_range;
 		}
 	}
 
@@ -6456,8 +6507,8 @@
 	 * Convert to 0..65535 scale.
 	 * If it can't be measured (AGC is disabled), just show 100%.
 	 */
-	if (totalGain > 0)
-		*strength = (65535UL * atten / totalGain / 100);
+	if (total_gain > 0)
+		*strength = (65535UL * atten / total_gain / 100);
 	else
 		*strength = 65535;
 
@@ -6480,14 +6531,14 @@
 	u32 pkt_error_count;
 	s32 cnr;
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
 	/* get status */
 	state->fe_status = 0;
-	GetLockStatus(state, &stat);
+	get_lock_status(state, &stat);
 	if (stat == MPEG_LOCK)
 		state->fe_status |= 0x1f;
 	if (stat == FEC_LOCK)
@@ -6503,7 +6554,7 @@
 
 
 	if (stat >= DEMOD_LOCK) {
-		GetSignalToNoise(state, &cnr);
+		get_signal_to_noise(state, &cnr);
 		c->cnr.stat[0].svalue = cnr * 100;
 		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
 	} else {
@@ -6524,9 +6575,11 @@
 
 	/* BER measurement is valid if at least FEC lock is achieved */
 
-	/* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
-		to set nr of symbols or bits over which
-		to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
+	/*
+	 * OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be
+	 * written to set nr of symbols or bits over which to measure
+	 * EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg().
+	 */
 
 	/* Read registers for post/preViterbi BER calculation */
 	status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, &reg16);
@@ -6610,9 +6663,9 @@
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
 	*strength = c->strength.stat[0].uvalue;
@@ -6626,12 +6679,12 @@
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
-	GetSignalToNoise(state, &snr2);
+	get_signal_to_noise(state, &snr2);
 
 	/* No negative SNR, clip to zero */
 	if (snr2 < 0)
@@ -6647,27 +6700,27 @@
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
-	DVBTQAMGetAccPktErr(state, &err);
+	dvbtqam_get_acc_pkt_err(state, &err);
 	*ucblocks = (u32) err;
 	return 0;
 }
 
-static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
-				    *sets)
+static int drxk_get_tune_settings(struct dvb_frontend *fe,
+				  struct dvb_frontend_tune_settings *sets)
 {
 	struct drxk_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 
 	dprintk(1, "\n");
 
-	if (state->m_DrxkState == DRXK_NO_DEV)
+	if (state->m_drxk_state == DRXK_NO_DEV)
 		return -ENODEV;
-	if (state->m_DrxkState == DRXK_UNINITIALIZED)
+	if (state->m_drxk_state == DRXK_UNINITIALIZED)
 		return -EAGAIN;
 
 	switch (p->delivery_system) {
@@ -6737,36 +6790,36 @@
 	state->no_i2c_bridge = config->no_i2c_bridge;
 	state->antenna_gpio = config->antenna_gpio;
 	state->antenna_dvbt = config->antenna_dvbt;
-	state->m_ChunkSize = config->chunk_size;
+	state->m_chunk_size = config->chunk_size;
 	state->enable_merr_cfg = config->enable_merr_cfg;
 
 	if (config->dynamic_clk) {
-		state->m_DVBTStaticCLK = 0;
-		state->m_DVBCStaticCLK = 0;
+		state->m_dvbt_static_clk = 0;
+		state->m_dvbc_static_clk = 0;
 	} else {
-		state->m_DVBTStaticCLK = 1;
-		state->m_DVBCStaticCLK = 1;
+		state->m_dvbt_static_clk = 1;
+		state->m_dvbc_static_clk = 1;
 	}
 
 
 	if (config->mpeg_out_clk_strength)
-		state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
+		state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07;
 	else
-		state->m_TSClockkStrength = 0x06;
+		state->m_ts_clockk_strength = 0x06;
 
 	if (config->parallel_ts)
-		state->m_enableParallel = true;
+		state->m_enable_parallel = true;
 	else
-		state->m_enableParallel = false;
+		state->m_enable_parallel = false;
 
 	/* NOTE: as more UIO bits will be used, add them to the mask */
-	state->UIO_mask = config->antenna_gpio;
+	state->uio_mask = config->antenna_gpio;
 
 	/* Default gpio to DVB-C */
 	if (!state->antenna_dvbt && state->antenna_gpio)
-		state->m_GPIO |= state->antenna_gpio;
+		state->m_gpio |= state->antenna_gpio;
 	else
-		state->m_GPIO &= ~state->antenna_gpio;
+		state->m_gpio &= ~state->antenna_gpio;
 
 	mutex_init(&state->mutex);
 
@@ -6792,8 +6845,7 @@
 					      GFP_KERNEL,
 					      state, load_firmware_cb);
 			if (status < 0) {
-				printk(KERN_ERR
-				       "drxk: failed to request a firmware\n");
+				pr_err("failed to request a firmware\n");
 				return NULL;
 			}
 		}
@@ -6821,11 +6873,11 @@
 	p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
 	p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
 
-	printk(KERN_INFO "drxk: frontend initialized.\n");
+	pr_info("frontend initialized.\n");
 	return &state->frontend;
 
 error:
-	printk(KERN_ERR "drxk: not found\n");
+	pr_err("not found\n");
 	kfree(state);
 	return NULL;
 }
diff --git a/drivers/media/dvb-frontends/drxk_hard.h b/drivers/media/dvb-frontends/drxk_hard.h
index b8424f1..bae9c71 100644
--- a/drivers/media/dvb-frontends/drxk_hard.h
+++ b/drivers/media/dvb-frontends/drxk_hard.h
@@ -46,7 +46,7 @@
 #define     IQM_RC_ADJ_SEL_B_QAM                                            0x1
 #define     IQM_RC_ADJ_SEL_B_VSB                                            0x2
 
-enum OperationMode {
+enum operation_mode {
 	OM_NONE,
 	OM_QAM_ITU_A,
 	OM_QAM_ITU_B,
@@ -54,7 +54,7 @@
 	OM_DVBT
 };
 
-enum DRXPowerMode {
+enum drx_power_mode {
 	DRX_POWER_UP = 0,
 	DRX_POWER_MODE_1,
 	DRX_POWER_MODE_2,
@@ -77,24 +77,29 @@
 };
 
 
-/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */
+/* Intermediate power mode for DRXK, power down OFDM clock domain */
 #ifndef DRXK_POWER_DOWN_OFDM
 #define DRXK_POWER_DOWN_OFDM        DRX_POWER_MODE_1
 #endif
 
-/** /brief Intermediate power mode for DRXK, power down core (sysclk) */
+/* Intermediate power mode for DRXK, power down core (sysclk) */
 #ifndef DRXK_POWER_DOWN_CORE
 #define DRXK_POWER_DOWN_CORE        DRX_POWER_MODE_9
 #endif
 
-/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */
+/* Intermediate power mode for DRXK, power down pll (only osc runs) */
 #ifndef DRXK_POWER_DOWN_PLL
 #define DRXK_POWER_DOWN_PLL         DRX_POWER_MODE_10
 #endif
 
 
-enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF };
-enum EDrxkState {
+enum agc_ctrl_mode {
+	DRXK_AGC_CTRL_AUTO = 0,
+	DRXK_AGC_CTRL_USER,
+	DRXK_AGC_CTRL_OFF
+};
+
+enum e_drxk_state {
 	DRXK_UNINITIALIZED = 0,
 	DRXK_STOPPED,
 	DRXK_DTV_STARTED,
@@ -103,7 +108,7 @@
 	DRXK_NO_DEV			/* If drxk init failed */
 };
 
-enum EDrxkCoefArrayIndex {
+enum e_drxk_coef_array_index {
 	DRXK_COEF_IDX_MN = 0,
 	DRXK_COEF_IDX_FM    ,
 	DRXK_COEF_IDX_L     ,
@@ -113,13 +118,13 @@
 	DRXK_COEF_IDX_I     ,
 	DRXK_COEF_IDX_MAX
 };
-enum EDrxkSifAttenuation {
+enum e_drxk_sif_attenuation {
 	DRXK_SIF_ATTENUATION_0DB,
 	DRXK_SIF_ATTENUATION_3DB,
 	DRXK_SIF_ATTENUATION_6DB,
 	DRXK_SIF_ATTENUATION_9DB
 };
-enum EDrxkConstellation {
+enum e_drxk_constellation {
 	DRX_CONSTELLATION_BPSK = 0,
 	DRX_CONSTELLATION_QPSK,
 	DRX_CONSTELLATION_PSK8,
@@ -133,7 +138,7 @@
 	DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
 	DRX_CONSTELLATION_AUTO    = DRX_AUTO
 };
-enum EDrxkInterleaveMode {
+enum e_drxk_interleave_mode {
 	DRXK_QAM_I12_J17    = 16,
 	DRXK_QAM_I_UNKNOWN  = DRX_UNKNOWN
 };
@@ -144,14 +149,14 @@
 	DRXK_SPIN_UNKNOWN
 };
 
-enum DRXKCfgDvbtSqiSpeed {
+enum drxk_cfg_dvbt_sqi_speed {
 	DRXK_DVBT_SQI_SPEED_FAST = 0,
 	DRXK_DVBT_SQI_SPEED_MEDIUM,
 	DRXK_DVBT_SQI_SPEED_SLOW,
 	DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN
 } ;
 
-enum DRXFftmode_t {
+enum drx_fftmode_t {
 	DRX_FFTMODE_2K = 0,
 	DRX_FFTMODE_4K,
 	DRX_FFTMODE_8K,
@@ -159,47 +164,47 @@
 	DRX_FFTMODE_AUTO    = DRX_AUTO
 };
 
-enum DRXMPEGStrWidth_t {
+enum drxmpeg_str_width_t {
 	DRX_MPEG_STR_WIDTH_1,
 	DRX_MPEG_STR_WIDTH_8
 };
 
-enum DRXQamLockRange_t {
+enum drx_qam_lock_range_t {
 	DRX_QAM_LOCKRANGE_NORMAL,
 	DRX_QAM_LOCKRANGE_EXTENDED
 };
 
-struct DRXKCfgDvbtEchoThres_t {
+struct drxk_cfg_dvbt_echo_thres_t {
 	u16             threshold;
-	enum DRXFftmode_t      fftMode;
+	enum drx_fftmode_t      fft_mode;
 } ;
 
-struct SCfgAgc {
-	enum AGC_CTRL_MODE     ctrlMode;        /* off, user, auto */
-	u16            outputLevel;     /* range dependent on AGC */
-	u16            minOutputLevel;  /* range dependent on AGC */
-	u16            maxOutputLevel;  /* range dependent on AGC */
+struct s_cfg_agc {
+	enum agc_ctrl_mode     ctrl_mode;        /* off, user, auto */
+	u16            output_level;     /* range dependent on AGC */
+	u16            min_output_level;  /* range dependent on AGC */
+	u16            max_output_level;  /* range dependent on AGC */
 	u16            speed;           /* range dependent on AGC */
 	u16            top;             /* rf-agc take over point */
-	u16            cutOffCurrent;   /* rf-agc is accelerated if output current
+	u16            cut_off_current;   /* rf-agc is accelerated if output current
 					   is below cut-off current */
-	u16            IngainTgtMax;
-	u16            FastClipCtrlDelay;
+	u16            ingain_tgt_max;
+	u16            fast_clip_ctrl_delay;
 };
 
-struct SCfgPreSaw {
+struct s_cfg_pre_saw {
 	u16        reference; /* pre SAW reference value, range 0 .. 31 */
-	bool          usePreSaw; /* TRUE algorithms must use pre SAW sense */
+	bool          use_pre_saw; /* TRUE algorithms must use pre SAW sense */
 };
 
-struct DRXKOfdmScCmd_t {
-	u16 cmd;        /**< Command number */
-	u16 subcmd;     /**< Sub-command parameter*/
-	u16 param0;     /**< General purpous param */
-	u16 param1;     /**< General purpous param */
-	u16 param2;     /**< General purpous param */
-	u16 param3;     /**< General purpous param */
-	u16 param4;     /**< General purpous param */
+struct drxk_ofdm_sc_cmd_t {
+	u16 cmd;        /* Command number */
+	u16 subcmd;     /* Sub-command parameter*/
+	u16 param0;     /* General purpous param */
+	u16 param1;     /* General purpous param */
+	u16 param2;     /* General purpous param */
+	u16 param3;     /* General purpous param */
+	u16 param4;     /* General purpous param */
 };
 
 struct drxk_state {
@@ -213,121 +218,121 @@
 
 	struct mutex mutex;
 
-	u32    m_Instance;           /**< Channel 1,2,3 or 4 */
+	u32    m_instance;           /* Channel 1,2,3 or 4 */
 
-	int    m_ChunkSize;
-	u8 Chunk[256];
+	int    m_chunk_size;
+	u8 chunk[256];
 
-	bool   m_hasLNA;
-	bool   m_hasDVBT;
-	bool   m_hasDVBC;
-	bool   m_hasAudio;
-	bool   m_hasATV;
-	bool   m_hasOOB;
-	bool   m_hasSAWSW;         /**< TRUE if mat_tx is available */
-	bool   m_hasGPIO1;         /**< TRUE if mat_rx is available */
-	bool   m_hasGPIO2;         /**< TRUE if GPIO is available */
-	bool   m_hasIRQN;          /**< TRUE if IRQN is available */
-	u16    m_oscClockFreq;
-	u16    m_HICfgTimingDiv;
-	u16    m_HICfgBridgeDelay;
-	u16    m_HICfgWakeUpKey;
-	u16    m_HICfgTimeout;
-	u16    m_HICfgCtrl;
-	s32    m_sysClockFreq;      /**< system clock frequency in kHz */
+	bool   m_has_lna;
+	bool   m_has_dvbt;
+	bool   m_has_dvbc;
+	bool   m_has_audio;
+	bool   m_has_atv;
+	bool   m_has_oob;
+	bool   m_has_sawsw;         /* TRUE if mat_tx is available */
+	bool   m_has_gpio1;         /* TRUE if mat_rx is available */
+	bool   m_has_gpio2;         /* TRUE if GPIO is available */
+	bool   m_has_irqn;          /* TRUE if IRQN is available */
+	u16    m_osc_clock_freq;
+	u16    m_hi_cfg_timing_div;
+	u16    m_hi_cfg_bridge_delay;
+	u16    m_hi_cfg_wake_up_key;
+	u16    m_hi_cfg_timeout;
+	u16    m_hi_cfg_ctrl;
+	s32    m_sys_clock_freq;      /* system clock frequency in kHz */
 
-	enum EDrxkState    m_DrxkState;      /**< State of Drxk (init,stopped,started) */
-	enum OperationMode m_OperationMode;  /**< digital standards */
-	struct SCfgAgc     m_vsbRfAgcCfg;    /**< settings for VSB RF-AGC */
-	struct SCfgAgc     m_vsbIfAgcCfg;    /**< settings for VSB IF-AGC */
-	u16                m_vsbPgaCfg;      /**< settings for VSB PGA */
-	struct SCfgPreSaw  m_vsbPreSawCfg;   /**< settings for pre SAW sense */
-	s32    m_Quality83percent;  /**< MER level (*0.1 dB) for 83% quality indication */
-	s32    m_Quality93percent;  /**< MER level (*0.1 dB) for 93% quality indication */
-	bool   m_smartAntInverted;
-	bool   m_bDebugEnableBridge;
-	bool   m_bPDownOpenBridge;  /**< only open DRXK bridge before power-down once it has been accessed */
-	bool   m_bPowerDown;        /**< Power down when not used */
+	enum e_drxk_state    m_drxk_state;      /* State of Drxk (init,stopped,started) */
+	enum operation_mode m_operation_mode;  /* digital standards */
+	struct s_cfg_agc     m_vsb_rf_agc_cfg;    /* settings for VSB RF-AGC */
+	struct s_cfg_agc     m_vsb_if_agc_cfg;    /* settings for VSB IF-AGC */
+	u16                m_vsb_pga_cfg;      /* settings for VSB PGA */
+	struct s_cfg_pre_saw  m_vsb_pre_saw_cfg;   /* settings for pre SAW sense */
+	s32    m_Quality83percent;  /* MER level (*0.1 dB) for 83% quality indication */
+	s32    m_Quality93percent;  /* MER level (*0.1 dB) for 93% quality indication */
+	bool   m_smart_ant_inverted;
+	bool   m_b_debug_enable_bridge;
+	bool   m_b_p_down_open_bridge;  /* only open DRXK bridge before power-down once it has been accessed */
+	bool   m_b_power_down;        /* Power down when not used */
 
-	u32    m_IqmFsRateOfs;      /**< frequency shift as written to DRXK register (28bit fixpoint) */
+	u32    m_iqm_fs_rate_ofs;      /* frequency shift as written to DRXK register (28bit fixpoint) */
 
-	bool   m_enableMPEGOutput;  /**< If TRUE, enable MPEG output */
-	bool   m_insertRSByte;      /**< If TRUE, insert RS byte */
-	bool   m_enableParallel;    /**< If TRUE, parallel out otherwise serial */
-	bool   m_invertDATA;        /**< If TRUE, invert DATA signals */
-	bool   m_invertERR;         /**< If TRUE, invert ERR signal */
-	bool   m_invertSTR;         /**< If TRUE, invert STR signals */
-	bool   m_invertVAL;         /**< If TRUE, invert VAL signals */
-	bool   m_invertCLK;         /**< If TRUE, invert CLK signals */
-	bool   m_DVBCStaticCLK;
-	bool   m_DVBTStaticCLK;     /**< If TRUE, static MPEG clockrate will
+	bool   m_enable_mpeg_output;  /* If TRUE, enable MPEG output */
+	bool   m_insert_rs_byte;      /* If TRUE, insert RS byte */
+	bool   m_enable_parallel;    /* If TRUE, parallel out otherwise serial */
+	bool   m_invert_data;        /* If TRUE, invert DATA signals */
+	bool   m_invert_err;         /* If TRUE, invert ERR signal */
+	bool   m_invert_str;         /* If TRUE, invert STR signals */
+	bool   m_invert_val;         /* If TRUE, invert VAL signals */
+	bool   m_invert_clk;         /* If TRUE, invert CLK signals */
+	bool   m_dvbc_static_clk;
+	bool   m_dvbt_static_clk;     /* If TRUE, static MPEG clockrate will
 					 be used, otherwise clockrate will
 					 adapt to the bitrate of the TS */
-	u32    m_DVBTBitrate;
-	u32    m_DVBCBitrate;
+	u32    m_dvbt_bitrate;
+	u32    m_dvbc_bitrate;
 
-	u8     m_TSDataStrength;
-	u8     m_TSClockkStrength;
+	u8     m_ts_data_strength;
+	u8     m_ts_clockk_strength;
 
 	bool   m_itut_annex_c;      /* If true, uses ITU-T DVB-C Annex C, instead of Annex A */
 
-	enum DRXMPEGStrWidth_t  m_widthSTR;    /**< MPEG start width */
-	u32    m_mpegTsStaticBitrate;          /**< Maximum bitrate in b/s in case
+	enum drxmpeg_str_width_t  m_width_str;    /* MPEG start width */
+	u32    m_mpeg_ts_static_bitrate;          /* Maximum bitrate in b/s in case
 						    static clockrate is selected */
 
-	/* LARGE_INTEGER   m_StartTime; */     /**< Contains the time of the last demod start */
-	s32    m_MpegLockTimeOut;      /**< WaitForLockStatus Timeout (counts from start time) */
-	s32    m_DemodLockTimeOut;     /**< WaitForLockStatus Timeout (counts from start time) */
+	/* LARGE_INTEGER   m_startTime; */     /* Contains the time of the last demod start */
+	s32    m_mpeg_lock_time_out;      /* WaitForLockStatus Timeout (counts from start time) */
+	s32    m_demod_lock_time_out;     /* WaitForLockStatus Timeout (counts from start time) */
 
-	bool   m_disableTEIhandling;
+	bool   m_disable_te_ihandling;
 
-	bool   m_RfAgcPol;
-	bool   m_IfAgcPol;
+	bool   m_rf_agc_pol;
+	bool   m_if_agc_pol;
 
-	struct SCfgAgc    m_atvRfAgcCfg;  /**< settings for ATV RF-AGC */
-	struct SCfgAgc    m_atvIfAgcCfg;  /**< settings for ATV IF-AGC */
-	struct SCfgPreSaw m_atvPreSawCfg; /**< settings for ATV pre SAW sense */
-	bool              m_phaseCorrectionBypass;
-	s16               m_atvTopVidPeak;
-	u16               m_atvTopNoiseTh;
-	enum EDrxkSifAttenuation m_sifAttenuation;
-	bool              m_enableCVBSOutput;
-	bool              m_enableSIFOutput;
-	bool              m_bMirrorFreqSpect;
-	enum EDrxkConstellation  m_Constellation; /**< Constellation type of the channel */
-	u32               m_CurrSymbolRate;       /**< Current QAM symbol rate */
-	struct SCfgAgc    m_qamRfAgcCfg;          /**< settings for QAM RF-AGC */
-	struct SCfgAgc    m_qamIfAgcCfg;          /**< settings for QAM IF-AGC */
-	u16               m_qamPgaCfg;            /**< settings for QAM PGA */
-	struct SCfgPreSaw m_qamPreSawCfg;         /**< settings for QAM pre SAW sense */
-	enum EDrxkInterleaveMode m_qamInterleaveMode; /**< QAM Interleave mode */
-	u16               m_fecRsPlen;
-	u16               m_fecRsPrescale;
+	struct s_cfg_agc    m_atv_rf_agc_cfg;  /* settings for ATV RF-AGC */
+	struct s_cfg_agc    m_atv_if_agc_cfg;  /* settings for ATV IF-AGC */
+	struct s_cfg_pre_saw m_atv_pre_saw_cfg; /* settings for ATV pre SAW sense */
+	bool              m_phase_correction_bypass;
+	s16               m_atv_top_vid_peak;
+	u16               m_atv_top_noise_th;
+	enum e_drxk_sif_attenuation m_sif_attenuation;
+	bool              m_enable_cvbs_output;
+	bool              m_enable_sif_output;
+	bool              m_b_mirror_freq_spect;
+	enum e_drxk_constellation  m_constellation; /* constellation type of the channel */
+	u32               m_curr_symbol_rate;       /* Current QAM symbol rate */
+	struct s_cfg_agc    m_qam_rf_agc_cfg;          /* settings for QAM RF-AGC */
+	struct s_cfg_agc    m_qam_if_agc_cfg;          /* settings for QAM IF-AGC */
+	u16               m_qam_pga_cfg;            /* settings for QAM PGA */
+	struct s_cfg_pre_saw m_qam_pre_saw_cfg;         /* settings for QAM pre SAW sense */
+	enum e_drxk_interleave_mode m_qam_interleave_mode; /* QAM Interleave mode */
+	u16               m_fec_rs_plen;
+	u16               m_fec_rs_prescale;
 
-	enum DRXKCfgDvbtSqiSpeed m_sqiSpeed;
+	enum drxk_cfg_dvbt_sqi_speed m_sqi_speed;
 
-	u16               m_GPIO;
-	u16               m_GPIOCfg;
+	u16               m_gpio;
+	u16               m_gpio_cfg;
 
-	struct SCfgAgc    m_dvbtRfAgcCfg;     /**< settings for QAM RF-AGC */
-	struct SCfgAgc    m_dvbtIfAgcCfg;     /**< settings for QAM IF-AGC */
-	struct SCfgPreSaw m_dvbtPreSawCfg;    /**< settings for QAM pre SAW sense */
+	struct s_cfg_agc    m_dvbt_rf_agc_cfg;     /* settings for QAM RF-AGC */
+	struct s_cfg_agc    m_dvbt_if_agc_cfg;     /* settings for QAM IF-AGC */
+	struct s_cfg_pre_saw m_dvbt_pre_saw_cfg;    /* settings for QAM pre SAW sense */
 
-	u16               m_agcFastClipCtrlDelay;
-	bool              m_adcCompPassed;
+	u16               m_agcfast_clip_ctrl_delay;
+	bool              m_adc_comp_passed;
 	u16               m_adcCompCoef[64];
-	u16               m_adcState;
+	u16               m_adc_state;
 
 	u8               *m_microcode;
 	int               m_microcode_length;
-	bool		  m_DRXK_A3_ROM_CODE;
-	bool              m_DRXK_A3_PATCH_CODE;
+	bool		  m_drxk_a3_rom_code;
+	bool              m_drxk_a3_patch_code;
 
 	bool              m_rfmirror;
-	u8                m_deviceSpin;
-	u32               m_iqmRcRate;
+	u8                m_device_spin;
+	u32               m_iqm_rc_rate;
 
-	enum DRXPowerMode m_currentPowerMode;
+	enum drx_power_mode m_current_power_mode;
 
 	/* when true, avoids other devices to use the I2C bus */
 	bool		  drxk_i2c_exclusive_lock;
@@ -337,7 +342,7 @@
 	 * at struct drxk_config.
 	 */
 
-	u16	UIO_mask;	/* Bits used by UIO */
+	u16	uio_mask;	/* Bits used by UIO */
 
 	bool	enable_merr_cfg;
 	bool	single_master;
diff --git a/drivers/media/dvb-frontends/stb0899_algo.c b/drivers/media/dvb-frontends/stb0899_algo.c
index 117a569..93596e0 100644
--- a/drivers/media/dvb-frontends/stb0899_algo.c
+++ b/drivers/media/dvb-frontends/stb0899_algo.c
@@ -226,8 +226,8 @@
 			next_loop--;
 
 		if (next_loop) {
-			STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
-			STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+			STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
+			STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
 			stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency		*/
 		}
 		internal->direction = -internal->direction;	/* Change zigzag direction		*/
@@ -235,7 +235,7 @@
 
 	if (internal->status == TIMINGOK) {
 		stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency		*/
-		internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+		internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
 		dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq);
 	}
 
@@ -306,8 +306,8 @@
 				STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
 				stb0899_write_reg(state, STB0899_CFD, reg);
 
-				STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
-				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+				STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
+				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
 				stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency	*/
 			}
 		}
@@ -317,7 +317,7 @@
 
 	if (internal->status == CARRIEROK) {
 		stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
-		internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+		internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
 		dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq);
 	} else {
 		internal->derot_freq = last_derot_freq;
@@ -412,8 +412,8 @@
 				STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
 				stb0899_write_reg(state, STB0899_CFD, reg);
 
-				STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
-				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
+				STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(internal->inversion * derot_freq));
+				STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(internal->inversion * derot_freq));
 				stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency	*/
 
 				stb0899_check_carrier(state);
@@ -425,7 +425,15 @@
 
 	if (internal->status == DATAOK) {
 		stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
-		internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
+
+		/* store autodetected IQ swapping as default for DVB-S2 tuning */
+		reg = stb0899_read_reg(state, STB0899_IQSWAP);
+		if (STB0899_GETFIELD(SYM, reg))
+			internal->inversion = IQ_SWAP_ON;
+		else
+			internal->inversion = IQ_SWAP_OFF;
+
+		internal->derot_freq = internal->inversion * MAKEWORD16(cfr[0], cfr[1]);
 		dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq);
 	}
 
@@ -444,7 +452,7 @@
 	int range_offst, tp_freq;
 
 	range_offst = internal->srch_range / 2000;
-	tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000;
+	tp_freq = internal->freq - (internal->derot_freq * internal->mclk) / 1000;
 
 	if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) {
 		internal->status = RANGEOK;
@@ -638,7 +646,7 @@
 							"RANGE OK ! derot freq=%d, mclk=%d",
 							internal->derot_freq, internal->mclk);
 
-						internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000);
+						internal->freq = params->freq - ((internal->derot_freq * internal->mclk) / 1000);
 						reg = stb0899_read_reg(state, STB0899_PLPARM);
 						internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg);
 						dprintk(state->verbose, FE_DEBUG, 1,
@@ -1373,9 +1381,6 @@
 	case IQ_SWAP_ON:
 		STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
 		break;
-	case IQ_SWAP_AUTO:	/* use last successful search first	*/
-		STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
-		break;
 	}
 	stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
 	stb0899_dvbs2_reacquire(state);
@@ -1405,41 +1410,39 @@
 	}
 
 	if (internal->status != DVBS2_FEC_LOCK) {
-		if (internal->inversion == IQ_SWAP_AUTO) {
-			reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
-			iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
-			/* IQ Spectrum Inversion	*/
-			STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
-			stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
-			/* start acquistion process	*/
-			stb0899_dvbs2_reacquire(state);
+		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
+		iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
+		/* IQ Spectrum Inversion	*/
+		STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
+		stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
+		/* start acquistion process	*/
+		stb0899_dvbs2_reacquire(state);
 
-			/* Wait for demod lock (UWP and CSM)	*/
-			internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
-			if (internal->status == DVBS2_DEMOD_LOCK) {
-				i = 0;
-				/* Demod Locked, check FEC	*/
-				internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
-				/*try thrice for false locks, (UWP and CSM Locked but no FEC)	*/
-				while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
-					/*	Read the frequency offset*/
-					offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
+		/* Wait for demod lock (UWP and CSM)	*/
+		internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
+		if (internal->status == DVBS2_DEMOD_LOCK) {
+			i = 0;
+			/* Demod Locked, check FEC	*/
+			internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
+			/*try thrice for false locks, (UWP and CSM Locked but no FEC)	*/
+			while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
+				/*	Read the frequency offset*/
+				offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
 
-					/* Set the Nominal frequency to the found frequency offset for the next reacquire*/
-					reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
-					STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
-					stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
+				/* Set the Nominal frequency to the found frequency offset for the next reacquire*/
+				reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
+				STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
+				stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
 
-					stb0899_dvbs2_reacquire(state);
-					internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
-					i++;
-				}
+				stb0899_dvbs2_reacquire(state);
+				internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
+				i++;
 			}
-/*
-			if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
-				pParams->IQLocked = !iqSpectrum;
-*/
 		}
+/*
+		if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
+			pParams->IQLocked = !iqSpectrum;
+*/
 	}
 	if (internal->status == DVBS2_FEC_LOCK) {
 		dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
@@ -1487,13 +1490,21 @@
 		/* Store signal parameters	*/
 		offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
 
+		/* sign extend 30 bit value before using it in calculations */
+		if (offsetfreq & (1 << 29))
+			offsetfreq |= -1 << 30;
+
 		offsetfreq = offsetfreq / ((1 << 30) / 1000);
 		offsetfreq *= (internal->master_clk / 1000000);
+
+		/* store current inversion for next run */
 		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
 		if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
-			offsetfreq *= -1;
+			internal->inversion = IQ_SWAP_ON;
+		else
+			internal->inversion = IQ_SWAP_OFF;
 
-		internal->freq = internal->freq - offsetfreq;
+		internal->freq = internal->freq + offsetfreq;
 		internal->srate = stb0899_dvbs2_get_srate(state);
 
 		reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
index cc278b3..3dd5714 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.c
+++ b/drivers/media/dvb-frontends/stb0899_drv.c
@@ -1618,19 +1618,18 @@
 struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
 {
 	struct stb0899_state *state = NULL;
-	enum stb0899_inversion inversion;
 
 	state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL);
 	if (state == NULL)
 		goto error;
 
-	inversion				= config->inversion;
 	state->verbose				= &verbose;
 	state->config				= config;
 	state->i2c				= i2c;
 	state->frontend.ops			= stb0899_ops;
 	state->frontend.demodulator_priv	= state;
-	state->internal.inversion		= inversion;
+	/* use configured inversion as default -- we'll later autodetect inversion */
+	state->internal.inversion		= config->inversion;
 
 	stb0899_wakeup(&state->frontend);
 	if (stb0899_get_dev_id(state) == -ENODEV) {
diff --git a/drivers/media/dvb-frontends/stb0899_drv.h b/drivers/media/dvb-frontends/stb0899_drv.h
index 8d26ff6..139264d 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.h
+++ b/drivers/media/dvb-frontends/stb0899_drv.h
@@ -45,9 +45,8 @@
 };
 
 enum stb0899_inversion {
-	IQ_SWAP_OFF	= 0,
-	IQ_SWAP_ON,
-	IQ_SWAP_AUTO
+	IQ_SWAP_OFF	= +1, /* inversion affects the sign of e. g. */
+	IQ_SWAP_ON	= -1, /* the derotator frequency register    */
 };
 
 #define STB0899_GPIO00				0xf140
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index f981d50..b2cd8ca 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -245,6 +245,15 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called ks0127.
 
+config VIDEO_ML86V7667
+	tristate "OKI ML86V7667 video decoder"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the OKI Semiconductor ML86V7667 video decoder.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ml86v7667.
+
 config VIDEO_SAA7110
 	tristate "Philips SAA7110 video decoder"
 	depends on VIDEO_V4L2 && I2C
@@ -425,6 +434,15 @@
 	help
 	  Video output driver for AKM AK8813 and AK8814 TV encoders
 
+config VIDEO_THS8200
+	tristate "Texas Instruments THS8200 video encoder"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the Texas Instruments THS8200 video encoder.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ths8200.
+
 comment "Camera sensor devices"
 
 config VIDEO_APTINA_PLL
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 720f42d..dc20653 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -34,6 +34,7 @@
 obj-$(CONFIG_VIDEO_BT866) += bt866.o
 obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
 obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
+obj-$(CONFIG_VIDEO_THS8200) += ths8200.o
 obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
 obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
 obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
@@ -70,3 +71,4 @@
 obj-$(CONFIG_VIDEO_SMIAPP_PLL)	+= smiapp-pll.o
 obj-$(CONFIG_VIDEO_AK881X)		+= ak881x.o
 obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
+obj-$(CONFIG_VIDEO_ML86V7667)	+= ml86v7667.o
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index 58344b6..ba4364d 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -32,7 +32,6 @@
 #include <linux/workqueue.h>
 #include <linux/v4l2-dv-timings.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 #include <media/ad9389b.h>
@@ -343,12 +342,6 @@
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ad9389b_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = ad9389b_rd(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -356,24 +349,11 @@
 
 static int ad9389b_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	ad9389b_wr(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
 #endif
 
-static int ad9389b_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_AD9389B, 0);
-}
-
 static int ad9389b_log_status(struct v4l2_subdev *sd)
 {
 	struct ad9389b_state *state = get_ad9389b_state(sd);
@@ -600,7 +580,6 @@
 
 static const struct v4l2_subdev_core_ops ad9389b_core_ops = {
 	.log_status = ad9389b_log_status,
-	.g_chip_ident = ad9389b_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = ad9389b_g_register,
 	.s_register = ad9389b_s_register,
@@ -1188,15 +1167,14 @@
 	v4l_dbg(1, debug, client, "detecting ad9389b client on address 0x%x\n",
 			client->addr << 1);
 
-	state = kzalloc(sizeof(struct ad9389b_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return -ENOMEM;
 
 	/* Platform data */
 	if (pdata == NULL) {
 		v4l_err(client, "No platform data!\n");
-		err = -ENODEV;
-		goto err_free;
+		return -ENODEV;
 	}
 	memcpy(&state->pdata, pdata, sizeof(state->pdata));
 
@@ -1251,12 +1229,14 @@
 	state->edid_i2c_client = i2c_new_dummy(client->adapter, (0x7e>>1));
 	if (state->edid_i2c_client == NULL) {
 		v4l2_err(sd, "failed to register edid i2c client\n");
+		err = -ENOMEM;
 		goto err_entity;
 	}
 
 	state->work_queue = create_singlethread_workqueue(sd->name);
 	if (state->work_queue == NULL) {
 		v4l2_err(sd, "could not create workqueue\n");
+		err = -ENOMEM;
 		goto err_unreg;
 	}
 
@@ -1276,8 +1256,6 @@
 	media_entity_cleanup(&sd->entity);
 err_hdl:
 	v4l2_ctrl_handler_free(&state->hdl);
-err_free:
-	kfree(state);
 	return err;
 }
 
@@ -1302,15 +1280,14 @@
 	v4l2_device_unregister_subdev(sd);
 	media_entity_cleanup(&sd->entity);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	kfree(get_ad9389b_state(sd));
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_device_id ad9389b_id[] = {
-	{ "ad9389b", V4L2_IDENT_AD9389B },
-	{ "ad9889b", V4L2_IDENT_AD9389B },
+	{ "ad9389b", 0 },
+	{ "ad9889b", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, ad9389b_id);
diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c
index ef75abe..873fe19 100644
--- a/drivers/media/i2c/adp1653.c
+++ b/drivers/media/i2c/adp1653.c
@@ -417,7 +417,7 @@
 	if (client->dev.platform_data == NULL)
 		return -ENODEV;
 
-	flash = kzalloc(sizeof(*flash), GFP_KERNEL);
+	flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
 	if (flash == NULL)
 		return -ENOMEM;
 
@@ -443,7 +443,6 @@
 
 free_and_quit:
 	v4l2_ctrl_handler_free(&flash->ctrls);
-	kfree(flash);
 	return ret;
 }
 
@@ -455,7 +454,7 @@
 	v4l2_device_unregister_subdev(&flash->subdev);
 	v4l2_ctrl_handler_free(&flash->ctrls);
 	media_entity_cleanup(&flash->subdev.entity);
-	kfree(flash);
+
 	return 0;
 }
 
diff --git a/drivers/media/i2c/adv7170.c b/drivers/media/i2c/adv7170.c
index 6bc01fb..04bb297 100644
--- a/drivers/media/i2c/adv7170.c
+++ b/drivers/media/i2c/adv7170.c
@@ -36,7 +36,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
 MODULE_AUTHOR("Maxim Yevtyushkin");
@@ -317,19 +316,8 @@
 	return ret;
 }
 
-static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7170, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
-static const struct v4l2_subdev_core_ops adv7170_core_ops = {
-	.g_chip_ident = adv7170_g_chip_ident,
-};
-
 static const struct v4l2_subdev_video_ops adv7170_video_ops = {
 	.s_std_output = adv7170_s_std_output,
 	.s_routing = adv7170_s_routing,
@@ -339,7 +327,6 @@
 };
 
 static const struct v4l2_subdev_ops adv7170_ops = {
-	.core = &adv7170_core_ops,
 	.video = &adv7170_video_ops,
 };
 
@@ -359,7 +346,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
+	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
 	sd = &encoder->sd;
@@ -384,7 +371,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_adv7170(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/adv7175.c b/drivers/media/i2c/adv7175.c
index c7640fa..b88f3b3 100644
--- a/drivers/media/i2c/adv7175.c
+++ b/drivers/media/i2c/adv7175.c
@@ -32,7 +32,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
 MODULE_AUTHOR("Dave Perks");
@@ -355,13 +354,6 @@
 	return ret;
 }
 
-static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
-}
-
 static int adv7175_s_power(struct v4l2_subdev *sd, int on)
 {
 	if (on)
@@ -375,7 +367,6 @@
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops adv7175_core_ops = {
-	.g_chip_ident = adv7175_g_chip_ident,
 	.init = adv7175_init,
 	.s_power = adv7175_s_power,
 };
@@ -409,7 +400,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
+	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
 	sd = &encoder->sd;
@@ -434,7 +425,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_adv7175(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index afd561a..d7d99f1 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1,6 +1,8 @@
 /*
  * adv7180.c Analog Devices ADV7180 video decoder driver
  * Copyright (c) 2009 Intel Corporation
+ * Copyright (C) 2013 Cogent Embedded, Inc.
+ * Copyright (C) 2013 Renesas Solutions Corp.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -27,7 +29,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 #include <linux/mutex.h>
 
 #define ADV7180_INPUT_CONTROL_REG			0x00
@@ -272,14 +273,6 @@
 	return ret;
 }
 
-static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
-}
-
 static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 {
 	struct adv7180_state *state = to_state(sd);
@@ -397,14 +390,57 @@
 	v4l2_ctrl_handler_free(&state->ctrl_hdl);
 }
 
+static int adv7180_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
+				 enum v4l2_mbus_pixelcode *code)
+{
+	if (index > 0)
+		return -EINVAL;
+
+	*code = V4L2_MBUS_FMT_YUYV8_2X8;
+
+	return 0;
+}
+
+static int adv7180_mbus_fmt(struct v4l2_subdev *sd,
+			    struct v4l2_mbus_framefmt *fmt)
+{
+	struct adv7180_state *state = to_state(sd);
+
+	fmt->code = V4L2_MBUS_FMT_YUYV8_2X8;
+	fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+	fmt->field = V4L2_FIELD_INTERLACED;
+	fmt->width = 720;
+	fmt->height = state->curr_norm & V4L2_STD_525_60 ? 480 : 576;
+
+	return 0;
+}
+
+static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
+				 struct v4l2_mbus_config *cfg)
+{
+	/*
+	 * The ADV7180 sensor supports BT.601/656 output modes.
+	 * The BT.656 is default and not yet configurable by s/w.
+	 */
+	cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
+		     V4L2_MBUS_DATA_ACTIVE_HIGH;
+	cfg->type = V4L2_MBUS_BT656;
+
+	return 0;
+}
+
 static const struct v4l2_subdev_video_ops adv7180_video_ops = {
 	.querystd = adv7180_querystd,
 	.g_input_status = adv7180_g_input_status,
 	.s_routing = adv7180_s_routing,
+	.enum_mbus_fmt = adv7180_enum_mbus_fmt,
+	.try_mbus_fmt = adv7180_mbus_fmt,
+	.g_mbus_fmt = adv7180_mbus_fmt,
+	.s_mbus_fmt = adv7180_mbus_fmt,
+	.g_mbus_config = adv7180_g_mbus_config,
 };
 
 static const struct v4l2_subdev_core_ops adv7180_core_ops = {
-	.g_chip_ident = adv7180_g_chip_ident,
 	.s_std = adv7180_s_std,
 };
 
@@ -555,7 +591,7 @@
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 		 client->addr, client->adapter->name);
 
-	state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL) {
 		ret = -ENOMEM;
 		goto err;
@@ -582,7 +618,6 @@
 err_unreg_subdev:
 	mutex_destroy(&state->mutex);
 	v4l2_device_unregister_subdev(sd);
-	kfree(state);
 err:
 	printk(KERN_ERR KBUILD_MODNAME ": Failed to probe: %d\n", ret);
 	return ret;
@@ -607,7 +642,6 @@
 
 	mutex_destroy(&state->mutex);
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 	return 0;
 }
 
@@ -616,9 +650,10 @@
 	{},
 };
 
-#ifdef CONFIG_PM
-static int adv7180_suspend(struct i2c_client *client, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int adv7180_suspend(struct device *dev)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	int ret;
 
 	ret = i2c_smbus_write_byte_data(client, ADV7180_PWR_MAN_REG,
@@ -628,8 +663,9 @@
 	return 0;
 }
 
-static int adv7180_resume(struct i2c_client *client)
+static int adv7180_resume(struct device *dev)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct adv7180_state *state = to_state(sd);
 	int ret;
@@ -643,6 +679,12 @@
 		return ret;
 	return 0;
 }
+
+static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, adv7180_suspend, adv7180_resume);
+#define ADV7180_PM_OPS (&adv7180_pm_ops)
+
+#else
+#define ADV7180_PM_OPS NULL
 #endif
 
 MODULE_DEVICE_TABLE(i2c, adv7180_id);
@@ -651,13 +693,10 @@
 	.driver = {
 		   .owner = THIS_MODULE,
 		   .name = KBUILD_MODNAME,
+		   .pm = ADV7180_PM_OPS,
 		   },
 	.probe = adv7180_probe,
 	.remove = adv7180_remove,
-#ifdef CONFIG_PM
-	.suspend = adv7180_suspend,
-	.resume = adv7180_resume,
-#endif
 	.id_table = adv7180_id,
 };
 
diff --git a/drivers/media/i2c/adv7183.c b/drivers/media/i2c/adv7183.c
index 56a1fa4..6f738d8 100644
--- a/drivers/media/i2c/adv7183.c
+++ b/drivers/media/i2c/adv7183.c
@@ -28,7 +28,6 @@
 #include <linux/videodev2.h>
 
 #include <media/adv7183.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 
@@ -375,28 +374,28 @@
 	reg = adv7183_read(sd, ADV7183_STATUS_1);
 	switch ((reg >> 0x4) & 0x7) {
 	case 0:
-		*std = V4L2_STD_NTSC;
+		*std &= V4L2_STD_NTSC;
 		break;
 	case 1:
-		*std = V4L2_STD_NTSC_443;
+		*std &= V4L2_STD_NTSC_443;
 		break;
 	case 2:
-		*std = V4L2_STD_PAL_M;
+		*std &= V4L2_STD_PAL_M;
 		break;
 	case 3:
-		*std = V4L2_STD_PAL_60;
+		*std &= V4L2_STD_PAL_60;
 		break;
 	case 4:
-		*std = V4L2_STD_PAL;
+		*std &= V4L2_STD_PAL;
 		break;
 	case 5:
-		*std = V4L2_STD_SECAM;
+		*std &= V4L2_STD_SECAM;
 		break;
 	case 6:
-		*std = V4L2_STD_PAL_Nc;
+		*std &= V4L2_STD_PAL_Nc;
 		break;
 	case 7:
-		*std = V4L2_STD_SECAM;
+		*std &= V4L2_STD_SECAM;
 		break;
 	default:
 		*std = V4L2_STD_UNKNOWN;
@@ -474,34 +473,16 @@
 	struct adv7183 *decoder = to_adv7183(sd);
 
 	if (enable)
-		gpio_direction_output(decoder->oe_pin, 0);
+		gpio_set_value(decoder->oe_pin, 0);
 	else
-		gpio_direction_output(decoder->oe_pin, 1);
+		gpio_set_value(decoder->oe_pin, 1);
 	udelay(1);
 	return 0;
 }
 
-static int adv7183_g_chip_ident(struct v4l2_subdev *sd,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	int rev;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	/* 0x11 for adv7183, 0x13 for adv7183b */
-	rev = adv7183_read(sd, ADV7183_IDENT);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7183, rev);
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int adv7183_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = adv7183_read(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -509,12 +490,6 @@
 
 static int adv7183_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	adv7183_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
@@ -529,7 +504,6 @@
 	.g_std = adv7183_g_std,
 	.s_std = adv7183_s_std,
 	.reset = adv7183_reset,
-	.g_chip_ident = adv7183_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = adv7183_g_register,
 	.s_register = adv7183_s_register,
@@ -573,23 +547,24 @@
 	if (pin_array == NULL)
 		return -EINVAL;
 
-	decoder = kzalloc(sizeof(struct adv7183), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (decoder == NULL)
 		return -ENOMEM;
 
 	decoder->reset_pin = pin_array[0];
 	decoder->oe_pin = pin_array[1];
 
-	if (gpio_request(decoder->reset_pin, "ADV7183 Reset")) {
+	if (devm_gpio_request_one(&client->dev, decoder->reset_pin,
+				  GPIOF_OUT_INIT_LOW, "ADV7183 Reset")) {
 		v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin);
-		ret = -EBUSY;
-		goto err_free_decoder;
+		return -EBUSY;
 	}
 
-	if (gpio_request(decoder->oe_pin, "ADV7183 Output Enable")) {
+	if (devm_gpio_request_one(&client->dev, decoder->oe_pin,
+				  GPIOF_OUT_INIT_HIGH,
+				  "ADV7183 Output Enable")) {
 		v4l_err(client, "failed to request GPIO %d\n", decoder->oe_pin);
-		ret = -EBUSY;
-		goto err_free_reset;
+		return -EBUSY;
 	}
 
 	sd = &decoder->sd;
@@ -611,7 +586,7 @@
 		ret = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		goto err_free_oe;
+		return ret;
 	}
 
 	/* v4l2 doesn't support an autodetect standard, pick PAL as default */
@@ -619,12 +594,10 @@
 	decoder->input = ADV7183_COMPOSITE4;
 	decoder->output = ADV7183_8BIT_OUT;
 
-	gpio_direction_output(decoder->oe_pin, 1);
 	/* reset chip */
-	gpio_direction_output(decoder->reset_pin, 0);
 	/* reset pulse width at least 5ms */
 	mdelay(10);
-	gpio_direction_output(decoder->reset_pin, 1);
+	gpio_set_value(decoder->reset_pin, 1);
 	/* wait 5ms before any further i2c writes are performed */
 	mdelay(5);
 
@@ -638,29 +611,18 @@
 	ret = v4l2_ctrl_handler_setup(hdl);
 	if (ret) {
 		v4l2_ctrl_handler_free(hdl);
-		goto err_free_oe;
+		return ret;
 	}
 
 	return 0;
-err_free_oe:
-	gpio_free(decoder->oe_pin);
-err_free_reset:
-	gpio_free(decoder->reset_pin);
-err_free_decoder:
-	kfree(decoder);
-	return ret;
 }
 
 static int adv7183_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct adv7183 *decoder = to_adv7183(sd);
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	gpio_free(decoder->oe_pin);
-	gpio_free(decoder->reset_pin);
-	kfree(decoder);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index 9fc2b98..7606218 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -28,7 +28,6 @@
 
 #include <media/adv7343.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #include "adv7343_regs.h"
@@ -311,21 +310,12 @@
 	return -EINVAL;
 }
 
-static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0);
-}
-
 static const struct v4l2_ctrl_ops adv7343_ctrl_ops = {
 	.s_ctrl = adv7343_s_ctrl,
 };
 
 static const struct v4l2_subdev_core_ops adv7343_core_ops = {
 	.log_status = adv7343_log_status,
-	.g_chip_ident = adv7343_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
diff --git a/drivers/media/i2c/adv7393.c b/drivers/media/i2c/adv7393.c
index 3dc6098..558f191 100644
--- a/drivers/media/i2c/adv7393.c
+++ b/drivers/media/i2c/adv7393.c
@@ -33,7 +33,6 @@
 
 #include <media/adv7393.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #include "adv7393_regs.h"
@@ -301,21 +300,12 @@
 	return -EINVAL;
 }
 
-static int adv7393_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7393, 0);
-}
-
 static const struct v4l2_ctrl_ops adv7393_ctrl_ops = {
 	.s_ctrl = adv7393_s_ctrl,
 };
 
 static const struct v4l2_subdev_core_ops adv7393_core_ops = {
 	.log_status = adv7393_log_status,
-	.g_chip_ident = adv7393_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -410,7 +400,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct adv7393_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 
@@ -444,16 +434,13 @@
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 	v4l2_ctrl_handler_setup(&state->hdl);
 
 	err = adv7393_initialize(&state->sd);
-	if (err) {
+	if (err)
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
-	}
 	return err;
 }
 
@@ -464,7 +451,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 
 	return 0;
 }
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 31a63c9..1d675b5 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -38,7 +38,6 @@
 #include <linux/v4l2-dv-timings.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/adv7604.h>
 
 static int debug;
@@ -643,12 +642,6 @@
 static int adv7604_g_register(struct v4l2_subdev *sd,
 					struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->size = 1;
 	switch (reg->reg >> 8) {
 	case 0:
@@ -701,12 +694,6 @@
 static int adv7604_s_register(struct v4l2_subdev *sd,
 					const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	switch (reg->reg >> 8) {
 	case 0:
 		io_write(sd, reg->reg & 0xff, reg->val & 0xff);
@@ -984,14 +971,6 @@
 	return -EINVAL;
 }
 
-static int adv7604_g_chip_ident(struct v4l2_subdev *sd,
-					struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7604, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static inline bool no_power(struct v4l2_subdev *sd)
@@ -1787,7 +1766,6 @@
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.queryctrl = v4l2_subdev_queryctrl,
 	.querymenu = v4l2_subdev_querymenu,
-	.g_chip_ident = adv7604_g_chip_ident,
 	.interrupt_service_routine = adv7604_isr,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = adv7604_g_register,
@@ -1968,7 +1946,7 @@
 	v4l_dbg(1, debug, client, "detecting adv7604 client on address 0x%x\n",
 			client->addr << 1);
 
-	state = kzalloc(sizeof(struct adv7604_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (!state) {
 		v4l_err(client, "Could not allocate adv7604_state memory!\n");
 		return -ENOMEM;
@@ -1977,8 +1955,7 @@
 	/* platform data */
 	if (!pdata) {
 		v4l_err(client, "No platform data!\n");
-		err = -ENODEV;
-		goto err_state;
+		return -ENODEV;
 	}
 	memcpy(&state->pdata, pdata, sizeof(state->pdata));
 
@@ -1991,8 +1968,7 @@
 	if (adv_smbus_read_byte_data_check(client, 0xfb, false) != 0x68) {
 		v4l2_info(sd, "not an adv7604 on address 0x%x\n",
 				client->addr << 1);
-		err = -ENODEV;
-		goto err_state;
+		return -ENODEV;
 	}
 
 	/* control handlers */
@@ -2093,8 +2069,6 @@
 	adv7604_unregister_clients(state);
 err_hdl:
 	v4l2_ctrl_handler_free(hdl);
-err_state:
-	kfree(state);
 	return err;
 }
 
@@ -2111,7 +2085,6 @@
 	media_entity_cleanup(&sd->entity);
 	adv7604_unregister_clients(to_state(sd));
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/ak881x.c b/drivers/media/i2c/ak881x.c
index fd47465..c14e667 100644
--- a/drivers/media/i2c/ak881x.c
+++ b/drivers/media/i2c/ak881x.c
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 
 #include <media/ak881x.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 
@@ -33,7 +32,6 @@
 	struct v4l2_subdev subdev;
 	struct ak881x_pdata *pdata;
 	unsigned int lines;
-	int id;	/* DEVICE_ID code V4L2_IDENT_AK881X code from v4l2-chip-ident.h */
 	char revision;	/* DEVICE_REVISION content */
 };
 
@@ -62,36 +60,16 @@
 	return container_of(i2c_get_clientdata(client), struct ak881x, subdev);
 }
 
-static int ak881x_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ak881x *ak881x = to_ak881x(client);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= ak881x->id;
-	id->revision	= ak881x->revision;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ak881x_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x26)
+	if (reg->reg > 0x26)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
+	reg->size = 1;
 	reg->val = reg_read(client, reg->reg);
 
 	if (reg->val > 0xffff)
@@ -105,12 +83,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x26)
+	if (reg->reg > 0x26)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -229,7 +204,6 @@
 }
 
 static struct v4l2_subdev_core_ops ak881x_subdev_core_ops = {
-	.g_chip_ident	= ak881x_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= ak881x_g_register,
 	.s_register	= ak881x_s_register,
@@ -264,7 +238,7 @@
 		return -EIO;
 	}
 
-	ak881x = kzalloc(sizeof(struct ak881x), GFP_KERNEL);
+	ak881x = devm_kzalloc(&client->dev, sizeof(*ak881x), GFP_KERNEL);
 	if (!ak881x)
 		return -ENOMEM;
 
@@ -274,15 +248,11 @@
 
 	switch (data) {
 	case 0x13:
-		ak881x->id = V4L2_IDENT_AK8813;
-		break;
 	case 0x14:
-		ak881x->id = V4L2_IDENT_AK8814;
 		break;
 	default:
 		dev_err(&client->dev,
 			"No ak881x chip detected, register read %x\n", data);
-		kfree(ak881x);
 		return -ENODEV;
 	}
 
@@ -331,7 +301,6 @@
 	struct ak881x *ak881x = to_ak881x(client);
 
 	v4l2_device_unregister_subdev(&ak881x->subdev);
-	kfree(ak881x);
 
 	return 0;
 }
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c
index 58d523f..301084b 100644
--- a/drivers/media/i2c/as3645a.c
+++ b/drivers/media/i2c/as3645a.c
@@ -813,7 +813,7 @@
 	if (client->dev.platform_data == NULL)
 		return -ENODEV;
 
-	flash = kzalloc(sizeof(*flash), GFP_KERNEL);
+	flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
 	if (flash == NULL)
 		return -ENOMEM;
 
@@ -838,10 +838,8 @@
 	flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
 
 done:
-	if (ret < 0) {
+	if (ret < 0)
 		v4l2_ctrl_handler_free(&flash->ctrls);
-		kfree(flash);
-	}
 
 	return ret;
 }
@@ -855,7 +853,6 @@
 	v4l2_ctrl_handler_free(&flash->ctrls);
 	media_entity_cleanup(&flash->subdev.entity);
 	mutex_destroy(&flash->power_lock);
-	kfree(flash);
 
 	return 0;
 }
diff --git a/drivers/media/i2c/bt819.c b/drivers/media/i2c/bt819.c
index 377bf05..369cf6f 100644
--- a/drivers/media/i2c/bt819.c
+++ b/drivers/media/i2c/bt819.c
@@ -36,7 +36,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/bt819.h>
 
@@ -57,7 +56,6 @@
 	unsigned char reg[32];
 
 	v4l2_std_id norm;
-	int ident;
 	int input;
 	int enable;
 };
@@ -217,15 +215,17 @@
 	struct bt819 *decoder = to_bt819(sd);
 	int status = bt819_read(decoder, 0x00);
 	int res = V4L2_IN_ST_NO_SIGNAL;
-	v4l2_std_id std;
+	v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
 
 	if ((status & 0x80))
 		res = 0;
+	else
+		std = V4L2_STD_UNKNOWN;
 
 	if ((status & 0x10))
-		std = V4L2_STD_PAL;
+		std &= V4L2_STD_PAL;
 	else
-		std = V4L2_STD_NTSC;
+		std &= V4L2_STD_NTSC;
 	if (pstd)
 		*pstd = std;
 	if (pstatus)
@@ -373,14 +373,6 @@
 	return 0;
 }
 
-static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct bt819 *decoder = to_bt819(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
@@ -388,7 +380,6 @@
 };
 
 static const struct v4l2_subdev_core_ops bt819_core_ops = {
-	.g_chip_ident = bt819_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -425,7 +416,7 @@
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (decoder == NULL)
 		return -ENOMEM;
 	sd = &decoder->sd;
@@ -435,15 +426,12 @@
 	switch (ver & 0xf0) {
 	case 0x70:
 		name = "bt819a";
-		decoder->ident = V4L2_IDENT_BT819A;
 		break;
 	case 0x60:
 		name = "bt817a";
-		decoder->ident = V4L2_IDENT_BT817A;
 		break;
 	case 0x20:
 		name = "bt815a";
-		decoder->ident = V4L2_IDENT_BT815A;
 		break;
 	default:
 		v4l2_dbg(1, debug, sd,
@@ -476,7 +464,6 @@
 		int err = decoder->hdl.error;
 
 		v4l2_ctrl_handler_free(&decoder->hdl);
-		kfree(decoder);
 		return err;
 	}
 	v4l2_ctrl_handler_setup(&decoder->hdl);
@@ -490,7 +477,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&decoder->hdl);
-	kfree(decoder);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/bt856.c b/drivers/media/i2c/bt856.c
index 7e5bd36..7fc163d 100644
--- a/drivers/media/i2c/bt856.c
+++ b/drivers/media/i2c/bt856.c
@@ -36,7 +36,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
 MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -177,17 +176,9 @@
 	return 0;
 }
 
-static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops bt856_core_ops = {
-	.g_chip_ident = bt856_g_chip_ident,
 	.init = bt856_init,
 };
 
@@ -216,7 +207,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
+	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
 	sd = &encoder->sd;
@@ -250,7 +241,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_bt856(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/bt866.c b/drivers/media/i2c/bt866.c
index 905320b..a8bf10f 100644
--- a/drivers/media/i2c/bt866.c
+++ b/drivers/media/i2c/bt866.c
@@ -36,7 +36,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
 MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -175,26 +174,14 @@
 	bt866_write(client, 0xdc, val);
 #endif
 
-static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
-static const struct v4l2_subdev_core_ops bt866_core_ops = {
-	.g_chip_ident = bt866_g_chip_ident,
-};
-
 static const struct v4l2_subdev_video_ops bt866_video_ops = {
 	.s_std_output = bt866_s_std_output,
 	.s_routing = bt866_s_routing,
 };
 
 static const struct v4l2_subdev_ops bt866_ops = {
-	.core = &bt866_core_ops,
 	.video = &bt866_video_ops,
 };
 
@@ -207,7 +194,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
+	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
 	sd = &encoder->sd;
@@ -220,7 +207,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_bt866(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/cs5345.c b/drivers/media/i2c/cs5345.c
index 1d2f7c8..34b76a9 100644
--- a/drivers/media/i2c/cs5345.c
+++ b/drivers/media/i2c/cs5345.c
@@ -24,7 +24,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC");
@@ -99,12 +98,6 @@
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int cs5345_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->size = 1;
 	reg->val = cs5345_read(sd, reg->reg & 0x1f);
 	return 0;
@@ -112,24 +105,11 @@
 
 static int cs5345_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	cs5345_write(sd, reg->reg & 0x1f, reg->val & 0xff);
 	return 0;
 }
 #endif
 
-static int cs5345_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_CS5345, 0);
-}
-
 static int cs5345_log_status(struct v4l2_subdev *sd)
 {
 	u8 v = cs5345_read(sd, 0x09) & 7;
@@ -152,7 +132,6 @@
 
 static const struct v4l2_subdev_core_ops cs5345_core_ops = {
 	.log_status = cs5345_log_status,
-	.g_chip_ident = cs5345_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -190,7 +169,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct cs5345_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -206,7 +185,6 @@
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 	/* set volume/mute */
@@ -227,7 +205,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/cs53l32a.c b/drivers/media/i2c/cs53l32a.c
index b293912..27400c1 100644
--- a/drivers/media/i2c/cs53l32a.c
+++ b/drivers/media/i2c/cs53l32a.c
@@ -28,7 +28,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
@@ -104,14 +103,6 @@
 	return -EINVAL;
 }
 
-static int cs53l32a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client,
-			chip, V4L2_IDENT_CS53l32A, 0);
-}
-
 static int cs53l32a_log_status(struct v4l2_subdev *sd)
 {
 	struct cs53l32a_state *state = to_state(sd);
@@ -130,7 +121,6 @@
 
 static const struct v4l2_subdev_core_ops cs53l32a_core_ops = {
 	.log_status = cs53l32a_log_status,
-	.g_chip_ident = cs53l32a_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -175,7 +165,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct cs53l32a_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -197,7 +187,6 @@
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 
@@ -228,7 +217,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index 12fb9b2..2e3771d 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -45,7 +45,6 @@
 #include <linux/delay.h>
 #include <linux/math64.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/cx25840.h>
 
 #include "cx25840-core.h"
@@ -498,7 +497,7 @@
 
 	/* Sys PLL */
 	switch (state->id) {
-	case V4L2_IDENT_CX23888_AV:
+	case CX23888_AV:
 		/*
 		 * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz
 		 * 572.73 MHz before post divide
@@ -511,7 +510,7 @@
 		cx25840_write4(client, 0x42c, 0x42600000);
 		cx25840_write4(client, 0x44c, 0x161f1000);
 		break;
-	case V4L2_IDENT_CX23887_AV:
+	case CX23887_AV:
 		/*
 		 * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz
 		 * 572.73 MHz before post divide
@@ -519,7 +518,7 @@
 		cx25840_write4(client, 0x11c, 0x01d1744c);
 		cx25840_write4(client, 0x118, 0x00000416);
 		break;
-	case V4L2_IDENT_CX23885_AV:
+	case CX23885_AV:
 	default:
 		/*
 		 * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz
@@ -546,7 +545,7 @@
 
 	/* HVR1850 */
 	switch (state->id) {
-	case V4L2_IDENT_CX23888_AV:
+	case CX23888_AV:
 		/* 888/HVR1250 specific */
 		cx25840_write4(client, 0x10c, 0x13333333);
 		cx25840_write4(client, 0x108, 0x00000515);
@@ -570,7 +569,7 @@
 	 * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz
 	 */
 	switch (state->id) {
-	case V4L2_IDENT_CX23888_AV:
+	case CX23888_AV:
 		/*
 		 * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz
 		 * 368.64 MHz before post divide
@@ -580,7 +579,7 @@
 		cx25840_write4(client, 0x114, 0x017dbf48);
 		cx25840_write4(client, 0x110, 0x000a030e);
 		break;
-	case V4L2_IDENT_CX23887_AV:
+	case CX23887_AV:
 		/*
 		 * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz
 		 * 368.64 MHz before post divide
@@ -589,7 +588,7 @@
 		cx25840_write4(client, 0x114, 0x017dbf48);
 		cx25840_write4(client, 0x110, 0x000a030e);
 		break;
-	case V4L2_IDENT_CX23885_AV:
+	case CX23885_AV:
 	default:
 		/*
 		 * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz
@@ -1662,10 +1661,6 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->size = 1;
 	reg->val = cx25840_read(client, reg->reg & 0x0fff);
 	return 0;
@@ -1675,10 +1670,6 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
 	return 0;
 }
@@ -1938,14 +1929,6 @@
 	return 0;
 }
 
-static int cx25840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct cx25840_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
-}
-
 static int cx25840_log_status(struct v4l2_subdev *sd)
 {
 	struct cx25840_state *state = to_state(sd);
@@ -5051,7 +5034,6 @@
 
 static const struct v4l2_subdev_core_ops cx25840_core_ops = {
 	.log_status = cx25840_log_status,
-	.g_chip_ident = cx25840_g_chip_ident,
 	.g_ctrl = v4l2_subdev_g_ctrl,
 	.s_ctrl = v4l2_subdev_s_ctrl,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -5128,18 +5110,18 @@
 		ret = cx25840_read4(client, 0x300);
 		if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {
 			/* No DIF */
-			ret = V4L2_IDENT_CX23885_AV;
+			ret = CX23885_AV;
 		} else {
 			/* CX23887 has a broken DIF, but the registers
 			 * appear valid (but unused), good enough to detect. */
-			ret = V4L2_IDENT_CX23887_AV;
+			ret = CX23887_AV;
 		}
 	} else if (cx25840_read4(client, 0x300) & 0x0fffffff) {
 		/* DIF PLL Freq Word reg exists; chip must be a CX23888 */
-		ret = V4L2_IDENT_CX23888_AV;
+		ret = CX23888_AV;
 	} else {
 		v4l_err(client, "Unable to detect h/w, assuming cx23887\n");
-		ret = V4L2_IDENT_CX23887_AV;
+		ret = CX23887_AV;
 	}
 
 	/* Back into digital power down */
@@ -5153,7 +5135,7 @@
 	struct cx25840_state *state;
 	struct v4l2_subdev *sd;
 	int default_volume;
-	u32 id = V4L2_IDENT_NONE;
+	u32 id;
 	u16 device_id;
 
 	/* Check if the adapter supports the needed features */
@@ -5169,14 +5151,14 @@
 	/* The high byte of the device ID should be
 	 * 0x83 for the cx2583x and 0x84 for the cx2584x */
 	if ((device_id & 0xff00) == 0x8300) {
-		id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
+		id = CX25836 + ((device_id >> 4) & 0xf) - 6;
 	} else if ((device_id & 0xff00) == 0x8400) {
-		id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
+		id = CX25840 + ((device_id >> 4) & 0xf);
 	} else if (device_id == 0x0000) {
 		id = get_cx2388x_ident(client);
 	} else if ((device_id & 0xfff0) == 0x5A30) {
 		/* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */
-		id = V4L2_IDENT_CX2310X_AV;
+		id = CX2310X_AV;
 	} else if ((device_id & 0xff) == (device_id >> 8)) {
 		v4l_err(client,
 			"likely a confused/unresponsive cx2388[578] A/V decoder"
@@ -5190,7 +5172,7 @@
 		return -ENODEV;
 	}
 
-	state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 
@@ -5198,26 +5180,26 @@
 	v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
 
 	switch (id) {
-	case V4L2_IDENT_CX23885_AV:
+	case CX23885_AV:
 		v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
 			 client->addr << 1, client->adapter->name);
 		break;
-	case V4L2_IDENT_CX23887_AV:
+	case CX23887_AV:
 		v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",
 			 client->addr << 1, client->adapter->name);
 		break;
-	case V4L2_IDENT_CX23888_AV:
+	case CX23888_AV:
 		v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",
 			 client->addr << 1, client->adapter->name);
 		break;
-	case V4L2_IDENT_CX2310X_AV:
+	case CX2310X_AV:
 		v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",
 			 device_id, client->addr << 1, client->adapter->name);
 		break;
-	case V4L2_IDENT_CX25840:
-	case V4L2_IDENT_CX25841:
-	case V4L2_IDENT_CX25842:
-	case V4L2_IDENT_CX25843:
+	case CX25840:
+	case CX25841:
+	case CX25842:
+	case CX25843:
 		/* Note: revision '(device_id & 0x0f) == 2' was never built. The
 		   marking skips from 0x1 == 22 to 0x3 == 23. */
 		v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
@@ -5226,8 +5208,8 @@
 						: (device_id & 0x0f),
 			 client->addr << 1, client->adapter->name);
 		break;
-	case V4L2_IDENT_CX25836:
-	case V4L2_IDENT_CX25837:
+	case CX25836:
+	case CX25837:
 	default:
 		v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",
 			 (device_id & 0xfff0) >> 4, device_id & 0x0f,
@@ -5292,7 +5274,6 @@
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 	if (!is_cx2583x(state))
@@ -5317,7 +5298,6 @@
 	cx25840_ir_remove(sd);
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/cx25840/cx25840-core.h b/drivers/media/i2c/cx25840/cx25840-core.h
index bd4ada2..37bc042 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.h
+++ b/drivers/media/i2c/cx25840/cx25840-core.h
@@ -23,12 +23,24 @@
 
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <linux/i2c.h>
 
 struct cx25840_ir_state;
 
+enum cx25840_model {
+	CX23885_AV,
+	CX23887_AV,
+	CX23888_AV,
+	CX2310X_AV,
+	CX25840,
+	CX25841,
+	CX25842,
+	CX25843,
+	CX25836,
+	CX25837,
+};
+
 struct cx25840_state {
 	struct i2c_client *c;
 	struct v4l2_subdev sd;
@@ -46,7 +58,7 @@
 	u32 audclk_freq;
 	int audmode;
 	int vbi_line_offset;
-	u32 id;
+	enum cx25840_model id;
 	u32 rev;
 	int is_initialized;
 	wait_queue_head_t fw_wait;    /* wake up when the fw load is finished */
@@ -66,35 +78,35 @@
 
 static inline bool is_cx2583x(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX25836 ||
-	       state->id == V4L2_IDENT_CX25837;
+	return state->id == CX25836 ||
+	       state->id == CX25837;
 }
 
 static inline bool is_cx231xx(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX2310X_AV;
+	return state->id == CX2310X_AV;
 }
 
 static inline bool is_cx2388x(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX23885_AV ||
-	       state->id == V4L2_IDENT_CX23887_AV ||
-	       state->id == V4L2_IDENT_CX23888_AV;
+	return state->id == CX23885_AV ||
+	       state->id == CX23887_AV ||
+	       state->id == CX23888_AV;
 }
 
 static inline bool is_cx23885(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX23885_AV;
+	return state->id == CX23885_AV;
 }
 
 static inline bool is_cx23887(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX23887_AV;
+	return state->id == CX23887_AV;
 }
 
 static inline bool is_cx23888(struct cx25840_state *state)
 {
-	return state->id == V4L2_IDENT_CX23888_AV;
+	return state->id == CX23888_AV;
 }
 
 /* ----------------------------------------------------------------------- */
diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c
index 9ae977b..e6588ee 100644
--- a/drivers/media/i2c/cx25840/cx25840-ir.c
+++ b/drivers/media/i2c/cx25840/cx25840-ir.c
@@ -1230,16 +1230,14 @@
 	if (!(is_cx23885(state) || is_cx23887(state)))
 		return 0;
 
-	ir_state = kzalloc(sizeof(struct cx25840_ir_state), GFP_KERNEL);
+	ir_state = devm_kzalloc(&state->c->dev, sizeof(*ir_state), GFP_KERNEL);
 	if (ir_state == NULL)
 		return -ENOMEM;
 
 	spin_lock_init(&ir_state->rx_kfifo_lock);
 	if (kfifo_alloc(&ir_state->rx_kfifo,
-			CX25840_IR_RX_KFIFO_SIZE, GFP_KERNEL)) {
-		kfree(ir_state);
+			CX25840_IR_RX_KFIFO_SIZE, GFP_KERNEL))
 		return -ENOMEM;
-	}
 
 	ir_state->c = state->c;
 	state->ir_state = ir_state;
@@ -1273,7 +1271,6 @@
 	cx25840_ir_tx_shutdown(sd);
 
 	kfifo_free(&ir_state->rx_kfifo);
-	kfree(ir_state);
 	state->ir_state = NULL;
 	return 0;
 }
diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
index 8e2f79c..82bf567 100644
--- a/drivers/media/i2c/ir-kbd-i2c.c
+++ b/drivers/media/i2c/ir-kbd-i2c.c
@@ -295,7 +295,7 @@
 	unsigned short addr = client->addr;
 	int err;
 
-	ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
+	ir = devm_kzalloc(&client->dev, sizeof(*ir), GFP_KERNEL);
 	if (!ir)
 		return -ENOMEM;
 
@@ -398,10 +398,8 @@
 		 * internally
 		 */
 		rc = rc_allocate_device();
-		if (!rc) {
-			err = -ENOMEM;
-			goto err_out_free;
-		}
+		if (!rc)
+			return -ENOMEM;
 	}
 	ir->rc = rc;
 
@@ -454,7 +452,6 @@
  err_out_free:
 	/* Only frees rc if it were allocated internally */
 	rc_free_device(rc);
-	kfree(ir);
 	return err;
 }
 
@@ -470,7 +467,6 @@
 		rc_unregister_device(ir->rc);
 
 	/* free memory */
-	kfree(ir);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/ks0127.c b/drivers/media/i2c/ks0127.c
index 04a6efa..c3e94ae 100644
--- a/drivers/media/i2c/ks0127.c
+++ b/drivers/media/i2c/ks0127.c
@@ -42,7 +42,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include "ks0127.h"
 
 MODULE_DESCRIPTION("KS0127 video decoder driver");
@@ -200,7 +199,6 @@
 struct ks0127 {
 	struct v4l2_subdev sd;
 	v4l2_std_id	norm;
-	int		ident;
 	u8 		regs[256];
 };
 
@@ -371,12 +369,9 @@
 ****************************************************************************/
 static void ks0127_init(struct v4l2_subdev *sd)
 {
-	struct ks0127 *ks = to_ks0127(sd);
 	u8 *table = reg_defaults;
 	int i;
 
-	ks->ident = V4L2_IDENT_KS0127;
-
 	v4l2_dbg(1, debug, sd, "reset\n");
 	msleep(1);
 
@@ -397,7 +392,6 @@
 
 
 	if ((ks0127_read(sd, KS_STAT) & 0x80) == 0) {
-		ks->ident = V4L2_IDENT_KS0122S;
 		v4l2_dbg(1, debug, sd, "ks0122s found\n");
 		return;
 	}
@@ -408,7 +402,6 @@
 		break;
 
 	case 9:
-		ks->ident = V4L2_IDENT_KS0127B;
 		v4l2_dbg(1, debug, sd, "ks0127B Revision A found\n");
 		break;
 
@@ -616,17 +609,24 @@
 {
 	int stat = V4L2_IN_ST_NO_SIGNAL;
 	u8 status;
-	v4l2_std_id std = V4L2_STD_ALL;
+	v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
 
 	status = ks0127_read(sd, KS_STAT);
 	if (!(status & 0x20))		 /* NOVID not set */
 		stat = 0;
-	if (!(status & 0x01))		      /* CLOCK set */
+	if (!(status & 0x01)) {		      /* CLOCK set */
 		stat |= V4L2_IN_ST_NO_COLOR;
-	if ((status & 0x08))		   /* PALDET set */
-		std = V4L2_STD_PAL;
+		std = V4L2_STD_UNKNOWN;
+	} else {
+		if ((status & 0x08))		   /* PALDET set */
+			std &= V4L2_STD_PAL;
+		else
+			std &= V4L2_STD_NTSC;
+	}
+	if ((status & 0x10))		   /* PALDET set */
+		std &= V4L2_STD_525_60;
 	else
-		std = V4L2_STD_NTSC;
+		std &= V4L2_STD_625_50;
 	if (pstd)
 		*pstd = std;
 	if (pstatus)
@@ -646,18 +646,9 @@
 	return ks0127_status(sd, status, NULL);
 }
 
-static int ks0127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ks0127 *ks = to_ks0127(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, ks->ident, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops ks0127_core_ops = {
-	.g_chip_ident = ks0127_g_chip_ident,
 	.s_std = ks0127_s_std,
 };
 
@@ -685,7 +676,7 @@
 		client->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
 		client->addr << 1, client->adapter->name);
 
-	ks = kzalloc(sizeof(*ks), GFP_KERNEL);
+	ks = devm_kzalloc(&client->dev, sizeof(*ks), GFP_KERNEL);
 	if (ks == NULL)
 		return -ENOMEM;
 	sd = &ks->sd;
@@ -708,7 +699,6 @@
 	v4l2_device_unregister_subdev(sd);
 	ks0127_write(sd, KS_OFMTA, 0x20); /* tristate */
 	ks0127_write(sd, KS_CMDA, 0x2c | 0x80); /* power down */
-	kfree(to_ks0127(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/m52790.c b/drivers/media/i2c/m52790.c
index 39f50fd..bf47635 100644
--- a/drivers/media/i2c/m52790.c
+++ b/drivers/media/i2c/m52790.c
@@ -29,7 +29,6 @@
 #include <linux/videodev2.h>
 #include <media/m52790.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch");
 MODULE_AUTHOR("Hans Verkuil");
@@ -83,12 +82,7 @@
 static int m52790_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
 	struct m52790_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	if (reg->reg != 0)
 		return -EINVAL;
 	reg->size = 1;
@@ -99,12 +93,7 @@
 static int m52790_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
 	struct m52790_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	if (reg->reg != 0)
 		return -EINVAL;
 	state->input = reg->val & 0x0303;
@@ -114,13 +103,6 @@
 }
 #endif
 
-static int m52790_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_M52790, 0);
-}
-
 static int m52790_log_status(struct v4l2_subdev *sd)
 {
 	struct m52790_state *state = to_state(sd);
@@ -136,7 +118,6 @@
 
 static const struct v4l2_subdev_core_ops m52790_core_ops = {
 	.log_status = m52790_log_status,
-	.g_chip_ident = m52790_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = m52790_g_register,
 	.s_register = m52790_s_register,
@@ -174,7 +155,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct m52790_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 
@@ -191,7 +172,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
index 0b899cb..8d870b7 100644
--- a/drivers/media/i2c/m5mols/m5mols_core.c
+++ b/drivers/media/i2c/m5mols/m5mols_core.c
@@ -930,6 +930,7 @@
 			const struct i2c_device_id *id)
 {
 	const struct m5mols_platform_data *pdata = client->dev.platform_data;
+	unsigned long gpio_flags;
 	struct m5mols_info *info;
 	struct v4l2_subdev *sd;
 	int ret;
@@ -949,24 +950,27 @@
 		return -EINVAL;
 	}
 
-	info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL);
+	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
 	info->pdata = pdata;
 	info->set_power	= pdata->set_power;
 
-	ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
+	gpio_flags = pdata->reset_polarity
+		   ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+	ret = devm_gpio_request_one(&client->dev, pdata->gpio_reset, gpio_flags,
+				    "M5MOLS_NRST");
 	if (ret) {
 		dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
-		goto out_free;
+		return ret;
 	}
-	gpio_direction_output(pdata->gpio_reset, pdata->reset_polarity);
 
-	ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
+	ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies),
+				      supplies);
 	if (ret) {
 		dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
-		goto out_gpio;
+		return ret;
 	}
 
 	sd = &info->sd;
@@ -978,17 +982,17 @@
 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
 	if (ret < 0)
-		goto out_reg;
+		return ret;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
 
 	init_waitqueue_head(&info->irq_waitq);
 	mutex_init(&info->lock);
 
-	ret = request_irq(client->irq, m5mols_irq_handler,
-			  IRQF_TRIGGER_RISING, MODULE_NAME, sd);
+	ret = devm_request_irq(&client->dev, client->irq, m5mols_irq_handler,
+			       IRQF_TRIGGER_RISING, MODULE_NAME, sd);
 	if (ret) {
 		dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
-		goto out_me;
+		goto error;
 	}
 	info->res_type = M5MOLS_RESTYPE_MONITOR;
 	info->ffmt[0] = m5mols_default_ffmt[0];
@@ -996,7 +1000,7 @@
 
 	ret = m5mols_sensor_power(info, true);
 	if (ret)
-		goto out_irq;
+		goto error;
 
 	ret = m5mols_fw_start(sd);
 	if (!ret)
@@ -1005,32 +1009,19 @@
 	ret = m5mols_sensor_power(info, false);
 	if (!ret)
 		return 0;
-out_irq:
-	free_irq(client->irq, sd);
-out_me:
+error:
 	media_entity_cleanup(&sd->entity);
-out_reg:
-	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
-out_gpio:
-	gpio_free(pdata->gpio_reset);
-out_free:
-	kfree(info);
 	return ret;
 }
 
 static int m5mols_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct m5mols_info *info = to_m5mols(sd);
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	free_irq(client->irq, sd);
-
-	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
-	gpio_free(info->pdata->gpio_reset);
 	media_entity_cleanup(&sd->entity);
-	kfree(info);
+
 	return 0;
 }
 
diff --git a/drivers/media/i2c/ml86v7667.c b/drivers/media/i2c/ml86v7667.c
new file mode 100644
index 0000000..efdc873
--- /dev/null
+++ b/drivers/media/i2c/ml86v7667.c
@@ -0,0 +1,431 @@
+/*
+ * OKI Semiconductor ML86V7667 video decoder driver
+ *
+ * Author: Vladimir Barinov <source@cogentembedded.com>
+ * Copyright (C) 2013 Cogent Embedded, Inc.
+ * Copyright (C) 2013 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+
+#define DRV_NAME "ml86v7667"
+
+/* Subaddresses */
+#define MRA_REG			0x00 /* Mode Register A */
+#define MRC_REG			0x02 /* Mode Register C */
+#define LUMC_REG		0x0C /* Luminance Control */
+#define CLC_REG			0x10 /* Contrast level control */
+#define SSEPL_REG		0x11 /* Sync separation level */
+#define CHRCA_REG		0x12 /* Chrominance Control A */
+#define ACCC_REG		0x14 /* ACC Loop filter & Chrominance control */
+#define ACCRC_REG		0x15 /* ACC Reference level control */
+#define HUE_REG			0x16 /* Hue control */
+#define ADC2_REG		0x1F /* ADC Register 2 */
+#define PLLR1_REG		0x20 /* PLL Register 1 */
+#define STATUS_REG		0x2C /* STATUS Register */
+
+/* Mode Register A register bits */
+#define MRA_OUTPUT_MODE_MASK	(3 << 6)
+#define MRA_ITUR_BT601		(1 << 6)
+#define MRA_ITUR_BT656		(0 << 6)
+#define MRA_INPUT_MODE_MASK	(7 << 3)
+#define MRA_PAL_BT601		(4 << 3)
+#define MRA_NTSC_BT601		(0 << 3)
+#define MRA_REGISTER_MODE	(1 << 0)
+
+/* Mode Register C register bits */
+#define MRC_AUTOSELECT		(1 << 7)
+
+/* Luminance Control register bits */
+#define LUMC_ONOFF_SHIFT	7
+#define LUMC_ONOFF_MASK		(1 << 7)
+
+/* Contrast level control register bits */
+#define CLC_CONTRAST_ONOFF	(1 << 7)
+#define CLC_CONTRAST_MASK	0x0F
+
+/* Sync separation level register bits */
+#define SSEPL_LUMINANCE_ONOFF	(1 << 7)
+#define SSEPL_LUMINANCE_MASK	0x7F
+
+/* Chrominance Control A register bits */
+#define CHRCA_MODE_SHIFT	6
+#define CHRCA_MODE_MASK		(1 << 6)
+
+/* ACC Loop filter & Chrominance control register bits */
+#define ACCC_CHROMA_CR_SHIFT	3
+#define ACCC_CHROMA_CR_MASK	(7 << 3)
+#define ACCC_CHROMA_CB_SHIFT	0
+#define ACCC_CHROMA_CB_MASK	(7 << 0)
+
+/* ACC Reference level control register bits */
+#define ACCRC_CHROMA_MASK	0xfc
+#define ACCRC_CHROMA_SHIFT	2
+
+/* ADC Register 2 register bits */
+#define ADC2_CLAMP_VOLTAGE_MASK	(7 << 1)
+#define ADC2_CLAMP_VOLTAGE(n)	((n & 7) << 1)
+
+/* PLL Register 1 register bits */
+#define PLLR1_FIXED_CLOCK	(1 << 7)
+
+/* STATUS Register register bits */
+#define STATUS_HLOCK_DETECT	(1 << 3)
+#define STATUS_NTSCPAL		(1 << 2)
+
+struct ml86v7667_priv {
+	struct v4l2_subdev		sd;
+	struct v4l2_ctrl_handler	hdl;
+	v4l2_std_id			std;
+};
+
+static inline struct ml86v7667_priv *to_ml86v7667(struct v4l2_subdev *subdev)
+{
+	return container_of(subdev, struct ml86v7667_priv, sd);
+}
+
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+	return &container_of(ctrl->handler, struct ml86v7667_priv, hdl)->sd;
+}
+
+static int ml86v7667_mask_set(struct i2c_client *client, const u8 reg,
+			      const u8 mask, const u8 data)
+{
+	int val = i2c_smbus_read_byte_data(client, reg);
+	if (val < 0)
+		return val;
+
+	val = (val & ~mask) | (data & mask);
+	return i2c_smbus_write_byte_data(client, reg, val);
+}
+
+static int ml86v7667_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct v4l2_subdev *sd = to_sd(ctrl);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret;
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ret = ml86v7667_mask_set(client, SSEPL_REG,
+					 SSEPL_LUMINANCE_MASK, ctrl->val);
+		break;
+	case V4L2_CID_CONTRAST:
+		ret = ml86v7667_mask_set(client, CLC_REG,
+					 CLC_CONTRAST_MASK, ctrl->val);
+		break;
+	case V4L2_CID_CHROMA_GAIN:
+		ret = ml86v7667_mask_set(client, ACCRC_REG, ACCRC_CHROMA_MASK,
+					 ctrl->val << ACCRC_CHROMA_SHIFT);
+		break;
+	case V4L2_CID_HUE:
+		ret = ml86v7667_mask_set(client, HUE_REG, ~0, ctrl->val);
+		break;
+	case V4L2_CID_RED_BALANCE:
+		ret = ml86v7667_mask_set(client, ACCC_REG,
+					 ACCC_CHROMA_CR_MASK,
+					 ctrl->val << ACCC_CHROMA_CR_SHIFT);
+		break;
+	case V4L2_CID_BLUE_BALANCE:
+		ret = ml86v7667_mask_set(client, ACCC_REG,
+					 ACCC_CHROMA_CB_MASK,
+					 ctrl->val << ACCC_CHROMA_CB_SHIFT);
+		break;
+	case V4L2_CID_SHARPNESS:
+		ret = ml86v7667_mask_set(client, LUMC_REG,
+					 LUMC_ONOFF_MASK,
+					 ctrl->val << LUMC_ONOFF_SHIFT);
+		break;
+	case V4L2_CID_COLOR_KILLER:
+		ret = ml86v7667_mask_set(client, CHRCA_REG,
+					 CHRCA_MODE_MASK,
+					 ctrl->val << CHRCA_MODE_SHIFT);
+		break;
+	}
+
+	return 0;
+}
+
+static int ml86v7667_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int status;
+
+	status = i2c_smbus_read_byte_data(client, STATUS_REG);
+	if (status < 0)
+		return status;
+
+	if (status & STATUS_HLOCK_DETECT)
+		*std &= status & STATUS_NTSCPAL ? V4L2_STD_625_50 : V4L2_STD_525_60;
+	else
+		*std = V4L2_STD_UNKNOWN;
+
+	return 0;
+}
+
+static int ml86v7667_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int status_reg;
+
+	status_reg = i2c_smbus_read_byte_data(client, STATUS_REG);
+	if (status_reg < 0)
+		return status_reg;
+
+	*status = status_reg & STATUS_HLOCK_DETECT ? 0 : V4L2_IN_ST_NO_SIGNAL;
+
+	return 0;
+}
+
+static int ml86v7667_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
+				   enum v4l2_mbus_pixelcode *code)
+{
+	if (index > 0)
+		return -EINVAL;
+
+	*code = V4L2_MBUS_FMT_YUYV8_2X8;
+
+	return 0;
+}
+
+static int ml86v7667_mbus_fmt(struct v4l2_subdev *sd,
+			      struct v4l2_mbus_framefmt *fmt)
+{
+	struct ml86v7667_priv *priv = to_ml86v7667(sd);
+
+	fmt->code = V4L2_MBUS_FMT_YUYV8_2X8;
+	fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
+	fmt->field = V4L2_FIELD_INTERLACED;
+	fmt->width = 720;
+	fmt->height = priv->std & V4L2_STD_525_60 ? 480 : 576;
+
+	return 0;
+}
+
+static int ml86v7667_g_mbus_config(struct v4l2_subdev *sd,
+				   struct v4l2_mbus_config *cfg)
+{
+	cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
+		     V4L2_MBUS_DATA_ACTIVE_HIGH;
+	cfg->type = V4L2_MBUS_BT656;
+
+	return 0;
+}
+
+static int ml86v7667_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct ml86v7667_priv *priv = to_ml86v7667(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+	int ret;
+	u8 mode;
+
+	/* PAL/NTSC ITU-R BT.601 input mode */
+	mode = std & V4L2_STD_525_60 ? MRA_NTSC_BT601 : MRA_PAL_BT601;
+	ret = ml86v7667_mask_set(client, MRA_REG, MRA_INPUT_MODE_MASK, mode);
+	if (ret < 0)
+		return ret;
+
+	priv->std = std;
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ml86v7667_g_register(struct v4l2_subdev *sd,
+				struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(client, (u8)reg->reg);
+	if (ret < 0)
+		return ret;
+
+	reg->val = ret;
+	reg->size = sizeof(u8);
+
+	return 0;
+}
+
+static int ml86v7667_s_register(struct v4l2_subdev *sd,
+				const struct v4l2_dbg_register *reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return i2c_smbus_write_byte_data(client, (u8)reg->reg, (u8)reg->val);
+}
+#endif
+
+static const struct v4l2_ctrl_ops ml86v7667_ctrl_ops = {
+	.s_ctrl = ml86v7667_s_ctrl,
+};
+
+static struct v4l2_subdev_video_ops ml86v7667_subdev_video_ops = {
+	.querystd = ml86v7667_querystd,
+	.g_input_status = ml86v7667_g_input_status,
+	.enum_mbus_fmt = ml86v7667_enum_mbus_fmt,
+	.try_mbus_fmt = ml86v7667_mbus_fmt,
+	.g_mbus_fmt = ml86v7667_mbus_fmt,
+	.s_mbus_fmt = ml86v7667_mbus_fmt,
+	.g_mbus_config = ml86v7667_g_mbus_config,
+};
+
+static struct v4l2_subdev_core_ops ml86v7667_subdev_core_ops = {
+	.s_std = ml86v7667_s_std,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = ml86v7667_g_register,
+	.s_register = ml86v7667_s_register,
+#endif
+};
+
+static struct v4l2_subdev_ops ml86v7667_subdev_ops = {
+	.core = &ml86v7667_subdev_core_ops,
+	.video = &ml86v7667_subdev_video_ops,
+};
+
+static int ml86v7667_init(struct ml86v7667_priv *priv)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&priv->sd);
+	int val;
+	int ret;
+
+	/* BT.656-4 output mode, register mode */
+	ret = ml86v7667_mask_set(client, MRA_REG,
+				 MRA_OUTPUT_MODE_MASK | MRA_REGISTER_MODE,
+				 MRA_ITUR_BT656 | MRA_REGISTER_MODE);
+
+	/* PLL circuit fixed clock, 32MHz */
+	ret |= ml86v7667_mask_set(client, PLLR1_REG, PLLR1_FIXED_CLOCK,
+				  PLLR1_FIXED_CLOCK);
+
+	/* ADC2 clamping voltage maximum  */
+	ret |= ml86v7667_mask_set(client, ADC2_REG, ADC2_CLAMP_VOLTAGE_MASK,
+				  ADC2_CLAMP_VOLTAGE(7));
+
+	/* enable luminance function */
+	ret |= ml86v7667_mask_set(client, SSEPL_REG, SSEPL_LUMINANCE_ONOFF,
+				  SSEPL_LUMINANCE_ONOFF);
+
+	/* enable contrast function */
+	ret |= ml86v7667_mask_set(client, CLC_REG, CLC_CONTRAST_ONOFF, 0);
+
+	/*
+	 * PAL/NTSC autodetection is enabled after reset,
+	 * set the autodetected std in manual std mode and
+	 * disable autodetection
+	 */
+	val = i2c_smbus_read_byte_data(client, STATUS_REG);
+	if (val < 0)
+		return val;
+
+	priv->std = val & STATUS_NTSCPAL ? V4L2_STD_625_50 : V4L2_STD_525_60;
+	ret |= ml86v7667_mask_set(client, MRC_REG, MRC_AUTOSELECT, 0);
+
+	val = priv->std & V4L2_STD_525_60 ? MRA_NTSC_BT601 : MRA_PAL_BT601;
+	ret |= ml86v7667_mask_set(client, MRA_REG, MRA_INPUT_MODE_MASK, val);
+
+	return ret;
+}
+
+static int ml86v7667_probe(struct i2c_client *client,
+			   const struct i2c_device_id *did)
+{
+	struct ml86v7667_priv *priv;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	v4l2_i2c_subdev_init(&priv->sd, client, &ml86v7667_subdev_ops);
+
+	v4l2_ctrl_handler_init(&priv->hdl, 8);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_BRIGHTNESS, -64, 63, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_CONTRAST, -8, 7, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_CHROMA_GAIN, -32, 31, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_HUE, -128, 127, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_RED_BALANCE, -4, 3, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_BLUE_BALANCE, -4, 3, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_SHARPNESS, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(&priv->hdl, &ml86v7667_ctrl_ops,
+			  V4L2_CID_COLOR_KILLER, 0, 1, 1, 0);
+	priv->sd.ctrl_handler = &priv->hdl;
+
+	ret = priv->hdl.error;
+	if (ret)
+		goto cleanup;
+
+	v4l2_ctrl_handler_setup(&priv->hdl);
+
+	ret = ml86v7667_init(priv);
+	if (ret)
+		goto cleanup;
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+		 client->addr, client->adapter->name);
+	return 0;
+
+cleanup:
+	v4l2_ctrl_handler_free(&priv->hdl);
+	v4l2_device_unregister_subdev(&priv->sd);
+	v4l_err(client, "failed to probe @ 0x%02x (%s)\n",
+		client->addr, client->adapter->name);
+	return ret;
+}
+
+static int ml86v7667_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ml86v7667_priv *priv = to_ml86v7667(sd);
+
+	v4l2_ctrl_handler_free(&priv->hdl);
+	v4l2_device_unregister_subdev(&priv->sd);
+
+	return 0;
+}
+
+static const struct i2c_device_id ml86v7667_id[] = {
+	{DRV_NAME, 0},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, ml86v7667_id);
+
+static struct i2c_driver ml86v7667_i2c_driver = {
+	.driver = {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ml86v7667_probe,
+	.remove		= ml86v7667_remove,
+	.id_table	= ml86v7667_id,
+};
+
+module_i2c_driver(ml86v7667_i2c_driver);
+
+MODULE_DESCRIPTION("OKI Semiconductor ML86V7667 video decoder driver");
+MODULE_AUTHOR("Vladimir Barinov");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c
index 54a9dd3..8190fec 100644
--- a/drivers/media/i2c/msp3400-driver.c
+++ b/drivers/media/i2c/msp3400-driver.c
@@ -570,15 +570,6 @@
 	return 0;
 }
 
-static int msp_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct msp_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->ident,
-			(state->rev1 << 16) | state->rev2);
-}
-
 static int msp_log_status(struct v4l2_subdev *sd)
 {
 	struct msp_state *state = to_state(sd);
@@ -651,7 +642,6 @@
 
 static const struct v4l2_subdev_core_ops msp_core_ops = {
 	.log_status = msp_log_status,
-	.g_chip_ident = msp_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -707,7 +697,7 @@
 		return -ENODEV;
 	}
 
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return -ENOMEM;
 
@@ -732,7 +722,6 @@
 	if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) {
 		v4l_dbg(1, msp_debug, client,
 				"not an msp3400 (cannot read chip version)\n");
-		kfree(state);
 		return -ENODEV;
 	}
 
@@ -827,7 +816,6 @@
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(state);
 		return err;
 	}
 
@@ -889,7 +877,6 @@
 	msp_reset(client);
 
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c
index 8edb3d8..846b15f 100644
--- a/drivers/media/i2c/mt9m032.c
+++ b/drivers/media/i2c/mt9m032.c
@@ -554,10 +554,8 @@
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
 	int val;
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
 
 	val = mt9m032_read(client, reg->reg);
 	if (val < 0)
@@ -575,12 +573,9 @@
 	struct mt9m032 *sensor = to_mt9m032(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	return mt9m032_write(client, reg->reg, reg->val);
 }
 #endif
@@ -730,7 +725,7 @@
 	if (!client->dev.platform_data)
 		return -ENODEV;
 
-	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
+	sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
 	if (sensor == NULL)
 		return -ENOMEM;
 
@@ -860,7 +855,6 @@
 	v4l2_ctrl_handler_free(&sensor->ctrls);
 error_sensor:
 	mutex_destroy(&sensor->lock);
-	kfree(sensor);
 	return ret;
 }
 
@@ -873,7 +867,6 @@
 	v4l2_ctrl_handler_free(&sensor->ctrls);
 	media_entity_cleanup(&subdev->entity);
 	mutex_destroy(&sensor->lock);
-	kfree(sensor);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 28cf95b..4734836 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -16,18 +16,19 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/gpio.h>
-#include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
 #include <linux/pm.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 
 #include <media/mt9p031.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-of.h>
 #include <media/v4l2-subdev.h>
 
 #include "aptina-pll.h"
@@ -124,9 +125,7 @@
 	int power_count;
 
 	struct clk *clk;
-	struct regulator *vaa;
-	struct regulator *vdd;
-	struct regulator *vdd_io;
+	struct regulator_bulk_data regulators[3];
 
 	enum mt9p031_model model;
 	struct aptina_pll pll;
@@ -271,23 +270,26 @@
 
 static int mt9p031_power_on(struct mt9p031 *mt9p031)
 {
+	int ret;
+
 	/* Ensure RESET_BAR is low */
-	if (mt9p031->reset != -1) {
+	if (gpio_is_valid(mt9p031->reset)) {
 		gpio_set_value(mt9p031->reset, 0);
 		usleep_range(1000, 2000);
 	}
 
 	/* Bring up the supplies */
-	regulator_enable(mt9p031->vdd);
-	regulator_enable(mt9p031->vdd_io);
-	regulator_enable(mt9p031->vaa);
+	ret = regulator_bulk_enable(ARRAY_SIZE(mt9p031->regulators),
+				   mt9p031->regulators);
+	if (ret < 0)
+		return ret;
 
 	/* Emable clock */
 	if (mt9p031->clk)
 		clk_prepare_enable(mt9p031->clk);
 
 	/* Now RESET_BAR must be high */
-	if (mt9p031->reset != -1) {
+	if (gpio_is_valid(mt9p031->reset)) {
 		gpio_set_value(mt9p031->reset, 1);
 		usleep_range(1000, 2000);
 	}
@@ -297,14 +299,13 @@
 
 static void mt9p031_power_off(struct mt9p031 *mt9p031)
 {
-	if (mt9p031->reset != -1) {
+	if (gpio_is_valid(mt9p031->reset)) {
 		gpio_set_value(mt9p031->reset, 0);
 		usleep_range(1000, 2000);
 	}
 
-	regulator_disable(mt9p031->vaa);
-	regulator_disable(mt9p031->vdd_io);
-	regulator_disable(mt9p031->vdd);
+	regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
+			       mt9p031->regulators);
 
 	if (mt9p031->clk)
 		clk_disable_unprepare(mt9p031->clk);
@@ -849,18 +850,18 @@
 
 	/* Read out the chip version register */
 	data = mt9p031_read(client, MT9P031_CHIP_VERSION);
+	mt9p031_power_off(mt9p031);
+
 	if (data != MT9P031_CHIP_VERSION_VALUE) {
 		dev_err(&client->dev, "MT9P031 not detected, wrong version "
 			"0x%04x\n", data);
 		return -ENODEV;
 	}
 
-	mt9p031_power_off(mt9p031);
-
 	dev_info(&client->dev, "MT9P031 detected at address 0x%02x\n",
 		 client->addr);
 
-	return ret;
+	return 0;
 }
 
 static int mt9p031_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
@@ -928,10 +929,36 @@
  * Driver initialization and probing
  */
 
+static struct mt9p031_platform_data *
+mt9p031_get_pdata(struct i2c_client *client)
+{
+	struct mt9p031_platform_data *pdata;
+	struct device_node *np;
+
+	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
+		return client->dev.platform_data;
+
+	np = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	if (!np)
+		return NULL;
+
+	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		goto done;
+
+	pdata->reset = of_get_named_gpio(client->dev.of_node, "reset-gpios", 0);
+	of_property_read_u32(np, "input-clock-frequency", &pdata->ext_freq);
+	of_property_read_u32(np, "pixel-clock-frequency", &pdata->target_freq);
+
+done:
+	of_node_put(np);
+	return pdata;
+}
+
 static int mt9p031_probe(struct i2c_client *client,
 			 const struct i2c_device_id *did)
 {
-	struct mt9p031_platform_data *pdata = client->dev.platform_data;
+	struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client);
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
 	struct mt9p031 *mt9p031;
 	unsigned int i;
@@ -958,14 +985,14 @@
 	mt9p031->model = did->driver_data;
 	mt9p031->reset = -1;
 
-	mt9p031->vaa = devm_regulator_get(&client->dev, "vaa");
-	mt9p031->vdd = devm_regulator_get(&client->dev, "vdd");
-	mt9p031->vdd_io = devm_regulator_get(&client->dev, "vdd_io");
+	mt9p031->regulators[0].supply = "vdd";
+	mt9p031->regulators[1].supply = "vdd_io";
+	mt9p031->regulators[2].supply = "vaa";
 
-	if (IS_ERR(mt9p031->vaa) || IS_ERR(mt9p031->vdd) ||
-	    IS_ERR(mt9p031->vdd_io)) {
+	ret = devm_regulator_bulk_get(&client->dev, 3, mt9p031->regulators);
+	if (ret < 0) {
 		dev_err(&client->dev, "Unable to get regulators\n");
-		return -ENODEV;
+		return ret;
 	}
 
 	v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6);
@@ -1031,7 +1058,7 @@
 	mt9p031->format.field = V4L2_FIELD_NONE;
 	mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
 
-	if (pdata->reset != -1) {
+	if (gpio_is_valid(pdata->reset)) {
 		ret = devm_gpio_request_one(&client->dev, pdata->reset,
 					    GPIOF_OUT_INIT_LOW, "mt9p031_rst");
 		if (ret < 0)
@@ -1070,8 +1097,18 @@
 };
 MODULE_DEVICE_TABLE(i2c, mt9p031_id);
 
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id mt9p031_of_match[] = {
+	{ .compatible = "aptina,mt9p031", },
+	{ .compatible = "aptina,mt9p031m", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt9p031_of_match);
+#endif
+
 static struct i2c_driver mt9p031_i2c_driver = {
 	.driver = {
+		.of_match_table = of_match_ptr(mt9p031_of_match),
 		.name = "mt9p031",
 	},
 	.probe          = mt9p031_probe,
diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c
index 2e189d8..7964634 100644
--- a/drivers/media/i2c/mt9t001.c
+++ b/drivers/media/i2c/mt9t001.c
@@ -740,7 +740,7 @@
 	if (ret < 0)
 		return ret;
 
-	mt9t001 = kzalloc(sizeof(*mt9t001), GFP_KERNEL);
+	mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL);
 	if (!mt9t001)
 		return -ENOMEM;
 
@@ -801,7 +801,6 @@
 	if (ret < 0) {
 		v4l2_ctrl_handler_free(&mt9t001->ctrls);
 		media_entity_cleanup(&mt9t001->subdev.entity);
-		kfree(mt9t001);
 	}
 
 	return ret;
@@ -815,7 +814,6 @@
 	v4l2_ctrl_handler_free(&mt9t001->ctrls);
 	v4l2_device_unregister_subdev(subdev);
 	media_entity_cleanup(&subdev->entity);
-	kfree(mt9t001);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
index 3f415fd..f74698c 100644
--- a/drivers/media/i2c/mt9v011.c
+++ b/drivers/media/i2c/mt9v011.c
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <asm/div64.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/mt9v011.h>
 
@@ -407,13 +406,6 @@
 static int mt9v011_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	reg->val = mt9v011_read(sd, reg->reg & 0xff);
 	reg->size = 2;
 
@@ -423,31 +415,12 @@
 static int mt9v011_s_register(struct v4l2_subdev *sd,
 			      const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	mt9v011_write(sd, reg->reg & 0xff, reg->val & 0xffff);
 
 	return 0;
 }
 #endif
 
-static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	u16 version;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_MT9V011,
-					  version);
-}
-
 static int mt9v011_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct mt9v011 *core =
@@ -489,7 +462,6 @@
 
 static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
 	.reset = mt9v011_reset,
-	.g_chip_ident = mt9v011_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = mt9v011_g_register,
 	.s_register = mt9v011_s_register,
@@ -526,7 +498,7 @@
 	     I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
 		return -EIO;
 
-	core = kzalloc(sizeof(struct mt9v011), GFP_KERNEL);
+	core = devm_kzalloc(&c->dev, sizeof(struct mt9v011), GFP_KERNEL);
 	if (!core)
 		return -ENOMEM;
 
@@ -539,7 +511,6 @@
 	    (version != MT9V011_REV_B_VERSION)) {
 		v4l2_info(sd, "*** unknown micron chip detected (0x%04x).\n",
 			  version);
-		kfree(core);
 		return -EINVAL;
 	}
 
@@ -562,7 +533,6 @@
 
 		v4l2_err(sd, "control initialization error %d\n", ret);
 		v4l2_ctrl_handler_free(&core->ctrls);
-		kfree(core);
 		return ret;
 	}
 	core->sd.ctrl_handler = &core->ctrls;
@@ -598,7 +568,7 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&core->ctrls);
-	kfree(to_mt9v011(sd));
+
 	return 0;
 }
 
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 3f356cb..60c6f67 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -744,7 +744,7 @@
 		return -EIO;
 	}
 
-	mt9v032 = kzalloc(sizeof(*mt9v032), GFP_KERNEL);
+	mt9v032 = devm_kzalloc(&client->dev, sizeof(*mt9v032), GFP_KERNEL);
 	if (!mt9v032)
 		return -ENOMEM;
 
@@ -830,8 +830,9 @@
 
 	mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
+
 	if (ret < 0)
-		kfree(mt9v032);
+		v4l2_ctrl_handler_free(&mt9v032->ctrls);
 
 	return ret;
 }
@@ -841,9 +842,10 @@
 	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
 	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
 
+	v4l2_ctrl_handler_free(&mt9v032->ctrls);
 	v4l2_device_unregister_subdev(subdev);
 	media_entity_cleanup(&subdev->entity);
-	kfree(mt9v032);
+
 	return 0;
 }
 
diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
index 8554b47..271d0b7 100644
--- a/drivers/media/i2c/noon010pc30.c
+++ b/drivers/media/i2c/noon010pc30.c
@@ -19,7 +19,6 @@
 #include <linux/slab.h>
 #include <linux/regulator/consumer.h>
 #include <media/noon010pc30.h>
-#include <media/v4l2-chip-ident.h>
 #include <linux/videodev2.h>
 #include <linux/module.h>
 #include <media/v4l2-ctrls.h>
@@ -712,7 +711,7 @@
 		return -EIO;
 	}
 
-	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -746,57 +745,50 @@
 	info->curr_win		= &noon010_sizes[0];
 
 	if (gpio_is_valid(pdata->gpio_nreset)) {
-		ret = gpio_request(pdata->gpio_nreset, "NOON010PC30 NRST");
+		ret = devm_gpio_request_one(&client->dev, pdata->gpio_nreset,
+					    GPIOF_OUT_INIT_LOW,
+					    "NOON010PC30 NRST");
 		if (ret) {
 			dev_err(&client->dev, "GPIO request error: %d\n", ret);
 			goto np_err;
 		}
 		info->gpio_nreset = pdata->gpio_nreset;
-		gpio_direction_output(info->gpio_nreset, 0);
 		gpio_export(info->gpio_nreset, 0);
 	}
 
 	if (gpio_is_valid(pdata->gpio_nstby)) {
-		ret = gpio_request(pdata->gpio_nstby, "NOON010PC30 NSTBY");
+		ret = devm_gpio_request_one(&client->dev, pdata->gpio_nstby,
+					    GPIOF_OUT_INIT_LOW,
+					    "NOON010PC30 NSTBY");
 		if (ret) {
 			dev_err(&client->dev, "GPIO request error: %d\n", ret);
-			goto np_gpio_err;
+			goto np_err;
 		}
 		info->gpio_nstby = pdata->gpio_nstby;
-		gpio_direction_output(info->gpio_nstby, 0);
 		gpio_export(info->gpio_nstby, 0);
 	}
 
 	for (i = 0; i < NOON010_NUM_SUPPLIES; i++)
 		info->supply[i].supply = noon010_supply_name[i];
 
-	ret = regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
+	ret = devm_regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
 				 info->supply);
 	if (ret)
-		goto np_reg_err;
+		goto np_err;
 
 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
 	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
 	if (ret < 0)
-		goto np_me_err;
+		goto np_err;
 
 	ret = noon010_detect(client, info);
 	if (!ret)
 		return 0;
 
-np_me_err:
-	regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
-np_reg_err:
-	if (gpio_is_valid(info->gpio_nstby))
-		gpio_free(info->gpio_nstby);
-np_gpio_err:
-	if (gpio_is_valid(info->gpio_nreset))
-		gpio_free(info->gpio_nreset);
 np_err:
 	v4l2_ctrl_handler_free(&info->hdl);
 	v4l2_device_unregister_subdev(sd);
-	kfree(info);
 	return ret;
 }
 
@@ -807,17 +799,8 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&info->hdl);
-
-	regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
-
-	if (gpio_is_valid(info->gpio_nreset))
-		gpio_free(info->gpio_nreset);
-
-	if (gpio_is_valid(info->gpio_nstby))
-		gpio_free(info->gpio_nstby);
-
 	media_entity_cleanup(&sd->entity);
-	kfree(info);
+
 	return 0;
 }
 
diff --git a/drivers/media/i2c/ov7640.c b/drivers/media/i2c/ov7640.c
index b0cc927..faa64ba 100644
--- a/drivers/media/i2c/ov7640.c
+++ b/drivers/media/i2c/ov7640.c
@@ -20,7 +20,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <linux/slab.h>
 
 MODULE_DESCRIPTION("OmniVision ov7640 sensor driver");
@@ -59,7 +58,7 @@
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
 	if (sd == NULL)
 		return -ENOMEM;
 	v4l2_i2c_subdev_init(sd, client, &ov7640_ops);
@@ -71,7 +70,6 @@
 
 	if (write_regs(client, initial_registers) < 0) {
 		v4l_err(client, "error initializing OV7640\n");
-		kfree(sd);
 		return -ENODEV;
 	}
 
@@ -84,7 +82,7 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(sd);
+
 	return 0;
 }
 
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index 617ad3f..e8a1ce2 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-mediabus.h>
 #include <media/ov7670.h>
@@ -1462,25 +1461,12 @@
 	.g_volatile_ctrl = ov7670_g_volatile_ctrl,
 };
 
-static int ov7670_g_chip_ident(struct v4l2_subdev *sd,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0);
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	unsigned char val = 0;
 	int ret;
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	ret = ov7670_read(sd, reg->reg & 0xff, &val);
 	reg->val = val;
 	reg->size = 1;
@@ -1489,12 +1475,6 @@
 
 static int ov7670_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	ov7670_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
@@ -1503,7 +1483,6 @@
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops ov7670_core_ops = {
-	.g_chip_ident = ov7670_g_chip_ident,
 	.reset = ov7670_reset,
 	.init = ov7670_init,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1552,7 +1531,7 @@
 	struct ov7670_info *info;
 	int ret;
 
-	info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL);
+	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
 	if (info == NULL)
 		return -ENOMEM;
 	sd = &info->sd;
@@ -1590,7 +1569,6 @@
 		v4l_dbg(1, debug, client,
 			"chip found @ 0x%x (%s) is not an ov7670 chip.\n",
 			client->addr << 1, client->adapter->name);
-		kfree(info);
 		return ret;
 	}
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
@@ -1635,7 +1613,6 @@
 		int err = info->hdl.error;
 
 		v4l2_ctrl_handler_free(&info->hdl);
-		kfree(info);
 		return err;
 	}
 	/*
@@ -1659,7 +1636,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&info->hdl);
-	kfree(info);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 9eac531..825ea86 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1385,9 +1385,12 @@
 	}
 	return 0;
 err:
-	for (++i; i < S5C73M3_MAX_SUPPLIES; i++)
-		regulator_enable(state->supplies[i].consumer);
-
+	for (++i; i < S5C73M3_MAX_SUPPLIES; i++) {
+		int r = regulator_enable(state->supplies[i].consumer);
+		if (r < 0)
+			v4l2_err(&state->oif_sd, "Failed to reenable %s: %d\n",
+				 state->supplies[i].supply, r);
+	}
 	return ret;
 }
 
@@ -1511,59 +1514,40 @@
 	.video	= &s5c73m3_oif_video_ops,
 };
 
-static int s5c73m3_configure_gpio(int nr, int val, const char *name)
-{
-	unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-	int ret;
-
-	if (!gpio_is_valid(nr))
-		return 0;
-	ret = gpio_request_one(nr, flags, name);
-	if (!ret)
-		gpio_export(nr, 0);
-	return ret;
-}
-
-static int s5c73m3_free_gpios(struct s5c73m3 *state)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(state->gpio); i++) {
-		if (!gpio_is_valid(state->gpio[i].gpio))
-			continue;
-		gpio_free(state->gpio[i].gpio);
-		state->gpio[i].gpio = -EINVAL;
-	}
-	return 0;
-}
-
 static int s5c73m3_configure_gpios(struct s5c73m3 *state,
 				   const struct s5c73m3_platform_data *pdata)
 {
-	const struct s5c73m3_gpio *gpio = &pdata->gpio_stby;
+	struct device *dev = &state->i2c_client->dev;
+	const struct s5c73m3_gpio *gpio;
+	unsigned long flags;
 	int ret;
 
 	state->gpio[STBY].gpio = -EINVAL;
 	state->gpio[RST].gpio  = -EINVAL;
 
-	ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_STBY");
-	if (ret) {
-		s5c73m3_free_gpios(state);
-		return ret;
+	gpio = &pdata->gpio_stby;
+	if (gpio_is_valid(gpio->gpio)) {
+		flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+		      | GPIOF_EXPORT;
+		ret = devm_gpio_request_one(dev, gpio->gpio, flags,
+					    "S5C73M3_STBY");
+		if (ret < 0)
+			return ret;
+
+		state->gpio[STBY] = *gpio;
 	}
-	state->gpio[STBY] = *gpio;
-	if (gpio_is_valid(gpio->gpio))
-		gpio_set_value(gpio->gpio, 0);
 
 	gpio = &pdata->gpio_reset;
-	ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_RST");
-	if (ret) {
-		s5c73m3_free_gpios(state);
-		return ret;
+	if (gpio_is_valid(gpio->gpio)) {
+		flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+		      | GPIOF_EXPORT;
+		ret = devm_gpio_request_one(dev, gpio->gpio, flags,
+					    "S5C73M3_RST");
+		if (ret < 0)
+			return ret;
+
+		state->gpio[RST] = *gpio;
 	}
-	state->gpio[RST] = *gpio;
-	if (gpio_is_valid(gpio->gpio))
-		gpio_set_value(gpio->gpio, 0);
 
 	return 0;
 }
@@ -1626,10 +1610,11 @@
 
 	state->mclk_frequency = pdata->mclk_frequency;
 	state->bus_type = pdata->bus_type;
+	state->i2c_client = client;
 
 	ret = s5c73m3_configure_gpios(state, pdata);
 	if (ret)
-		goto out_err1;
+		goto out_err;
 
 	for (i = 0; i < S5C73M3_MAX_SUPPLIES; i++)
 		state->supplies[i].supply = s5c73m3_supply_names[i];
@@ -1638,12 +1623,12 @@
 			       state->supplies);
 	if (ret) {
 		dev_err(dev, "failed to get regulators\n");
-		goto out_err2;
+		goto out_err;
 	}
 
 	ret = s5c73m3_init_controls(state);
 	if (ret)
-		goto out_err2;
+		goto out_err;
 
 	state->sensor_pix_size[RES_ISP] = &s5c73m3_isp_resolutions[1];
 	state->sensor_pix_size[RES_JPEG] = &s5c73m3_jpeg_resolutions[1];
@@ -1659,16 +1644,12 @@
 
 	ret = s5c73m3_register_spi_driver(state);
 	if (ret < 0)
-		goto out_err2;
-
-	state->i2c_client = client;
+		goto out_err;
 
 	v4l2_info(sd, "%s: completed succesfully\n", __func__);
 	return 0;
 
-out_err2:
-	s5c73m3_free_gpios(state);
-out_err1:
+out_err:
 	media_entity_cleanup(&sd->entity);
 	return ret;
 }
@@ -1688,7 +1669,6 @@
 	media_entity_cleanup(&sensor_sd->entity);
 
 	s5c73m3_unregister_spi_driver(state);
-	s5c73m3_free_gpios(state);
 
 	return 0;
 }
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
index 6f3a9c0..8079e26 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-spi.c
@@ -73,7 +73,7 @@
 
 	memset(padding, 0, sizeof(padding));
 
-	for (i = 0; i < count ; i++) {
+	for (i = 0; i < count; i++) {
 		r = spi_xmit(spi_dev, (void *)addr + j, tx_size, SPI_DIR_TX);
 		if (r < 0)
 			return r;
@@ -98,7 +98,7 @@
 	unsigned int i, j = 0;
 	int r = 0;
 
-	for (i = 0; i < count ; i++) {
+	for (i = 0; i < count; i++) {
 		r = spi_xmit(spi_dev, addr + j, tx_size, SPI_DIR_RX);
 		if (r < 0)
 			return r;
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c
index bdf5e3d..789c02a 100644
--- a/drivers/media/i2c/s5k6aa.c
+++ b/drivers/media/i2c/s5k6aa.c
@@ -1491,58 +1491,41 @@
 /*
  * GPIO setup
  */
-static int s5k6aa_configure_gpio(int nr, int val, const char *name)
-{
-	unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-	int ret;
-
-	if (!gpio_is_valid(nr))
-		return 0;
-	ret = gpio_request_one(nr, flags, name);
-	if (!ret)
-		gpio_export(nr, 0);
-	return ret;
-}
-
-static void s5k6aa_free_gpios(struct s5k6aa *s5k6aa)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(s5k6aa->gpio); i++) {
-		if (!gpio_is_valid(s5k6aa->gpio[i].gpio))
-			continue;
-		gpio_free(s5k6aa->gpio[i].gpio);
-		s5k6aa->gpio[i].gpio = -EINVAL;
-	}
-}
 
 static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa,
 				  const struct s5k6aa_platform_data *pdata)
 {
-	const struct s5k6aa_gpio *gpio = &pdata->gpio_stby;
+	struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
+	const struct s5k6aa_gpio *gpio;
+	unsigned long flags;
 	int ret;
 
 	s5k6aa->gpio[STBY].gpio = -EINVAL;
 	s5k6aa->gpio[RST].gpio  = -EINVAL;
 
-	ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_STBY");
-	if (ret) {
-		s5k6aa_free_gpios(s5k6aa);
-		return ret;
+	gpio = &pdata->gpio_stby;
+	if (gpio_is_valid(gpio->gpio)) {
+		flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+		      | GPIOF_EXPORT;
+		ret = devm_gpio_request_one(&client->dev, gpio->gpio, flags,
+					    "S5K6AA_STBY");
+		if (ret < 0)
+			return ret;
+
+		s5k6aa->gpio[STBY] = *gpio;
 	}
-	s5k6aa->gpio[STBY] = *gpio;
-	if (gpio_is_valid(gpio->gpio))
-		gpio_set_value(gpio->gpio, 0);
 
 	gpio = &pdata->gpio_reset;
-	ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_RST");
-	if (ret) {
-		s5k6aa_free_gpios(s5k6aa);
-		return ret;
+	if (gpio_is_valid(gpio->gpio)) {
+		flags = (gpio->level ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW)
+		      | GPIOF_EXPORT;
+		ret = devm_gpio_request_one(&client->dev, gpio->gpio, flags,
+					    "S5K6AA_RST");
+		if (ret < 0)
+			return ret;
+
+		s5k6aa->gpio[RST] = *gpio;
 	}
-	s5k6aa->gpio[RST] = *gpio;
-	if (gpio_is_valid(gpio->gpio))
-		gpio_set_value(gpio->gpio, 0);
 
 	return 0;
 }
@@ -1593,7 +1576,7 @@
 
 	ret = s5k6aa_configure_gpios(s5k6aa, pdata);
 	if (ret)
-		goto out_err2;
+		goto out_err;
 
 	for (i = 0; i < S5K6AA_NUM_SUPPLIES; i++)
 		s5k6aa->supplies[i].supply = s5k6aa_supply_names[i];
@@ -1602,12 +1585,12 @@
 				 s5k6aa->supplies);
 	if (ret) {
 		dev_err(&client->dev, "Failed to get regulators\n");
-		goto out_err3;
+		goto out_err;
 	}
 
 	ret = s5k6aa_initialize_ctrls(s5k6aa);
 	if (ret)
-		goto out_err3;
+		goto out_err;
 
 	s5k6aa_presets_data_init(s5k6aa);
 
@@ -1618,9 +1601,7 @@
 
 	return 0;
 
-out_err3:
-	s5k6aa_free_gpios(s5k6aa);
-out_err2:
+out_err:
 	media_entity_cleanup(&s5k6aa->sd.entity);
 	return ret;
 }
@@ -1628,12 +1609,10 @@
 static int s5k6aa_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct s5k6aa *s5k6aa = to_s5k6aa(sd);
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
 	media_entity_cleanup(&sd->entity);
-	s5k6aa_free_gpios(s5k6aa);
 
 	return 0;
 }
diff --git a/drivers/media/i2c/saa6588.c b/drivers/media/i2c/saa6588.c
index b4e1ccb..70bc72e 100644
--- a/drivers/media/i2c/saa6588.c
+++ b/drivers/media/i2c/saa6588.c
@@ -33,7 +33,6 @@
 
 #include <media/saa6588.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 
 /* insmod options */
@@ -443,17 +442,9 @@
 	return 0;
 }
 
-static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA6588, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops saa6588_core_ops = {
-	.g_chip_ident = saa6588_g_chip_ident,
 	.ioctl = saa6588_ioctl,
 };
 
@@ -478,17 +469,15 @@
 	v4l_info(client, "saa6588 found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	s = kzalloc(sizeof(*s), GFP_KERNEL);
+	s = devm_kzalloc(&client->dev, sizeof(*s), GFP_KERNEL);
 	if (s == NULL)
 		return -ENOMEM;
 
 	s->buf_size = bufblocks * 3;
 
-	s->buffer = kmalloc(s->buf_size, GFP_KERNEL);
-	if (s->buffer == NULL) {
-		kfree(s);
+	s->buffer = devm_kzalloc(&client->dev, s->buf_size, GFP_KERNEL);
+	if (s->buffer == NULL)
 		return -ENOMEM;
-	}
 	sd = &s->sd;
 	v4l2_i2c_subdev_init(sd, client, &saa6588_ops);
 	spin_lock_init(&s->lock);
@@ -516,8 +505,6 @@
 
 	cancel_delayed_work_sync(&s->work);
 
-	kfree(s->buffer);
-	kfree(s);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/saa7110.c b/drivers/media/i2c/saa7110.c
index 51cd4c8..ac43e92 100644
--- a/drivers/media/i2c/saa7110.c
+++ b/drivers/media/i2c/saa7110.c
@@ -35,7 +35,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
@@ -203,7 +202,7 @@
 	status = saa7110_read(sd);
 	if (status & 0x40) {
 		v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status);
-		return decoder->norm;	/* no change*/
+		return V4L2_STD_UNKNOWN;
 	}
 	if ((status & 3) == 0) {
 		saa7110_write(sd, 0x06, 0x83);
@@ -265,7 +264,7 @@
 
 static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
 {
-	*(v4l2_std_id *)std = determine_norm(sd);
+	*std &= determine_norm(sd);
 	return 0;
 }
 
@@ -352,13 +351,6 @@
 	return 0;
 }
 
-static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7110, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
@@ -366,7 +358,6 @@
 };
 
 static const struct v4l2_subdev_core_ops saa7110_core_ops = {
-	.g_chip_ident = saa7110_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -406,7 +397,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (!decoder)
 		return -ENOMEM;
 	sd = &decoder->sd;
@@ -428,7 +419,6 @@
 		int err = decoder->hdl.error;
 
 		v4l2_ctrl_handler_free(&decoder->hdl);
-		kfree(decoder);
 		return err;
 	}
 	v4l2_ctrl_handler_setup(&decoder->hdl);
@@ -469,7 +459,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&decoder->hdl);
-	kfree(decoder);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
index 52c717d..7fd766e 100644
--- a/drivers/media/i2c/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -46,7 +46,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/saa7115.h>
 #include <asm/div64.h>
 
@@ -63,6 +62,16 @@
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 
+enum saa711x_model {
+	SAA7111A,
+	SAA7111,
+	SAA7113,
+	GM7113C,
+	SAA7114,
+	SAA7115,
+	SAA7118,
+};
+
 struct saa711x_state {
 	struct v4l2_subdev sd;
 	struct v4l2_ctrl_handler hdl;
@@ -80,7 +89,7 @@
 	int radio;
 	int width;
 	int height;
-	u32 ident;
+	enum saa711x_model ident;
 	u32 audclk_freq;
 	u32 crystal_freq;
 	bool ucgc;
@@ -111,10 +120,10 @@
 /* Sanity routine to check if a register is present */
 static int saa711x_has_reg(const int id, const u8 reg)
 {
-	if (id == V4L2_IDENT_SAA7111)
+	if (id == SAA7111)
 		return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
 		       (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
-	if (id == V4L2_IDENT_SAA7111A)
+	if (id == SAA7111A)
 		return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
 		       reg != 0x14 && reg != 0x18 && reg != 0x19 &&
 		       reg != 0x1d && reg != 0x1e;
@@ -127,16 +136,18 @@
 		return 0;
 
 	switch (id) {
-	case V4L2_IDENT_SAA7113:
+	case GM7113C:
+		return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && reg < 0x20;
+	case SAA7113:
 		return reg != 0x14 && (reg < 0x18 || reg > 0x1e) && (reg < 0x20 || reg > 0x3f) &&
 		       reg != 0x5d && reg < 0x63;
-	case V4L2_IDENT_SAA7114:
+	case SAA7114:
 		return (reg < 0x1a || reg > 0x1e) && (reg < 0x20 || reg > 0x2f) &&
 		       (reg < 0x63 || reg > 0x7f) && reg != 0x33 && reg != 0x37 &&
 		       reg != 0x81 && reg < 0xf0;
-	case V4L2_IDENT_SAA7115:
+	case SAA7115:
 		return (reg < 0x20 || reg > 0x2f) && reg != 0x65 && (reg < 0xfc || reg > 0xfe);
-	case V4L2_IDENT_SAA7118:
+	case SAA7118:
 		return (reg < 0x1a || reg > 0x1d) && (reg < 0x20 || reg > 0x22) &&
 		       (reg < 0x26 || reg > 0x28) && reg != 0x33 && reg != 0x37 &&
 		       (reg < 0x63 || reg > 0x7f) && reg != 0x81 && reg < 0xf0;
@@ -214,7 +225,10 @@
 	0x00, 0x00
 };
 
-/* SAA7113 init codes */
+/* SAA7113/GM7113C init codes
+ * It's important that R_14... R_17 == 0x00
+ * for the gm7113c chip to deliver stable video
+ */
 static const unsigned char saa7113_init[] = {
 	R_01_INC_DELAY, 0x08,
 	R_02_INPUT_CNTL_1, 0xc2,
@@ -448,6 +462,24 @@
 
 /* ============== SAA7715 VIDEO templates (end) =======  */
 
+/* ============== GM7113C VIDEO templates =============  */
+static const unsigned char gm7113c_cfg_60hz_video[] = {
+	R_08_SYNC_CNTL, 0x68,			/* 0xBO: auto detection, 0x68 = NTSC */
+	R_0E_CHROMA_CNTL_1, 0x07,		/* video autodetection is on */
+
+	0x00, 0x00
+};
+
+static const unsigned char gm7113c_cfg_50hz_video[] = {
+	R_08_SYNC_CNTL, 0x28,			/* 0x28 = PAL */
+	R_0E_CHROMA_CNTL_1, 0x07,
+
+	0x00, 0x00
+};
+
+/* ============== GM7113C VIDEO templates (end) =======  */
+
+
 static const unsigned char saa7115_cfg_vbi_on[] = {
 	R_80_GLOBAL_CNTL_1, 0x00,			/* reset tasks */
 	R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0,		/* reset scaler */
@@ -932,11 +964,17 @@
 	// This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
 	if (std & V4L2_STD_525_60) {
 		v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
-		saa711x_writeregs(sd, saa7115_cfg_60hz_video);
+		if (state->ident == GM7113C)
+			saa711x_writeregs(sd, gm7113c_cfg_60hz_video);
+		else
+			saa711x_writeregs(sd, saa7115_cfg_60hz_video);
 		saa711x_set_size(sd, 720, 480);
 	} else {
 		v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
-		saa711x_writeregs(sd, saa7115_cfg_50hz_video);
+		if (state->ident == GM7113C)
+			saa711x_writeregs(sd, gm7113c_cfg_50hz_video);
+		else
+			saa711x_writeregs(sd, saa7115_cfg_50hz_video);
 		saa711x_set_size(sd, 720, 576);
 	}
 
@@ -949,7 +987,8 @@
 	011 NTSC N (3.58MHz)            PAL M (3.58MHz)
 	100 reserved                    NTSC-Japan (3.58MHz)
 	*/
-	if (state->ident <= V4L2_IDENT_SAA7113) {
+	if (state->ident <= SAA7113 ||
+	    state->ident == GM7113C) {
 		u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
 
 		if (std == V4L2_STD_PAL_M) {
@@ -968,9 +1007,8 @@
 		/* restart task B if needed */
 		int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
 
-		if (taskb && state->ident == V4L2_IDENT_SAA7114) {
+		if (taskb && state->ident == SAA7114)
 			saa711x_writeregs(sd, saa7115_cfg_vbi_on);
-		}
 
 		/* switch audio mode too! */
 		saa711x_s_clock_freq(sd, state->audclk_freq);
@@ -992,7 +1030,7 @@
 
 #else
 	/* SAA7113 and SAA7118 also should support VBI - Need testing */
-	if (state->ident != V4L2_IDENT_SAA7115)
+	if (state->ident != SAA7115)
 		return;
 #endif
 
@@ -1214,13 +1252,14 @@
 			     u32 input, u32 output, u32 config)
 {
 	struct saa711x_state *state = to_state(sd);
-	u8 mask = (state->ident <= V4L2_IDENT_SAA7111A) ? 0xf8 : 0xf0;
+	u8 mask = (state->ident <= SAA7111A) ? 0xf8 : 0xf0;
 
 	v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
 		input, output);
 
 	/* saa7111/3 does not have these inputs */
-	if (state->ident <= V4L2_IDENT_SAA7113 &&
+	if ((state->ident <= SAA7113 ||
+	     state->ident == GM7113C) &&
 	    (input == SAA7115_COMPOSITE4 ||
 	     input == SAA7115_COMPOSITE5)) {
 		return -EINVAL;
@@ -1235,7 +1274,7 @@
 	state->input = input;
 
 	/* saa7111 has slightly different input numbering */
-	if (state->ident <= V4L2_IDENT_SAA7111A) {
+	if (state->ident <= SAA7111A) {
 		if (input >= SAA7115_COMPOSITE4)
 			input -= 2;
 		/* saa7111 specific */
@@ -1258,13 +1297,13 @@
 			(state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
 
 	state->output = output;
-	if (state->ident == V4L2_IDENT_SAA7114 ||
-			state->ident == V4L2_IDENT_SAA7115) {
+	if (state->ident == SAA7114 ||
+			state->ident == SAA7115) {
 		saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
 				(saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
 				(state->output & 0x01));
 	}
-	if (state->ident > V4L2_IDENT_SAA7111A) {
+	if (state->ident > SAA7111A) {
 		if (config & SAA7115_IDQ_IS_DEFAULT)
 			saa711x_write(sd, R_85_I_PORT_SIGNAL_POLAR, 0x20);
 		else
@@ -1277,7 +1316,7 @@
 {
 	struct saa711x_state *state = to_state(sd);
 
-	if (state->ident > V4L2_IDENT_SAA7111A)
+	if (state->ident > SAA7111A)
 		return -EINVAL;
 	saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
 		(val ? 0x80 : 0));
@@ -1367,7 +1406,7 @@
 
 	reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
 
-	if (state->ident == V4L2_IDENT_SAA7115) {
+	if (state->ident == SAA7115) {
 		reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
 
 		v4l2_dbg(1, debug, sd, "Status byte 1 (0x1e)=0x%02x\n", reg1e);
@@ -1389,6 +1428,7 @@
 			*std &= V4L2_STD_SECAM;
 			break;
 		default:
+			*std = V4L2_STD_UNKNOWN;
 			/* Can't detect anything */
 			break;
 		}
@@ -1397,8 +1437,10 @@
 	v4l2_dbg(1, debug, sd, "Status byte 2 (0x1f)=0x%02x\n", reg1f);
 
 	/* horizontal/vertical not locked */
-	if (reg1f & 0x40)
+	if (reg1f & 0x40) {
+		*std = V4L2_STD_UNKNOWN;
 		goto ret;
+	}
 
 	if (reg1f & 0x20)
 		*std &= V4L2_STD_525_60;
@@ -1418,7 +1460,7 @@
 	int reg1f;
 
 	*status = V4L2_IN_ST_NO_SIGNAL;
-	if (state->ident == V4L2_IDENT_SAA7115)
+	if (state->ident == SAA7115)
 		reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
 	reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
 	if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
@@ -1429,12 +1471,6 @@
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = saa711x_read(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -1442,25 +1478,11 @@
 
 static int saa711x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
 #endif
 
-static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct saa711x_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
-}
-
 static int saa711x_log_status(struct v4l2_subdev *sd)
 {
 	struct saa711x_state *state = to_state(sd);
@@ -1469,7 +1491,7 @@
 	int vcr;
 
 	v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
-	if (state->ident != V4L2_IDENT_SAA7115) {
+	if (state->ident != SAA7115) {
 		/* status for the saa7114 */
 		reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
 		signalOk = (reg1f & 0xc1) == 0x81;
@@ -1520,7 +1542,6 @@
 
 static const struct v4l2_subdev_core_ops saa711x_core_ops = {
 	.log_status = saa711x_log_status,
-	.g_chip_ident = saa711x_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -1571,55 +1592,145 @@
 	.vbi = &saa711x_vbi_ops,
 };
 
+#define CHIP_VER_SIZE	16
+
 /* ----------------------------------------------------------------------- */
 
+/**
+ * saa711x_detect_chip - Detects the saa711x (or clone) variant
+ * @client:		I2C client structure.
+ * @id:			I2C device ID structure.
+ * @name:		Name of the device to be filled.
+ *
+ * Detects the Philips/NXP saa711x chip, or some clone of it.
+ * if 'id' is NULL or id->driver_data is equal to 1, it auto-probes
+ * the analog demod.
+ * If the tuner is not found, it returns -ENODEV.
+ * If auto-detection is disabled and the tuner doesn't match what it was
+ *	requred, it returns -EINVAL and fills 'name'.
+ * If the chip is found, it returns the chip ID and fills 'name'.
+ */
+static int saa711x_detect_chip(struct i2c_client *client,
+			       const struct i2c_device_id *id,
+			       char *name)
+{
+	char chip_ver[CHIP_VER_SIZE];
+	char chip_id;
+	int i;
+	int autodetect;
+
+	autodetect = !id || id->driver_data == 1;
+
+	/* Read the chip version register */
+	for (i = 0; i < CHIP_VER_SIZE; i++) {
+		i2c_smbus_write_byte_data(client, 0, i);
+		chip_ver[i] = i2c_smbus_read_byte_data(client, 0);
+		name[i] = (chip_ver[i] & 0x0f) + '0';
+		if (name[i] > '9')
+			name[i] += 'a' - '9' - 1;
+	}
+	name[i] = '\0';
+
+	/* Check if it is a Philips/NXP chip */
+	if (!memcmp(name + 1, "f711", 4)) {
+		chip_id = name[5];
+		snprintf(name, CHIP_VER_SIZE, "saa711%c", chip_id);
+
+		if (!autodetect && strcmp(name, id->name))
+			return -EINVAL;
+
+		switch (chip_id) {
+		case '1':
+			if (chip_ver[0] & 0xf0) {
+				snprintf(name, CHIP_VER_SIZE, "saa711%ca", chip_id);
+				v4l_info(client, "saa7111a variant found\n");
+				return SAA7111A;
+			}
+			return SAA7111;
+		case '3':
+			return SAA7113;
+		case '4':
+			return SAA7114;
+		case '5':
+			return SAA7115;
+		case '8':
+			return SAA7118;
+		default:
+			v4l2_info(client,
+				  "WARNING: Philips/NXP chip unknown - Falling back to saa7111\n");
+			return SAA7111;
+		}
+	}
+
+	/* Check if it is a gm7113c */
+	if (!memcmp(name, "0000", 4)) {
+		chip_id = 0;
+		for (i = 0; i < 4; i++) {
+			chip_id = chip_id << 1;
+			chip_id |= (chip_ver[i] & 0x80) ? 1 : 0;
+		}
+
+		/*
+		 * Note: From the datasheet, only versions 1 and 2
+		 * exists. However, tests on a device labeled as:
+		 * "GM7113C 1145" returned "10" on all 16 chip
+		 * version (reg 0x00) reads. So, we need to also
+		 * accept at least verion 0. For now, let's just
+		 * assume that a device that returns "0000" for
+		 * the lower nibble is a gm7113c.
+		 */
+
+		strlcpy(name, "gm7113c", CHIP_VER_SIZE);
+
+		if (!autodetect && strcmp(name, id->name))
+			return -EINVAL;
+
+		v4l_dbg(1, debug, client,
+			"It seems to be a %s chip (%*ph) @ 0x%x.\n",
+			name, 16, chip_ver, client->addr << 1);
+
+		return GM7113C;
+	}
+
+	/* Chip was not discovered. Return its ID and don't bind */
+	v4l_dbg(1, debug, client, "chip %*ph @ 0x%x is unknown.\n",
+		16, chip_ver, client->addr << 1);
+	return -ENODEV;
+}
+
 static int saa711x_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
 	struct saa711x_state *state;
 	struct v4l2_subdev *sd;
 	struct v4l2_ctrl_handler *hdl;
-	int i;
-	char name[17];
-	char chip_id;
-	int autodetect = !id || id->driver_data == 1;
+	int ident;
+	char name[CHIP_VER_SIZE + 1];
 
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
 
-	for (i = 0; i < 0x0f; i++) {
-		i2c_smbus_write_byte_data(client, 0, i);
-		name[i] = (i2c_smbus_read_byte_data(client, 0) & 0x0f) + '0';
-		if (name[i] > '9')
-			name[i] += 'a' - '9' - 1;
-	}
-	name[i] = '\0';
-
-	chip_id = name[5];
-
-	/* Check whether this chip is part of the saa711x series */
-	if (memcmp(name + 1, "f711", 4)) {
-		v4l_dbg(1, debug, client, "chip found @ 0x%x (ID %s) does not match a known saa711x chip.\n",
-			client->addr << 1, name);
+	ident = saa711x_detect_chip(client, id, name);
+	if (ident == -EINVAL) {
+		/* Chip exists, but doesn't match */
+		v4l_warn(client, "found %s while %s was expected\n",
+			 name, id->name);
 		return -ENODEV;
 	}
+	if (ident < 0)
+		return ident;
 
-	/* Safety check */
-	if (!autodetect && id->name[6] != chip_id) {
-		v4l_warn(client, "found saa711%c while %s was expected\n",
-			 chip_id, id->name);
-	}
-	snprintf(client->name, sizeof(client->name), "saa711%c", chip_id);
-	v4l_info(client, "saa711%c found (%s) @ 0x%x (%s)\n", chip_id, name,
-		 client->addr << 1, client->adapter->name);
+	strlcpy(client->name, name, sizeof(client->name));
 
-	state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
 
+	v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+		 client->addr << 1, client->adapter->name);
 	hdl = &state->hdl;
 	v4l2_ctrl_handler_init(hdl, 6);
 	/* add in ascending ID order */
@@ -1640,7 +1751,6 @@
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(state);
 		return err;
 	}
 	v4l2_ctrl_auto_cluster(2, &state->agc, 0, true);
@@ -1649,31 +1759,7 @@
 	state->output = SAA7115_IPORT_ON;
 	state->enable = 1;
 	state->radio = 0;
-	switch (chip_id) {
-	case '1':
-		state->ident = V4L2_IDENT_SAA7111;
-		if (saa711x_read(sd, R_00_CHIP_VERSION) & 0xf0) {
-			v4l_info(client, "saa7111a variant found\n");
-			state->ident = V4L2_IDENT_SAA7111A;
-		}
-		break;
-	case '3':
-		state->ident = V4L2_IDENT_SAA7113;
-		break;
-	case '4':
-		state->ident = V4L2_IDENT_SAA7114;
-		break;
-	case '5':
-		state->ident = V4L2_IDENT_SAA7115;
-		break;
-	case '8':
-		state->ident = V4L2_IDENT_SAA7118;
-		break;
-	default:
-		state->ident = V4L2_IDENT_SAA7111;
-		v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
-		break;
-	}
+	state->ident = ident;
 
 	state->audclk_freq = 48000;
 
@@ -1682,18 +1768,19 @@
 	/* init to 60hz/48khz */
 	state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
 	switch (state->ident) {
-	case V4L2_IDENT_SAA7111:
-	case V4L2_IDENT_SAA7111A:
+	case SAA7111:
+	case SAA7111A:
 		saa711x_writeregs(sd, saa7111_init);
 		break;
-	case V4L2_IDENT_SAA7113:
+	case GM7113C:
+	case SAA7113:
 		saa711x_writeregs(sd, saa7113_init);
 		break;
 	default:
 		state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
 		saa711x_writeregs(sd, saa7115_init_auto_input);
 	}
-	if (state->ident > V4L2_IDENT_SAA7111A)
+	if (state->ident > SAA7111A)
 		saa711x_writeregs(sd, saa7115_init_misc);
 	saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
 	v4l2_ctrl_handler_setup(hdl);
@@ -1712,7 +1799,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	kfree(to_state(sd));
 	return 0;
 }
 
@@ -1723,6 +1809,7 @@
 	{ "saa7114", 0 },
 	{ "saa7115", 0 },
 	{ "saa7118", 0 },
+	{ "gm7113c", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, saa711x_id);
diff --git a/drivers/media/i2c/saa7127.c b/drivers/media/i2c/saa7127.c
index 8a47ac1..264b755 100644
--- a/drivers/media/i2c/saa7127.c
+++ b/drivers/media/i2c/saa7127.c
@@ -54,7 +54,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/saa7127.h>
 
 static int debug;
@@ -251,10 +250,15 @@
  **********************************************************************
  */
 
+enum saa712x_model {
+	SAA7127,
+	SAA7129,
+};
+
 struct saa7127_state {
 	struct v4l2_subdev sd;
 	v4l2_std_id std;
-	u32 ident;
+	enum saa712x_model ident;
 	enum saa7127_input_type input_type;
 	enum saa7127_output_type output_type;
 	int video_enable;
@@ -482,7 +486,7 @@
 		inittab = saa7127_init_config_60hz;
 		state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
 
-	} else if (state->ident == V4L2_IDENT_SAA7129 &&
+	} else if (state->ident == SAA7129 &&
 		   (std & V4L2_STD_SECAM) &&
 		   !(std & (V4L2_STD_625_50 & ~V4L2_STD_SECAM))) {
 
@@ -517,7 +521,7 @@
 		break;
 
 	case SAA7127_OUTPUT_TYPE_COMPOSITE:
-		if (state->ident == V4L2_IDENT_SAA7129)
+		if (state->ident == SAA7129)
 			state->reg_2d = 0x20;	/* CVBS only */
 		else
 			state->reg_2d = 0x08;	/* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
@@ -525,7 +529,7 @@
 		break;
 
 	case SAA7127_OUTPUT_TYPE_SVIDEO:
-		if (state->ident == V4L2_IDENT_SAA7129)
+		if (state->ident == SAA7129)
 			state->reg_2d = 0x18;	/* Y + C */
 		else
 			state->reg_2d = 0xff;   /*11111111  croma -> R, luma -> CVBS + G + B */
@@ -543,7 +547,7 @@
 		break;
 
 	case SAA7127_OUTPUT_TYPE_BOTH:
-		if (state->ident == V4L2_IDENT_SAA7129)
+		if (state->ident == SAA7129)
 			state->reg_2d = 0x38;
 		else
 			state->reg_2d = 0xbf;
@@ -661,12 +665,6 @@
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int saa7127_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = saa7127_read(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -674,25 +672,11 @@
 
 static int saa7127_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	saa7127_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
 #endif
 
-static int saa7127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct saa7127_state *state = to_state(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
-}
-
 static int saa7127_log_status(struct v4l2_subdev *sd)
 {
 	struct saa7127_state *state = to_state(sd);
@@ -712,7 +696,6 @@
 
 static const struct v4l2_subdev_core_ops saa7127_core_ops = {
 	.log_status = saa7127_log_status,
-	.g_chip_ident = saa7127_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = saa7127_g_register,
 	.s_register = saa7127_s_register,
@@ -752,7 +735,7 @@
 	v4l_dbg(1, debug, client, "detecting saa7127 client on address 0x%x\n",
 			client->addr << 1);
 
-	state = kzalloc(sizeof(struct saa7127_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 
@@ -767,7 +750,6 @@
 	if ((saa7127_read(sd, 0) & 0xe4) != 0 ||
 			(saa7127_read(sd, 0x29) & 0x3f) != 0x1d) {
 		v4l2_dbg(1, debug, sd, "saa7127 not found\n");
-		kfree(state);
 		return -ENODEV;
 	}
 
@@ -782,10 +764,10 @@
 		if (saa7127_read(sd, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
 			saa7127_write(sd, SAA7129_REG_FADE_KEY_COL2,
 					read_result);
-			state->ident = V4L2_IDENT_SAA7129;
+			state->ident = SAA7129;
 			strlcpy(client->name, "saa7129", I2C_NAME_SIZE);
 		} else {
-			state->ident = V4L2_IDENT_SAA7127;
+			state->ident = SAA7127;
 			strlcpy(client->name, "saa7127", I2C_NAME_SIZE);
 		}
 	}
@@ -809,7 +791,7 @@
 		saa7127_set_input_type(sd, SAA7127_INPUT_TYPE_NORMAL);
 	saa7127_set_video_enable(sd, 1);
 
-	if (state->ident == V4L2_IDENT_SAA7129)
+	if (state->ident == SAA7129)
 		saa7127_write_inittab(sd, saa7129_init_config_extra);
 	return 0;
 }
@@ -823,7 +805,6 @@
 	v4l2_device_unregister_subdev(sd);
 	/* Turn off TV output */
 	saa7127_set_video_enable(sd, 0);
-	kfree(to_state(sd));
 	return 0;
 }
 
@@ -831,10 +812,10 @@
 
 static struct i2c_device_id saa7127_id[] = {
 	{ "saa7127_auto", 0 },	/* auto-detection */
-	{ "saa7126", V4L2_IDENT_SAA7127 },
-	{ "saa7127", V4L2_IDENT_SAA7127 },
-	{ "saa7128", V4L2_IDENT_SAA7129 },
-	{ "saa7129", V4L2_IDENT_SAA7129 },
+	{ "saa7126", SAA7127 },
+	{ "saa7127", SAA7127 },
+	{ "saa7128", SAA7129 },
+	{ "saa7129", SAA7129 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, saa7127_id);
diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c
index cf3a0aa..401ca11 100644
--- a/drivers/media/i2c/saa717x.c
+++ b/drivers/media/i2c/saa717x.c
@@ -977,12 +977,6 @@
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = saa717x_read(sd, reg->reg);
 	reg->size = 1;
 	return 0;
@@ -990,14 +984,9 @@
 
 static int saa717x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	u16 addr = reg->reg & 0xffff;
 	u8 val = reg->val & 0xff;
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	saa717x_write(sd, addr, val);
 	return 0;
 }
@@ -1262,7 +1251,7 @@
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
 
-	decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (decoder == NULL)
 		return -ENOMEM;
 
@@ -1276,7 +1265,6 @@
 		id = saa717x_read(sd, 0x5a0);
 	if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) {
 		v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id);
-		kfree(decoder);
 		return -ENODEV;
 	}
 	if (id == 0xc2)
@@ -1316,7 +1304,6 @@
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(decoder);
 		return err;
 	}
 
@@ -1353,7 +1340,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/saa7185.c b/drivers/media/i2c/saa7185.c
index 2c6b65c..f56c1c8 100644
--- a/drivers/media/i2c/saa7185.c
+++ b/drivers/media/i2c/saa7185.c
@@ -32,7 +32,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
 MODULE_AUTHOR("Dave Perks");
@@ -285,17 +284,9 @@
 	return 0;
 }
 
-static int saa7185_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7185, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops saa7185_core_ops = {
-	.g_chip_ident = saa7185_g_chip_ident,
 	.init = saa7185_init,
 };
 
@@ -326,7 +317,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
+	encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
 	if (encoder == NULL)
 		return -ENOMEM;
 	encoder->norm = V4L2_STD_NTSC;
@@ -352,7 +343,6 @@
 	v4l2_device_unregister_subdev(sd);
 	/* SW: output off is active */
 	saa7185_write(sd, 0x61, (encoder->reg[0x61]) | 0x40);
-	kfree(encoder);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/saa7191.c b/drivers/media/i2c/saa7191.c
index d7d1670..606a4ba 100644
--- a/drivers/media/i2c/saa7191.c
+++ b/drivers/media/i2c/saa7191.c
@@ -22,7 +22,6 @@
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 #include "saa7191.h"
 
@@ -272,7 +271,7 @@
 
 	dprintk("SAA7191 extended signal auto-detection...\n");
 
-	*norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
+	*norm &= V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
 	stdc &= ~SAA7191_STDC_SECS;
 	ctl3 &= ~(SAA7191_CTL3_FSEL);
 
@@ -303,7 +302,7 @@
 	if (status & SAA7191_STATUS_FIDT) {
 		/* 60Hz signal -> NTSC */
 		dprintk("60Hz signal: NTSC\n");
-		*norm = V4L2_STD_NTSC;
+		*norm &= V4L2_STD_NTSC;
 		return 0;
 	}
 
@@ -325,12 +324,13 @@
 	if (status & SAA7191_STATUS_FIDT) {
 		dprintk("No 50Hz signal\n");
 		saa7191_s_std(sd, old_norm);
-		return -EAGAIN;
+		*norm = V4L2_STD_UNKNOWN;
+		return 0;
 	}
 
 	if (status & SAA7191_STATUS_CODE) {
 		dprintk("PAL\n");
-		*norm = V4L2_STD_PAL;
+		*norm &= V4L2_STD_PAL;
 		return saa7191_s_std(sd, old_norm);
 	}
 
@@ -350,18 +350,19 @@
 	/* not 50Hz ? */
 	if (status & SAA7191_STATUS_FIDT) {
 		dprintk("No 50Hz signal\n");
-		err = -EAGAIN;
+		*norm = V4L2_STD_UNKNOWN;
 		goto out;
 	}
 
 	if (status & SAA7191_STATUS_CODE) {
 		/* Color detected -> SECAM */
 		dprintk("SECAM\n");
-		*norm = V4L2_STD_SECAM;
+		*norm &= V4L2_STD_SECAM;
 		return saa7191_s_std(sd, old_norm);
 	}
 
 	dprintk("No color detected with SECAM - Going back to PAL.\n");
+	*norm = V4L2_STD_UNKNOWN;
 
 out:
 	return saa7191_s_std(sd, old_norm);
@@ -567,18 +568,9 @@
 }
 
 
-static int saa7191_g_chip_ident(struct v4l2_subdev *sd,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops saa7191_core_ops = {
-	.g_chip_ident = saa7191_g_chip_ident,
 	.g_ctrl = saa7191_g_ctrl,
 	.s_ctrl = saa7191_s_ctrl,
 	.s_std = saa7191_s_std,
@@ -605,7 +597,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (!decoder)
 		return -ENOMEM;
 
@@ -615,7 +607,6 @@
 	err = saa7191_write_block(sd, sizeof(initseq), initseq);
 	if (err) {
 		printk(KERN_ERR "SAA7191 initialization failed\n");
-		kfree(decoder);
 		return err;
 	}
 
@@ -636,7 +627,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_saa7191(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index cae4f46..7ac7580 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2383,8 +2383,9 @@
 	}
 
 	if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN) {
-		if (gpio_request_one(sensor->platform_data->xshutdown, 0,
-				     "SMIA++ xshutdown") != 0) {
+		if (devm_gpio_request_one(&client->dev,
+					  sensor->platform_data->xshutdown, 0,
+					  "SMIA++ xshutdown") != 0) {
 			dev_err(&client->dev,
 				"unable to acquire reset gpio %d\n",
 				sensor->platform_data->xshutdown);
@@ -2393,10 +2394,8 @@
 	}
 
 	rval = smiapp_power_on(sensor);
-	if (rval) {
-		rval = -ENODEV;
-		goto out_smiapp_power_on;
-	}
+	if (rval)
+		return -ENODEV;
 
 	rval = smiapp_identify_module(subdev);
 	if (rval) {
@@ -2656,11 +2655,6 @@
 
 out_power_off:
 	smiapp_power_off(sensor);
-
-out_smiapp_power_on:
-	if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
-		gpio_free(sensor->platform_data->xshutdown);
-
 	return rval;
 }
 
@@ -2854,12 +2848,10 @@
 		device_remove_file(&client->dev, &dev_attr_nvm);
 
 	for (i = 0; i < sensor->ssds_used; i++) {
-		media_entity_cleanup(&sensor->ssds[i].sd.entity);
 		v4l2_device_unregister_subdev(&sensor->ssds[i].sd);
+		media_entity_cleanup(&sensor->ssds[i].sd.entity);
 	}
 	smiapp_free_controls(sensor);
-	if (sensor->platform_data->xshutdown != SMIAPP_NO_XSHUTDOWN)
-		gpio_free(sensor->platform_data->xshutdown);
 
 	return 0;
 }
diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c
index a2a5cbb..1d384a3 100644
--- a/drivers/media/i2c/soc_camera/imx074.c
+++ b/drivers/media/i2c/soc_camera/imx074.c
@@ -18,8 +18,9 @@
 #include <linux/module.h>
 
 #include <media/soc_camera.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
 
 /* IMX074 registers */
 
@@ -77,6 +78,7 @@
 struct imx074 {
 	struct v4l2_subdev		subdev;
 	const struct imx074_datafmt	*fmt;
+	struct v4l2_clk			*clk;
 };
 
 static const struct imx074_datafmt imx074_colour_fmts[] = {
@@ -251,29 +253,13 @@
 	return reg_write(client, MODE_SELECT, !!enable);
 }
 
-static int imx074_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= V4L2_IDENT_IMX074;
-	id->revision	= 0;
-
-	return 0;
-}
-
 static int imx074_s_power(struct v4l2_subdev *sd, int on)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct imx074 *priv = to_imx074(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 static int imx074_g_mbus_config(struct v4l2_subdev *sd,
@@ -299,7 +285,6 @@
 };
 
 static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
-	.g_chip_ident	= imx074_g_chip_ident,
 	.s_power	= imx074_s_power,
 };
 
@@ -431,6 +416,7 @@
 	struct imx074 *priv;
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	int ret;
 
 	if (!ssdd) {
 		dev_err(&client->dev, "IMX074: missing platform data!\n");
@@ -451,12 +437,35 @@
 
 	priv->fmt	= &imx074_colour_fmts[0];
 
-	return imx074_video_probe(client);
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		dev_info(&client->dev, "Error %ld getting clock\n", PTR_ERR(priv->clk));
+		return -EPROBE_DEFER;
+	}
+
+	ret = soc_camera_power_init(&client->dev, ssdd);
+	if (ret < 0)
+		goto epwrinit;
+
+	ret = imx074_video_probe(client);
+	if (ret < 0)
+		goto eprobe;
+
+	return v4l2_async_register_subdev(&priv->subdev);
+
+epwrinit:
+eprobe:
+	v4l2_clk_put(priv->clk);
+	return ret;
 }
 
 static int imx074_remove(struct i2c_client *client)
 {
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct imx074 *priv = to_imx074(client);
+
+	v4l2_async_unregister_subdev(&priv->subdev);
+	v4l2_clk_put(priv->clk);
 
 	if (ssdd->free_bus)
 		ssdd->free_bus(ssdd);
diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c
index dd90898..df97033 100644
--- a/drivers/media/i2c/soc_camera/mt9m001.c
+++ b/drivers/media/i2c/soc_camera/mt9m001.c
@@ -16,8 +16,8 @@
 
 #include <media/soc_camera.h>
 #include <media/soc_mediabus.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 /*
@@ -94,10 +94,10 @@
 		struct v4l2_ctrl *exposure;
 	};
 	struct v4l2_rect rect;	/* Sensor window */
+	struct v4l2_clk *clk;
 	const struct mt9m001_datafmt *fmt;
 	const struct mt9m001_datafmt *fmts;
 	int num_fmts;
-	int model;	/* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
 	unsigned int total_h;
 	unsigned short y_skip_top;	/* Lines to skip at the top */
 };
@@ -320,36 +320,15 @@
 	return 0;
 }
 
-static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct mt9m001 *mt9m001 = to_mt9m001(client);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= mt9m001->model;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int mt9m001_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	reg->size = 2;
 	reg->val = reg_read(client, reg->reg);
 
@@ -364,12 +343,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -381,8 +357,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, mt9m001->clk, on);
 }
 
 static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
@@ -505,11 +482,9 @@
 	switch (data) {
 	case 0x8411:
 	case 0x8421:
-		mt9m001->model = V4L2_IDENT_MT9M001C12ST;
 		mt9m001->fmts = mt9m001_colour_fmts;
 		break;
 	case 0x8431:
-		mt9m001->model = V4L2_IDENT_MT9M001C12STM;
 		mt9m001->fmts = mt9m001_monochrome_fmts;
 		break;
 	default:
@@ -580,7 +555,6 @@
 };
 
 static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
-	.g_chip_ident	= mt9m001_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= mt9m001_g_register,
 	.s_register	= mt9m001_s_register,
@@ -710,9 +684,18 @@
 	mt9m001->rect.width	= MT9M001_MAX_WIDTH;
 	mt9m001->rect.height	= MT9M001_MAX_HEIGHT;
 
+	mt9m001->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(mt9m001->clk)) {
+		ret = PTR_ERR(mt9m001->clk);
+		goto eclkget;
+	}
+
 	ret = mt9m001_video_probe(ssdd, client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(mt9m001->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&mt9m001->hdl);
+	}
 
 	return ret;
 }
@@ -722,6 +705,7 @@
 	struct mt9m001 *mt9m001 = to_mt9m001(client);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 
+	v4l2_clk_put(mt9m001->clk);
 	v4l2_device_unregister_subdev(&mt9m001->subdev);
 	v4l2_ctrl_handler_free(&mt9m001->hdl);
 	mt9m001_video_remove(ssdd);
diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c
index 8bd4e0d..de3605d 100644
--- a/drivers/media/i2c/soc_camera/mt9m111.c
+++ b/drivers/media/i2c/soc_camera/mt9m111.c
@@ -17,9 +17,9 @@
 #include <linux/module.h>
 
 #include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 
 /*
  * MT9M111, MT9M112 and MT9M131:
@@ -205,10 +205,9 @@
 	struct v4l2_subdev subdev;
 	struct v4l2_ctrl_handler hdl;
 	struct v4l2_ctrl *gain;
-	int model;	/* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code
-			 * from v4l2-chip-ident.h */
 	struct mt9m111_context *ctx;
 	struct v4l2_rect rect;	/* cropping rectangle */
+	struct v4l2_clk *clk;
 	int width;		/* output */
 	int height;		/* sizes */
 	struct mutex power_lock; /* lock to protect power_count */
@@ -600,24 +599,6 @@
 	return ret;
 }
 
-static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= mt9m111->model;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int mt9m111_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
@@ -625,10 +606,8 @@
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int val;
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
+	if (reg->reg > 0x2ff)
 		return -EINVAL;
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
 
 	val = mt9m111_reg_read(client, reg->reg);
 	reg->size = 2;
@@ -645,12 +624,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
+	if (reg->reg > 0x2ff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (mt9m111_reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -801,14 +777,14 @@
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 	int ret;
 
-	ret = soc_camera_power_on(&client->dev, ssdd);
+	ret = soc_camera_power_on(&client->dev, ssdd, mt9m111->clk);
 	if (ret < 0)
 		return ret;
 
 	ret = mt9m111_resume(mt9m111);
 	if (ret < 0) {
 		dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret);
-		soc_camera_power_off(&client->dev, ssdd);
+		soc_camera_power_off(&client->dev, ssdd, mt9m111->clk);
 	}
 
 	return ret;
@@ -820,7 +796,7 @@
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 
 	mt9m111_suspend(mt9m111);
-	soc_camera_power_off(&client->dev, ssdd);
+	soc_camera_power_off(&client->dev, ssdd, mt9m111->clk);
 }
 
 static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
@@ -856,7 +832,6 @@
 };
 
 static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
-	.g_chip_ident	= mt9m111_g_chip_ident,
 	.s_power	= mt9m111_s_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= mt9m111_g_register,
@@ -923,12 +898,10 @@
 
 	switch (data) {
 	case 0x143a: /* MT9M111 or MT9M131 */
-		mt9m111->model = V4L2_IDENT_MT9M111;
 		dev_info(&client->dev,
 			"Detected a MT9M111/MT9M131 chip ID %x\n", data);
 		break;
 	case 0x148c: /* MT9M112 */
-		mt9m111->model = V4L2_IDENT_MT9M112;
 		dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data);
 		break;
 	default:
@@ -1002,9 +975,18 @@
 	mt9m111->lastpage	= -1;
 	mutex_init(&mt9m111->power_lock);
 
+	mt9m111->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(mt9m111->clk)) {
+		ret = PTR_ERR(mt9m111->clk);
+		goto eclkget;
+	}
+
 	ret = mt9m111_video_probe(client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(mt9m111->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&mt9m111->hdl);
+	}
 
 	return ret;
 }
@@ -1013,6 +995,7 @@
 {
 	struct mt9m111 *mt9m111 = to_mt9m111(client);
 
+	v4l2_clk_put(mt9m111->clk);
 	v4l2_device_unregister_subdev(&mt9m111->subdev);
 	v4l2_ctrl_handler_free(&mt9m111->hdl);
 
diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c
index 26a15b8..47d18d0 100644
--- a/drivers/media/i2c/soc_camera/mt9t031.c
+++ b/drivers/media/i2c/soc_camera/mt9t031.c
@@ -18,7 +18,7 @@
 #include <linux/module.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-ctrls.h>
 
@@ -76,7 +76,7 @@
 		struct v4l2_ctrl *exposure;
 	};
 	struct v4l2_rect rect;	/* Sensor window */
-	int model;	/* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
+	struct v4l2_clk *clk;
 	u16 xskip;
 	u16 yskip;
 	unsigned int total_h;
@@ -391,36 +391,16 @@
 	return 0;
 }
 
-static int mt9t031_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct mt9t031 *mt9t031 = to_mt9t031(client);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= mt9t031->model;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int mt9t031_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
+	reg->size = 1;
 	reg->val = reg_read(client, reg->reg);
 
 	if (reg->val > 0xffff)
@@ -434,12 +414,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -595,7 +572,7 @@
 	return 0;
 }
 
-static struct dev_pm_ops mt9t031_dev_pm_ops = {
+static const struct dev_pm_ops mt9t031_dev_pm_ops = {
 	.runtime_suspend	= mt9t031_runtime_suspend,
 	.runtime_resume		= mt9t031_runtime_resume,
 };
@@ -610,16 +587,17 @@
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 	struct video_device *vdev = soc_camera_i2c_to_vdev(client);
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
 	int ret;
 
 	if (on) {
-		ret = soc_camera_power_on(&client->dev, ssdd);
+		ret = soc_camera_power_on(&client->dev, ssdd, mt9t031->clk);
 		if (ret < 0)
 			return ret;
 		vdev->dev.type = &mt9t031_dev_type;
 	} else {
 		vdev->dev.type = NULL;
-		soc_camera_power_off(&client->dev, ssdd);
+		soc_camera_power_off(&client->dev, ssdd, mt9t031->clk);
 	}
 
 	return 0;
@@ -650,7 +628,6 @@
 
 	switch (data) {
 	case 0x1621:
-		mt9t031->model = V4L2_IDENT_MT9T031;
 		break;
 	default:
 		dev_err(&client->dev,
@@ -685,7 +662,6 @@
 };
 
 static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
-	.g_chip_ident	= mt9t031_g_chip_ident,
 	.s_power	= mt9t031_s_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= mt9t031_g_register,
@@ -812,9 +788,18 @@
 	mt9t031->xskip = 1;
 	mt9t031->yskip = 1;
 
+	mt9t031->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(mt9t031->clk)) {
+		ret = PTR_ERR(mt9t031->clk);
+		goto eclkget;
+	}
+
 	ret = mt9t031_video_probe(client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(mt9t031->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&mt9t031->hdl);
+	}
 
 	return ret;
 }
@@ -823,6 +808,7 @@
 {
 	struct mt9t031 *mt9t031 = to_mt9t031(client);
 
+	v4l2_clk_put(mt9t031->clk);
 	v4l2_device_unregister_subdev(&mt9t031->subdev);
 	v4l2_ctrl_handler_free(&mt9t031->hdl);
 
diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c
index a7256b7..46f431a 100644
--- a/drivers/media/i2c/soc_camera/mt9t112.c
+++ b/drivers/media/i2c/soc_camera/mt9t112.c
@@ -27,7 +27,7 @@
 
 #include <media/mt9t112.h>
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-common.h>
 
 /* you can check PLL/clock info */
@@ -90,8 +90,8 @@
 	struct mt9t112_camera_info	*info;
 	struct i2c_client		*client;
 	struct v4l2_rect		 frame;
+	struct v4l2_clk			*clk;
 	const struct mt9t112_format	*format;
-	int				 model;
 	int				 num_formats;
 	u32				 flags;
 /* for flags */
@@ -738,17 +738,6 @@
 /************************************************************************
 			v4l2_subdev_core_ops
 ************************************************************************/
-static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct mt9t112_priv *priv = to_mt9t112(client);
-
-	id->ident    = priv->model;
-	id->revision = 0;
-
-	return 0;
-}
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int mt9t112_g_register(struct v4l2_subdev *sd,
@@ -781,12 +770,12 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct mt9t112_priv *priv = to_mt9t112(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
-	.g_chip_ident	= mt9t112_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= mt9t112_g_register,
 	.s_register	= mt9t112_s_register,
@@ -1061,12 +1050,10 @@
 	switch (chipid) {
 	case 0x2680:
 		devname = "mt9t111";
-		priv->model = V4L2_IDENT_MT9T111;
 		priv->num_formats = 1;
 		break;
 	case 0x2682:
 		devname = "mt9t112";
-		priv->model = V4L2_IDENT_MT9T112;
 		priv->num_formats = ARRAY_SIZE(mt9t112_cfmts);
 		break;
 	default:
@@ -1108,18 +1095,26 @@
 
 	v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
 
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);
+
 	ret = mt9t112_camera_probe(client);
-	if (ret)
-		return ret;
 
 	/* Cannot fail: using the default supported pixel code */
-	mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
+	if (!ret)
+		mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
+	else
+		v4l2_clk_put(priv->clk);
 
 	return ret;
 }
 
 static int mt9t112_remove(struct i2c_client *client)
 {
+	struct mt9t112_priv *priv = to_mt9t112(client);
+
+	v4l2_clk_put(priv->clk);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c
index a295e59..f9f95f8 100644
--- a/drivers/media/i2c/soc_camera/mt9v022.c
+++ b/drivers/media/i2c/soc_camera/mt9v022.c
@@ -19,7 +19,7 @@
 #include <media/soc_camera.h>
 #include <media/soc_mediabus.h>
 #include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-ctrls.h>
 
 /*
@@ -133,6 +133,11 @@
 	.pixclk_fv_lv			= MT9V024_PIXCLK_FV_LV,
 };
 
+enum mt9v022_model {
+	MT9V022IX7ATM,
+	MT9V022IX7ATC,
+};
+
 struct mt9v022 {
 	struct v4l2_subdev subdev;
 	struct v4l2_ctrl_handler hdl;
@@ -149,11 +154,12 @@
 	struct v4l2_ctrl *hblank;
 	struct v4l2_ctrl *vblank;
 	struct v4l2_rect rect;	/* Sensor window */
+	struct v4l2_clk *clk;
 	const struct mt9v022_datafmt *fmt;
 	const struct mt9v022_datafmt *fmts;
 	const struct mt9v02x_register *reg;
 	int num_fmts;
-	int model;	/* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
+	enum mt9v022_model model;
 	u16 chip_control;
 	u16 chip_version;
 	unsigned short y_skip_top;	/* Lines to skip at the top */
@@ -406,12 +412,12 @@
 	switch (mf->code) {
 	case V4L2_MBUS_FMT_Y8_1X8:
 	case V4L2_MBUS_FMT_Y10_1X10:
-		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
+		if (mt9v022->model != MT9V022IX7ATM)
 			return -EINVAL;
 		break;
 	case V4L2_MBUS_FMT_SBGGR8_1X8:
 	case V4L2_MBUS_FMT_SBGGR10_1X10:
-		if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
+		if (mt9v022->model != MT9V022IX7ATC)
 			return -EINVAL;
 		break;
 	default:
@@ -457,36 +463,15 @@
 	return 0;
 }
 
-static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct mt9v022 *mt9v022 = to_mt9v022(client);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= mt9v022->model;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int mt9v022_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	reg->size = 2;
 	reg->val = reg_read(client, reg->reg);
 
@@ -501,12 +486,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
+	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -518,8 +500,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, mt9v022->clk, on);
 }
 
 static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
@@ -706,11 +689,11 @@
 	if (sensor_type && (!strcmp("colour", sensor_type) ||
 			    !strcmp("color", sensor_type))) {
 		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
-		mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
+		mt9v022->model = MT9V022IX7ATC;
 		mt9v022->fmts = mt9v022_colour_fmts;
 	} else {
 		ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11);
-		mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
+		mt9v022->model = MT9V022IX7ATM;
 		mt9v022->fmts = mt9v022_monochrome_fmts;
 	}
 
@@ -740,7 +723,7 @@
 	mt9v022->fmt = &mt9v022->fmts[0];
 
 	dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
-		 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
+		 data, mt9v022->model == MT9V022IX7ATM ?
 		 "monochrome" : "colour");
 
 	ret = mt9v022_init(client);
@@ -768,7 +751,6 @@
 };
 
 static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
-	.g_chip_ident	= mt9v022_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= mt9v022_g_register,
 	.s_register	= mt9v022_s_register,
@@ -957,9 +939,18 @@
 	mt9v022->rect.width	= MT9V022_MAX_WIDTH;
 	mt9v022->rect.height	= MT9V022_MAX_HEIGHT;
 
+	mt9v022->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(mt9v022->clk)) {
+		ret = PTR_ERR(mt9v022->clk);
+		goto eclkget;
+	}
+
 	ret = mt9v022_video_probe(client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(mt9v022->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&mt9v022->hdl);
+	}
 
 	return ret;
 }
@@ -969,6 +960,7 @@
 	struct mt9v022 *mt9v022 = to_mt9v022(client);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 
+	v4l2_clk_put(mt9v022->clk);
 	v4l2_device_unregister_subdev(&mt9v022->subdev);
 	if (ssdd->free_bus)
 		ssdd->free_bus(ssdd);
diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c
index e316842..6c6b1c3 100644
--- a/drivers/media/i2c/soc_camera/ov2640.c
+++ b/drivers/media/i2c/soc_camera/ov2640.c
@@ -22,7 +22,7 @@
 #include <linux/videodev2.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-ctrls.h>
 
@@ -303,8 +303,8 @@
 	struct v4l2_subdev		subdev;
 	struct v4l2_ctrl_handler	hdl;
 	enum v4l2_mbus_pixelcode	cfmt_code;
+	struct v4l2_clk			*clk;
 	const struct ov2640_win_size	*win;
-	int				model;
 };
 
 /*
@@ -723,18 +723,6 @@
 	return -EINVAL;
 }
 
-static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ov2640_priv *priv = to_ov2640(client);
-
-	id->ident    = priv->model;
-	id->revision = 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov2640_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
@@ -772,8 +760,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov2640_priv *priv = to_ov2640(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 /* Select the nearest higher resolution for capture */
@@ -1009,7 +998,6 @@
 	switch (VERSION(pid, ver)) {
 	case PID_OV2640:
 		devname     = "ov2640";
-		priv->model = V4L2_IDENT_OV2640;
 		break;
 	default:
 		dev_err(&client->dev,
@@ -1034,7 +1022,6 @@
 };
 
 static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
-	.g_chip_ident	= ov2640_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= ov2640_g_register,
 	.s_register	= ov2640_s_register,
@@ -1113,11 +1100,20 @@
 	if (priv->hdl.error)
 		return priv->hdl.error;
 
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		ret = PTR_ERR(priv->clk);
+		goto eclkget;
+	}
+
 	ret = ov2640_video_probe(client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(priv->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&priv->hdl);
-	else
+	} else {
 		dev_info(&adapter->dev, "OV2640 Probed\n");
+	}
 
 	return ret;
 }
@@ -1126,6 +1122,7 @@
 {
 	struct ov2640_priv       *priv = to_ov2640(client);
 
+	v4l2_clk_put(priv->clk);
 	v4l2_device_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c
index 9aa56de..0a5c5d4 100644
--- a/drivers/media/i2c/soc_camera/ov5642.c
+++ b/drivers/media/i2c/soc_camera/ov5642.c
@@ -24,7 +24,7 @@
 #include <linux/v4l2-mediabus.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
 
 /* OV5642 registers */
@@ -610,6 +610,7 @@
 	struct v4l2_subdev		subdev;
 	const struct ov5642_datafmt	*fmt;
 	struct v4l2_rect                crop_rect;
+	struct v4l2_clk			*clk;
 
 	/* blanking information */
 	int total_width;
@@ -848,23 +849,6 @@
 	return 0;
 }
 
-static int ov5642_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= V4L2_IDENT_OV5642;
-	id->revision	= 0;
-
-	return 0;
-}
-
 static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -935,12 +919,13 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov5642 *priv = to_ov5642(client);
 	int ret;
 
 	if (!on)
-		return soc_camera_power_off(&client->dev, ssdd);
+		return soc_camera_power_off(&client->dev, ssdd, priv->clk);
 
-	ret = soc_camera_power_on(&client->dev, ssdd);
+	ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
 	if (ret < 0)
 		return ret;
 
@@ -966,7 +951,6 @@
 
 static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
 	.s_power	= ov5642_s_power,
-	.g_chip_ident	= ov5642_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= ov5642_get_register,
 	.s_register	= ov5642_set_register,
@@ -1021,6 +1005,7 @@
 {
 	struct ov5642 *priv;
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	int ret;
 
 	if (!ssdd) {
 		dev_err(&client->dev, "OV5642: missing platform data!\n");
@@ -1042,13 +1027,23 @@
 	priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
 	priv->total_height = BLANKING_MIN_HEIGHT;
 
-	return ov5642_video_probe(client);
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);
+
+	ret = ov5642_video_probe(client);
+	if (ret < 0)
+		v4l2_clk_put(priv->clk);
+
+	return ret;
 }
 
 static int ov5642_remove(struct i2c_client *client)
 {
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov5642 *priv = to_ov5642(client);
 
+	v4l2_clk_put(priv->clk);
 	if (ssdd->free_bus)
 		ssdd->free_bus(ssdd);
 
diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c
index 991202d..ab01598 100644
--- a/drivers/media/i2c/soc_camera/ov6650.c
+++ b/drivers/media/i2c/soc_camera/ov6650.c
@@ -32,7 +32,7 @@
 #include <linux/module.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-ctrls.h>
 
 /* Register definitions */
@@ -196,6 +196,7 @@
 		struct v4l2_ctrl *blue;
 		struct v4l2_ctrl *red;
 	};
+	struct v4l2_clk		*clk;
 	bool			half_scale;	/* scale down output by 2 */
 	struct v4l2_rect	rect;		/* sensor cropping window */
 	unsigned long		pclk_limit;	/* from host */
@@ -390,16 +391,6 @@
 	return -EINVAL;
 }
 
-/* Get chip identification */
-static int ov6650_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	id->ident	= V4L2_IDENT_OV6650;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov6650_get_register(struct v4l2_subdev *sd,
 				struct v4l2_dbg_register *reg)
@@ -436,8 +427,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov6650 *priv = to_ov6650(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
@@ -879,7 +871,6 @@
 };
 
 static struct v4l2_subdev_core_ops ov6650_core_ops = {
-	.g_chip_ident		= ov6650_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register		= ov6650_get_register,
 	.s_register		= ov6650_set_register,
@@ -1025,9 +1016,18 @@
 	priv->code	  = V4L2_MBUS_FMT_YUYV8_2X8;
 	priv->colorspace  = V4L2_COLORSPACE_JPEG;
 
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		ret = PTR_ERR(priv->clk);
+		goto eclkget;
+	}
+
 	ret = ov6650_video_probe(client);
-	if (ret)
+	if (ret) {
+		v4l2_clk_put(priv->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&priv->hdl);
+	}
 
 	return ret;
 }
@@ -1036,6 +1036,7 @@
 {
 	struct ov6650 *priv = to_ov6650(client);
 
+	v4l2_clk_put(priv->clk);
 	v4l2_device_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c
index 713d62e..7f2b3c8 100644
--- a/drivers/media/i2c/soc_camera/ov772x.c
+++ b/drivers/media/i2c/soc_camera/ov772x.c
@@ -26,8 +26,8 @@
 
 #include <media/ov772x.h>
 #include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-subdev.h>
 
 /*
@@ -396,10 +396,10 @@
 struct ov772x_priv {
 	struct v4l2_subdev                subdev;
 	struct v4l2_ctrl_handler	  hdl;
+	struct v4l2_clk			 *clk;
 	struct ov772x_camera_info        *info;
 	const struct ov772x_color_format *cfmt;
 	const struct ov772x_win_size     *win;
-	int                               model;
 	unsigned short                    flag_vflip:1;
 	unsigned short                    flag_hflip:1;
 	/* band_filter = COM8[5] ? 256 - BDBASE : 0 */
@@ -620,17 +620,6 @@
 	return -EINVAL;
 }
 
-static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct ov772x_priv *priv = to_ov772x(sd);
-
-	id->ident    = priv->model;
-	id->revision = 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov772x_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
@@ -668,8 +657,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov772x_priv *priv = to_ov772x(sd);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
@@ -965,11 +955,9 @@
 	switch (VERSION(pid, ver)) {
 	case OV7720:
 		devname     = "ov7720";
-		priv->model = V4L2_IDENT_OV7720;
 		break;
 	case OV7725:
 		devname     = "ov7725";
-		priv->model = V4L2_IDENT_OV7725;
 		break;
 	default:
 		dev_err(&client->dev,
@@ -997,7 +985,6 @@
 };
 
 static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
-	.g_chip_ident	= ov772x_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= ov772x_g_register,
 	.s_register	= ov772x_s_register,
@@ -1088,13 +1075,22 @@
 	if (priv->hdl.error)
 		return priv->hdl.error;
 
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		ret = PTR_ERR(priv->clk);
+		goto eclkget;
+	}
+
 	ret = ov772x_video_probe(priv);
 	if (ret < 0) {
+		v4l2_clk_put(priv->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&priv->hdl);
 	} else {
 		priv->cfmt = &ov772x_cfmts[0];
 		priv->win = &ov772x_win_sizes[0];
 	}
+
 	return ret;
 }
 
@@ -1102,6 +1098,7 @@
 {
 	struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client));
 
+	v4l2_clk_put(priv->clk);
 	v4l2_device_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c
index 20ca62d..e968c3f 100644
--- a/drivers/media/i2c/soc_camera/ov9640.c
+++ b/drivers/media/i2c/soc_camera/ov9640.c
@@ -28,7 +28,7 @@
 #include <linux/videodev2.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 
@@ -61,7 +61,7 @@
 
 /* Configurations
  * NOTE: for YUV, alter the following registers:
- * 		COM12 |= OV9640_COM12_YUV_AVG
+ *		COM12 |= OV9640_COM12_YUV_AVG
  *
  *	 for RGB, alter the following registers:
  *		COM7  |= OV9640_COM7_RGB
@@ -287,18 +287,6 @@
 	return -EINVAL;
 }
 
-/* Get chip identification */
-static int ov9640_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *id)
-{
-	struct ov9640_priv *priv = to_ov9640_sensor(sd);
-
-	id->ident	= priv->model;
-	id->revision	= priv->revision;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ov9640_get_register(struct v4l2_subdev *sd,
 				struct v4l2_dbg_register *reg)
@@ -337,8 +325,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct ov9640_priv *priv = to_ov9640_sensor(sd);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 /* select nearest higher resolution for capture */
@@ -615,12 +604,10 @@
 	switch (VERSION(pid, ver)) {
 	case OV9640_V2:
 		devname		= "ov9640";
-		priv->model	= V4L2_IDENT_OV9640;
 		priv->revision	= 2;
 		break;
 	case OV9640_V3:
 		devname		= "ov9640";
-		priv->model	= V4L2_IDENT_OV9640;
 		priv->revision	= 3;
 		break;
 	default:
@@ -644,7 +631,6 @@
 };
 
 static struct v4l2_subdev_core_ops ov9640_core_ops = {
-	.g_chip_ident		= ov9640_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register		= ov9640_get_register,
 	.s_register		= ov9640_set_register,
@@ -716,10 +702,18 @@
 	if (priv->hdl.error)
 		return priv->hdl.error;
 
-	ret = ov9640_video_probe(client);
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		ret = PTR_ERR(priv->clk);
+		goto eclkget;
+	}
 
-	if (ret)
+	ret = ov9640_video_probe(client);
+	if (ret) {
+		v4l2_clk_put(priv->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&priv->hdl);
+	}
 
 	return ret;
 }
@@ -729,6 +723,7 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct ov9640_priv *priv = to_ov9640_sensor(sd);
 
+	v4l2_clk_put(priv->clk);
 	v4l2_device_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
diff --git a/drivers/media/i2c/soc_camera/ov9640.h b/drivers/media/i2c/soc_camera/ov9640.h
index 6b33a97..65d13ff 100644
--- a/drivers/media/i2c/soc_camera/ov9640.h
+++ b/drivers/media/i2c/soc_camera/ov9640.h
@@ -199,6 +199,7 @@
 struct ov9640_priv {
 	struct v4l2_subdev		subdev;
 	struct v4l2_ctrl_handler	hdl;
+	struct v4l2_clk			*clk;
 
 	int				model;
 	int				revision;
diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c
index 012bd62..ea76863 100644
--- a/drivers/media/i2c/soc_camera/ov9740.c
+++ b/drivers/media/i2c/soc_camera/ov9740.c
@@ -17,7 +17,7 @@
 #include <linux/v4l2-mediabus.h>
 
 #include <media/soc_camera.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-ctrls.h>
 
 #define to_ov9740(sd)		container_of(sd, struct ov9740_priv, subdev)
@@ -196,8 +196,8 @@
 struct ov9740_priv {
 	struct v4l2_subdev		subdev;
 	struct v4l2_ctrl_handler	hdl;
+	struct v4l2_clk			*clk;
 
-	int				ident;
 	u16				model;
 	u8				revision;
 	u8				manid;
@@ -772,18 +772,6 @@
 	return 0;
 }
 
-/* Get chip identification */
-static int ov9740_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct ov9740_priv *priv = to_ov9740(sd);
-
-	id->ident = priv->ident;
-	id->revision = priv->revision;
-
-	return 0;
-}
-
 static int ov9740_s_power(struct v4l2_subdev *sd, int on)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -792,7 +780,7 @@
 	int ret;
 
 	if (on) {
-		ret = soc_camera_power_on(&client->dev, ssdd);
+		ret = soc_camera_power_on(&client->dev, ssdd, priv->clk);
 		if (ret < 0)
 			return ret;
 
@@ -806,7 +794,7 @@
 			priv->current_enable = true;
 		}
 
-		soc_camera_power_off(&client->dev, ssdd);
+		soc_camera_power_off(&client->dev, ssdd, priv->clk);
 	}
 
 	return 0;
@@ -887,8 +875,6 @@
 		goto done;
 	}
 
-	priv->ident = V4L2_IDENT_OV9740;
-
 	dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, "
 		 "Manufacturer 0x%02x, SMIA Version 0x%02x\n",
 		 priv->model, priv->revision, priv->manid, priv->smiaver);
@@ -927,7 +913,6 @@
 };
 
 static struct v4l2_subdev_core_ops ov9740_core_ops = {
-	.g_chip_ident		= ov9740_g_chip_ident,
 	.s_power		= ov9740_s_power,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register		= ov9740_get_register,
@@ -975,9 +960,18 @@
 	if (priv->hdl.error)
 		return priv->hdl.error;
 
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk)) {
+		ret = PTR_ERR(priv->clk);
+		goto eclkget;
+	}
+
 	ret = ov9740_video_probe(client);
-	if (ret < 0)
+	if (ret < 0) {
+		v4l2_clk_put(priv->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&priv->hdl);
+	}
 
 	return ret;
 }
@@ -986,6 +980,7 @@
 {
 	struct ov9740_priv *priv = i2c_get_clientdata(client);
 
+	v4l2_clk_put(priv->clk);
 	v4l2_device_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
 	return 0;
diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
index 1f9ec3b..7e6d978 100644
--- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c
+++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c
@@ -17,8 +17,8 @@
 
 #include <media/rj54n1cb0c.h>
 #include <media/soc_camera.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #define RJ54N1_DEV_CODE			0x0400
@@ -151,6 +151,7 @@
 struct rj54n1 {
 	struct v4l2_subdev subdev;
 	struct v4l2_ctrl_handler hdl;
+	struct v4l2_clk *clk;
 	struct rj54n1_clock_div clk_div;
 	const struct rj54n1_datafmt *fmt;
 	struct v4l2_rect rect;	/* Sensor window */
@@ -1120,37 +1121,16 @@
 	return 0;
 }
 
-static int rj54n1_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	if (id->match.addr != client->addr)
-		return -ENODEV;
-
-	id->ident	= V4L2_IDENT_RJ54N1CB0C;
-	id->revision	= 0;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int rj54n1_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
-	    reg->reg < 0x400 || reg->reg > 0x1fff)
+	if (reg->reg < 0x400 || reg->reg > 0x1fff)
 		/* Registers > 0x0800 are only available from Sharp support */
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	reg->size = 1;
 	reg->val = reg_read(client, reg->reg);
 
@@ -1165,14 +1145,10 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR ||
-	    reg->reg < 0x400 || reg->reg > 0x1fff)
+	if (reg->reg < 0x400 || reg->reg > 0x1fff)
 		/* Registers >= 0x0800 are only available from Sharp support */
 		return -EINVAL;
 
-	if (reg->match.addr != client->addr)
-		return -ENODEV;
-
 	if (reg_write(client, reg->reg, reg->val) < 0)
 		return -EIO;
 
@@ -1184,8 +1160,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct rj54n1 *rj54n1 = to_rj54n1(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, rj54n1->clk, on);
 }
 
 static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -1233,7 +1210,6 @@
 };
 
 static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
-	.g_chip_ident	= rj54n1_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register	= rj54n1_g_register,
 	.s_register	= rj54n1_s_register,
@@ -1382,9 +1358,18 @@
 	rj54n1->tgclk_mhz	= (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
 		(clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
 
+	rj54n1->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(rj54n1->clk)) {
+		ret = PTR_ERR(rj54n1->clk);
+		goto eclkget;
+	}
+
 	ret = rj54n1_video_probe(client, rj54n1_priv);
-	if (ret < 0)
+	if (ret < 0) {
+		v4l2_clk_put(rj54n1->clk);
+eclkget:
 		v4l2_ctrl_handler_free(&rj54n1->hdl);
+	}
 
 	return ret;
 }
@@ -1394,6 +1379,7 @@
 	struct rj54n1 *rj54n1 = to_rj54n1(client);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
 
+	v4l2_clk_put(rj54n1->clk);
 	v4l2_device_unregister_subdev(&rj54n1->subdev);
 	if (ssdd->free_bus)
 		ssdd->free_bus(ssdd);
diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c
index bad90b1..ab54628 100644
--- a/drivers/media/i2c/soc_camera/tw9910.c
+++ b/drivers/media/i2c/soc_camera/tw9910.c
@@ -27,7 +27,7 @@
 
 #include <media/soc_camera.h>
 #include <media/tw9910.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-subdev.h>
 
 #define GET_ID(val)  ((val & 0xF8) >> 3)
@@ -228,6 +228,7 @@
 
 struct tw9910_priv {
 	struct v4l2_subdev		subdev;
+	struct v4l2_clk			*clk;
 	struct tw9910_video_info	*info;
 	const struct tw9910_scale_ctrl	*scale;
 	v4l2_std_id			norm;
@@ -518,18 +519,6 @@
 	return 0;
 }
 
-static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
-			       struct v4l2_dbg_chip_ident *id)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct tw9910_priv *priv = to_tw9910(client);
-
-	id->ident = V4L2_IDENT_TW9910;
-	id->revision = priv->revision;
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int tw9910_g_register(struct v4l2_subdev *sd,
 			     struct v4l2_dbg_register *reg)
@@ -540,6 +529,7 @@
 	if (reg->reg > 0xff)
 		return -EINVAL;
 
+	reg->size = 1;
 	ret = i2c_smbus_read_byte_data(client, reg->reg);
 	if (ret < 0)
 		return ret;
@@ -570,8 +560,9 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client);
+	struct tw9910_priv *priv = to_tw9910(client);
 
-	return soc_camera_set_power(&client->dev, ssdd, on);
+	return soc_camera_set_power(&client->dev, ssdd, priv->clk, on);
 }
 
 static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
@@ -823,7 +814,6 @@
 }
 
 static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
-	.g_chip_ident	= tw9910_g_chip_ident,
 	.s_std		= tw9910_s_std,
 	.g_std		= tw9910_g_std,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -912,6 +902,7 @@
 	struct i2c_adapter		*adapter =
 		to_i2c_adapter(client->dev.parent);
 	struct soc_camera_subdev_desc	*ssdd = soc_camera_i2c_to_desc(client);
+	int ret;
 
 	if (!ssdd || !ssdd->drv_priv) {
 		dev_err(&client->dev, "TW9910: missing platform data!\n");
@@ -935,11 +926,21 @@
 
 	v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
 
-	return tw9910_video_probe(client);
+	priv->clk = v4l2_clk_get(&client->dev, "mclk");
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);
+
+	ret = tw9910_video_probe(client);
+	if (ret < 0)
+		v4l2_clk_put(priv->clk);
+
+	return ret;
 }
 
 static int tw9910_remove(struct i2c_client *client)
 {
+	struct tw9910_priv *priv = to_tw9910(client);
+	v4l2_clk_put(priv->clk);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/sony-btf-mpx.c b/drivers/media/i2c/sony-btf-mpx.c
index 38cbea9..32d8232 100644
--- a/drivers/media/i2c/sony-btf-mpx.c
+++ b/drivers/media/i2c/sony-btf-mpx.c
@@ -30,7 +30,7 @@
 
 static int debug;
 module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on\n");
+MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on");
 
 /* #define MPX_DEBUG */
 
@@ -355,7 +355,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	t = kzalloc(sizeof(struct sony_btf_mpx), GFP_KERNEL);
+	t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
 	if (t == NULL)
 		return -ENOMEM;
 
@@ -374,7 +374,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 
 	return 0;
 }
diff --git a/drivers/media/i2c/sr030pc30.c b/drivers/media/i2c/sr030pc30.c
index e9d95bd..ae94326 100644
--- a/drivers/media/i2c/sr030pc30.c
+++ b/drivers/media/i2c/sr030pc30.c
@@ -23,6 +23,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-mediabus.h>
+#include <media/v4l2-ctrls.h>
 #include <media/sr030pc30.h>
 
 static int debug;
@@ -142,17 +143,24 @@
 
 struct sr030pc30_info {
 	struct v4l2_subdev sd;
+	struct v4l2_ctrl_handler hdl;
 	const struct sr030pc30_platform_data *pdata;
 	const struct sr030pc30_format *curr_fmt;
 	const struct sr030pc30_frmsize *curr_win;
-	unsigned int auto_wb:1;
-	unsigned int auto_exp:1;
 	unsigned int hflip:1;
 	unsigned int vflip:1;
 	unsigned int sleep:1;
-	unsigned int exposure;
-	u8 blue_balance;
-	u8 red_balance;
+	struct {
+		/* auto whitebalance control cluster */
+		struct v4l2_ctrl *awb;
+		struct v4l2_ctrl *red;
+		struct v4l2_ctrl *blue;
+	};
+	struct {
+		/* auto exposure control cluster */
+		struct v4l2_ctrl *autoexp;
+		struct v4l2_ctrl *exp;
+	};
 	u8 i2c_reg_page;
 };
 
@@ -173,52 +181,6 @@
 	u16 val;
 };
 
-static const struct v4l2_queryctrl sr030pc30_ctrl[] = {
-	{
-		.id		= V4L2_CID_AUTO_WHITE_BALANCE,
-		.type		= V4L2_CTRL_TYPE_BOOLEAN,
-		.name		= "Auto White Balance",
-		.minimum	= 0,
-		.maximum	= 1,
-		.step		= 1,
-		.default_value	= 1,
-	}, {
-		.id		= V4L2_CID_RED_BALANCE,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Red Balance",
-		.minimum	= 0,
-		.maximum	= 127,
-		.step		= 1,
-		.default_value	= 64,
-		.flags		= 0,
-	}, {
-		.id		= V4L2_CID_BLUE_BALANCE,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Blue Balance",
-		.minimum	= 0,
-		.maximum	= 127,
-		.step		= 1,
-		.default_value	= 64,
-	}, {
-		.id		= V4L2_CID_EXPOSURE_AUTO,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Auto Exposure",
-		.minimum	= 0,
-		.maximum	= 1,
-		.step		= 1,
-		.default_value	= 1,
-	}, {
-		.id		= V4L2_CID_EXPOSURE,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Exposure",
-		.minimum	= EXPOS_MIN_MS,
-		.maximum	= EXPOS_MAX_MS,
-		.step		= 1,
-		.default_value	= 1,
-	}, {
-	}
-};
-
 /* supported resolutions */
 static const struct sr030pc30_frmsize sr030pc30_sizes[] = {
 	{
@@ -394,48 +356,6 @@
 	return ret;
 }
 
-static inline int sr030pc30_enable_autoexposure(struct v4l2_subdev *sd, int on)
-{
-	struct sr030pc30_info *info = to_sr030pc30(sd);
-	/* auto anti-flicker is also enabled here */
-	int ret = cam_i2c_write(sd, AE_CTL1_REG, on ? 0xDC : 0x0C);
-	if (!ret)
-		info->auto_exp = on;
-	return ret;
-}
-
-static int sr030pc30_set_exposure(struct v4l2_subdev *sd, int value)
-{
-	struct sr030pc30_info *info = to_sr030pc30(sd);
-
-	unsigned long expos = value * info->pdata->clk_rate / (8 * 1000);
-
-	int ret = cam_i2c_write(sd, EXP_TIMEH_REG, expos >> 16 & 0xFF);
-	if (!ret)
-		ret = cam_i2c_write(sd, EXP_TIMEM_REG, expos >> 8 & 0xFF);
-	if (!ret)
-		ret = cam_i2c_write(sd, EXP_TIMEL_REG, expos & 0xFF);
-	if (!ret) { /* Turn off AE */
-		info->exposure = value;
-		ret = sr030pc30_enable_autoexposure(sd, 0);
-	}
-	return ret;
-}
-
-/* Automatic white balance control */
-static int sr030pc30_enable_autowhitebalance(struct v4l2_subdev *sd, int on)
-{
-	struct sr030pc30_info *info = to_sr030pc30(sd);
-
-	int ret = cam_i2c_write(sd, AWB_CTL2_REG, on ? 0x2E : 0x2F);
-	if (!ret)
-		ret = cam_i2c_write(sd, AWB_CTL1_REG, on ? 0xFB : 0x7B);
-	if (!ret)
-		info->auto_wb = on;
-
-	return ret;
-}
-
 static int sr030pc30_set_flip(struct v4l2_subdev *sd)
 {
 	struct sr030pc30_info *info = to_sr030pc30(sd);
@@ -498,107 +418,56 @@
 	return -EINVAL;
 }
 
-static int sr030pc30_queryctrl(struct v4l2_subdev *sd,
-			       struct v4l2_queryctrl *qc)
+static int sr030pc30_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(sr030pc30_ctrl); i++)
-		if (qc->id == sr030pc30_ctrl[i].id) {
-			*qc = sr030pc30_ctrl[i];
-			v4l2_dbg(1, debug, sd, "%s id: %d\n",
-				 __func__, qc->id);
-			return 0;
-		}
-
-	return -EINVAL;
-}
-
-static inline int sr030pc30_set_bluebalance(struct v4l2_subdev *sd, int value)
-{
-	int ret = cam_i2c_write(sd, MWB_BGAIN_REG, value);
-	if (!ret)
-		to_sr030pc30(sd)->blue_balance = value;
-	return ret;
-}
-
-static inline int sr030pc30_set_redbalance(struct v4l2_subdev *sd, int value)
-{
-	int ret = cam_i2c_write(sd, MWB_RGAIN_REG, value);
-	if (!ret)
-		to_sr030pc30(sd)->red_balance = value;
-	return ret;
-}
-
-static int sr030pc30_s_ctrl(struct v4l2_subdev *sd,
-			    struct v4l2_control *ctrl)
-{
-	int i, ret = 0;
-
-	for (i = 0; i < ARRAY_SIZE(sr030pc30_ctrl); i++)
-		if (ctrl->id == sr030pc30_ctrl[i].id)
-			break;
-
-	if (i == ARRAY_SIZE(sr030pc30_ctrl))
-		return -EINVAL;
-
-	if (ctrl->value < sr030pc30_ctrl[i].minimum ||
-		ctrl->value > sr030pc30_ctrl[i].maximum)
-			return -ERANGE;
+	struct sr030pc30_info *info =
+		container_of(ctrl->handler, struct sr030pc30_info, hdl);
+	struct v4l2_subdev *sd = &info->sd;
+	int ret = 0;
 
 	v4l2_dbg(1, debug, sd, "%s: ctrl_id: %d, value: %d\n",
-			 __func__, ctrl->id, ctrl->value);
+			 __func__, ctrl->id, ctrl->val);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUTO_WHITE_BALANCE:
-		sr030pc30_enable_autowhitebalance(sd, ctrl->value);
-		break;
-	case V4L2_CID_BLUE_BALANCE:
-		ret = sr030pc30_set_bluebalance(sd, ctrl->value);
-		break;
-	case V4L2_CID_RED_BALANCE:
-		ret = sr030pc30_set_redbalance(sd, ctrl->value);
-		break;
+		if (ctrl->is_new) {
+			ret = cam_i2c_write(sd, AWB_CTL2_REG,
+					ctrl->val ? 0x2E : 0x2F);
+			if (!ret)
+				ret = cam_i2c_write(sd, AWB_CTL1_REG,
+						ctrl->val ? 0xFB : 0x7B);
+		}
+		if (!ret && info->blue->is_new)
+			ret = cam_i2c_write(sd, MWB_BGAIN_REG, info->blue->val);
+		if (!ret && info->red->is_new)
+			ret = cam_i2c_write(sd, MWB_RGAIN_REG, info->red->val);
+		return ret;
+
 	case V4L2_CID_EXPOSURE_AUTO:
-		sr030pc30_enable_autoexposure(sd,
-			ctrl->value == V4L2_EXPOSURE_AUTO);
-		break;
-	case V4L2_CID_EXPOSURE:
-		ret = sr030pc30_set_exposure(sd, ctrl->value);
-		break;
+		/* auto anti-flicker is also enabled here */
+		if (ctrl->is_new)
+			ret = cam_i2c_write(sd, AE_CTL1_REG,
+				ctrl->val == V4L2_EXPOSURE_AUTO ? 0xDC : 0x0C);
+		if (info->exp->is_new) {
+			unsigned long expos = info->exp->val;
+
+			expos = expos * info->pdata->clk_rate / (8 * 1000);
+
+			if (!ret)
+				ret = cam_i2c_write(sd, EXP_TIMEH_REG,
+						expos >> 16 & 0xFF);
+			if (!ret)
+				ret = cam_i2c_write(sd, EXP_TIMEM_REG,
+						expos >> 8 & 0xFF);
+			if (!ret)
+				ret = cam_i2c_write(sd, EXP_TIMEL_REG,
+						expos & 0xFF);
+		}
+		return ret;
 	default:
 		return -EINVAL;
 	}
 
-	return ret;
-}
-
-static int sr030pc30_g_ctrl(struct v4l2_subdev *sd,
-			    struct v4l2_control *ctrl)
-{
-	struct sr030pc30_info *info = to_sr030pc30(sd);
-
-	v4l2_dbg(1, debug, sd, "%s: id: %d\n", __func__, ctrl->id);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUTO_WHITE_BALANCE:
-		ctrl->value = info->auto_wb;
-		break;
-	case V4L2_CID_BLUE_BALANCE:
-		ctrl->value = info->blue_balance;
-		break;
-	case V4L2_CID_RED_BALANCE:
-		ctrl->value = info->red_balance;
-		break;
-	case V4L2_CID_EXPOSURE_AUTO:
-		ctrl->value = info->auto_exp;
-		break;
-	case V4L2_CID_EXPOSURE:
-		ctrl->value = info->exposure;
-		break;
-	default:
-		return -EINVAL;
-	}
 	return 0;
 }
 
@@ -752,11 +621,19 @@
 	return ret;
 }
 
+static const struct v4l2_ctrl_ops sr030pc30_ctrl_ops = {
+	.s_ctrl = sr030pc30_s_ctrl,
+};
+
 static const struct v4l2_subdev_core_ops sr030pc30_core_ops = {
 	.s_power	= sr030pc30_s_power,
-	.queryctrl	= sr030pc30_queryctrl,
-	.s_ctrl		= sr030pc30_s_ctrl,
-	.g_ctrl		= sr030pc30_g_ctrl,
+	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+	.g_ctrl = v4l2_subdev_g_ctrl,
+	.s_ctrl = v4l2_subdev_s_ctrl,
+	.queryctrl = v4l2_subdev_queryctrl,
+	.querymenu = v4l2_subdev_querymenu,
 };
 
 static const struct v4l2_subdev_video_ops sr030pc30_video_ops = {
@@ -807,6 +684,7 @@
 {
 	struct sr030pc30_info *info;
 	struct v4l2_subdev *sd;
+	struct v4l2_ctrl_handler *hdl;
 	const struct sr030pc30_platform_data *pdata
 		= client->dev.platform_data;
 	int ret;
@@ -820,7 +698,7 @@
 	if (ret)
 		return ret;
 
-	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -830,10 +708,31 @@
 
 	v4l2_i2c_subdev_init(sd, client, &sr030pc30_ops);
 
+	hdl = &info->hdl;
+	v4l2_ctrl_handler_init(hdl, 6);
+	info->awb = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+			V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
+	info->red = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+			V4L2_CID_RED_BALANCE, 0, 127, 1, 64);
+	info->blue = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+			V4L2_CID_BLUE_BALANCE, 0, 127, 1, 64);
+	info->autoexp = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+			V4L2_CID_EXPOSURE_AUTO, 0, 1, 1, 1);
+	info->exp = v4l2_ctrl_new_std(hdl, &sr030pc30_ctrl_ops,
+			V4L2_CID_EXPOSURE, EXPOS_MIN_MS, EXPOS_MAX_MS, 1, 30);
+	sd->ctrl_handler = hdl;
+	if (hdl->error) {
+		int err = hdl->error;
+
+		v4l2_ctrl_handler_free(hdl);
+		return err;
+	}
+	v4l2_ctrl_auto_cluster(3, &info->awb, 0, false);
+	v4l2_ctrl_auto_cluster(2, &info->autoexp, V4L2_EXPOSURE_MANUAL, false);
+	v4l2_ctrl_handler_setup(hdl);
+
 	info->i2c_reg_page	= -1;
 	info->hflip		= 1;
-	info->auto_exp		= 1;
-	info->exposure		= 30;
 
 	return 0;
 }
@@ -841,10 +740,9 @@
 static int sr030pc30_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct sr030pc30_info *info = to_sr030pc30(sd);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(info);
+	v4l2_ctrl_handler_free(sd->ctrl_handler);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/tda7432.c b/drivers/media/i2c/tda7432.c
index 28b5121..72af644 100644
--- a/drivers/media/i2c/tda7432.c
+++ b/drivers/media/i2c/tda7432.c
@@ -359,7 +359,7 @@
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	t = kzalloc(sizeof(*t), GFP_KERNEL);
+	t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
 	if (!t)
 		return -ENOMEM;
 	sd = &t->sd;
@@ -380,7 +380,6 @@
 		int err = t->hdl.error;
 
 		v4l2_ctrl_handler_free(&t->hdl);
-		kfree(t);
 		return err;
 	}
 	v4l2_ctrl_cluster(2, &t->bass);
@@ -406,7 +405,6 @@
 	tda7432_set(sd);
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&t->hdl);
-	kfree(t);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/tda9840.c b/drivers/media/i2c/tda9840.c
index 01441e3..fbdff8b 100644
--- a/drivers/media/i2c/tda9840.c
+++ b/drivers/media/i2c/tda9840.c
@@ -31,7 +31,6 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
 MODULE_DESCRIPTION("tda9840 driver");
@@ -145,26 +144,14 @@
 	return 0;
 }
 
-static int tda9840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TDA9840, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
-static const struct v4l2_subdev_core_ops tda9840_core_ops = {
-	.g_chip_ident = tda9840_g_chip_ident,
-};
-
 static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = {
 	.s_tuner = tda9840_s_tuner,
 	.g_tuner = tda9840_g_tuner,
 };
 
 static const struct v4l2_subdev_ops tda9840_ops = {
-	.core = &tda9840_core_ops,
 	.tuner = &tda9840_tuner_ops,
 };
 
@@ -184,7 +171,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
 	if (sd == NULL)
 		return -ENOMEM;
 	v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
@@ -201,7 +188,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(sd);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/tea6415c.c b/drivers/media/i2c/tea6415c.c
index 3d5b06a..bbe1a99 100644
--- a/drivers/media/i2c/tea6415c.c
+++ b/drivers/media/i2c/tea6415c.c
@@ -33,7 +33,6 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include "tea6415c.h"
 
 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -119,25 +118,13 @@
 	return ret;
 }
 
-static int tea6415c_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6415C, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
-static const struct v4l2_subdev_core_ops tea6415c_core_ops = {
-	.g_chip_ident = tea6415c_g_chip_ident,
-};
-
 static const struct v4l2_subdev_video_ops tea6415c_video_ops = {
 	.s_routing = tea6415c_s_routing,
 };
 
 static const struct v4l2_subdev_ops tea6415c_ops = {
-	.core = &tea6415c_core_ops,
 	.video = &tea6415c_video_ops,
 };
 
@@ -152,7 +139,7 @@
 
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
-	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
 	if (sd == NULL)
 		return -ENOMEM;
 	v4l2_i2c_subdev_init(sd, client, &tea6415c_ops);
@@ -164,7 +151,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(sd);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/tea6420.c b/drivers/media/i2c/tea6420.c
index 3875721..30a8d75 100644
--- a/drivers/media/i2c/tea6420.c
+++ b/drivers/media/i2c/tea6420.c
@@ -33,7 +33,6 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include "tea6420.h"
 
 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -90,25 +89,13 @@
 	return 0;
 }
 
-static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
-static const struct v4l2_subdev_core_ops tea6420_core_ops = {
-	.g_chip_ident = tea6420_g_chip_ident,
-};
-
 static const struct v4l2_subdev_audio_ops tea6420_audio_ops = {
 	.s_routing = tea6420_s_routing,
 };
 
 static const struct v4l2_subdev_ops tea6420_ops = {
-	.core = &tea6420_core_ops,
 	.audio = &tea6420_audio_ops,
 };
 
@@ -125,7 +112,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
 	if (sd == NULL)
 		return -ENOMEM;
 	v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
@@ -146,7 +133,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(sd);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c
index c433955..0a2dacb 100644
--- a/drivers/media/i2c/ths7303.c
+++ b/drivers/media/i2c/ths7303.c
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 
 #include <media/ths7303.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-device.h>
 
 #define THS7303_CHANNEL_1	1
@@ -35,11 +34,10 @@
 
 struct ths7303_state {
 	struct v4l2_subdev		sd;
-	struct ths7303_platform_data	pdata;
+	const struct ths7303_platform_data *pdata;
 	struct v4l2_bt_timings		bt;
 	int std_id;
 	int stream_on;
-	int driver_data;
 };
 
 enum ths7303_filter_mode {
@@ -89,7 +87,7 @@
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct ths7303_state *state = to_state(sd);
-	struct ths7303_platform_data *pdata = &state->pdata;
+	const struct ths7303_platform_data *pdata = state->pdata;
 	u8 val, sel = 0;
 	int err, disable = 0;
 
@@ -212,15 +210,6 @@
 	return ths7303_config(sd);
 }
 
-static int ths7303_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct ths7303_state *state = to_state(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, state->driver_data, 0);
-}
-
 static const struct v4l2_subdev_video_ops ths7303_video_ops = {
 	.s_stream	= ths7303_s_stream,
 	.s_std_output	= ths7303_s_std_output,
@@ -232,13 +221,6 @@
 static int ths7303_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	reg->size = 1;
 	reg->val = ths7303_read(sd, reg->reg);
 	return 0;
@@ -247,13 +229,6 @@
 static int ths7303_s_register(struct v4l2_subdev *sd,
 			      const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	ths7303_write(sd, reg->reg, reg->val);
 	return 0;
 }
@@ -340,7 +315,6 @@
 }
 
 static const struct v4l2_subdev_core_ops ths7303_core_ops = {
-	.g_chip_ident = ths7303_g_chip_ident,
 	.log_status = ths7303_log_status,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = ths7303_g_register,
@@ -353,32 +327,6 @@
 	.video 	= &ths7303_video_ops,
 };
 
-static int ths7303_setup(struct v4l2_subdev *sd)
-{
-	struct ths7303_state *state = to_state(sd);
-	struct ths7303_platform_data *pdata = &state->pdata;
-	int ret;
-	u8 mask;
-
-	state->stream_on = pdata->init_enable;
-
-	mask = state->stream_on ? 0xff : 0xf8;
-
-	ret = ths7303_write(sd, THS7303_CHANNEL_1, pdata->ch_1 & mask);
-	if (ret)
-		return ret;
-
-	ret = ths7303_write(sd, THS7303_CHANNEL_2, pdata->ch_2 & mask);
-	if (ret)
-		return ret;
-
-	ret = ths7303_write(sd, THS7303_CHANNEL_3, pdata->ch_3 & mask);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
 static int ths7303_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -386,6 +334,11 @@
 	struct ths7303_state *state;
 	struct v4l2_subdev *sd;
 
+	if (pdata == NULL) {
+		dev_err(&client->dev, "No platform data\n");
+		return -EINVAL;
+	}
+
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
@@ -397,20 +350,14 @@
 	if (!state)
 		return -ENOMEM;
 
-	if (!pdata)
-		v4l_warn(client, "No platform data, using default data!\n");
-	else
-		state->pdata = *pdata;
-
+	state->pdata = pdata;
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
 
-	/* store the driver data to differntiate the chip */
-	state->driver_data = (int)id->driver_data;
-
-	if (ths7303_setup(sd) < 0) {
-		v4l_err(client, "init failed\n");
-		return -EIO;
+	/* set to default 480I_576I filter mode */
+	if (ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I) < 0) {
+		v4l_err(client, "Setting to 480I_576I filter mode failed!\n");
+		return -EINVAL;
 	}
 
 	return 0;
@@ -426,8 +373,8 @@
 }
 
 static const struct i2c_device_id ths7303_id[] = {
-	{"ths7303", V4L2_IDENT_THS7303},
-	{"ths7353", V4L2_IDENT_THS7353},
+	{"ths7303", 0},
+	{"ths7353", 0},
 	{},
 };
 
diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c
new file mode 100644
index 0000000..a24f90c
--- /dev/null
+++ b/drivers/media/i2c/ths8200.c
@@ -0,0 +1,556 @@
+/*
+ * ths8200 - Texas Instruments THS8200 video encoder driver
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates.
+ *
+ * This program is free software; you may 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 free software; 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/i2c.h>
+#include <linux/module.h>
+#include <linux/v4l2-dv-timings.h>
+
+#include <media/v4l2-device.h>
+
+#include "ths8200_regs.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+
+MODULE_DESCRIPTION("Texas Instruments THS8200 video encoder driver");
+MODULE_AUTHOR("Mats Randgaard <mats.randgaard@cisco.com>");
+MODULE_AUTHOR("Martin Bugge <martin.bugge@cisco.com>");
+MODULE_LICENSE("GPL v2");
+
+struct ths8200_state {
+	struct v4l2_subdev sd;
+	uint8_t chip_version;
+	/* Is the ths8200 powered on? */
+	bool power_on;
+	struct v4l2_dv_timings dv_timings;
+};
+
+static const struct v4l2_dv_timings ths8200_timings[] = {
+	V4L2_DV_BT_CEA_720X480P59_94,
+	V4L2_DV_BT_CEA_1280X720P24,
+	V4L2_DV_BT_CEA_1280X720P25,
+	V4L2_DV_BT_CEA_1280X720P30,
+	V4L2_DV_BT_CEA_1280X720P50,
+	V4L2_DV_BT_CEA_1280X720P60,
+	V4L2_DV_BT_CEA_1920X1080P24,
+	V4L2_DV_BT_CEA_1920X1080P25,
+	V4L2_DV_BT_CEA_1920X1080P30,
+	V4L2_DV_BT_CEA_1920X1080P50,
+	V4L2_DV_BT_CEA_1920X1080P60,
+};
+
+static inline struct ths8200_state *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct ths8200_state, sd);
+}
+
+static inline unsigned hblanking(const struct v4l2_bt_timings *t)
+{
+	return t->hfrontporch + t->hsync + t->hbackporch;
+}
+
+static inline unsigned htotal(const struct v4l2_bt_timings *t)
+{
+	return t->width + t->hfrontporch + t->hsync + t->hbackporch;
+}
+
+static inline unsigned vblanking(const struct v4l2_bt_timings *t)
+{
+	return t->vfrontporch + t->vsync + t->vbackporch;
+}
+
+static inline unsigned vtotal(const struct v4l2_bt_timings *t)
+{
+	return t->height + t->vfrontporch + t->vsync + t->vbackporch;
+}
+
+static int ths8200_read(struct v4l2_subdev *sd, u8 reg)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int ths8200_write(struct v4l2_subdev *sd, u8 reg, u8 val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret;
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		ret = i2c_smbus_write_byte_data(client, reg, val);
+		if (ret == 0)
+			return 0;
+	}
+	v4l2_err(sd, "I2C Write Problem\n");
+	return ret;
+}
+
+/* To set specific bits in the register, a clear-mask is given (to be AND-ed),
+ * and then the value-mask (to be OR-ed).
+ */
+static inline void
+ths8200_write_and_or(struct v4l2_subdev *sd, u8 reg,
+		     uint8_t clr_mask, uint8_t val_mask)
+{
+	ths8200_write(sd, reg, (ths8200_read(sd, reg) & clr_mask) | val_mask);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+static int ths8200_g_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
+{
+	reg->val = ths8200_read(sd, reg->reg & 0xff);
+	reg->size = 1;
+
+	return 0;
+}
+
+static int ths8200_s_register(struct v4l2_subdev *sd,
+			      const struct v4l2_dbg_register *reg)
+{
+	ths8200_write(sd, reg->reg & 0xff, reg->val & 0xff);
+
+	return 0;
+}
+#endif
+
+static void ths8200_print_timings(struct v4l2_subdev *sd,
+				  struct v4l2_dv_timings *timings,
+				  const char *txt, bool detailed)
+{
+	struct v4l2_bt_timings *bt = &timings->bt;
+	u32 htot, vtot;
+
+	if (timings->type != V4L2_DV_BT_656_1120)
+		return;
+
+	htot = htotal(bt);
+	vtot = vtotal(bt);
+
+	v4l2_info(sd, "%s %dx%d%s%d (%dx%d)",
+		  txt, bt->width, bt->height, bt->interlaced ? "i" : "p",
+		  (htot * vtot) > 0 ? ((u32)bt->pixelclock / (htot * vtot)) : 0,
+		  htot, vtot);
+
+	if (detailed) {
+		v4l2_info(sd, "    horizontal: fp = %d, %ssync = %d, bp = %d\n",
+			  bt->hfrontporch,
+			  (bt->polarities & V4L2_DV_HSYNC_POS_POL) ? "+" : "-",
+			  bt->hsync, bt->hbackporch);
+		v4l2_info(sd, "    vertical: fp = %d, %ssync = %d, bp = %d\n",
+			  bt->vfrontporch,
+			  (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-",
+			  bt->vsync, bt->vbackporch);
+		v4l2_info(sd,
+			  "    pixelclock: %lld, flags: 0x%x, standards: 0x%x\n",
+			  bt->pixelclock, bt->flags, bt->standards);
+	}
+}
+
+static int ths8200_log_status(struct v4l2_subdev *sd)
+{
+	struct ths8200_state *state = to_state(sd);
+	uint8_t reg_03 = ths8200_read(sd, THS8200_CHIP_CTL);
+
+	v4l2_info(sd, "----- Chip status -----\n");
+	v4l2_info(sd, "version: %u\n", state->chip_version);
+	v4l2_info(sd, "power: %s\n", (reg_03 & 0x0c) ? "off" : "on");
+	v4l2_info(sd, "reset: %s\n", (reg_03 & 0x01) ? "off" : "on");
+	v4l2_info(sd, "test pattern: %s\n",
+		  (reg_03 & 0x20) ? "enabled" : "disabled");
+	v4l2_info(sd, "format: %ux%u\n",
+		  ths8200_read(sd, THS8200_DTG2_PIXEL_CNT_MSB) * 256 +
+		  ths8200_read(sd, THS8200_DTG2_PIXEL_CNT_LSB),
+		  (ths8200_read(sd, THS8200_DTG2_LINE_CNT_MSB) & 0x07) * 256 +
+		  ths8200_read(sd, THS8200_DTG2_LINE_CNT_LSB));
+	ths8200_print_timings(sd, &state->dv_timings,
+			      "Configured format:", true);
+
+	return 0;
+}
+
+/* Power up/down ths8200 */
+static int ths8200_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct ths8200_state *state = to_state(sd);
+
+	v4l2_dbg(1, debug, sd, "%s: power %s\n", __func__, on ? "on" : "off");
+
+	state->power_on = on;
+
+	/* Power up/down - leave in reset state until input video is present */
+	ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0xf2, (on ? 0x00 : 0x0c));
+
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops ths8200_core_ops = {
+	.log_status = ths8200_log_status,
+	.s_power = ths8200_s_power,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = ths8200_g_register,
+	.s_register = ths8200_s_register,
+#endif
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev video operations
+ */
+
+static int ths8200_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct ths8200_state *state = to_state(sd);
+
+	if (enable && !state->power_on)
+		ths8200_s_power(sd, true);
+
+	ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0xfe,
+			     (enable ? 0x01 : 0x00));
+
+	v4l2_dbg(1, debug, sd, "%s: %sable\n",
+		 __func__, (enable ? "en" : "dis"));
+
+	return 0;
+}
+
+static void ths8200_core_init(struct v4l2_subdev *sd)
+{
+	/* setup clocks */
+	ths8200_write_and_or(sd, THS8200_CHIP_CTL, 0x3f, 0xc0);
+
+	/**** Data path control (DATA) ****/
+	/* Set FSADJ 700 mV,
+	 * bypass 422-444 interpolation,
+	 * input format 30 bit RGB444
+	 */
+	ths8200_write(sd, THS8200_DATA_CNTL, 0x70);
+
+	/* DTG Mode (Video blocked during blanking
+	 * VESA slave
+	 */
+	ths8200_write(sd, THS8200_DTG1_MODE, 0x87);
+
+	/**** Display Timing Generator Control, Part 1 (DTG1). ****/
+
+	/* Disable embedded syncs on the output by setting
+	 * the amplitude to zero for all channels.
+	 */
+	ths8200_write(sd, THS8200_DTG1_Y_SYNC_MSB, 0x2a);
+	ths8200_write(sd, THS8200_DTG1_CBCR_SYNC_MSB, 0x2a);
+}
+
+static void ths8200_setup(struct v4l2_subdev *sd, struct v4l2_bt_timings *bt)
+{
+	uint8_t polarity = 0;
+	uint16_t line_start_active_video = (bt->vsync + bt->vbackporch);
+	uint16_t line_start_front_porch  = (vtotal(bt) - bt->vfrontporch);
+
+	/*** System ****/
+	/* Set chip in reset while it is configured */
+	ths8200_s_stream(sd, false);
+
+	/* configure video output timings */
+	ths8200_write(sd, THS8200_DTG1_SPEC_A, bt->hsync);
+	ths8200_write(sd, THS8200_DTG1_SPEC_B, bt->hfrontporch);
+
+	/* Zero for progressive scan formats.*/
+	if (!bt->interlaced)
+		ths8200_write(sd, THS8200_DTG1_SPEC_C, 0x00);
+
+	/* Distance from leading edge of h sync to start of active video.
+	 * MSB in 0x2b
+	 */
+	ths8200_write(sd, THS8200_DTG1_SPEC_D_LSB,
+		      (bt->hbackporch + bt->hsync) & 0xff);
+	/* Zero for SDTV-mode. MSB in 0x2b */
+	ths8200_write(sd, THS8200_DTG1_SPEC_E_LSB, 0x00);
+	/*
+	 * MSB for dtg1_spec(d/e/h). See comment for
+	 * corresponding LSB registers.
+	 */
+	ths8200_write(sd, THS8200_DTG1_SPEC_DEH_MSB,
+		      ((bt->hbackporch + bt->hsync) & 0x100) >> 1);
+
+	/* h front porch */
+	ths8200_write(sd, THS8200_DTG1_SPEC_K_LSB, (bt->hfrontporch) & 0xff);
+	ths8200_write(sd, THS8200_DTG1_SPEC_K_MSB,
+		      ((bt->hfrontporch) & 0x700) >> 8);
+
+	/* Half the line length. Used to calculate SDTV line types. */
+	ths8200_write(sd, THS8200_DTG1_SPEC_G_LSB, (htotal(bt)/2) & 0xff);
+	ths8200_write(sd, THS8200_DTG1_SPEC_G_MSB,
+		      ((htotal(bt)/2) >> 8) & 0x0f);
+
+	/* Total pixels per line (ex. 720p: 1650) */
+	ths8200_write(sd, THS8200_DTG1_TOT_PIXELS_MSB, htotal(bt) >> 8);
+	ths8200_write(sd, THS8200_DTG1_TOT_PIXELS_LSB, htotal(bt) & 0xff);
+
+	/* Frame height and field height */
+	/* Field height should be programmed higher than frame_size for
+	 * progressive scan formats
+	 */
+	ths8200_write(sd, THS8200_DTG1_FRAME_FIELD_SZ_MSB,
+		      ((vtotal(bt) >> 4) & 0xf0) + 0x7);
+	ths8200_write(sd, THS8200_DTG1_FRAME_SZ_LSB, vtotal(bt) & 0xff);
+
+	/* Should be programmed higher than frame_size
+	 * for progressive formats
+	 */
+	if (!bt->interlaced)
+		ths8200_write(sd, THS8200_DTG1_FIELD_SZ_LSB, 0xff);
+
+	/**** Display Timing Generator Control, Part 2 (DTG2). ****/
+	/* Set breakpoint line numbers and types
+	 * THS8200 generates line types with different properties. A line type
+	 * that sets all the RGB-outputs to zero is used in the blanking areas,
+	 * while a line type that enable the RGB-outputs is used in active video
+	 * area. The line numbers for start of active video, start of front
+	 * porch and after the last line in the frame must be set with the
+	 * corresponding line types.
+	 *
+	 * Line types:
+	 * 0x9 - Full normal sync pulse: Blocks data when dtg1_pass is off.
+	 *       Used in blanking area.
+	 * 0x0 - Active video: Video data is always passed. Used in active
+	 *       video area.
+	 */
+	ths8200_write_and_or(sd, THS8200_DTG2_BP1_2_MSB, 0x88,
+			     ((line_start_active_video >> 4) & 0x70) +
+			     ((line_start_front_porch >> 8) & 0x07));
+	ths8200_write(sd, THS8200_DTG2_BP3_4_MSB, ((vtotal(bt)) >> 4) & 0x70);
+	ths8200_write(sd, THS8200_DTG2_BP1_LSB, line_start_active_video & 0xff);
+	ths8200_write(sd, THS8200_DTG2_BP2_LSB, line_start_front_porch & 0xff);
+	ths8200_write(sd, THS8200_DTG2_BP3_LSB, (vtotal(bt)) & 0xff);
+
+	/* line types */
+	ths8200_write(sd, THS8200_DTG2_LINETYPE1, 0x90);
+	ths8200_write(sd, THS8200_DTG2_LINETYPE2, 0x90);
+
+	/* h sync width transmitted */
+	ths8200_write(sd, THS8200_DTG2_HLENGTH_LSB, bt->hsync & 0xff);
+	ths8200_write_and_or(sd, THS8200_DTG2_HLENGTH_LSB_HDLY_MSB, 0x3f,
+			     (bt->hsync >> 2) & 0xc0);
+
+	/* The pixel value h sync is asserted on */
+	ths8200_write_and_or(sd, THS8200_DTG2_HLENGTH_LSB_HDLY_MSB, 0xe0,
+			     (htotal(bt) >> 8) & 0x1f);
+	ths8200_write(sd, THS8200_DTG2_HLENGTH_HDLY_LSB, htotal(bt));
+
+	/* v sync width transmitted */
+	ths8200_write(sd, THS8200_DTG2_VLENGTH1_LSB, (bt->vsync) & 0xff);
+	ths8200_write_and_or(sd, THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB, 0x3f,
+			     ((bt->vsync) >> 2) & 0xc0);
+
+	/* The pixel value v sync is asserted on */
+	ths8200_write_and_or(sd, THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB, 0xf8,
+			     (vtotal(bt)>>8) & 0x7);
+	ths8200_write(sd, THS8200_DTG2_VDLY1_LSB, vtotal(bt));
+
+	/* For progressive video vlength2 must be set to all 0 and vdly2 must
+	 * be set to all 1.
+	 */
+	ths8200_write(sd, THS8200_DTG2_VLENGTH2_LSB, 0x00);
+	ths8200_write(sd, THS8200_DTG2_VLENGTH2_MSB_VDLY2_MSB, 0x07);
+	ths8200_write(sd, THS8200_DTG2_VDLY2_LSB, 0xff);
+
+	/* Internal delay factors to synchronize the sync pulses and the data */
+	/* Experimental values delays (hor 4, ver 1) */
+	ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_MSB, (htotal(bt)>>8) & 0x1f);
+	ths8200_write(sd, THS8200_DTG2_HS_IN_DLY_LSB, (htotal(bt) - 4) & 0xff);
+	ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_MSB, 0);
+	ths8200_write(sd, THS8200_DTG2_VS_IN_DLY_LSB, 1);
+
+	/* Polarity of received and transmitted sync signals */
+	if (bt->polarities & V4L2_DV_HSYNC_POS_POL) {
+		polarity |= 0x01; /* HS_IN */
+		polarity |= 0x08; /* HS_OUT */
+	}
+	if (bt->polarities & V4L2_DV_VSYNC_POS_POL) {
+		polarity |= 0x02; /* VS_IN */
+		polarity |= 0x10; /* VS_OUT */
+	}
+
+	/* RGB mode, no embedded timings */
+	/* Timing of video input bus is derived from HS, VS, and FID dedicated
+	 * inputs
+	 */
+	ths8200_write(sd, THS8200_DTG2_CNTL, 0x47 | polarity);
+
+	/* leave reset */
+	ths8200_s_stream(sd, true);
+
+	v4l2_dbg(1, debug, sd, "%s: frame %dx%d, polarity %d\n"
+		 "horizontal: front porch %d, back porch %d, sync %d\n"
+		 "vertical: sync %d\n", __func__, htotal(bt), vtotal(bt),
+		 polarity, bt->hfrontporch, bt->hbackporch,
+		 bt->hsync, bt->vsync);
+}
+
+static int ths8200_s_dv_timings(struct v4l2_subdev *sd,
+				struct v4l2_dv_timings *timings)
+{
+	struct ths8200_state *state = to_state(sd);
+	int i;
+
+	v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+
+	if (timings->type != V4L2_DV_BT_656_1120)
+		return -EINVAL;
+
+	/* TODO Support interlaced formats */
+	if (timings->bt.interlaced) {
+		v4l2_dbg(1, debug, sd, "TODO Support interlaced formats\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ths8200_timings); i++) {
+		if (v4l_match_dv_timings(&ths8200_timings[i], timings, 10))
+			break;
+	}
+
+	if (i == ARRAY_SIZE(ths8200_timings)) {
+		v4l2_dbg(1, debug, sd, "Unsupported format\n");
+		return -EINVAL;
+	}
+
+	timings->bt.flags &= ~V4L2_DV_FL_REDUCED_FPS;
+
+	/* save timings */
+	state->dv_timings = *timings;
+
+	ths8200_setup(sd, &timings->bt);
+
+	return 0;
+}
+
+static int ths8200_g_dv_timings(struct v4l2_subdev *sd,
+				struct v4l2_dv_timings *timings)
+{
+	struct ths8200_state *state = to_state(sd);
+
+	v4l2_dbg(1, debug, sd, "%s:\n", __func__);
+
+	*timings = state->dv_timings;
+
+	return 0;
+}
+
+static int ths8200_enum_dv_timings(struct v4l2_subdev *sd,
+				   struct v4l2_enum_dv_timings *timings)
+{
+	/* Check requested format index is within range */
+	if (timings->index >= ARRAY_SIZE(ths8200_timings))
+		return -EINVAL;
+
+	timings->timings = ths8200_timings[timings->index];
+
+	return 0;
+}
+
+static int ths8200_dv_timings_cap(struct v4l2_subdev *sd,
+				  struct v4l2_dv_timings_cap *cap)
+{
+	cap->type = V4L2_DV_BT_656_1120;
+	cap->bt.max_width = 1920;
+	cap->bt.max_height = 1080;
+	cap->bt.min_pixelclock = 27000000;
+	cap->bt.max_pixelclock = 148500000;
+	cap->bt.standards = V4L2_DV_BT_STD_CEA861;
+	cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE;
+
+	return 0;
+}
+
+/* Specific video subsystem operation handlers */
+static const struct v4l2_subdev_video_ops ths8200_video_ops = {
+	.s_stream = ths8200_s_stream,
+	.s_dv_timings = ths8200_s_dv_timings,
+	.g_dv_timings = ths8200_g_dv_timings,
+	.enum_dv_timings = ths8200_enum_dv_timings,
+	.dv_timings_cap = ths8200_dv_timings_cap,
+};
+
+/* V4L2 top level operation handlers */
+static const struct v4l2_subdev_ops ths8200_ops = {
+	.core  = &ths8200_core_ops,
+	.video = &ths8200_video_ops,
+};
+
+static int ths8200_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct ths8200_state *state;
+	struct v4l2_subdev *sd;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	sd = &state->sd;
+	v4l2_i2c_subdev_init(sd, client, &ths8200_ops);
+
+	state->chip_version = ths8200_read(sd, THS8200_VERSION);
+	v4l2_dbg(1, debug, sd, "chip version 0x%x\n", state->chip_version);
+
+	ths8200_core_init(sd);
+
+	v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
+		  client->addr << 1, client->adapter->name);
+
+	return 0;
+}
+
+static int ths8200_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_dbg(1, debug, sd, "%s removed @ 0x%x (%s)\n", client->name,
+		 client->addr << 1, client->adapter->name);
+
+	ths8200_s_power(sd, false);
+
+	v4l2_device_unregister_subdev(sd);
+
+	return 0;
+}
+
+static struct i2c_device_id ths8200_id[] = {
+	{ "ths8200", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, ths8200_id);
+
+static struct i2c_driver ths8200_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "ths8200",
+	},
+	.probe = ths8200_probe,
+	.remove = ths8200_remove,
+	.id_table = ths8200_id,
+};
+
+module_i2c_driver(ths8200_driver);
diff --git a/drivers/media/i2c/ths8200_regs.h b/drivers/media/i2c/ths8200_regs.h
new file mode 100644
index 0000000..6bc9fd1
--- /dev/null
+++ b/drivers/media/i2c/ths8200_regs.h
@@ -0,0 +1,161 @@
+/*
+ * ths8200 - Texas Instruments THS8200 video encoder driver
+ *
+ * Copyright 2013 Cisco Systems, Inc. and/or its affiliates.
+ *
+ * This program is free software; you may 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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef THS8200_REGS_H
+#define THS8200_REGS_H
+
+/* Register offset macros */
+#define THS8200_VERSION				0x02
+#define THS8200_CHIP_CTL			0x03
+#define THS8200_CSC_R11				0x04
+#define THS8200_CSC_R12				0x05
+#define THS8200_CSC_R21				0x06
+#define THS8200_CSC_R22				0x07
+#define THS8200_CSC_R31				0x08
+#define THS8200_CSC_R32				0x09
+#define THS8200_CSC_G11				0x0a
+#define THS8200_CSC_G12				0x0b
+#define THS8200_CSC_G21				0x0c
+#define THS8200_CSC_G22				0x0d
+#define THS8200_CSC_G31				0x0e
+#define THS8200_CSC_G32				0x0f
+#define THS8200_CSC_B11				0x10
+#define THS8200_CSC_B12				0x11
+#define THS8200_CSC_B21				0x12
+#define THS8200_CSC_B22				0x13
+#define THS8200_CSC_B31				0x14
+#define THS8200_CSC_B32				0x15
+#define THS8200_CSC_OFFS1			0x16
+#define THS8200_CSC_OFFS12			0x17
+#define THS8200_CSC_OFFS23			0x18
+#define THS8200_CSC_OFFS3			0x19
+#define THS8200_TST_CNTL1			0x1a
+#define THS8200_TST_CNTL2			0x1b
+#define THS8200_DATA_CNTL			0x1c
+#define THS8200_DTG1_Y_SYNC1_LSB		0x1d
+#define THS8200_DTG1_Y_SYNC2_LSB		0x1e
+#define THS8200_DTG1_Y_SYNC3_LSB		0x1f
+#define THS8200_DTG1_CBCR_SYNC1_LSB		0x20
+#define THS8200_DTG1_CBCR_SYNC2_LSB		0x21
+#define THS8200_DTG1_CBCR_SYNC3_LSB		0x22
+#define THS8200_DTG1_Y_SYNC_MSB			0x23
+#define THS8200_DTG1_CBCR_SYNC_MSB		0x24
+#define THS8200_DTG1_SPEC_A			0x25
+#define THS8200_DTG1_SPEC_B			0x26
+#define THS8200_DTG1_SPEC_C			0x27
+#define THS8200_DTG1_SPEC_D_LSB			0x28
+#define THS8200_DTG1_SPEC_D1			0x29
+#define THS8200_DTG1_SPEC_E_LSB			0x2a
+#define THS8200_DTG1_SPEC_DEH_MSB		0x2b
+#define THS8200_DTG1_SPEC_H_LSB			0x2c
+#define THS8200_DTG1_SPEC_I_MSB			0x2d
+#define THS8200_DTG1_SPEC_I_LSB			0x2e
+#define THS8200_DTG1_SPEC_K_LSB			0x2f
+#define THS8200_DTG1_SPEC_K_MSB			0x30
+#define THS8200_DTG1_SPEC_K1			0x31
+#define THS8200_DTG1_SPEC_G_LSB			0x32
+#define THS8200_DTG1_SPEC_G_MSB			0x33
+#define THS8200_DTG1_TOT_PIXELS_MSB		0x34
+#define THS8200_DTG1_TOT_PIXELS_LSB		0x35
+#define THS8200_DTG1_FLD_FLIP_LINECNT_MSB	0x36
+#define THS8200_DTG1_LINECNT_LSB		0x37
+#define THS8200_DTG1_MODE			0x38
+#define THS8200_DTG1_FRAME_FIELD_SZ_MSB		0x39
+#define THS8200_DTG1_FRAME_SZ_LSB		0x3a
+#define THS8200_DTG1_FIELD_SZ_LSB		0x3b
+#define THS8200_DTG1_VESA_CBAR_SIZE		0x3c
+#define THS8200_DAC_CNTL_MSB			0x3d
+#define THS8200_DAC1_CNTL_LSB			0x3e
+#define THS8200_DAC2_CNTL_LSB			0x3f
+#define THS8200_DAC3_CNTL_LSB			0x40
+#define THS8200_CSM_CLIP_GY_LOW			0x41
+#define THS8200_CSM_CLIP_BCB_LOW		0x42
+#define THS8200_CSM_CLIP_RCR_LOW		0x43
+#define THS8200_CSM_CLIP_GY_HIGH		0x44
+#define THS8200_CSM_CLIP_BCB_HIGH		0x45
+#define THS8200_CSM_CLIP_RCR_HIGH		0x46
+#define THS8200_CSM_SHIFT_GY			0x47
+#define THS8200_CSM_SHIFT_BCB			0x48
+#define THS8200_CSM_SHIFT_RCR			0x49
+#define THS8200_CSM_GY_CNTL_MULT_MSB		0x4a
+#define THS8200_CSM_MULT_BCB_RCR_MSB		0x4b
+#define THS8200_CSM_MULT_GY_LSB			0x4c
+#define THS8200_CSM_MULT_BCB_LSB		0x4d
+#define THS8200_CSM_MULT_RCR_LSB		0x4e
+#define THS8200_CSM_MULT_RCR_BCB_CNTL		0x4f
+#define THS8200_CSM_MULT_RCR_LSB		0x4e
+#define THS8200_DTG2_BP1_2_MSB			0x50
+#define THS8200_DTG2_BP3_4_MSB			0x51
+#define THS8200_DTG2_BP5_6_MSB			0x52
+#define THS8200_DTG2_BP7_8_MSB			0x53
+#define THS8200_DTG2_BP9_10_MSB			0x54
+#define THS8200_DTG2_BP11_12_MSB		0x55
+#define THS8200_DTG2_BP13_14_MSB		0x56
+#define THS8200_DTG2_BP15_16_MSB		0x57
+#define THS8200_DTG2_BP1_LSB			0x58
+#define THS8200_DTG2_BP2_LSB			0x59
+#define THS8200_DTG2_BP3_LSB			0x5a
+#define THS8200_DTG2_BP4_LSB			0x5b
+#define THS8200_DTG2_BP5_LSB			0x5c
+#define THS8200_DTG2_BP6_LSB			0x5d
+#define THS8200_DTG2_BP7_LSB			0x5e
+#define THS8200_DTG2_BP8_LSB			0x5f
+#define THS8200_DTG2_BP9_LSB			0x60
+#define THS8200_DTG2_BP10_LSB			0x61
+#define THS8200_DTG2_BP11_LSB			0x62
+#define THS8200_DTG2_BP12_LSB			0x63
+#define THS8200_DTG2_BP13_LSB			0x64
+#define THS8200_DTG2_BP14_LSB			0x65
+#define THS8200_DTG2_BP15_LSB			0x66
+#define THS8200_DTG2_BP16_LSB			0x67
+#define THS8200_DTG2_LINETYPE1			0x68
+#define THS8200_DTG2_LINETYPE2			0x69
+#define THS8200_DTG2_LINETYPE3			0x6a
+#define THS8200_DTG2_LINETYPE4			0x6b
+#define THS8200_DTG2_LINETYPE5			0x6c
+#define THS8200_DTG2_LINETYPE6			0x6d
+#define THS8200_DTG2_LINETYPE7			0x6e
+#define THS8200_DTG2_LINETYPE8			0x6f
+#define THS8200_DTG2_HLENGTH_LSB		0x70
+#define THS8200_DTG2_HLENGTH_LSB_HDLY_MSB	0x71
+#define THS8200_DTG2_HLENGTH_HDLY_LSB		0x72
+#define THS8200_DTG2_VLENGTH1_LSB		0x73
+#define THS8200_DTG2_VLENGTH1_MSB_VDLY1_MSB	0x74
+#define THS8200_DTG2_VDLY1_LSB			0x75
+#define THS8200_DTG2_VLENGTH2_LSB		0x76
+#define THS8200_DTG2_VLENGTH2_MSB_VDLY2_MSB	0x77
+#define THS8200_DTG2_VDLY2_LSB			0x78
+#define THS8200_DTG2_HS_IN_DLY_MSB		0x79
+#define THS8200_DTG2_HS_IN_DLY_LSB		0x7a
+#define THS8200_DTG2_VS_IN_DLY_MSB		0x7b
+#define THS8200_DTG2_VS_IN_DLY_LSB		0x7c
+#define THS8200_DTG2_PIXEL_CNT_MSB		0x7d
+#define THS8200_DTG2_PIXEL_CNT_LSB		0x7e
+#define THS8200_DTG2_LINE_CNT_MSB		0x7f
+#define THS8200_DTG2_LINE_CNT_LSB		0x80
+#define THS8200_DTG2_CNTL			0x82
+#define THS8200_CGMS_CNTL_HEADER		0x83
+#define THS8200_CGMS_PAYLOAD_MSB		0x84
+#define THS8200_CGMS_PAYLOAD_LSB		0x85
+#define THS8200_MISC_PPL_LSB			0x86
+#define THS8200_MISC_PPL_MSB			0x87
+#define THS8200_MISC_LPF_MSB			0x88
+#define THS8200_MISC_LPF_LSB			0x89
+
+#endif /* THS8200_REGS_H */
diff --git a/drivers/media/i2c/tlv320aic23b.c b/drivers/media/i2c/tlv320aic23b.c
index 809a75a..ef87f7b 100644
--- a/drivers/media/i2c/tlv320aic23b.c
+++ b/drivers/media/i2c/tlv320aic23b.c
@@ -162,7 +162,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct tlv320aic23b_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -191,7 +191,6 @@
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 	v4l2_ctrl_handler_setup(&state->hdl);
@@ -205,7 +204,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c
index e0634c8..d76c53a8 100644
--- a/drivers/media/i2c/tvaudio.c
+++ b/drivers/media/i2c/tvaudio.c
@@ -38,7 +38,6 @@
 
 #include <media/tvaudio.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #include <media/i2c-addr.h>
@@ -1838,13 +1837,6 @@
 	return 0;
 }
 
-static int tvaudio_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVAUDIO, 0);
-}
-
 static int tvaudio_log_status(struct v4l2_subdev *sd)
 {
 	struct CHIPSTATE *chip = to_state(sd);
@@ -1863,7 +1855,6 @@
 
 static const struct v4l2_subdev_core_ops tvaudio_core_ops = {
 	.log_status = tvaudio_log_status,
-	.g_chip_ident = tvaudio_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -1910,7 +1901,7 @@
 		printk("\n");
 	}
 
-	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
 	sd = &chip->sd;
@@ -1930,7 +1921,6 @@
 	}
 	if (desc->name == NULL) {
 		v4l2_dbg(1, debug, sd, "no matching chip description found\n");
-		kfree(chip);
 		return -EIO;
 	}
 	v4l2_info(sd, "%s found @ 0x%x (%s)\n", desc->name, client->addr<<1, client->adapter->name);
@@ -2001,7 +1991,6 @@
 		int err = chip->hdl.error;
 
 		v4l2_ctrl_handler_free(&chip->hdl);
-		kfree(chip);
 		return err;
 	}
 	/* set controls to the default values */
@@ -2044,7 +2033,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&chip->hdl);
-	kfree(chip);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index ab8f3fe..9c6d66a 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -39,7 +39,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-mediabus.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-of.h>
 #include <media/v4l2-ctrls.h>
 #include <media/tvp514x.h>
 #include <media/media-entity.h>
@@ -123,6 +123,8 @@
 	/* mc related members */
 	struct media_pad pad;
 	struct v4l2_mbus_framefmt format;
+
+	struct tvp514x_reg *int_seq;
 };
 
 /* TVP514x default register values */
@@ -543,8 +545,6 @@
 	if (std_id == NULL)
 		return -EINVAL;
 
-	*std_id = V4L2_STD_UNKNOWN;
-
 	/* To query the standard the TVP514x must power on the ADCs. */
 	if (!decoder->streaming) {
 		tvp514x_s_stream(sd, 1);
@@ -553,8 +553,10 @@
 
 	/* query the current standard */
 	current_std = tvp514x_query_current_std(sd);
-	if (current_std == STD_INVALID)
+	if (current_std == STD_INVALID) {
+		*std_id = V4L2_STD_UNKNOWN;
 		return 0;
+	}
 
 	input_sel = decoder->input;
 
@@ -595,10 +597,12 @@
 	}
 	/* check whether signal is locked */
 	sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1);
-	if (lock_mask != (sync_lock_status & lock_mask))
+	if (lock_mask != (sync_lock_status & lock_mask)) {
+		*std_id = V4L2_STD_UNKNOWN;
 		return 0;	/* No input detected */
+	}
 
-	*std_id = decoder->std_list[current_std].standard.id;
+	*std_id &= decoder->std_list[current_std].standard.id;
 
 	v4l2_dbg(1, debug, sd, "Current STD: %s\n",
 			decoder->std_list[current_std].standard.name);
@@ -862,7 +866,6 @@
 static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
 {
 	int err = 0;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct tvp514x_decoder *decoder = to_decoder(sd);
 
 	if (decoder->streaming == enable)
@@ -882,11 +885,8 @@
 	}
 	case 1:
 	{
-		struct tvp514x_reg *int_seq = (struct tvp514x_reg *)
-				client->driver->id_table->driver_data;
-
 		/* Power Up Sequence */
-		err = tvp514x_write_regs(sd, int_seq);
+		err = tvp514x_write_regs(sd, decoder->int_seq);
 		if (err) {
 			v4l2_err(sd, "Unable to turn on decoder\n");
 			return err;
@@ -1055,6 +1055,42 @@
 
 };
 
+static struct tvp514x_platform_data *
+tvp514x_get_pdata(struct i2c_client *client)
+{
+	struct tvp514x_platform_data *pdata;
+	struct v4l2_of_endpoint bus_cfg;
+	struct device_node *endpoint;
+	unsigned int flags;
+
+	if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
+		return client->dev.platform_data;
+
+	endpoint = v4l2_of_get_next_endpoint(client->dev.of_node, NULL);
+	if (!endpoint)
+		return NULL;
+
+	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		goto done;
+
+	v4l2_of_parse_endpoint(endpoint, &bus_cfg);
+	flags = bus_cfg.bus.parallel.flags;
+
+	if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+		pdata->hs_polarity = 1;
+
+	if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
+		pdata->vs_polarity = 1;
+
+	if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+		pdata->clk_polarity = 1;
+
+done:
+	of_node_put(endpoint);
+	return pdata;
+}
+
 /**
  * tvp514x_probe() - decoder driver i2c probe handler
  * @client: i2c driver client device structure
@@ -1066,19 +1102,20 @@
 static int
 tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
+	struct tvp514x_platform_data *pdata = tvp514x_get_pdata(client);
 	struct tvp514x_decoder *decoder;
 	struct v4l2_subdev *sd;
 	int ret;
 
+	if (pdata == NULL) {
+		dev_err(&client->dev, "No platform data\n");
+		return -EINVAL;
+	}
+
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
 
-	if (!client->dev.platform_data) {
-		v4l2_err(client, "No platform data!!\n");
-		return -ENODEV;
-	}
-
 	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (!decoder)
 		return -ENOMEM;
@@ -1089,8 +1126,10 @@
 	memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
 			sizeof(tvp514x_reg_list_default));
 
+	decoder->int_seq = (struct tvp514x_reg *)id->driver_data;
+
 	/* Copy board specific information here */
-	decoder->pdata = client->dev.platform_data;
+	decoder->pdata = pdata;
 
 	/**
 	 * Fetch platform specific data, and configure the
@@ -1109,7 +1148,6 @@
 	/* Register with V4L2 layer as slave device */
 	sd = &decoder->sd;
 	v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
-	strlcpy(sd->name, TVP514X_MODULE_NAME, sizeof(sd->name));
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	decoder->pad.flags = MEDIA_PAD_FL_SOURCE;
@@ -1120,7 +1158,6 @@
 	if (ret < 0) {
 		v4l2_err(sd, "%s decoder driver failed to register !!\n",
 			 sd->name);
-		kfree(decoder);
 		return ret;
 	}
 #endif
@@ -1231,8 +1268,20 @@
 
 MODULE_DEVICE_TABLE(i2c, tvp514x_id);
 
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id tvp514x_of_match[] = {
+	{ .compatible = "ti,tvp5146", },
+	{ .compatible = "ti,tvp5146m2", },
+	{ .compatible = "ti,tvp5147", },
+	{ .compatible = "ti,tvp5147m1", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, tvp514x_of_match);
+#endif
+
 static struct i2c_driver tvp514x_driver = {
 	.driver = {
+		.of_match_table = of_match_ptr(tvp514x_of_match),
 		.owner = THIS_MODULE,
 		.name = TVP514X_MODULE_NAME,
 	},
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 485159a..89c0b13 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <media/v4l2-device.h>
 #include <media/tvp5150.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #include "tvp5150_reg.h"
@@ -727,13 +726,11 @@
 
 	/* First tests should be against specific std */
 
-	if (std == V4L2_STD_ALL) {
-		fmt = VIDEO_STD_AUTO_SWITCH_BIT;	/* Autodetect mode */
-	} else if (std & V4L2_STD_NTSC_443) {
+	if (std == V4L2_STD_NTSC_443) {
 		fmt = VIDEO_STD_NTSC_4_43_BIT;
-	} else if (std & V4L2_STD_PAL_M) {
+	} else if (std == V4L2_STD_PAL_M) {
 		fmt = VIDEO_STD_PAL_M_BIT;
-	} else if (std & (V4L2_STD_PAL_N | V4L2_STD_PAL_Nc)) {
+	} else if (std == V4L2_STD_PAL_N || std == V4L2_STD_PAL_Nc) {
 		fmt = VIDEO_STD_PAL_COMBINATION_N_BIT;
 	} else {
 		/* Then, test against generic ones */
@@ -1031,31 +1028,11 @@
 	return 0;
 }
 
-static int tvp5150_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	int rev;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	rev = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER) << 8 |
-	      tvp5150_read(sd, TVP5150_ROM_MINOR_VER);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP5150,
-					  rev);
-}
-
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int tvp5150_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
 	int res;
 
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	res = tvp5150_read(sd, reg->reg & 0xff);
 	if (res < 0) {
 		v4l2_err(sd, "%s: failed with error = %d\n", __func__, res);
@@ -1069,12 +1046,6 @@
 
 static int tvp5150_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	tvp5150_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
@@ -1098,7 +1069,6 @@
 	.log_status = tvp5150_log_status,
 	.s_std = tvp5150_s_std,
 	.reset = tvp5150_reset,
-	.g_chip_ident = tvp5150_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = tvp5150_g_register,
 	.s_register = tvp5150_s_register,
@@ -1152,10 +1122,9 @@
 	     I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
 		return -EIO;
 
-	core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL);
-	if (!core) {
+	core = devm_kzalloc(&c->dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
 		return -ENOMEM;
-	}
 	sd = &core->sd;
 	v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
 
@@ -1166,7 +1135,7 @@
 	for (i = 0; i < 4; i++) {
 		res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i);
 		if (res < 0)
-			goto free_core;
+			return res;
 		tvp5150_id[i] = res;
 	}
 
@@ -1209,7 +1178,7 @@
 	if (core->hdl.error) {
 		res = core->hdl.error;
 		v4l2_ctrl_handler_free(&core->hdl);
-		goto free_core;
+		return res;
 	}
 	v4l2_ctrl_handler_setup(&core->hdl);
 
@@ -1225,10 +1194,6 @@
 	if (debug > 1)
 		tvp5150_log_status(sd);
 	return 0;
-
-free_core:
-	kfree(core);
-	return res;
 }
 
 static int tvp5150_remove(struct i2c_client *c)
@@ -1242,7 +1207,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&decoder->hdl);
-	kfree(to_tvp5150(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 027809c..a4e4948 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -32,7 +32,6 @@
 #include <linux/v4l2-dv-timings.h>
 #include <media/tvp7002.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 #include "tvp7002_reg.h"
@@ -41,9 +40,6 @@
 MODULE_AUTHOR("Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>");
 MODULE_LICENSE("GPL");
 
-/* Module Name */
-#define TVP7002_MODULE_NAME	"tvp7002"
-
 /* I2C retry attempts */
 #define I2C_RETRY_COUNT		(5)
 
@@ -424,6 +420,7 @@
 	int streaming;
 
 	const struct tvp7002_timings_definition *current_timings;
+	struct media_pad pad;
 };
 
 /*
@@ -535,29 +532,6 @@
 }
 
 /*
- * tvp7002_g_chip_ident() - Get chip identification number
- * @sd: ptr to v4l2_subdev struct
- * @chip: ptr to v4l2_dbg_chip_ident struct
- *
- * Obtains the chip's identification number.
- * Returns zero or -EINVAL if read operation fails.
- */
-static int tvp7002_g_chip_ident(struct v4l2_subdev *sd,
-					struct v4l2_dbg_chip_ident *chip)
-{
-	u8 rev;
-	int error;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	error = tvp7002_read(sd, TVP7002_CHIP_REV, &rev);
-
-	if (error < 0)
-		return error;
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP7002, rev);
-}
-
-/*
  * tvp7002_write_inittab() - Write initialization values
  * @sd: ptr to v4l2_subdev struct
  * @regs: ptr to i2c_reg_value struct
@@ -738,23 +712,17 @@
  *
  * Get the value of a TVP7002 decoder device register.
  * Returns zero when successful, -EINVAL if register read fails or
- * access to I2C client fails, -EPERM if the call is not allowed
- * by disabled CAP_SYS_ADMIN.
+ * access to I2C client fails.
  */
 static int tvp7002_g_register(struct v4l2_subdev *sd,
 						struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	u8 val;
 	int ret;
 
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	ret = tvp7002_read(sd, reg->reg & 0xff, &val);
 	reg->val = val;
+	reg->size = 1;
 	return ret;
 }
 
@@ -764,19 +732,11 @@
  * @reg: ptr to v4l2_dbg_register struct
  *
  * Get the value of a TVP7002 decoder device register.
- * Returns zero when successful, -EINVAL if register read fails or
- * -EPERM if call not allowed.
+ * Returns zero when successful, -EINVAL if register read fails.
  */
 static int tvp7002_s_register(struct v4l2_subdev *sd,
 						const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
 	return tvp7002_write(sd, reg->reg & 0xff, reg->val & 0xff);
 }
 #endif
@@ -880,9 +840,67 @@
 	.s_ctrl = tvp7002_s_ctrl,
 };
 
+/*
+ * tvp7002_enum_mbus_code() - Enum supported digital video format on pad
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @fh: file handle for the subdev
+ * @code: pointer to subdev enum mbus code struct
+ *
+ * Enumerate supported digital video formats for pad.
+ */
+static int
+tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_mbus_code_enum *code)
+{
+	/* Check requested format index is within range */
+	if (code->index != 0)
+		return -EINVAL;
+
+	code->code = V4L2_MBUS_FMT_YUYV10_1X20;
+
+	return 0;
+}
+
+/*
+ * tvp7002_get_pad_format() - get video format on pad
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @fh: file handle for the subdev
+ * @fmt: pointer to subdev format struct
+ *
+ * get video format for pad.
+ */
+static int
+tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_format *fmt)
+{
+	struct tvp7002 *tvp7002 = to_tvp7002(sd);
+
+	fmt->format.code = V4L2_MBUS_FMT_YUYV10_1X20;
+	fmt->format.width = tvp7002->current_timings->timings.bt.width;
+	fmt->format.height = tvp7002->current_timings->timings.bt.height;
+	fmt->format.field = tvp7002->current_timings->scanmode;
+	fmt->format.colorspace = tvp7002->current_timings->color_space;
+
+	return 0;
+}
+
+/*
+ * tvp7002_set_pad_format() - set video format on pad
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @fh: file handle for the subdev
+ * @fmt: pointer to subdev format struct
+ *
+ * set video format for pad.
+ */
+static int
+tvp7002_set_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_format *fmt)
+{
+	return tvp7002_get_pad_format(sd, fh, fmt);
+}
+
 /* V4L2 core operation handlers */
 static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
-	.g_chip_ident = tvp7002_g_chip_ident,
 	.log_status = tvp7002_log_status,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
@@ -910,10 +928,18 @@
 	.enum_mbus_fmt = tvp7002_enum_mbus_fmt,
 };
 
+/* media pad related operation handlers */
+static const struct v4l2_subdev_pad_ops tvp7002_pad_ops = {
+	.enum_mbus_code = tvp7002_enum_mbus_code,
+	.get_fmt = tvp7002_get_pad_format,
+	.set_fmt = tvp7002_set_pad_format,
+};
+
 /* V4L2 top level operation handlers */
 static const struct v4l2_subdev_ops tvp7002_ops = {
 	.core = &tvp7002_core_ops,
 	.video = &tvp7002_video_ops,
+	.pad = &tvp7002_pad_ops,
 };
 
 /*
@@ -993,19 +1019,34 @@
 	timings = device->current_timings->timings;
 	error = tvp7002_s_dv_timings(sd, &timings);
 
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	device->pad.flags = MEDIA_PAD_FL_SOURCE;
+	device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
+
+	error = media_entity_init(&device->sd.entity, 1, &device->pad, 0);
+	if (error < 0)
+		return error;
+#endif
+
 	v4l2_ctrl_handler_init(&device->hdl, 1);
 	v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops,
 			V4L2_CID_GAIN, 0, 255, 1, 0);
 	sd->ctrl_handler = &device->hdl;
 	if (device->hdl.error) {
-		int err = device->hdl.error;
-
-		v4l2_ctrl_handler_free(&device->hdl);
-		return err;
+		error = device->hdl.error;
+		goto error;
 	}
 	v4l2_ctrl_handler_setup(&device->hdl);
 
 	return 0;
+
+error:
+	v4l2_ctrl_handler_free(&device->hdl);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&device->sd.entity);
+#endif
+	return error;
 }
 
 /*
@@ -1022,7 +1063,9 @@
 
 	v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter"
 				"on address 0x%x\n", c->addr);
-
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&device->sd.entity);
+#endif
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&device->hdl);
 	return 0;
diff --git a/drivers/media/i2c/tw2804.c b/drivers/media/i2c/tw2804.c
index c5dc2c3b..f58607d 100644
--- a/drivers/media/i2c/tw2804.c
+++ b/drivers/media/i2c/tw2804.c
@@ -23,7 +23,6 @@
 #include <linux/slab.h>
 #include <media/v4l2-subdev.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 #define TW2804_REG_AUTOGAIN		0x02
@@ -368,8 +367,7 @@
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	state = kzalloc(sizeof(struct tw2804), GFP_KERNEL);
-
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -410,7 +408,6 @@
 	err = state->hdl.error;
 	if (err) {
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 
@@ -427,7 +424,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/tw9903.c b/drivers/media/i2c/tw9903.c
index 87880b1..285b759 100644
--- a/drivers/media/i2c/tw9903.c
+++ b/drivers/media/i2c/tw9903.c
@@ -215,7 +215,7 @@
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	dec = kzalloc(sizeof(struct tw9903), GFP_KERNEL);
+	dec = devm_kzalloc(&client->dev, sizeof(*dec), GFP_KERNEL);
 	if (dec == NULL)
 		return -ENOMEM;
 	sd = &dec->sd;
@@ -233,7 +233,6 @@
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(dec);
 		return err;
 	}
 
@@ -242,7 +241,6 @@
 
 	if (write_regs(sd, initial_registers) < 0) {
 		v4l2_err(client, "error initializing TW9903\n");
-		kfree(dec);
 		return -EINVAL;
 	}
 
@@ -255,7 +253,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&to_state(sd)->hdl);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/tw9906.c b/drivers/media/i2c/tw9906.c
index accd79e..f6bef25 100644
--- a/drivers/media/i2c/tw9906.c
+++ b/drivers/media/i2c/tw9906.c
@@ -183,7 +183,7 @@
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	dec = kzalloc(sizeof(struct tw9906), GFP_KERNEL);
+	dec = devm_kzalloc(&client->dev, sizeof(*dec), GFP_KERNEL);
 	if (dec == NULL)
 		return -ENOMEM;
 	sd = &dec->sd;
@@ -201,7 +201,6 @@
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(dec);
 		return err;
 	}
 
@@ -210,7 +209,6 @@
 
 	if (write_regs(sd, initial_registers) < 0) {
 		v4l2_err(client, "error initializing TW9906\n");
-		kfree(dec);
 		return -EINVAL;
 	}
 
@@ -223,7 +221,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&to_state(sd)->hdl);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/uda1342.c b/drivers/media/i2c/uda1342.c
index 3af4085..081786d 100644
--- a/drivers/media/i2c/uda1342.c
+++ b/drivers/media/i2c/uda1342.c
@@ -69,7 +69,7 @@
 	dev_dbg(&client->dev, "initializing UDA1342 at address %d on %s\n",
 		client->addr, adapter->name);
 
-	sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);
 	if (sd == NULL)
 		return -ENOMEM;
 
@@ -89,7 +89,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(sd);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/upd64031a.c b/drivers/media/i2c/upd64031a.c
index f0a0921..d248e6a 100644
--- a/drivers/media/i2c/upd64031a.c
+++ b/drivers/media/i2c/upd64031a.c
@@ -27,7 +27,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/upd64031a.h>
 
 /* --------------------- read registers functions define -------------------- */
@@ -147,13 +146,6 @@
 	return upd64031a_s_frequency(sd, NULL);
 }
 
-static int upd64031a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_UPD64031A, 0);
-}
-
 static int upd64031a_log_status(struct v4l2_subdev *sd)
 {
 	v4l2_info(sd, "Status: SA00=0x%02x SA01=0x%02x\n",
@@ -164,12 +156,6 @@
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int upd64031a_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = upd64031a_read(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -177,12 +163,6 @@
 
 static int upd64031a_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	upd64031a_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
@@ -192,7 +172,6 @@
 
 static const struct v4l2_subdev_core_ops upd64031a_core_ops = {
 	.log_status = upd64031a_log_status,
-	.g_chip_ident = upd64031a_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = upd64031a_g_register,
 	.s_register = upd64031a_s_register,
@@ -230,7 +209,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct upd64031a_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -249,7 +228,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/upd64083.c b/drivers/media/i2c/upd64083.c
index 343e021..3a152ce 100644
--- a/drivers/media/i2c/upd64083.c
+++ b/drivers/media/i2c/upd64083.c
@@ -27,7 +27,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/upd64083.h>
 
 MODULE_DESCRIPTION("uPD64083 driver");
@@ -122,12 +121,6 @@
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int upd64083_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = upd64083_read(sd, reg->reg & 0xff);
 	reg->size = 1;
 	return 0;
@@ -135,24 +128,11 @@
 
 static int upd64083_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	upd64083_write(sd, reg->reg & 0xff, reg->val & 0xff);
 	return 0;
 }
 #endif
 
-static int upd64083_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_UPD64083, 0);
-}
-
 static int upd64083_log_status(struct v4l2_subdev *sd)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -169,7 +149,6 @@
 
 static const struct v4l2_subdev_core_ops upd64083_core_ops = {
 	.log_status = upd64083_log_status,
-	.g_chip_ident = upd64083_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = upd64083_g_register,
 	.s_register = upd64083_s_register,
@@ -202,7 +181,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct upd64083_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -221,7 +200,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/vp27smpx.c b/drivers/media/i2c/vp27smpx.c
index e71f139..6a3a3ff 100644
--- a/drivers/media/i2c/vp27smpx.c
+++ b/drivers/media/i2c/vp27smpx.c
@@ -29,7 +29,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 MODULE_DESCRIPTION("vp27smpx driver");
 MODULE_AUTHOR("Hans Verkuil");
@@ -112,13 +111,6 @@
 	return 0;
 }
 
-static int vp27smpx_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VP27SMPX, 0);
-}
-
 static int vp27smpx_log_status(struct v4l2_subdev *sd)
 {
 	struct vp27smpx_state *state = to_state(sd);
@@ -132,7 +124,6 @@
 
 static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
 	.log_status = vp27smpx_log_status,
-	.g_chip_ident = vp27smpx_g_chip_ident,
 	.s_std = vp27smpx_s_std,
 };
 
@@ -169,7 +160,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct vp27smpx_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -186,7 +177,6 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/vpx3220.c b/drivers/media/i2c/vpx3220.c
index 2f67b4c..ece90df 100644
--- a/drivers/media/i2c/vpx3220.c
+++ b/drivers/media/i2c/vpx3220.c
@@ -27,7 +27,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
@@ -49,7 +48,6 @@
 	unsigned char reg[255];
 
 	v4l2_std_id norm;
-	int ident;
 	int input;
 	int enable;
 };
@@ -297,7 +295,7 @@
 static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
 {
 	int res = V4L2_IN_ST_NO_SIGNAL, status;
-	v4l2_std_id std = 0;
+	v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
 
 	status = vpx3220_fp_read(sd, 0x0f3);
 
@@ -314,19 +312,21 @@
 		case 0x10:
 		case 0x14:
 		case 0x18:
-			std = V4L2_STD_PAL;
+			std &= V4L2_STD_PAL;
 			break;
 
 		case 0x08:
-			std = V4L2_STD_SECAM;
+			std &= V4L2_STD_SECAM;
 			break;
 
 		case 0x04:
 		case 0x0c:
 		case 0x1c:
-			std = V4L2_STD_NTSC;
+			std &= V4L2_STD_NTSC;
 			break;
 		}
+	} else {
+		std = V4L2_STD_UNKNOWN;
 	}
 	if (pstd)
 		*pstd = std;
@@ -442,14 +442,6 @@
 	return -EINVAL;
 }
 
-static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct vpx3220 *decoder = to_vpx3220(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_ctrl_ops vpx3220_ctrl_ops = {
@@ -457,7 +449,6 @@
 };
 
 static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
-	.g_chip_ident = vpx3220_g_chip_ident,
 	.init = vpx3220_init,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
@@ -499,7 +490,7 @@
 		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
 		return -ENODEV;
 
-	decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
+	decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
 	if (decoder == NULL)
 		return -ENOMEM;
 	sd = &decoder->sd;
@@ -521,7 +512,6 @@
 		int err = decoder->hdl.error;
 
 		v4l2_ctrl_handler_free(&decoder->hdl);
-		kfree(decoder);
 		return err;
 	}
 	v4l2_ctrl_handler_setup(&decoder->hdl);
@@ -529,7 +519,6 @@
 	ver = i2c_smbus_read_byte_data(client, 0x00);
 	pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
 		i2c_smbus_read_byte_data(client, 0x01);
-	decoder->ident = V4L2_IDENT_VPX3220A;
 	if (ver == 0xec) {
 		switch (pn) {
 		case 0x4680:
@@ -537,11 +526,9 @@
 			break;
 		case 0x4260:
 			name = "vpx3216b";
-			decoder->ident = V4L2_IDENT_VPX3216B;
 			break;
 		case 0x4280:
 			name = "vpx3214c";
-			decoder->ident = V4L2_IDENT_VPX3214C;
 			break;
 		}
 	}
@@ -566,7 +553,7 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&decoder->hdl);
-	kfree(decoder);
+
 	return 0;
 }
 
diff --git a/drivers/media/i2c/vs6624.c b/drivers/media/i2c/vs6624.c
index f366fad..25bdd93 100644
--- a/drivers/media/i2c/vs6624.c
+++ b/drivers/media/i2c/vs6624.c
@@ -27,7 +27,6 @@
 #include <linux/types.h>
 #include <linux/videodev2.h>
 
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-mediabus.h>
@@ -722,27 +721,9 @@
 	return 0;
 }
 
-static int vs6624_g_chip_ident(struct v4l2_subdev *sd,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	int rev;
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	rev = (vs6624_read(sd, VS6624_FW_VSN_MAJOR) << 8)
-		| vs6624_read(sd, VS6624_FW_VSN_MINOR);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_VS6624, rev);
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int vs6624_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->val = vs6624_read(sd, reg->reg & 0xffff);
 	reg->size = 1;
 	return 0;
@@ -750,12 +731,6 @@
 
 static int vs6624_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (!v4l2_chip_match_i2c_client(client, &reg->match))
-		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	vs6624_write(sd, reg->reg & 0xffff, reg->val & 0xff);
 	return 0;
 }
@@ -766,7 +741,6 @@
 };
 
 static const struct v4l2_subdev_core_ops vs6624_core_ops = {
-	.g_chip_ident = vs6624_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = vs6624_g_register,
 	.s_register = vs6624_s_register,
@@ -805,20 +779,18 @@
 	if (ce == NULL)
 		return -EINVAL;
 
-	ret = gpio_request(*ce, "VS6624 Chip Enable");
+	ret = devm_gpio_request_one(&client->dev, *ce, GPIOF_OUT_INIT_HIGH,
+				    "VS6624 Chip Enable");
 	if (ret) {
 		v4l_err(client, "failed to request GPIO %d\n", *ce);
 		return ret;
 	}
-	gpio_direction_output(*ce, 1);
 	/* wait 100ms before any further i2c writes are performed */
 	mdelay(100);
 
-	sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
-	if (sensor == NULL) {
-		gpio_free(*ce);
+	sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
+	if (sensor == NULL)
 		return -ENOMEM;
-	}
 
 	sd = &sensor->sd;
 	v4l2_i2c_subdev_init(sd, client, &vs6624_ops);
@@ -866,30 +838,22 @@
 		int err = hdl->error;
 
 		v4l2_ctrl_handler_free(hdl);
-		kfree(sensor);
-		gpio_free(*ce);
 		return err;
 	}
 
 	/* initialize the hardware to the default control values */
 	ret = v4l2_ctrl_handler_setup(hdl);
-	if (ret) {
+	if (ret)
 		v4l2_ctrl_handler_free(hdl);
-		kfree(sensor);
-		gpio_free(*ce);
-	}
 	return ret;
 }
 
 static int vs6624_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
-	struct vs6624 *sensor = to_vs6624(sd);
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
-	gpio_free(sensor->ce_pin);
-	kfree(sensor);
 	return 0;
 }
 
diff --git a/drivers/media/i2c/wm8739.c b/drivers/media/i2c/wm8739.c
index 3bb99e9..3be73f6 100644
--- a/drivers/media/i2c/wm8739.c
+++ b/drivers/media/i2c/wm8739.c
@@ -29,7 +29,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 
 MODULE_DESCRIPTION("wm8739 driver");
@@ -160,13 +159,6 @@
 	return 0;
 }
 
-static int wm8739_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_WM8739, 0);
-}
-
 static int wm8739_log_status(struct v4l2_subdev *sd)
 {
 	struct wm8739_state *state = to_state(sd);
@@ -184,7 +176,6 @@
 
 static const struct v4l2_subdev_core_ops wm8739_core_ops = {
 	.log_status = wm8739_log_status,
-	.g_chip_ident = wm8739_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -220,7 +211,7 @@
 	v4l_info(client, "chip found @ 0x%x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct wm8739_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -237,7 +228,6 @@
 		int err = state->hdl.error;
 
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 	v4l2_ctrl_cluster(3, &state->volume);
@@ -271,7 +261,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(to_state(sd));
 	return 0;
 }
 
diff --git a/drivers/media/i2c/wm8775.c b/drivers/media/i2c/wm8775.c
index 27c27b4..3f584a7 100644
--- a/drivers/media/i2c/wm8775.c
+++ b/drivers/media/i2c/wm8775.c
@@ -33,7 +33,6 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/wm8775.h>
 
@@ -158,13 +157,6 @@
 	return -EINVAL;
 }
 
-static int wm8775_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_WM8775, 0);
-}
-
 static int wm8775_log_status(struct v4l2_subdev *sd)
 {
 	struct wm8775_state *state = to_state(sd);
@@ -188,7 +180,6 @@
 
 static const struct v4l2_subdev_core_ops wm8775_core_ops = {
 	.log_status = wm8775_log_status,
-	.g_chip_ident = wm8775_g_chip_ident,
 	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
@@ -241,7 +232,7 @@
 	v4l_info(client, "chip found @ 0x%02x (%s)\n",
 			client->addr << 1, client->adapter->name);
 
-	state = kzalloc(sizeof(struct wm8775_state), GFP_KERNEL);
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 	if (state == NULL)
 		return -ENOMEM;
 	sd = &state->sd;
@@ -261,7 +252,6 @@
 	err = state->hdl.error;
 	if (err) {
 		v4l2_ctrl_handler_free(&state->hdl);
-		kfree(state);
 		return err;
 	}
 
@@ -319,7 +309,6 @@
 
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&state->hdl);
-	kfree(state);
 	return 0;
 }
 
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 1957c0d..d5a7a13 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -142,6 +142,8 @@
 
 		for (p = 0; p < entity->num_pads; p++) {
 			struct media_pad_desc pad;
+
+			memset(&pad, 0, sizeof(pad));
 			media_device_kpad_to_upad(&entity->pads[p], &pad);
 			if (copy_to_user(&links->pads[p], &pad, sizeof(pad)))
 				return -EFAULT;
@@ -159,6 +161,7 @@
 			if (entity->links[l].source->entity != entity)
 				continue;
 
+			memset(&link, 0, sizeof(link));
 			media_device_kpad_to_upad(entity->links[l].source,
 						  &link.source);
 			media_device_kpad_to_upad(entity->links[l].sink,
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index e1cd132..cb30ffb 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -429,6 +429,56 @@
 }
 EXPORT_SYMBOL_GPL(media_entity_create_link);
 
+void __media_entity_remove_links(struct media_entity *entity)
+{
+	unsigned int i;
+
+	for (i = 0; i < entity->num_links; i++) {
+		struct media_link *link = &entity->links[i];
+		struct media_entity *remote;
+		unsigned int r = 0;
+
+		if (link->source->entity == entity)
+			remote = link->sink->entity;
+		else
+			remote = link->source->entity;
+
+		while (r < remote->num_links) {
+			struct media_link *rlink = &remote->links[r];
+
+			if (rlink != link->reverse) {
+				r++;
+				continue;
+			}
+
+			if (link->source->entity == entity)
+				remote->num_backlinks--;
+
+			if (--remote->num_links == 0)
+				break;
+
+			/* Insert last entry in place of the dropped link. */
+			*rlink = remote->links[remote->num_links];
+		}
+	}
+
+	entity->num_links = 0;
+	entity->num_backlinks = 0;
+}
+EXPORT_SYMBOL_GPL(__media_entity_remove_links);
+
+void media_entity_remove_links(struct media_entity *entity)
+{
+	/* Do nothing if the entity is not registered. */
+	if (entity->parent == NULL)
+		return;
+
+	mutex_lock(&entity->parent->graph_mutex);
+	__media_entity_remove_links(entity);
+	mutex_unlock(&entity->parent->graph_mutex);
+}
+EXPORT_SYMBOL_GPL(media_entity_remove_links);
+
 static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
 {
 	int ret;
@@ -496,25 +546,17 @@
 
 	mdev = source->parent;
 
-	if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) {
-		ret = mdev->link_notify(link->source, link->sink,
-					MEDIA_LNK_FL_ENABLED);
+	if (mdev->link_notify) {
+		ret = mdev->link_notify(link, flags,
+					MEDIA_DEV_NOTIFY_PRE_LINK_CH);
 		if (ret < 0)
 			return ret;
 	}
 
 	ret = __media_entity_setup_link_notify(link, flags);
-	if (ret < 0)
-		goto err;
 
-	if (!(flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
-		mdev->link_notify(link->source, link->sink, 0);
-
-	return 0;
-
-err:
-	if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
-		mdev->link_notify(link->source, link->sink, 0);
+	if (mdev->link_notify)
+		mdev->link_notify(link, flags, MEDIA_DEV_NOTIFY_POST_LINK_CH);
 
 	return ret;
 }
@@ -560,17 +602,16 @@
 EXPORT_SYMBOL_GPL(media_entity_find_link);
 
 /**
- * media_entity_remote_source - Find the source pad at the remote end of a link
- * @pad: Sink pad at the local end of the link
+ * media_entity_remote_pad - Find the pad at the remote end of a link
+ * @pad: Pad at the local end of the link
  *
- * Search for a remote source pad connected to the given sink pad by iterating
- * over all links originating or terminating at that pad until an enabled link
- * is found.
+ * Search for a remote pad connected to the given pad by iterating over all
+ * links originating or terminating at that pad until an enabled link is found.
  *
  * Return a pointer to the pad at the remote end of the first found enabled
  * link, or NULL if no enabled link has been found.
  */
-struct media_pad *media_entity_remote_source(struct media_pad *pad)
+struct media_pad *media_entity_remote_pad(struct media_pad *pad)
 {
 	unsigned int i;
 
@@ -590,4 +631,4 @@
 	return NULL;
 
 }
-EXPORT_SYMBOL_GPL(media_entity_remote_source);
+EXPORT_SYMBOL_GPL(media_entity_remote_pad);
diff --git a/drivers/media/parport/bw-qcam.c b/drivers/media/parport/bw-qcam.c
index 06231b8..d12bd33 100644
--- a/drivers/media/parport/bw-qcam.c
+++ b/drivers/media/parport/bw-qcam.c
@@ -687,6 +687,7 @@
 
 	parport_release(qcam->pdev);
 	mutex_unlock(&qcam->lock);
+	v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
 	if (len != size)
 		vb->state = VB2_BUF_STATE_ERROR;
 	vb2_set_plane_payload(vb, 0, len);
@@ -964,6 +965,7 @@
 	q->drv_priv = qcam;
 	q->ops = &qcam_video_qops;
 	q->mem_ops = &vb2_vmalloc_memops;
+	q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 	err = vb2_queue_init(q);
 	if (err < 0) {
 		v4l2_err(v4l2_dev, "couldn't init vb2_queue for %s.\n", port->name);
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index d4e2ed3..53196f1 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -1,6 +1,7 @@
+if PCI && MEDIA_SUPPORT
+
 menuconfig MEDIA_PCI_SUPPORT
 	bool "Media PCI Adapters"
-	depends on PCI && MEDIA_SUPPORT
 	help
 	  Enable media drivers for PCI/PCIe bus.
 	  If you have such devices, say Y.
@@ -45,3 +46,4 @@
 endif
 
 endif #MEDIA_PCI_SUPPORT
+endif #PCI
diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c
index 44f8fb5..447afbd 100644
--- a/drivers/media/pci/b2c2/flexcop-pci.c
+++ b/drivers/media/pci/b2c2/flexcop-pci.c
@@ -432,18 +432,7 @@
 	.remove   = flexcop_pci_remove,
 };
 
-static int __init flexcop_pci_module_init(void)
-{
-	return pci_register_driver(&flexcop_pci_driver);
-}
-
-static void __exit flexcop_pci_module_exit(void)
-{
-	pci_unregister_driver(&flexcop_pci_driver);
-}
-
-module_init(flexcop_pci_module_init);
-module_exit(flexcop_pci_module_exit);
+module_pci_driver(flexcop_pci_driver);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_NAME);
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c
index b7dc921..e564aac 100644
--- a/drivers/media/pci/bt8xx/bttv-cards.c
+++ b/drivers/media/pci/bt8xx/bttv-cards.c
@@ -131,7 +131,7 @@
 		 "[yet another chipset flaw workaround]");
 MODULE_PARM_DESC(latency,"pci latency timer");
 MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
-MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
+MODULE_PARM_DESC(pll, "specify installed crystal (0=none, 28=28 MHz, 35=35 MHz, 14=14 MHz)");
 MODULE_PARM_DESC(tuner,"specify installed tuner type");
 MODULE_PARM_DESC(autoload, "obsolete option, please do not use anymore");
 MODULE_PARM_DESC(audiodev, "specify audio device:\n"
@@ -2705,7 +2705,7 @@
 		.has_radio      = 1,
 		.has_remote     = 1,
 	},
-		[BTTV_BOARD_VD012] = {
+	[BTTV_BOARD_VD012] = {
 		/* D.Heer@Phytec.de */
 		.name           = "PHYTEC VD-012 (bt878)",
 		.video_inputs   = 4,
@@ -2718,7 +2718,7 @@
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
-		[BTTV_BOARD_VD012_X1] = {
+	[BTTV_BOARD_VD012_X1] = {
 		/* D.Heer@Phytec.de */
 		.name           = "PHYTEC VD-012-X1 (bt878)",
 		.video_inputs   = 4,
@@ -2731,7 +2731,7 @@
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
-		[BTTV_BOARD_VD012_X2] = {
+	[BTTV_BOARD_VD012_X2] = {
 		/* D.Heer@Phytec.de */
 		.name           = "PHYTEC VD-012-X2 (bt878)",
 		.video_inputs   = 4,
@@ -2744,7 +2744,7 @@
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
-		[BTTV_BOARD_GEOVISION_GV800S] = {
+	[BTTV_BOARD_GEOVISION_GV800S] = {
 		/* Bruno Christo <bchristo@inf.ufsm.br>
 		 *
 		 * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
@@ -2771,7 +2771,7 @@
 		.no_tda7432	= 1,
 		.muxsel_hook    = gv800s_muxsel,
 	},
-		[BTTV_BOARD_GEOVISION_GV800S_SL] = {
+	[BTTV_BOARD_GEOVISION_GV800S_SL] = {
 		/* Bruno Christo <bchristo@inf.ufsm.br>
 		 *
 		 * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
@@ -2808,6 +2808,7 @@
 		.tuner_type     = TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
+	/* ---- card 0xa0---------------------------------- */
 	[BTTV_BOARD_TVT_TD3116] = {
 		.name           = "Tongwei Video Technology TD-3116",
 		.video_inputs   = 16,
@@ -2825,6 +2826,35 @@
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.tuner_type     = TUNER_ABSENT,
 	},
+	[BTTV_BOARD_ADLINK_MPG24] = {
+		/* Adlink MPG24 */
+		.name           = "Adlink MPG24",
+		.video_inputs   = 1,
+		/* .audio_inputs= 1, */
+		.svhs           = NO_SVHS,
+		.muxsel         = MUXSEL(2, 2, 2, 2),
+		.tuner_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.pll            = PLL_28,
+	},
+	[BTTV_BOARD_BT848_CAP_14] = {
+		.name		= "Bt848 Capture 14MHz",
+		.video_inputs	= 4,
+		.svhs		= 2,
+		.muxsel		= MUXSEL(2, 3, 1, 0),
+		.pll		= PLL_14,
+		.tuner_type	= TUNER_ABSENT,
+	},
+	[BTTV_BOARD_CYBERVISION_CV06] = {
+		.name		= "CyberVision CV06 (SV)",
+		.video_inputs	= 4,
+		/* .audio_inputs= 0, */
+		.svhs		= NO_SVHS,
+		.muxsel		= MUXSEL(2, 3, 1, 0),
+		.pll		= PLL_28,
+		.tuner_type	= TUNER_ABSENT,
+		.tuner_addr	= ADDR_UNSET,
+	},
 
 };
 
@@ -3390,6 +3420,10 @@
 			btv->pll.pll_ifreq=35468950;
 			btv->pll.pll_crystal=BT848_IFORM_XT1;
 		}
+		if (PLL_14 == bttv_tvcards[btv->c.type].pll) {
+			btv->pll.pll_ifreq = 14318181;
+			btv->pll.pll_crystal = BT848_IFORM_XT0;
+		}
 		/* insmod options can override */
 		switch (pll[btv->c.nr]) {
 		case 0: /* none */
@@ -3409,6 +3443,12 @@
 			btv->pll.pll_ofreq   = 0;
 			btv->pll.pll_crystal = BT848_IFORM_XT1;
 			break;
+		case 3: /* 14 MHz */
+		case 14:
+			btv->pll.pll_ifreq   = 14318181;
+			btv->pll.pll_ofreq   = 0;
+			btv->pll.pll_crystal = BT848_IFORM_XT0;
+			break;
 		}
 	}
 	btv->pll.pll_current = -1;
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index e7d0884..c6532de 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -50,7 +50,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/tvaudio.h>
 #include <media/msp3400.h>
 
@@ -1761,9 +1760,9 @@
 	struct bttv *btv = fh->btv;
 
 	if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML)
-		*id = V4L2_STD_625_50;
+		*id &= V4L2_STD_625_50;
 	else
-		*id = V4L2_STD_525_60;
+		*id &= V4L2_STD_525_60;
 	return 0;
 }
 
@@ -1907,28 +1906,6 @@
 	return 0;
 }
 
-static int bttv_g_chip_ident(struct file *file, void *f, struct v4l2_dbg_chip_ident *chip)
-{
-	struct bttv_fh *fh  = f;
-	struct bttv *btv = fh->btv;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
-		if (v4l2_chip_match_host(&chip->match)) {
-			chip->ident = btv->id;
-			if (chip->ident == PCI_DEVICE_ID_FUSION879)
-				chip->ident = V4L2_IDENT_BT879;
-		}
-		return 0;
-	}
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-	    chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-	/* TODO: is this correct? */
-	return bttv_call_all_err(btv, core, g_chip_ident, chip);
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int bttv_g_register(struct file *file, void *f,
 					struct v4l2_dbg_register *reg)
@@ -1936,16 +1913,6 @@
 	struct bttv_fh *fh = f;
 	struct bttv *btv = fh->btv;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	if (!v4l2_chip_match_host(&reg->match)) {
-		/* TODO: subdev errors should not be ignored, this should become a
-		   subdev helper function. */
-		bttv_call_all(btv, core, g_register, reg);
-		return 0;
-	}
-
 	/* bt848 has a 12-bit register space */
 	reg->reg &= 0xfff;
 	reg->val = btread(reg->reg);
@@ -1960,16 +1927,6 @@
 	struct bttv_fh *fh = f;
 	struct bttv *btv = fh->btv;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	if (!v4l2_chip_match_host(&reg->match)) {
-		/* TODO: subdev errors should not be ignored, this should become a
-		   subdev helper function. */
-		bttv_call_all(btv, core, s_register, reg);
-		return 0;
-	}
-
 	/* bt848 has a 12-bit register space */
 	btwrite(reg->val, reg->reg & 0xfff);
 
@@ -3209,7 +3166,6 @@
 	.vidioc_querystd		= bttv_querystd,
 	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident		= bttv_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register		= bttv_g_register,
 	.vidioc_s_register		= bttv_s_register,
diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h
index 6139ce2..df578ef 100644
--- a/drivers/media/pci/bt8xx/bttv.h
+++ b/drivers/media/pci/bt8xx/bttv.h
@@ -185,6 +185,9 @@
 #define BTTV_BOARD_PV183                   0x9f
 #define BTTV_BOARD_TVT_TD3116		   0xa0
 #define BTTV_BOARD_APOSONIC_WDVR           0xa1
+#define BTTV_BOARD_ADLINK_MPG24            0xa2
+#define BTTV_BOARD_BT848_CAP_14            0xa3
+#define BTTV_BOARD_CYBERVISION_CV06        0xa4
 
 /* more card-specific defines */
 #define PT2254_L_CHANNEL 0x10
@@ -232,6 +235,7 @@
 #define PLL_NONE 0
 #define PLL_28   1
 #define PLL_35   2
+#define PLL_14   3
 
 	/* i2c audio flags */
 	unsigned int no_msp34xx:1;
diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c
index 38b1d64..c4890a4 100644
--- a/drivers/media/pci/cx18/cx18-av-core.c
+++ b/drivers/media/pci/cx18/cx18-av-core.c
@@ -22,7 +22,6 @@
  *  02110-1301, USA.
  */
 
-#include <media/v4l2-chip-ident.h>
 #include "cx18-driver.h"
 #include "cx18-io.h"
 #include "cx18-cards.h"
@@ -1231,35 +1230,14 @@
 	return 0;
 }
 
-static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match)
-{
-	return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1;
-}
-
-static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct cx18_av_state *state = to_cx18_av_state(sd);
-
-	if (cx18_av_dbg_match(&chip->match)) {
-		chip->ident = state->id;
-		chip->revision = state->rev;
-	}
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int cx18_av_g_register(struct v4l2_subdev *sd,
 			      struct v4l2_dbg_register *reg)
 {
 	struct cx18 *cx = v4l2_get_subdevdata(sd);
 
-	if (!cx18_av_dbg_match(&reg->match))
-		return -EINVAL;
 	if ((reg->reg & 0x3) != 0)
 		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->size = 4;
 	reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc);
 	return 0;
@@ -1270,12 +1248,8 @@
 {
 	struct cx18 *cx = v4l2_get_subdevdata(sd);
 
-	if (!cx18_av_dbg_match(&reg->match))
-		return -EINVAL;
 	if ((reg->reg & 0x3) != 0)
 		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val);
 	return 0;
 }
@@ -1286,17 +1260,9 @@
 };
 
 static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
-	.g_chip_ident = cx18_av_g_chip_ident,
 	.log_status = cx18_av_log_status,
 	.load_fw = cx18_av_load_fw,
 	.reset = cx18_av_reset,
-	.g_ctrl = v4l2_subdev_g_ctrl,
-	.s_ctrl = v4l2_subdev_s_ctrl,
-	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
-	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
-	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
-	.queryctrl = v4l2_subdev_queryctrl,
-	.querymenu = v4l2_subdev_querymenu,
 	.s_std = cx18_av_s_std,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = cx18_av_g_register,
@@ -1344,8 +1310,6 @@
 	int err;
 
 	state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
-	state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
-		    ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
 
 	state->vid_input = CX18_AV_COMPOSITE7;
 	state->aud_input = CX18_AV_AUDIO8;
diff --git a/drivers/media/pci/cx18/cx18-av-core.h b/drivers/media/pci/cx18/cx18-av-core.h
index e9c69d9..4c559e8 100644
--- a/drivers/media/pci/cx18/cx18-av-core.h
+++ b/drivers/media/pci/cx18/cx18-av-core.h
@@ -104,7 +104,6 @@
 	enum cx18_av_audio_input aud_input;
 	u32 audclk_freq;
 	int audmode;
-	u32 id;
 	u32 rev;
 	int is_initialized;
 
diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c
index aee7b6d..1110bcb 100644
--- a/drivers/media/pci/cx18/cx18-ioctl.c
+++ b/drivers/media/pci/cx18/cx18-ioctl.c
@@ -39,7 +39,6 @@
 #include "cx18-cards.h"
 #include "cx18-av-core.h"
 #include <media/tveeprom.h>
-#include <media/v4l2-chip-ident.h>
 
 u16 cx18_service2vbi(int type)
 {
@@ -362,73 +361,18 @@
 	return 0;
 }
 
-static int cx18_g_chip_ident(struct file *file, void *fh,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct cx18 *cx = fh2id(fh)->cx;
-	int err = 0;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	switch (chip->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		switch (chip->match.addr) {
-		case 0:
-			chip->ident = V4L2_IDENT_CX23418;
-			chip->revision = cx18_read_reg(cx, 0xC72028);
-			break;
-		case 1:
-			/*
-			 * The A/V decoder is always present, but in the rare
-			 * case that the card doesn't have analog, we don't
-			 * use it.  We find it w/o using the cx->sd_av pointer
-			 */
-			cx18_call_hw(cx, CX18_HW_418_AV,
-				     core, g_chip_ident, chip);
-			break;
-		default:
-			/*
-			 * Could return ident = V4L2_IDENT_UNKNOWN if we had
-			 * other host chips at higher addresses, but we don't
-			 */
-			err = -EINVAL; /* per V4L2 spec */
-			break;
-		}
-		break;
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		/* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
-		cx18_call_all(cx, core, g_chip_ident, chip);
-		break;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/*
-		 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
-		 * to look if a chip is at the address with no driver.  That's a
-		 * dangerous thing to do with EEPROMs anyway.
-		 */
-		cx18_call_all(cx, core, g_chip_ident, chip);
-		break;
-	default:
-		err = -EINVAL;
-		break;
-	}
-	return err;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int cx18_g_register(struct file *file, void *fh,
 				struct v4l2_dbg_register *reg)
 {
 	struct cx18 *cx = fh2id(fh)->cx;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
-			return -EINVAL;
-		reg->size = 4;
-		reg->val = cx18_read_enc(cx, reg->reg);
-		return 0;
-	}
-	/* FIXME - errors shouldn't be ignored */
-	cx18_call_all(cx, core, g_register, reg);
+	if (reg->reg & 0x3)
+		return -EINVAL;
+	if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
+		return -EINVAL;
+	reg->size = 4;
+	reg->val = cx18_read_enc(cx, reg->reg);
 	return 0;
 }
 
@@ -437,14 +381,11 @@
 {
 	struct cx18 *cx = fh2id(fh)->cx;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
-			return -EINVAL;
-		cx18_write_enc(cx, reg->val, reg->reg);
-		return 0;
-	}
-	/* FIXME - errors shouldn't be ignored */
-	cx18_call_all(cx, core, s_register, reg);
+	if (reg->reg & 0x3)
+		return -EINVAL;
+	if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
+		return -EINVAL;
+	cx18_write_enc(cx, reg->val, reg->reg);
 	return 0;
 }
 #endif
@@ -1162,7 +1103,6 @@
 	.vidioc_try_fmt_vbi_cap         = cx18_try_fmt_vbi_cap,
 	.vidioc_try_fmt_sliced_vbi_cap  = cx18_try_fmt_sliced_vbi_cap,
 	.vidioc_g_sliced_vbi_cap        = cx18_g_sliced_vbi_cap,
-	.vidioc_g_chip_ident            = cx18_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register              = cx18_g_register,
 	.vidioc_s_register              = cx18_s_register,
diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index 6dea11a..e3fc2c7 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1217,8 +1217,7 @@
 	struct cx23885_fh  *fh  = file->private_data;
 	struct cx23885_dev *dev = fh->dev;
 
-	call_all(dev, core, g_std, id);
-
+	*id = dev->tvnorm;
 	return 0;
 }
 
@@ -1661,7 +1660,6 @@
 };
 
 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
-	.vidioc_querystd	 = vidioc_g_std,
 	.vidioc_g_std		 = vidioc_g_std,
 	.vidioc_s_std		 = vidioc_s_std,
 	.vidioc_enum_input	 = vidioc_enum_input,
@@ -1690,8 +1688,8 @@
 	.vidioc_log_status	 = vidioc_log_status,
 	.vidioc_querymenu	 = vidioc_querymenu,
 	.vidioc_queryctrl	 = vidioc_queryctrl,
-	.vidioc_g_chip_ident	 = cx23885_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_chip_info	 = cx23885_g_chip_info,
 	.vidioc_g_register	 = cx23885_g_register,
 	.vidioc_s_register	 = cx23885_s_register,
 #endif
@@ -1702,7 +1700,6 @@
 	.fops          = &mpeg_fops,
 	.ioctl_ops     = &mpeg_ioctl_ops,
 	.tvnorms       = CX23885_NORMS,
-	.current_norm  = V4L2_STD_NTSC_M,
 };
 
 void cx23885_417_unregister(struct cx23885_dev *dev)
@@ -1735,7 +1732,7 @@
 	*vfd = *template;
 	snprintf(vfd->name, sizeof(vfd->name), "%s (%s)",
 		cx23885_boards[tsport->dev->board].name, type);
-	vfd->parent  = &pci->dev;
+	vfd->v4l2_dev = &dev->v4l2_dev;
 	vfd->release = video_device_release;
 	return vfd;
 }
diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.c b/drivers/media/pci/cx23885/cx23885-ioctl.c
index acdb6d5..271d69d 100644
--- a/drivers/media/pci/cx23885/cx23885-ioctl.c
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.c
@@ -24,93 +24,21 @@
 #include "cx23885.h"
 #include "cx23885-ioctl.h"
 
-#include <media/v4l2-chip-ident.h>
-
-int cx23885_g_chip_ident(struct file *file, void *fh,
-			 struct v4l2_dbg_chip_ident *chip)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+int cx23885_g_chip_info(struct file *file, void *fh,
+			 struct v4l2_dbg_chip_info *chip)
 {
 	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
-	int err = 0;
-	u8 rev;
 
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	switch (chip->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		switch (chip->match.addr) {
-		case 0:
-			rev = cx_read(RDR_CFG2) & 0xff;
-			switch (dev->pci->device) {
-			case 0x8852:
-				/* rev 0x04 could be '885 or '888. Pick '888. */
-				if (rev == 0x04)
-					chip->ident = V4L2_IDENT_CX23888;
-				else
-					chip->ident = V4L2_IDENT_CX23885;
-				break;
-			case 0x8880:
-				if (rev == 0x0e || rev == 0x0f)
-					chip->ident = V4L2_IDENT_CX23887;
-				else
-					chip->ident = V4L2_IDENT_CX23888;
-				break;
-			default:
-				chip->ident = V4L2_IDENT_UNKNOWN;
-				break;
-			}
-			chip->revision = (dev->pci->device << 16) | (rev << 8) |
-					 (dev->hwrevision & 0xff);
-			break;
-		case 1:
-			if (dev->v4l_device != NULL) {
-				chip->ident = V4L2_IDENT_CX23417;
-				chip->revision = 0;
-			}
-			break;
-		case 2:
-			/*
-			 * The integrated IR controller on the CX23888 is
-			 * host chip 2.  It may not be used/initialized or sd_ir
-			 * may be pointing at the cx25840 subdevice for the
-			 * IR controller on the CX23885.  Thus we find it
-			 * without using the dev->sd_ir pointer.
-			 */
-			call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident,
-				chip);
-			break;
-		default:
-			err = -EINVAL; /* per V4L2 spec */
-			break;
-		}
-		break;
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		/* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
-		call_all(dev, core, g_chip_ident, chip);
-		break;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/*
-		 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
-		 * to look if a chip is at the address with no driver.  That's a
-		 * dangerous thing to do with EEPROMs anyway.
-		 */
-		call_all(dev, core, g_chip_ident, chip);
-		break;
-	default:
-		err = -EINVAL;
-		break;
-	}
-	return err;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int cx23885_g_host_register(struct cx23885_dev *dev,
-				   struct v4l2_dbg_register *reg)
-{
-	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
+	if (chip->match.addr > 1)
 		return -EINVAL;
-
-	reg->size = 4;
-	reg->val = cx_read(reg->reg);
+	if (chip->match.addr == 1) {
+		if (dev->v4l_device == NULL)
+			return -EINVAL;
+		strlcpy(chip->name, "cx23417", sizeof(chip->name));
+	} else {
+		strlcpy(chip->name, dev->v4l2_dev.name, sizeof(chip->name));
+	}
 	return 0;
 }
 
@@ -138,32 +66,16 @@
 {
 	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
+	if (reg->match.addr > 1)
+		return -EINVAL;
+	if (reg->match.addr)
+		return cx23417_g_register(dev, reg);
 
-	if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
-		switch (reg->match.addr) {
-		case 0:
-			return cx23885_g_host_register(dev, reg);
-		case 1:
-			return cx23417_g_register(dev, reg);
-		default:
-			break;
-		}
-	}
-
-	/* FIXME - any error returns should not be ignored */
-	call_all(dev, core, g_register, reg);
-	return 0;
-}
-
-static int cx23885_s_host_register(struct cx23885_dev *dev,
-				   const struct v4l2_dbg_register *reg)
-{
 	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
 		return -EINVAL;
 
-	cx_write(reg->reg, reg->val);
+	reg->size = 4;
+	reg->val = cx_read(reg->reg);
 	return 0;
 }
 
@@ -186,22 +98,15 @@
 {
 	struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
+	if (reg->match.addr > 1)
+		return -EINVAL;
+	if (reg->match.addr)
+		return cx23417_s_register(dev, reg);
 
-	if (reg->match.type == V4L2_CHIP_MATCH_HOST) {
-		switch (reg->match.addr) {
-		case 0:
-			return cx23885_s_host_register(dev, reg);
-		case 1:
-			return cx23417_s_register(dev, reg);
-		default:
-			break;
-		}
-	}
+	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
+		return -EINVAL;
 
-	/* FIXME - any error returns should not be ignored */
-	call_all(dev, core, s_register, reg);
+	cx_write(reg->reg, reg->val);
 	return 0;
 }
 #endif
diff --git a/drivers/media/pci/cx23885/cx23885-ioctl.h b/drivers/media/pci/cx23885/cx23885-ioctl.h
index a608096..92d9f07 100644
--- a/drivers/media/pci/cx23885/cx23885-ioctl.h
+++ b/drivers/media/pci/cx23885/cx23885-ioctl.h
@@ -24,8 +24,8 @@
 #ifndef _CX23885_IOCTL_H_
 #define _CX23885_IOCTL_H_
 
-int cx23885_g_chip_ident(struct file *file, void *fh,
-			 struct v4l2_dbg_chip_ident *chip);
+int cx23885_g_chip_info(struct file *file, void *fh,
+			 struct v4l2_dbg_chip_info *chip);
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 int cx23885_g_register(struct file *file, void *fh,
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index ed08c89..e33d1a7 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -1254,8 +1254,7 @@
 	struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev;
 	dprintk(1, "%s()\n", __func__);
 
-	call_all(dev, core, g_std, id);
-
+	*id = dev->tvnorm;
 	return 0;
 }
 
@@ -1743,7 +1742,6 @@
 	.vidioc_dqbuf         = vidioc_dqbuf,
 	.vidioc_s_std         = vidioc_s_std,
 	.vidioc_g_std         = vidioc_g_std,
-	.vidioc_querystd      = vidioc_g_std,
 	.vidioc_enum_input    = vidioc_enum_input,
 	.vidioc_g_input       = vidioc_g_input,
 	.vidioc_s_input       = vidioc_s_input,
@@ -1757,8 +1755,8 @@
 	.vidioc_s_tuner       = vidioc_s_tuner,
 	.vidioc_g_frequency   = vidioc_g_frequency,
 	.vidioc_s_frequency   = vidioc_s_frequency,
-	.vidioc_g_chip_ident  = cx23885_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_chip_info   = cx23885_g_chip_info,
 	.vidioc_g_register    = cx23885_g_register,
 	.vidioc_s_register    = cx23885_s_register,
 #endif
@@ -1773,7 +1771,6 @@
 	.fops                 = &video_fops,
 	.ioctl_ops 	      = &video_ioctl_ops,
 	.tvnorms              = CX23885_NORMS,
-	.current_norm         = V4L2_STD_NTSC_M,
 };
 
 static const struct v4l2_file_operations radio_fops = {
@@ -1822,7 +1819,7 @@
 	cx23885_vbi_template = cx23885_video_template;
 	strcpy(cx23885_vbi_template.name, "cx23885-vbi");
 
-	dev->tvnorm = cx23885_video_template.current_norm;
+	dev->tvnorm = V4L2_STD_NTSC_M;
 
 	/* init video dma queues */
 	INIT_LIST_HEAD(&dev->vidq.active);
diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c
index fa672fe..2c951de 100644
--- a/drivers/media/pci/cx23885/cx23888-ir.c
+++ b/drivers/media/pci/cx23885/cx23888-ir.c
@@ -25,7 +25,6 @@
 #include <linux/slab.h>
 
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/rc-core.h>
 
 #include "cx23885.h"
@@ -131,8 +130,6 @@
 struct cx23888_ir_state {
 	struct v4l2_subdev sd;
 	struct cx23885_dev *dev;
-	u32 id;
-	u32 rev;
 
 	struct v4l2_subdev_ir_parameters rx_params;
 	struct mutex rx_params_lock;
@@ -1086,23 +1083,6 @@
 	return 0;
 }
 
-static inline int cx23888_ir_dbg_match(const struct v4l2_dbg_match *match)
-{
-	return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 2;
-}
-
-static int cx23888_ir_g_chip_ident(struct v4l2_subdev *sd,
-				   struct v4l2_dbg_chip_ident *chip)
-{
-	struct cx23888_ir_state *state = to_state(sd);
-
-	if (cx23888_ir_dbg_match(&chip->match)) {
-		chip->ident = state->id;
-		chip->revision = state->rev;
-	}
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int cx23888_ir_g_register(struct v4l2_subdev *sd,
 				 struct v4l2_dbg_register *reg)
@@ -1110,14 +1090,10 @@
 	struct cx23888_ir_state *state = to_state(sd);
 	u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
 
-	if (!cx23888_ir_dbg_match(&reg->match))
-		return -EINVAL;
 	if ((addr & 0x3) != 0)
 		return -EINVAL;
 	if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
 		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	reg->size = 4;
 	reg->val = cx23888_ir_read4(state->dev, addr);
 	return 0;
@@ -1129,21 +1105,16 @@
 	struct cx23888_ir_state *state = to_state(sd);
 	u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg;
 
-	if (!cx23888_ir_dbg_match(&reg->match))
-		return -EINVAL;
 	if ((addr & 0x3) != 0)
 		return -EINVAL;
 	if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG)
 		return -EINVAL;
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
 	cx23888_ir_write4(state->dev, addr, reg->val);
 	return 0;
 }
 #endif
 
 static const struct v4l2_subdev_core_ops cx23888_ir_core_ops = {
-	.g_chip_ident = cx23888_ir_g_chip_ident,
 	.log_status = cx23888_ir_log_status,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.g_register = cx23888_ir_g_register,
@@ -1217,8 +1188,6 @@
 		return -ENOMEM;
 
 	state->dev = dev;
-	state->id = V4L2_IDENT_CX23888_IR;
-	state->rev = 0;
 	sd = &state->sd;
 
 	v4l2_subdev_init(sd, &cx23888_ir_controller_ops);
diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c
index a87a0e1..e18a7ac 100644
--- a/drivers/media/pci/cx88/cx88-cards.c
+++ b/drivers/media/pci/cx88/cx88-cards.c
@@ -744,7 +744,7 @@
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 		/* Some variants use a tda9874 and so need the tvaudio module. */
-		.audio_chip     = V4L2_IDENT_TVAUDIO,
+		.audio_chip     = CX88_AUDIO_TVAUDIO,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -976,7 +976,7 @@
 		.radio_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.audio_chip	= V4L2_IDENT_WM8775,
+		.audio_chip	= CX88_AUDIO_WM8775,
 		.i2sinputcntl   = 2,
 		.input		= {{
 			.type	= CX88_VMUX_DVB,
@@ -1014,7 +1014,7 @@
 		.radio_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.audio_chip = V4L2_IDENT_WM8775,
+		.audio_chip = CX88_AUDIO_WM8775,
 		.input		= {{
 			.type	= CX88_VMUX_DVB,
 			.vmux	= 0,
@@ -1376,7 +1376,7 @@
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-		.audio_chip     = V4L2_IDENT_WM8775,
+		.audio_chip     = CX88_AUDIO_WM8775,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -1461,7 +1461,7 @@
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-		.audio_chip     = V4L2_IDENT_WM8775,
+		.audio_chip     = CX88_AUDIO_WM8775,
 		/*
 		 * gpio0 as reported by Mike Crash <mike AT mikecrash.com>
 		 */
@@ -1929,7 +1929,7 @@
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-		.audio_chip     = V4L2_IDENT_WM8775,
+		.audio_chip     = CX88_AUDIO_WM8775,
 		/*
 		 * GPIO0 (WINTV2000)
 		 *
diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c
index c8f3dcc..ad59dc9 100644
--- a/drivers/media/pci/cx88/cx88-core.c
+++ b/drivers/media/pci/cx88/cx88-core.c
@@ -1034,7 +1034,14 @@
 	if (NULL == vfd)
 		return NULL;
 	*vfd = *template_;
+	/*
+	 * The dev pointer of v4l2_device is NULL, instead we set the
+	 * video_device dev_parent pointer to the correct PCI bus device.
+	 * This driver is a rare example where there is one v4l2_device,
+	 * but the video nodes have different parent (PCI) devices.
+	 */
 	vfd->v4l2_dev = &core->v4l2_dev;
+	vfd->dev_parent = &pci->dev;
 	vfd->release = video_device_release;
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
 		 core->name, type, core->board.name);
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index c7a9be1..ecf21d9 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -1353,26 +1353,14 @@
 	return cx88_set_freq(core, f);
 }
 
-static int vidioc_g_chip_ident(struct file *file, void *priv,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	if (!v4l2_chip_match_host(&chip->match))
-		return -EINVAL;
-	chip->revision = 0;
-	chip->ident = V4L2_IDENT_UNKNOWN;
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int vidioc_g_register (struct file *file, void *fh,
 				struct v4l2_dbg_register *reg)
 {
 	struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
 	/* cx2388x has a 24-bit register space */
-	reg->val = cx_read(reg->reg & 0xffffff);
+	reg->val = cx_read(reg->reg & 0xfffffc);
 	reg->size = 4;
 	return 0;
 }
@@ -1382,9 +1370,7 @@
 {
 	struct cx88_core *core = ((struct cx8800_fh*)fh)->dev->core;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
-	cx_write(reg->reg & 0xffffff, reg->val);
+	cx_write(reg->reg & 0xfffffc, reg->val);
 	return 0;
 }
 #endif
@@ -1578,7 +1564,6 @@
 	.vidioc_s_frequency   = vidioc_s_frequency,
 	.vidioc_subscribe_event      = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event    = v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident  = vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
@@ -1612,7 +1597,6 @@
 	.vidioc_s_tuner       = vidioc_s_tuner,
 	.vidioc_g_frequency   = vidioc_g_frequency,
 	.vidioc_s_frequency   = vidioc_s_frequency,
-	.vidioc_g_chip_ident  = vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
@@ -1643,7 +1627,6 @@
 	.vidioc_s_frequency   = vidioc_s_frequency,
 	.vidioc_subscribe_event      = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event    = v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident  = vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register    = vidioc_g_register,
 	.vidioc_s_register    = vidioc_s_register,
@@ -1794,7 +1777,7 @@
 
 	/* load and configure helper modules */
 
-	if (core->board.audio_chip == V4L2_IDENT_WM8775) {
+	if (core->board.audio_chip == CX88_AUDIO_WM8775) {
 		struct i2c_board_info wm8775_info = {
 			.type = "wm8775",
 			.addr = 0x36 >> 1,
@@ -1815,7 +1798,7 @@
 		}
 	}
 
-	if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
+	if (core->board.audio_chip == CX88_AUDIO_TVAUDIO) {
 		/* This probes for a tda9874 as is used on some
 		   Pixelview Ultra boards. */
 		v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
index 51ce2c0..afe0eae 100644
--- a/drivers/media/pci/cx88/cx88.h
+++ b/drivers/media/pci/cx88/cx88.h
@@ -30,7 +30,6 @@
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/videobuf-dma-sg.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/cx2341x.h>
 #include <media/videobuf-dvb.h>
 #include <media/ir-kbd-i2c.h>
@@ -259,6 +258,11 @@
 	unsigned int    audioroute:4;
 };
 
+enum cx88_audio_chip {
+	CX88_AUDIO_WM8775,
+	CX88_AUDIO_TVAUDIO,
+};
+
 struct cx88_board {
 	const char              *name;
 	unsigned int            tuner_type;
@@ -269,7 +273,7 @@
 	struct cx88_input       input[MAX_CX88_INPUT];
 	struct cx88_input       radio;
 	enum cx88_board_type    mpeg;
-	unsigned int            audio_chip;
+	enum cx88_audio_chip	audio_chip;
 	int			num_frontends;
 
 	/* Used for I2S devices */
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index 026767b..ab797fe 100644
--- a/drivers/media/pci/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
@@ -1241,18 +1241,7 @@
 	.remove = dm1105_remove,
 };
 
-static int __init dm1105_init(void)
-{
-	return pci_register_driver(&dm1105_driver);
-}
-
-static void __exit dm1105_exit(void)
-{
-	pci_unregister_driver(&dm1105_driver);
-}
-
-module_init(dm1105_init);
-module_exit(dm1105_exit);
+module_pci_driver(dm1105_driver);
 
 MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
 MODULE_DESCRIPTION("SDMC DM1105 DVB driver");
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c
index b809bc8..c08ae3e 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.c
+++ b/drivers/media/pci/ivtv/ivtv-driver.c
@@ -58,7 +58,6 @@
 #include <linux/dma-mapping.h>
 #include <media/tveeprom.h>
 #include <media/saa7115.h>
-#include <media/v4l2-chip-ident.h>
 #include "tuner-xc2028.h"
 
 /* If you have already X v4l cards, then set this to X. This way
@@ -968,15 +967,10 @@
 	}
 
 	if (hw & IVTV_HW_SAA711X) {
-		struct v4l2_dbg_chip_ident v;
-
 		/* determine the exact saa711x model */
 		itv->hw_flags &= ~IVTV_HW_SAA711X;
 
-		v.match.type = V4L2_CHIP_MATCH_I2C_DRIVER;
-		strlcpy(v.match.name, "saa7115", sizeof(v.match.name));
-		ivtv_call_hw(itv, IVTV_HW_SAA711X, core, g_chip_ident, &v);
-		if (v.ident == V4L2_IDENT_SAA7114) {
+		if (strstr(itv->sd_video->name, "saa7114")) {
 			itv->hw_flags |= IVTV_HW_SAA7114;
 			/* VBI is not yet supported by the saa7114 driver. */
 			itv->v4l2_cap &= ~(V4L2_CAP_SLICED_VBI_CAPTURE|V4L2_CAP_VBI_CAPTURE);
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index 9cbbce0..807b275 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -34,7 +34,6 @@
 #include "ivtv-cards.h"
 #include <media/saa7127.h>
 #include <media/tveeprom.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-event.h>
 #include <linux/dvb/audio.h>
 
@@ -692,31 +691,13 @@
 	return ret;
 }
 
-static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
-{
-	struct ivtv *itv = fh2id(fh)->itv;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
-		if (v4l2_chip_match_host(&chip->match))
-			chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
-		return 0;
-	}
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-	    chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-	/* TODO: is this correct? */
-	return ivtv_call_all_err(itv, core, g_chip_ident, chip);
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int ivtv_itvc(struct ivtv *itv, bool get, u64 reg, u64 *val)
 {
 	volatile u8 __iomem *reg_start;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
+	if (reg & 0x3)
+		return -EINVAL;
 	if (reg >= IVTV_REG_OFFSET && reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
 		reg_start = itv->reg_mem - IVTV_REG_OFFSET;
 	else if (itv->has_cx23415 && reg >= IVTV_DECODER_OFFSET &&
@@ -738,29 +719,16 @@
 {
 	struct ivtv *itv = fh2id(fh)->itv;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		reg->size = 4;
-		return ivtv_itvc(itv, true, reg->reg, &reg->val);
-	}
-	/* TODO: subdev errors should not be ignored, this should become a
-	   subdev helper function. */
-	ivtv_call_all(itv, core, g_register, reg);
-	return 0;
+	reg->size = 4;
+	return ivtv_itvc(itv, true, reg->reg, &reg->val);
 }
 
 static int ivtv_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)
 {
 	struct ivtv *itv = fh2id(fh)->itv;
+	u64 val = reg->val;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		u64 val = reg->val;
-
-		return ivtv_itvc(itv, false, reg->reg, &val);
-	}
-	/* TODO: subdev errors should not be ignored, this should become a
-	   subdev helper function. */
-	ivtv_call_all(itv, core, s_register, reg);
-	return 0;
+	return ivtv_itvc(itv, false, reg->reg, &val);
 }
 #endif
 
@@ -1914,7 +1882,6 @@
 	.vidioc_try_fmt_vid_out_overlay     = ivtv_try_fmt_vid_out_overlay,
 	.vidioc_try_fmt_sliced_vbi_out 	    = ivtv_try_fmt_sliced_vbi_out,
 	.vidioc_g_sliced_vbi_cap 	    = ivtv_g_sliced_vbi_cap,
-	.vidioc_g_chip_ident 		    = ivtv_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register 		    = ivtv_g_register,
 	.vidioc_s_register 		    = ivtv_s_register,
diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c
index 6fe9fe5..104914a 100644
--- a/drivers/media/pci/mantis/hopper_cards.c
+++ b/drivers/media/pci/mantis/hopper_cards.c
@@ -260,18 +260,7 @@
 	.remove		= hopper_pci_remove,
 };
 
-static int hopper_init(void)
-{
-	return pci_register_driver(&hopper_pci_driver);
-}
-
-static void hopper_exit(void)
-{
-	return pci_unregister_driver(&hopper_pci_driver);
-}
-
-module_init(hopper_init);
-module_exit(hopper_exit);
+module_pci_driver(hopper_pci_driver);
 
 MODULE_DESCRIPTION("HOPPER driver");
 MODULE_AUTHOR("Manu Abraham");
diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c
index 932a0d7..801fc55 100644
--- a/drivers/media/pci/mantis/mantis_cards.c
+++ b/drivers/media/pci/mantis/mantis_cards.c
@@ -290,18 +290,7 @@
 	.remove		= mantis_pci_remove,
 };
 
-static int mantis_init(void)
-{
-	return pci_register_driver(&mantis_pci_driver);
-}
-
-static void mantis_exit(void)
-{
-	return pci_unregister_driver(&mantis_pci_driver);
-}
-
-module_init(mantis_init);
-module_exit(mantis_exit);
+module_pci_driver(mantis_pci_driver);
 
 MODULE_DESCRIPTION("MANTIS driver");
 MODULE_AUTHOR("Manu Abraham");
diff --git a/drivers/media/pci/mantis/mantis_vp1041.c b/drivers/media/pci/mantis/mantis_vp1041.c
index 07aa887..07a2074 100644
--- a/drivers/media/pci/mantis/mantis_vp1041.c
+++ b/drivers/media/pci/mantis/mantis_vp1041.c
@@ -273,7 +273,7 @@
 	.demod_address 		= 0x68, /*  0xd0 >> 1 */
 
 	.xtal_freq		= 27000000,
-	.inversion		= IQ_SWAP_ON, /* 1 */
+	.inversion		= IQ_SWAP_ON,
 
 	.lo_clk			= 76500000,
 	.hi_clk			= 99000000,
diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c
index 2290fae..4938285 100644
--- a/drivers/media/pci/pluto2/pluto2.c
+++ b/drivers/media/pci/pluto2/pluto2.c
@@ -796,18 +796,7 @@
 	.remove = pluto2_remove,
 };
 
-static int __init pluto2_init(void)
-{
-	return pci_register_driver(&pluto2_driver);
-}
-
-static void __exit pluto2_exit(void)
-{
-	pci_unregister_driver(&pluto2_driver);
-}
-
-module_init(pluto2_init);
-module_exit(pluto2_exit);
+module_pci_driver(pluto2_driver);
 
 MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
 MODULE_DESCRIPTION("Pluto2 driver");
diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
index e921108..75ce142 100644
--- a/drivers/media/pci/pt1/pt1.c
+++ b/drivers/media/pci/pt1/pt1.c
@@ -1225,20 +1225,7 @@
 	.id_table	= pt1_id_table,
 };
 
-
-static int __init pt1_init(void)
-{
-	return pci_register_driver(&pt1_driver);
-}
-
-
-static void __exit pt1_cleanup(void)
-{
-	pci_unregister_driver(&pt1_driver);
-}
-
-module_init(pt1_init);
-module_exit(pt1_cleanup);
+module_pci_driver(pt1_driver);
 
 MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>");
 MODULE_DESCRIPTION("Earthsoft PT1/PT2 Driver");
diff --git a/drivers/media/pci/saa7134/saa6752hs.c b/drivers/media/pci/saa7134/saa6752hs.c
index f147b05b..8ac4b1f 100644
--- a/drivers/media/pci/saa7134/saa6752hs.c
+++ b/drivers/media/pci/saa7134/saa6752hs.c
@@ -34,8 +34,8 @@
 #include <linux/types.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 #include <linux/init.h>
 #include <linux/crc32.h>
 
@@ -92,7 +92,12 @@
 
 struct saa6752hs_state {
 	struct v4l2_subdev            sd;
-	int 			      chip;
+	struct v4l2_ctrl_handler      hdl;
+	struct { /* video bitrate mode control cluster */
+		struct v4l2_ctrl *video_bitrate_mode;
+		struct v4l2_ctrl *video_bitrate;
+		struct v4l2_ctrl *video_bitrate_peak;
+	};
 	u32 			      revision;
 	int 			      has_ac3;
 	struct saa6752hs_mpeg_params  params;
@@ -362,314 +367,70 @@
 	return 0;
 }
 
-
-static int get_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
-		struct v4l2_ext_control *ctrl)
+static int saa6752hs_try_ctrl(struct v4l2_ctrl *ctrl)
 {
+	struct saa6752hs_state *h =
+		container_of(ctrl->handler, struct saa6752hs_state, hdl);
+
 	switch (ctrl->id) {
-	case V4L2_CID_MPEG_STREAM_TYPE:
-		ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_PMT:
-		ctrl->value = params->ts_pid_pmt;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
-		ctrl->value = params->ts_pid_audio;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
-		ctrl->value = params->ts_pid_video;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_PCR:
-		ctrl->value = params->ts_pid_pcr;
-		break;
-	case V4L2_CID_MPEG_AUDIO_ENCODING:
-		ctrl->value = params->au_encoding;
-		break;
-	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-		ctrl->value = params->au_l2_bitrate;
-		break;
-	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
-		if (!has_ac3)
-			return -EINVAL;
-		ctrl->value = params->au_ac3_bitrate;
-		break;
-	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
-		ctrl->value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
-		break;
-	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
-		break;
-	case V4L2_CID_MPEG_VIDEO_ASPECT:
-		ctrl->value = params->vi_aspect;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		ctrl->value = params->vi_bitrate * 1000;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
-		ctrl->value = params->vi_bitrate_peak * 1000;
-		break;
 	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-		ctrl->value = params->vi_bitrate_mode;
+		/* peak bitrate shall be >= normal bitrate */
+		if (ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
+		    h->video_bitrate_peak->val < h->video_bitrate->val)
+			h->video_bitrate_peak->val = h->video_bitrate->val;
 		break;
-	default:
-		return -EINVAL;
 	}
 	return 0;
 }
 
-static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
-		struct v4l2_ext_control *ctrl, int set)
+static int saa6752hs_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	int old = 0, new;
-
-	new = ctrl->value;
-	switch (ctrl->id) {
-	case V4L2_CID_MPEG_STREAM_TYPE:
-		old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
-		if (set && new != old)
-			return -ERANGE;
-		new = old;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_PMT:
-		old = params->ts_pid_pmt;
-		if (set && new > MPEG_PID_MAX)
-			return -ERANGE;
-		if (new > MPEG_PID_MAX)
-			new = MPEG_PID_MAX;
-		params->ts_pid_pmt = new;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
-		old = params->ts_pid_audio;
-		if (set && new > MPEG_PID_MAX)
-			return -ERANGE;
-		if (new > MPEG_PID_MAX)
-			new = MPEG_PID_MAX;
-		params->ts_pid_audio = new;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
-		old = params->ts_pid_video;
-		if (set && new > MPEG_PID_MAX)
-			return -ERANGE;
-		if (new > MPEG_PID_MAX)
-			new = MPEG_PID_MAX;
-		params->ts_pid_video = new;
-		break;
-	case V4L2_CID_MPEG_STREAM_PID_PCR:
-		old = params->ts_pid_pcr;
-		if (set && new > MPEG_PID_MAX)
-			return -ERANGE;
-		if (new > MPEG_PID_MAX)
-			new = MPEG_PID_MAX;
-		params->ts_pid_pcr = new;
-		break;
-	case V4L2_CID_MPEG_AUDIO_ENCODING:
-		old = params->au_encoding;
-		if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
-		    (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
-			return -ERANGE;
-		params->au_encoding = new;
-		break;
-	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-		old = params->au_l2_bitrate;
-		if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
-			   new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
-			return -ERANGE;
-		if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
-			new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
-		else
-			new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
-		params->au_l2_bitrate = new;
-		break;
-	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
-		if (!has_ac3)
-			return -EINVAL;
-		old = params->au_ac3_bitrate;
-		if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
-			   new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
-			return -ERANGE;
-		if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
-			new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
-		else
-			new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
-		params->au_ac3_bitrate = new;
-		break;
-	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
-		old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
-		if (set && new != old)
-			return -ERANGE;
-		new = old;
-		break;
-	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
-		if (set && new != old)
-			return -ERANGE;
-		new = old;
-		break;
-	case V4L2_CID_MPEG_VIDEO_ASPECT:
-		old = params->vi_aspect;
-		if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
-			   new != V4L2_MPEG_VIDEO_ASPECT_4x3)
-			return -ERANGE;
-		if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
-			new = V4L2_MPEG_VIDEO_ASPECT_4x3;
-		params->vi_aspect = new;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		old = params->vi_bitrate * 1000;
-		new = 1000 * (new / 1000);
-		if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-			return -ERANGE;
-		if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-			new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
-		params->vi_bitrate = new / 1000;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
-		old = params->vi_bitrate_peak * 1000;
-		new = 1000 * (new / 1000);
-		if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-			return -ERANGE;
-		if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
-			new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
-		params->vi_bitrate_peak = new / 1000;
-		break;
-	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-		old = params->vi_bitrate_mode;
-		params->vi_bitrate_mode = new;
-		break;
-	default:
-		return -EINVAL;
-	}
-	ctrl->value = new;
-	return 0;
-}
-
-
-static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
-{
-	struct saa6752hs_state *h = to_state(sd);
+	struct saa6752hs_state *h =
+		container_of(ctrl->handler, struct saa6752hs_state, hdl);
 	struct saa6752hs_mpeg_params *params = &h->params;
-	int err;
 
-	switch (qctrl->id) {
-	case V4L2_CID_MPEG_AUDIO_ENCODING:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
-				h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 :
-					V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
-				1, V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
-
-	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_L2_BITRATE_256K,
-				V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
-				V4L2_MPEG_AUDIO_L2_BITRATE_256K);
-
-	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
-		if (!h->has_ac3)
-			return -EINVAL;
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
-				V4L2_MPEG_AUDIO_AC3_BITRATE_384K, 1,
-				V4L2_MPEG_AUDIO_AC3_BITRATE_256K);
-
-	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
-				V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, 1,
-				V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
-
-	case V4L2_CID_MPEG_VIDEO_ENCODING:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
-				V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
-
-	case V4L2_CID_MPEG_VIDEO_ASPECT:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_VIDEO_ASPECT_4x3,
-				V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
-				V4L2_MPEG_VIDEO_ASPECT_4x3);
-
-	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
-		err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
-		if (err == 0 &&
-		    params->vi_bitrate_mode ==
-				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
-			qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
-		return err;
-
+	switch (ctrl->id) {
 	case V4L2_CID_MPEG_STREAM_TYPE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
-				V4L2_MPEG_STREAM_TYPE_MPEG2_TS, 1,
-				V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
-
-	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
-		return v4l2_ctrl_query_fill(qctrl,
-				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
-				V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
-				V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
-	case V4L2_CID_MPEG_VIDEO_BITRATE:
-		return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
-	case V4L2_CID_MPEG_STREAM_PID_PMT:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
-	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
-	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
-	case V4L2_CID_MPEG_STREAM_PID_PCR:
-		return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
-
-	default:
 		break;
-	}
-	return -EINVAL;
-}
-
-static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qmenu)
-{
-	static const u32 mpeg_audio_encoding[] = {
-		V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
-		V4L2_CTRL_MENU_IDS_END
-	};
-	static const u32 mpeg_audio_ac3_encoding[] = {
-		V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
-		V4L2_MPEG_AUDIO_ENCODING_AC3,
-		V4L2_CTRL_MENU_IDS_END
-	};
-	static u32 mpeg_audio_l2_bitrate[] = {
-		V4L2_MPEG_AUDIO_L2_BITRATE_256K,
-		V4L2_MPEG_AUDIO_L2_BITRATE_384K,
-		V4L2_CTRL_MENU_IDS_END
-	};
-	static u32 mpeg_audio_ac3_bitrate[] = {
-		V4L2_MPEG_AUDIO_AC3_BITRATE_256K,
-		V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
-		V4L2_CTRL_MENU_IDS_END
-	};
-	struct saa6752hs_state *h = to_state(sd);
-	struct v4l2_queryctrl qctrl;
-	int err;
-
-	qctrl.id = qmenu->id;
-	err = saa6752hs_queryctrl(sd, &qctrl);
-	if (err)
-		return err;
-	switch (qmenu->id) {
-	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
-		return v4l2_ctrl_query_menu_valid_items(qmenu,
-				mpeg_audio_l2_bitrate);
-	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
-		if (!h->has_ac3)
-			return -EINVAL;
-		return v4l2_ctrl_query_menu_valid_items(qmenu,
-				mpeg_audio_ac3_bitrate);
+	case V4L2_CID_MPEG_STREAM_PID_PMT:
+		params->ts_pid_pmt = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+		params->ts_pid_audio = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+		params->ts_pid_video = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_STREAM_PID_PCR:
+		params->ts_pid_pcr = ctrl->val;
+		break;
 	case V4L2_CID_MPEG_AUDIO_ENCODING:
-		return v4l2_ctrl_query_menu_valid_items(qmenu,
-			h->has_ac3 ? mpeg_audio_ac3_encoding :
-				mpeg_audio_encoding);
+		params->au_encoding = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+		params->au_l2_bitrate = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+		params->au_ac3_bitrate = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+		break;
+	case V4L2_CID_MPEG_VIDEO_ENCODING:
+		break;
+	case V4L2_CID_MPEG_VIDEO_ASPECT:
+		params->vi_aspect = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		params->vi_bitrate_mode = ctrl->val;
+		params->vi_bitrate = h->video_bitrate->val / 1000;
+		params->vi_bitrate_peak = h->video_bitrate_peak->val / 1000;
+		v4l2_ctrl_activate(h->video_bitrate_peak,
+				ctrl->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
+		break;
+	default:
+		return -EINVAL;
 	}
-	return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
+	return 0;
 }
 
 static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes)
@@ -793,58 +554,6 @@
 	return 0;
 }
 
-static int saa6752hs_do_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls, int set)
-{
-	struct saa6752hs_state *h = to_state(sd);
-	struct saa6752hs_mpeg_params params;
-	int i;
-
-	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-		return -EINVAL;
-
-	params = h->params;
-	for (i = 0; i < ctrls->count; i++) {
-		int err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, set);
-
-		if (err) {
-			ctrls->error_idx = i;
-			return err;
-		}
-	}
-	if (set)
-		h->params = params;
-	return 0;
-}
-
-static int saa6752hs_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
-	return saa6752hs_do_ext_ctrls(sd, ctrls, 1);
-}
-
-static int saa6752hs_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
-	return saa6752hs_do_ext_ctrls(sd, ctrls, 0);
-}
-
-static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
-{
-	struct saa6752hs_state *h = to_state(sd);
-	int i;
-
-	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
-		return -EINVAL;
-
-	for (i = 0; i < ctrls->count; i++) {
-		int err = get_ctrl(h->has_ac3, &h->params, ctrls->controls + i);
-
-		if (err) {
-			ctrls->error_idx = i;
-			return err;
-		}
-	}
-	return 0;
-}
-
 static int saa6752hs_g_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
 {
 	struct saa6752hs_state *h = to_state(sd);
@@ -859,10 +568,36 @@
 	return 0;
 }
 
+static int saa6752hs_try_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
+{
+	int dist_352, dist_480, dist_720;
+
+	f->code = V4L2_MBUS_FMT_FIXED;
+
+	dist_352 = abs(f->width - 352);
+	dist_480 = abs(f->width - 480);
+	dist_720 = abs(f->width - 720);
+	if (dist_720 < dist_480) {
+		f->width = 720;
+		f->height = 576;
+	} else if (dist_480 < dist_352) {
+		f->width = 480;
+		f->height = 576;
+	} else {
+		f->width = 352;
+		if (abs(f->height - 576) < abs(f->height - 288))
+			f->height = 576;
+		else
+			f->height = 288;
+	}
+	f->field = V4L2_FIELD_INTERLACED;
+	f->colorspace = V4L2_COLORSPACE_SMPTE170M;
+	return 0;
+}
+
 static int saa6752hs_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
 {
 	struct saa6752hs_state *h = to_state(sd);
-	int dist_352, dist_480, dist_720;
 
 	if (f->code != V4L2_MBUS_FMT_FIXED)
 		return -EINVAL;
@@ -879,30 +614,15 @@
 	  D1     | 720x576 | 720x480
 	*/
 
-	dist_352 = abs(f->width - 352);
-	dist_480 = abs(f->width - 480);
-	dist_720 = abs(f->width - 720);
-	if (dist_720 < dist_480) {
-		f->width = 720;
-		f->height = 576;
+	saa6752hs_try_mbus_fmt(sd, f);
+	if (f->width == 720)
 		h->video_format = SAA6752HS_VF_D1;
-	} else if (dist_480 < dist_352) {
-		f->width = 480;
-		f->height = 576;
+	else if (f->width == 480)
 		h->video_format = SAA6752HS_VF_2_3_D1;
-	} else {
-		f->width = 352;
-		if (abs(f->height - 576) <
-		    abs(f->height - 288)) {
-			f->height = 576;
-			h->video_format = SAA6752HS_VF_1_2_D1;
-		} else {
-			f->height = 288;
-			h->video_format = SAA6752HS_VF_SIF;
-		}
-	}
-	f->field = V4L2_FIELD_INTERLACED;
-	f->colorspace = V4L2_COLORSPACE_SMPTE170M;
+	else if (f->height == 576)
+		h->video_format = SAA6752HS_VF_1_2_D1;
+	else
+		h->video_format = SAA6752HS_VF_SIF;
 	return 0;
 }
 
@@ -914,30 +634,28 @@
 	return 0;
 }
 
-static int saa6752hs_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct saa6752hs_state *h = to_state(sd);
-
-	return v4l2_chip_ident_i2c_client(client,
-			chip, h->chip, h->revision);
-}
-
 /* ----------------------------------------------------------------------- */
 
+static const struct v4l2_ctrl_ops saa6752hs_ctrl_ops = {
+	.try_ctrl = saa6752hs_try_ctrl,
+	.s_ctrl = saa6752hs_s_ctrl,
+};
+
 static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
-	.g_chip_ident = saa6752hs_g_chip_ident,
 	.init = saa6752hs_init,
-	.queryctrl = saa6752hs_queryctrl,
-	.querymenu = saa6752hs_querymenu,
-	.g_ext_ctrls = saa6752hs_g_ext_ctrls,
-	.s_ext_ctrls = saa6752hs_s_ext_ctrls,
-	.try_ext_ctrls = saa6752hs_try_ext_ctrls,
+	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+	.g_ctrl = v4l2_subdev_g_ctrl,
+	.s_ctrl = v4l2_subdev_s_ctrl,
+	.queryctrl = v4l2_subdev_queryctrl,
+	.querymenu = v4l2_subdev_querymenu,
 	.s_std = saa6752hs_s_std,
 };
 
 static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
 	.s_mbus_fmt = saa6752hs_s_mbus_fmt,
+	.try_mbus_fmt = saa6752hs_try_mbus_fmt,
 	.g_mbus_fmt = saa6752hs_g_mbus_fmt,
 };
 
@@ -951,6 +669,7 @@
 {
 	struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
 	struct v4l2_subdev *sd;
+	struct v4l2_ctrl_handler *hdl;
 	u8 addr = 0x13;
 	u8 data[12];
 
@@ -963,15 +682,88 @@
 
 	i2c_master_send(client, &addr, 1);
 	i2c_master_recv(client, data, sizeof(data));
-	h->chip = V4L2_IDENT_SAA6752HS;
 	h->revision = (data[8] << 8) | data[9];
 	h->has_ac3 = 0;
 	if (h->revision == 0x0206) {
-		h->chip = V4L2_IDENT_SAA6752HS_AC3;
 		h->has_ac3 = 1;
-		v4l_info(client, "support AC-3\n");
+		v4l_info(client, "supports AC-3\n");
 	}
 	h->params = param_defaults;
+
+	hdl = &h->hdl;
+	v4l2_ctrl_handler_init(hdl, 14);
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_AUDIO_ENCODING,
+		h->has_ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3 :
+			V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+		0x0d, V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
+
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_AUDIO_L2_BITRATE,
+		V4L2_MPEG_AUDIO_L2_BITRATE_384K,
+		~((1 << V4L2_MPEG_AUDIO_L2_BITRATE_256K) |
+		  (1 << V4L2_MPEG_AUDIO_L2_BITRATE_384K)),
+		V4L2_MPEG_AUDIO_L2_BITRATE_256K);
+
+	if (h->has_ac3)
+		v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+			V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
+			V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
+			~((1 << V4L2_MPEG_AUDIO_AC3_BITRATE_256K) |
+			  (1 << V4L2_MPEG_AUDIO_AC3_BITRATE_384K)),
+			V4L2_MPEG_AUDIO_AC3_BITRATE_256K);
+
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
+		V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
+		~(1 << V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000),
+		V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
+
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_VIDEO_ENCODING,
+		V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
+		~(1 << V4L2_MPEG_VIDEO_ENCODING_MPEG_2),
+		V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
+
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_VIDEO_ASPECT,
+		V4L2_MPEG_VIDEO_ASPECT_16x9, 0x01,
+		V4L2_MPEG_VIDEO_ASPECT_4x3);
+
+	h->video_bitrate_peak = v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+		1000000, 27000000, 1000, 8000000);
+
+	v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_STREAM_TYPE,
+		V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
+		~(1 << V4L2_MPEG_STREAM_TYPE_MPEG2_TS),
+		V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
+
+	h->video_bitrate_mode = v4l2_ctrl_new_std_menu(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+		V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
+		V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
+	h->video_bitrate = v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_VIDEO_BITRATE, 1000000, 27000000, 1000, 6000000);
+	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_STREAM_PID_PMT, 0, (1 << 14) - 1, 1, 16);
+	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_STREAM_PID_AUDIO, 0, (1 << 14) - 1, 1, 260);
+	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_STREAM_PID_VIDEO, 0, (1 << 14) - 1, 1, 256);
+	v4l2_ctrl_new_std(hdl, &saa6752hs_ctrl_ops,
+		V4L2_CID_MPEG_STREAM_PID_PCR, 0, (1 << 14) - 1, 1, 259);
+	sd->ctrl_handler = hdl;
+	if (hdl->error) {
+		int err = hdl->error;
+
+		v4l2_ctrl_handler_free(hdl);
+		kfree(h);
+		return err;
+	}
+	v4l2_ctrl_cluster(3, &h->video_bitrate_mode);
+	v4l2_ctrl_handler_setup(hdl);
 	h->standard = 0; /* Assume 625 input lines */
 	return 0;
 }
@@ -981,6 +773,7 @@
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
 	v4l2_device_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&to_state(sd)->hdl);
 	kfree(to_state(sd));
 	return 0;
 }
@@ -1002,11 +795,3 @@
 };
 
 module_i2c_driver(saa6752hs_driver);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c
index 66a7081..3022eb2 100644
--- a/drivers/media/pci/saa7134/saa7134-empress.c
+++ b/drivers/media/pci/saa7134/saa7134-empress.c
@@ -28,7 +28,6 @@
 
 #include <media/saa6752hs.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 
 /* ------------------------------------------------------------------ */
 
@@ -213,7 +212,7 @@
 
 	strlcpy(f->description, "MPEG TS", sizeof(f->description));
 	f->pixelformat = V4L2_PIX_FMT_MPEG;
-
+	f->flags = V4L2_FMT_FLAG_COMPRESSED;
 	return 0;
 }
 
@@ -228,6 +227,8 @@
 	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
+	f->fmt.pix.bytesperline = 0;
+	f->fmt.pix.priv = 0;
 
 	return 0;
 }
@@ -244,6 +245,8 @@
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
+	f->fmt.pix.bytesperline = 0;
+	f->fmt.pix.priv = 0;
 
 	return 0;
 }
@@ -252,9 +255,16 @@
 				struct v4l2_format *f)
 {
 	struct saa7134_dev *dev = file->private_data;
+	struct v4l2_mbus_framefmt mbus_fmt;
+
+	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
+	saa_call_all(dev, video, try_mbus_fmt, &mbus_fmt);
+	v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
 
 	f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
 	f->fmt.pix.sizeimage    = TS_PACKET_SIZE * dev->ts.nr_packets;
+	f->fmt.pix.bytesperline = 0;
+	f->fmt.pix.priv = 0;
 
 	return 0;
 }
@@ -413,21 +423,6 @@
 	return saa_call_empress(dev, core, querymenu, c);
 }
 
-static int empress_g_chip_ident(struct file *file, void *fh,
-	       struct v4l2_dbg_chip_ident *chip)
-{
-	struct saa7134_dev *dev = file->private_data;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER &&
-	    !strcmp(chip->match.name, "saa6752hs"))
-		return saa_call_empress(dev, core, g_chip_ident, chip);
-	if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR)
-		return saa_call_empress(dev, core, g_chip_ident, chip);
-	return -EINVAL;
-}
-
 static int empress_s_std(struct file *file, void *priv, v4l2_std_id id)
 {
 	struct saa7134_dev *dev = file->private_data;
@@ -475,7 +470,6 @@
 	.vidioc_querymenu		= empress_querymenu,
 	.vidioc_g_ctrl			= empress_g_ctrl,
 	.vidioc_s_ctrl			= empress_s_ctrl,
-	.vidioc_g_chip_ident 		= empress_g_chip_ident,
 	.vidioc_s_std			= empress_s_std,
 	.vidioc_g_std			= empress_g_std,
 };
@@ -488,7 +482,6 @@
 	.ioctl_ops     = &ts_ioctl_ops,
 
 	.tvnorms			= SAA7134_NORMS,
-	.current_norm			= V4L2_STD_PAL,
 };
 
 static void empress_signal_update(struct work_struct *work)
@@ -518,7 +511,7 @@
 	if (NULL == dev->empress_dev)
 		return -ENOMEM;
 	*(dev->empress_dev) = saa7134_empress_template;
-	dev->empress_dev->parent  = &dev->pci->dev;
+	dev->empress_dev->v4l2_dev  = &dev->v4l2_dev;
 	dev->empress_dev->release = video_device_release;
 	snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
 		 "%s empress (%s)", dev->name,
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index cc40938..e12bbd8 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -825,20 +825,22 @@
 	return 0;
 }
 
-static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
+static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win, bool try)
 {
 	enum v4l2_field field;
 	int maxw, maxh;
 
-	if (NULL == dev->ovbuf.base)
+	if (!try && (dev->ovbuf.base == NULL || dev->ovfmt == NULL))
 		return -EINVAL;
-	if (NULL == dev->ovfmt)
-		return -EINVAL;
-	if (win->w.width < 48 || win->w.height <  32)
-		return -EINVAL;
-	if (win->clipcount > 2048)
-		return -EINVAL;
+	if (win->w.width < 48)
+		win->w.width = 48;
+	if (win->w.height < 32)
+		win->w.height = 32;
+	if (win->clipcount > 8)
+		win->clipcount = 8;
 
+	win->chromakey = 0;
+	win->global_alpha = 0;
 	field = win->field;
 	maxw  = dev->crop_current.width;
 	maxh  = dev->crop_current.height;
@@ -853,10 +855,9 @@
 	case V4L2_FIELD_BOTTOM:
 		maxh = maxh / 2;
 		break;
-	case V4L2_FIELD_INTERLACED:
-		break;
 	default:
-		return -EINVAL;
+		field = V4L2_FIELD_INTERLACED;
+		break;
 	}
 
 	win->field = field;
@@ -872,20 +873,20 @@
 	unsigned long base,control,bpl;
 	int err;
 
-	err = verify_preview(dev,&fh->win);
+	err = verify_preview(dev, &dev->win, false);
 	if (0 != err)
 		return err;
 
-	dev->ovfield = fh->win.field;
+	dev->ovfield = dev->win.field;
 	dprintk("start_preview %dx%d+%d+%d %s field=%s\n",
-		fh->win.w.width,fh->win.w.height,
-		fh->win.w.left,fh->win.w.top,
-		dev->ovfmt->name,v4l2_field_names[dev->ovfield]);
+		dev->win.w.width, dev->win.w.height,
+		dev->win.w.left, dev->win.w.top,
+		dev->ovfmt->name, v4l2_field_names[dev->ovfield]);
 
 	/* setup window + clipping */
-	set_size(dev,TASK_B,fh->win.w.width,fh->win.w.height,
+	set_size(dev, TASK_B, dev->win.w.width, dev->win.w.height,
 		 V4L2_FIELD_HAS_BOTH(dev->ovfield));
-	setup_clipping(dev,fh->clips,fh->nclips,
+	setup_clipping(dev, dev->clips, dev->nclips,
 		       V4L2_FIELD_HAS_BOTH(dev->ovfield));
 	if (dev->ovfmt->yuv)
 		saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03);
@@ -895,8 +896,8 @@
 
 	/* dma: setup channel 1 (= Video Task B) */
 	base  = (unsigned long)dev->ovbuf.base;
-	base += dev->ovbuf.fmt.bytesperline * fh->win.w.top;
-	base += dev->ovfmt->depth/8         * fh->win.w.left;
+	base += dev->ovbuf.fmt.bytesperline * dev->win.w.top;
+	base += dev->ovfmt->depth/8         * dev->win.w.left;
 	bpl   = dev->ovbuf.fmt.bytesperline;
 	control = SAA7134_RS_CONTROL_BURST_16;
 	if (dev->ovfmt->bswap)
@@ -1024,38 +1025,38 @@
 	int err;
 
 	/* sanity checks */
-	if (NULL == fh->fmt)
+	if (NULL == dev->fmt)
 		return -EINVAL;
-	if (fh->width    < 48 ||
-	    fh->height   < 32 ||
-	    fh->width/4  > dev->crop_current.width  ||
-	    fh->height/4 > dev->crop_current.height ||
-	    fh->width    > dev->crop_bounds.width  ||
-	    fh->height   > dev->crop_bounds.height)
+	if (dev->width    < 48 ||
+	    dev->height   < 32 ||
+	    dev->width/4  > dev->crop_current.width  ||
+	    dev->height/4 > dev->crop_current.height ||
+	    dev->width    > dev->crop_bounds.width  ||
+	    dev->height   > dev->crop_bounds.height)
 		return -EINVAL;
-	size = (fh->width * fh->height * fh->fmt->depth) >> 3;
+	size = (dev->width * dev->height * dev->fmt->depth) >> 3;
 	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
 		return -EINVAL;
 
 	dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n",
-		vb->i,fh->width,fh->height,size,v4l2_field_names[field],
-		fh->fmt->name);
-	if (buf->vb.width  != fh->width  ||
-	    buf->vb.height != fh->height ||
+		vb->i, dev->width, dev->height, size, v4l2_field_names[field],
+		dev->fmt->name);
+	if (buf->vb.width  != dev->width  ||
+	    buf->vb.height != dev->height ||
 	    buf->vb.size   != size       ||
 	    buf->vb.field  != field      ||
-	    buf->fmt       != fh->fmt) {
+	    buf->fmt       != dev->fmt) {
 		saa7134_dma_free(q,buf);
 	}
 
 	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
 		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 
-		buf->vb.width  = fh->width;
-		buf->vb.height = fh->height;
+		buf->vb.width  = dev->width;
+		buf->vb.height = dev->height;
 		buf->vb.size   = size;
 		buf->vb.field  = field;
-		buf->fmt       = fh->fmt;
+		buf->fmt       = dev->fmt;
 		buf->pt        = &fh->pt_cap;
 		dev->video_q.curr = NULL;
 
@@ -1082,8 +1083,9 @@
 buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
 {
 	struct saa7134_fh *fh = q->priv_data;
+	struct saa7134_dev *dev = fh->dev;
 
-	*size = fh->fmt->depth * fh->width * fh->height >> 3;
+	*size = dev->fmt->depth * dev->width * dev->height >> 3;
 	if (0 == *count)
 		*count = gbuffers;
 	*count = saa7134_buffer_count(*size,*count);
@@ -1287,15 +1289,17 @@
 
 /* ------------------------------------------------------------------ */
 
-static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh)
+static struct videobuf_queue *saa7134_queue(struct file *file)
 {
-	struct videobuf_queue* q = NULL;
+	struct video_device *vdev = video_devdata(file);
+	struct saa7134_fh *fh = file->private_data;
+	struct videobuf_queue *q = NULL;
 
-	switch (fh->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	switch (vdev->vfl_type) {
+	case VFL_TYPE_GRABBER:
 		q = &fh->cap;
 		break;
-	case V4L2_BUF_TYPE_VBI_CAPTURE:
+	case VFL_TYPE_VBI:
 		q = &fh->vbi;
 		break;
 	default:
@@ -1304,12 +1308,14 @@
 	return q;
 }
 
-static int saa7134_resource(struct saa7134_fh *fh)
+static int saa7134_resource(struct file *file)
 {
-	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+	struct video_device *vdev = video_devdata(file);
+
+	if (vdev->vfl_type == VFL_TYPE_GRABBER)
 		return RESOURCE_VIDEO;
 
-	if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+	if (vdev->vfl_type == VFL_TYPE_VBI)
 		return RESOURCE_VBI;
 
 	BUG();
@@ -1321,23 +1327,6 @@
 	struct video_device *vdev = video_devdata(file);
 	struct saa7134_dev *dev = video_drvdata(file);
 	struct saa7134_fh *fh;
-	enum v4l2_buf_type type = 0;
-	int radio = 0;
-
-	switch (vdev->vfl_type) {
-	case VFL_TYPE_GRABBER:
-		type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		break;
-	case VFL_TYPE_VBI:
-		type = V4L2_BUF_TYPE_VBI_CAPTURE;
-		break;
-	case VFL_TYPE_RADIO:
-		radio = 1;
-		break;
-	}
-
-	dprintk("open dev=%s radio=%d type=%s\n", video_device_node_name(vdev),
-		radio, v4l2_type_names[type]);
 
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh),GFP_KERNEL);
@@ -1347,11 +1336,6 @@
 	v4l2_fh_init(&fh->fh, vdev);
 	file->private_data = fh;
 	fh->dev      = dev;
-	fh->radio    = radio;
-	fh->type     = type;
-	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);
-	fh->width    = 720;
-	fh->height   = 576;
 
 	videobuf_queue_sg_init(&fh->cap, &video_qops,
 			    &dev->pci->dev, &dev->slock,
@@ -1368,7 +1352,7 @@
 	saa7134_pgtable_alloc(dev->pci,&fh->pt_cap);
 	saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi);
 
-	if (fh->radio) {
+	if (vdev->vfl_type == VFL_TYPE_RADIO) {
 		/* switch to radio mode */
 		saa7134_tvaudio_setinput(dev,&card(dev).radio);
 		saa_call_all(dev, tuner, s_radio);
@@ -1384,19 +1368,20 @@
 static ssize_t
 video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct saa7134_fh *fh = file->private_data;
 
-	switch (fh->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	switch (vdev->vfl_type) {
+	case VFL_TYPE_GRABBER:
 		if (res_locked(fh->dev,RESOURCE_VIDEO))
 			return -EBUSY;
-		return videobuf_read_one(saa7134_queue(fh),
+		return videobuf_read_one(saa7134_queue(file),
 					 data, count, ppos,
 					 file->f_flags & O_NONBLOCK);
-	case V4L2_BUF_TYPE_VBI_CAPTURE:
+	case VFL_TYPE_VBI:
 		if (!res_get(fh->dev,fh,RESOURCE_VBI))
 			return -EBUSY;
-		return videobuf_read_stream(saa7134_queue(fh),
+		return videobuf_read_stream(saa7134_queue(file),
 					    data, count, ppos, 1,
 					    file->f_flags & O_NONBLOCK);
 		break;
@@ -1409,11 +1394,12 @@
 static unsigned int
 video_poll(struct file *file, struct poll_table_struct *wait)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct saa7134_fh *fh = file->private_data;
 	struct videobuf_buffer *buf = NULL;
 	unsigned int rc = 0;
 
-	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
+	if (vdev->vfl_type == VFL_TYPE_VBI)
 		return videobuf_poll_stream(file, &fh->vbi, wait);
 
 	if (res_check(fh,RESOURCE_VIDEO)) {
@@ -1451,6 +1437,7 @@
 
 static int video_release(struct file *file)
 {
+	struct video_device *vdev = video_devdata(file);
 	struct saa7134_fh  *fh  = file->private_data;
 	struct saa7134_dev *dev = fh->dev;
 	struct saa6588_command cmd;
@@ -1489,7 +1476,7 @@
 	saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
 
 	saa_call_all(dev, core, s_power, 0);
-	if (fh->radio)
+	if (vdev->vfl_type == VFL_TYPE_RADIO)
 		saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd);
 
 	/* free stuff */
@@ -1507,9 +1494,7 @@
 
 static int video_mmap(struct file *file, struct vm_area_struct * vma)
 {
-	struct saa7134_fh *fh = file->private_data;
-
-	return videobuf_mmap_mapper(saa7134_queue(fh), vma);
+	return videobuf_mmap_mapper(saa7134_queue(file), vma);
 }
 
 static ssize_t radio_read(struct file *file, char __user *data,
@@ -1570,15 +1555,18 @@
 				struct v4l2_format *f)
 {
 	struct saa7134_fh *fh = priv;
+	struct saa7134_dev *dev = fh->dev;
 
-	f->fmt.pix.width        = fh->width;
-	f->fmt.pix.height       = fh->height;
+	f->fmt.pix.width        = dev->width;
+	f->fmt.pix.height       = dev->height;
 	f->fmt.pix.field        = fh->cap.field;
-	f->fmt.pix.pixelformat  = fh->fmt->fourcc;
+	f->fmt.pix.pixelformat  = dev->fmt->fourcc;
 	f->fmt.pix.bytesperline =
-		(f->fmt.pix.width * fh->fmt->depth) >> 3;
+		(f->fmt.pix.width * dev->fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
 		f->fmt.pix.height * f->fmt.pix.bytesperline;
+	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
+	f->fmt.pix.priv = 0;
 	return 0;
 }
 
@@ -1586,14 +1574,33 @@
 				struct v4l2_format *f)
 {
 	struct saa7134_fh *fh = priv;
+	struct saa7134_dev *dev = fh->dev;
+	struct v4l2_clip __user *clips = f->fmt.win.clips;
+	u32 clipcount = f->fmt.win.clipcount;
+	int err = 0;
+	int i;
 
 	if (saa7134_no_overlay > 0) {
 		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
 		return -EINVAL;
 	}
-	f->fmt.win = fh->win;
+	mutex_lock(&dev->lock);
+	f->fmt.win = dev->win;
+	f->fmt.win.clips = clips;
+	if (clips == NULL)
+		clipcount = 0;
+	if (dev->nclips < clipcount)
+		clipcount = dev->nclips;
+	f->fmt.win.clipcount = clipcount;
 
-	return 0;
+	for (i = 0; !err && i < clipcount; i++) {
+		if (copy_to_user(&f->fmt.win.clips[i].c, &dev->clips[i].c,
+					sizeof(struct v4l2_rect)))
+			err = -EFAULT;
+	}
+	mutex_unlock(&dev->lock);
+
+	return err;
 }
 
 static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
@@ -1623,10 +1630,9 @@
 	case V4L2_FIELD_BOTTOM:
 		maxh = maxh / 2;
 		break;
-	case V4L2_FIELD_INTERLACED:
-		break;
 	default:
-		return -EINVAL;
+		field = V4L2_FIELD_INTERLACED;
+		break;
 	}
 
 	f->fmt.pix.field = field;
@@ -1643,6 +1649,8 @@
 		(f->fmt.pix.width * fmt->depth) >> 3;
 	f->fmt.pix.sizeimage =
 		f->fmt.pix.height * f->fmt.pix.bytesperline;
+	f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
+	f->fmt.pix.priv = 0;
 
 	return 0;
 }
@@ -1658,22 +1666,25 @@
 		return -EINVAL;
 	}
 
-	return verify_preview(dev, &f->fmt.win);
+	if (f->fmt.win.clips == NULL)
+		f->fmt.win.clipcount = 0;
+	return verify_preview(dev, &f->fmt.win, true);
 }
 
 static int saa7134_s_fmt_vid_cap(struct file *file, void *priv,
 					struct v4l2_format *f)
 {
 	struct saa7134_fh *fh = priv;
+	struct saa7134_dev *dev = fh->dev;
 	int err;
 
 	err = saa7134_try_fmt_vid_cap(file, priv, f);
 	if (0 != err)
 		return err;
 
-	fh->fmt       = format_by_fourcc(f->fmt.pix.pixelformat);
-	fh->width     = f->fmt.pix.width;
-	fh->height    = f->fmt.pix.height;
+	dev->fmt       = format_by_fourcc(f->fmt.pix.pixelformat);
+	dev->width     = f->fmt.pix.width;
+	dev->height    = f->fmt.pix.height;
 	fh->cap.field = f->fmt.pix.field;
 	return 0;
 }
@@ -1690,20 +1701,19 @@
 		printk(KERN_ERR "V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
 		return -EINVAL;
 	}
-	err = verify_preview(dev, &f->fmt.win);
+	if (f->fmt.win.clips == NULL)
+		f->fmt.win.clipcount = 0;
+	err = verify_preview(dev, &f->fmt.win, true);
 	if (0 != err)
 		return err;
 
 	mutex_lock(&dev->lock);
 
-	fh->win    = f->fmt.win;
-	fh->nclips = f->fmt.win.clipcount;
+	dev->win    = f->fmt.win;
+	dev->nclips = f->fmt.win.clipcount;
 
-	if (fh->nclips > 8)
-		fh->nclips = 8;
-
-	if (copy_from_user(fh->clips, f->fmt.win.clips,
-			   sizeof(struct v4l2_clip)*fh->nclips)) {
+	if (copy_from_user(dev->clips, f->fmt.win.clips,
+			   sizeof(struct v4l2_clip) * dev->nclips)) {
 		mutex_unlock(&dev->lock);
 		return -EFAULT;
 	}
@@ -2057,7 +2067,6 @@
 	if (0 != f->tuner)
 		return -EINVAL;
 
-	f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 	saa_call_all(dev, tuner, g_frequency, f);
 
 	return 0;
@@ -2071,10 +2080,6 @@
 
 	if (0 != f->tuner)
 		return -EINVAL;
-	if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
-		return -EINVAL;
-	if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
-		return -EINVAL;
 	mutex_lock(&dev->lock);
 
 	saa_call_all(dev, tuner, s_frequency, f);
@@ -2186,27 +2191,23 @@
 static int saa7134_reqbufs(struct file *file, void *priv,
 					struct v4l2_requestbuffers *p)
 {
-	struct saa7134_fh *fh = priv;
-	return videobuf_reqbufs(saa7134_queue(fh), p);
+	return videobuf_reqbufs(saa7134_queue(file), p);
 }
 
 static int saa7134_querybuf(struct file *file, void *priv,
 					struct v4l2_buffer *b)
 {
-	struct saa7134_fh *fh = priv;
-	return videobuf_querybuf(saa7134_queue(fh), b);
+	return videobuf_querybuf(saa7134_queue(file), b);
 }
 
 static int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 {
-	struct saa7134_fh *fh = priv;
-	return videobuf_qbuf(saa7134_queue(fh), b);
+	return videobuf_qbuf(saa7134_queue(file), b);
 }
 
 static int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 {
-	struct saa7134_fh *fh = priv;
-	return videobuf_dqbuf(saa7134_queue(fh), b,
+	return videobuf_dqbuf(saa7134_queue(file), b,
 				file->f_flags & O_NONBLOCK);
 }
 
@@ -2215,7 +2216,7 @@
 {
 	struct saa7134_fh *fh = priv;
 	struct saa7134_dev *dev = fh->dev;
-	int res = saa7134_resource(fh);
+	int res = saa7134_resource(file);
 
 	if (!res_get(dev, fh, res))
 		return -EBUSY;
@@ -2227,11 +2228,11 @@
 	 * Unfortunately, I lack register-level documentation to check the
 	 * Linux FIFO setup and confirm the perfect value.
 	 */
-	pm_qos_add_request(&fh->qos_request,
+	pm_qos_add_request(&dev->qos_request,
 			   PM_QOS_CPU_DMA_LATENCY,
 			   20);
 
-	return videobuf_streamon(saa7134_queue(fh));
+	return videobuf_streamon(saa7134_queue(file));
 }
 
 static int saa7134_streamoff(struct file *file, void *priv,
@@ -2240,11 +2241,11 @@
 	int err;
 	struct saa7134_fh *fh = priv;
 	struct saa7134_dev *dev = fh->dev;
-	int res = saa7134_resource(fh);
+	int res = saa7134_resource(file);
 
-	pm_qos_remove_request(&fh->qos_request);
+	pm_qos_remove_request(&dev->qos_request);
 
-	err = videobuf_streamoff(saa7134_queue(fh));
+	err = videobuf_streamoff(saa7134_queue(file));
 	if (err < 0)
 		return err;
 	res_free(dev, fh, res);
@@ -2258,9 +2259,7 @@
 	struct saa7134_fh *fh = priv;
 	struct saa7134_dev *dev = fh->dev;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
-	reg->val = saa_readb(reg->reg);
+	reg->val = saa_readb(reg->reg & 0xffffff);
 	reg->size = 1;
 	return 0;
 }
@@ -2271,9 +2270,7 @@
 	struct saa7134_fh *fh = priv;
 	struct saa7134_dev *dev = fh->dev;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
-	saa_writeb(reg->reg&0xffffff, reg->val);
+	saa_writeb(reg->reg & 0xffffff, reg->val);
 	return 0;
 }
 #endif
@@ -2287,9 +2284,7 @@
 	if (0 != t->index)
 		return -EINVAL;
 
-	memset(t, 0, sizeof(*t));
 	strcpy(t->name, "Radio");
-	t->type = V4L2_TUNER_RADIO;
 
 	saa_call_all(dev, tuner, g_tuner, t);
 	t->audmode &= V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO;
@@ -2443,7 +2438,6 @@
 	.fops				= &video_fops,
 	.ioctl_ops 			= &video_ioctl_ops,
 	.tvnorms			= SAA7134_NORMS,
-	.current_norm			= V4L2_STD_PAL,
 };
 
 struct video_device saa7134_radio_template = {
@@ -2480,6 +2474,16 @@
 	dev->video_q.timeout.function = saa7134_buffer_timeout;
 	dev->video_q.timeout.data     = (unsigned long)(&dev->video_q);
 	dev->video_q.dev              = dev;
+	dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
+	dev->width    = 720;
+	dev->height   = 576;
+	dev->win.w.width = dev->width;
+	dev->win.w.height = dev->height;
+	dev->win.field = V4L2_FIELD_INTERLACED;
+	dev->ovbuf.fmt.width = dev->width;
+	dev->ovbuf.fmt.height = dev->height;
+	dev->ovbuf.fmt.pixelformat = dev->fmt->fourcc;
+	dev->ovbuf.fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
 
 	if (saa7134_boards[dev->board].video_out)
 		saa7134_videoport_init(dev);
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index d2ad16c..8d1453a 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -471,19 +471,9 @@
 struct saa7134_fh {
 	struct v4l2_fh             fh;
 	struct saa7134_dev         *dev;
-	unsigned int               radio;
-	enum v4l2_buf_type         type;
 	unsigned int               resources;
-	struct pm_qos_request	   qos_request;
-
-	/* video overlay */
-	struct v4l2_window         win;
-	struct v4l2_clip           clips[8];
-	unsigned int               nclips;
 
 	/* video capture */
-	struct saa7134_format      *fmt;
-	unsigned int               width,height;
 	struct videobuf_queue      cap;
 	struct saa7134_pgtable     pt_cap;
 
@@ -592,12 +582,19 @@
 	struct saa7134_format      *ovfmt;
 	unsigned int               ovenable;
 	enum v4l2_field            ovfield;
+	struct v4l2_window         win;
+	struct v4l2_clip           clips[8];
+	unsigned int               nclips;
+
 
 	/* video+ts+vbi capture */
 	struct saa7134_dmaqueue    video_q;
 	struct saa7134_dmaqueue    vbi_q;
 	unsigned int               video_fieldcount;
 	unsigned int               vbi_fieldcount;
+	struct saa7134_format      *fmt;
+	unsigned int               width, height;
+	struct pm_qos_request	   qos_request;
 
 	/* various v4l controls */
 	struct saa7134_tvnorm      *tvnorm;              /* video */
diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c
index 71e8bea..33abe33 100644
--- a/drivers/media/pci/saa7146/mxb.c
+++ b/drivers/media/pci/saa7146/mxb.c
@@ -669,14 +669,10 @@
 {
 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-	if (v4l2_chip_match_host(&reg->match)) {
-		reg->val = saa7146_read(dev, reg->reg);
-		reg->size = 4;
-		return 0;
-	}
-	call_all(dev, core, g_register, reg);
+	if (reg->reg > pci_resource_len(dev->pci, 0) - 4)
+		return -EINVAL;
+	reg->val = saa7146_read(dev, reg->reg);
+	reg->size = 4;
 	return 0;
 }
 
@@ -684,13 +680,10 @@
 {
 	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-	if (v4l2_chip_match_host(&reg->match)) {
-		saa7146_write(dev, reg->reg, reg->val);
-		return 0;
-	}
-	return call_all(dev, core, s_register, reg);
+	if (reg->reg > pci_resource_len(dev->pci, 0) - 4)
+		return -EINVAL;
+	saa7146_write(dev, reg->reg, reg->val);
+	return 0;
 }
 #endif
 
diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
index 7618fda..d37ee37 100644
--- a/drivers/media/pci/saa7164/saa7164-core.c
+++ b/drivers/media/pci/saa7164/saa7164-core.c
@@ -1196,6 +1196,12 @@
 	if (NULL == dev)
 		return -ENOMEM;
 
+	err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+	if (err < 0) {
+		dev_err(&pci_dev->dev, "v4l2_device_register failed\n");
+		goto fail_free;
+	}
+
 	/* pci init */
 	dev->pci = pci_dev;
 	if (pci_enable_device(pci_dev)) {
@@ -1367,6 +1373,7 @@
 fail_irq:
 	saa7164_dev_unregister(dev);
 fail_free:
+	v4l2_device_unregister(&dev->v4l2_dev);
 	kfree(dev);
 	return err;
 }
@@ -1439,6 +1446,7 @@
 	mutex_unlock(&devlist);
 
 	saa7164_dev_unregister(dev);
+	v4l2_device_unregister(&dev->v4l2_dev);
 	kfree(dev);
 }
 
diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c
index 0b74fb2..9266965 100644
--- a/drivers/media/pci/saa7164/saa7164-encoder.c
+++ b/drivers/media/pci/saa7164/saa7164-encoder.c
@@ -228,6 +228,7 @@
 		return -EINVAL;
 
 	port->encodernorm = saa7164_tvnorms[i];
+	port->std = id;
 
 	/* Update the audio decoder while is not running in
 	 * auto detect mode.
@@ -239,6 +240,15 @@
 	return 0;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+	struct saa7164_encoder_fh *fh = file->private_data;
+	struct saa7164_port *port = fh->port;
+
+	*id = port->std;
+	return 0;
+}
+
 static int vidioc_enum_input(struct file *file, void *priv,
 	struct v4l2_input *i)
 {
@@ -1288,46 +1298,9 @@
 	.unlocked_ioctl	= video_ioctl2,
 };
 
-static int saa7164_g_chip_ident(struct file *file, void *fh,
-				struct v4l2_dbg_chip_ident *chip)
-{
-	struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
-	struct saa7164_dev *dev = port->dev;
-	dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
-	return 0;
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int saa7164_g_register(struct file *file, void *fh,
-			      struct v4l2_dbg_register *reg)
-{
-	struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
-	struct saa7164_dev *dev = port->dev;
-	dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	return 0;
-}
-
-static int saa7164_s_register(struct file *file, void *fh,
-			      const struct v4l2_dbg_register *reg)
-{
-	struct saa7164_port *port = ((struct saa7164_encoder_fh *)fh)->port;
-	struct saa7164_dev *dev = port->dev;
-	dprintk(DBGLVL_ENC, "%s()\n", __func__);
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	return 0;
-}
-#endif
-
 static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_s_std		 = vidioc_s_std,
+	.vidioc_g_std		 = vidioc_g_std,
 	.vidioc_enum_input	 = vidioc_enum_input,
 	.vidioc_g_input		 = vidioc_g_input,
 	.vidioc_s_input		 = vidioc_s_input,
@@ -1346,11 +1319,6 @@
 	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
 	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
 	.vidioc_queryctrl	 = vidioc_queryctrl,
-	.vidioc_g_chip_ident	 = saa7164_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register	 = saa7164_g_register,
-	.vidioc_s_register	 = saa7164_s_register,
-#endif
 };
 
 static struct video_device saa7164_mpeg_template = {
@@ -1359,7 +1327,6 @@
 	.ioctl_ops     = &mpeg_ioctl_ops,
 	.minor         = -1,
 	.tvnorms       = SAA7164_NORMS,
-	.current_norm  = V4L2_STD_NTSC_M,
 };
 
 static struct video_device *saa7164_encoder_alloc(
@@ -1381,7 +1348,7 @@
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
 		type, saa7164_boards[dev->board].name);
 
-	vfd->parent  = &pci->dev;
+	vfd->v4l2_dev  = &dev->v4l2_dev;
 	vfd->release = video_device_release;
 	return vfd;
 }
@@ -1426,6 +1393,7 @@
 	port->encoder_params.ctl_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
 	port->encoder_params.refdist = 1;
 	port->encoder_params.gop_size = SAA7164_ENCODER_DEFAULT_GOP_SIZE;
+	port->std = V4L2_STD_NTSC_M;
 
 	if (port->encodernorm.id & V4L2_STD_525_60)
 		port->height = 480;
diff --git a/drivers/media/pci/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c
index da224eb..6e025fe 100644
--- a/drivers/media/pci/saa7164/saa7164-vbi.c
+++ b/drivers/media/pci/saa7164/saa7164-vbi.c
@@ -200,6 +200,7 @@
 		return -EINVAL;
 
 	port->encodernorm = saa7164_tvnorms[i];
+	port->std = id;
 
 	/* Update the audio decoder while is not running in
 	 * auto detect mode.
@@ -211,6 +212,15 @@
 	return 0;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+	struct saa7164_encoder_fh *fh = file->private_data;
+	struct saa7164_port *port = fh->port;
+
+	*id = port->std;
+	return 0;
+}
+
 static int vidioc_enum_input(struct file *file, void *priv,
 	struct v4l2_input *i)
 {
@@ -1236,6 +1246,7 @@
 
 static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
 	.vidioc_s_std		 = vidioc_s_std,
+	.vidioc_g_std		 = vidioc_g_std,
 	.vidioc_enum_input	 = vidioc_enum_input,
 	.vidioc_g_input		 = vidioc_g_input,
 	.vidioc_s_input		 = vidioc_s_input,
@@ -1254,15 +1265,6 @@
 	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
 	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
 	.vidioc_queryctrl	 = vidioc_queryctrl,
-#if 0
-	.vidioc_g_chip_ident	 = saa7164_g_chip_ident,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-#if 0
-	.vidioc_g_register	 = saa7164_g_register,
-	.vidioc_s_register	 = saa7164_s_register,
-#endif
-#endif
 	.vidioc_g_fmt_vbi_cap	 = saa7164_vbi_fmt,
 	.vidioc_try_fmt_vbi_cap	 = saa7164_vbi_fmt,
 	.vidioc_s_fmt_vbi_cap	 = saa7164_vbi_fmt,
@@ -1274,7 +1276,6 @@
 	.ioctl_ops     = &vbi_ioctl_ops,
 	.minor         = -1,
 	.tvnorms       = SAA7164_NORMS,
-	.current_norm  = V4L2_STD_NTSC_M,
 };
 
 static struct video_device *saa7164_vbi_alloc(
@@ -1296,7 +1297,7 @@
 	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
 		type, saa7164_boards[dev->board].name);
 
-	vfd->parent  = &pci->dev;
+	vfd->v4l2_dev  = &dev->v4l2_dev;
 	vfd->release = video_device_release;
 	return vfd;
 }
@@ -1333,6 +1334,7 @@
 		goto failed;
 	}
 
+	port->std = V4L2_STD_NTSC_M;
 	video_set_drvdata(port->v4l_device, port);
 	result = video_register_device(port->v4l_device,
 		VFL_TYPE_VBI, -1);
diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h
index 437284e..8b29e89 100644
--- a/drivers/media/pci/saa7164/saa7164.h
+++ b/drivers/media/pci/saa7164/saa7164.h
@@ -63,7 +63,7 @@
 #include <dmxdev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-device.h>
 
 #include "saa7164-reg.h"
 #include "saa7164-types.h"
@@ -376,6 +376,7 @@
 	/* Encoder */
 	/* Defaults established in saa7164-encoder.c */
 	struct saa7164_tvnorm encodernorm;
+	v4l2_std_id std;
 	u32 height;
 	u32 width;
 	u32 freq;
@@ -427,6 +428,8 @@
 	struct list_head	devlist;
 	atomic_t		refcount;
 
+	struct v4l2_device v4l2_dev;
+
 	/* pci stuff */
 	struct pci_dev	*pci;
 	unsigned char	pci_rev, pci_lat;
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
index 7005695..77edc11 100644
--- a/drivers/media/pci/sta2x11/sta2x11_vip.c
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
@@ -1047,7 +1047,8 @@
 	ret = sta2x11_vip_init_controls(vip);
 	if (ret)
 		goto free_mem;
-	if (v4l2_device_register(&pdev->dev, &vip->v4l2_dev))
+	ret = v4l2_device_register(&pdev->dev, &vip->v4l2_dev);
+	if (ret)
 		goto free_mem;
 
 	dev_dbg(&pdev->dev, "BAR #0 at 0x%lx 0x%lx irq %d\n",
diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c
index 1f8b1bb..0ba3875 100644
--- a/drivers/media/pci/ttpci/budget-av.c
+++ b/drivers/media/pci/ttpci/budget-av.c
@@ -1128,7 +1128,7 @@
 //	.ts_pfbit_toggle	= STB0899_MPEG_NORMAL,	/* DirecTV, MPEG toggling seq	*/
 
 	.xtal_freq		= 27000000,
-	.inversion		= IQ_SWAP_OFF, /* 1 */
+	.inversion		= IQ_SWAP_OFF,
 
 	.lo_clk			= 76500000,
 	.hi_clk			= 90000000,
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
index 98e5241..0acf920 100644
--- a/drivers/media/pci/ttpci/budget-ci.c
+++ b/drivers/media/pci/ttpci/budget-ci.c
@@ -1280,7 +1280,7 @@
 	.demod_address 		= 0x68,
 
 	.xtal_freq		= 27000000,
-	.inversion		= IQ_SWAP_ON, /* 1 */
+	.inversion		= IQ_SWAP_ON,
 
 	.lo_clk			= 76500000,
 	.hi_clk			= 99000000,
diff --git a/drivers/media/pci/zoran/zoran_card.c b/drivers/media/pci/zoran/zoran_card.c
index bb53d24..923d59a 100644
--- a/drivers/media/pci/zoran/zoran_card.c
+++ b/drivers/media/pci/zoran/zoran_card.c
@@ -1050,7 +1050,7 @@
 	 *   Now add the template and register the device unit.
 	 */
 	memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
-	zr->video_dev->parent = &zr->pci_dev->dev;
+	zr->video_dev->v4l2_dev = &zr->v4l2_dev;
 	strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
 	/* It's not a mem2mem device, but you can both capture and output from
 	   one and the same device. This should really be split up into two
diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c
index d133c30..e7e9840 100644
--- a/drivers/media/pci/zoran/zoran_driver.c
+++ b/drivers/media/pci/zoran/zoran_driver.c
@@ -1456,29 +1456,6 @@
 		return -EINVAL;
 	}
 
-	if (norm == V4L2_STD_ALL) {
-		unsigned int status = 0;
-		v4l2_std_id std = 0;
-
-		decoder_call(zr, video, querystd, &std);
-		decoder_call(zr, core, s_std, std);
-
-		/* let changes come into effect */
-		ssleep(2);
-
-		decoder_call(zr, video, g_input_status, &status);
-		if (status & V4L2_IN_ST_NO_SIGNAL) {
-			dprintk(1,
-				KERN_ERR
-				"%s: %s - no norm detected\n",
-				ZR_DEVNAME(zr), __func__);
-			/* reset norm */
-			decoder_call(zr, core, s_std, zr->norm);
-			return -EIO;
-		}
-
-		norm = std;
-	}
 	if (norm & V4L2_STD_SECAM)
 		zr->timing = zr->card.tvn[2];
 	else if (norm & V4L2_STD_NTSC)
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 25eaf61..08de865 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -36,7 +36,7 @@
 config VIDEO_SH_VOU
 	tristate "SuperH VOU video output driver"
 	depends on MEDIA_CAMERA_SUPPORT
-	depends on VIDEO_DEV && ARCH_SHMOBILE
+	depends on VIDEO_DEV && ARCH_SHMOBILE && I2C
 	select VIDEOBUF_DMA_CONTIG
 	help
 	  Support for the Video Output Unit (VOU) on SuperH SoCs.
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c
index 0e55b08..7f838c6 100644
--- a/drivers/media/platform/blackfin/bfin_capture.c
+++ b/drivers/media/platform/blackfin/bfin_capture.c
@@ -32,7 +32,6 @@
 #include <linux/time.h>
 #include <linux/types.h>
 
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
@@ -649,18 +648,30 @@
 	return 0;
 }
 
+static int bcap_enum_dv_timings(struct file *file, void *priv,
+				struct v4l2_enum_dv_timings *timings)
+{
+	struct bcap_device *bcap_dev = video_drvdata(file);
+
+	return v4l2_subdev_call(bcap_dev->sd, video,
+			enum_dv_timings, timings);
+}
+
+static int bcap_query_dv_timings(struct file *file, void *priv,
+				struct v4l2_dv_timings *timings)
+{
+	struct bcap_device *bcap_dev = video_drvdata(file);
+
+	return v4l2_subdev_call(bcap_dev->sd, video,
+				query_dv_timings, timings);
+}
+
 static int bcap_g_dv_timings(struct file *file, void *priv,
 				struct v4l2_dv_timings *timings)
 {
 	struct bcap_device *bcap_dev = video_drvdata(file);
-	int ret;
 
-	ret = v4l2_subdev_call(bcap_dev->sd, video,
-				g_dv_timings, timings);
-	if (ret < 0)
-		return ret;
-
-	bcap_dev->dv_timings = *timings;
+	*timings = bcap_dev->dv_timings;
 	return 0;
 }
 
@@ -864,41 +875,6 @@
 	return v4l2_subdev_call(bcap_dev->sd, video, s_parm, a);
 }
 
-static int bcap_g_chip_ident(struct file *file, void *priv,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct bcap_device *bcap_dev = video_drvdata(file);
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-			chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	return v4l2_subdev_call(bcap_dev->sd, core,
-			g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int bcap_dbg_g_register(struct file *file, void *priv,
-		struct v4l2_dbg_register *reg)
-{
-	struct bcap_device *bcap_dev = video_drvdata(file);
-
-	return v4l2_subdev_call(bcap_dev->sd, core,
-			g_register, reg);
-}
-
-static int bcap_dbg_s_register(struct file *file, void *priv,
-		const struct v4l2_dbg_register *reg)
-{
-	struct bcap_device *bcap_dev = video_drvdata(file);
-
-	return v4l2_subdev_call(bcap_dev->sd, core,
-			s_register, reg);
-}
-#endif
-
 static int bcap_log_status(struct file *file, void *priv)
 {
 	struct bcap_device *bcap_dev = video_drvdata(file);
@@ -921,6 +897,8 @@
 	.vidioc_g_std            = bcap_g_std,
 	.vidioc_s_dv_timings     = bcap_s_dv_timings,
 	.vidioc_g_dv_timings     = bcap_g_dv_timings,
+	.vidioc_query_dv_timings = bcap_query_dv_timings,
+	.vidioc_enum_dv_timings  = bcap_enum_dv_timings,
 	.vidioc_reqbufs          = bcap_reqbufs,
 	.vidioc_querybuf         = bcap_querybuf,
 	.vidioc_qbuf             = bcap_qbuf,
@@ -929,11 +907,6 @@
 	.vidioc_streamoff        = bcap_streamoff,
 	.vidioc_g_parm           = bcap_g_parm,
 	.vidioc_s_parm           = bcap_s_parm,
-	.vidioc_g_chip_ident     = bcap_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register       = bcap_dbg_g_register,
-	.vidioc_s_register       = bcap_dbg_s_register,
-#endif
 	.vidioc_log_status       = bcap_log_status,
 };
 
@@ -960,7 +933,7 @@
 	int ret;
 
 	config = pdev->dev.platform_data;
-	if (!config) {
+	if (!config || !config->num_inputs) {
 		v4l2_err(pdev->dev.driver, "Unable to get board config\n");
 		return -ENODEV;
 	}
@@ -1031,7 +1004,9 @@
 	q->mem_ops = &vb2_dma_contig_memops;
 	q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 
-	vb2_queue_init(q);
+	ret = vb2_queue_init(q);
+	if (ret)
+		goto err_free_handler;
 
 	mutex_init(&bcap_dev->mutex);
 	init_completion(&bcap_dev->comp);
@@ -1067,11 +1042,6 @@
 						 NULL);
 	if (bcap_dev->sd) {
 		int i;
-		if (!config->num_inputs) {
-			v4l2_err(&bcap_dev->v4l2_dev,
-					"Unable to work without input\n");
-			goto err_unreg_vdev;
-		}
 
 		/* update tvnorms from the sub devices */
 		for (i = 0; i < config->num_inputs; i++)
@@ -1079,6 +1049,7 @@
 	} else {
 		v4l2_err(&bcap_dev->v4l2_dev,
 				"Unable to register sub device\n");
+		ret = -ENODEV;
 		goto err_unreg_vdev;
 	}
 
diff --git a/drivers/media/platform/blackfin/ppi.c b/drivers/media/platform/blackfin/ppi.c
index 01b5b50..15e9c2b 100644
--- a/drivers/media/platform/blackfin/ppi.c
+++ b/drivers/media/platform/blackfin/ppi.c
@@ -266,6 +266,18 @@
 		bfin_write32(&reg->vcnt, params->height);
 		if (params->int_mask)
 			bfin_write32(&reg->imsk, params->int_mask & 0xFF);
+		if (ppi->ppi_control & PORT_DIR) {
+			u32 hsync_width, vsync_width, vsync_period;
+
+			hsync_width = params->hsync
+					* params->bpp / params->dlen;
+			vsync_width = params->vsync * samples_per_line;
+			vsync_period = samples_per_line * params->frame;
+			bfin_write32(&reg->fs1_wlhb, hsync_width);
+			bfin_write32(&reg->fs1_paspl, samples_per_line);
+			bfin_write32(&reg->fs2_wlvb, vsync_width);
+			bfin_write32(&reg->fs2_palpf, vsync_period);
+		}
 		break;
 	}
 	default:
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
index 9d1481a..df4ada88 100644
--- a/drivers/media/platform/coda.c
+++ b/drivers/media/platform/coda.c
@@ -49,16 +49,14 @@
 
 #define CODA_MAX_FRAMEBUFFERS	2
 
-#define MAX_W		720
-#define MAX_H		576
-#define CODA_MAX_FRAME_SIZE	0x90000
+#define MAX_W		8192
+#define MAX_H		8192
+#define CODA_MAX_FRAME_SIZE	0x100000
 #define FMO_SLICE_SAVE_BUF_SIZE         (32)
 #define CODA_DEFAULT_GAMMA		4096
 
 #define MIN_W 176
 #define MIN_H 144
-#define MAX_W 720
-#define MAX_H 576
 
 #define S_ALIGN		1 /* multiple of 2 */
 #define W_ALIGN		1 /* multiple of 2 */
@@ -67,7 +65,7 @@
 #define fh_to_ctx(__fh)	container_of(__fh, struct coda_ctx, fh)
 
 static int coda_debug;
-module_param(coda_debug, int, 0);
+module_param(coda_debug, int, 0644);
 MODULE_PARM_DESC(coda_debug, "Debug level (0-1)");
 
 enum {
@@ -75,11 +73,6 @@
 	V4L2_M2M_DST = 1,
 };
 
-enum coda_fmt_type {
-	CODA_FMT_ENC,
-	CODA_FMT_RAW,
-};
-
 enum coda_inst_type {
 	CODA_INST_ENCODER,
 	CODA_INST_DECODER,
@@ -93,14 +86,21 @@
 struct coda_fmt {
 	char *name;
 	u32 fourcc;
-	enum coda_fmt_type type;
+};
+
+struct coda_codec {
+	u32 mode;
+	u32 src_fourcc;
+	u32 dst_fourcc;
+	u32 max_w;
+	u32 max_h;
 };
 
 struct coda_devtype {
 	char			*firmware;
 	enum coda_product	product;
-	struct coda_fmt		*formats;
-	unsigned int		num_formats;
+	struct coda_codec	*codecs;
+	unsigned int		num_codecs;
 	size_t			workbuf_size;
 };
 
@@ -109,7 +109,7 @@
 	unsigned int		width;
 	unsigned int		height;
 	unsigned int		sizeimage;
-	struct coda_fmt	*fmt;
+	unsigned int		fourcc;
 };
 
 struct coda_aux_buf {
@@ -137,12 +137,12 @@
 
 	spinlock_t		irqlock;
 	struct mutex		dev_mutex;
+	struct mutex		coda_mutex;
 	struct v4l2_m2m_dev	*m2m_dev;
 	struct vb2_alloc_ctx	*alloc_ctx;
 	struct list_head	instances;
 	unsigned long		instance_mask;
 	struct delayed_work	timeout;
-	struct completion	done;
 };
 
 struct coda_params {
@@ -164,11 +164,12 @@
 	struct coda_dev			*dev;
 	struct list_head		list;
 	int				aborting;
-	int				rawstreamon;
-	int				compstreamon;
+	int				streamon_out;
+	int				streamon_cap;
 	u32				isequence;
 	struct coda_q_data		q_data[2];
 	enum coda_inst_type		inst_type;
+	struct coda_codec		*codec;
 	enum v4l2_colorspace		colorspace;
 	struct coda_params		params;
 	struct v4l2_m2m_ctx		*m2m_ctx;
@@ -257,62 +258,89 @@
 }
 
 /*
- * Add one array of supported formats for each version of Coda:
- *  i.MX27 -> codadx6
- *  i.MX51 -> coda7
- *  i.MX6  -> coda960
+ * Array of all formats supported by any version of Coda:
  */
-static struct coda_fmt codadx6_formats[] = {
+static struct coda_fmt coda_formats[] = {
 	{
-		.name = "YUV 4:2:0 Planar",
+		.name = "YUV 4:2:0 Planar, YCbCr",
 		.fourcc = V4L2_PIX_FMT_YUV420,
-		.type = CODA_FMT_RAW,
+	},
+	{
+		.name = "YUV 4:2:0 Planar, YCrCb",
+		.fourcc = V4L2_PIX_FMT_YVU420,
 	},
 	{
 		.name = "H264 Encoded Stream",
 		.fourcc = V4L2_PIX_FMT_H264,
-		.type = CODA_FMT_ENC,
 	},
 	{
 		.name = "MPEG4 Encoded Stream",
 		.fourcc = V4L2_PIX_FMT_MPEG4,
-		.type = CODA_FMT_ENC,
 	},
 };
 
-static struct coda_fmt coda7_formats[] = {
-	{
-		.name = "YUV 4:2:0 Planar",
-		.fourcc = V4L2_PIX_FMT_YUV420,
-		.type = CODA_FMT_RAW,
-	},
-	{
-		.name = "H264 Encoded Stream",
-		.fourcc = V4L2_PIX_FMT_H264,
-		.type = CODA_FMT_ENC,
-	},
-	{
-		.name = "MPEG4 Encoded Stream",
-		.fourcc = V4L2_PIX_FMT_MPEG4,
-		.type = CODA_FMT_ENC,
-	},
+#define CODA_CODEC(mode, src_fourcc, dst_fourcc, max_w, max_h) \
+	{ mode, src_fourcc, dst_fourcc, max_w, max_h }
+
+/*
+ * Arrays of codecs supported by each given version of Coda:
+ *  i.MX27 -> codadx6
+ *  i.MX5x -> coda7
+ *  i.MX6  -> coda960
+ * Use V4L2_PIX_FMT_YUV420 as placeholder for all supported YUV 4:2:0 variants
+ */
+static struct coda_codec codadx6_codecs[] = {
+	CODA_CODEC(CODADX6_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264,  720, 576),
+	CODA_CODEC(CODADX6_MODE_ENCODE_MP4,  V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 720, 576),
 };
 
-static struct coda_fmt *find_format(struct coda_dev *dev, struct v4l2_format *f)
+static struct coda_codec coda7_codecs[] = {
+	CODA_CODEC(CODA7_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264,   1280, 720),
+	CODA_CODEC(CODA7_MODE_ENCODE_MP4,  V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4,  1280, 720),
+};
+
+static bool coda_format_is_yuv(u32 fourcc)
 {
-	struct coda_fmt *formats = dev->devtype->formats;
-	int num_formats = dev->devtype->num_formats;
-	unsigned int k;
+	switch (fourcc) {
+	case V4L2_PIX_FMT_YUV420:
+	case V4L2_PIX_FMT_YVU420:
+		return true;
+	default:
+		return false;
+	}
+}
 
-	for (k = 0; k < num_formats; k++) {
-		if (formats[k].fourcc == f->fmt.pix.pixelformat)
+/*
+ * Normalize all supported YUV 4:2:0 formats to the value used in the codec
+ * tables.
+ */
+static u32 coda_format_normalize_yuv(u32 fourcc)
+{
+	return coda_format_is_yuv(fourcc) ? V4L2_PIX_FMT_YUV420 : fourcc;
+}
+
+static struct coda_codec *coda_find_codec(struct coda_dev *dev, int src_fourcc,
+					  int dst_fourcc)
+{
+	struct coda_codec *codecs = dev->devtype->codecs;
+	int num_codecs = dev->devtype->num_codecs;
+	int k;
+
+	src_fourcc = coda_format_normalize_yuv(src_fourcc);
+	dst_fourcc = coda_format_normalize_yuv(dst_fourcc);
+	if (src_fourcc == dst_fourcc)
+		return NULL;
+
+	for (k = 0; k < num_codecs; k++) {
+		if (codecs[k].src_fourcc == src_fourcc &&
+		    codecs[k].dst_fourcc == dst_fourcc)
 			break;
 	}
 
-	if (k == num_formats)
+	if (k == num_codecs)
 		return NULL;
 
-	return &formats[k];
+	return &codecs[k];
 }
 
 /*
@@ -323,7 +351,7 @@
 {
 	strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver));
 	strlcpy(cap->card, CODA_NAME, sizeof(cap->card));
-	strlcpy(cap->bus_info, CODA_NAME, sizeof(cap->bus_info));
+	strlcpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info));
 	/*
 	 * This is only a mem-to-mem video device. The capture and output
 	 * device capability flags are left only for backward compatibility
@@ -337,17 +365,34 @@
 }
 
 static int enum_fmt(void *priv, struct v4l2_fmtdesc *f,
-			enum coda_fmt_type type)
+			enum v4l2_buf_type type)
 {
 	struct coda_ctx *ctx = fh_to_ctx(priv);
-	struct coda_dev *dev = ctx->dev;
-	struct coda_fmt *formats = dev->devtype->formats;
+	struct coda_codec *codecs = ctx->dev->devtype->codecs;
+	struct coda_fmt *formats = coda_formats;
 	struct coda_fmt *fmt;
-	int num_formats = dev->devtype->num_formats;
-	int i, num = 0;
+	int num_codecs = ctx->dev->devtype->num_codecs;
+	int num_formats = ARRAY_SIZE(coda_formats);
+	int i, k, num = 0;
 
 	for (i = 0; i < num_formats; i++) {
-		if (formats[i].type == type) {
+		/* Both uncompressed formats are always supported */
+		if (coda_format_is_yuv(formats[i].fourcc)) {
+			if (num == f->index)
+				break;
+			++num;
+			continue;
+		}
+		/* Compressed formats may be supported, check the codec list */
+		for (k = 0; k < num_codecs; k++) {
+			if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+			    formats[i].fourcc == codecs[k].dst_fourcc)
+				break;
+			if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+			    formats[i].fourcc == codecs[k].src_fourcc)
+				break;
+		}
+		if (k < num_codecs) {
 			if (num == f->index)
 				break;
 			++num;
@@ -368,13 +413,13 @@
 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
 				   struct v4l2_fmtdesc *f)
 {
-	return enum_fmt(priv, f, CODA_FMT_ENC);
+	return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_CAPTURE);
 }
 
 static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
 				   struct v4l2_fmtdesc *f)
 {
-	return enum_fmt(priv, f, CODA_FMT_RAW);
+	return enum_fmt(priv, f, V4L2_BUF_TYPE_VIDEO_OUTPUT);
 }
 
 static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
@@ -390,10 +435,10 @@
 	q_data = get_q_data(ctx, f->type);
 
 	f->fmt.pix.field	= V4L2_FIELD_NONE;
-	f->fmt.pix.pixelformat	= q_data->fmt->fourcc;
+	f->fmt.pix.pixelformat	= q_data->fourcc;
 	f->fmt.pix.width	= q_data->width;
 	f->fmt.pix.height	= q_data->height;
-	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
+	if (coda_format_is_yuv(f->fmt.pix.pixelformat))
 		f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
 	else /* encoded formats h.264/mpeg4 */
 		f->fmt.pix.bytesperline = 0;
@@ -404,8 +449,9 @@
 	return 0;
 }
 
-static int vidioc_try_fmt(struct coda_dev *dev, struct v4l2_format *f)
+static int vidioc_try_fmt(struct coda_codec *codec, struct v4l2_format *f)
 {
+	unsigned int max_w, max_h;
 	enum v4l2_field field;
 
 	field = f->fmt.pix.field;
@@ -418,12 +464,21 @@
 	 * if any of the dimensions is unsupported */
 	f->fmt.pix.field = field;
 
-	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
-		v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
-				      W_ALIGN, &f->fmt.pix.height,
-				      MIN_H, MAX_H, H_ALIGN, S_ALIGN);
-		f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
-		f->fmt.pix.sizeimage = f->fmt.pix.width *
+	if (codec) {
+		max_w = codec->max_w;
+		max_h = codec->max_h;
+	} else {
+		max_w = MAX_W;
+		max_h = MAX_H;
+	}
+	v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w,
+			      W_ALIGN, &f->fmt.pix.height,
+			      MIN_H, max_h, H_ALIGN, S_ALIGN);
+
+	if (coda_format_is_yuv(f->fmt.pix.pixelformat)) {
+		/* Frame stride must be multiple of 8 */
+		f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8);
+		f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
 					f->fmt.pix.height * 3 / 2;
 	} else { /*encoded formats h.264/mpeg4 */
 		f->fmt.pix.bytesperline = 0;
@@ -436,57 +491,38 @@
 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 				  struct v4l2_format *f)
 {
-	int ret;
-	struct coda_fmt *fmt;
 	struct coda_ctx *ctx = fh_to_ctx(priv);
+	struct coda_codec *codec = NULL;
 
-	fmt = find_format(ctx->dev, f);
-	/*
-	 * Since decoding support is not implemented yet do not allow
-	 * CODA_FMT_RAW formats in the capture interface.
-	 */
-	if (!fmt || !(fmt->type == CODA_FMT_ENC))
-		f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
+	/* Determine codec by the encoded format */
+	codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420,
+				f->fmt.pix.pixelformat);
 
 	f->fmt.pix.colorspace = ctx->colorspace;
 
-	ret = vidioc_try_fmt(ctx->dev, f);
-	if (ret < 0)
-		return ret;
-
-	return 0;
+	return vidioc_try_fmt(codec, f);
 }
 
 static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
 				  struct v4l2_format *f)
 {
 	struct coda_ctx *ctx = fh_to_ctx(priv);
-	struct coda_fmt *fmt;
-	int ret;
+	struct coda_codec *codec;
 
-	fmt = find_format(ctx->dev, f);
-	/*
-	 * Since decoding support is not implemented yet do not allow
-	 * CODA_FMT formats in the capture interface.
-	 */
-	if (!fmt || !(fmt->type == CODA_FMT_RAW))
-		f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+	/* Determine codec by encoded format, returns NULL if raw or invalid */
+	codec = coda_find_codec(ctx->dev, f->fmt.pix.pixelformat,
+				V4L2_PIX_FMT_YUV420);
 
 	if (!f->fmt.pix.colorspace)
 		f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
 
-	ret = vidioc_try_fmt(ctx->dev, f);
-	if (ret < 0)
-		return ret;
-
-	return 0;
+	return vidioc_try_fmt(codec, f);
 }
 
 static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
 {
 	struct coda_q_data *q_data;
 	struct vb2_queue *vq;
-	int ret;
 
 	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
 	if (!vq)
@@ -501,18 +537,14 @@
 		return -EBUSY;
 	}
 
-	ret = vidioc_try_fmt(ctx->dev, f);
-	if (ret)
-		return ret;
-
-	q_data->fmt = find_format(ctx->dev, f);
+	q_data->fourcc = f->fmt.pix.pixelformat;
 	q_data->width = f->fmt.pix.width;
 	q_data->height = f->fmt.pix.height;
 	q_data->sizeimage = f->fmt.pix.sizeimage;
 
 	v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 		"Setting format for type %d, wxh: %dx%d, fmt: %d\n",
-		f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
+		f->type, q_data->width, q_data->height, q_data->fourcc);
 
 	return 0;
 }
@@ -520,13 +552,14 @@
 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
+	struct coda_ctx *ctx = fh_to_ctx(priv);
 	int ret;
 
 	ret = vidioc_try_fmt_vid_cap(file, priv, f);
 	if (ret)
 		return ret;
 
-	return vidioc_s_fmt(fh_to_ctx(priv), f);
+	return vidioc_s_fmt(ctx, f);
 }
 
 static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
@@ -569,6 +602,14 @@
 	return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
 }
 
+static int vidioc_expbuf(struct file *file, void *priv,
+			 struct v4l2_exportbuffer *eb)
+{
+	struct coda_ctx *ctx = fh_to_ctx(priv);
+
+	return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
+}
+
 static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 {
 	struct coda_ctx *ctx = fh_to_ctx(priv);
@@ -617,6 +658,7 @@
 	.vidioc_querybuf	= vidioc_querybuf,
 
 	.vidioc_qbuf		= vidioc_qbuf,
+	.vidioc_expbuf		= vidioc_expbuf,
 	.vidioc_dqbuf		= vidioc_dqbuf,
 	.vidioc_create_bufs	= vidioc_create_bufs,
 
@@ -639,11 +681,13 @@
 	u32 pic_stream_buffer_addr, pic_stream_buffer_size;
 	u32 dst_fourcc;
 
+	mutex_lock(&dev->coda_mutex);
+
 	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
 	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
 	q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
 	q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
-	dst_fourcc = q_data_dst->fmt->fourcc;
+	dst_fourcc = q_data_dst->fourcc;
 
 	src_buf->v4l2_buf.sequence = ctx->isequence;
 	dst_buf->v4l2_buf.sequence = ctx->isequence;
@@ -725,9 +769,20 @@
 
 
 	picture_y = vb2_dma_contig_plane_dma_addr(src_buf, 0);
-	picture_cb = picture_y + q_data_src->width * q_data_src->height;
-	picture_cr = picture_cb + q_data_src->width / 2 *
-			q_data_src->height / 2;
+	switch (q_data_src->fourcc) {
+	case V4L2_PIX_FMT_YVU420:
+		/* Switch Cb and Cr for YVU420 format */
+		picture_cr = picture_y + q_data_src->width * q_data_src->height;
+		picture_cb = picture_cr + q_data_src->width / 2 *
+				q_data_src->height / 2;
+		break;
+	case V4L2_PIX_FMT_YUV420:
+	default:
+		picture_cb = picture_y + q_data_src->width * q_data_src->height;
+		picture_cr = picture_cb + q_data_src->width / 2 *
+				q_data_src->height / 2;
+		break;
+	}
 
 	coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y);
 	coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB);
@@ -748,7 +803,6 @@
 	/* 1 second timeout in case CODA locks up */
 	schedule_delayed_work(&dev->timeout, HZ);
 
-	INIT_COMPLETION(dev->done);
 	coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
 }
 
@@ -767,6 +821,12 @@
 		return 0;
 	}
 
+	if (ctx->aborting) {
+		v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
+			 "not ready: aborting\n");
+		return 0;
+	}
+
 	v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 			"job ready\n");
 	return 1;
@@ -775,14 +835,11 @@
 static void coda_job_abort(void *priv)
 {
 	struct coda_ctx *ctx = priv;
-	struct coda_dev *dev = ctx->dev;
 
 	ctx->aborting = 1;
 
 	v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 		 "Aborting task\n");
-
-	v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx);
 }
 
 static void coda_lock(void *m2m_priv)
@@ -809,7 +866,12 @@
 
 static void set_default_params(struct coda_ctx *ctx)
 {
-	struct coda_dev *dev = ctx->dev;
+	int max_w;
+	int max_h;
+
+	ctx->codec = &ctx->dev->devtype->codecs[0];
+	max_w = ctx->codec->max_w;
+	max_h = ctx->codec->max_h;
 
 	ctx->params.codec_mode = CODA_MODE_INVALID;
 	ctx->colorspace = V4L2_COLORSPACE_REC709;
@@ -817,13 +879,13 @@
 	ctx->aborting = 0;
 
 	/* Default formats for output and input queues */
-	ctx->q_data[V4L2_M2M_SRC].fmt = &dev->devtype->formats[0];
-	ctx->q_data[V4L2_M2M_DST].fmt = &dev->devtype->formats[1];
-	ctx->q_data[V4L2_M2M_SRC].width = MAX_W;
-	ctx->q_data[V4L2_M2M_SRC].height = MAX_H;
-	ctx->q_data[V4L2_M2M_SRC].sizeimage = (MAX_W * MAX_H * 3) / 2;
-	ctx->q_data[V4L2_M2M_DST].width = MAX_W;
-	ctx->q_data[V4L2_M2M_DST].height = MAX_H;
+	ctx->q_data[V4L2_M2M_SRC].fourcc = ctx->codec->src_fourcc;
+	ctx->q_data[V4L2_M2M_DST].fourcc = ctx->codec->dst_fourcc;
+	ctx->q_data[V4L2_M2M_SRC].width = max_w;
+	ctx->q_data[V4L2_M2M_SRC].height = max_h;
+	ctx->q_data[V4L2_M2M_SRC].sizeimage = (max_w * max_h * 3) / 2;
+	ctx->q_data[V4L2_M2M_DST].width = max_w;
+	ctx->q_data[V4L2_M2M_DST].height = max_h;
 	ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE;
 }
 
@@ -868,8 +930,6 @@
 		return -EINVAL;
 	}
 
-	vb2_set_plane_payload(vb, 0, q_data->sizeimage);
-
 	return 0;
 }
 
@@ -906,21 +966,34 @@
 	}
 }
 
+static void coda_parabuf_write(struct coda_ctx *ctx, int index, u32 value)
+{
+	struct coda_dev *dev = ctx->dev;
+	u32 *p = ctx->parabuf.vaddr;
+
+	if (dev->devtype->product == CODA_DX6)
+		p[index] = value;
+	else
+		p[index ^ 1] = value;
+}
+
 static int coda_alloc_framebuffers(struct coda_ctx *ctx, struct coda_q_data *q_data, u32 fourcc)
 {
 	struct coda_dev *dev = ctx->dev;
 
 	int height = q_data->height;
-	int width = q_data->width;
-	u32 *p;
+	dma_addr_t paddr;
+	int ysize;
 	int i;
 
+	ysize = round_up(q_data->width, 8) * height;
+
 	/* Allocate frame buffers */
 	ctx->num_internal_frames = CODA_MAX_FRAMEBUFFERS;
 	for (i = 0; i < ctx->num_internal_frames; i++) {
 		ctx->internal_frames[i].size = q_data->sizeimage;
 		if (fourcc == V4L2_PIX_FMT_H264 && dev->devtype->product != CODA_DX6)
-			ctx->internal_frames[i].size += width / 2 * height / 2;
+			ctx->internal_frames[i].size += ysize/4;
 		ctx->internal_frames[i].vaddr = dma_alloc_coherent(
 				&dev->plat_dev->dev, ctx->internal_frames[i].size,
 				&ctx->internal_frames[i].paddr, GFP_KERNEL);
@@ -931,32 +1004,14 @@
 	}
 
 	/* Register frame buffers in the parameter buffer */
-	p = ctx->parabuf.vaddr;
+	for (i = 0; i < ctx->num_internal_frames; i++) {
+		paddr = ctx->internal_frames[i].paddr;
+		coda_parabuf_write(ctx, i * 3 + 0, paddr); /* Y */
+		coda_parabuf_write(ctx, i * 3 + 1, paddr + ysize); /* Cb */
+		coda_parabuf_write(ctx, i * 3 + 2, paddr + ysize + ysize/4); /* Cr */
 
-	if (dev->devtype->product == CODA_DX6) {
-		for (i = 0; i < ctx->num_internal_frames; i++) {
-			p[i * 3] = ctx->internal_frames[i].paddr; /* Y */
-			p[i * 3 + 1] = p[i * 3] + width * height; /* Cb */
-			p[i * 3 + 2] = p[i * 3 + 1] + width / 2 * height / 2; /* Cr */
-		}
-	} else {
-		for (i = 0; i < ctx->num_internal_frames; i += 2) {
-			p[i * 3 + 1] = ctx->internal_frames[i].paddr; /* Y */
-			p[i * 3] = p[i * 3 + 1] + width * height; /* Cb */
-			p[i * 3 + 3] = p[i * 3] + (width / 2) * (height / 2); /* Cr */
-
-			if (fourcc == V4L2_PIX_FMT_H264)
-				p[96 + i + 1] = p[i * 3 + 3] + (width / 2) * (height / 2);
-
-			if (i + 1 < ctx->num_internal_frames) {
-				p[i * 3 + 2] = ctx->internal_frames[i+1].paddr; /* Y */
-				p[i * 3 + 5] = p[i * 3 + 2] + width * height ; /* Cb */
-				p[i * 3 + 4] = p[i * 3 + 5] + (width / 2) * (height / 2); /* Cr */
-
-				if (fourcc == V4L2_PIX_FMT_H264)
-					p[96 + i] = p[i * 3 + 4] + (width / 2) * (height / 2);
-			}
-		}
+		if (dev->devtype->product != CODA_DX6 && fourcc == V4L2_PIX_FMT_H264)
+			coda_parabuf_write(ctx, 96 + i, ctx->internal_frames[i].paddr + ysize + ysize/4 + ysize/4);
 	}
 
 	return 0;
@@ -980,6 +1035,28 @@
 	return nal_size;
 }
 
+static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
+			      int header_code, u8 *header, int *size)
+{
+	struct coda_dev *dev = ctx->dev;
+	int ret;
+
+	coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0),
+		   CODA_CMD_ENC_HEADER_BB_START);
+	coda_write(dev, vb2_plane_size(buf, 0), CODA_CMD_ENC_HEADER_BB_SIZE);
+	coda_write(dev, header_code, CODA_CMD_ENC_HEADER_CODE);
+	ret = coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER);
+	if (ret < 0) {
+		v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
+		return ret;
+	}
+	*size = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
+		coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+	memcpy(header, vb2_plane_vaddr(buf, 0), *size);
+
+	return 0;
+}
+
 static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
 {
 	struct coda_ctx *ctx = vb2_get_drv_priv(q);
@@ -990,43 +1067,38 @@
 	struct vb2_buffer *buf;
 	u32 dst_fourcc;
 	u32 value;
-	int ret;
+	int ret = 0;
 
 	if (count < 1)
 		return -EINVAL;
 
 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		ctx->rawstreamon = 1;
+		ctx->streamon_out = 1;
 	else
-		ctx->compstreamon = 1;
-
-	/* Don't start the coda unless both queues are on */
-	if (!(ctx->rawstreamon & ctx->compstreamon))
-		return 0;
-
-	if (coda_isbusy(dev))
-		if (wait_for_completion_interruptible_timeout(&dev->done, HZ) <= 0)
-			return -EBUSY;
-
-	ctx->gopcounter = ctx->params.gop_size - 1;
+		ctx->streamon_cap = 1;
 
 	q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	if (ctx->streamon_out) {
+		if (coda_format_is_yuv(q_data_src->fourcc))
+			ctx->inst_type = CODA_INST_ENCODER;
+		else
+			ctx->inst_type = CODA_INST_DECODER;
+	}
+
+	/* Don't start the coda unless both queues are on */
+	if (!(ctx->streamon_out & ctx->streamon_cap))
+		return 0;
+
+	ctx->gopcounter = ctx->params.gop_size - 1;
 	buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
 	bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
 	q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
 	bitstream_size = q_data_dst->sizeimage;
-	dst_fourcc = q_data_dst->fmt->fourcc;
+	dst_fourcc = q_data_dst->fourcc;
 
-	/* Find out whether coda must encode or decode */
-	if (q_data_src->fmt->type == CODA_FMT_RAW &&
-	    q_data_dst->fmt->type == CODA_FMT_ENC) {
-		ctx->inst_type = CODA_INST_ENCODER;
-	} else if (q_data_src->fmt->type == CODA_FMT_ENC &&
-		   q_data_dst->fmt->type == CODA_FMT_RAW) {
-		ctx->inst_type = CODA_INST_DECODER;
-		v4l2_err(v4l2_dev, "decoding not supported.\n");
-		return -EINVAL;
-	} else {
+	ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc,
+				     q_data_dst->fourcc);
+	if (!ctx->codec) {
 		v4l2_err(v4l2_dev, "couldn't tell instance type.\n");
 		return -EINVAL;
 	}
@@ -1035,6 +1107,9 @@
 		v4l2_err(v4l2_dev, "coda is not initialized.\n");
 		return -EFAULT;
 	}
+
+	mutex_lock(&dev->coda_mutex);
+
 	coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR);
 	coda_write(dev, bitstream_buf, CODA_REG_BIT_RD_PTR(ctx->idx));
 	coda_write(dev, bitstream_buf, CODA_REG_BIT_WR_PTR(ctx->idx));
@@ -1057,38 +1132,31 @@
 	switch (dev->devtype->product) {
 	case CODA_DX6:
 		value = (q_data_src->width & CODADX6_PICWIDTH_MASK) << CODADX6_PICWIDTH_OFFSET;
+		value |= (q_data_src->height & CODADX6_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
 		break;
 	default:
 		value = (q_data_src->width & CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET;
+		value |= (q_data_src->height & CODA7_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
 	}
-	value |= (q_data_src->height & CODA_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
 	coda_write(dev, value, CODA_CMD_ENC_SEQ_SRC_SIZE);
 	coda_write(dev, ctx->params.framerate,
 		   CODA_CMD_ENC_SEQ_SRC_F_RATE);
 
+	ctx->params.codec_mode = ctx->codec->mode;
 	switch (dst_fourcc) {
 	case V4L2_PIX_FMT_MPEG4:
-		if (dev->devtype->product == CODA_DX6)
-			ctx->params.codec_mode = CODADX6_MODE_ENCODE_MP4;
-		else
-			ctx->params.codec_mode = CODA7_MODE_ENCODE_MP4;
-
 		coda_write(dev, CODA_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
 		coda_write(dev, 0, CODA_CMD_ENC_SEQ_MP4_PARA);
 		break;
 	case V4L2_PIX_FMT_H264:
-		if (dev->devtype->product == CODA_DX6)
-			ctx->params.codec_mode = CODADX6_MODE_ENCODE_H264;
-		else
-			ctx->params.codec_mode = CODA7_MODE_ENCODE_H264;
-
 		coda_write(dev, CODA_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
 		coda_write(dev, 0, CODA_CMD_ENC_SEQ_264_PARA);
 		break;
 	default:
 		v4l2_err(v4l2_dev,
 			 "dst format (0x%08x) invalid.\n", dst_fourcc);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	switch (ctx->params.slice_mode) {
@@ -1129,8 +1197,14 @@
 	value = (CODA_DEFAULT_GAMMA & CODA_GAMMA_MASK) << CODA_GAMMA_OFFSET;
 	coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_GAMMA);
 
-	value  = (CODA_DEFAULT_GAMMA > 0) << CODA_OPTION_GAMMA_OFFSET;
-	value |= (0 & CODA_OPTION_SLICEREPORT_MASK) << CODA_OPTION_SLICEREPORT_OFFSET;
+	if (CODA_DEFAULT_GAMMA > 0) {
+		if (dev->devtype->product == CODA_DX6)
+			value  = 1 << CODADX6_OPTION_GAMMA_OFFSET;
+		else
+			value  = 1 << CODA7_OPTION_GAMMA_OFFSET;
+	} else {
+		value = 0;
+	}
 	coda_write(dev, value, CODA_CMD_ENC_SEQ_OPTION);
 
 	if (dst_fourcc == V4L2_PIX_FMT_H264) {
@@ -1145,17 +1219,23 @@
 		}
 	}
 
-	if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
+	ret = coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT);
+	if (ret < 0) {
 		v4l2_err(v4l2_dev, "CODA_COMMAND_SEQ_INIT timeout\n");
-		return -ETIMEDOUT;
+		goto out;
 	}
 
-	if (coda_read(dev, CODA_RET_ENC_SEQ_SUCCESS) == 0)
-		return -EFAULT;
+	if (coda_read(dev, CODA_RET_ENC_SEQ_SUCCESS) == 0) {
+		v4l2_err(v4l2_dev, "CODA_COMMAND_SEQ_INIT failed\n");
+		ret = -EFAULT;
+		goto out;
+	}
 
 	ret = coda_alloc_framebuffers(ctx, q_data_src, dst_fourcc);
-	if (ret < 0)
-		return ret;
+	if (ret < 0) {
+		v4l2_err(v4l2_dev, "failed to allocate framebuffers\n");
+		goto out;
+	}
 
 	coda_write(dev, ctx->num_internal_frames, CODA_CMD_SET_FRAME_BUF_NUM);
 	coda_write(dev, round_up(q_data_src->width, 8), CODA_CMD_SET_FRAME_BUF_STRIDE);
@@ -1167,9 +1247,10 @@
 		coda_write(dev, dev->iram_paddr + 68 * 1024, CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
 		coda_write(dev, 0x0, CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
 	}
-	if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
+	ret = coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF);
+	if (ret < 0) {
 		v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
-		return -ETIMEDOUT;
+		goto out;
 	}
 
 	/* Save stream headers */
@@ -1180,33 +1261,22 @@
 		 * Get SPS in the first frame and copy it to an
 		 * intermediate buffer.
 		 */
-		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
-		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
-		coda_write(dev, CODA_HEADER_H264_SPS, CODA_CMD_ENC_HEADER_CODE);
-		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
-			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
-			return -ETIMEDOUT;
-		}
-		ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
-				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
-		memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
-		       ctx->vpu_header_size[0]);
+		ret = coda_encode_header(ctx, buf, CODA_HEADER_H264_SPS,
+					 &ctx->vpu_header[0][0],
+					 &ctx->vpu_header_size[0]);
+		if (ret < 0)
+			goto out;
 
 		/*
 		 * Get PPS in the first frame and copy it to an
 		 * intermediate buffer.
 		 */
-		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
-		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
-		coda_write(dev, CODA_HEADER_H264_PPS, CODA_CMD_ENC_HEADER_CODE);
-		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
-			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
-			return -ETIMEDOUT;
-		}
-		ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
-				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
-		memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),
-		       ctx->vpu_header_size[1]);
+		ret = coda_encode_header(ctx, buf, CODA_HEADER_H264_PPS,
+					 &ctx->vpu_header[1][0],
+					 &ctx->vpu_header_size[1]);
+		if (ret < 0)
+			goto out;
+
 		/*
 		 * Length of H.264 headers is variable and thus it might not be
 		 * aligned for the coda to append the encoded frame. In that is
@@ -1222,48 +1292,32 @@
 		 * Get VOS in the first frame and copy it to an
 		 * intermediate buffer
 		 */
-		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
-		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
-		coda_write(dev, CODA_HEADER_MP4V_VOS, CODA_CMD_ENC_HEADER_CODE);
-		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
-			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
-			return -ETIMEDOUT;
-		}
-		ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
-				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
-		memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
-		       ctx->vpu_header_size[0]);
+		ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VOS,
+					 &ctx->vpu_header[0][0],
+					 &ctx->vpu_header_size[0]);
+		if (ret < 0)
+			goto out;
 
-		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
-		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
-		coda_write(dev, CODA_HEADER_MP4V_VIS, CODA_CMD_ENC_HEADER_CODE);
-		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
-			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
-			return -ETIMEDOUT;
-		}
-		ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
-				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
-		memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),
-		       ctx->vpu_header_size[1]);
+		ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VIS,
+					 &ctx->vpu_header[1][0],
+					 &ctx->vpu_header_size[1]);
+		if (ret < 0)
+			goto out;
 
-		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
-		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
-		coda_write(dev, CODA_HEADER_MP4V_VOL, CODA_CMD_ENC_HEADER_CODE);
-		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
-			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
-			return -ETIMEDOUT;
-		}
-		ctx->vpu_header_size[2] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
-				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
-		memcpy(&ctx->vpu_header[2][0], vb2_plane_vaddr(buf, 0),
-		       ctx->vpu_header_size[2]);
+		ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VOL,
+					 &ctx->vpu_header[2][0],
+					 &ctx->vpu_header_size[2]);
+		if (ret < 0)
+			goto out;
 		break;
 	default:
 		/* No more formats need to save headers at the moment */
 		break;
 	}
 
-	return 0;
+out:
+	mutex_unlock(&dev->coda_mutex);
+	return ret;
 }
 
 static int coda_stop_streaming(struct vb2_queue *q)
@@ -1274,26 +1328,20 @@
 	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
 		v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 			 "%s: output\n", __func__);
-		ctx->rawstreamon = 0;
+		ctx->streamon_out = 0;
 	} else {
 		v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 			 "%s: capture\n", __func__);
-		ctx->compstreamon = 0;
+		ctx->streamon_cap = 0;
 	}
 
 	/* Don't stop the coda unless both queues are off */
-	if (ctx->rawstreamon || ctx->compstreamon)
+	if (ctx->streamon_out || ctx->streamon_cap)
 		return 0;
 
-	if (coda_isbusy(dev)) {
-		if (wait_for_completion_interruptible_timeout(&dev->done, HZ) <= 0) {
-			v4l2_warn(&dev->v4l2_dev,
-				  "%s: timeout, sending SEQ_END anyway\n", __func__);
-		}
-	}
-
 	cancel_delayed_work(&dev->timeout);
 
+	mutex_lock(&dev->coda_mutex);
 	v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
 		 "%s: sent command 'SEQ_END' to coda\n", __func__);
 	if (coda_command_sync(ctx, CODA_COMMAND_SEQ_END)) {
@@ -1301,6 +1349,7 @@
 			 "CODA_COMMAND_SEQ_END failed\n");
 		return -ETIMEDOUT;
 	}
+	mutex_unlock(&dev->coda_mutex);
 
 	coda_free_framebuffers(ctx);
 
@@ -1431,7 +1480,7 @@
 	int ret;
 
 	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+	src_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
 	src_vq->drv_priv = ctx;
 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	src_vq->ops = &coda_qops;
@@ -1443,7 +1492,7 @@
 		return ret;
 
 	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+	dst_vq->io_modes = VB2_DMABUF | VB2_MMAP | VB2_USERPTR;
 	dst_vq->drv_priv = ctx;
 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	dst_vq->ops = &coda_qops;
@@ -1484,7 +1533,7 @@
 	ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
 					 &coda_queue_init);
 	if (IS_ERR(ctx->m2m_ctx)) {
-		int ret = PTR_ERR(ctx->m2m_ctx);
+		ret = PTR_ERR(ctx->m2m_ctx);
 
 		v4l2_err(&dev->v4l2_dev, "%s return error (%d)\n",
 			 __func__, ret);
@@ -1596,12 +1645,14 @@
 	ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
 	if (ctx == NULL) {
 		v4l2_err(&dev->v4l2_dev, "Instance released before the end of transaction\n");
+		mutex_unlock(&dev->coda_mutex);
 		return IRQ_HANDLED;
 	}
 
 	if (ctx->aborting) {
 		v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
 			 "task has been aborted\n");
+		mutex_unlock(&dev->coda_mutex);
 		return IRQ_HANDLED;
 	}
 
@@ -1611,8 +1662,6 @@
 		return IRQ_NONE;
 	}
 
-	complete(&dev->done);
-
 	src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
 	dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
 
@@ -1660,6 +1709,8 @@
 		(dst_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) ?
 		"KEYFRAME" : "PFRAME");
 
+	mutex_unlock(&dev->coda_mutex);
+
 	v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
 
 	return IRQ_HANDLED;
@@ -1671,12 +1722,7 @@
 	struct coda_dev *dev = container_of(to_delayed_work(work),
 					    struct coda_dev, timeout);
 
-	if (completion_done(&dev->done))
-		return;
-
-	complete(&dev->done);
-
-	v4l2_err(&dev->v4l2_dev, "CODA PIC_RUN timeout, stopping all streams\n");
+	dev_err(&dev->plat_dev->dev, "CODA PIC_RUN timeout, stopping all streams\n");
 
 	mutex_lock(&dev->dev_mutex);
 	list_for_each_entry(ctx, &dev->instances, list) {
@@ -1684,6 +1730,10 @@
 		v4l2_m2m_streamoff(NULL, ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
 	}
 	mutex_unlock(&dev->dev_mutex);
+
+	mutex_unlock(&dev->coda_mutex);
+	ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
+	v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
 }
 
 static u32 coda_supported_firmwares[] = {
@@ -1748,6 +1798,10 @@
 		}
 	}
 
+	/* Clear registers */
+	for (i = 0; i < 64; i++)
+		coda_write(dev, 0, CODA_REG_BIT_CODE_BUF_ADDR + i * 4);
+
 	/* Tell the BIT where to find everything it needs */
 	coda_write(dev, dev->workbuf.paddr,
 		      CODA_REG_BIT_WORK_BUF_ADDR);
@@ -1911,16 +1965,16 @@
 
 static const struct coda_devtype coda_devdata[] = {
 	[CODA_IMX27] = {
-		.firmware    = "v4l-codadx6-imx27.bin",
-		.product     = CODA_DX6,
-		.formats     = codadx6_formats,
-		.num_formats = ARRAY_SIZE(codadx6_formats),
+		.firmware   = "v4l-codadx6-imx27.bin",
+		.product    = CODA_DX6,
+		.codecs     = codadx6_codecs,
+		.num_codecs = ARRAY_SIZE(codadx6_codecs),
 	},
 	[CODA_IMX53] = {
-		.firmware    = "v4l-coda7541-imx53.bin",
-		.product     = CODA_7541,
-		.formats     = coda7_formats,
-		.num_formats = ARRAY_SIZE(coda7_formats),
+		.firmware   = "v4l-coda7541-imx53.bin",
+		.product    = CODA_7541,
+		.codecs     = coda7_codecs,
+		.num_codecs = ARRAY_SIZE(coda7_codecs),
 	},
 };
 
@@ -1962,8 +2016,6 @@
 	spin_lock_init(&dev->irqlock);
 	INIT_LIST_HEAD(&dev->instances);
 	INIT_DELAYED_WORK(&dev->timeout, coda_timeout);
-	init_completion(&dev->done);
-	complete(&dev->done);
 
 	dev->plat_dev = pdev;
 	dev->clk_per = devm_clk_get(&pdev->dev, "per");
@@ -1985,17 +2037,9 @@
 		return -ENOENT;
 	}
 
-	if (devm_request_mem_region(&pdev->dev, res->start,
-			resource_size(res), CODA_NAME) == NULL) {
-		dev_err(&pdev->dev, "failed to request memory region\n");
-		return -ENOENT;
-	}
-	dev->regs_base = devm_ioremap(&pdev->dev, res->start,
-				      resource_size(res));
-	if (!dev->regs_base) {
-		dev_err(&pdev->dev, "failed to ioremap address region\n");
-		return -ENOENT;
-	}
+	dev->regs_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dev->regs_base))
+		return PTR_ERR(dev->regs_base);
 
 	/* IRQ */
 	irq = platform_get_irq(pdev, 0);
@@ -2025,6 +2069,7 @@
 		return ret;
 
 	mutex_init(&dev->dev_mutex);
+	mutex_init(&dev->coda_mutex);
 
 	pdev_id = of_id ? of_id->data : platform_get_device_id(pdev);
 
diff --git a/drivers/media/platform/coda.h b/drivers/media/platform/coda.h
index f3f5e43..ace0bf0 100644
--- a/drivers/media/platform/coda.h
+++ b/drivers/media/platform/coda.h
@@ -96,16 +96,12 @@
 #define CODA_CMD_ENC_SEQ_BB_START				0x180
 #define CODA_CMD_ENC_SEQ_BB_SIZE				0x184
 #define CODA_CMD_ENC_SEQ_OPTION				0x188
-#define		CODA_OPTION_GAMMA_OFFSET			7
-#define		CODA_OPTION_GAMMA_MASK				0x01
+#define		CODA7_OPTION_GAMMA_OFFSET			8
+#define		CODADX6_OPTION_GAMMA_OFFSET			7
 #define		CODA_OPTION_LIMITQP_OFFSET			6
-#define		CODA_OPTION_LIMITQP_MASK			0x01
 #define		CODA_OPTION_RCINTRAQP_OFFSET			5
-#define		CODA_OPTION_RCINTRAQP_MASK			0x01
 #define		CODA_OPTION_FMO_OFFSET				4
-#define		CODA_OPTION_FMO_MASK				0x01
 #define		CODA_OPTION_SLICEREPORT_OFFSET			1
-#define		CODA_OPTION_SLICEREPORT_MASK			0x01
 #define CODA_CMD_ENC_SEQ_COD_STD				0x18c
 #define		CODA_STD_MPEG4					0
 #define		CODA_STD_H263					1
@@ -117,7 +113,8 @@
 #define		CODADX6_PICWIDTH_OFFSET				10
 #define		CODADX6_PICWIDTH_MASK				0x3ff
 #define		CODA_PICHEIGHT_OFFSET				0
-#define		CODA_PICHEIGHT_MASK				0x3ff
+#define		CODADX6_PICHEIGHT_MASK				0x3ff
+#define		CODA7_PICHEIGHT_MASK				0xffff
 #define CODA_CMD_ENC_SEQ_SRC_F_RATE				0x194
 #define CODA_CMD_ENC_SEQ_MP4_PARA				0x198
 #define		CODA_MP4PARAM_VERID_OFFSET			6
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index d0b375c..e180ff72 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -944,7 +944,7 @@
 	cfg->interlaced = vpbe_dev->current_timings.interlaced;
 
 	if (V4L2_PIX_FMT_UYVY == pixfmt->pixelformat)
-		cfg->pixfmt = PIXFMT_YCbCrI;
+		cfg->pixfmt = PIXFMT_YCBCRI;
 
 	/* Change of the default pixel format for both video windows */
 	if (V4L2_PIX_FMT_NV12 == pixfmt->pixelformat) {
@@ -1593,31 +1593,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int vpbe_display_g_register(struct file *file, void *priv,
-			struct v4l2_dbg_register *reg)
-{
-	struct v4l2_dbg_match *match = &reg->match;
-	struct vpbe_fh *fh = file->private_data;
-	struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
-
-	if (match->type >= 2) {
-		v4l2_subdev_call(vpbe_dev->venc,
-				 core,
-				 g_register,
-				 reg);
-	}
-
-	return 0;
-}
-
-static int vpbe_display_s_register(struct file *file, void *priv,
-			const struct v4l2_dbg_register *reg)
-{
-	return 0;
-}
-#endif
-
 /* vpbe capture ioctl operations */
 static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
 	.vidioc_querycap	 = vpbe_display_querycap,
@@ -1644,10 +1619,6 @@
 	.vidioc_s_dv_timings	 = vpbe_display_s_dv_timings,
 	.vidioc_g_dv_timings	 = vpbe_display_g_dv_timings,
 	.vidioc_enum_dv_timings	 = vpbe_display_enum_dv_timings,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register	 = vpbe_display_g_register,
-	.vidioc_s_register	 = vpbe_display_s_register,
-#endif
 };
 
 static struct v4l2_file_operations vpbe_fops = {
diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c
index 396a51c..6ed82e8 100644
--- a/drivers/media/platform/davinci/vpbe_osd.c
+++ b/drivers/media/platform/davinci/vpbe_osd.c
@@ -119,7 +119,7 @@
 #define is_rgb_pixfmt(pixfmt) \
 	(((pixfmt) == PIXFMT_RGB565) || ((pixfmt) == PIXFMT_RGB888))
 #define is_yc_pixfmt(pixfmt) \
-	(((pixfmt) == PIXFMT_YCbCrI) || ((pixfmt) == PIXFMT_YCrCbI) || \
+	(((pixfmt) == PIXFMT_YCBCRI) || ((pixfmt) == PIXFMT_YCRCBI) || \
 	((pixfmt) == PIXFMT_NV12))
 #define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X
 #define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5)
@@ -360,8 +360,8 @@
 			osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
 				  OSD_TRANSPVALL);
 		break;
-	case PIXFMT_YCbCrI:
-	case PIXFMT_YCrCbI:
+	case PIXFMT_YCBCRI:
+	case PIXFMT_YCRCBI:
 		if (sd->vpbe_type == VPBE_VERSION_3)
 			osd_modify(sd, OSD_TRANSPVALU_Y, colorkey,
 				   OSD_TRANSPVALU);
@@ -813,8 +813,8 @@
 		if (osd->vpbe_type == VPBE_VERSION_1)
 			bad_config = !is_vid_win(layer);
 		break;
-	case PIXFMT_YCbCrI:
-	case PIXFMT_YCrCbI:
+	case PIXFMT_YCBCRI:
+	case PIXFMT_YCRCBI:
 		bad_config = !is_vid_win(layer);
 		break;
 	case PIXFMT_RGB888:
@@ -950,9 +950,9 @@
 	 * The caller must ensure that all windows using YC pixfmt use the same
 	 * Cb/Cr order.
 	 */
-	if (pixfmt == PIXFMT_YCbCrI)
+	if (pixfmt == PIXFMT_YCBCRI)
 		osd_clear(sd, OSD_MODE_CS, OSD_MODE);
-	else if (pixfmt == PIXFMT_YCrCbI)
+	else if (pixfmt == PIXFMT_YCRCBI)
 		osd_set(sd, OSD_MODE_CS, OSD_MODE);
 }
 
@@ -981,8 +981,8 @@
 				winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
 				_osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0);
 				break;
-			case PIXFMT_YCbCrI:
-			case PIXFMT_YCrCbI:
+			case PIXFMT_YCBCRI:
+			case PIXFMT_YCRCBI:
 				winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
 				break;
 			default:
@@ -1128,8 +1128,8 @@
 					_osd_enable_rgb888_pixblend(sd,
 							OSDWIN_OSD1);
 					break;
-				case PIXFMT_YCbCrI:
-				case PIXFMT_YCrCbI:
+				case PIXFMT_YCBCRI:
+				case PIXFMT_YCRCBI:
 					winmd |=
 					    (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
 					break;
@@ -1508,7 +1508,7 @@
 	_osd_init(osd);
 
 	/* set default Cb/Cr order */
-	osd->yc_pixfmt = PIXFMT_YCbCrI;
+	osd->yc_pixfmt = PIXFMT_YCBCRI;
 
 	if (osd->vpbe_type == VPBE_VERSION_3) {
 		/*
diff --git a/drivers/media/platform/davinci/vpif.c b/drivers/media/platform/davinci/vpif.c
index ea82a8b..cd08e52 100644
--- a/drivers/media/platform/davinci/vpif.c
+++ b/drivers/media/platform/davinci/vpif.c
@@ -17,30 +17,26 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/err.h>
 #include <linux/pm_runtime.h>
+#include <linux/spinlock.h>
 #include <linux/v4l2-dv-timings.h>
 
-#include <mach/hardware.h>
-
 #include "vpif.h"
 
 MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
 MODULE_LICENSE("GPL");
 
-#define VPIF_CH0_MAX_MODES	(22)
-#define VPIF_CH1_MAX_MODES	(02)
-#define VPIF_CH2_MAX_MODES	(15)
-#define VPIF_CH3_MAX_MODES	(02)
+#define VPIF_CH0_MAX_MODES	22
+#define VPIF_CH1_MAX_MODES	2
+#define VPIF_CH2_MAX_MODES	15
+#define VPIF_CH3_MAX_MODES	2
 
-static resource_size_t	res_len;
-static struct resource	*res;
 spinlock_t vpif_lock;
 
 void __iomem *vpif_base;
@@ -423,23 +419,12 @@
 
 static int vpif_probe(struct platform_device *pdev)
 {
-	int status = 0;
+	static struct resource	*res;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENOENT;
-
-	res_len = resource_size(res);
-
-	res = request_mem_region(res->start, res_len, res->name);
-	if (!res)
-		return -EBUSY;
-
-	vpif_base = ioremap(res->start, res_len);
-	if (!vpif_base) {
-		status = -EBUSY;
-		goto fail;
-	}
+	vpif_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(vpif_base))
+		return PTR_ERR(vpif_base);
 
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get(&pdev->dev);
@@ -447,17 +432,11 @@
 	spin_lock_init(&vpif_lock);
 	dev_info(&pdev->dev, "vpif probe success\n");
 	return 0;
-
-fail:
-	release_mem_region(res->start, res_len);
-	return status;
 }
 
 static int vpif_remove(struct platform_device *pdev)
 {
 	pm_runtime_disable(&pdev->dev);
-	iounmap(vpif_base);
-	release_mem_region(res->start, res_len);
 	return 0;
 }
 
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 5f98df1..5514175 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -18,28 +18,16 @@
  * TODO : add support for VBI & HBI data service
  *	  add static buffer allocation
  */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
 
-#include "vpif_capture.h"
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-ioctl.h>
+
 #include "vpif.h"
+#include "vpif_capture.h"
 
 MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
 MODULE_LICENSE("GPL");
@@ -1874,66 +1862,6 @@
 }
 
 /*
- * vpif_g_chip_ident() - Identify the chip
- * @file: file ptr
- * @priv: file handle
- * @chip: chip identity
- *
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_g_chip_ident(struct file *file, void *priv,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-			chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
-		vpif_dbg(2, debug, "match_type is invalid.\n");
-		return -EINVAL;
-	}
-
-	return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
-			g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * vpif_dbg_g_register() - Read register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be read
- *
- * Debugging only
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_dbg_g_register(struct file *file, void *priv,
-		struct v4l2_dbg_register *reg){
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	return v4l2_subdev_call(ch->sd, core, g_register, reg);
-}
-
-/*
- * vpif_dbg_s_register() - Write to register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be modified
- *
- * Debugging only
- * Returns zero or -EINVAL if write operations fails.
- */
-static int vpif_dbg_s_register(struct file *file, void *priv,
-		const struct v4l2_dbg_register *reg)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	return v4l2_subdev_call(ch->sd, core, s_register, reg);
-}
-#endif
-
-/*
  * vpif_log_status() - Status information
  * @file: file ptr
  * @priv: file handle
@@ -1974,11 +1902,6 @@
 	.vidioc_query_dv_timings        = vpif_query_dv_timings,
 	.vidioc_s_dv_timings            = vpif_s_dv_timings,
 	.vidioc_g_dv_timings            = vpif_g_dv_timings,
-	.vidioc_g_chip_ident		= vpif_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register		= vpif_dbg_g_register,
-	.vidioc_s_register		= vpif_dbg_s_register,
-#endif
 	.vidioc_log_status		= vpif_log_status,
 };
 
@@ -2092,16 +2015,13 @@
 	}
 
 	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
-		for (i = res->start; i <= res->end; i++) {
-			if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
-					"VPIF_Capture", (void *)
-					(&vpif_obj.dev[res_idx]->channel_id))) {
-				err = -EBUSY;
-				for (j = 0; j < i; j++)
-					free_irq(j, (void *)
-					(&vpif_obj.dev[res_idx]->channel_id));
-				goto vpif_int_err;
-			}
+		err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
+					IRQF_SHARED, "VPIF_Capture",
+					(void *)(&vpif_obj.dev[res_idx]->
+					channel_id));
+		if (err) {
+			err = -EINVAL;
+			goto vpif_unregister;
 		}
 		res_idx++;
 	}
@@ -2117,7 +2037,7 @@
 				video_device_release(ch->video_dev);
 			}
 			err = -ENOMEM;
-			goto vpif_int_err;
+			goto vpif_unregister;
 		}
 
 		/* Initialize field of video device */
@@ -2170,6 +2090,7 @@
 
 		if (!vpif_obj.sd[i]) {
 			vpif_err("Error registering v4l2 subdevice\n");
+			err = -ENODEV;
 			goto probe_subdev_out;
 		}
 		v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
@@ -2217,13 +2138,9 @@
 		/* Note: does nothing if ch->video_dev == NULL */
 		video_device_release(ch->video_dev);
 	}
-vpif_int_err:
+vpif_unregister:
 	v4l2_device_unregister(&vpif_obj.v4l2_dev);
-	for (i = 0; i < res_idx; i++) {
-		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
-		for (j = res->start; j <= res->end; j++)
-			free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
-	}
+
 	return err;
 }
 
@@ -2235,17 +2152,19 @@
  */
 static int vpif_remove(struct platform_device *device)
 {
-	int i;
 	struct channel_obj *ch;
+	int i;
 
 	v4l2_device_unregister(&vpif_obj.v4l2_dev);
 
+	kfree(vpif_obj.sd);
 	/* un-register device */
 	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
 		/* Get the pointer to the channel object */
 		ch = vpif_obj.dev[i];
 		/* Unregister video device */
 		video_unregister_device(ch->video_dev);
+		kfree(vpif_obj.dev[i]);
 	}
 	return 0;
 }
@@ -2336,47 +2255,4 @@
 	.remove = vpif_remove,
 };
 
-/**
- * vpif_init: initialize the vpif driver
- *
- * This function registers device and driver to the kernel, requests irq
- * handler and allocates memory
- * for channel objects
- */
-static __init int vpif_init(void)
-{
-	return platform_driver_register(&vpif_driver);
-}
-
-/**
- * vpif_cleanup : This function clean up the vpif capture resources
- *
- * This will un-registers device and driver to the kernel, frees
- * requested irq handler and de-allocates memory allocated for channel
- * objects.
- */
-static void vpif_cleanup(void)
-{
-	struct platform_device *pdev;
-	struct resource *res;
-	int irq_num;
-	int i = 0;
-
-	pdev = container_of(vpif_dev, struct platform_device, dev);
-	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
-		for (irq_num = res->start; irq_num <= res->end; irq_num++)
-			free_irq(irq_num,
-				 (void *)(&vpif_obj.dev[i]->channel_id));
-		i++;
-	}
-
-	platform_driver_unregister(&vpif_driver);
-
-	kfree(vpif_obj.sd);
-	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
-		kfree(vpif_obj.dev[i]);
-}
-
-/* Function for module initialization and cleanup */
-module_init(vpif_init);
-module_exit(vpif_cleanup);
+module_platform_driver(vpif_driver);
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h
index 3d3c1e5..0ebb312 100644
--- a/drivers/media/platform/davinci/vpif_capture.h
+++ b/drivers/media/platform/davinci/vpif_capture.h
@@ -22,11 +22,8 @@
 #ifdef __KERNEL__
 
 /* Header files */
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
 #include <media/videobuf2-dma-contig.h>
-#include <media/davinci/vpif_types.h>
+#include <media/v4l2-device.h>
 
 #include "vpif.h"
 
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 1b3fb5c..e6e5736 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -14,33 +14,15 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/string.h>
-#include <linux/videodev2.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/i2c.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/io.h>
 #include <linux/slab.h>
 
-#include <asm/irq.h>
-#include <asm/page.h>
-
-#include <media/adv7343.h>
-#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
 
-#include "vpif_display.h"
 #include "vpif.h"
+#include "vpif_display.h"
 
 MODULE_DESCRIPTION("TI DaVinci VPIF Display driver");
 MODULE_LICENSE("GPL");
@@ -1518,66 +1500,6 @@
 }
 
 /*
- * vpif_g_chip_ident() - Identify the chip
- * @file: file ptr
- * @priv: file handle
- * @chip: chip identity
- *
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_g_chip_ident(struct file *file, void *priv,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-			chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
-		vpif_dbg(2, debug, "match_type is invalid.\n");
-		return -EINVAL;
-	}
-
-	return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
-			g_chip_ident, chip);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * vpif_dbg_g_register() - Read register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be read
- *
- * Debugging only
- * Returns zero or -EINVAL if read operations fails.
- */
-static int vpif_dbg_g_register(struct file *file, void *priv,
-		struct v4l2_dbg_register *reg){
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	return v4l2_subdev_call(ch->sd, core, g_register, reg);
-}
-
-/*
- * vpif_dbg_s_register() - Write to register
- * @file: file ptr
- * @priv: file handle
- * @reg: register to be modified
- *
- * Debugging only
- * Returns zero or -EINVAL if write operations fails.
- */
-static int vpif_dbg_s_register(struct file *file, void *priv,
-		const struct v4l2_dbg_register *reg)
-{
-	struct vpif_fh *fh = priv;
-	struct channel_obj *ch = fh->channel;
-
-	return v4l2_subdev_call(ch->sd, core, s_register, reg);
-}
-#endif
-
-/*
  * vpif_log_status() - Status information
  * @file: file ptr
  * @priv: file handle
@@ -1616,11 +1538,6 @@
 	.vidioc_enum_dv_timings         = vpif_enum_dv_timings,
 	.vidioc_s_dv_timings            = vpif_s_dv_timings,
 	.vidioc_g_dv_timings            = vpif_g_dv_timings,
-	.vidioc_g_chip_ident		= vpif_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register		= vpif_dbg_g_register,
-	.vidioc_s_register		= vpif_dbg_s_register,
-#endif
 	.vidioc_log_status		= vpif_log_status,
 };
 
@@ -1734,16 +1651,14 @@
 	}
 
 	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
-		for (i = res->start; i <= res->end; i++) {
-			if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
-					"VPIF_Display", (void *)
-					(&vpif_obj.dev[res_idx]->channel_id))) {
-				err = -EBUSY;
-				for (j = 0; j < i; j++)
-					free_irq(j, (void *)
-					(&vpif_obj.dev[res_idx]->channel_id));
-				goto vpif_int_err;
-			}
+		err = devm_request_irq(&pdev->dev, res->start, vpif_channel_isr,
+					IRQF_SHARED, "VPIF_Display",
+					(void *)(&vpif_obj.dev[res_idx]->
+					channel_id));
+		if (err) {
+			err = -EINVAL;
+			vpif_err("VPIF IRQ request failed\n");
+			goto vpif_unregister;
 		}
 		res_idx++;
 	}
@@ -1760,7 +1675,7 @@
 				video_device_release(ch->video_dev);
 			}
 			err = -ENOMEM;
-			goto vpif_int_err;
+			goto vpif_unregister;
 		}
 
 		/* Initialize field of video device */
@@ -1813,6 +1728,7 @@
 						NULL);
 		if (!vpif_obj.sd[i]) {
 			vpif_err("Error registering v4l2 subdevice\n");
+			err = -ENODEV;
 			goto probe_subdev_out;
 		}
 
@@ -1893,14 +1809,8 @@
 		/* Note: does nothing if ch->video_dev == NULL */
 		video_device_release(ch->video_dev);
 	}
-vpif_int_err:
+vpif_unregister:
 	v4l2_device_unregister(&vpif_obj.v4l2_dev);
-	vpif_err("VPIF IRQ request failed\n");
-	for (i = 0; i < res_idx; i++) {
-		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
-		for (j = res->start; j <= res->end; j++)
-			free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
-	}
 
 	return err;
 }
@@ -1915,6 +1825,7 @@
 
 	v4l2_device_unregister(&vpif_obj.v4l2_dev);
 
+	kfree(vpif_obj.sd);
 	/* un-register device */
 	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
 		/* Get the pointer to the channel object */
@@ -1923,6 +1834,7 @@
 		video_unregister_device(ch->video_dev);
 
 		ch->video_dev = NULL;
+		kfree(vpif_obj.dev[i]);
 	}
 
 	return 0;
@@ -2008,37 +1920,4 @@
 	.remove	= vpif_remove,
 };
 
-static __init int vpif_init(void)
-{
-	return platform_driver_register(&vpif_driver);
-}
-
-/*
- * vpif_cleanup: This function un-registers device and driver to the kernel,
- * frees requested irq handler and de-allocates memory allocated for channel
- * objects.
- */
-static void vpif_cleanup(void)
-{
-	struct platform_device *pdev;
-	struct resource *res;
-	int irq_num;
-	int i = 0;
-
-	pdev = container_of(vpif_dev, struct platform_device, dev);
-
-	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
-		for (irq_num = res->start; irq_num <= res->end; irq_num++)
-			free_irq(irq_num,
-				 (void *)(&vpif_obj.dev[i]->channel_id));
-		i++;
-	}
-
-	platform_driver_unregister(&vpif_driver);
-	kfree(vpif_obj.sd);
-	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
-		kfree(vpif_obj.dev[i]);
-}
-
-module_init(vpif_init);
-module_exit(vpif_cleanup);
+module_platform_driver(vpif_driver);
diff --git a/drivers/media/platform/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h
index a5a18f7..5d87fc8 100644
--- a/drivers/media/platform/davinci/vpif_display.h
+++ b/drivers/media/platform/davinci/vpif_display.h
@@ -17,11 +17,8 @@
 #define DAVINCIHD_DISPLAY_H
 
 /* Header files */
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-device.h>
 #include <media/videobuf2-dma-contig.h>
-#include <media/davinci/vpif_types.h>
+#include <media/v4l2-device.h>
 
 #include "vpif.h"
 
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c
index 33b5ffc..559fab2 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -988,7 +988,7 @@
 
 	if (pdev->dev.of_node) {
 		const struct of_device_id *match;
-		match = of_match_node(of_match_ptr(exynos_gsc_match),
+		match = of_match_node(exynos_gsc_match,
 					pdev->dev.of_node);
 		if (match)
 			driver_data = (struct gsc_driverdata *)match->data;
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
index 436a62a..53ad0f0 100644
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ b/drivers/media/platform/exynos4-is/Kconfig
@@ -9,12 +9,16 @@
 
 if VIDEO_SAMSUNG_EXYNOS4_IS
 
+config VIDEO_EXYNOS4_IS_COMMON
+       tristate
+
 config VIDEO_S5P_FIMC
 	tristate "S5P/EXYNOS4 FIMC/CAMIF camera interface driver"
 	depends on I2C
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_MEM2MEM_DEV
 	select MFD_SYSCON if OF
+	select VIDEO_EXYNOS4_IS_COMMON
 	help
 	  This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host
 	  interface and video postprocessor (FIMC) devices.
@@ -39,6 +43,7 @@
 	tristate "EXYNOS FIMC-LITE camera interface driver"
 	depends on I2C
 	select VIDEOBUF2_DMA_CONTIG
+	select VIDEO_EXYNOS4_IS_COMMON
 	help
 	  This is a V4L2 driver for Samsung EXYNOS4/5 SoC FIMC-LITE camera
 	  host interface.
diff --git a/drivers/media/platform/exynos4-is/Makefile b/drivers/media/platform/exynos4-is/Makefile
index f25f463..c2ff29b 100644
--- a/drivers/media/platform/exynos4-is/Makefile
+++ b/drivers/media/platform/exynos4-is/Makefile
@@ -1,10 +1,13 @@
 s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-m2m.o fimc-capture.o media-dev.o
 exynos-fimc-lite-objs += fimc-lite-reg.o fimc-lite.o
+s5p-csis-objs := mipi-csis.o
+exynos4-is-common-objs := common.o
+
 exynos-fimc-is-objs := fimc-is.o fimc-isp.o fimc-is-sensor.o fimc-is-regs.o
 exynos-fimc-is-objs += fimc-is-param.o fimc-is-errno.o fimc-is-i2c.o
-s5p-csis-objs := mipi-csis.o
 
 obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS)	+= s5p-csis.o
 obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE)	+= exynos-fimc-lite.o
 obj-$(CONFIG_VIDEO_EXYNOS4_FIMC_IS)	+= exynos-fimc-is.o
 obj-$(CONFIG_VIDEO_S5P_FIMC)		+= s5p-fimc.o
+obj-$(CONFIG_VIDEO_EXYNOS4_IS_COMMON)	+= exynos4-is-common.o
diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c
new file mode 100644
index 0000000..0ec210b
--- /dev/null
+++ b/drivers/media/platform/exynos4-is/common.c
@@ -0,0 +1,53 @@
+/*
+ * Samsung S5P/EXYNOS4 SoC Camera Subsystem driver
+ *
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <media/s5p_fimc.h>
+#include "common.h"
+
+/* Called with the media graph mutex held or entity->stream_count > 0. */
+struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)
+{
+	struct media_pad *pad = &entity->pads[0];
+	struct v4l2_subdev *sd;
+
+	while (pad->flags & MEDIA_PAD_FL_SINK) {
+		/* source pad */
+		pad = media_entity_remote_pad(pad);
+		if (pad == NULL ||
+		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+			break;
+
+		sd = media_entity_to_v4l2_subdev(pad->entity);
+
+		if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR ||
+		    sd->grp_id == GRP_ID_SENSOR)
+			return sd;
+		/* sink pad */
+		pad = &sd->entity.pads[0];
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(fimc_find_remote_sensor);
+
+void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
+						unsigned int caps)
+{
+	strlcpy(cap->driver, dev->driver->name, sizeof(cap->driver));
+	strlcpy(cap->card, dev->driver->name, sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+				"platform:%s", dev_name(dev));
+	cap->device_caps = caps;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+}
+EXPORT_SYMBOL(__fimc_vidioc_querycap);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/exynos4-is/common.h b/drivers/media/platform/exynos4-is/common.h
new file mode 100644
index 0000000..75b9c71
--- /dev/null
+++ b/drivers/media/platform/exynos4-is/common.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include <linux/device.h>
+#include <linux/videodev2.h>
+#include <media/media-entity.h>
+#include <media/v4l2-subdev.h>
+
+struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity);
+void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
+			    unsigned int caps);
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index 528f413..fb27ff7 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -27,9 +27,10 @@
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-dma-contig.h>
 
-#include "media-dev.h"
+#include "common.h"
 #include "fimc-core.h"
 #include "fimc-reg.h"
+#include "media-dev.h"
 
 static int fimc_capture_hw_init(struct fimc_dev *fimc)
 {
@@ -119,8 +120,7 @@
 	spin_unlock_irqrestore(&fimc->slock, flags);
 
 	if (streaming)
-		return fimc_pipeline_call(fimc, set_stream,
-					  &fimc->pipeline, 0);
+		return fimc_pipeline_call(&cap->ve, set_stream, 0);
 	else
 		return 0;
 }
@@ -178,8 +178,9 @@
 
 void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
 {
-	struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
 	struct fimc_vid_cap *cap = &fimc->vid_cap;
+	struct fimc_pipeline *p = to_fimc_pipeline(cap->ve.pipe);
+	struct v4l2_subdev *csis = p->subdevs[IDX_CSIS];
 	struct fimc_frame *f = &cap->ctx->d_frame;
 	struct fimc_vid_buffer *v_buf;
 	struct timeval *tv;
@@ -287,8 +288,7 @@
 		fimc_activate_capture(ctx);
 
 		if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
-			return fimc_pipeline_call(fimc, set_stream,
-						  &fimc->pipeline, 1);
+			return fimc_pipeline_call(&vid_cap->ve, set_stream, 1);
 	}
 
 	return 0;
@@ -312,7 +312,7 @@
 	int ret = fimc_stop_capture(fimc, suspend);
 	if (ret)
 		return ret;
-	return fimc_pipeline_call(fimc, close, &fimc->pipeline);
+	return fimc_pipeline_call(&fimc->vid_cap.ve, close);
 }
 
 static void buffer_queue(struct vb2_buffer *vb);
@@ -320,6 +320,7 @@
 int fimc_capture_resume(struct fimc_dev *fimc)
 {
 	struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
+	struct exynos_video_entity *ve = &vid_cap->ve;
 	struct fimc_vid_buffer *buf;
 	int i;
 
@@ -328,8 +329,7 @@
 
 	INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
 	vid_cap->buf_index = 0;
-	fimc_pipeline_call(fimc, open, &fimc->pipeline,
-			   &vid_cap->vfd.entity, false);
+	fimc_pipeline_call(ve, open, &ve->vdev.entity, false);
 	fimc_capture_hw_init(fimc);
 
 	clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
@@ -397,7 +397,7 @@
 		unsigned long size = ctx->d_frame.payload[i];
 
 		if (vb2_plane_size(vb, i) < size) {
-			v4l2_err(&ctx->fimc_dev->vid_cap.vfd,
+			v4l2_err(&ctx->fimc_dev->vid_cap.ve.vdev,
 				 "User buffer too small (%ld < %ld)\n",
 				 vb2_plane_size(vb, i), size);
 			return -EINVAL;
@@ -415,6 +415,7 @@
 	struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 	struct fimc_dev *fimc = ctx->fimc_dev;
 	struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
+	struct exynos_video_entity *ve = &vid_cap->ve;
 	unsigned long flags;
 	int min_bufs;
 
@@ -452,9 +453,9 @@
 		if (test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
 			return;
 
-		ret = fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 1);
+		ret = fimc_pipeline_call(ve, set_stream, 1);
 		if (ret < 0)
-			v4l2_err(&vid_cap->vfd, "stream on failed: %d\n", ret);
+			v4l2_err(&ve->vdev, "stream on failed: %d\n", ret);
 		return;
 	}
 	spin_unlock_irqrestore(&fimc->slock, flags);
@@ -470,44 +471,17 @@
 	.stop_streaming		= stop_streaming,
 };
 
-/**
- * fimc_capture_ctrls_create - initialize the control handler
- * Initialize the capture video node control handler and fill it
- * with the FIMC controls. Inherit any sensor's controls if the
- * 'user_subdev_api' flag is false (default behaviour).
- * This function need to be called with the graph mutex held.
- */
-int fimc_capture_ctrls_create(struct fimc_dev *fimc)
-{
-	struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
-	struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
-	int ret;
-
-	if (WARN_ON(vid_cap->ctx == NULL))
-		return -ENXIO;
-	if (vid_cap->ctx->ctrls.ready)
-		return 0;
-
-	ret = fimc_ctrls_create(vid_cap->ctx);
-
-	if (ret || vid_cap->user_subdev_api || !sensor ||
-	    !vid_cap->ctx->ctrls.ready)
-		return ret;
-
-	return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
-				     sensor->ctrl_handler, NULL);
-}
-
 static int fimc_capture_set_default_format(struct fimc_dev *fimc);
 
 static int fimc_capture_open(struct file *file)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
+	struct fimc_vid_cap *vc = &fimc->vid_cap;
+	struct exynos_video_entity *ve = &vc->ve;
 	int ret = -EBUSY;
 
 	dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
 
-	fimc_md_graph_lock(fimc);
 	mutex_lock(&fimc->lock);
 
 	if (fimc_m2m_active(fimc))
@@ -520,31 +494,42 @@
 
 	ret = v4l2_fh_open(file);
 	if (ret) {
-		pm_runtime_put(&fimc->pdev->dev);
+		pm_runtime_put_sync(&fimc->pdev->dev);
 		goto unlock;
 	}
 
 	if (v4l2_fh_is_singular_file(file)) {
-		ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
-					 &fimc->vid_cap.vfd.entity, true);
+		fimc_md_graph_lock(ve);
 
-		if (!ret && !fimc->vid_cap.user_subdev_api)
+		ret = fimc_pipeline_call(ve, open, &ve->vdev.entity, true);
+
+		if (ret == 0 && vc->user_subdev_api && vc->inh_sensor_ctrls) {
+			/*
+			 * Recreate controls of the the video node to drop
+			 * any controls inherited from the sensor subdev.
+			 */
+			fimc_ctrls_delete(vc->ctx);
+
+			ret = fimc_ctrls_create(vc->ctx);
+			if (ret == 0)
+				vc->inh_sensor_ctrls = false;
+		}
+		if (ret == 0)
+			ve->vdev.entity.use_count++;
+
+		fimc_md_graph_unlock(ve);
+
+		if (ret == 0)
 			ret = fimc_capture_set_default_format(fimc);
 
-		if (!ret)
-			ret = fimc_capture_ctrls_create(fimc);
-
 		if (ret < 0) {
 			clear_bit(ST_CAPT_BUSY, &fimc->state);
 			pm_runtime_put_sync(&fimc->pdev->dev);
 			v4l2_fh_release(file);
-		} else {
-			fimc->vid_cap.refcnt++;
 		}
 	}
 unlock:
 	mutex_unlock(&fimc->lock);
-	fimc_md_graph_unlock(fimc);
 	return ret;
 }
 
@@ -552,30 +537,31 @@
 {
 	struct fimc_dev *fimc = video_drvdata(file);
 	struct fimc_vid_cap *vc = &fimc->vid_cap;
+	bool close = v4l2_fh_is_singular_file(file);
 	int ret;
 
 	dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
 
 	mutex_lock(&fimc->lock);
 
-	if (v4l2_fh_is_singular_file(file)) {
-		if (vc->streaming) {
-			media_entity_pipeline_stop(&vc->vfd.entity);
-			vc->streaming = false;
-		}
-		clear_bit(ST_CAPT_BUSY, &fimc->state);
-		fimc_stop_capture(fimc, false);
-		fimc_pipeline_call(fimc, close, &fimc->pipeline);
-		clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
-		fimc->vid_cap.refcnt--;
+	if (close && vc->streaming) {
+		media_entity_pipeline_stop(&vc->ve.vdev.entity);
+		vc->streaming = false;
 	}
 
-	pm_runtime_put(&fimc->pdev->dev);
-
-	if (v4l2_fh_is_singular_file(file))
-		fimc_ctrls_delete(fimc->vid_cap.ctx);
-
 	ret = vb2_fop_release(file);
+
+	if (close) {
+		clear_bit(ST_CAPT_BUSY, &fimc->state);
+		fimc_pipeline_call(&vc->ve, close);
+		clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
+
+		fimc_md_graph_lock(&vc->ve);
+		vc->ve.vdev.entity.use_count--;
+		fimc_md_graph_unlock(&vc->ve);
+	}
+
+	pm_runtime_put_sync(&fimc->pdev->dev);
 	mutex_unlock(&fimc->lock);
 
 	return ret;
@@ -773,7 +759,7 @@
 	struct media_pad *pad = &me->pads[0];
 
 	while (!(pad->flags & MEDIA_PAD_FL_SOURCE)) {
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (!pad)
 			break;
 		me = pad->entity;
@@ -797,7 +783,8 @@
 				    bool set)
 {
 	struct fimc_dev *fimc = ctx->fimc_dev;
-	struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
+	struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe);
+	struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR];
 	struct v4l2_subdev_format sfmt;
 	struct v4l2_mbus_framefmt *mf = &sfmt.format;
 	struct media_entity *me;
@@ -845,7 +832,7 @@
 					return ret;
 			}
 
-			pad = media_entity_remote_source(&me->pads[sfmt.pad]);
+			pad = media_entity_remote_pad(&me->pads[sfmt.pad]);
 			if (!pad)
 				return -EINVAL;
 			me = pad->entity;
@@ -929,57 +916,101 @@
 	return 0;
 }
 
-static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
-				   struct v4l2_format *f)
+/*
+ * Try or set format on the fimc.X.capture video node and additionally
+ * on the whole pipeline if @try is false.
+ * Locking: the caller must _not_ hold the graph mutex.
+ */
+static int __video_try_or_set_format(struct fimc_dev *fimc,
+				     struct v4l2_format *f, bool try,
+				     struct fimc_fmt **inp_fmt,
+				     struct fimc_fmt **out_fmt)
 {
 	struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
-	struct fimc_dev *fimc = video_drvdata(file);
-	struct fimc_ctx *ctx = fimc->vid_cap.ctx;
-	struct v4l2_mbus_framefmt mf;
-	struct fimc_fmt *ffmt = NULL;
+	struct fimc_vid_cap *vc = &fimc->vid_cap;
+	struct exynos_video_entity *ve = &vc->ve;
+	struct fimc_ctx *ctx = vc->ctx;
+	unsigned int width = 0, height = 0;
 	int ret = 0;
 
-	fimc_md_graph_lock(fimc);
-	mutex_lock(&fimc->lock);
-
+	/* Pre-configure format at the camera input interface, for JPEG only */
 	if (fimc_jpeg_fourcc(pix->pixelformat)) {
 		fimc_capture_try_format(ctx, &pix->width, &pix->height,
 					NULL, &pix->pixelformat,
 					FIMC_SD_PAD_SINK_CAM);
-		ctx->s_frame.f_width  = pix->width;
-		ctx->s_frame.f_height = pix->height;
-	}
-	ffmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
-				       NULL, &pix->pixelformat,
-				       FIMC_SD_PAD_SOURCE);
-	if (!ffmt) {
-		ret = -EINVAL;
-		goto unlock;
+		if (try) {
+			width = pix->width;
+			height = pix->height;
+		} else {
+			ctx->s_frame.f_width = pix->width;
+			ctx->s_frame.f_height = pix->height;
+		}
 	}
 
-	if (!fimc->vid_cap.user_subdev_api) {
-		mf.width = pix->width;
-		mf.height = pix->height;
-		mf.code = ffmt->mbus_code;
-		fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
-		pix->width = mf.width;
-		pix->height = mf.height;
-		if (ffmt)
-			pix->pixelformat = ffmt->fourcc;
+	/* Try the format at the scaler and the DMA output */
+	*out_fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
+					  NULL, &pix->pixelformat,
+					  FIMC_SD_PAD_SOURCE);
+	if (*out_fmt == NULL)
+		return -EINVAL;
+
+	/* Restore image width/height for JPEG (no resizing supported). */
+	if (try && fimc_jpeg_fourcc(pix->pixelformat)) {
+		pix->width = width;
+		pix->height = height;
 	}
 
-	fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
+	/* Try to match format at the host and the sensor */
+	if (!vc->user_subdev_api) {
+		struct v4l2_mbus_framefmt mbus_fmt;
+		struct v4l2_mbus_framefmt *mf;
 
-	if (ffmt->flags & FMT_FLAGS_COMPRESSED)
-		fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
-					pix->plane_fmt, ffmt->memplanes, true);
-unlock:
-	mutex_unlock(&fimc->lock);
-	fimc_md_graph_unlock(fimc);
+		mf = try ? &mbus_fmt : &fimc->vid_cap.ci_fmt;
+
+		mf->code = (*out_fmt)->mbus_code;
+		mf->width = pix->width;
+		mf->height = pix->height;
+
+		fimc_md_graph_lock(ve);
+		ret = fimc_pipeline_try_format(ctx, mf, inp_fmt, try);
+		fimc_md_graph_unlock(ve);
+
+		if (ret < 0)
+			return ret;
+
+		pix->width = mf->width;
+		pix->height = mf->height;
+	}
+
+	fimc_adjust_mplane_format(*out_fmt, pix->width, pix->height, pix);
+
+	if ((*out_fmt)->flags & FMT_FLAGS_COMPRESSED) {
+		struct v4l2_subdev *sensor;
+
+		fimc_md_graph_lock(ve);
+
+		sensor = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
+		if (sensor)
+			fimc_get_sensor_frame_desc(sensor, pix->plane_fmt,
+						   (*out_fmt)->memplanes, try);
+		else
+			ret = -EPIPE;
+
+		fimc_md_graph_unlock(ve);
+	}
 
 	return ret;
 }
 
+static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
+				   struct v4l2_format *f)
+{
+	struct fimc_dev *fimc = video_drvdata(file);
+	struct fimc_fmt *out_fmt = NULL, *inp_fmt = NULL;
+
+	return __video_try_or_set_format(fimc, f, true, &inp_fmt, &out_fmt);
+}
+
 static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx,
 					enum fimc_color_fmt color)
 {
@@ -997,57 +1028,23 @@
 static int __fimc_capture_set_format(struct fimc_dev *fimc,
 				     struct v4l2_format *f)
 {
-	struct fimc_ctx *ctx = fimc->vid_cap.ctx;
+	struct fimc_vid_cap *vc = &fimc->vid_cap;
+	struct fimc_ctx *ctx = vc->ctx;
 	struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
-	struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.ci_fmt;
 	struct fimc_frame *ff = &ctx->d_frame;
-	struct fimc_fmt *s_fmt = NULL;
+	struct fimc_fmt *inp_fmt = NULL;
 	int ret, i;
 
 	if (vb2_is_busy(&fimc->vid_cap.vbq))
 		return -EBUSY;
 
-	/* Pre-configure format at camera interface input, for JPEG only */
-	if (fimc_jpeg_fourcc(pix->pixelformat)) {
-		fimc_capture_try_format(ctx, &pix->width, &pix->height,
-					NULL, &pix->pixelformat,
-					FIMC_SD_PAD_SINK_CAM);
-		ctx->s_frame.f_width  = pix->width;
-		ctx->s_frame.f_height = pix->height;
-	}
-	/* Try the format at the scaler and the DMA output */
-	ff->fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
-					  NULL, &pix->pixelformat,
-					  FIMC_SD_PAD_SOURCE);
-	if (!ff->fmt)
-		return -EINVAL;
+	ret = __video_try_or_set_format(fimc, f, false, &inp_fmt, &ff->fmt);
+	if (ret < 0)
+		return ret;
 
 	/* Update RGB Alpha control state and value range */
 	fimc_alpha_ctrl_update(ctx);
 
-	/* Try to match format at the host and the sensor */
-	if (!fimc->vid_cap.user_subdev_api) {
-		mf->code   = ff->fmt->mbus_code;
-		mf->width  = pix->width;
-		mf->height = pix->height;
-		ret = fimc_pipeline_try_format(ctx, mf, &s_fmt, true);
-		if (ret)
-			return ret;
-
-		pix->width  = mf->width;
-		pix->height = mf->height;
-	}
-
-	fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
-
-	if (ff->fmt->flags & FMT_FLAGS_COMPRESSED) {
-		ret = fimc_get_sensor_frame_desc(fimc->pipeline.subdevs[IDX_SENSOR],
-					pix->plane_fmt, ff->fmt->memplanes,
-					true);
-		if (ret < 0)
-			return ret;
-	}
-
 	for (i = 0; i < ff->fmt->memplanes; i++) {
 		ff->bytesperline[i] = pix->plane_fmt[i].bytesperline;
 		ff->payload[i] = pix->plane_fmt[i].sizeimage;
@@ -1061,8 +1058,8 @@
 	fimc_capture_mark_jpeg_xfer(ctx, ff->fmt->color);
 
 	/* Reset cropping and set format at the camera interface input */
-	if (!fimc->vid_cap.user_subdev_api) {
-		ctx->s_frame.fmt = s_fmt;
+	if (!vc->user_subdev_api) {
+		ctx->s_frame.fmt = inp_fmt;
 		set_frame_bounds(&ctx->s_frame, pix->width, pix->height);
 		set_frame_crop(&ctx->s_frame, 0, 0, pix->width, pix->height);
 	}
@@ -1074,37 +1071,28 @@
 				 struct v4l2_format *f)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
-	int ret;
 
-	fimc_md_graph_lock(fimc);
-	mutex_lock(&fimc->lock);
-	/*
-	 * The graph is walked within __fimc_capture_set_format() to set
-	 * the format at subdevs thus the graph mutex needs to be held at
-	 * this point and acquired before the video mutex, to avoid  AB-BA
-	 * deadlock when fimc_md_link_notify() is called by other thread.
-	 * Ideally the graph walking and setting format at the whole pipeline
-	 * should be removed from this driver and handled in userspace only.
-	 */
-	ret = __fimc_capture_set_format(fimc, f);
-
-	mutex_unlock(&fimc->lock);
-	fimc_md_graph_unlock(fimc);
-	return ret;
+	return __fimc_capture_set_format(fimc, f);
 }
 
 static int fimc_cap_enum_input(struct file *file, void *priv,
 			       struct v4l2_input *i)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
-	struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
+	struct exynos_video_entity *ve = &fimc->vid_cap.ve;
+	struct v4l2_subdev *sd;
 
 	if (i->index != 0)
 		return -EINVAL;
 
 	i->type = V4L2_INPUT_TYPE_CAMERA;
+	fimc_md_graph_lock(ve);
+	sd = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
+	fimc_md_graph_unlock(ve);
+
 	if (sd)
 		strlcpy(i->name, sd->name, sizeof(i->name));
+
 	return 0;
 }
 
@@ -1130,6 +1118,7 @@
 	struct v4l2_subdev_format sink_fmt, src_fmt;
 	struct fimc_vid_cap *vc = &fimc->vid_cap;
 	struct v4l2_subdev *sd = &vc->subdev;
+	struct fimc_pipeline *p = to_fimc_pipeline(vc->ve.pipe);
 	struct media_pad *sink_pad, *src_pad;
 	int i, ret;
 
@@ -1146,7 +1135,7 @@
 
 			if (p->flags & MEDIA_PAD_FL_SINK) {
 				sink_pad = p;
-				src_pad = media_entity_remote_source(sink_pad);
+				src_pad = media_entity_remote_pad(sink_pad);
 				if (src_pad)
 					break;
 			}
@@ -1183,7 +1172,7 @@
 		    src_fmt.format.code != sink_fmt.format.code)
 			return -EPIPE;
 
-		if (sd == fimc->pipeline.subdevs[IDX_SENSOR] &&
+		if (sd == p->subdevs[IDX_SENSOR] &&
 		    fimc_user_defined_mbus_fmt(src_fmt.format.code)) {
 			struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES];
 			struct fimc_frame *frame = &vc->ctx->d_frame;
@@ -1207,9 +1196,8 @@
 			     enum v4l2_buf_type type)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
-	struct fimc_pipeline *p = &fimc->pipeline;
 	struct fimc_vid_cap *vc = &fimc->vid_cap;
-	struct media_entity *entity = &vc->vfd.entity;
+	struct media_entity *entity = &vc->ve.vdev.entity;
 	struct fimc_source_info *si = NULL;
 	struct v4l2_subdev *sd;
 	int ret;
@@ -1217,11 +1205,11 @@
 	if (fimc_capture_active(fimc))
 		return -EBUSY;
 
-	ret = media_entity_pipeline_start(entity, p->m_pipeline);
+	ret = media_entity_pipeline_start(entity, &vc->ve.pipe->mp);
 	if (ret < 0)
 		return ret;
 
-	sd = p->subdevs[IDX_SENSOR];
+	sd = __fimc_md_get_subdev(vc->ve.pipe, IDX_SENSOR);
 	if (sd)
 		si = v4l2_get_subdev_hostdata(sd);
 
@@ -1259,14 +1247,15 @@
 			    enum v4l2_buf_type type)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
+	struct fimc_vid_cap *vc = &fimc->vid_cap;
 	int ret;
 
 	ret = vb2_ioctl_streamoff(file, priv, type);
 	if (ret < 0)
 		return ret;
 
-	media_entity_pipeline_stop(&fimc->vid_cap.vfd.entity);
-	fimc->vid_cap.streaming = false;
+	media_entity_pipeline_stop(&vc->ve.vdev.entity);
+	vc->streaming = false;
 	return 0;
 }
 
@@ -1405,6 +1394,8 @@
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
+	struct fimc_vid_cap *vc = &fimc->vid_cap;
+	struct v4l2_subdev *sensor;
 
 	if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 		return -EINVAL;
@@ -1416,15 +1407,26 @@
 	    local->entity->name, remote->entity->name, flags,
 	    fimc->vid_cap.input);
 
-	if (flags & MEDIA_LNK_FL_ENABLED) {
-		if (fimc->vid_cap.input != 0)
-			return -EBUSY;
-		fimc->vid_cap.input = sd->grp_id;
+	if (!(flags & MEDIA_LNK_FL_ENABLED)) {
+		fimc->vid_cap.input = 0;
 		return 0;
 	}
 
-	fimc->vid_cap.input = 0;
-	return 0;
+	if (vc->input != 0)
+		return -EBUSY;
+
+	vc->input = sd->grp_id;
+
+	if (vc->user_subdev_api || vc->inh_sensor_ctrls)
+		return 0;
+
+	/* Inherit V4L2 controls from the image sensor subdev. */
+	sensor = fimc_find_remote_sensor(&vc->subdev.entity);
+	if (sensor == NULL)
+		return 0;
+
+	return v4l2_ctrl_add_handler(&vc->ctx->ctrls.handler,
+				     sensor->ctrl_handler, NULL);
 }
 
 static const struct media_entity_operations fimc_sd_media_ops = {
@@ -1720,8 +1722,8 @@
 	struct v4l2_format fmt = {
 		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
 		.fmt.pix_mp = {
-			.width		= 640,
-			.height		= 480,
+			.width		= FIMC_DEFAULT_WIDTH,
+			.height		= FIMC_DEFAULT_HEIGHT,
 			.pixelformat	= V4L2_PIX_FMT_YUYV,
 			.field		= V4L2_FIELD_NONE,
 			.colorspace	= V4L2_COLORSPACE_JPEG,
@@ -1735,10 +1737,11 @@
 static int fimc_register_capture_device(struct fimc_dev *fimc,
 				 struct v4l2_device *v4l2_dev)
 {
-	struct video_device *vfd = &fimc->vid_cap.vfd;
+	struct video_device *vfd = &fimc->vid_cap.ve.vdev;
 	struct vb2_queue *q = &fimc->vid_cap.vbq;
 	struct fimc_ctx *ctx;
 	struct fimc_vid_cap *vid_cap;
+	struct fimc_fmt *fmt;
 	int ret = -ENOMEM;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -1784,22 +1787,34 @@
 
 	ret = vb2_queue_init(q);
 	if (ret)
-		goto err_ent;
+		goto err_free_ctx;
+
+	/* Default format configuration */
+	fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
+	vid_cap->ci_fmt.width = FIMC_DEFAULT_WIDTH;
+	vid_cap->ci_fmt.height = FIMC_DEFAULT_HEIGHT;
+	vid_cap->ci_fmt.code = fmt->mbus_code;
+
+	ctx->s_frame.width = FIMC_DEFAULT_WIDTH;
+	ctx->s_frame.height = FIMC_DEFAULT_HEIGHT;
+	ctx->s_frame.fmt = fmt;
+
+	fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_WRITEBACK, 0);
+	vid_cap->wb_fmt = vid_cap->ci_fmt;
+	vid_cap->wb_fmt.code = fmt->mbus_code;
 
 	vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
 	ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
 	if (ret)
-		goto err_ent;
-	/*
-	 * For proper order of acquiring/releasing the video
-	 * and the graph mutex.
-	 */
-	v4l2_disable_ioctl_locking(vfd, VIDIOC_TRY_FMT);
-	v4l2_disable_ioctl_locking(vfd, VIDIOC_S_FMT);
+		goto err_free_ctx;
+
+	ret = fimc_ctrls_create(ctx);
+	if (ret)
+		goto err_me_cleanup;
 
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
 	if (ret)
-		goto err_vd;
+		goto err_ctrl_free;
 
 	v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
 		  vfd->name, video_device_node_name(vfd));
@@ -1807,9 +1822,11 @@
 	vfd->ctrl_handler = &ctx->ctrls.handler;
 	return 0;
 
-err_vd:
+err_ctrl_free:
+	fimc_ctrls_delete(ctx);
+err_me_cleanup:
 	media_entity_cleanup(&vfd->entity);
-err_ent:
+err_free_ctx:
 	kfree(ctx);
 	return ret;
 }
@@ -1826,12 +1843,12 @@
 	if (ret)
 		return ret;
 
-	fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
+	fimc->vid_cap.ve.pipe = v4l2_get_subdev_hostdata(sd);
 
 	ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
 	if (ret) {
 		fimc_unregister_m2m_device(fimc);
-		fimc->pipeline_ops = NULL;
+		fimc->vid_cap.ve.pipe = NULL;
 	}
 
 	return ret;
@@ -1840,19 +1857,26 @@
 static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
 {
 	struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
+	struct video_device *vdev;
 
 	if (fimc == NULL)
 		return;
 
-	fimc_unregister_m2m_device(fimc);
+	mutex_lock(&fimc->lock);
 
-	if (video_is_registered(&fimc->vid_cap.vfd)) {
-		video_unregister_device(&fimc->vid_cap.vfd);
-		media_entity_cleanup(&fimc->vid_cap.vfd.entity);
-		fimc->pipeline_ops = NULL;
+	fimc_unregister_m2m_device(fimc);
+	vdev = &fimc->vid_cap.ve.vdev;
+
+	if (video_is_registered(vdev)) {
+		video_unregister_device(vdev);
+		media_entity_cleanup(&vdev->entity);
+		fimc_ctrls_delete(fimc->vid_cap.ctx);
+		fimc->vid_cap.ve.pipe = NULL;
 	}
 	kfree(fimc->vid_cap.ctx);
 	fimc->vid_cap.ctx = NULL;
+
+	mutex_unlock(&fimc->lock);
 }
 
 static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index 379a5e9..6489c51 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -213,17 +213,6 @@
 	return &fimc_formats[index];
 }
 
-void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
-						unsigned int caps)
-{
-	strlcpy(cap->driver, dev->driver->name, sizeof(cap->driver));
-	strlcpy(cap->card, dev->driver->name, sizeof(cap->card));
-	snprintf(cap->bus_info, sizeof(cap->bus_info),
-				"platform:%s", dev_name(dev));
-	cap->device_caps = caps;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-}
-
 int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
 			    int dw, int dh, int rotation)
 {
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
index 539a3f7..3d376fa 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.h
+++ b/drivers/media/platform/exynos4-is/fimc-core.h
@@ -48,6 +48,8 @@
 #define FIMC_DEF_MIN_SIZE	16
 #define FIMC_DEF_HEIGHT_ALIGN	2
 #define FIMC_DEF_HOR_OFFS_ALIGN	1
+#define FIMC_DEFAULT_WIDTH	640
+#define FIMC_DEFAULT_HEIGHT	480
 
 /* indices to the clocks array */
 enum {
@@ -283,8 +285,8 @@
 /**
  * struct fimc_vid_cap - camera capture device information
  * @ctx: hardware context data
- * @vfd: video device node for camera capture mode
  * @subdev: subdev exposing the FIMC processing block
+ * @ve: exynos video device entity structure
  * @vd_pad: fimc video capture node pad
  * @sd_pads: fimc video processing block pads
  * @ci_fmt: image format at the FIMC camera input (and the scaler output)
@@ -298,15 +300,16 @@
  * @frame_count: the frame counter for statistics
  * @reqbufs_count: the number of buffers requested in REQBUFS ioctl
  * @input_index: input (camera sensor) index
- * @refcnt: driver's private reference counter
  * @input: capture input type, grp_id of the attached subdev
  * @user_subdev_api: true if subdevs are not configured by the host driver
+ * @inh_sensor_ctrls: a flag indicating v4l2 controls are inherited from
+ * 		      an image sensor subdev
  */
 struct fimc_vid_cap {
 	struct fimc_ctx			*ctx;
 	struct vb2_alloc_ctx		*alloc_ctx;
-	struct video_device		vfd;
 	struct v4l2_subdev		subdev;
+	struct exynos_video_entity	ve;
 	struct media_pad		vd_pad;
 	struct media_pad		sd_pads[FIMC_SD_PADS_NUM];
 	struct v4l2_mbus_framefmt	ci_fmt;
@@ -321,9 +324,9 @@
 	unsigned int			reqbufs_count;
 	bool				streaming;
 	int				input_index;
-	int				refcnt;
 	u32				input;
 	bool				user_subdev_api;
+	bool				inh_sensor_ctrls;
 };
 
 /**
@@ -434,8 +437,6 @@
 	struct fimc_vid_cap		vid_cap;
 	unsigned long			state;
 	struct vb2_alloc_ctx		*alloc_ctx;
-	struct fimc_pipeline		pipeline;
-	const struct fimc_pipeline_ops	*pipeline_ops;
 };
 
 /**
@@ -620,8 +621,6 @@
 /* fimc-core.c */
 int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
 				struct v4l2_fmtdesc *f);
-void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap,
-						unsigned int caps);
 int fimc_ctrls_create(struct fimc_ctx *ctx);
 void fimc_ctrls_delete(struct fimc_ctx *ctx);
 void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active);
diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.c b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
index c397777..617a798 100644
--- a/drivers/media/platform/exynos4-is/fimc-is-i2c.c
+++ b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
@@ -96,7 +96,7 @@
 	return clk_prepare_enable(isp_i2c->clock);
 }
 
-UNIVERSAL_DEV_PM_OPS(fimc_is_i2c_pm_ops, fimc_is_i2c_suspend,
+static UNIVERSAL_DEV_PM_OPS(fimc_is_i2c_pm_ops, fimc_is_i2c_suspend,
 		     fimc_is_i2c_resume, NULL);
 
 static const struct of_device_id fimc_is_i2c_of_match[] = {
diff --git a/drivers/media/platform/exynos4-is/fimc-is-param.c b/drivers/media/platform/exynos4-is/fimc-is-param.c
index 53fe2a2..c7e7f69 100644
--- a/drivers/media/platform/exynos4-is/fimc-is-param.c
+++ b/drivers/media/platform/exynos4-is/fimc-is-param.c
@@ -38,7 +38,7 @@
 	memcpy(dst, src, FIMC_IS_PARAM_MAX_SIZE);
 }
 
-void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
+static void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
 {
 	struct param_global_shotmode *dst, *src;
 
@@ -47,7 +47,7 @@
 	__hw_param_copy(dst, src);
 }
 
-void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
+static void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
 {
 	struct param_sensor_framerate *dst, *src;
 
@@ -168,8 +168,8 @@
 	unsigned int count;
 
 	spin_lock_irqsave(&is->slock, flags);
-	count = hweight32(config->p_region_index1);
-	count += hweight32(config->p_region_index2);
+	count = hweight32(config->p_region_index[0]);
+	count += hweight32(config->p_region_index[1]);
 	spin_unlock_irqrestore(&is->slock, flags);
 
 	return count;
@@ -177,31 +177,30 @@
 
 int __is_hw_update_params(struct fimc_is *is)
 {
-	unsigned long *p_index1, *p_index2;
+	unsigned long *p_index;
 	int i, id, ret = 0;
 
 	id = is->config_index;
-	p_index1 = &is->config[id].p_region_index1;
-	p_index2 = &is->config[id].p_region_index2;
+	p_index = &is->config[id].p_region_index[0];
 
-	if (test_bit(PARAM_GLOBAL_SHOTMODE, p_index1))
+	if (test_bit(PARAM_GLOBAL_SHOTMODE, p_index))
 		__fimc_is_hw_update_param_global_shotmode(is);
 
-	if (test_bit(PARAM_SENSOR_FRAME_RATE, p_index1))
+	if (test_bit(PARAM_SENSOR_FRAME_RATE, p_index))
 		__fimc_is_hw_update_param_sensor_framerate(is);
 
 	for (i = PARAM_ISP_CONTROL; i < PARAM_DRC_CONTROL; i++) {
-		if (test_bit(i, p_index1))
+		if (test_bit(i, p_index))
 			ret = __fimc_is_hw_update_param(is, i);
 	}
 
 	for (i = PARAM_DRC_CONTROL; i < PARAM_SCALERC_CONTROL; i++) {
-		if (test_bit(i, p_index1))
+		if (test_bit(i, p_index))
 			ret = __fimc_is_hw_update_param(is, i);
 	}
 
 	for (i = PARAM_FD_CONTROL; i <= PARAM_FD_CONFIG; i++) {
-		if (test_bit((i - 32), p_index2))
+		if (test_bit(i, p_index))
 			ret = __fimc_is_hw_update_param(is, i);
 	}
 
@@ -243,7 +242,7 @@
 	fd->otf_input.height = mf->height;
 
 	if (test_bit(PARAM_ISP_OTF_INPUT,
-		      &is->config[index].p_region_index1))
+		      &is->config[index].p_region_index[0]))
 		return;
 
 	/* Update field */
@@ -368,7 +367,7 @@
 	unsigned long *p_index;
 	struct isp_param *isp;
 
-	p_index = &is->config[index].p_region_index1;
+	p_index = &is->config[index].p_region_index[0];
 	isp = &is->config[index].isp;
 
 	switch (cmd) {
@@ -415,7 +414,7 @@
 	struct isp_param *isp;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index1;
+	p_index = &is->config[index].p_region_index[0];
 	isp = &is->config[index].isp;
 
 	switch (id) {
@@ -476,7 +475,7 @@
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->control.cmd = val;
@@ -491,7 +490,7 @@
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.max_number = val;
@@ -511,7 +510,7 @@
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.roll_angle = val;
@@ -531,7 +530,7 @@
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.yaw_angle = val;
@@ -551,7 +550,7 @@
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.smile_mode = val;
@@ -571,7 +570,7 @@
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.blink_mode = val;
@@ -591,7 +590,7 @@
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.eye_detect = val;
@@ -611,7 +610,7 @@
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.mouth_detect = val;
@@ -631,7 +630,7 @@
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.orientation = val;
@@ -651,7 +650,7 @@
 	struct fd_param *fd;
 	unsigned long *p_index;
 
-	p_index = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[1];
 	fd = &is->config[index].fd;
 
 	fd->config.orientation_value = val;
@@ -672,7 +671,7 @@
 	struct isp_param *isp;
 	struct drc_param *drc;
 	struct fd_param *fd;
-	unsigned long *p_index1, *p_index2;
+	unsigned long *p_index;
 	unsigned int index;
 
 	index = is->config_index;
@@ -681,8 +680,7 @@
 	isp = &is->config[index].isp;
 	drc = &is->config[index].drc;
 	fd = &is->config[index].fd;
-	p_index1 = &is->config[index].p_region_index1;
-	p_index2 = &is->config[index].p_region_index2;
+	p_index = &is->config[index].p_region_index[0];
 
 	/* Global */
 	global->shotmode.cmd = 1;
@@ -695,7 +693,7 @@
 	fimc_is_set_param_bit(is, PARAM_ISP_CONTROL);
 
 	isp->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
-	if (!test_bit(PARAM_ISP_OTF_INPUT, p_index1)) {
+	if (!test_bit(PARAM_ISP_OTF_INPUT, p_index)) {
 		isp->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
 		isp->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
 		fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT);
@@ -738,20 +736,20 @@
 	isp->aa.target = ISP_AA_TARGET_AE | ISP_AA_TARGET_AWB;
 	fimc_is_set_param_bit(is, PARAM_ISP_AA);
 
-	if (!test_bit(PARAM_ISP_FLASH, p_index1))
+	if (!test_bit(PARAM_ISP_FLASH, p_index))
 		__is_set_isp_flash(is, ISP_FLASH_COMMAND_DISABLE,
 						ISP_FLASH_REDEYE_DISABLE);
 
-	if (!test_bit(PARAM_ISP_AWB, p_index1))
+	if (!test_bit(PARAM_ISP_AWB, p_index))
 		__is_set_isp_awb(is, ISP_AWB_COMMAND_AUTO, 0);
 
-	if (!test_bit(PARAM_ISP_IMAGE_EFFECT, p_index1))
+	if (!test_bit(PARAM_ISP_IMAGE_EFFECT, p_index))
 		__is_set_isp_effect(is, ISP_IMAGE_EFFECT_DISABLE);
 
-	if (!test_bit(PARAM_ISP_ISO, p_index1))
+	if (!test_bit(PARAM_ISP_ISO, p_index))
 		__is_set_isp_iso(is, ISP_ISO_COMMAND_AUTO, 0);
 
-	if (!test_bit(PARAM_ISP_ADJUST, p_index1)) {
+	if (!test_bit(PARAM_ISP_ADJUST, p_index)) {
 		__is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_CONTRAST, 0);
 		__is_set_isp_adjust(is,
 				ISP_ADJUST_COMMAND_MANUAL_SATURATION, 0);
@@ -762,7 +760,7 @@
 		__is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_HUE, 0);
 	}
 
-	if (!test_bit(PARAM_ISP_METERING, p_index1)) {
+	if (!test_bit(PARAM_ISP_METERING, p_index)) {
 		__is_set_isp_metering(is, 0, ISP_METERING_COMMAND_CENTER);
 		__is_set_isp_metering(is, 1, 0);
 		__is_set_isp_metering(is, 2, 0);
@@ -770,11 +768,11 @@
 		__is_set_isp_metering(is, 4, 0);
 	}
 
-	if (!test_bit(PARAM_ISP_AFC, p_index1))
+	if (!test_bit(PARAM_ISP_AFC, p_index))
 		__is_set_isp_afc(is, ISP_AFC_COMMAND_AUTO, 0);
 
 	isp->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
-	if (!test_bit(PARAM_ISP_OTF_OUTPUT, p_index1)) {
+	if (!test_bit(PARAM_ISP_OTF_OUTPUT, p_index)) {
 		isp->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH;
 		isp->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT;
 		fimc_is_set_param_bit(is, PARAM_ISP_OTF_OUTPUT);
@@ -784,7 +782,7 @@
 	isp->otf_output.order = 0;
 	isp->otf_output.err = OTF_OUTPUT_ERROR_NONE;
 
-	if (!test_bit(PARAM_ISP_DMA1_OUTPUT, p_index1)) {
+	if (!test_bit(PARAM_ISP_DMA1_OUTPUT, p_index)) {
 		isp->dma1_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
 		isp->dma1_output.width = 0;
 		isp->dma1_output.height = 0;
@@ -800,7 +798,7 @@
 		fimc_is_set_param_bit(is, PARAM_ISP_DMA1_OUTPUT);
 	}
 
-	if (!test_bit(PARAM_ISP_DMA2_OUTPUT, p_index1)) {
+	if (!test_bit(PARAM_ISP_DMA2_OUTPUT, p_index)) {
 		isp->dma2_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
 		isp->dma2_output.width = 0;
 		isp->dma2_output.height = 0;
@@ -817,7 +815,7 @@
 	}
 
 	/* Sensor */
-	if (!test_bit(PARAM_SENSOR_FRAME_RATE, p_index1)) {
+	if (!test_bit(PARAM_SENSOR_FRAME_RATE, p_index)) {
 		if (is->config_index == 0)
 			__is_set_sensor(is, 0);
 	}
@@ -827,7 +825,7 @@
 	__is_set_drc_control(is, CONTROL_BYPASS_ENABLE);
 
 	drc->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
-	if (!test_bit(PARAM_DRC_OTF_INPUT, p_index1)) {
+	if (!test_bit(PARAM_DRC_OTF_INPUT, p_index)) {
 		drc->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
 		drc->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
 		fimc_is_set_param_bit(is, PARAM_DRC_OTF_INPUT);
@@ -850,7 +848,7 @@
 	fimc_is_set_param_bit(is, PARAM_DRC_DMA_INPUT);
 
 	drc->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
-	if (!test_bit(PARAM_DRC_OTF_OUTPUT, p_index1)) {
+	if (!test_bit(PARAM_DRC_OTF_OUTPUT, p_index)) {
 		drc->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH;
 		drc->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT;
 		fimc_is_set_param_bit(is, PARAM_DRC_OTF_OUTPUT);
@@ -865,7 +863,7 @@
 	fd->control.bypass = CONTROL_BYPASS_DISABLE;
 
 	fd->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
-	if (!test_bit((PARAM_FD_OTF_INPUT - 32), p_index2)) {
+	if (!test_bit(PARAM_FD_OTF_INPUT, p_index)) {
 		fd->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
 		fd->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
 		fimc_is_set_param_bit(is, PARAM_FD_OTF_INPUT);
diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c
index d05eaa2..63c68ec 100644
--- a/drivers/media/platform/exynos4-is/fimc-is-regs.c
+++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c
@@ -89,8 +89,8 @@
 	mcuctl_write(is->config_index, is, MCUCTL_REG_ISSR(2));
 
 	mcuctl_write(param_count, is, MCUCTL_REG_ISSR(3));
-	mcuctl_write(config->p_region_index1, is, MCUCTL_REG_ISSR(4));
-	mcuctl_write(config->p_region_index2, is, MCUCTL_REG_ISSR(5));
+	mcuctl_write(config->p_region_index[0], is, MCUCTL_REG_ISSR(4));
+	mcuctl_write(config->p_region_index[1], is, MCUCTL_REG_ISSR(5));
 
 	fimc_is_hw_set_intgr0_gd0(is);
 	return 0;
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 0741945..967f6a9 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -129,7 +129,7 @@
 					ATCLK_MCUISP_FREQUENCY);
 }
 
-int fimc_is_enable_clocks(struct fimc_is *is)
+static int fimc_is_enable_clocks(struct fimc_is *is)
 {
 	int i, ret;
 
@@ -149,7 +149,7 @@
 	return 0;
 }
 
-void fimc_is_disable_clocks(struct fimc_is *is)
+static void fimc_is_disable_clocks(struct fimc_is *is)
 {
 	int i;
 
@@ -527,8 +527,8 @@
 			break;
 
 		case HIC_SET_PARAMETER:
-			is->config[is->config_index].p_region_index1 = 0;
-			is->config[is->config_index].p_region_index2 = 0;
+			is->config[is->config_index].p_region_index[0] = 0;
+			is->config[is->config_index].p_region_index[1] = 0;
 			set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
 			pr_debug("HIC_SET_PARAMETER\n");
 			break;
@@ -587,8 +587,8 @@
 
 		switch (is->i2h_cmd.args[0]) {
 		case HIC_SET_PARAMETER:
-			is->config[is->config_index].p_region_index1 = 0;
-			is->config[is->config_index].p_region_index2 = 0;
+			is->config[is->config_index].p_region_index[0] = 0;
+			is->config[is->config_index].p_region_index[1] = 0;
 			set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
 			break;
 		}
diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
index d7db133..61bb012 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.h
+++ b/drivers/media/platform/exynos4-is/fimc-is.h
@@ -33,8 +33,8 @@
 
 #define FIMC_IS_DRV_NAME		"exynos4-fimc-is"
 
-#define FIMC_IS_FW_FILENAME		"fimc_is_fw.bin"
-#define FIMC_IS_SETFILE_6A3		"setfile.bin"
+#define FIMC_IS_FW_FILENAME		"exynos4_fimc_is_fw.bin"
+#define FIMC_IS_SETFILE_6A3		"exynos4_s5k6a3_setfile.bin"
 
 #define FIMC_IS_FW_LOAD_TIMEOUT		1000 /* ms */
 #define FIMC_IS_POWER_ON_TIMEOUT	1000 /* us */
@@ -225,8 +225,7 @@
 	struct drc_param	drc;
 	struct fd_param		fd;
 
-	unsigned long		p_region_index1;
-	unsigned long		p_region_index2;
+	unsigned long		p_region_index[2];
 };
 
 /**
@@ -302,10 +301,7 @@
 {
 	struct chain_config *cfg = &is->config[is->config_index];
 
-	if (num >= 32)
-		set_bit(num - 32, &cfg->p_region_index2);
-	else
-		set_bit(num, &cfg->p_region_index1);
+	set_bit(num, &cfg->p_region_index[0]);
 }
 
 static inline void fimc_is_set_param_ctrl_cmd(struct fimc_is *is, int cmd)
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index 7ede30b..cf520a7 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -30,8 +30,8 @@
 #include "fimc-is-regs.h"
 #include "fimc-is.h"
 
-static int debug;
-module_param_named(debug_isp, debug, int, S_IRUGO | S_IWUSR);
+int fimc_isp_debug;
+module_param_named(debug_isp, fimc_isp_debug, int, S_IRUGO | S_IWUSR);
 
 static const struct fimc_fmt fimc_isp_formats[FIMC_ISP_NUM_FORMATS] = {
 	{
@@ -128,57 +128,70 @@
 				   struct v4l2_subdev_format *fmt)
 {
 	struct fimc_isp *isp = v4l2_get_subdevdata(sd);
-	struct fimc_is *is = fimc_isp_to_is(isp);
 	struct v4l2_mbus_framefmt *mf = &fmt->format;
-	struct v4l2_mbus_framefmt cur_fmt;
 
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-		mf = v4l2_subdev_get_try_format(fh, fmt->pad);
-		fmt->format = *mf;
+		*mf = *v4l2_subdev_get_try_format(fh, fmt->pad);
 		return 0;
 	}
 
 	mf->colorspace = V4L2_COLORSPACE_SRGB;
 
 	mutex_lock(&isp->subdev_lock);
-	__is_get_frame_size(is, &cur_fmt);
 
 	if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
-		/* full camera input frame size */
-		mf->width = cur_fmt.width + FIMC_ISP_CAC_MARGIN_WIDTH;
-		mf->height = cur_fmt.height + FIMC_ISP_CAC_MARGIN_HEIGHT;
-		mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
+		/* ISP OTF input image format */
+		*mf = isp->sink_fmt;
 	} else {
-		/* crop size */
-		mf->width = cur_fmt.width;
-		mf->height = cur_fmt.height;
-		mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+		/* ISP OTF output image format */
+		*mf = isp->src_fmt;
+
+		if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
+			mf->colorspace = V4L2_COLORSPACE_JPEG;
+			mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+		}
 	}
 
 	mutex_unlock(&isp->subdev_lock);
 
-	v4l2_dbg(1, debug, sd, "%s: pad%d: fmt: 0x%x, %dx%d\n",
-		 __func__, fmt->pad, mf->code, mf->width, mf->height);
+	isp_dbg(1, sd, "%s: pad%d: fmt: 0x%x, %dx%d\n", __func__,
+		fmt->pad, mf->code, mf->width, mf->height);
 
 	return 0;
 }
 
 static void __isp_subdev_try_format(struct fimc_isp *isp,
-				   struct v4l2_subdev_format *fmt)
+				    struct v4l2_subdev_fh *fh,
+				    struct v4l2_subdev_format *fmt)
 {
 	struct v4l2_mbus_framefmt *mf = &fmt->format;
+	struct v4l2_mbus_framefmt *format;
+
+	mf->colorspace = V4L2_COLORSPACE_SRGB;
 
 	if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
 		v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN,
 				FIMC_ISP_SINK_WIDTH_MAX, 0,
 				&mf->height, FIMC_ISP_SINK_HEIGHT_MIN,
 				FIMC_ISP_SINK_HEIGHT_MAX, 0, 0);
-		isp->subdev_fmt = *mf;
+		mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
 	} else {
+		if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+			format = v4l2_subdev_get_try_format(fh,
+						FIMC_ISP_SD_PAD_SINK);
+		else
+			format = &isp->sink_fmt;
+
 		/* Allow changing format only on sink pad */
-		mf->width = isp->subdev_fmt.width - FIMC_ISP_CAC_MARGIN_WIDTH;
-		mf->height = isp->subdev_fmt.height - FIMC_ISP_CAC_MARGIN_HEIGHT;
-		mf->code = isp->subdev_fmt.code;
+		mf->width = format->width - FIMC_ISP_CAC_MARGIN_WIDTH;
+		mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT;
+
+		if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
+			mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+			mf->colorspace = V4L2_COLORSPACE_JPEG;
+		} else {
+			mf->code = format->code;
+		}
 	}
 }
 
@@ -191,27 +204,50 @@
 	struct v4l2_mbus_framefmt *mf = &fmt->format;
 	int ret = 0;
 
-	v4l2_dbg(1, debug, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
+	isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
 		 __func__, fmt->pad, mf->code, mf->width, mf->height);
 
-	mf->colorspace = V4L2_COLORSPACE_SRGB;
-
 	mutex_lock(&isp->subdev_lock);
-	__isp_subdev_try_format(isp, fmt);
+	__isp_subdev_try_format(isp, fh, fmt);
 
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
 		mf = v4l2_subdev_get_try_format(fh, fmt->pad);
 		*mf = fmt->format;
-		mutex_unlock(&isp->subdev_lock);
-		return 0;
+
+		/* Propagate format to the source pads */
+		if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
+			struct v4l2_subdev_format format = *fmt;
+			unsigned int pad;
+
+			for (pad = FIMC_ISP_SD_PAD_SRC_FIFO;
+					pad < FIMC_ISP_SD_PADS_NUM; pad++) {
+				format.pad = pad;
+				__isp_subdev_try_format(isp, fh, &format);
+				mf = v4l2_subdev_get_try_format(fh, pad);
+				*mf = format.format;
+			}
+		}
+	} else {
+		if (sd->entity.stream_count == 0) {
+			if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
+				struct v4l2_subdev_format format = *fmt;
+
+				isp->sink_fmt = *mf;
+
+				format.pad = FIMC_ISP_SD_PAD_SRC_DMA;
+				__isp_subdev_try_format(isp, fh, &format);
+
+				isp->src_fmt = format.format;
+				__is_set_frame_size(is, &isp->src_fmt);
+			} else {
+				isp->src_fmt = *mf;
+			}
+		} else {
+			ret = -EBUSY;
+		}
 	}
 
-	if (sd->entity.stream_count == 0)
-		__is_set_frame_size(is, mf);
-	else
-		ret = -EBUSY;
 	mutex_unlock(&isp->subdev_lock);
-
 	return ret;
 }
 
@@ -221,7 +257,7 @@
 	struct fimc_is *is = fimc_isp_to_is(isp);
 	int ret;
 
-	v4l2_dbg(1, debug, sd, "%s: on: %d\n", __func__, on);
+	isp_dbg(1, sd, "%s: on: %d\n", __func__, on);
 
 	if (!test_bit(IS_ST_INIT_DONE, &is->state))
 		return -EBUSY;
@@ -235,8 +271,8 @@
 				return ret;
 		}
 
-		v4l2_dbg(1, debug, sd, "changing mode to %d\n",
-						is->config_index);
+		isp_dbg(1, sd, "changing mode to %d\n", is->config_index);
+
 		ret = fimc_is_itf_mode_change(is);
 		if (ret)
 			return -EINVAL;
@@ -317,8 +353,8 @@
 		clear_bit(IS_ST_PWR_ON, &is->state);
 		clear_bit(IS_ST_INIT_DONE, &is->state);
 		is->state = 0;
-		is->config[is->config_index].p_region_index1 = 0;
-		is->config[is->config_index].p_region_index2 = 0;
+		is->config[is->config_index].p_region_index[0] = 0;
+		is->config[is->config_index].p_region_index[1] = 0;
 		set_bit(IS_ST_IDLE, &is->state);
 		wmb();
 	}
@@ -609,6 +645,22 @@
 	.s_ctrl	= fimc_is_s_ctrl,
 };
 
+static void __isp_subdev_set_default_format(struct fimc_isp *isp)
+{
+	struct fimc_is *is = fimc_isp_to_is(isp);
+
+	isp->sink_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH +
+				FIMC_ISP_CAC_MARGIN_WIDTH;
+	isp->sink_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT +
+				FIMC_ISP_CAC_MARGIN_HEIGHT;
+	isp->sink_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10;
+
+	isp->src_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH;
+	isp->src_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT;
+	isp->src_fmt.code = V4L2_MBUS_FMT_SGRBG10_1X10;
+	__is_set_frame_size(is, &isp->src_fmt);
+}
+
 int fimc_isp_subdev_create(struct fimc_isp *isp)
 {
 	const struct v4l2_ctrl_ops *ops = &fimc_isp_ctrl_ops;
@@ -689,6 +741,8 @@
 	sd->entity.ops = &fimc_is_subdev_media_ops;
 	v4l2_set_subdevdata(sd, isp);
 
+	__isp_subdev_set_default_format(isp);
+
 	return 0;
 }
 
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h
index 800aba7..03bf95a 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.h
+++ b/drivers/media/platform/exynos4-is/fimc-isp.h
@@ -26,6 +26,11 @@
 #include <media/v4l2-mediabus.h>
 #include <media/s5p_fimc.h>
 
+extern int fimc_isp_debug;
+
+#define isp_dbg(level, dev, fmt, arg...) \
+	v4l2_dbg(level, fimc_isp_debug, dev, fmt, ## arg)
+
 /* FIXME: revisit these constraints */
 #define FIMC_ISP_SINK_WIDTH_MIN		(16 + 8)
 #define FIMC_ISP_SINK_HEIGHT_MIN	(12 + 8)
@@ -118,7 +123,6 @@
 	unsigned int		frame_count;
 	unsigned int		reqbufs_count;
 	int			streaming;
-	unsigned long		payload[FIMC_ISP_MAX_PLANES];
 	const struct fimc_fmt	*format;
 };
 
@@ -128,15 +132,9 @@
  * @alloc_ctx: videobuf2 memory allocator context
  * @subdev: ISP v4l2_subdev
  * @subdev_pads: the ISP subdev media pads
- * @ctrl_handler: v4l2 controls handler
  * @test_pattern: test pattern controls
- * @pipeline: video capture pipeline data structure
+ * @ctrls: v4l2 controls structure
  * @video_lock: mutex serializing video device and the subdev operations
- * @fmt: pointer to color format description structure
- * @payload: image size in bytes (w x h x bpp)
- * @inp_frame: camera input frame structure
- * @out_frame: DMA output frame structure
- * @source_subdev_grp_id: group id of remote source subdev
  * @cac_margin_x: horizontal CAC margin in pixels
  * @cac_margin_y: vertical CAC margin in pixels
  * @state: driver state flags
@@ -147,17 +145,14 @@
 	struct vb2_alloc_ctx		*alloc_ctx;
 	struct v4l2_subdev		subdev;
 	struct media_pad		subdev_pads[FIMC_ISP_SD_PADS_NUM];
-	struct v4l2_mbus_framefmt	subdev_fmt;
+	struct v4l2_mbus_framefmt	src_fmt;
+	struct v4l2_mbus_framefmt	sink_fmt;
 	struct v4l2_ctrl		*test_pattern;
 	struct fimc_isp_ctrls		ctrls;
 
 	struct mutex			video_lock;
 	struct mutex			subdev_lock;
 
-	struct fimc_isp_frame		inp_frame;
-	struct fimc_isp_frame		out_frame;
-	unsigned int			source_subdev_grp_id;
-
 	unsigned int			cac_margin_x;
 	unsigned int			cac_margin_y;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
index 8cc0d39..72a343e3b 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
@@ -2,15 +2,16 @@
  * Register interface file for EXYNOS FIMC-LITE (camera interface) driver
  *
  * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
 */
 
-#include <linux/io.h>
+#include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/io.h>
 #include <media/s5p_fimc.h>
 
 #include "fimc-lite-reg.h"
@@ -68,7 +69,8 @@
 	if (atomic_read(&dev->out_path) == FIMC_IO_DMA) {
 		intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
 			 FLITE_REG_CIGCTRL_IRQ_LASTEN |
-			 FLITE_REG_CIGCTRL_IRQ_STARTEN;
+			 FLITE_REG_CIGCTRL_IRQ_STARTEN |
+			 FLITE_REG_CIGCTRL_IRQ_ENDEN;
 	} else {
 		/* An output to the FIMC-IS */
 		intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
@@ -137,7 +139,7 @@
 	}
 
 	if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
-		v4l2_err(&dev->vfd,
+		v4l2_err(&dev->ve.vdev,
 			 "Unsupported pixel code, falling back to %#08x\n",
 			 src_pixfmt_map[i][0]);
 	}
@@ -215,6 +217,18 @@
 	flite_hw_set_camera_port(dev, si->mux_id);
 }
 
+static void flite_hw_set_pack12(struct fimc_lite *dev, int on)
+{
+	u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
+
+	cfg &= ~FLITE_REG_CIODMAFMT_PACK12;
+
+	if (on)
+		cfg |= FLITE_REG_CIODMAFMT_PACK12;
+
+	writel(cfg, dev->regs + FLITE_REG_CIODMAFMT);
+}
+
 static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
 {
 	static const u32 pixcode[4][2] = {
@@ -250,6 +264,38 @@
 	writel(cfg, dev->regs + FLITE_REG_CIOOFF);
 }
 
+void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf)
+{
+	unsigned int index;
+	u32 cfg;
+
+	if (dev->dd->max_dma_bufs == 1)
+		index = 0;
+	else
+		index = buf->index;
+
+	if (index == 0)
+		writel(buf->paddr, dev->regs + FLITE_REG_CIOSA);
+	else
+		writel(buf->paddr, dev->regs + FLITE_REG_CIOSAN(index - 1));
+
+	cfg = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
+	cfg |= BIT(index);
+	writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
+}
+
+void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index)
+{
+	u32 cfg;
+
+	if (dev->dd->max_dma_bufs == 1)
+		index = 0;
+
+	cfg = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
+	cfg &= ~BIT(index);
+	writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
+}
+
 /* Enable/disable output DMA, set output pixel size and offsets (composition) */
 void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
 			     bool enable)
@@ -267,6 +313,7 @@
 
 	flite_hw_set_out_order(dev, f);
 	flite_hw_set_dma_window(dev, f);
+	flite_hw_set_pack12(dev, 0);
 }
 
 void flite_hw_dump_regs(struct fimc_lite *dev, const char *label)
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
index 3903839..10a7d7b 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
@@ -120,6 +120,9 @@
 /* b0: 1 - camera B, 0 - camera A */
 #define FLITE_REG_CIGENERAL_CAM_B		(1 << 0)
 
+#define FLITE_REG_CIFCNTSEQ			0x100
+#define FLITE_REG_CIOSAN(x)			(0x200 + (4 * (x)))
+
 /* ----------------------------------------------------------------------------
  * Function declarations
  */
@@ -142,9 +145,12 @@
 void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f);
 void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on);
 void flite_hw_dump_regs(struct fimc_lite *dev, const char *label);
+void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf);
+void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index);
 
-static inline void flite_hw_set_output_addr(struct fimc_lite *dev, u32 paddr)
+static inline void flite_hw_set_dma_buf_mask(struct fimc_lite *dev, u32 mask)
 {
-	writel(paddr, dev->regs + FLITE_REG_CIOSA);
+	writel(mask, dev->regs + FLITE_REG_CIFCNTSEQ);
 }
+
 #endif /* FIMC_LITE_REG_H */
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 14bb7bc..08fbfed 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1,8 +1,8 @@
 /*
  * Samsung EXYNOS FIMC-LITE (camera host interface) driver
 *
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@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
@@ -32,6 +32,7 @@
 #include <media/videobuf2-dma-contig.h>
 #include <media/s5p_fimc.h>
 
+#include "common.h"
 #include "fimc-core.h"
 #include "fimc-lite.h"
 #include "fimc-lite-reg.h"
@@ -43,6 +44,7 @@
 	{
 		.name		= "YUV 4:2:2 packed, YCbYCr",
 		.fourcc		= V4L2_PIX_FMT_YUYV,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_YCBYCR422,
 		.memplanes	= 1,
@@ -51,6 +53,7 @@
 	}, {
 		.name		= "YUV 4:2:2 packed, CbYCrY",
 		.fourcc		= V4L2_PIX_FMT_UYVY,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_CBYCRY422,
 		.memplanes	= 1,
@@ -59,6 +62,7 @@
 	}, {
 		.name		= "YUV 4:2:2 packed, CrYCbY",
 		.fourcc		= V4L2_PIX_FMT_VYUY,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_CRYCBY422,
 		.memplanes	= 1,
@@ -67,6 +71,7 @@
 	}, {
 		.name		= "YUV 4:2:2 packed, YCrYCb",
 		.fourcc		= V4L2_PIX_FMT_YVYU,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_YCRYCB422,
 		.memplanes	= 1,
@@ -75,6 +80,7 @@
 	}, {
 		.name		= "RAW8 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG8,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
 		.depth		= { 8 },
 		.color		= FIMC_FMT_RAW8,
 		.memplanes	= 1,
@@ -83,6 +89,7 @@
 	}, {
 		.name		= "RAW10 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG10,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
 		.depth		= { 10 },
 		.color		= FIMC_FMT_RAW10,
 		.memplanes	= 1,
@@ -91,6 +98,7 @@
 	}, {
 		.name		= "RAW12 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG12,
+		.colorspace	= V4L2_COLORSPACE_SRGB,
 		.depth		= { 12 },
 		.color		= FIMC_FMT_RAW12,
 		.memplanes	= 1,
@@ -131,30 +139,6 @@
 	return def_fmt;
 }
 
-/* Called with the media graph mutex held or @me stream_count > 0. */
-static struct v4l2_subdev *__find_remote_sensor(struct media_entity *me)
-{
-	struct media_pad *pad = &me->pads[0];
-	struct v4l2_subdev *sd;
-
-	while (pad->flags & MEDIA_PAD_FL_SINK) {
-		/* source pad */
-		pad = media_entity_remote_source(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
-			break;
-
-		sd = media_entity_to_v4l2_subdev(pad->entity);
-
-		if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR ||
-		    sd->grp_id == GRP_ID_SENSOR)
-			return sd;
-		/* sink pad */
-		pad = &sd->entity.pads[0];
-	}
-	return NULL;
-}
-
 static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output)
 {
 	struct fimc_source_info *si;
@@ -176,6 +160,7 @@
 	flite_hw_set_camera_bus(fimc, si);
 	flite_hw_set_source_format(fimc, &fimc->inp_frame);
 	flite_hw_set_window_offset(fimc, &fimc->inp_frame);
+	flite_hw_set_dma_buf_mask(fimc, 0);
 	flite_hw_set_output_dma(fimc, &fimc->out_frame, !isp_output);
 	flite_hw_set_interrupt_mask(fimc);
 	flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
@@ -233,7 +218,7 @@
 	if (!streaming)
 		return 0;
 
-	return fimc_pipeline_call(fimc, set_stream, &fimc->pipeline, 0);
+	return fimc_pipeline_call(&fimc->ve, set_stream, 0);
 }
 
 static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
@@ -299,19 +284,23 @@
 
 	if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
 	    test_bit(ST_FLITE_RUN, &fimc->state) &&
-	    !list_empty(&fimc->active_buf_q) &&
 	    !list_empty(&fimc->pending_buf_q)) {
+		vbuf = fimc_lite_pending_queue_pop(fimc);
+		flite_hw_set_dma_buffer(fimc, vbuf);
+		fimc_lite_active_queue_add(fimc, vbuf);
+	}
+
+	if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMEND) &&
+	    test_bit(ST_FLITE_RUN, &fimc->state) &&
+	    !list_empty(&fimc->active_buf_q)) {
 		vbuf = fimc_lite_active_queue_pop(fimc);
 		ktime_get_ts(&ts);
 		tv = &vbuf->vb.v4l2_buf.timestamp;
 		tv->tv_sec = ts.tv_sec;
 		tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
 		vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
+		flite_hw_mask_dma_buffer(fimc, vbuf->index);
 		vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
-
-		vbuf = fimc_lite_pending_queue_pop(fimc);
-		flite_hw_set_output_addr(fimc, vbuf->paddr);
-		fimc_lite_active_queue_add(fimc, vbuf);
 	}
 
 	if (test_bit(ST_FLITE_CONFIG, &fimc->state))
@@ -330,10 +319,16 @@
 static int start_streaming(struct vb2_queue *q, unsigned int count)
 {
 	struct fimc_lite *fimc = q->drv_priv;
+	unsigned long flags;
 	int ret;
 
+	spin_lock_irqsave(&fimc->slock, flags);
+
+	fimc->buf_index = 0;
 	fimc->frame_count = 0;
 
+	spin_unlock_irqrestore(&fimc->slock, flags);
+
 	ret = fimc_lite_hw_init(fimc, false);
 	if (ret) {
 		fimc_lite_reinit(fimc, false);
@@ -347,8 +342,7 @@
 		flite_hw_capture_start(fimc);
 
 		if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
-			fimc_pipeline_call(fimc, set_stream,
-					   &fimc->pipeline, 1);
+			fimc_pipeline_call(&fimc->ve, set_stream, 1);
 	}
 	if (debug > 0)
 		flite_hw_dump_regs(fimc, __func__);
@@ -415,7 +409,7 @@
 		unsigned long size = fimc->payload[i];
 
 		if (vb2_plane_size(vb, i) < size) {
-			v4l2_err(&fimc->vfd,
+			v4l2_err(&fimc->ve.vdev,
 				 "User buffer too small (%ld < %ld)\n",
 				 vb2_plane_size(vb, i), size);
 			return -EINVAL;
@@ -436,10 +430,14 @@
 	spin_lock_irqsave(&fimc->slock, flags);
 	buf->paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
 
+	buf->index = fimc->buf_index++;
+	if (fimc->buf_index >= fimc->reqbufs_count)
+		fimc->buf_index = 0;
+
 	if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
 	    !test_bit(ST_FLITE_STREAM, &fimc->state) &&
 	    list_empty(&fimc->active_buf_q)) {
-		flite_hw_set_output_addr(fimc, buf->paddr);
+		flite_hw_set_dma_buffer(fimc, buf);
 		fimc_lite_active_queue_add(fimc, buf);
 	} else {
 		fimc_lite_pending_queue_add(fimc, buf);
@@ -452,8 +450,7 @@
 		spin_unlock_irqrestore(&fimc->slock, flags);
 
 		if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
-			fimc_pipeline_call(fimc, set_stream,
-					   &fimc->pipeline, 1);
+			fimc_pipeline_call(&fimc->ve, set_stream, 1);
 		return;
 	}
 	spin_unlock_irqrestore(&fimc->slock, flags);
@@ -481,11 +478,9 @@
 static int fimc_lite_open(struct file *file)
 {
 	struct fimc_lite *fimc = video_drvdata(file);
-	struct media_entity *me = &fimc->vfd.entity;
+	struct media_entity *me = &fimc->ve.vdev.entity;
 	int ret;
 
-	mutex_lock(&me->parent->graph_mutex);
-
 	mutex_lock(&fimc->lock);
 	if (atomic_read(&fimc->out_path) != FIMC_IO_DMA) {
 		ret = -EBUSY;
@@ -505,11 +500,18 @@
 	    atomic_read(&fimc->out_path) != FIMC_IO_DMA)
 		goto unlock;
 
-	ret = fimc_pipeline_call(fimc, open, &fimc->pipeline,
-						me, true);
+	mutex_lock(&me->parent->graph_mutex);
+
+	ret = fimc_pipeline_call(&fimc->ve, open, me, true);
+
+	/* Mark video pipeline ending at this video node as in use. */
+	if (ret == 0)
+		me->use_count++;
+
+	mutex_unlock(&me->parent->graph_mutex);
+
 	if (!ret) {
 		fimc_lite_clear_event_counters(fimc);
-		fimc->ref_count++;
 		goto unlock;
 	}
 
@@ -519,26 +521,29 @@
 	clear_bit(ST_FLITE_IN_USE, &fimc->state);
 unlock:
 	mutex_unlock(&fimc->lock);
-	mutex_unlock(&me->parent->graph_mutex);
 	return ret;
 }
 
 static int fimc_lite_release(struct file *file)
 {
 	struct fimc_lite *fimc = video_drvdata(file);
+	struct media_entity *entity = &fimc->ve.vdev.entity;
 
 	mutex_lock(&fimc->lock);
 
 	if (v4l2_fh_is_singular_file(file) &&
 	    atomic_read(&fimc->out_path) == FIMC_IO_DMA) {
 		if (fimc->streaming) {
-			media_entity_pipeline_stop(&fimc->vfd.entity);
+			media_entity_pipeline_stop(entity);
 			fimc->streaming = false;
 		}
-		clear_bit(ST_FLITE_IN_USE, &fimc->state);
 		fimc_lite_stop_capture(fimc, false);
-		fimc_pipeline_call(fimc, close, &fimc->pipeline);
-		fimc->ref_count--;
+		fimc_pipeline_call(&fimc->ve, close);
+		clear_bit(ST_FLITE_IN_USE, &fimc->state);
+
+		mutex_lock(&entity->parent->graph_mutex);
+		entity->use_count--;
+		mutex_unlock(&entity->parent->graph_mutex);
 	}
 
 	vb2_fop_release(file);
@@ -562,37 +567,54 @@
  * Format and crop negotiation helpers
  */
 
-static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
-					u32 *width, u32 *height,
-					u32 *code, u32 *fourcc, int pad)
+static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
+					struct v4l2_subdev_fh *fh,
+					struct v4l2_subdev_format *format)
 {
 	struct flite_drvdata *dd = fimc->dd;
-	const struct fimc_fmt *fmt;
-	unsigned int flags = 0;
+	struct v4l2_mbus_framefmt *mf = &format->format;
+	const struct fimc_fmt *fmt = NULL;
 
-	if (pad == FLITE_SD_PAD_SINK) {
-		v4l_bound_align_image(width, 8, dd->max_width,
-				      ffs(dd->out_width_align) - 1,
-				      height, 0, dd->max_height, 0, 0);
+	if (format->pad == FLITE_SD_PAD_SINK) {
+		v4l_bound_align_image(&mf->width, 8, dd->max_width,
+				ffs(dd->out_width_align) - 1,
+				&mf->height, 0, dd->max_height, 0, 0);
+
+		fmt = fimc_lite_find_format(NULL, &mf->code, 0, 0);
+		if (WARN_ON(!fmt))
+			return NULL;
+
+		mf->colorspace = fmt->colorspace;
+		mf->code = fmt->mbus_code;
 	} else {
-		v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
-				      ffs(dd->out_width_align) - 1,
-				      height, 0, fimc->inp_frame.rect.height,
-				      0, 0);
-		flags = fimc->inp_frame.fmt->flags;
+		struct flite_frame *sink = &fimc->inp_frame;
+		struct v4l2_mbus_framefmt *sink_fmt;
+		struct v4l2_rect *rect;
+
+		if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+			sink_fmt = v4l2_subdev_get_try_format(fh,
+						FLITE_SD_PAD_SINK);
+
+			mf->code = sink_fmt->code;
+			mf->colorspace = sink_fmt->colorspace;
+
+			rect = v4l2_subdev_get_try_crop(fh,
+						FLITE_SD_PAD_SINK);
+		} else {
+			mf->code = sink->fmt->mbus_code;
+			mf->colorspace = sink->fmt->colorspace;
+			rect = &sink->rect;
+		}
+
+		/* Allow changing format only on sink pad */
+		mf->width = rect->width;
+		mf->height = rect->height;
 	}
 
-	fmt = fimc_lite_find_format(fourcc, code, flags, 0);
-	if (WARN_ON(!fmt))
-		return NULL;
+	mf->field = V4L2_FIELD_NONE;
 
-	if (code)
-		*code = fmt->mbus_code;
-	if (fourcc)
-		*fourcc = fmt->fourcc;
-
-	v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
-		 code ? *code : 0, *width, *height);
+	v4l2_dbg(1, debug, &fimc->subdev, "code: %#x (%d), %dx%d\n",
+		 mf->code, mf->colorspace, mf->width, mf->height);
 
 	return fmt;
 }
@@ -637,13 +659,18 @@
 /*
  * Video node ioctl operations
  */
-static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
+static int fimc_lite_querycap(struct file *file, void *priv,
 					struct v4l2_capability *cap)
 {
+	struct fimc_lite *fimc = video_drvdata(file);
+
 	strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
-	cap->bus_info[0] = 0;
-	cap->card[0] = 0;
-	cap->capabilities = V4L2_CAP_STREAMING;
+	strlcpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+					dev_name(&fimc->pdev->dev));
+
+	cap->device_caps = V4L2_CAP_STREAMING;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -679,7 +706,7 @@
 	pixm->width = frame->f_width;
 	pixm->height = frame->f_height;
 	pixm->field = V4L2_FIELD_NONE;
-	pixm->colorspace = V4L2_COLORSPACE_JPEG;
+	pixm->colorspace = fmt->colorspace;
 	return 0;
 }
 
@@ -722,7 +749,7 @@
 						fmt->depth[0]) / 8;
 	pixm->num_planes = fmt->memplanes;
 	pixm->pixelformat = fmt->fourcc;
-	pixm->colorspace = V4L2_COLORSPACE_JPEG;
+	pixm->colorspace = fmt->colorspace;
 	pixm->field = V4L2_FIELD_NONE;
 	return 0;
 }
@@ -786,7 +813,7 @@
 				return -EPIPE;
 		}
 		/* Retrieve format at the source pad */
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (pad == NULL ||
 		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 			break;
@@ -810,14 +837,13 @@
 			      enum v4l2_buf_type type)
 {
 	struct fimc_lite *fimc = video_drvdata(file);
-	struct media_entity *entity = &fimc->vfd.entity;
-	struct fimc_pipeline *p = &fimc->pipeline;
+	struct media_entity *entity = &fimc->ve.vdev.entity;
 	int ret;
 
 	if (fimc_lite_active(fimc))
 		return -EBUSY;
 
-	ret = media_entity_pipeline_start(entity, p->m_pipeline);
+	ret = media_entity_pipeline_start(entity, &fimc->ve.pipe->mp);
 	if (ret < 0)
 		return ret;
 
@@ -825,7 +851,7 @@
 	if (ret < 0)
 		goto err_p_stop;
 
-	fimc->sensor = __find_remote_sensor(&fimc->subdev.entity);
+	fimc->sensor = fimc_find_remote_sensor(&fimc->subdev.entity);
 
 	ret = vb2_ioctl_streamon(file, priv, type);
 	if (!ret) {
@@ -848,7 +874,7 @@
 	if (ret < 0)
 		return ret;
 
-	media_entity_pipeline_stop(&fimc->vfd.entity);
+	media_entity_pipeline_stop(&fimc->ve.vdev.entity);
 	fimc->streaming = false;
 	return 0;
 }
@@ -938,7 +964,7 @@
 }
 
 static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = {
-	.vidioc_querycap		= fimc_vidioc_querycap_capture,
+	.vidioc_querycap		= fimc_lite_querycap,
 	.vidioc_enum_fmt_vid_cap_mplane	= fimc_lite_enum_fmt_mplane,
 	.vidioc_try_fmt_vid_cap_mplane	= fimc_lite_try_fmt_mplane,
 	.vidioc_s_fmt_vid_cap_mplane	= fimc_lite_s_fmt_mplane,
@@ -972,8 +998,6 @@
 		 __func__, remote->entity->name, local->entity->name,
 		 flags, fimc->source_subdev_grp_id);
 
-	mutex_lock(&fimc->lock);
-
 	switch (local->index) {
 	case FLITE_SD_PAD_SINK:
 		if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) {
@@ -1015,7 +1039,6 @@
 	}
 	mb();
 
-	mutex_unlock(&fimc->lock);
 	return ret;
 }
 
@@ -1036,6 +1059,15 @@
 	return 0;
 }
 
+static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt(
+			struct v4l2_subdev_fh *fh, unsigned int pad)
+{
+	if (pad != FLITE_SD_PAD_SINK)
+		pad = FLITE_SD_PAD_SOURCE_DMA;
+
+	return v4l2_subdev_get_try_format(fh, pad);
+}
+
 static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
 				    struct v4l2_subdev_fh *fh,
 				    struct v4l2_subdev_format *fmt)
@@ -1045,13 +1077,13 @@
 	struct flite_frame *f = &fimc->inp_frame;
 
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-		mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+		mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
 		fmt->format = *mf;
 		return 0;
 	}
-	mf->colorspace = V4L2_COLORSPACE_JPEG;
 
 	mutex_lock(&fimc->lock);
+	mf->colorspace = f->fmt->colorspace;
 	mf->code = f->fmt->mbus_code;
 
 	if (fmt->pad == FLITE_SD_PAD_SINK) {
@@ -1080,7 +1112,6 @@
 	v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d\n",
 		 fmt->pad, mf->code, mf->width, mf->height);
 
-	mf->colorspace = V4L2_COLORSPACE_JPEG;
 	mutex_lock(&fimc->lock);
 
 	if ((atomic_read(&fimc->out_path) == FIMC_IO_ISP &&
@@ -1091,12 +1122,20 @@
 		return -EBUSY;
 	}
 
-	ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height,
-				    &mf->code, NULL, fmt->pad);
+	ffmt = fimc_lite_subdev_try_fmt(fimc, fh, fmt);
 
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-		mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+		struct v4l2_mbus_framefmt *src_fmt;
+
+		mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad);
 		*mf = fmt->format;
+
+		if (fmt->pad == FLITE_SD_PAD_SINK) {
+			unsigned int pad = FLITE_SD_PAD_SOURCE_DMA;
+			src_fmt = __fimc_lite_subdev_get_try_fmt(fh, pad);
+			*src_fmt = *mf;
+		}
+
 		mutex_unlock(&fimc->lock);
 		return 0;
 	}
@@ -1114,11 +1153,6 @@
 		source->rect = sink->rect;
 		source->f_width = mf->width;
 		source->f_height = mf->height;
-	} else {
-		/* Allow changing format only on sink pad */
-		mf->code = sink->fmt->mbus_code;
-		mf->width = sink->rect.width;
-		mf->height = sink->rect.height;
 	}
 
 	mutex_unlock(&fimc->lock);
@@ -1207,7 +1241,7 @@
 	 * The pipeline links are protected through entity.stream_count
 	 * so there is no need to take the media graph mutex here.
 	 */
-	fimc->sensor = __find_remote_sensor(&sd->entity);
+	fimc->sensor = fimc_find_remote_sensor(&sd->entity);
 
 	if (atomic_read(&fimc->out_path) != FIMC_IO_ISP)
 		return -ENOIOCTLCMD;
@@ -1252,13 +1286,10 @@
 {
 	struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
 	struct vb2_queue *q = &fimc->vb_queue;
-	struct video_device *vfd = &fimc->vfd;
+	struct video_device *vfd = &fimc->ve.vdev;
 	int ret;
 
 	memset(vfd, 0, sizeof(*vfd));
-
-	fimc->inp_frame.fmt = &fimc_lite_formats[0];
-	fimc->out_frame.fmt = &fimc_lite_formats[0];
 	atomic_set(&fimc->out_path, FIMC_IO_DMA);
 
 	snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
@@ -1295,12 +1326,12 @@
 		return ret;
 
 	video_set_drvdata(vfd, fimc);
-	fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
+	fimc->ve.pipe = v4l2_get_subdev_hostdata(sd);
 
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
 	if (ret < 0) {
 		media_entity_cleanup(&vfd->entity);
-		fimc->pipeline_ops = NULL;
+		fimc->ve.pipe = NULL;
 		return ret;
 	}
 
@@ -1316,11 +1347,15 @@
 	if (fimc == NULL)
 		return;
 
-	if (video_is_registered(&fimc->vfd)) {
-		video_unregister_device(&fimc->vfd);
-		media_entity_cleanup(&fimc->vfd.entity);
-		fimc->pipeline_ops = NULL;
+	mutex_lock(&fimc->lock);
+
+	if (video_is_registered(&fimc->ve.vdev)) {
+		video_unregister_device(&fimc->ve.vdev);
+		media_entity_cleanup(&fimc->ve.vdev.entity);
+		fimc->ve.pipe = NULL;
 	}
+
+	mutex_unlock(&fimc->lock);
 }
 
 static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {
@@ -1370,6 +1405,23 @@
 	.step	= 1,
 };
 
+static void fimc_lite_set_default_config(struct fimc_lite *fimc)
+{
+	struct flite_frame *sink = &fimc->inp_frame;
+	struct flite_frame *source = &fimc->out_frame;
+
+	sink->fmt = &fimc_lite_formats[0];
+	sink->f_width = FLITE_DEFAULT_WIDTH;
+	sink->f_height = FLITE_DEFAULT_HEIGHT;
+
+	sink->rect.width = FLITE_DEFAULT_WIDTH;
+	sink->rect.height = FLITE_DEFAULT_HEIGHT;
+	sink->rect.left = 0;
+	sink->rect.top = 0;
+
+	*source = *sink;
+}
+
 static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
 {
 	struct v4l2_ctrl_handler *handler = &fimc->ctrl_handler;
@@ -1417,12 +1469,12 @@
 
 static void fimc_lite_clk_put(struct fimc_lite *fimc)
 {
-	if (IS_ERR_OR_NULL(fimc->clock))
+	if (IS_ERR(fimc->clock))
 		return;
 
 	clk_unprepare(fimc->clock);
 	clk_put(fimc->clock);
-	fimc->clock = NULL;
+	fimc->clock = ERR_PTR(-EINVAL);
 }
 
 static int fimc_lite_clk_get(struct fimc_lite *fimc)
@@ -1436,7 +1488,7 @@
 	ret = clk_prepare(fimc->clock);
 	if (ret < 0) {
 		clk_put(fimc->clock);
-		fimc->clock = NULL;
+		fimc->clock = ERR_PTR(-EINVAL);
 	}
 	return ret;
 }
@@ -1461,13 +1513,14 @@
 		if (of_id)
 			drv_data = (struct flite_drvdata *)of_id->data;
 		fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
-	} else {
-		drv_data = fimc_lite_get_drvdata(pdev);
-		fimc->index = pdev->id;
 	}
 
-	if (!drv_data || fimc->index < 0 || fimc->index >= FIMC_LITE_MAX_DEVS)
+	if (!drv_data || fimc->index >= drv_data->num_instances ||
+						fimc->index < 0) {
+		dev_err(dev, "Wrong %s node alias\n",
+					dev->of_node->full_name);
 		return -EINVAL;
+	}
 
 	fimc->dd = drv_data;
 	fimc->pdev = pdev;
@@ -1514,8 +1567,11 @@
 		ret = PTR_ERR(fimc->alloc_ctx);
 		goto err_pm;
 	}
+
 	pm_runtime_put(dev);
 
+	fimc_lite_set_default_config(fimc);
+
 	dev_dbg(dev, "FIMC-LITE.%d registered successfully\n",
 		fimc->index);
 	return 0;
@@ -1565,8 +1621,8 @@
 		return 0;
 
 	INIT_LIST_HEAD(&fimc->active_buf_q);
-	fimc_pipeline_call(fimc, open, &fimc->pipeline,
-			   &fimc->vfd.entity, false);
+	fimc_pipeline_call(&fimc->ve, open,
+			   &fimc->ve.vdev.entity, false);
 	fimc_lite_hw_init(fimc, atomic_read(&fimc->out_path) == FIMC_IO_ISP);
 	clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
 
@@ -1592,7 +1648,7 @@
 	if (ret < 0 || !fimc_lite_active(fimc))
 		return ret;
 
-	return fimc_pipeline_call(fimc, close, &fimc->pipeline);
+	return fimc_pipeline_call(&fimc->ve, close);
 }
 #endif /* CONFIG_PM_SLEEP */
 
@@ -1624,22 +1680,30 @@
 	.out_width_align	= 8,
 	.win_hor_offs_align	= 2,
 	.out_hor_offs_align	= 8,
+	.max_dma_bufs		= 1,
+	.num_instances		= 2,
 };
 
-static struct platform_device_id fimc_lite_driver_ids[] = {
-	{
-		.name		= "exynos-fimc-lite",
-		.driver_data	= (unsigned long)&fimc_lite_drvdata_exynos4,
-	},
-	{ /* sentinel */ },
+/* EXYNOS5250 */
+static struct flite_drvdata fimc_lite_drvdata_exynos5 = {
+	.max_width		= 8192,
+	.max_height		= 8192,
+	.out_width_align	= 8,
+	.win_hor_offs_align	= 2,
+	.out_hor_offs_align	= 8,
+	.max_dma_bufs		= 32,
+	.num_instances		= 3,
 };
-MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids);
 
 static const struct of_device_id flite_of_match[] = {
 	{
 		.compatible = "samsung,exynos4212-fimc-lite",
 		.data = &fimc_lite_drvdata_exynos4,
 	},
+	{
+		.compatible = "samsung,exynos5250-fimc-lite",
+		.data = &fimc_lite_drvdata_exynos5,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, flite_of_match);
@@ -1647,7 +1711,6 @@
 static struct platform_driver fimc_lite_driver = {
 	.probe		= fimc_lite_probe,
 	.remove		= fimc_lite_remove,
-	.id_table	= fimc_lite_driver_ids,
 	.driver = {
 		.of_match_table = flite_of_match,
 		.name		= FIMC_LITE_DRV_NAME,
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
index 47da5e0..7428b2d 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite.h
@@ -27,8 +27,10 @@
 
 #define FIMC_LITE_DRV_NAME	"exynos-fimc-lite"
 #define FLITE_CLK_NAME		"flite"
-#define FIMC_LITE_MAX_DEVS	2
+#define FIMC_LITE_MAX_DEVS	3
 #define FLITE_REQ_BUFS_MIN	2
+#define FLITE_DEFAULT_WIDTH	640
+#define FLITE_DEFAULT_HEIGHT	480
 
 /* Bit index definitions for struct fimc_lite::state */
 enum {
@@ -48,17 +50,28 @@
 #define FLITE_SD_PAD_SOURCE_ISP	2
 #define FLITE_SD_PADS_NUM	3
 
+/**
+ * struct flite_drvdata - FIMC-LITE IP variant data structure
+ * @max_width: maximum camera interface input width in pixels
+ * @max_height: maximum camera interface input height in pixels
+ * @out_width_align: minimum output width alignment in pixels
+ * @win_hor_offs_align: minimum camera interface crop window horizontal
+ * 			offset alignment in pixels
+ * @out_hor_offs_align: minimum output DMA compose rectangle horizontal
+ * 			offset alignment in pixels
+ * @max_dma_bufs: number of output DMA buffer start address registers
+ * @num_instances: total number of FIMC-LITE IP instances available
+ */
 struct flite_drvdata {
 	unsigned short max_width;
 	unsigned short max_height;
 	unsigned short out_width_align;
 	unsigned short win_hor_offs_align;
 	unsigned short out_hor_offs_align;
+	unsigned short max_dma_bufs;
+	unsigned short num_instances;
 };
 
-#define fimc_lite_get_drvdata(_pdev) \
-	((struct flite_drvdata *) platform_get_device_id(_pdev)->driver_data)
-
 struct fimc_lite_events {
 	unsigned int data_overflow;
 };
@@ -83,20 +96,22 @@
  * struct flite_buffer - video buffer structure
  * @vb:    vb2 buffer
  * @list:  list head for the buffers queue
- * @paddr: precalculated physical address
+ * @paddr: DMA buffer start address
+ * @index: DMA start address register's index
  */
 struct flite_buffer {
 	struct vb2_buffer vb;
 	struct list_head list;
 	dma_addr_t paddr;
+	unsigned short index;
 };
 
 /**
  * struct fimc_lite - fimc lite structure
  * @pdev: pointer to FIMC-LITE platform device
  * @dd: SoC specific driver data structure
+ * @ve: exynos video device entity structure
  * @v4l2_dev: pointer to top the level v4l2_device
- * @vfd: video device node
  * @fh: v4l2 file handle
  * @alloc_ctx: videobuf2 memory allocator context
  * @subdev: FIMC-LITE subdev
@@ -122,16 +137,16 @@
  * @pending_buf_q: pending buffers queue head
  * @active_buf_q: the queue head of buffers scheduled in hardware
  * @vb_queue: vb2 buffers queue
+ * @buf_index: helps to keep track of the DMA start address register index
  * @active_buf_count: number of video buffers scheduled in hardware
  * @frame_count: the captured frames counter
  * @reqbufs_count: the number of buffers requested with REQBUFS ioctl
- * @ref_count: driver's private reference counter
  */
 struct fimc_lite {
 	struct platform_device	*pdev;
 	struct flite_drvdata	*dd;
+	struct exynos_video_entity ve;
 	struct v4l2_device	*v4l2_dev;
-	struct video_device	vfd;
 	struct v4l2_fh		fh;
 	struct vb2_alloc_ctx	*alloc_ctx;
 	struct v4l2_subdev	subdev;
@@ -141,8 +156,6 @@
 	struct v4l2_ctrl_handler ctrl_handler;
 	struct v4l2_ctrl	*test_pattern;
 	int			index;
-	struct fimc_pipeline	pipeline;
-	const struct fimc_pipeline_ops *pipeline_ops;
 
 	struct mutex		lock;
 	spinlock_t		slock;
@@ -161,9 +174,9 @@
 	struct list_head	pending_buf_q;
 	struct list_head	active_buf_q;
 	struct vb2_queue	vb_queue;
+	unsigned short		buf_index;
 	unsigned int		frame_count;
 	unsigned int		reqbufs_count;
-	int			ref_count;
 
 	struct fimc_lite_events	events;
 	bool			streaming;
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index bde1f47..8d33b68 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -27,6 +27,7 @@
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-dma-contig.h>
 
+#include "common.h"
 #include "fimc-core.h"
 #include "fimc-reg.h"
 #include "media-dev.h"
diff --git a/drivers/media/platform/exynos4-is/fimc-reg.c b/drivers/media/platform/exynos4-is/fimc-reg.c
index f079f36..1db8cb4 100644
--- a/drivers/media/platform/exynos4-is/fimc-reg.c
+++ b/drivers/media/platform/exynos4-is/fimc-reg.c
@@ -618,7 +618,7 @@
 		}
 
 		if (i == ARRAY_SIZE(pix_desc)) {
-			v4l2_err(&vc->vfd,
+			v4l2_err(&vc->ve.vdev,
 				 "Camera color format not supported: %d\n",
 				 vc->ci_fmt.code);
 			return -EINVAL;
@@ -698,7 +698,7 @@
 			cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
 			break;
 		default:
-			v4l2_err(&vid_cap->vfd,
+			v4l2_err(&vid_cap->ve.vdev,
 				 "Not supported camera pixel format: %#x\n",
 				 vid_cap->ci_fmt.code);
 			return -EINVAL;
@@ -721,7 +721,8 @@
 			WARN_ONCE(1, "ISP Writeback input is not supported\n");
 		break;
 	default:
-		v4l2_err(&vid_cap->vfd, "Invalid FIMC bus type selected: %d\n",
+		v4l2_err(&vid_cap->ve.vdev,
+			 "Invalid FIMC bus type selected: %d\n",
 			 source->fimc_bus_type);
 		return -EINVAL;
 	}
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 15ef8f2..19f556c 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -1,8 +1,8 @@
 /*
  * S5P/EXYNOS4 SoC series camera host interface media device driver
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published
@@ -39,6 +39,26 @@
 static int __fimc_md_set_camclk(struct fimc_md *fmd,
 				struct fimc_source_info *si,
 				bool on);
+
+/* Set up image sensor subdev -> FIMC capture node notifications. */
+static void __setup_sensor_notification(struct fimc_md *fmd,
+					struct v4l2_subdev *sensor,
+					struct v4l2_subdev *fimc_sd)
+{
+	struct fimc_source_info *src_inf;
+	struct fimc_sensor_info *md_si;
+	unsigned long flags;
+
+	src_inf = v4l2_get_subdev_hostdata(sensor);
+	if (!src_inf || WARN_ON(fmd == NULL))
+		return;
+
+	md_si = source_to_sensor_info(src_inf);
+	spin_lock_irqsave(&fmd->slock, flags);
+	md_si->host = v4l2_get_subdevdata(fimc_sd);
+	spin_unlock_irqrestore(&fmd->slock, flags);
+}
+
 /**
  * fimc_pipeline_prepare - update pipeline information with subdevice pointers
  * @me: media entity terminating the pipeline
@@ -46,9 +66,11 @@
  * Caller holds the graph mutex.
  */
 static void fimc_pipeline_prepare(struct fimc_pipeline *p,
-				  struct media_entity *me)
+					struct media_entity *me)
 {
+	struct fimc_md *fmd = entity_to_fimc_mdev(me);
 	struct v4l2_subdev *sd;
+	struct v4l2_subdev *sensor = NULL;
 	int i;
 
 	for (i = 0; i < IDX_MAX; i++)
@@ -62,7 +84,7 @@
 			struct media_pad *spad = &me->pads[i];
 			if (!(spad->flags & MEDIA_PAD_FL_SINK))
 				continue;
-			pad = media_entity_remote_source(spad);
+			pad = media_entity_remote_pad(spad);
 			if (pad)
 				break;
 		}
@@ -73,8 +95,10 @@
 		sd = media_entity_to_v4l2_subdev(pad->entity);
 
 		switch (sd->grp_id) {
-		case GRP_ID_FIMC_IS_SENSOR:
 		case GRP_ID_SENSOR:
+			sensor = sd;
+			/* fall through */
+		case GRP_ID_FIMC_IS_SENSOR:
 			p->subdevs[IDX_SENSOR] = sd;
 			break;
 		case GRP_ID_CSIS:
@@ -84,7 +108,7 @@
 			p->subdevs[IDX_FLITE] = sd;
 			break;
 		case GRP_ID_FIMC:
-			/* No need to control FIMC subdev through subdev ops */
+			p->subdevs[IDX_FIMC] = sd;
 			break;
 		case GRP_ID_FIMC_IS:
 			p->subdevs[IDX_IS_ISP] = sd;
@@ -96,6 +120,9 @@
 		if (me->num_pads == 1)
 			break;
 	}
+
+	if (sensor && p->subdevs[IDX_FIMC])
+		__setup_sensor_notification(fmd, sensor, p->subdevs[IDX_FIMC]);
 }
 
 /**
@@ -168,10 +195,11 @@
  *
  * Called with the graph mutex held.
  */
-static int __fimc_pipeline_open(struct fimc_pipeline *p,
+static int __fimc_pipeline_open(struct exynos_media_pipeline *ep,
 				struct media_entity *me, bool prepare)
 {
 	struct fimc_md *fmd = entity_to_fimc_mdev(me);
+	struct fimc_pipeline *p = to_fimc_pipeline(ep);
 	struct v4l2_subdev *sd;
 	int ret;
 
@@ -214,20 +242,21 @@
  *
  * Disable power of all subdevs and turn the external sensor clock off.
  */
-static int __fimc_pipeline_close(struct fimc_pipeline *p)
+static int __fimc_pipeline_close(struct exynos_media_pipeline *ep)
 {
+	struct fimc_pipeline *p = to_fimc_pipeline(ep);
 	struct v4l2_subdev *sd = p ? p->subdevs[IDX_SENSOR] : NULL;
 	struct fimc_md *fmd;
-	int ret = 0;
+	int ret;
 
-	if (WARN_ON(sd == NULL))
-		return -EINVAL;
-
-	if (p->subdevs[IDX_SENSOR]) {
-		ret = fimc_pipeline_s_power(p, 0);
-		fimc_md_set_camclk(sd, false);
+	if (sd == NULL) {
+		pr_warn("%s(): No sensor subdev\n", __func__);
+		return 0;
 	}
 
+	ret = fimc_pipeline_s_power(p, 0);
+	fimc_md_set_camclk(sd, false);
+
 	fmd = entity_to_fimc_mdev(&sd->entity);
 
 	/* Disable PXLASYNC clock if this pipeline includes FIMC-IS */
@@ -242,12 +271,13 @@
  * @pipeline: video pipeline structure
  * @on: passed as the s_stream() callback argument
  */
-static int __fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
+static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on)
 {
 	static const u8 seq[2][IDX_MAX] = {
 		{ IDX_FIMC, IDX_SENSOR, IDX_IS_ISP, IDX_CSIS, IDX_FLITE },
 		{ IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP },
 	};
+	struct fimc_pipeline *p = to_fimc_pipeline(ep);
 	int i, ret = 0;
 
 	if (p->subdevs[IDX_SENSOR] == NULL)
@@ -271,12 +301,38 @@
 }
 
 /* Media pipeline operations for the FIMC/FIMC-LITE video device driver */
-static const struct fimc_pipeline_ops fimc_pipeline_ops = {
+static const struct exynos_media_pipeline_ops fimc_pipeline_ops = {
 	.open		= __fimc_pipeline_open,
 	.close		= __fimc_pipeline_close,
 	.set_stream	= __fimc_pipeline_s_stream,
 };
 
+static struct exynos_media_pipeline *fimc_md_pipeline_create(
+						struct fimc_md *fmd)
+{
+	struct fimc_pipeline *p;
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return NULL;
+
+	list_add_tail(&p->list, &fmd->pipelines);
+
+	p->ep.ops = &fimc_pipeline_ops;
+	return &p->ep;
+}
+
+static void fimc_md_pipelines_free(struct fimc_md *fmd)
+{
+	while (!list_empty(&fmd->pipelines)) {
+		struct fimc_pipeline *p;
+
+		p = list_entry(fmd->pipelines.next, typeof(*p), list);
+		list_del(&p->list);
+		kfree(p);
+	}
+}
+
 /*
  * Sensor subdevice helper functions
  */
@@ -592,6 +648,7 @@
 				     struct fimc_lite *fimc_lite)
 {
 	struct v4l2_subdev *sd;
+	struct exynos_media_pipeline *ep;
 	int ret;
 
 	if (WARN_ON(fimc_lite->index >= FIMC_LITE_MAX_DEVS ||
@@ -600,7 +657,12 @@
 
 	sd = &fimc_lite->subdev;
 	sd->grp_id = GRP_ID_FLITE;
-	v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
+
+	ep = fimc_md_pipeline_create(fmd);
+	if (!ep)
+		return -ENOMEM;
+
+	v4l2_set_subdev_hostdata(sd, ep);
 
 	ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
 	if (!ret)
@@ -614,6 +676,7 @@
 static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc)
 {
 	struct v4l2_subdev *sd;
+	struct exynos_media_pipeline *ep;
 	int ret;
 
 	if (WARN_ON(fimc->id >= FIMC_MAX_DEVS || fmd->fimc[fimc->id]))
@@ -621,7 +684,12 @@
 
 	sd = &fimc->vid_cap.subdev;
 	sd->grp_id = GRP_ID_FIMC;
-	v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
+
+	ep = fimc_md_pipeline_create(fmd);
+	if (!ep)
+		return -ENOMEM;
+
+	v4l2_set_subdev_hostdata(sd, ep);
 
 	ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
 	if (!ret) {
@@ -736,8 +804,6 @@
 
 	if (!strcmp(pdev->name, CSIS_DRIVER_NAME)) {
 		plat_entity = IDX_CSIS;
-	} else if (!strcmp(pdev->name, FIMC_LITE_DRV_NAME)) {
-		plat_entity = IDX_FLITE;
 	} else {
 		p = strstr(pdev->name, "fimc");
 		if (p && *(p + 4) == 0)
@@ -797,17 +863,19 @@
 	int i;
 
 	for (i = 0; i < FIMC_MAX_DEVS; i++) {
-		if (fmd->fimc[i] == NULL)
+		struct fimc_dev *dev = fmd->fimc[i];
+		if (dev == NULL)
 			continue;
-		v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev);
-		fmd->fimc[i]->pipeline_ops = NULL;
+		v4l2_device_unregister_subdev(&dev->vid_cap.subdev);
+		dev->vid_cap.ve.pipe = NULL;
 		fmd->fimc[i] = NULL;
 	}
 	for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
-		if (fmd->fimc_lite[i] == NULL)
+		struct fimc_lite *dev = fmd->fimc_lite[i];
+		if (dev == NULL)
 			continue;
-		v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev);
-		fmd->fimc_lite[i]->pipeline_ops = NULL;
+		v4l2_device_unregister_subdev(&dev->subdev);
+		dev->ve.pipe = NULL;
 		fmd->fimc_lite[i] = NULL;
 	}
 	for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
@@ -880,18 +948,6 @@
 
 		v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]\n",
 			  source->name, flags ? '=' : '-', sink->name);
-
-		if (flags == 0 || sensor == NULL)
-			continue;
-
-		if (!WARN_ON(si == NULL)) {
-			unsigned long irq_flags;
-			struct fimc_sensor_info *inf = source_to_sensor_info(si);
-
-			spin_lock_irqsave(&fmd->slock, irq_flags);
-			inf->host = fmd->fimc[i];
-			spin_unlock_irqrestore(&fmd->slock, irq_flags);
-		}
 	}
 
 	for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
@@ -929,7 +985,7 @@
 			continue;
 
 		source = &fimc->subdev.entity;
-		sink = &fimc->vfd.entity;
+		sink = &fimc->ve.vdev.entity;
 		/* FIMC-LITE's subdev and video node */
 		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
 					       sink, 0, 0);
@@ -1066,7 +1122,7 @@
 			continue;
 
 		source = &fmd->fimc[i]->vid_cap.subdev.entity;
-		sink = &fmd->fimc[i]->vid_cap.vfd.entity;
+		sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
 
 		ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
 					      sink, 0, flags);
@@ -1231,66 +1287,98 @@
 	return __fimc_md_set_camclk(fmd, si, on);
 }
 
-static int fimc_md_link_notify(struct media_pad *source,
-			       struct media_pad *sink, u32 flags)
+static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
 {
-	struct fimc_lite *fimc_lite = NULL;
-	struct fimc_dev *fimc = NULL;
-	struct fimc_pipeline *pipeline;
-	struct v4l2_subdev *sd;
-	struct mutex *lock;
-	int i, ret = 0;
-	int ref_count;
+	struct exynos_video_entity *ve;
+	struct fimc_pipeline *p;
+	struct video_device *vdev;
+	int ret;
 
-	if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	vdev = media_entity_to_video_device(entity);
+	if (vdev->entity.use_count == 0)
 		return 0;
 
-	sd = media_entity_to_v4l2_subdev(sink->entity);
-
-	switch (sd->grp_id) {
-	case GRP_ID_FLITE:
-		fimc_lite = v4l2_get_subdevdata(sd);
-		if (WARN_ON(fimc_lite == NULL))
-			return 0;
-		pipeline = &fimc_lite->pipeline;
-		lock = &fimc_lite->lock;
-		break;
-	case GRP_ID_FIMC:
-		fimc = v4l2_get_subdevdata(sd);
-		if (WARN_ON(fimc == NULL))
-			return 0;
-		pipeline = &fimc->pipeline;
-		lock = &fimc->lock;
-		break;
-	default:
+	ve = vdev_to_exynos_video_entity(vdev);
+	p = to_fimc_pipeline(ve->pipe);
+	/*
+	 * Nothing to do if we are disabling the pipeline, some link
+	 * has been disconnected and p->subdevs array is cleared now.
+	 */
+	if (!enable && p->subdevs[IDX_SENSOR] == NULL)
 		return 0;
+
+	if (enable)
+		ret = __fimc_pipeline_open(ve->pipe, entity, true);
+	else
+		ret = __fimc_pipeline_close(ve->pipe);
+
+	if (ret == 0 && !enable)
+		memset(p->subdevs, 0, sizeof(p->subdevs));
+
+	return ret;
+}
+
+/* Locking: called with entity->parent->graph_mutex mutex held. */
+static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
+{
+	struct media_entity *entity_err = entity;
+	struct media_entity_graph graph;
+	int ret;
+
+	/*
+	 * Walk current graph and call the pipeline open/close routine for each
+	 * opened video node that belongs to the graph of entities connected
+	 * through active links. This is needed as we cannot power on/off the
+	 * subdevs in random order.
+	 */
+	media_entity_graph_walk_start(&graph, entity);
+
+	while ((entity = media_entity_graph_walk_next(&graph))) {
+		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+			continue;
+
+		ret  = __fimc_md_modify_pipeline(entity, enable);
+
+		if (ret < 0)
+			goto err;
 	}
 
-	mutex_lock(lock);
-	ref_count = fimc ? fimc->vid_cap.refcnt : fimc_lite->ref_count;
+	return 0;
+ err:
+	media_entity_graph_walk_start(&graph, entity_err);
 
-	if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-		if (ref_count > 0) {
-			ret = __fimc_pipeline_close(pipeline);
-			if (!ret && fimc)
-				fimc_ctrls_delete(fimc->vid_cap.ctx);
-		}
-		for (i = 0; i < IDX_MAX; i++)
-			pipeline->subdevs[i] = NULL;
-	} else if (ref_count > 0) {
-		/*
-		 * Link activation. Enable power of pipeline elements only if
-		 * the pipeline is already in use, i.e. its video node is open.
-		 * Recreate the controls destroyed during the link deactivation.
-		 */
-		ret = __fimc_pipeline_open(pipeline,
-					   source->entity, true);
-		if (!ret && fimc)
-			ret = fimc_capture_ctrls_create(fimc);
+	while ((entity_err = media_entity_graph_walk_next(&graph))) {
+		if (media_entity_type(entity_err) != MEDIA_ENT_T_DEVNODE)
+			continue;
+
+		__fimc_md_modify_pipeline(entity_err, !enable);
+
+		if (entity_err == entity)
+			break;
 	}
 
-	mutex_unlock(lock);
-	return ret ? -EPIPE : ret;
+	return ret;
+}
+
+static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
+				unsigned int notification)
+{
+	struct media_entity *sink = link->sink->entity;
+	int ret = 0;
+
+	/* Before link disconnection */
+	if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
+		if (!(flags & MEDIA_LNK_FL_ENABLED))
+			ret = __fimc_md_modify_pipelines(sink, false);
+		else
+			; /* TODO: Link state change validation */
+	/* After link activation */
+	} else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+		   (link->flags & MEDIA_LNK_FL_ENABLED)) {
+		ret = __fimc_md_modify_pipelines(sink, true);
+	}
+
+	return ret ? -EPIPE : 0;
 }
 
 static ssize_t fimc_md_sysfs_show(struct device *dev,
@@ -1370,6 +1458,7 @@
 
 	spin_lock_init(&fmd->slock);
 	fmd->pdev = pdev;
+	INIT_LIST_HEAD(&fmd->pipelines);
 
 	strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
 		sizeof(fmd->media_dev.model));
@@ -1457,6 +1546,7 @@
 		return 0;
 	device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
 	fimc_md_unregister_entities(fmd);
+	fimc_md_pipelines_free(fmd);
 	media_device_unregister(&fmd->media_dev);
 	fimc_md_put_clocks(fmd);
 	return 0;
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index 44d86b6..62599fd 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -18,6 +18,7 @@
 #include <media/media-entity.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-subdev.h>
+#include <media/s5p_fimc.h>
 
 #include "fimc-core.h"
 #include "fimc-lite.h"
@@ -40,6 +41,29 @@
 	FIMC_MAX_WBCLKS
 };
 
+enum fimc_subdev_index {
+	IDX_SENSOR,
+	IDX_CSIS,
+	IDX_FLITE,
+	IDX_IS_ISP,
+	IDX_FIMC,
+	IDX_MAX,
+};
+
+/*
+ * This structure represents a chain of media entities, including a data
+ * source entity (e.g. an image sensor subdevice), a data capture entity
+ * - a video capture device node and any remaining entities.
+ */
+struct fimc_pipeline {
+	struct exynos_media_pipeline ep;
+	struct list_head list;
+	struct media_entity *vdev_entity;
+	struct v4l2_subdev *subdevs[IDX_MAX];
+};
+
+#define to_fimc_pipeline(_ep) container_of(_ep, struct fimc_pipeline, ep)
+
 struct fimc_csis_info {
 	struct v4l2_subdev *sd;
 	int id;
@@ -104,17 +128,11 @@
 		struct pinctrl_state *state_idle;
 	} pinctl;
 	bool user_subdev_api;
+
 	spinlock_t slock;
+	struct list_head pipelines;
 };
 
-#define is_subdev_pad(pad) (pad == NULL || \
-	media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV)
-
-#define me_subtype(me) \
-	((me->type) & (MEDIA_ENT_TYPE_MASK | MEDIA_ENT_SUBTYPE_MASK))
-
-#define subdev_has_devnode(__sd) (__sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)
-
 static inline
 struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
 {
@@ -127,14 +145,14 @@
 		container_of(me->parent, struct fimc_md, media_dev);
 }
 
-static inline void fimc_md_graph_lock(struct fimc_dev *fimc)
+static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
 {
-	mutex_lock(&fimc->vid_cap.vfd.entity.parent->graph_mutex);
+	mutex_lock(&ve->vdev.entity.parent->graph_mutex);
 }
 
-static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
+static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
 {
-	mutex_unlock(&fimc->vid_cap.vfd.entity.parent->graph_mutex);
+	mutex_unlock(&ve->vdev.entity.parent->graph_mutex);
 }
 
 int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
@@ -149,4 +167,16 @@
 #define fimc_md_is_isp_available(node) (false)
 #endif /* CONFIG_OF */
 
+static inline struct v4l2_subdev *__fimc_md_get_subdev(
+				struct exynos_media_pipeline *ep,
+				unsigned int index)
+{
+	struct fimc_pipeline *p = to_fimc_pipeline(ep);
+
+	if (!p || index >= IDX_MAX)
+		return NULL;
+	else
+		return p->subdevs[index];
+}
+
 #endif
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index 254d70f..0914230 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -1,8 +1,8 @@
 /*
- * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
+ * Samsung S5P/EXYNOS SoC series MIPI-CSI receiver driver
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
+ * Author: Sylwester Nawrocki <s.nawrocki@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
@@ -66,11 +66,12 @@
 
 /* Interrupt mask */
 #define S5PCSIS_INTMSK			0x10
-#define S5PCSIS_INTMSK_EN_ALL		0xf000103f
 #define S5PCSIS_INTMSK_EVEN_BEFORE	(1 << 31)
 #define S5PCSIS_INTMSK_EVEN_AFTER	(1 << 30)
 #define S5PCSIS_INTMSK_ODD_BEFORE	(1 << 29)
 #define S5PCSIS_INTMSK_ODD_AFTER	(1 << 28)
+#define S5PCSIS_INTMSK_FRAME_START	(1 << 27)
+#define S5PCSIS_INTMSK_FRAME_END	(1 << 26)
 #define S5PCSIS_INTMSK_ERR_SOT_HS	(1 << 12)
 #define S5PCSIS_INTMSK_ERR_LOST_FS	(1 << 5)
 #define S5PCSIS_INTMSK_ERR_LOST_FE	(1 << 4)
@@ -78,6 +79,8 @@
 #define S5PCSIS_INTMSK_ERR_ECC		(1 << 2)
 #define S5PCSIS_INTMSK_ERR_CRC		(1 << 1)
 #define S5PCSIS_INTMSK_ERR_UNKNOWN	(1 << 0)
+#define S5PCSIS_INTMSK_EXYNOS4_EN_ALL	0xf000103f
+#define S5PCSIS_INTMSK_EXYNOS5_EN_ALL	0xfc00103f
 
 /* Interrupt source */
 #define S5PCSIS_INTSRC			0x14
@@ -88,6 +91,8 @@
 #define S5PCSIS_INTSRC_ODD_AFTER	(1 << 28)
 #define S5PCSIS_INTSRC_ODD		(0x3 << 28)
 #define S5PCSIS_INTSRC_NON_IMAGE_DATA	(0xff << 28)
+#define S5PCSIS_INTSRC_FRAME_START	(1 << 27)
+#define S5PCSIS_INTSRC_FRAME_END	(1 << 26)
 #define S5PCSIS_INTSRC_ERR_SOT_HS	(0xf << 12)
 #define S5PCSIS_INTSRC_ERR_LOST_FS	(1 << 5)
 #define S5PCSIS_INTSRC_ERR_LOST_FE	(1 << 4)
@@ -151,6 +156,9 @@
 	{ S5PCSIS_INTSRC_EVEN_AFTER,	"Non-image data after even frame" },
 	{ S5PCSIS_INTSRC_ODD_BEFORE,	"Non-image data before odd frame" },
 	{ S5PCSIS_INTSRC_ODD_AFTER,	"Non-image data after odd frame" },
+	/* Frame start/end */
+	{ S5PCSIS_INTSRC_FRAME_START,	"Frame Start" },
+	{ S5PCSIS_INTSRC_FRAME_END,	"Frame End" },
 };
 #define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events)
 
@@ -159,6 +167,11 @@
 	unsigned int len;
 };
 
+struct csis_drvdata {
+	/* Mask of all used interrupts in S5PCSIS_INTMSK register */
+	u32 interrupt_mask;
+};
+
 /**
  * struct csis_state - the driver's internal state data structure
  * @lock: mutex serializing the subdev and power management operations,
@@ -171,6 +184,7 @@
  * @supplies: CSIS regulator supplies
  * @clock: CSIS clocks
  * @irq: requested s5p-mipi-csis irq number
+ * @interrupt_mask: interrupt mask of the all used interrupts
  * @flags: the state variable for power and streaming control
  * @clock_frequency: device bus clock frequency
  * @hs_settle: HS-RX settle time
@@ -193,6 +207,7 @@
 	struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
 	struct clk *clock[NUM_CSIS_CLOCKS];
 	int irq;
+	u32 interrupt_mask;
 	u32 flags;
 
 	u32 clk_frequency;
@@ -274,9 +289,10 @@
 static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
 {
 	u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
-
-	val = on ? val | S5PCSIS_INTMSK_EN_ALL :
-		   val & ~S5PCSIS_INTMSK_EN_ALL;
+	if (on)
+		val |= state->interrupt_mask;
+	else
+		val &= ~state->interrupt_mask;
 	s5pcsis_write(state, S5PCSIS_INTMSK, val);
 }
 
@@ -771,8 +787,12 @@
 #define s5pcsis_parse_dt(pdev, state) (-ENOSYS)
 #endif
 
+static const struct of_device_id s5pcsis_of_match[];
+
 static int s5pcsis_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *of_id;
+	const struct csis_drvdata *drv_data;
 	struct device *dev = &pdev->dev;
 	struct resource *mem_res;
 	struct csis_state *state;
@@ -787,10 +807,19 @@
 	spin_lock_init(&state->slock);
 	state->pdev = pdev;
 
-	if (dev->of_node)
+	if (dev->of_node) {
+		of_id = of_match_node(s5pcsis_of_match, dev->of_node);
+		if (WARN_ON(of_id == NULL))
+			return -EINVAL;
+
+		drv_data = of_id->data;
+		state->interrupt_mask = drv_data->interrupt_mask;
+
 		ret = s5pcsis_parse_dt(pdev, state);
-	else
+	} else {
 		ret = s5pcsis_get_platform_data(pdev, state);
+	}
+
 	if (ret < 0)
 		return ret;
 
@@ -994,9 +1023,25 @@
 	SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
 };
 
+static const struct csis_drvdata exynos4_csis_drvdata = {
+	.interrupt_mask = S5PCSIS_INTMSK_EXYNOS4_EN_ALL,
+};
+
+static const struct csis_drvdata exynos5_csis_drvdata = {
+	.interrupt_mask = S5PCSIS_INTMSK_EXYNOS5_EN_ALL,
+};
+
 static const struct of_device_id s5pcsis_of_match[] = {
-	{ .compatible = "samsung,s5pv210-csis" },
-	{ .compatible = "samsung,exynos4210-csis" },
+	{
+		.compatible = "samsung,s5pv210-csis",
+		.data = &exynos4_csis_drvdata,
+	}, {
+		.compatible = "samsung,exynos4210-csis",
+		.data = &exynos4_csis_drvdata,
+	}, {
+		.compatible = "samsung,exynos5250-csis",
+		.data = &exynos5_csis_drvdata,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, s5pcsis_of_match);
diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c
index 3a6a0dc..221ec42 100644
--- a/drivers/media/platform/fsl-viu.c
+++ b/drivers/media/platform/fsl-viu.c
@@ -1475,7 +1475,6 @@
 	.release	= video_device_release,
 
 	.tvnorms        = V4L2_STD_NTSC_M | V4L2_STD_PAL,
-	.current_norm   = V4L2_STD_NTSC_M,
 };
 
 static int viu_of_probe(struct platform_device *op)
@@ -1546,6 +1545,7 @@
 	viu_dev->vidq.timeout.function = viu_vid_timeout;
 	viu_dev->vidq.timeout.data     = (unsigned long)viu_dev;
 	init_timer(&viu_dev->vidq.timeout);
+	viu_dev->std = V4L2_STD_NTSC_M;
 	viu_dev->first = 1;
 
 	/* Allocate memory for video device */
diff --git a/drivers/media/platform/indycam.c b/drivers/media/platform/indycam.c
index 5482363..f1d192b 100644
--- a/drivers/media/platform/indycam.c
+++ b/drivers/media/platform/indycam.c
@@ -23,7 +23,6 @@
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 #include "indycam.h"
 
@@ -283,20 +282,9 @@
 
 /* I2C-interface */
 
-static int indycam_g_chip_ident(struct v4l2_subdev *sd,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	struct indycam *camera = to_indycam(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_INDYCAM,
-		       camera->version);
-}
-
 /* ----------------------------------------------------------------------- */
 
 static const struct v4l2_subdev_core_ops indycam_core_ops = {
-	.g_chip_ident = indycam_g_chip_ident,
 	.g_ctrl = indycam_g_ctrl,
 	.s_ctrl = indycam_s_ctrl,
 };
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index 7585646..540516c 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -1033,6 +1033,7 @@
 
 	*vfd = deinterlace_videodev;
 	vfd->lock = &pcdev->dev_mutex;
+	vfd->v4l2_dev = &pcdev->v4l2_dev;
 
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
 	if (ret) {
diff --git a/drivers/media/platform/marvell-ccic/cafe-driver.c b/drivers/media/platform/marvell-ccic/cafe-driver.c
index d030f9b..1f079ff 100644
--- a/drivers/media/platform/marvell-ccic/cafe-driver.c
+++ b/drivers/media/platform/marvell-ccic/cafe-driver.c
@@ -27,7 +27,6 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <linux/device.h>
 #include <linux/wait.h>
 #include <linux/delay.h>
@@ -469,7 +468,7 @@
 		goto out;
 	cam->pdev = pdev;
 	mcam = &cam->mcam;
-	mcam->chip_id = V4L2_IDENT_CAFE;
+	mcam->chip_id = MCAM_CAFE;
 	spin_lock_init(&mcam->dev_lock);
 	init_waitqueue_head(&cam->smbus_wait);
 	mcam->plat_power_up = cafe_ctlr_power_up;
@@ -501,6 +500,7 @@
 		printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n");
 		goto out_disable;
 	}
+	mcam->regs_size = pci_resource_len(pdev, 0);
 	ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
 	if (ret)
 		goto out_iounmap;
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index 64ab91e..0821ed0 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -23,7 +23,6 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/ov7670.h>
 #include <media/videobuf2-vmalloc.h>
 #include <media/videobuf2-dma-contig.h>
@@ -336,7 +335,7 @@
 		mcam_reg_clear_bit(cam, REG_CTRL1, C1_TWOBUFS);
 	} else
 		mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS);
-	if (cam->chip_id == V4L2_IDENT_CAFE)
+	if (cam->chip_id == MCAM_CAFE)
 		mcam_reg_write(cam, REG_UBAR, 0); /* 32 bits only */
 }
 
@@ -796,7 +795,6 @@
  */
 static int mcam_cam_init(struct mcam_camera *cam)
 {
-	struct v4l2_dbg_chip_ident chip;
 	int ret;
 
 	mutex_lock(&cam->s_mutex);
@@ -804,24 +802,8 @@
 		cam_warn(cam, "Cam init with device in funky state %d",
 				cam->state);
 	ret = __mcam_cam_reset(cam);
-	if (ret)
-		goto out;
-	chip.ident = V4L2_IDENT_NONE;
-	chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
-	chip.match.addr = cam->sensor_addr;
-	ret = sensor_call(cam, core, g_chip_ident, &chip);
-	if (ret)
-		goto out;
-	cam->sensor_type = chip.ident;
-	if (cam->sensor_type != V4L2_IDENT_OV7670) {
-		cam_err(cam, "Unsupported sensor type 0x%x", cam->sensor_type);
-		ret = -EINVAL;
-		goto out;
-	}
-/* Get/set parameters? */
-	ret = 0;
+	/* Get/set parameters? */
 	cam->state = S_IDLE;
-out:
 	mcam_ctlr_power_down(cam);
 	mutex_unlock(&cam->s_mutex);
 	return ret;
@@ -1362,6 +1344,12 @@
 	return 0;
 }
 
+static int mcam_vidioc_g_std(struct file *filp, void *priv, v4l2_std_id *a)
+{
+	*a = V4L2_STD_NTSC_M;
+	return 0;
+}
+
 /*
  * G/S_PARM.  Most of this is done by the sensor, but we are
  * the level which controls the number of read buffers.
@@ -1392,20 +1380,6 @@
 	return ret;
 }
 
-static int mcam_vidioc_g_chip_ident(struct file *file, void *priv,
-		struct v4l2_dbg_chip_ident *chip)
-{
-	struct mcam_camera *cam = priv;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (v4l2_chip_match_host(&chip->match)) {
-		chip->ident = cam->chip_id;
-		return 0;
-	}
-	return sensor_call(cam, core, g_chip_ident, chip);
-}
-
 static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv,
 		struct v4l2_frmsizeenum *sizes)
 {
@@ -1436,12 +1410,11 @@
 {
 	struct mcam_camera *cam = priv;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		reg->val = mcam_reg_read(cam, reg->reg);
-		reg->size = 4;
-		return 0;
-	}
-	return sensor_call(cam, core, g_register, reg);
+	if (reg->reg > cam->regs_size - 4)
+		return -EINVAL;
+	reg->val = mcam_reg_read(cam, reg->reg);
+	reg->size = 4;
+	return 0;
 }
 
 static int mcam_vidioc_s_register(struct file *file, void *priv,
@@ -1449,11 +1422,10 @@
 {
 	struct mcam_camera *cam = priv;
 
-	if (v4l2_chip_match_host(&reg->match)) {
-		mcam_reg_write(cam, reg->reg, reg->val);
-		return 0;
-	}
-	return sensor_call(cam, core, s_register, reg);
+	if (reg->reg > cam->regs_size - 4)
+		return -EINVAL;
+	mcam_reg_write(cam, reg->reg, reg->val);
+	return 0;
 }
 #endif
 
@@ -1467,6 +1439,7 @@
 	.vidioc_g_input		= mcam_vidioc_g_input,
 	.vidioc_s_input		= mcam_vidioc_s_input,
 	.vidioc_s_std		= mcam_vidioc_s_std,
+	.vidioc_g_std		= mcam_vidioc_g_std,
 	.vidioc_reqbufs		= mcam_vidioc_reqbufs,
 	.vidioc_querybuf	= mcam_vidioc_querybuf,
 	.vidioc_qbuf		= mcam_vidioc_qbuf,
@@ -1477,7 +1450,6 @@
 	.vidioc_s_parm		= mcam_vidioc_s_parm,
 	.vidioc_enum_framesizes = mcam_vidioc_enum_framesizes,
 	.vidioc_enum_frameintervals = mcam_vidioc_enum_frameintervals,
-	.vidioc_g_chip_ident	= mcam_vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register	= mcam_vidioc_g_register,
 	.vidioc_s_register	= mcam_vidioc_s_register,
@@ -1593,7 +1565,6 @@
 static struct video_device mcam_v4l_template = {
 	.name = "mcam",
 	.tvnorms = V4L2_STD_NTSC_M,
-	.current_norm = V4L2_STD_NTSC_M,  /* make mplayer happy */
 
 	.fops = &mcam_v4l_fops,
 	.ioctl_ops = &mcam_v4l_ioctl_ops,
@@ -1695,7 +1666,7 @@
 	if (buffer_mode >= 0)
 		cam->buffer_mode = buffer_mode;
 	if (cam->buffer_mode == B_DMA_sg &&
-			cam->chip_id == V4L2_IDENT_CAFE) {
+			cam->chip_id == MCAM_CAFE) {
 		printk(KERN_ERR "marvell-cam: Cafe can't do S/G I/O, "
 			"attempting vmalloc mode instead\n");
 		cam->buffer_mode = B_vmalloc;
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h
index 01dec9e..520c8de 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.h
+++ b/drivers/media/platform/marvell-ccic/mcam-core.h
@@ -53,6 +53,11 @@
 	B_DMA_sg = 2
 };
 
+enum mcam_chip_id {
+	MCAM_CAFE,
+	MCAM_ARMADA610,
+};
+
 /*
  * Is a given buffer mode supported by the current kernel configuration?
  */
@@ -96,9 +101,10 @@
 	 */
 	struct i2c_adapter *i2c_adapter;
 	unsigned char __iomem *regs;
+	unsigned regs_size; /* size in bytes of the register space */
 	spinlock_t dev_lock;
 	struct device *dev; /* For messages, dma alloc */
-	unsigned int chip_id;
+	enum mcam_chip_id chip_id;
 	short int clock_speed;	/* Sensor clock speed, default 30 */
 	short int use_smbus;	/* SMBUS or straight I2c? */
 	enum mcam_buffer_mode buffer_mode;
@@ -152,7 +158,6 @@
 	void (*frame_complete)(struct mcam_camera *cam, int frame);
 
 	/* Current operating parameters */
-	u32 sensor_type;		/* Currently ov7670 only */
 	struct v4l2_pix_format pix_format;
 	enum v4l2_mbus_pixelcode mbus_code;
 
diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
index c4c17fe..a634888 100644
--- a/drivers/media/platform/marvell-ccic/mmp-driver.c
+++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
@@ -18,7 +18,6 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/mmp-camera.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
@@ -185,7 +184,7 @@
 	mcam->plat_power_down = mmpcam_power_down;
 	mcam->dev = &pdev->dev;
 	mcam->use_smbus = 0;
-	mcam->chip_id = V4L2_IDENT_ARMADA610;
+	mcam->chip_id = MCAM_ARMADA610;
 	mcam->buffer_mode = B_DMA_sg;
 	spin_lock_init(&mcam->dev_lock);
 	/*
@@ -203,6 +202,7 @@
 		ret = -ENODEV;
 		goto out_free;
 	}
+	mcam->regs_size = resource_size(res);
 	/*
 	 * Power/clock memory is elsewhere; get it too.  Perhaps this
 	 * should really be managed outside of this driver?
diff --git a/drivers/media/platform/mem2mem_testdev.c b/drivers/media/platform/mem2mem_testdev.c
index 4cc7f65d..6a17676 100644
--- a/drivers/media/platform/mem2mem_testdev.c
+++ b/drivers/media/platform/mem2mem_testdev.c
@@ -1051,6 +1051,7 @@
 
 	*vfd = m2mtest_videodev;
 	vfd->lock = &dev->dev_mutex;
+	vfd->v4l2_dev = &dev->v4l2_dev;
 
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
 	if (ret) {
@@ -1061,7 +1062,7 @@
 	video_set_drvdata(vfd, dev);
 	snprintf(vfd->name, sizeof(vfd->name), "%s", m2mtest_videodev.name);
 	dev->vfd = vfd;
-	v4l2_info(&dev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME
+	v4l2_info(&dev->v4l2_dev,
 			"Device registered as /dev/video%d\n", vfd->num);
 
 	setup_timer(&dev->timer, device_isr, (long)dev);
diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c
index f7440e5..c690435 100644
--- a/drivers/media/platform/mx2_emmaprp.c
+++ b/drivers/media/platform/mx2_emmaprp.c
@@ -937,6 +937,7 @@
 
 	*vfd = emmaprp_videodev;
 	vfd->lock = &pcdev->dev_mutex;
+	vfd->v4l2_dev = &pcdev->v4l2_dev;
 
 	video_set_drvdata(vfd, pcdev);
 	snprintf(vfd->name, sizeof(vfd->name), "%s", emmaprp_videodev.name);
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index d338b19..dfd0a21 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -335,8 +335,6 @@
 	ovl = ovid->overlays[0];
 
 	switch (pix->pixelformat) {
-	case 0:
-		break;
 	case V4L2_PIX_FMT_YUYV:
 		mode = OMAP_DSS_COLOR_YUV2;
 		break;
@@ -358,6 +356,7 @@
 		break;
 	default:
 		mode = -EINVAL;
+		break;
 	}
 	return mode;
 }
diff --git a/drivers/media/platform/omap24xxcam.c b/drivers/media/platform/omap24xxcam.c
index debb44c..d2b440c 100644
--- a/drivers/media/platform/omap24xxcam.c
+++ b/drivers/media/platform/omap24xxcam.c
@@ -1656,7 +1656,7 @@
 	}
 	vfd->release = video_device_release;
 
-	vfd->parent = cam->dev;
+	vfd->v4l2_dev = &cam->v4l2_dev;
 
 	strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
 	vfd->fops		 = &omap24xxcam_fops;
@@ -1752,6 +1752,11 @@
 
 	cam->dev = &pdev->dev;
 
+	if (v4l2_device_register(&pdev->dev, &cam->v4l2_dev)) {
+		dev_err(&pdev->dev, "v4l2_device_register failed\n");
+		goto err;
+	}
+
 	/*
 	 * Impose a lower limit on the amount of memory allocated for
 	 * capture. We require at least enough memory to double-buffer
@@ -1849,6 +1854,8 @@
 		cam->mmio_base_phys = 0;
 	}
 
+	v4l2_device_unregister(&cam->v4l2_dev);
+
 	kfree(cam);
 
 	return 0;
diff --git a/drivers/media/platform/omap24xxcam.h b/drivers/media/platform/omap24xxcam.h
index c439595..7f6f791 100644
--- a/drivers/media/platform/omap24xxcam.h
+++ b/drivers/media/platform/omap24xxcam.h
@@ -29,6 +29,7 @@
 
 #include <media/videobuf-dma-sg.h>
 #include <media/v4l2-int-device.h>
+#include <media/v4l2-device.h>
 
 /*
  *
@@ -462,6 +463,8 @@
 	 */
 	struct mutex mutex;
 
+	struct v4l2_device v4l2_dev;
+
 	/*** general driver state information ***/
 	atomic_t users;
 	/*
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 1d7dbd5..df3a0ec 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -792,9 +792,9 @@
 
 /*
  * isp_pipeline_link_notify - Link management notification callback
- * @source: Pad at the start of the link
- * @sink: Pad at the end of the link
+ * @link: The link
  * @flags: New link flags that will be applied
+ * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*)
  *
  * React to link management on powered pipelines by updating the use count of
  * all entities in the source and sink sides of the link. Entities are powered
@@ -804,29 +804,38 @@
  * off is assumed to never fail. This function will not fail for disconnection
  * events.
  */
-static int isp_pipeline_link_notify(struct media_pad *source,
-				    struct media_pad *sink, u32 flags)
+static int isp_pipeline_link_notify(struct media_link *link, u32 flags,
+				    unsigned int notification)
 {
-	int source_use = isp_pipeline_pm_use_count(source->entity);
-	int sink_use = isp_pipeline_pm_use_count(sink->entity);
+	struct media_entity *source = link->source->entity;
+	struct media_entity *sink = link->sink->entity;
+	int source_use = isp_pipeline_pm_use_count(source);
+	int sink_use = isp_pipeline_pm_use_count(sink);
 	int ret;
 
-	if (!(flags & MEDIA_LNK_FL_ENABLED)) {
+	if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+	    !(link->flags & MEDIA_LNK_FL_ENABLED)) {
 		/* Powering off entities is assumed to never fail. */
-		isp_pipeline_pm_power(source->entity, -sink_use);
-		isp_pipeline_pm_power(sink->entity, -source_use);
+		isp_pipeline_pm_power(source, -sink_use);
+		isp_pipeline_pm_power(sink, -source_use);
 		return 0;
 	}
 
-	ret = isp_pipeline_pm_power(source->entity, sink_use);
-	if (ret < 0)
+	if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
+		(flags & MEDIA_LNK_FL_ENABLED)) {
+
+		ret = isp_pipeline_pm_power(source, sink_use);
+		if (ret < 0)
+			return ret;
+
+		ret = isp_pipeline_pm_power(sink, source_use);
+		if (ret < 0)
+			isp_pipeline_pm_power(source, -sink_use);
+
 		return ret;
+	}
 
-	ret = isp_pipeline_pm_power(sink->entity, source_use);
-	if (ret < 0)
-		isp_pipeline_pm_power(source->entity, -sink_use);
-
-	return ret;
+	return 0;
 }
 
 /* -----------------------------------------------------------------------------
@@ -877,7 +886,7 @@
 		if (!(pad->flags & MEDIA_PAD_FL_SINK))
 			break;
 
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (pad == NULL ||
 		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 			break;
@@ -967,7 +976,7 @@
 		if (!(pad->flags & MEDIA_PAD_FL_SINK))
 			break;
 
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (pad == NULL ||
 		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 			break;
@@ -1083,7 +1092,7 @@
 	pipe = to_isp_pipeline(me);
 	if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED)
 		return 0;
-	pad = media_entity_remote_source(&pipe->output->pad);
+	pad = media_entity_remote_pad(&pipe->output->pad);
 	return pad->entity == me;
 }
 
@@ -2249,6 +2258,7 @@
 	ret = iommu_attach_device(isp->domain, &pdev->dev);
 	if (ret) {
 		dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret);
+		ret = -EPROBE_DEFER;
 		goto free_domain;
 	}
 
@@ -2287,12 +2297,11 @@
 	iommu_detach_device(isp->domain, &pdev->dev);
 free_domain:
 	iommu_domain_free(isp->domain);
+	isp->domain = NULL;
 error_isp:
 	isp_xclk_cleanup(isp);
 	omap3isp_put(isp);
 error:
-	platform_set_drvdata(pdev, NULL);
-
 	mutex_destroy(&isp->isp_mutex);
 
 	return ret;
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 60e60aa..907a205 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -1120,7 +1120,7 @@
 	u32 syn_mode;
 	u32 ccdc_pattern;
 
-	pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
+	pad = media_entity_remote_pad(&ccdc->pads[CCDC_PAD_SINK]);
 	sensor = media_entity_to_v4l2_subdev(pad->entity);
 	if (ccdc->input == CCDC_INPUT_PARALLEL)
 		pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index c5d84c9..e716514 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -158,13 +158,17 @@
  * @ccp2: pointer to ISP CCP2 device
  * @enable: enable/disable flag
  */
-static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
+static int ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
 {
 	struct isp_device *isp = to_isp_device(ccp2);
+	int ret;
 	int i;
 
-	if (enable && ccp2->vdds_csib)
-		regulator_enable(ccp2->vdds_csib);
+	if (enable && ccp2->vdds_csib) {
+		ret = regulator_enable(ccp2->vdds_csib);
+		if (ret < 0)
+			return ret;
+	}
 
 	/* Enable/Disable all the LCx channels */
 	for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)
@@ -179,6 +183,8 @@
 
 	if (!enable && ccp2->vdds_csib)
 		regulator_disable(ccp2->vdds_csib);
+
+	return 0;
 }
 
 /*
@@ -360,7 +366,7 @@
 
 	ccp2_pwr_cfg(ccp2);
 
-	pad = media_entity_remote_source(&ccp2->pads[CCP2_PAD_SINK]);
+	pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]);
 	sensor = media_entity_to_v4l2_subdev(pad->entity);
 	pdata = sensor->host_priv;
 
@@ -851,7 +857,12 @@
 		ccp2_print_status(ccp2);
 
 		/* Enable CSI1/CCP2 interface */
-		ccp2_if_enable(ccp2, 1);
+		ret = ccp2_if_enable(ccp2, 1);
+		if (ret < 0) {
+			if (ccp2->phy)
+				omap3isp_csiphy_release(ccp2->phy);
+			return ret;
+		}
 		break;
 
 	case ISP_PIPELINE_STREAM_SINGLESHOT:
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 783f4b0..6db245d 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -573,7 +573,7 @@
 	if (csi2->contexts[0].enabled || csi2->ctrl.if_enable)
 		return -EBUSY;
 
-	pad = media_entity_remote_source(&csi2->pads[CSI2_PAD_SINK]);
+	pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]);
 	sensor = media_entity_to_v4l2_subdev(pad->entity);
 	pdata = sensor->host_priv;
 
diff --git a/drivers/media/platform/omap3isp/ispqueue.h b/drivers/media/platform/omap3isp/ispqueue.h
index 908dfd7..3e048ad 100644
--- a/drivers/media/platform/omap3isp/ispqueue.h
+++ b/drivers/media/platform/omap3isp/ispqueue.h
@@ -28,6 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/mm_types.h>
 #include <linux/mutex.h>
 #include <linux/videodev2.h>
 #include <linux/wait.h>
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 8dac175..a908d00 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -219,7 +219,7 @@
 {
 	struct media_pad *remote;
 
-	remote = media_entity_remote_source(&video->pad);
+	remote = media_entity_remote_pad(&video->pad);
 
 	if (remote == NULL ||
 	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
@@ -314,7 +314,7 @@
 		 * entity can be found, and stop checking the pipeline if the
 		 * source entity isn't a subdev.
 		 */
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (pad == NULL)
 			return -EPIPE;
 
@@ -901,7 +901,7 @@
 			continue;
 
 		/* ISP entities have always sink pad == 0. Find source. */
-		source_pad = media_entity_remote_source(&ents[i]->pads[0]);
+		source_pad = media_entity_remote_pad(&ents[i]->pads[0]);
 		if (source_pad == NULL)
 			continue;
 
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index 70438a0..40b298a 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -845,7 +845,7 @@
 	int ret;
 
 	/* Retrieve format at the sensor subdev source pad */
-	pad = media_entity_remote_source(&camif->pads[0]);
+	pad = media_entity_remote_pad(&camif->pads[0]);
 	if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 		return -EPIPE;
 
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index 0d0fab1..b385747 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -341,10 +341,11 @@
 	int i;
 
 	for (i = 0; i < CLK_MAX_NUM; i++) {
-		if (IS_ERR_OR_NULL(camif->clock[i]))
+		if (IS_ERR(camif->clock[i]))
 			continue;
 		clk_unprepare(camif->clock[i]);
 		clk_put(camif->clock[i]);
+		camif->clock[i] = ERR_PTR(-EINVAL);
 	}
 }
 
@@ -352,6 +353,9 @@
 {
 	int ret, i;
 
+	for (i = 1; i < CLK_MAX_NUM; i++)
+		camif->clock[i] = ERR_PTR(-EINVAL);
+
 	for (i = 0; i < CLK_MAX_NUM; i++) {
 		camif->clock[i] = clk_get(camif->dev, camif_clocks[i]);
 		if (IS_ERR(camif->clock[i])) {
diff --git a/drivers/media/platform/s3c-camif/camif-regs.c b/drivers/media/platform/s3c-camif/camif-regs.c
index 1a3b4fc..a9e3b16 100644
--- a/drivers/media/platform/s3c-camif/camif-regs.c
+++ b/drivers/media/platform/s3c-camif/camif-regs.c
@@ -379,7 +379,7 @@
 	camif_write(camif, S3C_CAMIF_REG_CISCPREDST(vp->id, vp->offset), cfg);
 }
 
-void camif_s3c244x_hw_set_scaler(struct camif_vp *vp)
+static void camif_s3c244x_hw_set_scaler(struct camif_vp *vp)
 {
 	struct camif_dev *camif = vp->camif;
 	struct camif_scaler *scaler = &vp->scaler;
@@ -426,7 +426,7 @@
 		 scaler->main_h_ratio, scaler->main_v_ratio);
 }
 
-void camif_s3c64xx_hw_set_scaler(struct camif_vp *vp)
+static void camif_s3c64xx_hw_set_scaler(struct camif_vp *vp)
 {
 	struct camif_dev *camif = vp->camif;
 	struct camif_scaler *scaler = &vp->scaler;
@@ -601,6 +601,6 @@
 	pr_info("--- %s ---\n", label);
 	for (i = 0; i < ARRAY_SIZE(registers); i++) {
 		u32 cfg = readl(camif->io_base + registers[i].offset);
-		printk(KERN_INFO "%s:\t0x%08x\n", registers[i].name, cfg);
+		dev_info(camif->dev, "%s:\t0x%08x\n", registers[i].name, cfg);
 	}
 }
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index d12faa6..a130dcd 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1424,7 +1424,7 @@
 
 	if (pdev->dev.of_node) {
 		const struct of_device_id *match;
-		match = of_match_node(of_match_ptr(exynos_mfc_match),
+		match = of_match_node(exynos_mfc_match,
 				pdev->dev.of_node);
 		if (match)
 			driver_data = (struct s5p_mfc_variant *)match->data;
diff --git a/drivers/media/platform/s5p-tv/hdmi_drv.c b/drivers/media/platform/s5p-tv/hdmi_drv.c
index 4e86626..1b34c36 100644
--- a/drivers/media/platform/s5p-tv/hdmi_drv.c
+++ b/drivers/media/platform/s5p-tv/hdmi_drv.c
@@ -576,16 +576,22 @@
 	return hdmi_streamoff(hdev);
 }
 
-static void hdmi_resource_poweron(struct hdmi_resources *res)
+static int hdmi_resource_poweron(struct hdmi_resources *res)
 {
+	int ret;
+
 	/* turn HDMI power on */
-	regulator_bulk_enable(res->regul_count, res->regul_bulk);
+	ret = regulator_bulk_enable(res->regul_count, res->regul_bulk);
+	if (ret < 0)
+		return ret;
 	/* power-on hdmi physical interface */
 	clk_enable(res->hdmiphy);
 	/* use VPP as parent clock; HDMIPHY is not working yet */
 	clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
 	/* turn clocks on */
 	clk_enable(res->sclk_hdmi);
+
+	return 0;
 }
 
 static void hdmi_resource_poweroff(struct hdmi_resources *res)
@@ -728,11 +734,13 @@
 {
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
-	int ret = 0;
+	int ret;
 
 	dev_dbg(dev, "%s\n", __func__);
 
-	hdmi_resource_poweron(&hdev->res);
+	ret = hdmi_resource_poweron(&hdev->res);
+	if (ret < 0)
+		return ret;
 
 	/* starting MHL */
 	ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1);
@@ -755,6 +763,15 @@
 	.runtime_resume	 = hdmi_runtime_resume,
 };
 
+static void hdmi_resource_clear_clocks(struct hdmi_resources *res)
+{
+	res->hdmi	 = ERR_PTR(-EINVAL);
+	res->sclk_hdmi	 = ERR_PTR(-EINVAL);
+	res->sclk_pixel	 = ERR_PTR(-EINVAL);
+	res->sclk_hdmiphy = ERR_PTR(-EINVAL);
+	res->hdmiphy	 = ERR_PTR(-EINVAL);
+}
+
 static void hdmi_resources_cleanup(struct hdmi_device *hdev)
 {
 	struct hdmi_resources *res = &hdev->res;
@@ -765,17 +782,18 @@
 		regulator_bulk_free(res->regul_count, res->regul_bulk);
 	/* kfree is NULL-safe */
 	kfree(res->regul_bulk);
-	if (!IS_ERR_OR_NULL(res->hdmiphy))
+	if (!IS_ERR(res->hdmiphy))
 		clk_put(res->hdmiphy);
-	if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
+	if (!IS_ERR(res->sclk_hdmiphy))
 		clk_put(res->sclk_hdmiphy);
-	if (!IS_ERR_OR_NULL(res->sclk_pixel))
+	if (!IS_ERR(res->sclk_pixel))
 		clk_put(res->sclk_pixel);
-	if (!IS_ERR_OR_NULL(res->sclk_hdmi))
+	if (!IS_ERR(res->sclk_hdmi))
 		clk_put(res->sclk_hdmi);
-	if (!IS_ERR_OR_NULL(res->hdmi))
+	if (!IS_ERR(res->hdmi))
 		clk_put(res->hdmi);
 	memset(res, 0, sizeof(*res));
+	hdmi_resource_clear_clocks(res);
 }
 
 static int hdmi_resources_init(struct hdmi_device *hdev)
@@ -793,8 +811,9 @@
 	dev_dbg(dev, "HDMI resource init\n");
 
 	memset(res, 0, sizeof(*res));
-	/* get clocks, power */
+	hdmi_resource_clear_clocks(res);
 
+	/* get clocks, power */
 	res->hdmi = clk_get(dev, "hdmi");
 	if (IS_ERR(res->hdmi)) {
 		dev_err(dev, "failed to get clock 'hdmi'\n");
diff --git a/drivers/media/platform/s5p-tv/mixer_drv.c b/drivers/media/platform/s5p-tv/mixer_drv.c
index 5733033..51805a5 100644
--- a/drivers/media/platform/s5p-tv/mixer_drv.c
+++ b/drivers/media/platform/s5p-tv/mixer_drv.c
@@ -211,6 +211,15 @@
 	return ret;
 }
 
+static void mxr_resource_clear_clocks(struct mxr_resources *res)
+{
+	res->mixer	= ERR_PTR(-EINVAL);
+	res->vp		= ERR_PTR(-EINVAL);
+	res->sclk_mixer	= ERR_PTR(-EINVAL);
+	res->sclk_hdmi	= ERR_PTR(-EINVAL);
+	res->sclk_dac	= ERR_PTR(-EINVAL);
+}
+
 static void mxr_release_plat_resources(struct mxr_device *mdev)
 {
 	free_irq(mdev->res.irq, mdev);
@@ -222,15 +231,15 @@
 {
 	struct mxr_resources *res = &mdev->res;
 
-	if (!IS_ERR_OR_NULL(res->sclk_dac))
+	if (!IS_ERR(res->sclk_dac))
 		clk_put(res->sclk_dac);
-	if (!IS_ERR_OR_NULL(res->sclk_hdmi))
+	if (!IS_ERR(res->sclk_hdmi))
 		clk_put(res->sclk_hdmi);
-	if (!IS_ERR_OR_NULL(res->sclk_mixer))
+	if (!IS_ERR(res->sclk_mixer))
 		clk_put(res->sclk_mixer);
-	if (!IS_ERR_OR_NULL(res->vp))
+	if (!IS_ERR(res->vp))
 		clk_put(res->vp);
-	if (!IS_ERR_OR_NULL(res->mixer))
+	if (!IS_ERR(res->mixer))
 		clk_put(res->mixer);
 }
 
@@ -239,6 +248,8 @@
 	struct mxr_resources *res = &mdev->res;
 	struct device *dev = mdev->dev;
 
+	mxr_resource_clear_clocks(res);
+
 	res->mixer = clk_get(dev, "mixer");
 	if (IS_ERR(res->mixer)) {
 		mxr_err(mdev, "failed to get clock 'mixer'\n");
@@ -299,6 +310,7 @@
 	mxr_release_clocks(mdev);
 	mxr_release_plat_resources(mdev);
 	memset(&mdev->res, 0, sizeof(mdev->res));
+	mxr_resource_clear_clocks(&mdev->res);
 }
 
 static void mxr_release_layers(struct mxr_device *mdev)
diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c
index ef0efdf..641b1f0 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -81,8 +81,9 @@
 	}
 
 	mdev->alloc_ctx = vb2_dma_contig_init_ctx(mdev->dev);
-	if (IS_ERR_OR_NULL(mdev->alloc_ctx)) {
+	if (IS_ERR(mdev->alloc_ctx)) {
 		mxr_err(mdev, "could not acquire vb2 allocator\n");
+		ret = PTR_ERR(mdev->alloc_ctx);
 		goto fail_v4l2_dev;
 	}
 
diff --git a/drivers/media/platform/s5p-tv/sdo_drv.c b/drivers/media/platform/s5p-tv/sdo_drv.c
index ab6f9ef..0afa90f 100644
--- a/drivers/media/platform/s5p-tv/sdo_drv.c
+++ b/drivers/media/platform/s5p-tv/sdo_drv.c
@@ -262,11 +262,21 @@
 {
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct sdo_device *sdev = sd_to_sdev(sd);
+	int ret;
 
 	dev_info(dev, "resume\n");
-	clk_enable(sdev->sclk_dac);
-	regulator_enable(sdev->vdac);
-	regulator_enable(sdev->vdet);
+
+	ret = clk_enable(sdev->sclk_dac);
+	if (ret < 0)
+		return ret;
+
+	ret = regulator_enable(sdev->vdac);
+	if (ret < 0)
+		goto dac_clk_dis;
+
+	ret = regulator_enable(sdev->vdet);
+	if (ret < 0)
+		goto vdac_r_dis;
 
 	/* software reset */
 	sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_SW_RESET);
@@ -285,6 +295,12 @@
 		SDO_COMPENSATION_CVBS_COMP_OFF);
 	sdo_reg_debug(sdev);
 	return 0;
+
+vdac_r_dis:
+	regulator_disable(sdev->vdac);
+dac_clk_dis:
+	clk_disable(sdev->sclk_dac);
+	return ret;
 }
 
 static const struct dev_pm_ops sdo_pm_ops = {
diff --git a/drivers/media/platform/s5p-tv/sii9234_drv.c b/drivers/media/platform/s5p-tv/sii9234_drv.c
index 39b77d2..3dd762e 100644
--- a/drivers/media/platform/s5p-tv/sii9234_drv.c
+++ b/drivers/media/platform/s5p-tv/sii9234_drv.c
@@ -249,7 +249,9 @@
 	int ret;
 
 	dev_info(dev, "resume start\n");
-	regulator_enable(ctx->power);
+	ret = regulator_enable(ctx->power);
+	if (ret < 0)
+		return ret;
 
 	ret = sii9234_reset(ctx);
 	if (ret)
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c
index 59a9dee..aa4cca3 100644
--- a/drivers/media/platform/sh_veu.c
+++ b/drivers/media/platform/sh_veu.c
@@ -359,10 +359,7 @@
 	veu->m2m_ctx = v4l2_m2m_ctx_init(veu->m2m_dev, veu,
 					 sh_veu_queue_init);
 
-	if (IS_ERR(veu->m2m_ctx))
-		return PTR_ERR(veu->m2m_ctx);
-
-	return 0;
+	return PTR_RET(veu->m2m_ctx);
 }
 
 static int sh_veu_querycap(struct file *file, void *priv,
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 7d02350..7a9c5e9 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -1248,32 +1248,6 @@
 	return res;
 }
 
-static int sh_vou_g_chip_ident(struct file *file, void *fh,
-				   struct v4l2_dbg_chip_ident *id)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-
-	return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_chip_ident, id);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int sh_vou_g_register(struct file *file, void *fh,
-				 struct v4l2_dbg_register *reg)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-
-	return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_register, reg);
-}
-
-static int sh_vou_s_register(struct file *file, void *fh,
-				 const struct v4l2_dbg_register *reg)
-{
-	struct sh_vou_device *vou_dev = video_drvdata(file);
-
-	return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, s_register, reg);
-}
-#endif
-
 /* sh_vou display ioctl operations */
 static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
 	.vidioc_querycap        	= sh_vou_querycap,
@@ -1292,11 +1266,6 @@
 	.vidioc_cropcap			= sh_vou_cropcap,
 	.vidioc_g_crop			= sh_vou_g_crop,
 	.vidioc_s_crop			= sh_vou_s_crop,
-	.vidioc_g_chip_ident		= sh_vou_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register		= sh_vou_g_register,
-	.vidioc_s_register		= sh_vou_s_register,
-#endif
 };
 
 static const struct v4l2_file_operations sh_vou_fops = {
@@ -1313,7 +1282,6 @@
 	.fops		= &sh_vou_fops,
 	.ioctl_ops	= &sh_vou_ioctl_ops,
 	.tvnorms	= V4L2_STD_525_60, /* PAL only supported in 8-bit non-bt656 mode */
-	.current_norm	= V4L2_STD_NTSC_M,
 	.vfl_dir	= VFL_DIR_TX,
 };
 
@@ -1352,7 +1320,7 @@
 	pix = &vou_dev->pix;
 
 	/* Fill in defaults */
-	vou_dev->std		= sh_vou_video_template.current_norm;
+	vou_dev->std		= V4L2_STD_NTSC_M;
 	rect->left		= 0;
 	rect->top		= 0;
 	rect->width		= VOU_MAX_IMAGE_WIDTH;
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig
index b139b52..626dccc 100644
--- a/drivers/media/platform/soc_camera/Kconfig
+++ b/drivers/media/platform/soc_camera/Kconfig
@@ -8,6 +8,9 @@
 	  over a bus like PCI or USB. For example some i2c camera connected
 	  directly to the data bus of an SoC.
 
+config SOC_CAMERA_SCALE_CROP
+	tristate
+
 config SOC_CAMERA_PLATFORM
 	tristate "platform camera support"
 	depends on SOC_CAMERA
@@ -27,14 +30,10 @@
 	---help---
 	  This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
 
-config MX3_VIDEO
-	bool
-
 config VIDEO_MX3
 	tristate "i.MX3x Camera Sensor Interface driver"
 	depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
 	select VIDEOBUF2_DMA_CONTIG
-	select MX3_VIDEO
 	---help---
 	  This is a v4l2 driver for the i.MX3x Camera Sensor Interface
 
@@ -55,6 +54,7 @@
 	tristate "SuperH Mobile CEU Interface driver"
 	depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
 	select VIDEOBUF2_DMA_CONTIG
+	select SOC_CAMERA_SCALE_CROP
 	---help---
 	  This is a v4l2 driver for the SuperH Mobile CEU Interface
 
@@ -66,14 +66,10 @@
 	---help---
 	  This is a v4l2 driver for the TI OMAP1 camera interface
 
-config VIDEO_MX2_HOSTSUPPORT
-	bool
-
 config VIDEO_MX2
 	tristate "i.MX27 Camera Sensor Interface driver"
 	depends on VIDEO_DEV && SOC_CAMERA && MACH_MX27
 	select VIDEOBUF2_DMA_CONTIG
-	select VIDEO_MX2_HOSTSUPPORT
 	---help---
 	  This is a v4l2 driver for the i.MX27 Camera Sensor Interface
 
diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile
index 136b7f8..3918622 100644
--- a/drivers/media/platform/soc_camera/Makefile
+++ b/drivers/media/platform/soc_camera/Makefile
@@ -1,4 +1,8 @@
 obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o soc_mediabus.o
+obj-$(CONFIG_SOC_CAMERA_SCALE_CROP)	+= soc_scale_crop.o
+
+# a platform subdevice driver stub, allowing to support cameras by adding a
+# couple of callback functions to the board code
 obj-$(CONFIG_SOC_CAMERA_PLATFORM)	+= soc_camera_platform.o
 
 # soc-camera host drivers have to be linked after camera drivers
@@ -10,5 +14,3 @@
 obj-$(CONFIG_VIDEO_PXA27x)		+= pxa_camera.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2)	+= sh_mobile_csi2.o
-
-ccflags-y += -I$(srctree)/drivers/media/i2c/soc_camera
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index 1abbb36..1044856 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -102,7 +102,6 @@
 	struct list_head		video_buffer_list;
 	struct frame_buffer		*active;
 
-	struct soc_camera_device	*icd;
 	struct soc_camera_host		soc_host;
 };
 
@@ -367,7 +366,7 @@
 
 	/* Check if already in a frame */
 	if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
-		dev_err(isi->icd->parent, "Already in frame handling.\n");
+		dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n");
 		return;
 	}
 
@@ -746,16 +745,26 @@
 	return formats;
 }
 
-/* Called with .host_lock held */
 static int isi_camera_add_device(struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
+		 icd->devnum);
+
+	return 0;
+}
+
+static void isi_camera_remove_device(struct soc_camera_device *icd)
+{
+	dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
+		 icd->devnum);
+}
+
+/* Called with .host_lock held */
+static int isi_camera_clock_start(struct soc_camera_host *ici)
+{
 	struct atmel_isi *isi = ici->priv;
 	int ret;
 
-	if (isi->icd)
-		return -EBUSY;
-
 	ret = clk_enable(isi->pclk);
 	if (ret)
 		return ret;
@@ -766,25 +775,16 @@
 		return ret;
 	}
 
-	isi->icd = icd;
-	dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
-		 icd->devnum);
 	return 0;
 }
-/* Called with .host_lock held */
-static void isi_camera_remove_device(struct soc_camera_device *icd)
-{
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct atmel_isi *isi = ici->priv;
 
-	BUG_ON(icd != isi->icd);
+/* Called with .host_lock held */
+static void isi_camera_clock_stop(struct soc_camera_host *ici)
+{
+	struct atmel_isi *isi = ici->priv;
 
 	clk_disable(isi->mck);
 	clk_disable(isi->pclk);
-	isi->icd = NULL;
-
-	dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
-		 icd->devnum);
 }
 
 static unsigned int isi_camera_poll(struct file *file, poll_table *pt)
@@ -888,6 +888,8 @@
 	.owner		= THIS_MODULE,
 	.add		= isi_camera_add_device,
 	.remove		= isi_camera_remove_device,
+	.clock_start	= isi_camera_clock_start,
+	.clock_stop	= isi_camera_clock_stop,
 	.set_fmt	= isi_camera_set_fmt,
 	.try_fmt	= isi_camera_try_fmt,
 	.get_formats	= isi_camera_get_formats,
diff --git a/drivers/media/platform/soc_camera/mx1_camera.c b/drivers/media/platform/soc_camera/mx1_camera.c
index a3fd8d6..fea3e61 100644
--- a/drivers/media/platform/soc_camera/mx1_camera.c
+++ b/drivers/media/platform/soc_camera/mx1_camera.c
@@ -104,7 +104,6 @@
  */
 struct mx1_camera_dev {
 	struct soc_camera_host		soc_host;
-	struct soc_camera_device	*icd;
 	struct mx1_camera_pdata		*pdata;
 	struct mx1_buffer		*active;
 	struct resource			*res;
@@ -220,7 +219,7 @@
 static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
 {
 	struct videobuf_buffer *vbuf = &pcdev->active->vb;
-	struct device *dev = pcdev->icd->parent;
+	struct device *dev = pcdev->soc_host.icd->parent;
 	int ret;
 
 	if (unlikely(!pcdev->active)) {
@@ -331,7 +330,7 @@
 static void mx1_camera_dma_irq(int channel, void *data)
 {
 	struct mx1_camera_dev *pcdev = data;
-	struct device *dev = pcdev->icd->parent;
+	struct device *dev = pcdev->soc_host.icd->parent;
 	struct mx1_buffer *buf;
 	struct videobuf_buffer *vb;
 	unsigned long flags;
@@ -389,7 +388,7 @@
 	 */
 	div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
 
-	dev_dbg(pcdev->icd->parent,
+	dev_dbg(pcdev->soc_host.icd->parent,
 		"System clock %lukHz, target freq %dkHz, divisor %lu\n",
 		lcdclk / 1000, mclk / 1000, div);
 
@@ -400,7 +399,7 @@
 {
 	unsigned int csicr1 = CSICR1_EN;
 
-	dev_dbg(pcdev->icd->parent, "Activate device\n");
+	dev_dbg(pcdev->soc_host.v4l2_dev.dev, "Activate device\n");
 
 	clk_prepare_enable(pcdev->clk);
 
@@ -416,7 +415,7 @@
 
 static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
 {
-	dev_dbg(pcdev->icd->parent, "Deactivate device\n");
+	dev_dbg(pcdev->soc_host.v4l2_dev.dev, "Deactivate device\n");
 
 	/* Disable all CSI interface */
 	__raw_writel(0x00, pcdev->base + CSICR1);
@@ -424,36 +423,38 @@
 	clk_disable_unprepare(pcdev->clk);
 }
 
-/*
- * The following two functions absolutely depend on the fact, that
- * there can be only one camera on i.MX1/i.MXL camera sensor interface
- */
 static int mx1_camera_add_device(struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct mx1_camera_dev *pcdev = ici->priv;
-
-	if (pcdev->icd)
-		return -EBUSY;
-
 	dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n",
 		 icd->devnum);
 
-	mx1_camera_activate(pcdev);
-
-	pcdev->icd = icd;
-
 	return 0;
 }
 
 static void mx1_camera_remove_device(struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n",
+		 icd->devnum);
+}
+
+/*
+ * The following two functions absolutely depend on the fact, that
+ * there can be only one camera on i.MX1/i.MXL camera sensor interface
+ */
+static int mx1_camera_clock_start(struct soc_camera_host *ici)
+{
+	struct mx1_camera_dev *pcdev = ici->priv;
+
+	mx1_camera_activate(pcdev);
+
+	return 0;
+}
+
+static void mx1_camera_clock_stop(struct soc_camera_host *ici)
+{
 	struct mx1_camera_dev *pcdev = ici->priv;
 	unsigned int csicr1;
 
-	BUG_ON(icd != pcdev->icd);
-
 	/* disable interrupts */
 	csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
 	__raw_writel(csicr1, pcdev->base + CSICR1);
@@ -461,12 +462,7 @@
 	/* Stop DMA engine */
 	imx_dma_disable(pcdev->dma_chan);
 
-	dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n",
-		 icd->devnum);
-
 	mx1_camera_deactivate(pcdev);
-
-	pcdev->icd = NULL;
 }
 
 static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
@@ -679,6 +675,8 @@
 	.owner		= THIS_MODULE,
 	.add		= mx1_camera_add_device,
 	.remove		= mx1_camera_remove_device,
+	.clock_start	= mx1_camera_clock_start,
+	.clock_stop	= mx1_camera_clock_stop,
 	.set_bus_param	= mx1_camera_set_bus_param,
 	.set_fmt	= mx1_camera_set_fmt,
 	.try_fmt	= mx1_camera_try_fmt,
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index 5bbeb43..45a0276 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -236,7 +236,6 @@
 struct mx2_camera_dev {
 	struct device		*dev;
 	struct soc_camera_host	soc_host;
-	struct soc_camera_device *icd;
 	struct clk		*clk_emma_ahb, *clk_emma_ipg;
 	struct clk		*clk_csi_ahb, *clk_csi_per;
 
@@ -394,8 +393,8 @@
 		writel(phys, pcdev->base_emma +
 			PRP_DEST_Y_PTR - 0x14 * bufnum);
 		if (prp->out_fmt == V4L2_PIX_FMT_YUV420) {
-			u32 imgsize = pcdev->icd->user_height *
-					pcdev->icd->user_width;
+			u32 imgsize = pcdev->soc_host.icd->user_height *
+					pcdev->soc_host.icd->user_width;
 
 			writel(phys + imgsize, pcdev->base_emma +
 				PRP_DEST_CB_PTR - 0x14 * bufnum);
@@ -413,20 +412,30 @@
 	writel(0, pcdev->base_emma + PRP_CNTL);
 }
 
+static int mx2_camera_add_device(struct soc_camera_device *icd)
+{
+	dev_info(icd->parent, "Camera driver attached to camera %d\n",
+		 icd->devnum);
+
+	return 0;
+}
+
+static void mx2_camera_remove_device(struct soc_camera_device *icd)
+{
+	dev_info(icd->parent, "Camera driver detached from camera %d\n",
+		 icd->devnum);
+}
+
 /*
  * The following two functions absolutely depend on the fact, that
  * there can be only one camera on mx2 camera sensor interface
  */
-static int mx2_camera_add_device(struct soc_camera_device *icd)
+static int mx2_camera_clock_start(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct mx2_camera_dev *pcdev = ici->priv;
 	int ret;
 	u32 csicr1;
 
-	if (pcdev->icd)
-		return -EBUSY;
-
 	ret = clk_prepare_enable(pcdev->clk_csi_ahb);
 	if (ret < 0)
 		return ret;
@@ -441,12 +450,8 @@
 	pcdev->csicr1 = csicr1;
 	writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
 
-	pcdev->icd = icd;
 	pcdev->frame_count = 0;
 
-	dev_info(icd->parent, "Camera driver attached to camera %d\n",
-		 icd->devnum);
-
 	return 0;
 
 exit_csi_ahb:
@@ -455,19 +460,11 @@
 	return ret;
 }
 
-static void mx2_camera_remove_device(struct soc_camera_device *icd)
+static void mx2_camera_clock_stop(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct mx2_camera_dev *pcdev = ici->priv;
 
-	BUG_ON(icd != pcdev->icd);
-
-	dev_info(icd->parent, "Camera driver detached from camera %d\n",
-		 icd->devnum);
-
 	mx2_camera_deactivate(pcdev);
-
-	pcdev->icd = NULL;
 }
 
 /*
@@ -1280,6 +1277,8 @@
 	.owner		= THIS_MODULE,
 	.add		= mx2_camera_add_device,
 	.remove		= mx2_camera_remove_device,
+	.clock_start	= mx2_camera_clock_start,
+	.clock_stop	= mx2_camera_clock_stop,
 	.set_fmt	= mx2_camera_set_fmt,
 	.set_crop	= mx2_camera_set_crop,
 	.get_formats	= mx2_camera_get_formats,
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c
index 5da3377..1047e3e 100644
--- a/drivers/media/platform/soc_camera/mx3_camera.c
+++ b/drivers/media/platform/soc_camera/mx3_camera.c
@@ -94,7 +94,6 @@
 	 * Interface. If anyone ever builds hardware to enable more than one
 	 * camera _simultaneously_, they will have to modify this driver too
 	 */
-	struct soc_camera_device *icd;
 	struct clk		*clk;
 
 	void __iomem		*base;
@@ -461,8 +460,7 @@
 }
 
 /* First part of ipu_csi_init_interface() */
-static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
-				struct soc_camera_device *icd)
+static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam)
 {
 	u32 conf;
 	long rate;
@@ -506,51 +504,49 @@
 
 	clk_prepare_enable(mx3_cam->clk);
 	rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
-	dev_dbg(icd->parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
+	dev_dbg(mx3_cam->soc_host.v4l2_dev.dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
 	if (rate)
 		clk_set_rate(mx3_cam->clk, rate);
 }
 
-/* Called with .host_lock held */
 static int mx3_camera_add_device(struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct mx3_camera_dev *mx3_cam = ici->priv;
-
-	if (mx3_cam->icd)
-		return -EBUSY;
-
-	mx3_camera_activate(mx3_cam, icd);
-
-	mx3_cam->buf_total = 0;
-	mx3_cam->icd = icd;
-
 	dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
 		 icd->devnum);
 
 	return 0;
 }
 
-/* Called with .host_lock held */
 static void mx3_camera_remove_device(struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
+		 icd->devnum);
+}
+
+/* Called with .host_lock held */
+static int mx3_camera_clock_start(struct soc_camera_host *ici)
+{
+	struct mx3_camera_dev *mx3_cam = ici->priv;
+
+	mx3_camera_activate(mx3_cam);
+
+	mx3_cam->buf_total = 0;
+
+	return 0;
+}
+
+/* Called with .host_lock held */
+static void mx3_camera_clock_stop(struct soc_camera_host *ici)
+{
 	struct mx3_camera_dev *mx3_cam = ici->priv;
 	struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
 
-	BUG_ON(icd != mx3_cam->icd);
-
 	if (*ichan) {
 		dma_release_channel(&(*ichan)->dma_chan);
 		*ichan = NULL;
 	}
 
 	clk_disable_unprepare(mx3_cam->clk);
-
-	mx3_cam->icd = NULL;
-
-	dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
-		 icd->devnum);
 }
 
 static int test_platform_param(struct mx3_camera_dev *mx3_cam,
@@ -1133,6 +1129,8 @@
 	.owner		= THIS_MODULE,
 	.add		= mx3_camera_add_device,
 	.remove		= mx3_camera_remove_device,
+	.clock_start	= mx3_camera_clock_start,
+	.clock_stop	= mx3_camera_clock_stop,
 	.set_crop	= mx3_camera_set_crop,
 	.set_fmt	= mx3_camera_set_fmt,
 	.try_fmt	= mx3_camera_try_fmt,
diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c
index 9689a6e..6769193 100644
--- a/drivers/media/platform/soc_camera/omap1_camera.c
+++ b/drivers/media/platform/soc_camera/omap1_camera.c
@@ -150,7 +150,6 @@
 
 struct omap1_cam_dev {
 	struct soc_camera_host		soc_host;
-	struct soc_camera_device	*icd;
 	struct clk			*clk;
 
 	unsigned int			irq;
@@ -564,7 +563,7 @@
 {
 	struct omap1_cam_buf *buf = pcdev->active;
 	struct videobuf_buffer *vb;
-	struct device *dev = pcdev->icd->parent;
+	struct device *dev = pcdev->soc_host.icd->parent;
 
 	if (WARN_ON(!buf)) {
 		suspend_capture(pcdev);
@@ -790,7 +789,7 @@
 static irqreturn_t cam_isr(int irq, void *data)
 {
 	struct omap1_cam_dev *pcdev = data;
-	struct device *dev = pcdev->icd->parent;
+	struct device *dev = pcdev->soc_host.icd->parent;
 	struct omap1_cam_buf *buf = pcdev->active;
 	u32 it_status;
 	unsigned long flags;
@@ -894,19 +893,29 @@
 		CAM_WRITE(pcdev, GPIO, !reset);
 }
 
+static int omap1_cam_add_device(struct soc_camera_device *icd)
+{
+	dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
+			icd->devnum);
+
+	return 0;
+}
+
+static void omap1_cam_remove_device(struct soc_camera_device *icd)
+{
+	dev_dbg(icd->parent,
+		"OMAP1 Camera driver detached from camera %d\n", icd->devnum);
+}
+
 /*
  * The following two functions absolutely depend on the fact, that
  * there can be only one camera on OMAP1 camera sensor interface
  */
-static int omap1_cam_add_device(struct soc_camera_device *icd)
+static int omap1_cam_clock_start(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct omap1_cam_dev *pcdev = ici->priv;
 	u32 ctrlclock;
 
-	if (pcdev->icd)
-		return -EBUSY;
-
 	clk_enable(pcdev->clk);
 
 	/* setup sensor clock */
@@ -941,21 +950,14 @@
 
 	sensor_reset(pcdev, false);
 
-	pcdev->icd = icd;
-
-	dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
-			icd->devnum);
 	return 0;
 }
 
-static void omap1_cam_remove_device(struct soc_camera_device *icd)
+static void omap1_cam_clock_stop(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct omap1_cam_dev *pcdev = ici->priv;
 	u32 ctrlclock;
 
-	BUG_ON(icd != pcdev->icd);
-
 	suspend_capture(pcdev);
 	disable_capture(pcdev);
 
@@ -973,11 +975,6 @@
 	CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~MCLK_EN);
 
 	clk_disable(pcdev->clk);
-
-	pcdev->icd = NULL;
-
-	dev_dbg(icd->parent,
-		"OMAP1 Camera driver detached from camera %d\n", icd->devnum);
 }
 
 /* Duplicate standard formats based on host capability of byte swapping */
@@ -1535,6 +1532,8 @@
 	.owner		= THIS_MODULE,
 	.add		= omap1_cam_add_device,
 	.remove		= omap1_cam_remove_device,
+	.clock_start	= omap1_cam_clock_start,
+	.clock_stop	= omap1_cam_clock_stop,
 	.get_formats	= omap1_cam_get_formats,
 	.set_crop	= omap1_cam_set_crop,
 	.set_fmt	= omap1_cam_set_fmt,
diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c
index d665242..d4df305 100644
--- a/drivers/media/platform/soc_camera/pxa_camera.c
+++ b/drivers/media/platform/soc_camera/pxa_camera.c
@@ -200,7 +200,6 @@
 	 * interface. If anyone ever builds hardware to enable more than
 	 * one camera, they will have to modify this driver too
 	 */
-	struct soc_camera_device *icd;
 	struct clk		*clk;
 
 	unsigned int		irq;
@@ -956,39 +955,38 @@
 	return IRQ_HANDLED;
 }
 
-/*
- * The following two functions absolutely depend on the fact, that
- * there can be only one camera on PXA quick capture interface
- * Called with .host_lock held
- */
 static int pxa_camera_add_device(struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct pxa_camera_dev *pcdev = ici->priv;
-
-	if (pcdev->icd)
-		return -EBUSY;
-
-	pxa_camera_activate(pcdev);
-
-	pcdev->icd = icd;
-
 	dev_info(icd->parent, "PXA Camera driver attached to camera %d\n",
 		 icd->devnum);
 
 	return 0;
 }
 
-/* Called with .host_lock held */
 static void pxa_camera_remove_device(struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct pxa_camera_dev *pcdev = ici->priv;
-
-	BUG_ON(icd != pcdev->icd);
-
 	dev_info(icd->parent, "PXA Camera driver detached from camera %d\n",
 		 icd->devnum);
+}
+
+/*
+ * The following two functions absolutely depend on the fact, that
+ * there can be only one camera on PXA quick capture interface
+ * Called with .host_lock held
+ */
+static int pxa_camera_clock_start(struct soc_camera_host *ici)
+{
+	struct pxa_camera_dev *pcdev = ici->priv;
+
+	pxa_camera_activate(pcdev);
+
+	return 0;
+}
+
+/* Called with .host_lock held */
+static void pxa_camera_clock_stop(struct soc_camera_host *ici)
+{
+	struct pxa_camera_dev *pcdev = ici->priv;
 
 	/* disable capture, disable interrupts */
 	__raw_writel(0x3ff, pcdev->base + CICR0);
@@ -999,8 +997,6 @@
 	DCSR(pcdev->dma_chans[2]) = 0;
 
 	pxa_camera_deactivate(pcdev);
-
-	pcdev->icd = NULL;
 }
 
 static int test_platform_param(struct pxa_camera_dev *pcdev,
@@ -1596,8 +1592,8 @@
 	pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3);
 	pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4);
 
-	if (pcdev->icd) {
-		struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
+	if (pcdev->soc_host.icd) {
+		struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd);
 		ret = v4l2_subdev_call(sd, core, s_power, 0);
 		if (ret == -ENOIOCTLCMD)
 			ret = 0;
@@ -1622,8 +1618,8 @@
 	__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR3);
 	__raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4);
 
-	if (pcdev->icd) {
-		struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
+	if (pcdev->soc_host.icd) {
+		struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd);
 		ret = v4l2_subdev_call(sd, core, s_power, 1);
 		if (ret == -ENOIOCTLCMD)
 			ret = 0;
@@ -1640,6 +1636,8 @@
 	.owner		= THIS_MODULE,
 	.add		= pxa_camera_add_device,
 	.remove		= pxa_camera_remove_device,
+	.clock_start	= pxa_camera_clock_start,
+	.clock_stop	= pxa_camera_clock_stop,
 	.set_crop	= pxa_camera_set_crop,
 	.get_formats	= pxa_camera_get_formats,
 	.put_formats	= pxa_camera_put_formats,
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index 143d29fe..f2de006 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/moduleparam.h>
+#include <linux/of.h>
 #include <linux/time.h>
 #include <linux/slab.h>
 #include <linux/device.h>
@@ -35,6 +36,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/sched.h>
 
+#include <media/v4l2-async.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
 #include <media/soc_camera.h>
@@ -44,6 +46,8 @@
 #include <media/v4l2-mediabus.h>
 #include <media/soc_mediabus.h>
 
+#include "soc_scale_crop.h"
+
 /* register offsets for sh7722 / sh7723 */
 
 #define CAPSR  0x00 /* Capture start register */
@@ -95,7 +99,10 @@
 
 struct sh_mobile_ceu_dev {
 	struct soc_camera_host ici;
-	struct soc_camera_device *icd;
+	/* Asynchronous CSI2 linking */
+	struct v4l2_async_subdev *csi2_asd;
+	struct v4l2_subdev *csi2_sd;
+	/* Synchronous probing compatibility */
 	struct platform_device *csi2_pdev;
 
 	unsigned int irq;
@@ -119,6 +126,7 @@
 
 	enum v4l2_field field;
 	int sequence;
+	unsigned long flags;
 
 	unsigned int image_mode:1;
 	unsigned int is_16bit:1;
@@ -163,7 +171,6 @@
 static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
 {
 	int i, success = 0;
-	struct soc_camera_device *icd = pcdev->icd;
 
 	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
 
@@ -185,9 +192,8 @@
 		udelay(1);
 	}
 
-
 	if (2 != success) {
-		dev_warn(icd->pdev, "soft reset time out\n");
+		dev_warn(pcdev->ici.v4l2_dev.dev, "soft reset time out\n");
 		return -EIO;
 	}
 
@@ -277,7 +283,7 @@
  */
 static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 {
-	struct soc_camera_device *icd = pcdev->icd;
+	struct soc_camera_device *icd = pcdev->ici.icd;
 	dma_addr_t phys_addr_top, phys_addr_bottom;
 	unsigned long top1, top2;
 	unsigned long bottom1, bottom2;
@@ -534,72 +540,92 @@
 {
 	struct v4l2_subdev *sd;
 
-	if (!pcdev->csi2_pdev)
-		return NULL;
+	if (pcdev->csi2_sd)
+		return pcdev->csi2_sd;
 
-	v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
-		if (&pcdev->csi2_pdev->dev == v4l2_get_subdevdata(sd))
-			return sd;
+	if (pcdev->csi2_asd) {
+		char name[] = "sh-mobile-csi2";
+		v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
+			if (!strncmp(name, sd->name, sizeof(name) - 1)) {
+				pcdev->csi2_sd = sd;
+				return sd;
+			}
+	}
 
 	return NULL;
 }
 
-/* Called with .host_lock held */
+static struct v4l2_subdev *csi2_subdev(struct sh_mobile_ceu_dev *pcdev,
+				       struct soc_camera_device *icd)
+{
+	struct v4l2_subdev *sd = pcdev->csi2_sd;
+
+	return sd && sd->grp_id == soc_camera_grp_id(icd) ? sd : NULL;
+}
+
 static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	struct v4l2_subdev *csi2_sd;
+	struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
 	int ret;
 
-	if (pcdev->icd)
-		return -EBUSY;
+	if (csi2_sd) {
+		csi2_sd->grp_id = soc_camera_grp_id(icd);
+		v4l2_set_subdev_hostdata(csi2_sd, icd);
+	}
+
+	ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
+	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
+		return ret;
+
+	/*
+	 * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
+	 * has not found this soc-camera device among its clients
+	 */
+	if (csi2_sd && ret == -ENODEV)
+		csi2_sd->grp_id = 0;
 
 	dev_info(icd->parent,
-		 "SuperH Mobile CEU driver attached to camera %d\n",
+		 "SuperH Mobile CEU%s driver attached to camera %d\n",
+		 csi2_sd && csi2_sd->grp_id ? "/CSI-2" : "", icd->devnum);
+
+	return 0;
+}
+
+static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
+
+	dev_info(icd->parent,
+		 "SuperH Mobile CEU driver detached from camera %d\n",
 		 icd->devnum);
 
+	v4l2_subdev_call(csi2_sd, core, s_power, 0);
+}
+
+/* Called with .host_lock held */
+static int sh_mobile_ceu_clock_start(struct soc_camera_host *ici)
+{
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	int ret;
+
 	pm_runtime_get_sync(ici->v4l2_dev.dev);
 
 	pcdev->buf_total = 0;
 
 	ret = sh_mobile_ceu_soft_reset(pcdev);
 
-	csi2_sd = find_csi2(pcdev);
-	if (csi2_sd) {
-		csi2_sd->grp_id = soc_camera_grp_id(icd);
-		v4l2_set_subdev_hostdata(csi2_sd, icd);
-	}
-
-	ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
-	if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
-		pm_runtime_put(ici->v4l2_dev.dev);
-		return ret;
-	}
-
-	/*
-	 * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
-	 * has not found this soc-camera device among its clients
-	 */
-	if (ret == -ENODEV && csi2_sd)
-		csi2_sd->grp_id = 0;
-	pcdev->icd = icd;
-
 	return 0;
 }
 
 /* Called with .host_lock held */
-static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
+static void sh_mobile_ceu_clock_stop(struct soc_camera_host *ici)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
 
-	BUG_ON(icd != pcdev->icd);
-
-	v4l2_subdev_call(csi2_sd, core, s_power, 0);
-	if (csi2_sd)
-		csi2_sd->grp_id = 0;
 	/* disable capture, disable interrupts */
 	ceu_write(pcdev, CEIER, 0);
 	sh_mobile_ceu_soft_reset(pcdev);
@@ -614,12 +640,6 @@
 	spin_unlock_irq(&pcdev->lock);
 
 	pm_runtime_put(ici->v4l2_dev.dev);
-
-	dev_info(icd->parent,
-		 "SuperH Mobile CEU driver detached from camera %d\n",
-		 icd->devnum);
-
-	pcdev->icd = NULL;
 }
 
 /*
@@ -705,7 +725,7 @@
 	}
 
 	/* CSI2 special configuration */
-	if (pcdev->pdata->csi2) {
+	if (csi2_subdev(pcdev, icd)) {
 		in_width = ((in_width - 2) * 2);
 		left_offset *= 2;
 	}
@@ -762,13 +782,7 @@
 static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev,
 					   struct soc_camera_device *icd)
 {
-	if (pcdev->csi2_pdev) {
-		struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
-		if (csi2_sd && csi2_sd->grp_id == soc_camera_grp_id(icd))
-			return csi2_sd;
-	}
-
-	return soc_camera_to_subdev(icd);
+	return csi2_subdev(pcdev, icd) ? : soc_camera_to_subdev(icd);
 }
 
 #define CEU_BUS_FLAGS (V4L2_MBUS_MASTER |	\
@@ -809,7 +823,7 @@
 	/* Make choises, based on platform preferences */
 	if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
 	    (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
-		if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
+		if (pcdev->flags & SH_CEU_FLAG_HSYNC_LOW)
 			common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
 		else
 			common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
@@ -817,7 +831,7 @@
 
 	if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
 	    (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
-		if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
+		if (pcdev->flags & SH_CEU_FLAG_VSYNC_LOW)
 			common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
 		else
 			common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
@@ -872,11 +886,11 @@
 	value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
 	value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
 
-	if (pcdev->pdata->csi2) /* CSI2 mode */
+	if (csi2_subdev(pcdev, icd)) /* CSI2 mode */
 		value |= 3 << 12;
 	else if (pcdev->is_16bit)
 		value |= 1 << 12;
-	else if (pcdev->pdata->flags & SH_CEU_FLAG_LOWER_8BIT)
+	else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT)
 		value |= 2 << 12;
 
 	ceu_write(pcdev, CAMCR, value);
@@ -993,8 +1007,6 @@
 		 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
 }
 
-static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
-
 static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl)
 {
 	return container_of(ctrl->handler, struct soc_camera_device,
@@ -1051,7 +1063,7 @@
 		return 0;
 	}
 
-	if (!pcdev->pdata->csi2) {
+	if (!csi2_subdev(pcdev, icd)) {
 		/* Are there any restrictions in the CSI-2 case? */
 		ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
 		if (ret < 0)
@@ -1072,7 +1084,7 @@
 		/* FIXME: subwindow is lost between close / open */
 
 		/* Cache current client geometry */
-		ret = client_g_rect(sd, &rect);
+		ret = soc_camera_client_g_rect(sd, &rect);
 		if (ret < 0)
 			return ret;
 
@@ -1182,334 +1194,8 @@
 	icd->host_priv = NULL;
 }
 
-/* Check if any dimension of r1 is smaller than respective one of r2 */
-static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
-{
-	return r1->width < r2->width || r1->height < r2->height;
-}
-
-/* Check if r1 fails to cover r2 */
-static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
-{
-	return r1->left > r2->left || r1->top > r2->top ||
-		r1->left + r1->width < r2->left + r2->width ||
-		r1->top + r1->height < r2->top + r2->height;
-}
-
-static unsigned int scale_down(unsigned int size, unsigned int scale)
-{
-	return (size * 4096 + scale / 2) / scale;
-}
-
-static unsigned int calc_generic_scale(unsigned int input, unsigned int output)
-{
-	return (input * 4096 + output / 2) / output;
-}
-
-/* Get and store current client crop */
-static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
-{
-	struct v4l2_crop crop;
-	struct v4l2_cropcap cap;
-	int ret;
-
-	crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	ret = v4l2_subdev_call(sd, video, g_crop, &crop);
-	if (!ret) {
-		*rect = crop.c;
-		return ret;
-	}
-
-	/* Camera driver doesn't support .g_crop(), assume default rectangle */
-	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
-	if (!ret)
-		*rect = cap.defrect;
-
-	return ret;
-}
-
-/* Client crop has changed, update our sub-rectangle to remain within the area */
-static void update_subrect(struct sh_mobile_ceu_cam *cam)
-{
-	struct v4l2_rect *rect = &cam->rect, *subrect = &cam->subrect;
-
-	if (rect->width < subrect->width)
-		subrect->width = rect->width;
-
-	if (rect->height < subrect->height)
-		subrect->height = rect->height;
-
-	if (rect->left > subrect->left)
-		subrect->left = rect->left;
-	else if (rect->left + rect->width >
-		 subrect->left + subrect->width)
-		subrect->left = rect->left + rect->width -
-			subrect->width;
-
-	if (rect->top > subrect->top)
-		subrect->top = rect->top;
-	else if (rect->top + rect->height >
-		 subrect->top + subrect->height)
-		subrect->top = rect->top + rect->height -
-			subrect->height;
-}
-
-/*
- * The common for both scaling and cropping iterative approach is:
- * 1. try if the client can produce exactly what requested by the user
- * 2. if (1) failed, try to double the client image until we get one big enough
- * 3. if (2) failed, try to request the maximum image
- */
-static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
-			 struct v4l2_crop *cam_crop)
-{
-	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-	struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
-	struct device *dev = sd->v4l2_dev->dev;
-	struct sh_mobile_ceu_cam *cam = icd->host_priv;
-	struct v4l2_cropcap cap;
-	int ret;
-	unsigned int width, height;
-
-	v4l2_subdev_call(sd, video, s_crop, crop);
-	ret = client_g_rect(sd, cam_rect);
-	if (ret < 0)
-		return ret;
-
-	/*
-	 * Now cam_crop contains the current camera input rectangle, and it must
-	 * be within camera cropcap bounds
-	 */
-	if (!memcmp(rect, cam_rect, sizeof(*rect))) {
-		/* Even if camera S_CROP failed, but camera rectangle matches */
-		dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n",
-			rect->width, rect->height, rect->left, rect->top);
-		cam->rect = *cam_rect;
-		return 0;
-	}
-
-	/* Try to fix cropping, that camera hasn't managed to set */
-	dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n",
-		cam_rect->width, cam_rect->height,
-		cam_rect->left, cam_rect->top,
-		rect->width, rect->height, rect->left, rect->top);
-
-	/* We need sensor maximum rectangle */
-	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
-	if (ret < 0)
-		return ret;
-
-	/* Put user requested rectangle within sensor bounds */
-	soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
-			      cap.bounds.width);
-	soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
-			      cap.bounds.height);
-
-	/*
-	 * Popular special case - some cameras can only handle fixed sizes like
-	 * QVGA, VGA,... Take care to avoid infinite loop.
-	 */
-	width = max(cam_rect->width, 2);
-	height = max(cam_rect->height, 2);
-
-	/*
-	 * Loop as long as sensor is not covering the requested rectangle and
-	 * is still within its bounds
-	 */
-	while (!ret && (is_smaller(cam_rect, rect) ||
-			is_inside(cam_rect, rect)) &&
-	       (cap.bounds.width > width || cap.bounds.height > height)) {
-
-		width *= 2;
-		height *= 2;
-
-		cam_rect->width = width;
-		cam_rect->height = height;
-
-		/*
-		 * We do not know what capabilities the camera has to set up
-		 * left and top borders. We could try to be smarter in iterating
-		 * them, e.g., if camera current left is to the right of the
-		 * target left, set it to the middle point between the current
-		 * left and minimum left. But that would add too much
-		 * complexity: we would have to iterate each border separately.
-		 * Instead we just drop to the left and top bounds.
-		 */
-		if (cam_rect->left > rect->left)
-			cam_rect->left = cap.bounds.left;
-
-		if (cam_rect->left + cam_rect->width < rect->left + rect->width)
-			cam_rect->width = rect->left + rect->width -
-				cam_rect->left;
-
-		if (cam_rect->top > rect->top)
-			cam_rect->top = cap.bounds.top;
-
-		if (cam_rect->top + cam_rect->height < rect->top + rect->height)
-			cam_rect->height = rect->top + rect->height -
-				cam_rect->top;
-
-		v4l2_subdev_call(sd, video, s_crop, cam_crop);
-		ret = client_g_rect(sd, cam_rect);
-		dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret,
-			cam_rect->width, cam_rect->height,
-			cam_rect->left, cam_rect->top);
-	}
-
-	/* S_CROP must not modify the rectangle */
-	if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
-		/*
-		 * The camera failed to configure a suitable cropping,
-		 * we cannot use the current rectangle, set to max
-		 */
-		*cam_rect = cap.bounds;
-		v4l2_subdev_call(sd, video, s_crop, cam_crop);
-		ret = client_g_rect(sd, cam_rect);
-		dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret,
-			cam_rect->width, cam_rect->height,
-			cam_rect->left, cam_rect->top);
-	}
-
-	if (!ret) {
-		cam->rect = *cam_rect;
-		update_subrect(cam);
-	}
-
-	return ret;
-}
-
-/* Iterative s_mbus_fmt, also updates cached client crop on success */
-static int client_s_fmt(struct soc_camera_device *icd,
-			struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
-{
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	struct sh_mobile_ceu_cam *cam = icd->host_priv;
-	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-	struct device *dev = icd->parent;
-	unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
-	unsigned int max_width, max_height;
-	struct v4l2_cropcap cap;
-	bool ceu_1to1;
-	int ret;
-
-	ret = v4l2_device_call_until_err(sd->v4l2_dev,
-					 soc_camera_grp_id(icd), video,
-					 s_mbus_fmt, mf);
-	if (ret < 0)
-		return ret;
-
-	dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
-
-	if (width == mf->width && height == mf->height) {
-		/* Perfect! The client has done it all. */
-		ceu_1to1 = true;
-		goto update_cache;
-	}
-
-	ceu_1to1 = false;
-	if (!ceu_can_scale)
-		goto update_cache;
-
-	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
-	if (ret < 0)
-		return ret;
-
-	max_width = min(cap.bounds.width, pcdev->max_width);
-	max_height = min(cap.bounds.height, pcdev->max_height);
-
-	/* Camera set a format, but geometry is not precise, try to improve */
-	tmp_w = mf->width;
-	tmp_h = mf->height;
-
-	/* width <= max_width && height <= max_height - guaranteed by try_fmt */
-	while ((width > tmp_w || height > tmp_h) &&
-	       tmp_w < max_width && tmp_h < max_height) {
-		tmp_w = min(2 * tmp_w, max_width);
-		tmp_h = min(2 * tmp_h, max_height);
-		mf->width = tmp_w;
-		mf->height = tmp_h;
-		ret = v4l2_device_call_until_err(sd->v4l2_dev,
-					soc_camera_grp_id(icd), video,
-					s_mbus_fmt, mf);
-		dev_geo(dev, "Camera scaled to %ux%u\n",
-			mf->width, mf->height);
-		if (ret < 0) {
-			/* This shouldn't happen */
-			dev_err(dev, "Client failed to set format: %d\n", ret);
-			return ret;
-		}
-	}
-
-update_cache:
-	/* Update cache */
-	ret = client_g_rect(sd, &cam->rect);
-	if (ret < 0)
-		return ret;
-
-	if (ceu_1to1)
-		cam->subrect = cam->rect;
-	else
-		update_subrect(cam);
-
-	return 0;
-}
-
-/**
- * @width	- on output: user width, mapped back to input
- * @height	- on output: user height, mapped back to input
- * @mf		- in- / output camera output window
- */
-static int client_scale(struct soc_camera_device *icd,
-			struct v4l2_mbus_framefmt *mf,
-			unsigned int *width, unsigned int *height,
-			bool ceu_can_scale)
-{
-	struct sh_mobile_ceu_cam *cam = icd->host_priv;
-	struct device *dev = icd->parent;
-	struct v4l2_mbus_framefmt mf_tmp = *mf;
-	unsigned int scale_h, scale_v;
-	int ret;
-
-	/*
-	 * 5. Apply iterative camera S_FMT for camera user window (also updates
-	 *    client crop cache and the imaginary sub-rectangle).
-	 */
-	ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale);
-	if (ret < 0)
-		return ret;
-
-	dev_geo(dev, "5: camera scaled to %ux%u\n",
-		mf_tmp.width, mf_tmp.height);
-
-	/* 6. Retrieve camera output window (g_fmt) */
-
-	/* unneeded - it is already in "mf_tmp" */
-
-	/* 7. Calculate new client scales. */
-	scale_h = calc_generic_scale(cam->rect.width, mf_tmp.width);
-	scale_v = calc_generic_scale(cam->rect.height, mf_tmp.height);
-
-	mf->width	= mf_tmp.width;
-	mf->height	= mf_tmp.height;
-	mf->colorspace	= mf_tmp.colorspace;
-
-	/*
-	 * 8. Calculate new CEU crop - apply camera scales to previously
-	 *    updated "effective" crop.
-	 */
-	*width = scale_down(cam->subrect.width, scale_h);
-	*height = scale_down(cam->subrect.height, scale_v);
-
-	dev_geo(dev, "8: new client sub-window %ux%u\n", *width, *height);
-
-	return 0;
-}
+#define scale_down(size, scale) soc_camera_shift_scale(size, 12, scale)
+#define calc_generic_scale(in, out) soc_camera_calc_scale(in, 12, out)
 
 /*
  * CEU can scale and crop, but we don't want to waste bandwidth and kill the
@@ -1547,7 +1233,8 @@
 	 * 1. - 2. Apply iterative camera S_CROP for new input window, read back
 	 * actual camera rectangle.
 	 */
-	ret = client_s_crop(icd, &a_writable, &cam_crop);
+	ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop,
+				       &cam->rect, &cam->subrect);
 	if (ret < 0)
 		return ret;
 
@@ -1666,55 +1353,6 @@
 	return 0;
 }
 
-/*
- * Calculate real client output window by applying new scales to the current
- * client crop. New scales are calculated from the requested output format and
- * CEU crop, mapped backed onto the client input (subrect).
- */
-static void calculate_client_output(struct soc_camera_device *icd,
-		const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
-{
-	struct sh_mobile_ceu_cam *cam = icd->host_priv;
-	struct device *dev = icd->parent;
-	struct v4l2_rect *cam_subrect = &cam->subrect;
-	unsigned int scale_v, scale_h;
-
-	if (cam_subrect->width == cam->rect.width &&
-	    cam_subrect->height == cam->rect.height) {
-		/* No sub-cropping */
-		mf->width	= pix->width;
-		mf->height	= pix->height;
-		return;
-	}
-
-	/* 1.-2. Current camera scales and subwin - cached. */
-
-	dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
-		cam_subrect->width, cam_subrect->height,
-		cam_subrect->left, cam_subrect->top);
-
-	/*
-	 * 3. Calculate new combined scales from input sub-window to requested
-	 *    user window.
-	 */
-
-	/*
-	 * TODO: CEU cannot scale images larger than VGA to smaller than SubQCIF
-	 * (128x96) or larger than VGA
-	 */
-	scale_h = calc_generic_scale(cam_subrect->width, pix->width);
-	scale_v = calc_generic_scale(cam_subrect->height, pix->height);
-
-	dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
-
-	/*
-	 * 4. Calculate desired client output window by applying combined scales
-	 *    to client (real) input window.
-	 */
-	mf->width	= scale_down(cam->rect.width, scale_h);
-	mf->height	= scale_down(cam->rect.height, scale_v);
-}
-
 /* Similar to set_crop multistage iterative algorithm */
 static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
 				 struct v4l2_format *f)
@@ -1727,8 +1365,8 @@
 	struct v4l2_mbus_framefmt mf;
 	__u32 pixfmt = pix->pixelformat;
 	const struct soc_camera_format_xlate *xlate;
-	/* Keep Compiler Happy */
-	unsigned int ceu_sub_width = 0, ceu_sub_height = 0;
+	unsigned int ceu_sub_width = pcdev->max_width,
+		ceu_sub_height = pcdev->max_height;
 	u16 scale_v, scale_h;
 	int ret;
 	bool image_mode;
@@ -1755,7 +1393,7 @@
 	}
 
 	/* 1.-4. Calculate desired client output geometry */
-	calculate_client_output(icd, pix, &mf);
+	soc_camera_calc_client_output(icd, &cam->rect, &cam->subrect, pix, &mf, 12);
 	mf.field	= pix->field;
 	mf.colorspace	= pix->colorspace;
 	mf.code		= xlate->code;
@@ -1777,8 +1415,9 @@
 	dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
 
 	/* 5. - 9. */
-	ret = client_scale(icd, &mf, &ceu_sub_width, &ceu_sub_height,
-			   image_mode && V4L2_FIELD_NONE == field);
+	ret = soc_camera_client_scale(icd, &cam->rect, &cam->subrect,
+				&mf, &ceu_sub_width, &ceu_sub_height,
+				image_mode && V4L2_FIELD_NONE == field, 12);
 
 	dev_geo(dev, "5-9: client scale return %d\n", ret);
 
@@ -2036,6 +1675,8 @@
 	.owner		= THIS_MODULE,
 	.add		= sh_mobile_ceu_add_device,
 	.remove		= sh_mobile_ceu_remove_device,
+	.clock_start	= sh_mobile_ceu_clock_start,
+	.clock_stop	= sh_mobile_ceu_clock_stop,
 	.get_formats	= sh_mobile_ceu_get_formats,
 	.put_formats	= sh_mobile_ceu_put_formats,
 	.get_crop	= sh_mobile_ceu_get_crop,
@@ -2079,7 +1720,7 @@
 	struct resource *res;
 	void __iomem *base;
 	unsigned int irq;
-	int err = 0;
+	int err, i;
 	struct bus_wait wait = {
 		.completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion),
 		.notifier.notifier_call = bus_notify,
@@ -2104,13 +1745,36 @@
 	init_completion(&pcdev->complete);
 
 	pcdev->pdata = pdev->dev.platform_data;
-	if (!pcdev->pdata) {
+	if (!pcdev->pdata && !pdev->dev.of_node) {
 		dev_err(&pdev->dev, "CEU platform data not set.\n");
 		return -EINVAL;
 	}
 
-	pcdev->max_width = pcdev->pdata->max_width ? : 2560;
-	pcdev->max_height = pcdev->pdata->max_height ? : 1920;
+	/* TODO: implement per-device bus flags */
+	if (pcdev->pdata) {
+		pcdev->max_width = pcdev->pdata->max_width;
+		pcdev->max_height = pcdev->pdata->max_height;
+		pcdev->flags = pcdev->pdata->flags;
+	}
+
+	if (!pcdev->max_width) {
+		unsigned int v;
+		err = of_property_read_u32(pdev->dev.of_node, "renesas,max-width", &v);
+		if (!err)
+			pcdev->max_width = v;
+
+		if (!pcdev->max_width)
+			pcdev->max_width = 2560;
+	}
+	if (!pcdev->max_height) {
+		unsigned int v;
+		err = of_property_read_u32(pdev->dev.of_node, "renesas,max-height", &v);
+		if (!err)
+			pcdev->max_height = v;
+
+		if (!pcdev->max_height)
+			pcdev->max_height = 1920;
+	}
 
 	base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(base))
@@ -2160,31 +1824,60 @@
 		goto exit_free_clk;
 	}
 
-	err = soc_camera_host_register(&pcdev->ici);
-	if (err)
-		goto exit_free_ctx;
+	if (pcdev->pdata && pcdev->pdata->asd_sizes) {
+		struct v4l2_async_subdev **asd;
+		char name[] = "sh-mobile-csi2";
+		int j;
 
-	/* CSI2 interfacing */
-	csi2 = pcdev->pdata->csi2;
+		/*
+		 * CSI2 interfacing: several groups can use CSI2, pick up the
+		 * first one
+		 */
+		asd = pcdev->pdata->asd;
+		for (j = 0; pcdev->pdata->asd_sizes[j]; j++) {
+			for (i = 0; i < pcdev->pdata->asd_sizes[j]; i++, asd++) {
+				dev_dbg(&pdev->dev, "%s(): subdev #%d, type %u\n",
+					__func__, i, (*asd)->bus_type);
+				if ((*asd)->bus_type == V4L2_ASYNC_BUS_PLATFORM &&
+				    !strncmp(name, (*asd)->match.platform.name,
+					     sizeof(name) - 1)) {
+					pcdev->csi2_asd = *asd;
+					break;
+				}
+			}
+			if (pcdev->csi2_asd)
+				break;
+		}
+
+		pcdev->ici.asd = pcdev->pdata->asd;
+		pcdev->ici.asd_sizes = pcdev->pdata->asd_sizes;
+	}
+
+	/* Legacy CSI2 interfacing */
+	csi2 = pcdev->pdata ? pcdev->pdata->csi2 : NULL;
 	if (csi2) {
+		/*
+		 * TODO: remove this once all users are converted to
+		 * asynchronous CSI2 probing. If it has to be kept, csi2
+		 * platform device resources have to be added, using
+		 * platform_device_add_resources()
+		 */
 		struct platform_device *csi2_pdev =
 			platform_device_alloc("sh-mobile-csi2", csi2->id);
 		struct sh_csi2_pdata *csi2_pdata = csi2->platform_data;
 
 		if (!csi2_pdev) {
 			err = -ENOMEM;
-			goto exit_host_unregister;
+			goto exit_free_ctx;
 		}
 
 		pcdev->csi2_pdev		= csi2_pdev;
 
-		err = platform_device_add_data(csi2_pdev, csi2_pdata, sizeof(*csi2_pdata));
+		err = platform_device_add_data(csi2_pdev, csi2_pdata,
+					       sizeof(*csi2_pdata));
 		if (err < 0)
 			goto exit_pdev_put;
 
-		csi2_pdata			= csi2_pdev->dev.platform_data;
-		csi2_pdata->v4l2_dev		= &pcdev->ici.v4l2_dev;
-
 		csi2_pdev->resource		= csi2->resource;
 		csi2_pdev->num_resources	= csi2->num_resources;
 
@@ -2226,17 +1919,38 @@
 			err = -ENODEV;
 			goto exit_pdev_unregister;
 		}
+
+		pcdev->csi2_sd = platform_get_drvdata(csi2_pdev);
+	}
+
+	err = soc_camera_host_register(&pcdev->ici);
+	if (err)
+		goto exit_csi2_unregister;
+
+	if (csi2) {
+		err = v4l2_device_register_subdev(&pcdev->ici.v4l2_dev,
+						  pcdev->csi2_sd);
+		dev_dbg(&pdev->dev, "%s(): ret(register_subdev) = %d\n",
+			__func__, err);
+		if (err < 0)
+			goto exit_host_unregister;
+		/* v4l2_device_register_subdev() took a reference too */
+		module_put(pcdev->csi2_sd->owner);
 	}
 
 	return 0;
 
-exit_pdev_unregister:
-	platform_device_del(pcdev->csi2_pdev);
-exit_pdev_put:
-	pcdev->csi2_pdev->resource = NULL;
-	platform_device_put(pcdev->csi2_pdev);
 exit_host_unregister:
 	soc_camera_host_unregister(&pcdev->ici);
+exit_csi2_unregister:
+	if (csi2) {
+		module_put(pcdev->csi2_pdev->dev.driver->owner);
+exit_pdev_unregister:
+		platform_device_del(pcdev->csi2_pdev);
+exit_pdev_put:
+		pcdev->csi2_pdev->resource = NULL;
+		platform_device_put(pcdev->csi2_pdev);
+	}
 exit_free_ctx:
 	vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
 exit_free_clk:
@@ -2287,10 +2001,18 @@
 	.runtime_resume = sh_mobile_ceu_runtime_nop,
 };
 
+static const struct of_device_id sh_mobile_ceu_of_match[] = {
+	{ .compatible = "renesas,sh-mobile-ceu" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sh_mobile_ceu_of_match);
+
 static struct platform_driver sh_mobile_ceu_driver = {
 	.driver		= {
 		.name	= "sh_mobile_ceu",
+		.owner	= THIS_MODULE,
 		.pm	= &sh_mobile_ceu_dev_pm_ops,
+		.of_match_table = sh_mobile_ceu_of_match,
 	},
 	.probe		= sh_mobile_ceu_probe,
 	.remove		= sh_mobile_ceu_remove,
@@ -2314,5 +2036,5 @@
 MODULE_DESCRIPTION("SuperH Mobile CEU driver");
 MODULE_AUTHOR("Magnus Damm");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.6");
+MODULE_VERSION("0.1.0");
 MODULE_ALIAS("platform:sh_mobile_ceu");
diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c
index 09cb4fc..05dd21a 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_csi2.c
@@ -36,7 +36,6 @@
 
 struct sh_csi2 {
 	struct v4l2_subdev		subdev;
-	struct list_head		list;
 	unsigned int			irq;
 	unsigned long			mipi_flags;
 	void __iomem			*base;
@@ -44,6 +43,8 @@
 	struct sh_csi2_client_config	*client;
 };
 
+static void sh_csi2_hwinit(struct sh_csi2 *priv);
+
 static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
 			   struct v4l2_mbus_framefmt *mf)
 {
@@ -132,10 +133,58 @@
 static int sh_csi2_g_mbus_config(struct v4l2_subdev *sd,
 				 struct v4l2_mbus_config *cfg)
 {
-	cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
-		V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
-		V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH;
-	cfg->type = V4L2_MBUS_PARALLEL;
+	struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
+
+	if (!priv->mipi_flags) {
+		struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd);
+		struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
+		struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
+		unsigned long common_flags, csi2_flags;
+		struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,};
+		int ret;
+
+		/* Check if we can support this camera */
+		csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
+			V4L2_MBUS_CSI2_1_LANE;
+
+		switch (pdata->type) {
+		case SH_CSI2C:
+			if (priv->client->lanes != 1)
+				csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
+			break;
+		case SH_CSI2I:
+			switch (priv->client->lanes) {
+			default:
+				csi2_flags |= V4L2_MBUS_CSI2_4_LANE;
+			case 3:
+				csi2_flags |= V4L2_MBUS_CSI2_3_LANE;
+			case 2:
+				csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
+			}
+		}
+
+		ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &client_cfg);
+		if (ret == -ENOIOCTLCMD)
+			common_flags = csi2_flags;
+		else if (!ret)
+			common_flags = soc_mbus_config_compatible(&client_cfg,
+								  csi2_flags);
+		else
+			common_flags = 0;
+
+		if (!common_flags)
+			return -EINVAL;
+
+		/* All good: camera MIPI configuration supported */
+		priv->mipi_flags = common_flags;
+	}
+
+	if (cfg) {
+		cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
+			V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+			V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH;
+		cfg->type = V4L2_MBUS_PARALLEL;
+	}
 
 	return 0;
 }
@@ -146,8 +195,17 @@
 	struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
 	struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd);
 	struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
-	struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,
-					      .flags = priv->mipi_flags};
+	struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,};
+	int ret = sh_csi2_g_mbus_config(sd, NULL);
+
+	if (ret < 0)
+		return ret;
+
+	pm_runtime_get_sync(&priv->pdev->dev);
+
+	sh_csi2_hwinit(priv);
+
+	client_cfg.flags = priv->mipi_flags;
 
 	return v4l2_subdev_call(client_sd, video, s_mbus_config, &client_cfg);
 }
@@ -202,19 +260,19 @@
 
 static int sh_csi2_client_connect(struct sh_csi2 *priv)
 {
-	struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
-	struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev);
-	struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
 	struct device *dev = v4l2_get_subdevdata(&priv->subdev);
-	struct v4l2_mbus_config cfg;
-	unsigned long common_flags, csi2_flags;
-	int i, ret;
+	struct sh_csi2_pdata *pdata = dev->platform_data;
+	struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev);
+	int i;
 
 	if (priv->client)
 		return -EBUSY;
 
 	for (i = 0; i < pdata->num_clients; i++)
-		if (&pdata->clients[i].pdev->dev == icd->pdev)
+		if ((pdata->clients[i].pdev &&
+		     &pdata->clients[i].pdev->dev == icd->pdev) ||
+		    (icd->control &&
+		     strcmp(pdata->clients[i].name, dev_name(icd->control))))
 			break;
 
 	dev_dbg(dev, "%s(%p): found #%d\n", __func__, dev, i);
@@ -222,46 +280,8 @@
 	if (i == pdata->num_clients)
 		return -ENODEV;
 
-	/* Check if we can support this camera */
-	csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | V4L2_MBUS_CSI2_1_LANE;
-
-	switch (pdata->type) {
-	case SH_CSI2C:
-		if (pdata->clients[i].lanes != 1)
-			csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
-		break;
-	case SH_CSI2I:
-		switch (pdata->clients[i].lanes) {
-		default:
-			csi2_flags |= V4L2_MBUS_CSI2_4_LANE;
-		case 3:
-			csi2_flags |= V4L2_MBUS_CSI2_3_LANE;
-		case 2:
-			csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
-		}
-	}
-
-	cfg.type = V4L2_MBUS_CSI2;
-	ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &cfg);
-	if (ret == -ENOIOCTLCMD)
-		common_flags = csi2_flags;
-	else if (!ret)
-		common_flags = soc_mbus_config_compatible(&cfg,
-							  csi2_flags);
-	else
-		common_flags = 0;
-
-	if (!common_flags)
-		return -EINVAL;
-
-	/* All good: camera MIPI configuration supported */
-	priv->mipi_flags = common_flags;
 	priv->client = pdata->clients + i;
 
-	pm_runtime_get_sync(dev);
-
-	sh_csi2_hwinit(priv);
-
 	return 0;
 }
 
@@ -304,11 +324,18 @@
 	/* Platform data specify the PHY, lanes, ECC, CRC */
 	struct sh_csi2_pdata *pdata = pdev->dev.platform_data;
 
+	if (!pdata)
+		return -EINVAL;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_csi2), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	/* Interrupt unused so far */
 	irq = platform_get_irq(pdev, 0);
 
-	if (!res || (int)irq <= 0 || !pdata) {
+	if (!res || (int)irq <= 0) {
 		dev_err(&pdev->dev, "Not enough CSI2 platform resources.\n");
 		return -ENODEV;
 	}
@@ -319,10 +346,6 @@
 		return -EINVAL;
 	}
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_csi2), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
 	priv->irq = irq;
 
 	priv->base = devm_ioremap_resource(&pdev->dev, res);
@@ -330,37 +353,35 @@
 		return PTR_ERR(priv->base);
 
 	priv->pdev = pdev;
-	platform_set_drvdata(pdev, priv);
+	priv->subdev.owner = THIS_MODULE;
+	priv->subdev.dev = &pdev->dev;
+	platform_set_drvdata(pdev, &priv->subdev);
 
 	v4l2_subdev_init(&priv->subdev, &sh_csi2_subdev_ops);
 	v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
 
 	snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.mipi-csi",
-		 dev_name(pdata->v4l2_dev->dev));
-	ret = v4l2_device_register_subdev(pdata->v4l2_dev, &priv->subdev);
-	dev_dbg(&pdev->dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret);
+		 dev_name(&pdev->dev));
+
+	ret = v4l2_async_register_subdev(&priv->subdev);
 	if (ret < 0)
-		goto esdreg;
+		return ret;
 
 	pm_runtime_enable(&pdev->dev);
 
 	dev_dbg(&pdev->dev, "CSI2 probed.\n");
 
 	return 0;
-
-esdreg:
-	platform_set_drvdata(pdev, NULL);
-
-	return ret;
 }
 
 static int sh_csi2_remove(struct platform_device *pdev)
 {
-	struct sh_csi2 *priv = platform_get_drvdata(pdev);
+	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
+	struct sh_csi2 *priv = container_of(subdev, struct sh_csi2, subdev);
 
-	v4l2_device_unregister_subdev(&priv->subdev);
+	v4l2_async_unregister_subdev(&priv->subdev);
+	v4l2_device_unregister_subdev(subdev);
 	pm_runtime_disable(&pdev->dev);
-	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 3a4efbd..2dd0e52 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -21,21 +21,23 @@
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/list.h>
-#include <linux/mutex.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
-#include <linux/pm_runtime.h>
 #include <linux/vmalloc.h>
 
 #include <media/soc_camera.h>
+#include <media/soc_mediabus.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-clk.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-dev.h>
 #include <media/videobuf-core.h>
 #include <media/videobuf2-core.h>
-#include <media/soc_mediabus.h>
 
 /* Default to VGA resolution */
 #define DEFAULT_WIDTH	640
@@ -46,17 +48,39 @@
 	 (icd)->vb_vidq.streaming :			\
 	 vb2_is_streaming(&(icd)->vb2_vidq))
 
+#define MAP_MAX_NUM 32
+static DECLARE_BITMAP(device_map, MAP_MAX_NUM);
 static LIST_HEAD(hosts);
 static LIST_HEAD(devices);
-static DEFINE_MUTEX(list_lock);		/* Protects the list of hosts */
+/*
+ * Protects lists and bitmaps of hosts and devices.
+ * Lock nesting: Ok to take ->host_lock under list_lock.
+ */
+static DEFINE_MUTEX(list_lock);
 
-int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd)
+struct soc_camera_async_client {
+	struct v4l2_async_subdev *sensor;
+	struct v4l2_async_notifier notifier;
+	struct platform_device *pdev;
+	struct list_head list;		/* needed for clean up */
+};
+
+static int soc_camera_video_start(struct soc_camera_device *icd);
+static int video_dev_create(struct soc_camera_device *icd);
+
+int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+			struct v4l2_clk *clk)
 {
-	int ret = regulator_bulk_enable(ssdd->num_regulators,
+	int ret = clk ? v4l2_clk_enable(clk) : 0;
+	if (ret < 0) {
+		dev_err(dev, "Cannot enable clock: %d\n", ret);
+		return ret;
+	}
+	ret = regulator_bulk_enable(ssdd->num_regulators,
 					ssdd->regulators);
 	if (ret < 0) {
 		dev_err(dev, "Cannot enable regulators\n");
-		return ret;
+		goto eregenable;
 	}
 
 	if (ssdd->power) {
@@ -64,16 +88,25 @@
 		if (ret < 0) {
 			dev_err(dev,
 				"Platform failed to power-on the camera.\n");
-			regulator_bulk_disable(ssdd->num_regulators,
-					       ssdd->regulators);
+			goto epwron;
 		}
 	}
 
+	return 0;
+
+epwron:
+	regulator_bulk_disable(ssdd->num_regulators,
+			       ssdd->regulators);
+eregenable:
+	if (clk)
+		v4l2_clk_disable(clk);
+
 	return ret;
 }
 EXPORT_SYMBOL(soc_camera_power_on);
 
-int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd)
+int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+			 struct v4l2_clk *clk)
 {
 	int ret = 0;
 	int err;
@@ -94,10 +127,21 @@
 		ret = ret ? : err;
 	}
 
+	if (clk)
+		v4l2_clk_disable(clk);
+
 	return ret;
 }
 EXPORT_SYMBOL(soc_camera_power_off);
 
+int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd)
+{
+
+	return devm_regulator_bulk_get(dev, ssdd->num_regulators,
+				       ssdd->regulators);
+}
+EXPORT_SYMBOL(soc_camera_power_init);
+
 static int __soc_camera_power_on(struct soc_camera_device *icd)
 {
 	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
@@ -235,7 +279,6 @@
 
 	/* default is camera */
 	inp->type = V4L2_INPUT_TYPE_CAMERA;
-	inp->std  = V4L2_STD_UNKNOWN;
 	strcpy(inp->name, "Camera");
 
 	return 0;
@@ -505,6 +548,58 @@
 	return ici->ops->set_bus_param(icd);
 }
 
+static int soc_camera_add_device(struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	int ret;
+
+	if (ici->icd)
+		return -EBUSY;
+
+	if (!icd->clk) {
+		mutex_lock(&ici->clk_lock);
+		ret = ici->ops->clock_start(ici);
+		mutex_unlock(&ici->clk_lock);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (ici->ops->add) {
+		ret = ici->ops->add(icd);
+		if (ret < 0)
+			goto eadd;
+	}
+
+	ici->icd = icd;
+
+	return 0;
+
+eadd:
+	if (!icd->clk) {
+		mutex_lock(&ici->clk_lock);
+		ici->ops->clock_stop(ici);
+		mutex_unlock(&ici->clk_lock);
+	}
+	return ret;
+}
+
+static void soc_camera_remove_device(struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+
+	if (WARN_ON(icd != ici->icd))
+		return;
+
+	if (ici->ops->remove)
+		ici->ops->remove(icd);
+	if (!icd->clk) {
+		mutex_lock(&ici->clk_lock);
+		ici->ops->clock_stop(ici);
+		mutex_unlock(&ici->clk_lock);
+	}
+	ici->icd = NULL;
+}
+
 static int soc_camera_open(struct file *file)
 {
 	struct video_device *vdev = video_devdata(file);
@@ -525,7 +620,7 @@
 		return -ENODEV;
 	}
 
-	icd = dev_get_drvdata(vdev->parent);
+	icd = video_get_drvdata(vdev);
 	ici = to_soc_camera_host(icd->parent);
 
 	ret = try_module_get(ici->ops->owner) ? 0 : -ENODEV;
@@ -568,7 +663,7 @@
 		if (sdesc->subdev_desc.reset)
 			sdesc->subdev_desc.reset(icd->pdev);
 
-		ret = ici->ops->add(icd);
+		ret = soc_camera_add_device(icd);
 		if (ret < 0) {
 			dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret);
 			goto eiciadd;
@@ -610,8 +705,8 @@
 	return 0;
 
 	/*
-	 * First four errors are entered with the .host_lock held
-	 * and use_count == 1
+	 * All errors are entered with the .host_lock held, first four also
+	 * with use_count == 1
 	 */
 einitvb:
 esfmt:
@@ -619,7 +714,7 @@
 eresume:
 	__soc_camera_power_off(icd);
 epower:
-	ici->ops->remove(icd);
+	soc_camera_remove_device(icd);
 eiciadd:
 	icd->use_count--;
 	mutex_unlock(&ici->host_lock);
@@ -645,7 +740,7 @@
 			vb2_queue_release(&icd->vb2_vidq);
 		__soc_camera_power_off(icd);
 
-		ici->ops->remove(icd);
+		soc_camera_remove_device(icd);
 	}
 
 	if (icd->streamer == file)
@@ -1036,36 +1131,8 @@
 	return -ENOIOCTLCMD;
 }
 
-static int soc_camera_g_chip_ident(struct file *file, void *fh,
-				   struct v4l2_dbg_chip_ident *id)
-{
-	struct soc_camera_device *icd = file->private_data;
-	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
-	return v4l2_subdev_call(sd, core, g_chip_ident, id);
-}
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int soc_camera_g_register(struct file *file, void *fh,
-				 struct v4l2_dbg_register *reg)
-{
-	struct soc_camera_device *icd = file->private_data;
-	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
-	return v4l2_subdev_call(sd, core, g_register, reg);
-}
-
-static int soc_camera_s_register(struct file *file, void *fh,
-				 const struct v4l2_dbg_register *reg)
-{
-	struct soc_camera_device *icd = file->private_data;
-	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
-	return v4l2_subdev_call(sd, core, s_register, reg);
-}
-#endif
-
-static int soc_camera_probe(struct soc_camera_device *icd);
+static int soc_camera_probe(struct soc_camera_host *ici,
+			    struct soc_camera_device *icd);
 
 /* So far this function cannot fail */
 static void scan_add_host(struct soc_camera_host *ici)
@@ -1074,38 +1141,215 @@
 
 	mutex_lock(&list_lock);
 
-	list_for_each_entry(icd, &devices, list) {
+	list_for_each_entry(icd, &devices, list)
 		if (icd->iface == ici->nr) {
+			struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
+			struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc;
+
+			/* The camera could have been already on, try to reset */
+			if (ssdd->reset)
+				ssdd->reset(icd->pdev);
+
 			icd->parent = ici->v4l2_dev.dev;
-			soc_camera_probe(icd);
+
+			/* Ignore errors */
+			soc_camera_probe(ici, icd);
 		}
-	}
 
 	mutex_unlock(&list_lock);
 }
 
+/*
+ * It is invalid to call v4l2_clk_enable() after a successful probing
+ * asynchronously outside of V4L2 operations, i.e. with .host_lock not held.
+ */
+static int soc_camera_clk_enable(struct v4l2_clk *clk)
+{
+	struct soc_camera_device *icd = clk->priv;
+	struct soc_camera_host *ici;
+	int ret;
+
+	if (!icd || !icd->parent)
+		return -ENODEV;
+
+	ici = to_soc_camera_host(icd->parent);
+
+	if (!try_module_get(ici->ops->owner))
+		return -ENODEV;
+
+	/*
+	 * If a different client is currently being probed, the host will tell
+	 * you to go
+	 */
+	mutex_lock(&ici->clk_lock);
+	ret = ici->ops->clock_start(ici);
+	mutex_unlock(&ici->clk_lock);
+	return ret;
+}
+
+static void soc_camera_clk_disable(struct v4l2_clk *clk)
+{
+	struct soc_camera_device *icd = clk->priv;
+	struct soc_camera_host *ici;
+
+	if (!icd || !icd->parent)
+		return;
+
+	ici = to_soc_camera_host(icd->parent);
+
+	mutex_lock(&ici->clk_lock);
+	ici->ops->clock_stop(ici);
+	mutex_unlock(&ici->clk_lock);
+
+	module_put(ici->ops->owner);
+}
+
+/*
+ * Eventually, it would be more logical to make the respective host the clock
+ * owner, but then we would have to copy this struct for each ici. Besides, it
+ * would introduce the circular dependency problem, unless we port all client
+ * drivers to release the clock, when not in use.
+ */
+static const struct v4l2_clk_ops soc_camera_clk_ops = {
+	.owner = THIS_MODULE,
+	.enable = soc_camera_clk_enable,
+	.disable = soc_camera_clk_disable,
+};
+
+static int soc_camera_dyn_pdev(struct soc_camera_desc *sdesc,
+			       struct soc_camera_async_client *sasc)
+{
+	struct platform_device *pdev;
+	int ret, i;
+
+	mutex_lock(&list_lock);
+	i = find_first_zero_bit(device_map, MAP_MAX_NUM);
+	if (i < MAP_MAX_NUM)
+		set_bit(i, device_map);
+	mutex_unlock(&list_lock);
+	if (i >= MAP_MAX_NUM)
+		return -ENOMEM;
+
+	pdev = platform_device_alloc("soc-camera-pdrv", i);
+	if (!pdev)
+		return -ENOMEM;
+
+	ret = platform_device_add_data(pdev, sdesc, sizeof(*sdesc));
+	if (ret < 0) {
+		platform_device_put(pdev);
+		return ret;
+	}
+
+	sasc->pdev = pdev;
+
+	return 0;
+}
+
+static struct soc_camera_device *soc_camera_add_pdev(struct soc_camera_async_client *sasc)
+{
+	struct platform_device *pdev = sasc->pdev;
+	int ret;
+
+	ret = platform_device_add(pdev);
+	if (ret < 0 || !pdev->dev.driver)
+		return NULL;
+
+	return platform_get_drvdata(pdev);
+}
+
+/* Locking: called with .host_lock held */
+static int soc_camera_probe_finish(struct soc_camera_device *icd)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct v4l2_mbus_framefmt mf;
+	int ret;
+
+	sd->grp_id = soc_camera_grp_id(icd);
+	v4l2_set_subdev_hostdata(sd, icd);
+
+	ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL);
+	if (ret < 0)
+		return ret;
+
+	ret = soc_camera_add_device(icd);
+	if (ret < 0) {
+		dev_err(icd->pdev, "Couldn't activate the camera: %d\n", ret);
+		return ret;
+	}
+
+	/* At this point client .probe() should have run already */
+	ret = soc_camera_init_user_formats(icd);
+	if (ret < 0)
+		goto eusrfmt;
+
+	icd->field = V4L2_FIELD_ANY;
+
+	ret = soc_camera_video_start(icd);
+	if (ret < 0)
+		goto evidstart;
+
+	/* Try to improve our guess of a reasonable window format */
+	if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
+		icd->user_width		= mf.width;
+		icd->user_height	= mf.height;
+		icd->colorspace		= mf.colorspace;
+		icd->field		= mf.field;
+	}
+	soc_camera_remove_device(icd);
+
+	return 0;
+
+evidstart:
+	soc_camera_free_user_formats(icd);
+eusrfmt:
+	soc_camera_remove_device(icd);
+
+	return ret;
+}
+
 #ifdef CONFIG_I2C_BOARDINFO
-static int soc_camera_init_i2c(struct soc_camera_device *icd,
+static int soc_camera_i2c_init(struct soc_camera_device *icd,
 			       struct soc_camera_desc *sdesc)
 {
 	struct i2c_client *client;
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	struct soc_camera_host *ici;
 	struct soc_camera_host_desc *shd = &sdesc->host_desc;
-	struct i2c_adapter *adap = i2c_get_adapter(shd->i2c_adapter_id);
+	struct i2c_adapter *adap;
 	struct v4l2_subdev *subdev;
+	char clk_name[V4L2_SUBDEV_NAME_SIZE];
+	int ret;
 
+	/* First find out how we link the main client */
+	if (icd->sasc) {
+		/* Async non-OF probing handled by the subdevice list */
+		return -EPROBE_DEFER;
+	}
+
+	ici = to_soc_camera_host(icd->parent);
+	adap = i2c_get_adapter(shd->i2c_adapter_id);
 	if (!adap) {
 		dev_err(icd->pdev, "Cannot get I2C adapter #%d. No driver?\n",
 			shd->i2c_adapter_id);
-		goto ei2cga;
+		return -ENODEV;
 	}
 
 	shd->board_info->platform_data = &sdesc->subdev_desc;
 
+	snprintf(clk_name, sizeof(clk_name), "%d-%04x",
+		 shd->i2c_adapter_id, shd->board_info->addr);
+
+	icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd);
+	if (IS_ERR(icd->clk)) {
+		ret = PTR_ERR(icd->clk);
+		goto eclkreg;
+	}
+
 	subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
 				shd->board_info, NULL);
-	if (!subdev)
+	if (!subdev) {
+		ret = -ENODEV;
 		goto ei2cnd;
+	}
 
 	client = v4l2_get_subdevdata(subdev);
 
@@ -1114,39 +1358,203 @@
 
 	return 0;
 ei2cnd:
+	v4l2_clk_unregister(icd->clk);
+eclkreg:
+	icd->clk = NULL;
 	i2c_put_adapter(adap);
-ei2cga:
-	return -ENODEV;
+	return ret;
 }
 
-static void soc_camera_free_i2c(struct soc_camera_device *icd)
+static void soc_camera_i2c_free(struct soc_camera_device *icd)
 {
 	struct i2c_client *client =
 		to_i2c_client(to_soc_camera_control(icd));
-	struct i2c_adapter *adap = client->adapter;
+	struct i2c_adapter *adap;
 
 	icd->control = NULL;
+	if (icd->sasc)
+		return;
+
+	adap = client->adapter;
 	v4l2_device_unregister_subdev(i2c_get_clientdata(client));
 	i2c_unregister_device(client);
 	i2c_put_adapter(adap);
+	v4l2_clk_unregister(icd->clk);
+	icd->clk = NULL;
+}
+
+/*
+ * V4L2 asynchronous notifier callbacks. They are all called under a v4l2-async
+ * internal global mutex, therefore cannot race against other asynchronous
+ * events. Until notifier->complete() (soc_camera_async_complete()) is called,
+ * the video device node is not registered and no V4L fops can occur. Unloading
+ * of the host driver also calls a v4l2-async function, so also there we're
+ * protected.
+ */
+static int soc_camera_async_bound(struct v4l2_async_notifier *notifier,
+				  struct v4l2_subdev *sd,
+				  struct v4l2_async_subdev *asd)
+{
+	struct soc_camera_async_client *sasc = container_of(notifier,
+					struct soc_camera_async_client, notifier);
+	struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
+
+	if (asd == sasc->sensor && !WARN_ON(icd->control)) {
+		struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+		/*
+		 * Only now we get subdevice-specific information like
+		 * regulators, flags, callbacks, etc.
+		 */
+		if (client) {
+			struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
+			struct soc_camera_subdev_desc *ssdd =
+				soc_camera_i2c_to_desc(client);
+			if (ssdd) {
+				memcpy(&sdesc->subdev_desc, ssdd,
+				       sizeof(sdesc->subdev_desc));
+				if (ssdd->reset)
+					ssdd->reset(icd->pdev);
+			}
+
+			icd->control = &client->dev;
+		}
+	}
+
+	return 0;
+}
+
+static void soc_camera_async_unbind(struct v4l2_async_notifier *notifier,
+				    struct v4l2_subdev *sd,
+				    struct v4l2_async_subdev *asd)
+{
+	struct soc_camera_async_client *sasc = container_of(notifier,
+					struct soc_camera_async_client, notifier);
+	struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
+
+	if (icd->clk) {
+		v4l2_clk_unregister(icd->clk);
+		icd->clk = NULL;
+	}
+}
+
+static int soc_camera_async_complete(struct v4l2_async_notifier *notifier)
+{
+	struct soc_camera_async_client *sasc = container_of(notifier,
+					struct soc_camera_async_client, notifier);
+	struct soc_camera_device *icd = platform_get_drvdata(sasc->pdev);
+
+	if (to_soc_camera_control(icd)) {
+		struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+		int ret;
+
+		mutex_lock(&list_lock);
+		ret = soc_camera_probe(ici, icd);
+		mutex_unlock(&list_lock);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int scan_async_group(struct soc_camera_host *ici,
+			    struct v4l2_async_subdev **asd, unsigned int size)
+{
+	struct soc_camera_async_subdev *sasd;
+	struct soc_camera_async_client *sasc;
+	struct soc_camera_device *icd;
+	struct soc_camera_desc sdesc = {.host_desc.bus_id = ici->nr,};
+	char clk_name[V4L2_SUBDEV_NAME_SIZE];
+	int ret, i;
+
+	/* First look for a sensor */
+	for (i = 0; i < size; i++) {
+		sasd = container_of(asd[i], struct soc_camera_async_subdev, asd);
+		if (sasd->role == SOCAM_SUBDEV_DATA_SOURCE)
+			break;
+	}
+
+	if (i == size || asd[i]->bus_type != V4L2_ASYNC_BUS_I2C) {
+		/* All useless */
+		dev_err(ici->v4l2_dev.dev, "No I2C data source found!\n");
+		return -ENODEV;
+	}
+
+	/* Or shall this be managed by the soc-camera device? */
+	sasc = devm_kzalloc(ici->v4l2_dev.dev, sizeof(*sasc), GFP_KERNEL);
+	if (!sasc)
+		return -ENOMEM;
+
+	/* HACK: just need a != NULL */
+	sdesc.host_desc.board_info = ERR_PTR(-ENODATA);
+
+	ret = soc_camera_dyn_pdev(&sdesc, sasc);
+	if (ret < 0)
+		return ret;
+
+	sasc->sensor = &sasd->asd;
+
+	icd = soc_camera_add_pdev(sasc);
+	if (!icd) {
+		platform_device_put(sasc->pdev);
+		return -ENOMEM;
+	}
+
+	sasc->notifier.subdev = asd;
+	sasc->notifier.num_subdevs = size;
+	sasc->notifier.bound = soc_camera_async_bound;
+	sasc->notifier.unbind = soc_camera_async_unbind;
+	sasc->notifier.complete = soc_camera_async_complete;
+
+	icd->sasc = sasc;
+	icd->parent = ici->v4l2_dev.dev;
+
+	snprintf(clk_name, sizeof(clk_name), "%d-%04x",
+		 sasd->asd.match.i2c.adapter_id, sasd->asd.match.i2c.address);
+
+	icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd);
+	if (IS_ERR(icd->clk)) {
+		ret = PTR_ERR(icd->clk);
+		goto eclkreg;
+	}
+
+	ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier);
+	if (!ret)
+		return 0;
+
+	v4l2_clk_unregister(icd->clk);
+eclkreg:
+	icd->clk = NULL;
+	platform_device_unregister(sasc->pdev);
+	dev_err(ici->v4l2_dev.dev, "group probe failed: %d\n", ret);
+
+	return ret;
+}
+
+static void scan_async_host(struct soc_camera_host *ici)
+{
+	struct v4l2_async_subdev **asd;
+	int j;
+
+	for (j = 0, asd = ici->asd; ici->asd_sizes[j]; j++) {
+		scan_async_group(ici, asd, ici->asd_sizes[j]);
+		asd += ici->asd_sizes[j];
+	}
 }
 #else
-#define soc_camera_init_i2c(icd, sdesc)	(-ENODEV)
-#define soc_camera_free_i2c(icd)	do {} while (0)
+#define soc_camera_i2c_init(icd, sdesc)	(-ENODEV)
+#define soc_camera_i2c_free(icd)	do {} while (0)
+#define scan_async_host(ici)		do {} while (0)
 #endif
 
-static int soc_camera_video_start(struct soc_camera_device *icd);
-static int video_dev_create(struct soc_camera_device *icd);
 /* Called during host-driver probe */
-static int soc_camera_probe(struct soc_camera_device *icd)
+static int soc_camera_probe(struct soc_camera_host *ici,
+			    struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
 	struct soc_camera_host_desc *shd = &sdesc->host_desc;
-	struct soc_camera_subdev_desc *ssdd = &sdesc->subdev_desc;
 	struct device *control = NULL;
-	struct v4l2_subdev *sd;
-	struct v4l2_mbus_framefmt mf;
 	int ret;
 
 	dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev));
@@ -1162,30 +1570,32 @@
 	if (ret < 0)
 		return ret;
 
-	/* The camera could have been already on, try to reset */
-	if (ssdd->reset)
-		ssdd->reset(icd->pdev);
-
-	mutex_lock(&ici->host_lock);
-	ret = ici->ops->add(icd);
-	mutex_unlock(&ici->host_lock);
-	if (ret < 0)
-		goto eadd;
-
 	/* Must have icd->vdev before registering the device */
 	ret = video_dev_create(icd);
 	if (ret < 0)
 		goto evdc;
 
+	/*
+	 * ..._video_start() will create a device node, video_register_device()
+	 * itself is protected against concurrent open() calls, but we also have
+	 * to protect our data also during client probing.
+	 */
+
 	/* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
 	if (shd->board_info) {
-		ret = soc_camera_init_i2c(icd, sdesc);
-		if (ret < 0)
-			goto eadddev;
+		ret = soc_camera_i2c_init(icd, sdesc);
+		if (ret < 0 && ret != -EPROBE_DEFER)
+			goto eadd;
 	} else if (!shd->add_device || !shd->del_device) {
 		ret = -EINVAL;
-		goto eadddev;
+		goto eadd;
 	} else {
+		mutex_lock(&ici->clk_lock);
+		ret = ici->ops->clock_start(ici);
+		mutex_unlock(&ici->clk_lock);
+		if (ret < 0)
+			goto eadd;
+
 		if (shd->module_name)
 			ret = request_module(shd->module_name);
 
@@ -1206,81 +1616,49 @@
 		}
 	}
 
-	sd = soc_camera_to_subdev(icd);
-	sd->grp_id = soc_camera_grp_id(icd);
-	v4l2_set_subdev_hostdata(sd, icd);
-
-	ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler, NULL);
-	if (ret < 0)
-		goto ectrl;
-
-	/* At this point client .probe() should have run already */
-	ret = soc_camera_init_user_formats(icd);
-	if (ret < 0)
-		goto eiufmt;
-
-	icd->field = V4L2_FIELD_ANY;
-
-	/*
-	 * ..._video_start() will create a device node, video_register_device()
-	 * itself is protected against concurrent open() calls, but we also have
-	 * to protect our data.
-	 */
 	mutex_lock(&ici->host_lock);
-
-	ret = soc_camera_video_start(icd);
-	if (ret < 0)
-		goto evidstart;
-
-	/* Try to improve our guess of a reasonable window format */
-	if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
-		icd->user_width		= mf.width;
-		icd->user_height	= mf.height;
-		icd->colorspace		= mf.colorspace;
-		icd->field		= mf.field;
-	}
-
-	ici->ops->remove(icd);
-
+	ret = soc_camera_probe_finish(icd);
 	mutex_unlock(&ici->host_lock);
+	if (ret < 0)
+		goto efinish;
 
 	return 0;
 
-evidstart:
-	mutex_unlock(&ici->host_lock);
-	soc_camera_free_user_formats(icd);
-eiufmt:
-ectrl:
+efinish:
 	if (shd->board_info) {
-		soc_camera_free_i2c(icd);
+		soc_camera_i2c_free(icd);
 	} else {
 		shd->del_device(icd);
 		module_put(control->driver->owner);
-	}
 enodrv:
 eadddev:
+		mutex_lock(&ici->clk_lock);
+		ici->ops->clock_stop(ici);
+		mutex_unlock(&ici->clk_lock);
+	}
+eadd:
 	video_device_release(icd->vdev);
 	icd->vdev = NULL;
+	if (icd->vdev) {
+		video_device_release(icd->vdev);
+		icd->vdev = NULL;
+	}
 evdc:
-	mutex_lock(&ici->host_lock);
-	ici->ops->remove(icd);
-	mutex_unlock(&ici->host_lock);
-eadd:
 	v4l2_ctrl_handler_free(&icd->ctrl_handler);
 	return ret;
 }
 
 /*
  * This is called on device_unregister, which only means we have to disconnect
- * from the host, but not remove ourselves from the device list
+ * from the host, but not remove ourselves from the device list. With
+ * asynchronous client probing this can also be called without
+ * soc_camera_probe_finish() having run. Careful with clean up.
  */
 static int soc_camera_remove(struct soc_camera_device *icd)
 {
 	struct soc_camera_desc *sdesc = to_soc_camera_desc(icd);
 	struct video_device *vdev = icd->vdev;
 
-	BUG_ON(!icd->parent);
-
 	v4l2_ctrl_handler_free(&icd->ctrl_handler);
 	if (vdev) {
 		video_unregister_device(vdev);
@@ -1288,15 +1666,27 @@
 	}
 
 	if (sdesc->host_desc.board_info) {
-		soc_camera_free_i2c(icd);
+		soc_camera_i2c_free(icd);
 	} else {
-		struct device_driver *drv = to_soc_camera_control(icd)->driver;
+		struct device *dev = to_soc_camera_control(icd);
+		struct device_driver *drv = dev ? dev->driver : NULL;
 		if (drv) {
 			sdesc->host_desc.del_device(icd);
 			module_put(drv->owner);
 		}
 	}
-	soc_camera_free_user_formats(icd);
+
+	if (icd->num_user_formats)
+		soc_camera_free_user_formats(icd);
+
+	if (icd->clk) {
+		/* For the synchronous case */
+		v4l2_clk_unregister(icd->clk);
+		icd->clk = NULL;
+	}
+
+	if (icd->sasc)
+		platform_device_unregister(icd->sasc->pdev);
 
 	return 0;
 }
@@ -1372,8 +1762,8 @@
 	    ((!ici->ops->init_videobuf ||
 	      !ici->ops->reqbufs) &&
 	     !ici->ops->init_videobuf2) ||
-	    !ici->ops->add ||
-	    !ici->ops->remove ||
+	    !ici->ops->clock_start ||
+	    !ici->ops->clock_stop ||
 	    !ici->ops->poll ||
 	    !ici->v4l2_dev.dev)
 		return -EINVAL;
@@ -1407,7 +1797,18 @@
 	mutex_unlock(&list_lock);
 
 	mutex_init(&ici->host_lock);
-	scan_add_host(ici);
+	mutex_init(&ici->clk_lock);
+
+	if (ici->asd_sizes)
+		/*
+		 * No OF, host with a list of subdevices. Don't try to mix
+		 * modes by initialising some groups statically and some
+		 * dynamically!
+		 */
+		scan_async_host(ici);
+	else
+		/* Legacy: static platform devices from board data */
+		scan_add_host(ici);
 
 	return 0;
 
@@ -1420,13 +1821,30 @@
 /* Unregister all clients! */
 void soc_camera_host_unregister(struct soc_camera_host *ici)
 {
-	struct soc_camera_device *icd;
+	struct soc_camera_device *icd, *tmp;
+	struct soc_camera_async_client *sasc;
+	LIST_HEAD(notifiers);
+
+	mutex_lock(&list_lock);
+	list_del(&ici->list);
+	list_for_each_entry(icd, &devices, list)
+		if (icd->iface == ici->nr && icd->sasc) {
+			/* as long as we hold the device, sasc won't be freed */
+			get_device(icd->pdev);
+			list_add(&icd->sasc->list, &notifiers);
+		}
+	mutex_unlock(&list_lock);
+
+	list_for_each_entry(sasc, &notifiers, list) {
+		/* Must call unlocked to avoid AB-BA dead-lock */
+		v4l2_async_notifier_unregister(&sasc->notifier);
+		put_device(&sasc->pdev->dev);
+	}
 
 	mutex_lock(&list_lock);
 
-	list_del(&ici->list);
-	list_for_each_entry(icd, &devices, list)
-		if (icd->iface == ici->nr && to_soc_camera_control(icd))
+	list_for_each_entry_safe(icd, tmp, &devices, list)
+		if (icd->iface == ici->nr)
 			soc_camera_remove(icd);
 
 	mutex_unlock(&list_lock);
@@ -1441,6 +1859,7 @@
 	struct soc_camera_device *ix;
 	int num = -1, i;
 
+	mutex_lock(&list_lock);
 	for (i = 0; i < 256 && num < 0; i++) {
 		num = i;
 		/* Check if this index is available on this interface */
@@ -1452,18 +1871,34 @@
 		}
 	}
 
-	if (num < 0)
+	if (num < 0) {
 		/*
 		 * ok, we have 256 cameras on this host...
 		 * man, stay reasonable...
 		 */
+		mutex_unlock(&list_lock);
 		return -ENOMEM;
+	}
 
 	icd->devnum		= num;
 	icd->use_count		= 0;
 	icd->host_priv		= NULL;
 
+	/*
+	 * Dynamically allocated devices set the bit earlier, but it doesn't hurt setting
+	 * it again
+	 */
+	i = to_platform_device(icd->pdev)->id;
+	if (i < 0)
+		/* One static (legacy) soc-camera platform device */
+		i = 0;
+	if (i >= MAP_MAX_NUM) {
+		mutex_unlock(&list_lock);
+		return -EBUSY;
+	}
+	set_bit(i, device_map);
 	list_add_tail(&icd->list, &devices);
+	mutex_unlock(&list_lock);
 
 	return 0;
 }
@@ -1495,11 +1930,6 @@
 	.vidioc_s_selection	 = soc_camera_s_selection,
 	.vidioc_g_parm		 = soc_camera_g_parm,
 	.vidioc_s_parm		 = soc_camera_s_parm,
-	.vidioc_g_chip_ident     = soc_camera_g_chip_ident,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register	 = soc_camera_g_register,
-	.vidioc_s_register	 = soc_camera_s_register,
-#endif
 };
 
 static int video_dev_create(struct soc_camera_device *icd)
@@ -1512,12 +1942,10 @@
 
 	strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
 
-	vdev->parent		= icd->pdev;
-	vdev->current_norm	= V4L2_STD_UNKNOWN;
+	vdev->v4l2_dev		= &ici->v4l2_dev;
 	vdev->fops		= &soc_camera_fops;
 	vdev->ioctl_ops		= &soc_camera_ioctl_ops;
 	vdev->release		= video_device_release;
-	vdev->tvnorms		= V4L2_STD_UNKNOWN;
 	vdev->ctrl_handler	= &icd->ctrl_handler;
 	vdev->lock		= &ici->host_lock;
 
@@ -1537,6 +1965,7 @@
 	if (!icd->parent)
 		return -ENODEV;
 
+	video_set_drvdata(icd->vdev, icd);
 	ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1);
 	if (ret < 0) {
 		dev_err(icd->pdev, "video_register_device failed: %d\n", ret);
@@ -1563,6 +1992,12 @@
 	if (!icd)
 		return -ENOMEM;
 
+	/*
+	 * In the asynchronous case ssdd->num_regulators == 0 yet, so, the below
+	 * regulator allocation is a dummy. They will be really requested later
+	 * in soc_camera_async_bind(). Also note, that in that case regulators
+	 * are attached to the I2C device and not to the camera platform device.
+	 */
 	ret = devm_regulator_bulk_get(&pdev->dev, ssdd->num_regulators,
 				      ssdd->regulators);
 	if (ret < 0)
@@ -1587,11 +2022,25 @@
 static int soc_camera_pdrv_remove(struct platform_device *pdev)
 {
 	struct soc_camera_device *icd = platform_get_drvdata(pdev);
+	int i;
 
 	if (!icd)
 		return -EINVAL;
 
-	list_del(&icd->list);
+	i = pdev->id;
+	if (i < 0)
+		i = 0;
+
+	/*
+	 * In synchronous mode with static platform devices this is called in a
+	 * loop from drivers/base/dd.c::driver_detach(), no parallel execution,
+	 * no need to lock. In asynchronous case the caller -
+	 * soc_camera_host_unregister() - already holds the lock
+	 */
+	if (test_bit(i, device_map)) {
+		clear_bit(i, device_map);
+		list_del(&icd->list);
+	}
 
 	return 0;
 }
diff --git a/drivers/media/platform/soc_camera/soc_camera_platform.c b/drivers/media/platform/soc_camera/soc_camera_platform.c
index 1b7a88c..ceaddfb 100644
--- a/drivers/media/platform/soc_camera/soc_camera_platform.c
+++ b/drivers/media/platform/soc_camera/soc_camera_platform.c
@@ -54,7 +54,7 @@
 {
 	struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
 
-	return soc_camera_set_power(p->icd->control, &p->icd->sdesc->subdev_desc, on);
+	return soc_camera_set_power(p->icd->control, &p->icd->sdesc->subdev_desc, NULL, on);
 }
 
 static struct v4l2_subdev_core_ops platform_subdev_core_ops = {
@@ -137,7 +137,6 @@
 	struct soc_camera_platform_priv *priv;
 	struct soc_camera_platform_info *p = pdev->dev.platform_data;
 	struct soc_camera_device *icd;
-	int ret;
 
 	if (!p)
 		return -EINVAL;
@@ -165,15 +164,7 @@
 	v4l2_set_subdevdata(&priv->subdev, p);
 	strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);
 
-	ret = v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
-	if (ret)
-		goto evdrs;
-
-	return ret;
-
-evdrs:
-	platform_set_drvdata(pdev, NULL);
-	return ret;
+	return v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
 }
 
 static int soc_camera_platform_remove(struct platform_device *pdev)
@@ -183,7 +174,6 @@
 
 	p->icd->control = NULL;
 	v4l2_device_unregister_subdev(&priv->subdev);
-	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
new file mode 100644
index 0000000..cbd3a34
--- /dev/null
+++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
@@ -0,0 +1,402 @@
+/*
+ * soc-camera generic scaling-cropping manipulation functions
+ *
+ * Copyright (C) 2013 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+
+#include <media/soc_camera.h>
+#include <media/v4l2-common.h>
+
+#include "soc_scale_crop.h"
+
+#ifdef DEBUG_GEOMETRY
+#define dev_geo	dev_info
+#else
+#define dev_geo	dev_dbg
+#endif
+
+/* Check if any dimension of r1 is smaller than respective one of r2 */
+static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
+{
+	return r1->width < r2->width || r1->height < r2->height;
+}
+
+/* Check if r1 fails to cover r2 */
+static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
+{
+	return r1->left > r2->left || r1->top > r2->top ||
+		r1->left + r1->width < r2->left + r2->width ||
+		r1->top + r1->height < r2->top + r2->height;
+}
+
+/* Get and store current client crop */
+int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
+{
+	struct v4l2_crop crop;
+	struct v4l2_cropcap cap;
+	int ret;
+
+	crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, g_crop, &crop);
+	if (!ret) {
+		*rect = crop.c;
+		return ret;
+	}
+
+	/* Camera driver doesn't support .g_crop(), assume default rectangle */
+	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+	if (!ret)
+		*rect = cap.defrect;
+
+	return ret;
+}
+EXPORT_SYMBOL(soc_camera_client_g_rect);
+
+/* Client crop has changed, update our sub-rectangle to remain within the area */
+static void update_subrect(struct v4l2_rect *rect, struct v4l2_rect *subrect)
+{
+	if (rect->width < subrect->width)
+		subrect->width = rect->width;
+
+	if (rect->height < subrect->height)
+		subrect->height = rect->height;
+
+	if (rect->left > subrect->left)
+		subrect->left = rect->left;
+	else if (rect->left + rect->width >
+		 subrect->left + subrect->width)
+		subrect->left = rect->left + rect->width -
+			subrect->width;
+
+	if (rect->top > subrect->top)
+		subrect->top = rect->top;
+	else if (rect->top + rect->height >
+		 subrect->top + subrect->height)
+		subrect->top = rect->top + rect->height -
+			subrect->height;
+}
+
+/*
+ * The common for both scaling and cropping iterative approach is:
+ * 1. try if the client can produce exactly what requested by the user
+ * 2. if (1) failed, try to double the client image until we get one big enough
+ * 3. if (2) failed, try to request the maximum image
+ */
+int soc_camera_client_s_crop(struct v4l2_subdev *sd,
+			struct v4l2_crop *crop, struct v4l2_crop *cam_crop,
+			struct v4l2_rect *target_rect, struct v4l2_rect *subrect)
+{
+	struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
+	struct device *dev = sd->v4l2_dev->dev;
+	struct v4l2_cropcap cap;
+	int ret;
+	unsigned int width, height;
+
+	v4l2_subdev_call(sd, video, s_crop, crop);
+	ret = soc_camera_client_g_rect(sd, cam_rect);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Now cam_crop contains the current camera input rectangle, and it must
+	 * be within camera cropcap bounds
+	 */
+	if (!memcmp(rect, cam_rect, sizeof(*rect))) {
+		/* Even if camera S_CROP failed, but camera rectangle matches */
+		dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n",
+			rect->width, rect->height, rect->left, rect->top);
+		*target_rect = *cam_rect;
+		return 0;
+	}
+
+	/* Try to fix cropping, that camera hasn't managed to set */
+	dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n",
+		cam_rect->width, cam_rect->height,
+		cam_rect->left, cam_rect->top,
+		rect->width, rect->height, rect->left, rect->top);
+
+	/* We need sensor maximum rectangle */
+	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+	if (ret < 0)
+		return ret;
+
+	/* Put user requested rectangle within sensor bounds */
+	soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
+			      cap.bounds.width);
+	soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
+			      cap.bounds.height);
+
+	/*
+	 * Popular special case - some cameras can only handle fixed sizes like
+	 * QVGA, VGA,... Take care to avoid infinite loop.
+	 */
+	width = max(cam_rect->width, 2);
+	height = max(cam_rect->height, 2);
+
+	/*
+	 * Loop as long as sensor is not covering the requested rectangle and
+	 * is still within its bounds
+	 */
+	while (!ret && (is_smaller(cam_rect, rect) ||
+			is_inside(cam_rect, rect)) &&
+	       (cap.bounds.width > width || cap.bounds.height > height)) {
+
+		width *= 2;
+		height *= 2;
+
+		cam_rect->width = width;
+		cam_rect->height = height;
+
+		/*
+		 * We do not know what capabilities the camera has to set up
+		 * left and top borders. We could try to be smarter in iterating
+		 * them, e.g., if camera current left is to the right of the
+		 * target left, set it to the middle point between the current
+		 * left and minimum left. But that would add too much
+		 * complexity: we would have to iterate each border separately.
+		 * Instead we just drop to the left and top bounds.
+		 */
+		if (cam_rect->left > rect->left)
+			cam_rect->left = cap.bounds.left;
+
+		if (cam_rect->left + cam_rect->width < rect->left + rect->width)
+			cam_rect->width = rect->left + rect->width -
+				cam_rect->left;
+
+		if (cam_rect->top > rect->top)
+			cam_rect->top = cap.bounds.top;
+
+		if (cam_rect->top + cam_rect->height < rect->top + rect->height)
+			cam_rect->height = rect->top + rect->height -
+				cam_rect->top;
+
+		v4l2_subdev_call(sd, video, s_crop, cam_crop);
+		ret = soc_camera_client_g_rect(sd, cam_rect);
+		dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret,
+			cam_rect->width, cam_rect->height,
+			cam_rect->left, cam_rect->top);
+	}
+
+	/* S_CROP must not modify the rectangle */
+	if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
+		/*
+		 * The camera failed to configure a suitable cropping,
+		 * we cannot use the current rectangle, set to max
+		 */
+		*cam_rect = cap.bounds;
+		v4l2_subdev_call(sd, video, s_crop, cam_crop);
+		ret = soc_camera_client_g_rect(sd, cam_rect);
+		dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret,
+			cam_rect->width, cam_rect->height,
+			cam_rect->left, cam_rect->top);
+	}
+
+	if (!ret) {
+		*target_rect = *cam_rect;
+		update_subrect(target_rect, subrect);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(soc_camera_client_s_crop);
+
+/* Iterative s_mbus_fmt, also updates cached client crop on success */
+static int client_s_fmt(struct soc_camera_device *icd,
+			struct v4l2_rect *rect, struct v4l2_rect *subrect,
+			unsigned int max_width, unsigned int max_height,
+			struct v4l2_mbus_framefmt *mf, bool host_can_scale)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct device *dev = icd->parent;
+	unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
+	struct v4l2_cropcap cap;
+	bool host_1to1;
+	int ret;
+
+	ret = v4l2_device_call_until_err(sd->v4l2_dev,
+					 soc_camera_grp_id(icd), video,
+					 s_mbus_fmt, mf);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
+
+	if (width == mf->width && height == mf->height) {
+		/* Perfect! The client has done it all. */
+		host_1to1 = true;
+		goto update_cache;
+	}
+
+	host_1to1 = false;
+	if (!host_can_scale)
+		goto update_cache;
+
+	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+	if (ret < 0)
+		return ret;
+
+	if (max_width > cap.bounds.width)
+		max_width = cap.bounds.width;
+	if (max_height > cap.bounds.height)
+		max_height = cap.bounds.height;
+
+	/* Camera set a format, but geometry is not precise, try to improve */
+	tmp_w = mf->width;
+	tmp_h = mf->height;
+
+	/* width <= max_width && height <= max_height - guaranteed by try_fmt */
+	while ((width > tmp_w || height > tmp_h) &&
+	       tmp_w < max_width && tmp_h < max_height) {
+		tmp_w = min(2 * tmp_w, max_width);
+		tmp_h = min(2 * tmp_h, max_height);
+		mf->width = tmp_w;
+		mf->height = tmp_h;
+		ret = v4l2_device_call_until_err(sd->v4l2_dev,
+					soc_camera_grp_id(icd), video,
+					s_mbus_fmt, mf);
+		dev_geo(dev, "Camera scaled to %ux%u\n",
+			mf->width, mf->height);
+		if (ret < 0) {
+			/* This shouldn't happen */
+			dev_err(dev, "Client failed to set format: %d\n", ret);
+			return ret;
+		}
+	}
+
+update_cache:
+	/* Update cache */
+	ret = soc_camera_client_g_rect(sd, rect);
+	if (ret < 0)
+		return ret;
+
+	if (host_1to1)
+		*subrect = *rect;
+	else
+		update_subrect(rect, subrect);
+
+	return 0;
+}
+
+/**
+ * @icd		- soc-camera device
+ * @rect	- camera cropping window
+ * @subrect	- part of rect, sent to the user
+ * @mf		- in- / output camera output window
+ * @width	- on input: max host input width
+ *		  on output: user width, mapped back to input
+ * @height	- on input: max host input height
+ *		  on output: user height, mapped back to input
+ * @host_can_scale - host can scale this pixel format
+ * @shift	- shift, used for scaling
+ */
+int soc_camera_client_scale(struct soc_camera_device *icd,
+			struct v4l2_rect *rect, struct v4l2_rect *subrect,
+			struct v4l2_mbus_framefmt *mf,
+			unsigned int *width, unsigned int *height,
+			bool host_can_scale, unsigned int shift)
+{
+	struct device *dev = icd->parent;
+	struct v4l2_mbus_framefmt mf_tmp = *mf;
+	unsigned int scale_h, scale_v;
+	int ret;
+
+	/*
+	 * 5. Apply iterative camera S_FMT for camera user window (also updates
+	 *    client crop cache and the imaginary sub-rectangle).
+	 */
+	ret = client_s_fmt(icd, rect, subrect, *width, *height,
+			   &mf_tmp, host_can_scale);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "5: camera scaled to %ux%u\n",
+		mf_tmp.width, mf_tmp.height);
+
+	/* 6. Retrieve camera output window (g_fmt) */
+
+	/* unneeded - it is already in "mf_tmp" */
+
+	/* 7. Calculate new client scales. */
+	scale_h = soc_camera_calc_scale(rect->width, shift, mf_tmp.width);
+	scale_v = soc_camera_calc_scale(rect->height, shift, mf_tmp.height);
+
+	mf->width	= mf_tmp.width;
+	mf->height	= mf_tmp.height;
+	mf->colorspace	= mf_tmp.colorspace;
+
+	/*
+	 * 8. Calculate new host crop - apply camera scales to previously
+	 *    updated "effective" crop.
+	 */
+	*width = soc_camera_shift_scale(subrect->width, shift, scale_h);
+	*height = soc_camera_shift_scale(subrect->height, shift, scale_v);
+
+	dev_geo(dev, "8: new client sub-window %ux%u\n", *width, *height);
+
+	return 0;
+}
+EXPORT_SYMBOL(soc_camera_client_scale);
+
+/*
+ * Calculate real client output window by applying new scales to the current
+ * client crop. New scales are calculated from the requested output format and
+ * host crop, mapped backed onto the client input (subrect).
+ */
+void soc_camera_calc_client_output(struct soc_camera_device *icd,
+		struct v4l2_rect *rect, struct v4l2_rect *subrect,
+		const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf,
+		unsigned int shift)
+{
+	struct device *dev = icd->parent;
+	unsigned int scale_v, scale_h;
+
+	if (subrect->width == rect->width &&
+	    subrect->height == rect->height) {
+		/* No sub-cropping */
+		mf->width	= pix->width;
+		mf->height	= pix->height;
+		return;
+	}
+
+	/* 1.-2. Current camera scales and subwin - cached. */
+
+	dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
+		subrect->width, subrect->height,
+		subrect->left, subrect->top);
+
+	/*
+	 * 3. Calculate new combined scales from input sub-window to requested
+	 *    user window.
+	 */
+
+	/*
+	 * TODO: CEU cannot scale images larger than VGA to smaller than SubQCIF
+	 * (128x96) or larger than VGA. This and similar limitations have to be
+	 * taken into account here.
+	 */
+	scale_h = soc_camera_calc_scale(subrect->width, shift, pix->width);
+	scale_v = soc_camera_calc_scale(subrect->height, shift, pix->height);
+
+	dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
+
+	/*
+	 * 4. Calculate desired client output window by applying combined scales
+	 *    to client (real) input window.
+	 */
+	mf->width = soc_camera_shift_scale(rect->width, shift, scale_h);
+	mf->height = soc_camera_shift_scale(rect->height, shift, scale_v);
+}
+EXPORT_SYMBOL(soc_camera_calc_client_output);
diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.h b/drivers/media/platform/soc_camera/soc_scale_crop.h
new file mode 100644
index 0000000..184a30d
--- /dev/null
+++ b/drivers/media/platform/soc_camera/soc_scale_crop.h
@@ -0,0 +1,47 @@
+/*
+ * soc-camera generic scaling-cropping manipulation functions
+ *
+ * Copyright (C) 2013 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef SOC_SCALE_CROP_H
+#define SOC_SCALE_CROP_H
+
+#include <linux/kernel.h>
+
+struct soc_camera_device;
+
+struct v4l2_crop;
+struct v4l2_mbus_framefmt;
+struct v4l2_pix_format;
+struct v4l2_rect;
+struct v4l2_subdev;
+
+static inline unsigned int soc_camera_shift_scale(unsigned int size,
+				unsigned int shift, unsigned int scale)
+{
+	return DIV_ROUND_CLOSEST(size << shift, scale);
+}
+
+#define soc_camera_calc_scale(in, shift, out) soc_camera_shift_scale(in, shift, out)
+
+int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
+int soc_camera_client_s_crop(struct v4l2_subdev *sd,
+			struct v4l2_crop *crop, struct v4l2_crop *cam_crop,
+			struct v4l2_rect *target_rect, struct v4l2_rect *subrect);
+int soc_camera_client_scale(struct soc_camera_device *icd,
+			struct v4l2_rect *rect, struct v4l2_rect *subrect,
+			struct v4l2_mbus_framefmt *mf,
+			unsigned int *width, unsigned int *height,
+			bool host_can_scale, unsigned int shift);
+void soc_camera_calc_client_output(struct soc_camera_device *icd,
+		struct v4l2_rect *rect, struct v4l2_rect *subrect,
+		const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf,
+		unsigned int shift);
+
+#endif
diff --git a/drivers/media/platform/timblogiw.c b/drivers/media/platform/timblogiw.c
index a2f7bdd..b557caf 100644
--- a/drivers/media/platform/timblogiw.c
+++ b/drivers/media/platform/timblogiw.c
@@ -239,13 +239,12 @@
 	struct video_device *vdev = video_devdata(file);
 
 	dev_dbg(&vdev->dev, "%s: Entry\n",  __func__);
-	memset(cap, 0, sizeof(*cap));
 	strncpy(cap->card, TIMBLOGIWIN_NAME, sizeof(cap->card)-1);
 	strncpy(cap->driver, DRIVER_NAME, sizeof(cap->driver) - 1);
-	strlcpy(cap->bus_info, vdev->name, sizeof(cap->bus_info));
-	cap->version = TIMBLOGIW_VERSION_CODE;
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", vdev->name);
+	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
 		V4L2_CAP_READWRITE;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 
 	return 0;
 }
@@ -834,11 +833,9 @@
 		goto err_request;
 	}
 
-
 	return 0;
 
 err_request:
-	platform_set_drvdata(pdev, NULL);
 	v4l2_device_unregister(&lw->v4l2_dev);
 err_register:
 	kfree(lw);
@@ -858,8 +855,6 @@
 
 	kfree(lw);
 
-	platform_set_drvdata(pdev, NULL);
-
 	return 0;
 }
 
diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c
index a794cd6..b4f9d03 100644
--- a/drivers/media/platform/via-camera.c
+++ b/drivers/media/platform/via-camera.c
@@ -17,7 +17,6 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/ov7670.h>
 #include <media/videobuf-dma-sg.h>
@@ -805,20 +804,6 @@
  * The long list of v4l2 ioctl ops
  */
 
-static int viacam_g_chip_ident(struct file *file, void *priv,
-		struct v4l2_dbg_chip_ident *ident)
-{
-	struct via_camera *cam = priv;
-
-	ident->ident = V4L2_IDENT_NONE;
-	ident->revision = 0;
-	if (v4l2_chip_match_host(&ident->match)) {
-		ident->ident = V4L2_IDENT_VIA_VX855;
-		return 0;
-	}
-	return sensor_call(cam, core, g_chip_ident, ident);
-}
-
 /*
  * Only one input.
  */
@@ -852,6 +837,12 @@
 	return 0;
 }
 
+static int viacam_g_std(struct file *filp, void *priv, v4l2_std_id *std)
+{
+	*std = V4L2_STD_NTSC_M;
+	return 0;
+}
+
 /*
  * Video format stuff.	Here is our default format until
  * user space messes with things.
@@ -1174,11 +1165,11 @@
 
 
 static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
-	.vidioc_g_chip_ident	= viacam_g_chip_ident,
 	.vidioc_enum_input	= viacam_enum_input,
 	.vidioc_g_input		= viacam_g_input,
 	.vidioc_s_input		= viacam_s_input,
 	.vidioc_s_std		= viacam_s_std,
+	.vidioc_g_std		= viacam_g_std,
 	.vidioc_enum_fmt_vid_cap = viacam_enum_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap = viacam_try_fmt_vid_cap,
 	.vidioc_g_fmt_vid_cap	= viacam_g_fmt_vid_cap,
@@ -1266,7 +1257,6 @@
 	.name		= "via-camera",
 	.minor		= -1,
 	.tvnorms	= V4L2_STD_NTSC_M,
-	.current_norm	= V4L2_STD_NTSC_M,
 	.fops		= &viacam_fops,
 	.ioctl_ops	= &viacam_ioctl_ops,
 	.release	= video_device_release_empty, /* Check this */
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c
index 4c9ae76..21db23b 100644
--- a/drivers/media/radio/radio-keene.c
+++ b/drivers/media/radio/radio-keene.c
@@ -93,7 +93,7 @@
 	/* If bit 4 is set, then tune to the frequency.
 	   If bit 3 is set, then unmute; if bit 2 is set, then mute.
 	   If bit 1 is set, then enter idle mode; if bit 0 is set,
-	   then enter transit mode.
+	   then enter transmit mode.
 	 */
 	radio->buffer[5] = (radio->muted ? 4 : 8) | (play ? 1 : 2) |
 							(freq ? 0x10 : 0);
@@ -350,7 +350,6 @@
 	radio->pa = 118;
 	radio->tx = 0x32;
 	radio->stereo = true;
-	radio->curfreq = 95.16 * FREQ_MUL;
 	if (hdl->error) {
 		retval = hdl->error;
 
@@ -383,6 +382,10 @@
 	video_set_drvdata(&radio->vdev, radio);
 	set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
 
+	/* at least 11ms is needed in order to settle hardware */
+	msleep(20);
+	keene_cmd_main(radio, 95.16 * FREQ_MUL, false);
+
 	retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, -1);
 	if (retval < 0) {
 		dev_err(&intf->dev, "could not register video device\n");
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index adfcc61..6f4318f 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -27,6 +27,8 @@
 #include <linux/io.h>		/* outb, outb_p			*/
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
 #include "lm7000.h"
 
 MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
@@ -44,10 +46,11 @@
 struct fmi
 {
 	struct v4l2_device v4l2_dev;
+	struct v4l2_ctrl_handler hdl;
 	struct video_device vdev;
 	int io;
 	bool mute;
-	unsigned long curfreq; /* freq in kHz */
+	u32 curfreq; /* freq in kHz */
 	struct mutex lock;
 };
 
@@ -55,8 +58,8 @@
 static struct pnp_dev *dev;
 bool pnp_attached;
 
-#define RSF16_MINFREQ (87 * 16000)
-#define RSF16_MAXFREQ (108 * 16000)
+#define RSF16_MINFREQ (87U * 16000)
+#define RSF16_MAXFREQ (108U * 16000)
 
 #define FMI_BIT_TUN_CE		(1 << 0)
 #define FMI_BIT_TUN_CLK		(1 << 1)
@@ -115,13 +118,22 @@
 	return (res & 2) ? 0 : 0xFFFF;
 }
 
+static void fmi_set_freq(struct fmi *fmi)
+{
+	fmi->curfreq = clamp(fmi->curfreq, RSF16_MINFREQ, RSF16_MAXFREQ);
+	/* rounding in steps of 800 to match the freq
+	   that will be used */
+	lm7000_set_freq((fmi->curfreq / 800) * 800, fmi, fmi_set_pins);
+}
+
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *v)
 {
 	strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
 	strlcpy(v->card, "SF16-FMI/FMP/FMD radio", sizeof(v->card));
-	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	strlcpy(v->bus_info, "ISA:radio-sf16fmi", sizeof(v->bus_info));
+	v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -157,12 +169,10 @@
 
 	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
 		return -EINVAL;
-	if (f->frequency < RSF16_MINFREQ ||
-			f->frequency > RSF16_MAXFREQ)
-		return -EINVAL;
-	/* rounding in steps of 800 to match the freq
-	   that will be used */
-	lm7000_set_freq((f->frequency / 800) * 800, fmi, fmi_set_pins);
+
+	fmi->curfreq = f->frequency;
+	fmi_set_freq(fmi);
+
 	return 0;
 }
 
@@ -178,74 +188,31 @@
 	return 0;
 }
 
-static int vidioc_queryctrl(struct file *file, void *priv,
-					struct v4l2_queryctrl *qc)
+static int fmi_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct fmi *fmi = video_drvdata(file);
+	struct fmi *fmi = container_of(ctrl->handler, struct fmi, hdl);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = fmi->mute;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct fmi *fmi = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
+		if (ctrl->val)
 			fmi_mute(fmi);
 		else
 			fmi_unmute(fmi);
-		fmi->mute = ctrl->value;
+		fmi->mute = ctrl->val;
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
-					const struct v4l2_audio *a)
-{
-	return a->index ? -EINVAL : 0;
-}
+static const struct v4l2_ctrl_ops fmi_ctrl_ops = {
+	.s_ctrl = fmi_s_ctrl,
+};
 
 static const struct v4l2_file_operations fmi_fops = {
 	.owner		= THIS_MODULE,
+	.open		= v4l2_fh_open,
+	.release	= v4l2_fh_release,
+	.poll		= v4l2_ctrl_poll,
 	.unlocked_ioctl	= video_ioctl2,
 };
 
@@ -253,15 +220,11 @@
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
 	.vidioc_g_frequency = vidioc_g_frequency,
 	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
+	.vidioc_log_status  = v4l2_ctrl_log_status,
+	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
 /* ladis: this is my card. does any other types exist? */
@@ -311,6 +274,7 @@
 {
 	struct fmi *fmi = &fmi_card;
 	struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
+	struct v4l2_ctrl_handler *hdl = &fmi->hdl;
 	int res, i;
 	int probe_ports[] = { 0, 0x284, 0x384 };
 
@@ -363,19 +327,35 @@
 		return res;
 	}
 
+	v4l2_ctrl_handler_init(hdl, 1);
+	v4l2_ctrl_new_std(hdl, &fmi_ctrl_ops,
+			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+	v4l2_dev->ctrl_handler = hdl;
+	if (hdl->error) {
+		res = hdl->error;
+		v4l2_err(v4l2_dev, "Could not register controls\n");
+		v4l2_ctrl_handler_free(hdl);
+		v4l2_device_unregister(v4l2_dev);
+		return res;
+	}
+
 	strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
 	fmi->vdev.v4l2_dev = v4l2_dev;
 	fmi->vdev.fops = &fmi_fops;
 	fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
 	fmi->vdev.release = video_device_release_empty;
+	set_bit(V4L2_FL_USE_FH_PRIO, &fmi->vdev.flags);
 	video_set_drvdata(&fmi->vdev, fmi);
 
 	mutex_init(&fmi->lock);
 
-	/* mute card - prevents noisy bootups */
-	fmi_mute(fmi);
+	/* mute card and set default frequency */
+	fmi->mute = 1;
+	fmi->curfreq = RSF16_MINFREQ;
+	fmi_set_freq(fmi);
 
 	if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+		v4l2_ctrl_handler_free(hdl);
 		v4l2_device_unregister(v4l2_dev);
 		release_region(fmi->io, 2);
 		if (pnp_attached)
@@ -391,6 +371,7 @@
 {
 	struct fmi *fmi = &fmi_card;
 
+	v4l2_ctrl_handler_free(&fmi->hdl);
 	video_unregister_device(&fmi->vdev);
 	v4l2_device_unregister(&fmi->v4l2_dev);
 	release_region(fmi->io, 2);
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c
index 9dc8baf..9c9084c 100644
--- a/drivers/media/radio/radio-si476x.c
+++ b/drivers/media/radio/radio-si476x.c
@@ -1018,16 +1018,6 @@
 	return retval;
 }
 
-static int si476x_radio_g_chip_ident(struct file *file, void *fh,
-				     struct v4l2_dbg_chip_ident *chip)
-{
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
-	    v4l2_chip_match_host(&chip->match))
-		return 0;
-	return -EINVAL;
-}
-
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int si476x_radio_g_register(struct file *file, void *fh,
 				   struct v4l2_dbg_register *reg)
@@ -1203,7 +1193,6 @@
 	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
 
-	.vidioc_g_chip_ident		= si476x_radio_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register		= si476x_radio_g_register,
 	.vidioc_s_register		= si476x_radio_s_register,
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 38d563d..036e2f5 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -39,6 +39,9 @@
 #include <linux/i2c.h>			/* I2C				*/
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
 
 #define DRIVER_VERSION	"0.0.2"
 
@@ -57,8 +60,8 @@
 
 /* Frequency limits in MHz -- these are European values.  For Japanese
 devices, that would be 76000 and 91000.  */
-#define FREQ_MIN  87500
-#define FREQ_MAX 108000
+#define FREQ_MIN  87500U
+#define FREQ_MAX 108000U
 #define FREQ_MUL 16
 
 /* TEA5764 registers */
@@ -138,8 +141,10 @@
 static int use_xtal = RADIO_TEA5764_XTAL;
 
 struct tea5764_device {
+	struct v4l2_device		v4l2_dev;
+	struct v4l2_ctrl_handler	ctrl_handler;
 	struct i2c_client		*i2c_client;
-	struct video_device		*videodev;
+	struct video_device		vdev;
 	struct tea5764_regs		regs;
 	struct mutex			mutex;
 };
@@ -187,18 +192,6 @@
 	return 0;
 }
 
-/* V4L2 code related */
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	}
-};
-
 static void tea5764_power_up(struct tea5764_device *radio)
 {
 	struct tea5764_regs *r = &radio->regs;
@@ -291,23 +284,19 @@
 		tea5764_i2c_write(radio);
 }
 
-static int tea5764_is_muted(struct tea5764_device *radio)
-{
-	return radio->regs.tnctrl & TEA5764_TNCTRL_MU;
-}
-
 /* V4L2 vidioc */
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *v)
 {
 	struct tea5764_device *radio = video_drvdata(file);
-	struct video_device *dev = radio->videodev;
+	struct video_device *dev = &radio->vdev;
 
 	strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver));
 	strlcpy(v->card, dev->name, sizeof(v->card));
 	snprintf(v->bus_info, sizeof(v->bus_info),
 		 "I2C:%s", dev_name(&dev->dev));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -320,8 +309,7 @@
 	if (v->index > 0)
 		return -EINVAL;
 
-	memset(v, 0, sizeof(*v));
-	strcpy(v->name, "FM");
+	strlcpy(v->name, "FM", sizeof(v->name));
 	v->type = V4L2_TUNER_RADIO;
 	tea5764_i2c_read(radio);
 	v->rangelow   = FREQ_MIN * FREQ_MUL;
@@ -354,19 +342,23 @@
 				const struct v4l2_frequency *f)
 {
 	struct tea5764_device *radio = video_drvdata(file);
+	unsigned freq = f->frequency;
 
 	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
 		return -EINVAL;
-	if (f->frequency == 0) {
+	if (freq == 0) {
 		/* We special case this as a power down control. */
 		tea5764_power_down(radio);
+		/* Yes, that's what is returned in this case. This
+		   whole special case is non-compliant and should really
+		   be replaced with something better, but changing this
+		   might well break code that depends on this behavior.
+		   So we keep it as-is. */
+		return -EINVAL;
 	}
-	if (f->frequency < (FREQ_MIN * FREQ_MUL))
-		return -EINVAL;
-	if (f->frequency > (FREQ_MAX * FREQ_MUL))
-		return -EINVAL;
+	clamp(freq, FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL);
 	tea5764_power_up(radio);
-	tea5764_tune(radio, (f->frequency * 125) / 2);
+	tea5764_tune(radio, (freq * 125) / 2);
 	return 0;
 }
 
@@ -379,7 +371,6 @@
 	if (f->tuner != 0)
 		return -EINVAL;
 	tea5764_i2c_read(radio);
-	memset(f, 0, sizeof(*f));
 	f->type = V4L2_TUNER_RADIO;
 	if (r->tnctrl & TEA5764_TNCTRL_PUPD0)
 		f->frequency = (tea5764_get_freq(radio) * 2) / 125;
@@ -389,83 +380,29 @@
 	return 0;
 }
 
-static int vidioc_queryctrl(struct file *file, void *priv,
-			    struct v4l2_queryctrl *qc)
+static int tea5764_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
-			return 0;
-		}
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-			    struct v4l2_control *ctrl)
-{
-	struct tea5764_device *radio = video_drvdata(file);
+	struct tea5764_device *radio =
+		container_of(ctrl->handler, struct tea5764_device, ctrl_handler);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		tea5764_i2c_read(radio);
-		ctrl->value = tea5764_is_muted(radio) ? 1 : 0;
+		tea5764_mute(radio, ctrl->val);
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_s_ctrl(struct file *file, void *priv,
-			    struct v4l2_control *ctrl)
-{
-	struct tea5764_device *radio = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		tea5764_mute(radio, ctrl->value);
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	if (i != 0)
-		return -EINVAL;
-	return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-			   struct v4l2_audio *a)
-{
-	if (a->index > 1)
-		return -EINVAL;
-
-	strcpy(a->name, "Radio");
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
-			   const struct v4l2_audio *a)
-{
-	if (a->index != 0)
-		return -EINVAL;
-
-	return 0;
-}
+static const struct v4l2_ctrl_ops tea5764_ctrl_ops = {
+	.s_ctrl = tea5764_s_ctrl,
+};
 
 /* File system interface */
 static const struct v4l2_file_operations tea5764_fops = {
 	.owner		= THIS_MODULE,
+	.open		= v4l2_fh_open,
+	.release	= v4l2_fh_release,
+	.poll		= v4l2_ctrl_poll,
 	.unlocked_ioctl	= video_ioctl2,
 };
 
@@ -473,15 +410,11 @@
 	.vidioc_querycap    = vidioc_querycap,
 	.vidioc_g_tuner     = vidioc_g_tuner,
 	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
 	.vidioc_g_frequency = vidioc_g_frequency,
 	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
+	.vidioc_log_status  = v4l2_ctrl_log_status,
+	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
 /* V4L2 interface */
@@ -489,7 +422,7 @@
 	.name		= "TEA5764 FM-Radio",
 	.fops           = &tea5764_fops,
 	.ioctl_ops 	= &tea5764_ioctl_ops,
-	.release	= video_device_release,
+	.release	= video_device_release_empty,
 };
 
 /* I2C probe: check if the device exists and register with v4l if it is */
@@ -497,6 +430,8 @@
 			     const struct i2c_device_id *id)
 {
 	struct tea5764_device *radio;
+	struct v4l2_device *v4l2_dev;
+	struct v4l2_ctrl_handler *hdl;
 	struct tea5764_regs *r;
 	int ret;
 
@@ -505,31 +440,45 @@
 	if (!radio)
 		return -ENOMEM;
 
+	v4l2_dev = &radio->v4l2_dev;
+	ret = v4l2_device_register(&client->dev, v4l2_dev);
+	if (ret < 0) {
+		v4l2_err(v4l2_dev, "could not register v4l2_device\n");
+		goto errfr;
+	}
+
+	hdl = &radio->ctrl_handler;
+	v4l2_ctrl_handler_init(hdl, 1);
+	v4l2_ctrl_new_std(hdl, &tea5764_ctrl_ops,
+			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+	v4l2_dev->ctrl_handler = hdl;
+	if (hdl->error) {
+		ret = hdl->error;
+		v4l2_err(v4l2_dev, "Could not register controls\n");
+		goto errunreg;
+	}
+
 	mutex_init(&radio->mutex);
 	radio->i2c_client = client;
 	ret = tea5764_i2c_read(radio);
 	if (ret)
-		goto errfr;
+		goto errunreg;
 	r = &radio->regs;
 	PDEBUG("chipid = %04X, manid = %04X", r->chipid, r->manid);
 	if (r->chipid != TEA5764_CHIPID ||
 		(r->manid & 0x0fff) != TEA5764_MANID) {
 		PWARN("This chip is not a TEA5764!");
 		ret = -EINVAL;
-		goto errfr;
+		goto errunreg;
 	}
 
-	radio->videodev = video_device_alloc();
-	if (!(radio->videodev)) {
-		ret = -ENOMEM;
-		goto errfr;
-	}
-	memcpy(radio->videodev, &tea5764_radio_template,
-		sizeof(tea5764_radio_template));
+	radio->vdev = tea5764_radio_template;
 
 	i2c_set_clientdata(client, radio);
-	video_set_drvdata(radio->videodev, radio);
-	radio->videodev->lock = &radio->mutex;
+	video_set_drvdata(&radio->vdev, radio);
+	radio->vdev.lock = &radio->mutex;
+	radio->vdev.v4l2_dev = v4l2_dev;
+	set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
 
 	/* initialize and power off the chip */
 	tea5764_i2c_read(radio);
@@ -537,16 +486,17 @@
 	tea5764_mute(radio, 1);
 	tea5764_power_down(radio);
 
-	ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+	ret = video_register_device(&radio->vdev, VFL_TYPE_RADIO, radio_nr);
 	if (ret < 0) {
 		PWARN("Could not register video device!");
-		goto errrel;
+		goto errunreg;
 	}
 
 	PINFO("registered.");
 	return 0;
-errrel:
-	video_device_release(radio->videodev);
+errunreg:
+	v4l2_ctrl_handler_free(hdl);
+	v4l2_device_unregister(v4l2_dev);
 errfr:
 	kfree(radio);
 	return ret;
@@ -559,7 +509,9 @@
 	PDEBUG("remove");
 	if (radio) {
 		tea5764_power_down(radio);
-		video_unregister_device(radio->videodev);
+		video_unregister_device(&radio->vdev);
+		v4l2_ctrl_handler_free(&radio->ctrl_handler);
+		v4l2_device_unregister(&radio->v4l2_dev);
 		kfree(radio);
 	}
 	return 0;
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index bb7b143..0817964 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -19,6 +19,8 @@
 #include <linux/io.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
@@ -44,7 +46,8 @@
 	strlcpy(v->driver, DRIVER_NAME, sizeof(v->driver));
 	strlcpy(v->card, "Timberdale Radio", sizeof(v->card));
 	snprintf(v->bus_info, sizeof(v->bus_info), "platform:"DRIVER_NAME);
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -62,34 +65,6 @@
 	return v4l2_subdev_call(tr->sd_tuner, tuner, s_tuner, v);
 }
 
-static int timbradio_vidioc_g_input(struct file *filp, void *priv,
-	unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int timbradio_vidioc_s_input(struct file *filp, void *priv,
-	unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int timbradio_vidioc_g_audio(struct file *file, void *priv,
-	struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int timbradio_vidioc_s_audio(struct file *file, void *priv,
-	const struct v4l2_audio *a)
-{
-	return a->index ? -EINVAL : 0;
-}
-
 static int timbradio_vidioc_s_frequency(struct file *file, void *priv,
 	const struct v4l2_frequency *f)
 {
@@ -104,44 +79,22 @@
 	return v4l2_subdev_call(tr->sd_tuner, tuner, g_frequency, f);
 }
 
-static int timbradio_vidioc_queryctrl(struct file *file, void *priv,
-	struct v4l2_queryctrl *qc)
-{
-	struct timbradio *tr = video_drvdata(file);
-	return v4l2_subdev_call(tr->sd_dsp, core, queryctrl, qc);
-}
-
-static int timbradio_vidioc_g_ctrl(struct file *file, void *priv,
-	struct v4l2_control *ctrl)
-{
-	struct timbradio *tr = video_drvdata(file);
-	return v4l2_subdev_call(tr->sd_dsp, core, g_ctrl, ctrl);
-}
-
-static int timbradio_vidioc_s_ctrl(struct file *file, void *priv,
-	struct v4l2_control *ctrl)
-{
-	struct timbradio *tr = video_drvdata(file);
-	return v4l2_subdev_call(tr->sd_dsp, core, s_ctrl, ctrl);
-}
-
 static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
 	.vidioc_querycap	= timbradio_vidioc_querycap,
 	.vidioc_g_tuner		= timbradio_vidioc_g_tuner,
 	.vidioc_s_tuner		= timbradio_vidioc_s_tuner,
 	.vidioc_g_frequency	= timbradio_vidioc_g_frequency,
 	.vidioc_s_frequency	= timbradio_vidioc_s_frequency,
-	.vidioc_g_input		= timbradio_vidioc_g_input,
-	.vidioc_s_input		= timbradio_vidioc_s_input,
-	.vidioc_g_audio		= timbradio_vidioc_g_audio,
-	.vidioc_s_audio		= timbradio_vidioc_s_audio,
-	.vidioc_queryctrl	= timbradio_vidioc_queryctrl,
-	.vidioc_g_ctrl		= timbradio_vidioc_g_ctrl,
-	.vidioc_s_ctrl		= timbradio_vidioc_s_ctrl
+	.vidioc_log_status      = v4l2_ctrl_log_status,
+	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
 static const struct v4l2_file_operations timbradio_fops = {
 	.owner		= THIS_MODULE,
+	.open		= v4l2_fh_open,
+	.release	= v4l2_fh_release,
+	.poll		= v4l2_ctrl_poll,
 	.unlocked_ioctl	= video_ioctl2,
 };
 
@@ -173,6 +126,7 @@
 	tr->video_dev.release = video_device_release_empty;
 	tr->video_dev.minor = -1;
 	tr->video_dev.lock = &tr->lock;
+	set_bit(V4L2_FL_USE_FH_PRIO, &tr->video_dev.flags);
 
 	strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
 	err = v4l2_device_register(NULL, &tr->v4l2_dev);
@@ -181,6 +135,15 @@
 
 	tr->video_dev.v4l2_dev = &tr->v4l2_dev;
 
+	tr->sd_tuner = v4l2_i2c_new_subdev_board(&tr->v4l2_dev,
+		i2c_get_adapter(pdata->i2c_adapter), pdata->tuner, NULL);
+	tr->sd_dsp = v4l2_i2c_new_subdev_board(&tr->v4l2_dev,
+		i2c_get_adapter(pdata->i2c_adapter), pdata->dsp, NULL);
+	if (tr->sd_tuner == NULL || tr->sd_dsp == NULL)
+		goto err_video_req;
+
+	tr->v4l2_dev.ctrl_handler = tr->sd_dsp->ctrl_handler;
+
 	err = video_register_device(&tr->video_dev, VFL_TYPE_RADIO, -1);
 	if (err) {
 		dev_err(&pdev->dev, "Error reg video\n");
@@ -193,7 +156,6 @@
 	return 0;
 
 err_video_req:
-	video_device_release_empty(&tr->video_dev);
 	v4l2_device_unregister(&tr->v4l2_dev);
 err:
 	dev_err(&pdev->dev, "Failed to register: %d\n", err);
@@ -206,10 +168,7 @@
 	struct timbradio *tr = platform_get_drvdata(pdev);
 
 	video_unregister_device(&tr->video_dev);
-	video_device_release_empty(&tr->video_dev);
-
 	v4l2_device_unregister(&tr->v4l2_dev);
-
 	return 0;
 }
 
diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c
index 06c06cc..ec805b0 100644
--- a/drivers/media/radio/saa7706h.c
+++ b/drivers/media/radio/saa7706h.c
@@ -25,7 +25,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-ctrls.h>
 
 #define DRIVER_NAME "saa7706h"
 
@@ -127,6 +127,7 @@
 
 struct saa7706h_state {
 	struct v4l2_subdev sd;
+	struct v4l2_ctrl_handler hdl;
 	unsigned muted;
 };
 
@@ -317,51 +318,32 @@
 	return err;
 }
 
-static int saa7706h_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+static int saa7706h_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	}
-	return -EINVAL;
-}
-
-static int saa7706h_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-	struct saa7706h_state *state = to_state(sd);
+	struct saa7706h_state *state =
+		container_of(ctrl->handler, struct saa7706h_state, hdl);
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = state->muted;
-		return 0;
+		if (ctrl->val)
+			return saa7706h_mute(&state->sd);
+		return saa7706h_unmute(&state->sd);
 	}
 	return -EINVAL;
 }
 
-static int saa7706h_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
-			return saa7706h_mute(sd);
-		return saa7706h_unmute(sd);
-	}
-	return -EINVAL;
-}
-
-static int saa7706h_g_chip_ident(struct v4l2_subdev *sd,
-	struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7706H, 0);
-}
+static const struct v4l2_ctrl_ops saa7706h_ctrl_ops = {
+	.s_ctrl = saa7706h_s_ctrl,
+};
 
 static const struct v4l2_subdev_core_ops saa7706h_core_ops = {
-	.g_chip_ident = saa7706h_g_chip_ident,
-	.queryctrl = saa7706h_queryctrl,
-	.g_ctrl = saa7706h_g_ctrl,
-	.s_ctrl = saa7706h_s_ctrl,
+	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+	.g_ctrl = v4l2_subdev_g_ctrl,
+	.s_ctrl = v4l2_subdev_s_ctrl,
+	.queryctrl = v4l2_subdev_queryctrl,
+	.querymenu = v4l2_subdev_querymenu,
 };
 
 static const struct v4l2_subdev_ops saa7706h_ops = {
@@ -393,13 +375,20 @@
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &saa7706h_ops);
 
+	v4l2_ctrl_handler_init(&state->hdl, 4);
+	v4l2_ctrl_new_std(&state->hdl, &saa7706h_ctrl_ops,
+			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+	sd->ctrl_handler = &state->hdl;
+	err = state->hdl.error;
+	if (err)
+		goto err;
+
 	/* check the rom versions */
 	err = saa7706h_get_reg16(sd, SAA7706H_DSP1_ROM_VER);
 	if (err < 0)
 		goto err;
 	if (err != SUPPORTED_DSP1_ROM_VER)
 		v4l2_warn(sd, "Unknown DSP1 ROM code version: 0x%x\n", err);
-
 	state->muted = 1;
 
 	/* startup in a muted state */
@@ -411,6 +400,7 @@
 
 err:
 	v4l2_device_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&state->hdl);
 	kfree(to_state(sd));
 
 	printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", err);
@@ -421,9 +411,11 @@
 static int saa7706h_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct saa7706h_state *state = to_state(sd);
 
 	saa7706h_mute(sd);
 	v4l2_device_unregister_subdev(sd);
+	v4l2_ctrl_handler_free(&state->hdl);
 	kfree(to_state(sd));
 	return 0;
 }
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c
index 82c6c94..06ac692 100644
--- a/drivers/media/radio/tef6862.c
+++ b/drivers/media/radio/tef6862.c
@@ -25,14 +25,13 @@
 #include <linux/slab.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 
 #define DRIVER_NAME "tef6862"
 
 #define FREQ_MUL 16000
 
-#define TEF6862_LO_FREQ (875 * FREQ_MUL / 10)
-#define TEF6862_HI_FREQ (108 * FREQ_MUL)
+#define TEF6862_LO_FREQ (875U * FREQ_MUL / 10)
+#define TEF6862_HI_FREQ (108U * FREQ_MUL)
 
 /* Write mode sub addresses */
 #define WM_SUB_BANDWIDTH	0x0
@@ -105,6 +104,7 @@
 {
 	struct tef6862_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	unsigned freq = f->frequency;
 	u16 pll;
 	u8 i2cmsg[3];
 	int err;
@@ -112,7 +112,8 @@
 	if (f->tuner != 0)
 		return -EINVAL;
 
-	pll = 1964 + ((f->frequency - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
+	clamp(freq, TEF6862_LO_FREQ, TEF6862_HI_FREQ);
+	pll = 1964 + ((freq - TEF6862_LO_FREQ) * 20) / FREQ_MUL;
 	i2cmsg[0] = (MODE_PRESET << MODE_SHIFT) | WM_SUB_PLLM;
 	i2cmsg[1] = (pll >> 8) & 0xff;
 	i2cmsg[2] = pll & 0xff;
@@ -121,7 +122,7 @@
 	if (err != sizeof(i2cmsg))
 		return err < 0 ? err : -EIO;
 
-	state->freq = f->frequency;
+	state->freq = freq;
 	return 0;
 }
 
@@ -136,14 +137,6 @@
 	return 0;
 }
 
-static int tef6862_g_chip_ident(struct v4l2_subdev *sd,
-	struct v4l2_dbg_chip_ident *chip)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEF6862, 0);
-}
-
 static const struct v4l2_subdev_tuner_ops tef6862_tuner_ops = {
 	.g_tuner = tef6862_g_tuner,
 	.s_tuner = tef6862_s_tuner,
@@ -151,12 +144,7 @@
 	.g_frequency = tef6862_g_frequency,
 };
 
-static const struct v4l2_subdev_core_ops tef6862_core_ops = {
-	.g_chip_ident = tef6862_g_chip_ident,
-};
-
 static const struct v4l2_subdev_ops tef6862_ops = {
-	.core = &tef6862_core_ops,
 	.tuner = &tef6862_tuner_ops,
 };
 
diff --git a/drivers/media/radio/wl128x/fmdrv.h b/drivers/media/radio/wl128x/fmdrv.h
index aac0f02..a587c9b 100644
--- a/drivers/media/radio/wl128x/fmdrv.h
+++ b/drivers/media/radio/wl128x/fmdrv.h
@@ -30,6 +30,7 @@
 #include <linux/timer.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
 
 #define FM_DRV_VERSION            "0.1.1"
@@ -202,6 +203,7 @@
 /* FM driver operation structure */
 struct fmdev {
 	struct video_device *radio_dev;	/* V4L2 video device pointer */
+	struct v4l2_device v4l2_dev;	/* V4L2 top level struct */
 	struct snd_card *card;	/* Card which holds FM mixer controls */
 	u16 asci_id;
 	spinlock_t rds_buff_lock; /* To protect access to RDS buffer */
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
index a002234..253f307 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.c
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -715,7 +715,7 @@
 	struct fm_rdsdata_format rds_fmt;
 	struct fm_rds *rds = &fmdev->rx.rds;
 	unsigned long group_idx, flags;
-	u8 *rds_data, meta_data, tmpbuf[3];
+	u8 *rds_data, meta_data, tmpbuf[FM_RDS_BLK_SIZE];
 	u8 type, blk_idx;
 	u16 cur_picode;
 	u32 rds_len;
@@ -1073,6 +1073,7 @@
 		u8 __user *buf, size_t count)
 {
 	u32 block_count;
+	u8 tmpbuf[FM_RDS_BLK_SIZE];
 	unsigned long flags;
 	int ret;
 
@@ -1087,29 +1088,32 @@
 	}
 
 	/* Calculate block count from byte count */
-	count /= 3;
+	count /= FM_RDS_BLK_SIZE;
 	block_count = 0;
 	ret = 0;
 
-	spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
-
 	while (block_count < count) {
-		if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx)
-			break;
+		spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
 
-		if (copy_to_user(buf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
-					FM_RDS_BLK_SIZE))
+		if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) {
+			spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
 			break;
-
+		}
+		memcpy(tmpbuf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
+					FM_RDS_BLK_SIZE);
 		fmdev->rx.rds.rd_idx += FM_RDS_BLK_SIZE;
 		if (fmdev->rx.rds.rd_idx >= fmdev->rx.rds.buf_size)
 			fmdev->rx.rds.rd_idx = 0;
 
+		spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
+
+		if (copy_to_user(buf, tmpbuf, FM_RDS_BLK_SIZE))
+			break;
+
 		block_count++;
 		buf += FM_RDS_BLK_SIZE;
 		ret += FM_RDS_BLK_SIZE;
 	}
-	spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
 	return ret;
 }
 
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c
index 5dec323..b55012c 100644
--- a/drivers/media/radio/wl128x/fmdrv_v4l2.c
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c
@@ -533,6 +533,11 @@
 	struct v4l2_ctrl *ctrl;
 	int ret;
 
+	strlcpy(fmdev->v4l2_dev.name, FM_DRV_NAME, sizeof(fmdev->v4l2_dev.name));
+	ret = v4l2_device_register(NULL, &fmdev->v4l2_dev);
+	if (ret < 0)
+		return ret;
+
 	/* Init mutex for core locking */
 	mutex_init(&fmdev->mutex);
 
@@ -549,6 +554,7 @@
 	video_set_drvdata(gradio_dev, fmdev);
 
 	gradio_dev->lock = &fmdev->mutex;
+	gradio_dev->v4l2_dev = &fmdev->v4l2_dev;
 
 	/* Register with V4L2 subsystem as RADIO device */
 	if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
@@ -611,5 +617,7 @@
 	/* Unregister RADIO device from V4L2 subsystem */
 	video_unregister_device(gradio_dev);
 
+	v4l2_device_unregister(&fmdev->v4l2_dev);
+
 	return fmdev;
 }
diff --git a/drivers/media/rc/gpio-ir-recv.c b/drivers/media/rc/gpio-ir-recv.c
index 8b82ae9..07aacfa 100644
--- a/drivers/media/rc/gpio-ir-recv.c
+++ b/drivers/media/rc/gpio-ir-recv.c
@@ -178,7 +178,6 @@
 	return 0;
 
 err_request_irq:
-	platform_set_drvdata(pdev, NULL);
 	rc_unregister_device(rcdev);
 	rcdev = NULL;
 err_register_rc_device:
@@ -196,7 +195,6 @@
 	struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev);
 
 	free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev);
-	platform_set_drvdata(pdev, NULL);
 	rc_unregister_device(gpio_dev->rcdev);
 	gpio_free(gpio_dev->gpio_nr);
 	kfree(gpio_dev);
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 5ab94ea..b1cde8c 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -20,6 +20,7 @@
 			rc-budget-ci-old.o \
 			rc-cinergy-1400.o \
 			rc-cinergy.o \
+			rc-delock-61959.o \
 			rc-dib0700-nec.o \
 			rc-dib0700-rc5.o \
 			rc-digitalnow-tinytwin.o \
diff --git a/drivers/media/rc/keymaps/rc-delock-61959.c b/drivers/media/rc/keymaps/rc-delock-61959.c
new file mode 100644
index 0000000..01bed86
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-delock-61959.c
@@ -0,0 +1,83 @@
+/* rc-delock-61959.c - Keytable for Delock
+ *
+ * Copyright (c) 2013 by Jakob Haufe <sur5r@sur5r.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+/*
+ * Keytable for remote provided with Delock 61959
+ */
+static struct rc_map_table delock_61959[] = {
+	{ 0x866b16, KEY_POWER2 },	/* Power */
+	{ 0x866b0c, KEY_POWER },	/* Shut Down */
+
+	{ 0x866b00, KEY_1},
+	{ 0x866b01, KEY_2},
+	{ 0x866b02, KEY_3},
+	{ 0x866b03, KEY_4},
+	{ 0x866b04, KEY_5},
+	{ 0x866b05, KEY_6},
+	{ 0x866b06, KEY_7},
+	{ 0x866b07, KEY_8},
+	{ 0x866b08, KEY_9},
+	{ 0x866b14, KEY_0},
+
+	{ 0x866b0a, KEY_ZOOM},		/* Full Screen */
+	{ 0x866b10, KEY_CAMERA},	/* Photo */
+	{ 0x866b0e, KEY_CHANNEL},	/* circular arrow / Recall */
+	{ 0x866b13, KEY_ESC},           /* Back */
+
+	{ 0x866b20, KEY_UP},
+	{ 0x866b21, KEY_DOWN},
+	{ 0x866b42, KEY_LEFT},
+	{ 0x866b43, KEY_RIGHT},
+	{ 0x866b0b, KEY_OK},
+
+	{ 0x866b11, KEY_CHANNELUP},
+	{ 0x866b1b, KEY_CHANNELDOWN},
+
+	{ 0x866b12, KEY_VOLUMEUP},
+	{ 0x866b48, KEY_VOLUMEDOWN},
+	{ 0x866b44, KEY_MUTE},
+
+	{ 0x866b1a, KEY_RECORD},
+	{ 0x866b41, KEY_PLAY},
+	{ 0x866b40, KEY_STOP},
+	{ 0x866b19, KEY_PAUSE},
+	{ 0x866b1c, KEY_FASTFORWARD},	/* >> / FWD */
+	{ 0x866b1e, KEY_REWIND},	/* << / REW */
+
+};
+
+static struct rc_map_list delock_61959_map = {
+	.map = {
+		.scan    = delock_61959,
+		.size    = ARRAY_SIZE(delock_61959),
+		.rc_type = RC_TYPE_NEC,
+		.name    = RC_MAP_DELOCK_61959,
+	}
+};
+
+static int __init init_rc_map_delock_61959(void)
+{
+	return rc_map_register(&delock_61959_map);
+}
+
+static void __exit exit_rc_map_delock_61959(void)
+{
+	rc_map_unregister(&delock_61959_map);
+}
+
+module_init(init_rc_map_delock_61959)
+module_exit(exit_rc_map_delock_61959)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jakob Haufe <sur5r@sur5r.net>");
+MODULE_DESCRIPTION("Delock 61959 remote keytable");
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index 4835021..1c23666 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -364,8 +364,8 @@
 	}
 	if (len <= 0)
 		return;
-	if (len > NUM_REGS)
-		len = NUM_REGS;
+	if (len > NUM_REGS - r)
+		len = NUM_REGS - r;
 
 	tuner_dbg("%s: prev  reg=%02x len=%d: %*ph\n",
 		  __func__, r + REG_SHADOW_START, len, len, val);
@@ -1857,9 +1857,9 @@
 	int reg18, reg19, reg1f;
 
 	if (priv->cfg->xtal > 24000000)
-		ring_ref = priv->cfg->xtal / 2;
+		ring_ref = priv->cfg->xtal / 2000;
 	else
-		ring_ref = priv->cfg->xtal;
+		ring_ref = priv->cfg->xtal / 1000;
 
 	n_ring = 15;
 	for (n = 0; n < 16; n++) {
@@ -2256,7 +2256,6 @@
 
 	mutex_unlock(&r820t_list_mutex);
 
-	kfree(fe->tuner_priv);
 	fe->tuner_priv = NULL;
 
 	return 0;
@@ -2311,8 +2310,6 @@
 		break;
 	}
 
-	memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops, sizeof(r820t_tuner_ops));
-
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 
@@ -2327,15 +2324,14 @@
 
 	tuner_info("Rafael Micro r820t successfully identified\n");
 
-	fe->tuner_priv = priv;
-	memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops,
-			sizeof(struct dvb_tuner_ops));
-
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0);
 
 	mutex_unlock(&r820t_list_mutex);
 
+	memcpy(&fe->ops.tuner_ops, &r820t_tuner_ops,
+			sizeof(struct dvb_tuner_ops));
+
 	return fe;
 err:
 	if (fe->ops.i2c_gate_ctrl)
diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
index 0a7d520..cfe8056 100644
--- a/drivers/media/usb/Kconfig
+++ b/drivers/media/usb/Kconfig
@@ -1,6 +1,7 @@
+if USB && MEDIA_SUPPORT
+
 menuconfig MEDIA_USB_SUPPORT
 	bool "Media USB Adapters"
-	depends on USB && MEDIA_SUPPORT
 	help
 	  Enable media drivers for USB bus.
 	  If you have such devices, say Y.
@@ -17,6 +18,7 @@
 source "drivers/media/usb/stkwebcam/Kconfig"
 source "drivers/media/usb/s2255/Kconfig"
 source "drivers/media/usb/sn9c102/Kconfig"
+source "drivers/media/usb/usbtv/Kconfig"
 endif
 
 if MEDIA_ANALOG_TV_SUPPORT
@@ -52,3 +54,4 @@
 endif
 
 endif #MEDIA_USB_SUPPORT
+endif #USB
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
index 7f51d7e..0935f47 100644
--- a/drivers/media/usb/Makefile
+++ b/drivers/media/usb/Makefile
@@ -20,3 +20,4 @@
 obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
 obj-$(CONFIG_VIDEO_TM6000) += tm6000/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
+obj-$(CONFIG_VIDEO_USBTV) += usbtv/
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 75ac994..f615454 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -36,7 +36,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/tuner.h>
 #include "au0828.h"
 #include "au0828-reg.h"
@@ -1638,26 +1637,6 @@
 	return 0;
 }
 
-static int vidioc_g_chip_ident(struct file *file, void *priv,
-	       struct v4l2_dbg_chip_ident *chip)
-{
-	struct au0828_fh *fh = priv;
-	struct au0828_dev *dev = fh->dev;
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-
-	if (v4l2_chip_match_host(&chip->match)) {
-		chip->ident = V4L2_IDENT_AU0828;
-		return 0;
-	}
-
-	v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
-	if (chip->ident == V4L2_IDENT_NONE)
-		return -EINVAL;
-
-	return 0;
-}
-
 static int vidioc_cropcap(struct file *file, void *priv,
 			  struct v4l2_cropcap *cc)
 {
@@ -1779,16 +1758,8 @@
 	struct au0828_fh *fh = priv;
 	struct au0828_dev *dev = fh->dev;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
-		return 0;
-	default:
-		if (!v4l2_chip_match_host(&reg->match))
-			return -EINVAL;
-	}
-
 	reg->val = au0828_read(dev, reg->reg);
+	reg->size = 1;
 	return 0;
 }
 
@@ -1798,14 +1769,6 @@
 	struct au0828_fh *fh = priv;
 	struct au0828_dev *dev = fh->dev;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
-		return 0;
-	default:
-		if (!v4l2_chip_match_host(&reg->match))
-			return -EINVAL;
-	}
 	return au0828_writereg(dev, reg->reg, reg->val);
 }
 #endif
@@ -1943,7 +1906,6 @@
 	.vidioc_g_register          = vidioc_g_register,
 	.vidioc_s_register          = vidioc_s_register,
 #endif
-	.vidioc_g_chip_ident        = vidioc_g_chip_ident,
 	.vidioc_log_status	    = vidioc_log_status,
 	.vidioc_subscribe_event     = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event   = v4l2_event_unsubscribe,
diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c
index f548db8..2f63029 100644
--- a/drivers/media/usb/cx231xx/cx231xx-417.c
+++ b/drivers/media/usb/cx231xx/cx231xx-417.c
@@ -1840,7 +1840,6 @@
 	.vidioc_streamon	 = vidioc_streamon,
 	.vidioc_streamoff	 = vidioc_streamoff,
 	.vidioc_log_status	 = vidioc_log_status,
-	.vidioc_g_chip_ident	 = cx231xx_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register	 = cx231xx_g_register,
 	.vidioc_s_register	 = cx231xx_s_register,
diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c
index 235ba65..89de00b 100644
--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c
@@ -35,7 +35,6 @@
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
 
 #include "cx231xx.h"
 #include "cx231xx-dif.h"
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 13249e5..27948e1 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -29,7 +29,6 @@
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 
 #include <media/cx25840.h>
 #include "dvb-usb-ids.h"
diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c
index 1340ff2..c027942 100644
--- a/drivers/media/usb/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c
@@ -32,7 +32,6 @@
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/msp3400.h>
 #include <media/tuner.h>
 
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index cd22147..9906261 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -36,7 +36,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/msp3400.h>
 #include <media/tuner.h>
 
@@ -1228,179 +1227,93 @@
 	return rc;
 }
 
-int cx231xx_g_chip_ident(struct file *file, void *fh,
-			struct v4l2_dbg_chip_ident *chip)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+
+int cx231xx_g_chip_info(struct file *file, void *fh,
+			struct v4l2_dbg_chip_info *chip)
 {
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
-		if (v4l2_chip_match_host(&chip->match))
-			chip->ident = V4L2_IDENT_CX23100;
+	switch (chip->match.addr) {
+	case 0:	/* Cx231xx - internal registers */
+		return 0;
+	case 1:	/* AFE - read byte */
+		strlcpy(chip->name, "AFE (byte)", sizeof(chip->name));
+		return 0;
+	case 2:	/* Video Block - read byte */
+		strlcpy(chip->name, "Video (byte)", sizeof(chip->name));
+		return 0;
+	case 3:	/* I2S block - read byte */
+		strlcpy(chip->name, "I2S (byte)", sizeof(chip->name));
+		return 0;
+	case 4: /* AFE - read dword */
+		strlcpy(chip->name, "AFE (dword)", sizeof(chip->name));
+		return 0;
+	case 5: /* Video Block - read dword */
+		strlcpy(chip->name, "Video (dword)", sizeof(chip->name));
+		return 0;
+	case 6: /* I2S Block - read dword */
+		strlcpy(chip->name, "I2S (dword)", sizeof(chip->name));
 		return 0;
 	}
 	return -EINVAL;
 }
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-
-/*
-  -R, --list-registers=type=<host/i2cdrv/i2caddr>,
-				chip=<chip>[,min=<addr>,max=<addr>]
-		     dump registers from <min> to <max> [VIDIOC_DBG_G_REGISTER]
-  -r, --set-register=type=<host/i2cdrv/i2caddr>,
-				chip=<chip>,reg=<addr>,val=<val>
-		     set the register [VIDIOC_DBG_S_REGISTER]
-
-  if type == host, then <chip> is the hosts chip ID (default 0)
-  if type == i2cdrv (default), then <chip> is the I2C driver name or ID
-  if type == i2caddr, then <chip> is the 7-bit I2C address
-*/
-
 int cx231xx_g_register(struct file *file, void *priv,
 			     struct v4l2_dbg_register *reg)
 {
 	struct cx231xx_fh *fh = priv;
 	struct cx231xx *dev = fh->dev;
-	int ret = 0;
+	int ret;
 	u8 value[4] = { 0, 0, 0, 0 };
 	u32 data = 0;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		switch (reg->match.addr) {
-		case 0:	/* Cx231xx - internal registers */
-			ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
-						  (u16)reg->reg, value, 4);
-			reg->val = value[0] | value[1] << 8 |
-				   value[2] << 16 | value[3] << 24;
-			break;
-		case 1:	/* AFE - read byte */
-			ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
-						  (u16)reg->reg, 2, &data, 1);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 14: /* AFE - read dword */
-			ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
-						  (u16)reg->reg, 2, &data, 4);
-			reg->val = le32_to_cpu(data);
-			break;
-		case 2:	/* Video Block - read byte */
-			ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
-						  (u16)reg->reg, 2, &data, 1);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 24: /* Video Block - read dword */
-			ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
-						  (u16)reg->reg, 2, &data, 4);
-			reg->val = le32_to_cpu(data);
-			break;
-		case 3:	/* I2S block - read byte */
-			ret = cx231xx_read_i2c_data(dev,
-						    I2S_BLK_DEVICE_ADDRESS,
-						    (u16)reg->reg, 1,
-						    &data, 1);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 34: /* I2S Block - read dword */
-			ret =
-			    cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
-						  (u16)reg->reg, 1, &data, 4);
-			reg->val = le32_to_cpu(data);
-			break;
-		}
-		return ret < 0 ? ret : 0;
-
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		call_all(dev, core, g_register, reg);
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:/*for register debug*/
-		switch (reg->match.addr) {
-		case 0:	/* Cx231xx - internal registers */
-			ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
-						  (u16)reg->reg, value, 4);
-			reg->val = value[0] | value[1] << 8 |
-				   value[2] << 16 | value[3] << 24;
-
-			break;
-		case 0x600:/* AFE - read byte */
-			ret = cx231xx_read_i2c_master(dev, AFE_DEVICE_ADDRESS,
-						 (u16)reg->reg, 2,
-						 &data, 1 , 0);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-
-		case 0x880:/* Video Block - read byte */
-			if (reg->reg < 0x0b) {
-				ret = cx231xx_read_i2c_master(dev,
-						VID_BLK_I2C_ADDRESS,
-						 (u16)reg->reg, 2,
-						 &data, 1 , 0);
-				reg->val = le32_to_cpu(data & 0xff);
-			} else {
-				ret = cx231xx_read_i2c_master(dev,
-						VID_BLK_I2C_ADDRESS,
-						 (u16)reg->reg, 2,
-						 &data, 4 , 0);
-				reg->val = le32_to_cpu(data);
-			}
-			break;
-		case 0x980:
-			ret = cx231xx_read_i2c_master(dev,
-						I2S_BLK_DEVICE_ADDRESS,
-						(u16)reg->reg, 1,
-						&data, 1 , 0);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 0x400:
-			ret =
-			    cx231xx_read_i2c_master(dev, 0x40,
-						  (u16)reg->reg, 1,
-						 &data, 1 , 0);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 0xc01:
-			ret =
-				cx231xx_read_i2c_master(dev, 0xc0,
-						(u16)reg->reg, 2,
-						 &data, 38, 1);
-			reg->val = le32_to_cpu(data);
-			break;
-		case 0x022:
-			ret =
-				cx231xx_read_i2c_master(dev, 0x02,
-						(u16)reg->reg, 1,
-						 &data, 1, 2);
-			reg->val = le32_to_cpu(data & 0xff);
-			break;
-		case 0x322:
-			ret = cx231xx_read_i2c_master(dev,
-						0x32,
-						 (u16)reg->reg, 1,
-						 &data, 4 , 2);
-				reg->val = le32_to_cpu(data);
-			break;
-		case 0x342:
-			ret = cx231xx_read_i2c_master(dev,
-						0x34,
-						 (u16)reg->reg, 1,
-						 &data, 4 , 2);
-				reg->val = le32_to_cpu(data);
-			break;
-
-		default:
-			cx231xx_info("no match device address!!\n");
-			break;
-			}
-		return ret < 0 ? ret : 0;
-		/*return -EINVAL;*/
+	switch (reg->match.addr) {
+	case 0:	/* Cx231xx - internal registers */
+		ret = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
+				(u16)reg->reg, value, 4);
+		reg->val = value[0] | value[1] << 8 |
+			value[2] << 16 | value[3] << 24;
+		reg->size = 4;
+		break;
+	case 1:	/* AFE - read byte */
+		ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+				(u16)reg->reg, 2, &data, 1);
+		reg->val = data;
+		reg->size = 1;
+		break;
+	case 2:	/* Video Block - read byte */
+		ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+				(u16)reg->reg, 2, &data, 1);
+		reg->val = data;
+		reg->size = 1;
+		break;
+	case 3:	/* I2S block - read byte */
+		ret = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+				(u16)reg->reg, 1, &data, 1);
+		reg->val = data;
+		reg->size = 1;
+		break;
+	case 4: /* AFE - read dword */
+		ret = cx231xx_read_i2c_data(dev, AFE_DEVICE_ADDRESS,
+				(u16)reg->reg, 2, &data, 4);
+		reg->val = data;
+		reg->size = 4;
+		break;
+	case 5: /* Video Block - read dword */
+		ret = cx231xx_read_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+				(u16)reg->reg, 2, &data, 4);
+		reg->val = data;
+		reg->size = 4;
+		break;
+	case 6: /* I2S Block - read dword */
+		ret = cx231xx_read_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+				(u16)reg->reg, 1, &data, 4);
+		reg->val = data;
+		reg->size = 4;
+		break;
 	default:
-		if (!v4l2_chip_match_host(&reg->match))
-			return -EINVAL;
+		return -EINVAL;
 	}
-
-	call_all(dev, core, g_register, reg);
-
-	return ret;
+	return ret < 0 ? ret : 0;
 }
 
 int cx231xx_s_register(struct file *file, void *priv,
@@ -1408,165 +1321,46 @@
 {
 	struct cx231xx_fh *fh = priv;
 	struct cx231xx *dev = fh->dev;
-	int ret = 0;
-	__le64 buf;
-	u32 value;
+	int ret;
 	u8 data[4] = { 0, 0, 0, 0 };
 
-	buf = cpu_to_le64(reg->val);
-
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		{
-			value = (u32) buf & 0xffffffff;
-
-			switch (reg->match.addr) {
-			case 0:	/* cx231xx internal registers */
-				data[0] = (u8) value;
-				data[1] = (u8) (value >> 8);
-				data[2] = (u8) (value >> 16);
-				data[3] = (u8) (value >> 24);
-				ret = cx231xx_write_ctrl_reg(dev,
-							   VRT_SET_REGISTER,
-							   (u16)reg->reg, data,
-							   4);
-				break;
-			case 1:	/* AFE - read byte */
-				ret = cx231xx_write_i2c_data(dev,
-							AFE_DEVICE_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 1);
-				break;
-			case 14: /* AFE - read dword */
-				ret = cx231xx_write_i2c_data(dev,
-							AFE_DEVICE_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 4);
-				break;
-			case 2:	/* Video Block - read byte */
-				ret =
-				    cx231xx_write_i2c_data(dev,
-							VID_BLK_I2C_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 1);
-				break;
-			case 24: /* Video Block - read dword */
-				ret =
-				    cx231xx_write_i2c_data(dev,
-							VID_BLK_I2C_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 4);
-				break;
-			case 3:	/* I2S block - read byte */
-				ret =
-				    cx231xx_write_i2c_data(dev,
-							I2S_BLK_DEVICE_ADDRESS,
-							(u16)reg->reg, 1,
-							value, 1);
-				break;
-			case 34: /* I2S block - read dword */
-				ret =
-				    cx231xx_write_i2c_data(dev,
-							I2S_BLK_DEVICE_ADDRESS,
-							(u16)reg->reg, 1,
-							value, 4);
-				break;
-			}
-		}
-		return ret < 0 ? ret : 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		{
-			value = (u32) buf & 0xffffffff;
-
-			switch (reg->match.addr) {
-			case 0:/*cx231xx internal registers*/
-					data[0] = (u8) value;
-					data[1] = (u8) (value >> 8);
-					data[2] = (u8) (value >> 16);
-					data[3] = (u8) (value >> 24);
-					ret = cx231xx_write_ctrl_reg(dev,
-							   VRT_SET_REGISTER,
-							   (u16)reg->reg, data,
-							   4);
-					break;
-			case 0x600:/* AFE - read byte */
-					ret = cx231xx_write_i2c_master(dev,
-							AFE_DEVICE_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 1 , 0);
-					break;
-
-			case 0x880:/* Video Block - read byte */
-					if (reg->reg < 0x0b)
-						cx231xx_write_i2c_master(dev,
-							VID_BLK_I2C_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 1, 0);
-					else
-						cx231xx_write_i2c_master(dev,
-							VID_BLK_I2C_ADDRESS,
-							(u16)reg->reg, 2,
-							value, 4, 0);
-					break;
-			case 0x980:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							I2S_BLK_DEVICE_ADDRESS,
-							(u16)reg->reg, 1,
-							value, 1, 0);
-					break;
-			case 0x400:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							0x40,
-							(u16)reg->reg, 1,
-							value, 1, 0);
-					break;
-			case 0xc01:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							 0xc0,
-							 (u16)reg->reg, 1,
-							 value, 1, 1);
-					break;
-
-			case 0x022:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							0x02,
-							(u16)reg->reg, 1,
-							value, 1, 2);
-					break;
-			case 0x322:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							0x32,
-							(u16)reg->reg, 1,
-							value, 4, 2);
-					break;
-
-			case 0x342:
-					ret =
-						cx231xx_write_i2c_master(dev,
-							0x34,
-							(u16)reg->reg, 1,
-							value, 4, 2);
-					break;
-			default:
-				cx231xx_info("no match device address, "
-					"the value is %x\n", reg->match.addr);
-					break;
-
-					}
-
-		}
-	default:
+	switch (reg->match.addr) {
+	case 0:	/* cx231xx internal registers */
+		data[0] = (u8) reg->val;
+		data[1] = (u8) (reg->val >> 8);
+		data[2] = (u8) (reg->val >> 16);
+		data[3] = (u8) (reg->val >> 24);
+		ret = cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
+				(u16)reg->reg, data, 4);
 		break;
+	case 1:	/* AFE - write byte */
+		ret = cx231xx_write_i2c_data(dev, AFE_DEVICE_ADDRESS,
+				(u16)reg->reg, 2, reg->val, 1);
+		break;
+	case 2:	/* Video Block - write byte */
+		ret = cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+				(u16)reg->reg, 2, reg->val, 1);
+		break;
+	case 3:	/* I2S block - write byte */
+		ret = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+				(u16)reg->reg, 1, reg->val, 1);
+		break;
+	case 4: /* AFE - write dword */
+		ret = cx231xx_write_i2c_data(dev, AFE_DEVICE_ADDRESS,
+				(u16)reg->reg, 2, reg->val, 4);
+		break;
+	case 5: /* Video Block - write dword */
+		ret = cx231xx_write_i2c_data(dev, VID_BLK_I2C_ADDRESS,
+				(u16)reg->reg, 2, reg->val, 4);
+		break;
+	case 6: /* I2S block - write dword */
+		ret = cx231xx_write_i2c_data(dev, I2S_BLK_DEVICE_ADDRESS,
+				(u16)reg->reg, 1, reg->val, 4);
+		break;
+	default:
+		return -EINVAL;
 	}
-
-	call_all(dev, core, s_register, reg);
-
-	return ret;
+	return ret < 0 ? ret : 0;
 }
 #endif
 
@@ -2208,8 +2002,8 @@
 	.vidioc_s_tuner                = cx231xx_s_tuner,
 	.vidioc_g_frequency            = cx231xx_g_frequency,
 	.vidioc_s_frequency            = cx231xx_s_frequency,
-	.vidioc_g_chip_ident           = cx231xx_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_chip_info            = cx231xx_g_chip_info,
 	.vidioc_g_register             = cx231xx_g_register,
 	.vidioc_s_register             = cx231xx_s_register,
 #endif
@@ -2240,8 +2034,8 @@
 	.vidioc_s_tuner     = radio_s_tuner,
 	.vidioc_g_frequency = cx231xx_g_frequency,
 	.vidioc_s_frequency = cx231xx_s_frequency,
-	.vidioc_g_chip_ident = cx231xx_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_chip_info = cx231xx_g_chip_info,
 	.vidioc_g_register  = cx231xx_g_register,
 	.vidioc_s_register  = cx231xx_s_register,
 #endif
diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h
index 5ad9fd6..e812119 100644
--- a/drivers/media/usb/cx231xx/cx231xx.h
+++ b/drivers/media/usb/cx231xx/cx231xx.h
@@ -945,7 +945,7 @@
 			     struct v4l2_input *i);
 int cx231xx_g_input(struct file *file, void *priv, unsigned int *i);
 int cx231xx_s_input(struct file *file, void *priv, unsigned int i);
-int cx231xx_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip);
+int cx231xx_g_chip_info(struct file *file, void *fh, struct v4l2_dbg_chip_info *chip);
 int cx231xx_g_register(struct file *file, void *priv,
 			     struct v4l2_dbg_register *reg);
 int cx231xx_s_register(struct file *file, void *priv,
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index b638fc1..1ea17dc 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -55,7 +55,7 @@
 	if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
 			req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
 		dev_err(&d->udev->dev, "%s: too much data wlen=%d rlen=%d\n",
-				__func__, req->wlen, req->rlen);
+				KBUILD_MODNAME, req->wlen, req->rlen);
 		ret = -EINVAL;
 		goto exit;
 	}
@@ -91,9 +91,10 @@
 	checksum = af9035_checksum(state->buf, rlen - 2);
 	tmp_checksum = (state->buf[rlen - 2] << 8) | state->buf[rlen - 1];
 	if (tmp_checksum != checksum) {
-		dev_err(&d->udev->dev, "%s: command=%02x checksum mismatch " \
-				"(%04x != %04x)\n", KBUILD_MODNAME, req->cmd,
-				tmp_checksum, checksum);
+		dev_err(&d->udev->dev,
+				"%s: command=%02x checksum mismatch (%04x != %04x)\n",
+				KBUILD_MODNAME, req->cmd, tmp_checksum,
+				checksum);
 		ret = -EIO;
 		goto exit;
 	}
@@ -268,11 +269,29 @@
 			memcpy(&buf[5], msg[0].buf, msg[0].len);
 			ret = af9035_ctrl_msg(d, &req);
 		}
+	} else if (num == 1 && (msg[0].flags & I2C_M_RD)) {
+		if (msg[0].len > 40) {
+			/* TODO: correct limits > 40 */
+			ret = -EOPNOTSUPP;
+		} else {
+			/* I2C */
+			u8 buf[5];
+			struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
+					buf, msg[0].len, msg[0].buf };
+			req.mbox |= ((msg[0].addr & 0x80)  >>  3);
+			buf[0] = msg[0].len;
+			buf[1] = msg[0].addr << 1;
+			buf[2] = 0x00; /* reg addr len */
+			buf[3] = 0x00; /* reg addr MSB */
+			buf[4] = 0x00; /* reg addr LSB */
+			ret = af9035_ctrl_msg(d, &req);
+		}
 	} else {
 		/*
-		 * We support only two kind of I2C transactions:
-		 * 1) 1 x read + 1 x write
+		 * We support only three kind of I2C transactions:
+		 * 1) 1 x read + 1 x write (repeated start)
 		 * 2) 1 x write
+		 * 3) 1 x read
 		 */
 		ret = -EOPNOTSUPP;
 	}
@@ -317,8 +336,8 @@
 
 	dev_info(&d->udev->dev,
 			"%s: prechip_version=%02x chip_version=%02x chip_type=%04x\n",
-			__func__, state->prechip_version, state->chip_version,
-			state->chip_type);
+			KBUILD_MODNAME, state->prechip_version,
+			state->chip_version, state->chip_type);
 
 	if (state->chip_type == 0x9135) {
 		if (state->chip_version == 0x02)
@@ -382,9 +401,10 @@
 		hdr_checksum = fw->data[fw->size - i + 5] << 8;
 		hdr_checksum |= fw->data[fw->size - i + 6] << 0;
 
-		dev_dbg(&d->udev->dev, "%s: core=%d addr=%04x data_len=%d " \
-				"checksum=%04x\n", __func__, hdr_core, hdr_addr,
-				hdr_data_len, hdr_checksum);
+		dev_dbg(&d->udev->dev,
+				"%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
+				__func__, hdr_core, hdr_addr, hdr_data_len,
+				hdr_checksum);
 
 		if (((hdr_core != 1) && (hdr_core != 2)) ||
 				(hdr_data_len > i)) {
@@ -489,7 +509,7 @@
 	u8 rbuf[4];
 	u8 tmp;
 	struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
-	struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
+	struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf };
 	dev_dbg(&d->udev->dev, "%s:\n", __func__);
 
 	/*
@@ -498,11 +518,11 @@
 	 * which is done by master demod.
 	 * Master feeds also clock and controls power via GPIO.
 	 */
-	ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_DUAL_MODE, &tmp);
+	ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
 	if (ret < 0)
 		goto err;
 
-	if (tmp) {
+	if (tmp == 1 || tmp == 3) {
 		/* configure gpioh1, reset & power slave demod */
 		ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01);
 		if (ret < 0)
@@ -620,13 +640,15 @@
 	}
 
 	/* check if there is dual tuners */
-	ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_DUAL_MODE, &tmp);
+	ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
 	if (ret < 0)
 		goto err;
 
-	state->dual_mode = tmp;
-	dev_dbg(&d->udev->dev, "%s: dual mode=%d\n", __func__,
-			state->dual_mode);
+	if (tmp == 1 || tmp == 3)
+		state->dual_mode = true;
+
+	dev_dbg(&d->udev->dev, "%s: ts mode=%d dual mode=%d\n", __func__,
+			tmp, state->dual_mode);
 
 	if (state->dual_mode) {
 		/* read 2nd demodulator I2C address */
@@ -1200,9 +1222,9 @@
 		{ 0x80f9a4, 0x00, 0x01 },
 	};
 
-	dev_dbg(&d->udev->dev, "%s: USB speed=%d frame_size=%04x " \
-			"packet_size=%02x\n", __func__,
-			d->udev->speed, frame_size, packet_size);
+	dev_dbg(&d->udev->dev,
+			"%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
+			__func__, d->udev->speed, frame_size, packet_size);
 
 	/* init endpoints */
 	for (i = 0; i < ARRAY_SIZE(tab); i++) {
@@ -1477,7 +1499,7 @@
 		&af9035_props, "AVerMedia Twinstar (A825)", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100MINI_PLUS,
 		&af9035_props, "Asus U3100Mini Plus", NULL) },
-        { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa,
+	{ DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa,
 		&af9035_props, "TerraTec Cinergy T Stick (rev. 2)", NULL) },
 	/* IT9135 devices */
 #if 0
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h
index b5827ca..a1c68d8 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.h
+++ b/drivers/media/usb/dvb-usb-v2/af9035.h
@@ -100,8 +100,13 @@
  * eeprom is memory mapped as read only. Writing that memory mapped address
  * will not corrupt eeprom.
  *
- * eeprom has value 0x00 single mode and 0x03 for dual mode as far as I have
- * seen to this day.
+ * TS mode:
+ * 0  TS
+ * 1  DCA + PIP
+ * 3  PIP
+ * n  DCA
+ *
+ * Values 0 and 3 are seen to this day. 0 for single TS and 3 for dual TS.
  */
 
 #define EEPROM_BASE_AF9035        0x42fd
@@ -109,7 +114,7 @@
 #define EEPROM_SHIFT                0x10
 
 #define EEPROM_IR_MODE              0x10
-#define EEPROM_DUAL_MODE            0x29
+#define EEPROM_TS_MODE              0x29
 #define EEPROM_2ND_DEMOD_ADDR       0x2a
 #define EEPROM_IR_TYPE              0x2c
 #define EEPROM_1_IF_L               0x30
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
index 658c6d4..399916b 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
@@ -140,7 +140,7 @@
 	int (*change_protocol)(struct rc_dev *dev, u64 *rc_type);
 	int (*query) (struct dvb_usb_device *d);
 	unsigned int interval;
-	const enum rc_driver_type driver_type;
+	enum rc_driver_type driver_type;
 	bool bulk_mode;
 };
 
diff --git a/drivers/media/usb/dvb-usb-v2/it913x.c b/drivers/media/usb/dvb-usb-v2/it913x.c
index e48cdeb..1cb6899 100644
--- a/drivers/media/usb/dvb-usb-v2/it913x.c
+++ b/drivers/media/usb/dvb-usb-v2/it913x.c
@@ -45,7 +45,7 @@
 
 static int dvb_usb_it913x_firmware;
 module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644);
-MODULE_PARM_DESC(firmware, "set firmware 0=auto"\
+MODULE_PARM_DESC(firmware, "set firmware 0=auto "\
 	"1=IT9137 2=IT9135 V1 3=IT9135 V2");
 #define FW_IT9137 "dvb-usb-it9137-01.fw"
 #define FW_IT9135_V1 "dvb-usb-it9135-01.fw"
@@ -796,6 +796,9 @@
 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_4835,
 		&it913x_properties, "Avermedia A835B(4835)",
 			RC_MAP_IT913X_V2) },
+	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2,
+		&it913x_properties, "Digital Dual TV Receiver CTVDIGDUAL_V2",
+			RC_MAP_IT913X_V1) },
 	{}		/* Terminating entry */
 };
 
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
index ef4c65f..879c529 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
@@ -31,8 +31,6 @@
 	if (mxl111sf_tuner_debug) \
 		mxl_printk(KERN_DEBUG, fmt, ##arg)
 
-#define err pr_err
-
 /* ------------------------------------------------------------------------ */
 
 struct mxl111sf_tuner_state {
@@ -113,7 +111,7 @@
 		filt_bw = 63;
 		break;
 	default:
-		err("%s: invalid bandwidth setting!", __func__);
+		pr_err("%s: invalid bandwidth setting!", __func__);
 		return NULL;
 	}
 
@@ -304,12 +302,12 @@
 			bw = 8;
 			break;
 		default:
-			err("%s: bandwidth not set!", __func__);
+			pr_err("%s: bandwidth not set!", __func__);
 			return -EINVAL;
 		}
 		break;
 	default:
-		err("%s: modulation type not supported!", __func__);
+		pr_err("%s: modulation type not supported!", __func__);
 		return -EINVAL;
 	}
 	ret = mxl1x1sf_tune_rf(fe, c->frequency, bw);
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
index efdcb15..e97964e 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -52,12 +52,6 @@
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
-#define deb_info pr_debug
-#define deb_reg pr_debug
-#define deb_adv pr_debug
-#define err pr_err
-#define info pr_info
-
 int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
 		      u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
@@ -65,7 +59,7 @@
 	int ret;
 	u8 sndbuf[1+wlen];
 
-	deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
+	pr_debug("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
 
 	memset(sndbuf, 0, 1+wlen);
 
@@ -98,12 +92,12 @@
 	if (buf[0] == addr)
 		*data = buf[1];
 	else {
-		err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
+		pr_err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
 		    addr, buf[0], buf[1]);
 		ret = -EINVAL;
 	}
 
-	deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
+	pr_debug("R: (0x%02x, 0x%02x)\n", addr, *data);
 fail:
 	return ret;
 }
@@ -113,11 +107,11 @@
 	u8 buf[] = { addr, data };
 	int ret;
 
-	deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
+	pr_debug("W: (0x%02x, 0x%02x)\n", addr, data);
 
 	ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
 	if (mxl_fail(ret))
-		err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
+		pr_err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
 	return ret;
 }
 
@@ -134,7 +128,7 @@
 #if 1
 		/* dont know why this usually errors out on the first try */
 		if (mxl_fail(ret))
-			err("error writing addr: 0x%02x, mask: 0x%02x, "
+			pr_err("error writing addr: 0x%02x, mask: 0x%02x, "
 			    "data: 0x%02x, retrying...", addr, mask, data);
 
 		ret = mxl111sf_read_reg(state, addr, &val);
@@ -167,7 +161,7 @@
 					      ctrl_reg_info[i].mask,
 					      ctrl_reg_info[i].data);
 		if (mxl_fail(ret)) {
-			err("failed on reg #%d (0x%02x)", i,
+			pr_err("failed on reg #%d (0x%02x)", i,
 			    ctrl_reg_info[i].addr);
 			break;
 		}
@@ -225,7 +219,7 @@
 		mxl_rev = "UNKNOWN REVISION";
 		break;
 	}
-	info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
+	pr_info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
 fail:
 	return ret;
 }
@@ -239,7 +233,7 @@
 			  " on first probe attempt");			\
 		___ret = mxl1x1sf_get_chip_info(state);			\
 		if (mxl_fail(___ret))					\
-			err("failed to get chip info during probe");	\
+			pr_err("failed to get chip info during probe");	\
 		else							\
 			mxl_debug("probe needed a retry "		\
 				  "in order to succeed.");		\
@@ -270,14 +264,14 @@
 		goto fail;
 	}
 
-	deb_info("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	mutex_lock(&state->fe_lock);
 
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	err = mxl1x1sf_soft_reset(state);
 	mxl_fail(err);
@@ -326,7 +320,7 @@
 		goto fail;
 	}
 
-	deb_info("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
 
@@ -344,7 +338,7 @@
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
 	int ret = 0;
 
-	deb_info("%s(%d)\n", __func__, onoff);
+	pr_debug("%s(%d)\n", __func__, onoff);
 
 	if (onoff) {
 		ret = mxl111sf_enable_usb_output(state);
@@ -368,7 +362,7 @@
 	struct mxl111sf_state *state = fe_to_priv(fe);
 	int ret = 0;
 
-	deb_info("%s(%d)\n", __func__, onoff);
+	pr_debug("%s(%d)\n", __func__, onoff);
 
 	if (onoff) {
 		ret = mxl111sf_enable_usb_output(state);
@@ -394,7 +388,7 @@
 	struct mxl111sf_state *state = fe_to_priv(fe);
 	int ret = 0;
 
-	deb_info("%s(%d)\n", __func__, onoff);
+	pr_debug("%s(%d)\n", __func__, onoff);
 
 	if (onoff) {
 		ret = mxl111sf_enable_usb_output(state);
@@ -424,7 +418,7 @@
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
 	int ret;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	/* save a pointer to the dvb_usb_device in device state */
 	state->d = d;
@@ -432,7 +426,7 @@
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
 	adap_state->gpio_mode = state->gpio_mode;
@@ -495,7 +489,7 @@
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
 	int ret;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	/* save a pointer to the dvb_usb_device in device state */
 	state->d = d;
@@ -503,7 +497,7 @@
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	state->gpio_mode = MXL111SF_GPIO_MOD_MH;
 	adap_state->gpio_mode = state->gpio_mode;
@@ -580,7 +574,7 @@
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
 	int ret;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	/* save a pointer to the dvb_usb_device in device state */
 	state->d = d;
@@ -588,7 +582,7 @@
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	state->gpio_mode = MXL111SF_GPIO_MOD_MH;
 	adap_state->gpio_mode = state->gpio_mode;
@@ -667,7 +661,7 @@
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
 	int ret;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	/* save a pointer to the dvb_usb_device in device state */
 	state->d = d;
@@ -675,7 +669,7 @@
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	state->gpio_mode = MXL111SF_GPIO_MOD_MH;
 	adap_state->gpio_mode = state->gpio_mode;
@@ -742,7 +736,7 @@
 	struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
 	int ret;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	/* save a pointer to the dvb_usb_device in device state */
 	state->d = d;
@@ -750,7 +744,7 @@
 	state->alt_mode = adap_state->alt_mode;
 
 	if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
-		err("set interface failed");
+		pr_err("set interface failed");
 
 	state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
 	adap_state->gpio_mode = state->gpio_mode;
@@ -802,7 +796,7 @@
 }
 
 #define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
-	err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
+	pr_err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
 	    __func__, __LINE__, \
 	    (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
 	    pwr0, pwr1, pwr2, pwr3)
@@ -868,7 +862,7 @@
 	struct mxl111sf_state *state = adap_to_priv(adap);
 	int i;
 
-	deb_adv("%s()\n", __func__);
+	pr_debug("%s()\n", __func__);
 
 	for (i = 0; i < state->num_frontends; i++) {
 		if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state,
@@ -902,7 +896,7 @@
 
 	ret = get_chip_info(state);
 	if (mxl_fail(ret))
-		err("failed to get chip info during probe");
+		pr_err("failed to get chip info during probe");
 
 	mutex_init(&state->fe_lock);
 
@@ -950,7 +944,7 @@
 static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)
 {
 	int ret;
-	deb_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 
 	ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
 	if (ret < 0)
@@ -970,7 +964,7 @@
 static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
 {
 	int ret;
-	deb_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 
 	ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
 	if (ret < 0)
@@ -990,7 +984,7 @@
 static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
 {
 	int ret;
-	deb_info("%s\n", __func__);
+	pr_debug("%s\n", __func__);
 
 	ret = mxl111sf_attach_demod(adap, 0);
 	if (ret < 0)
@@ -1006,7 +1000,7 @@
 
 static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint)
 {
-	deb_info("%s: endpoint=%d size=8192\n", __func__, endpoint);
+	pr_debug("%s: endpoint=%d size=8192\n", __func__, endpoint);
 	stream->type = USB_BULK;
 	stream->count = 5;
 	stream->endpoint = endpoint;
@@ -1016,7 +1010,7 @@
 static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream,
 		u8 endpoint, int framesperurb, int framesize)
 {
-	deb_info("%s: endpoint=%d size=%d\n", __func__, endpoint,
+	pr_debug("%s: endpoint=%d size=%d\n", __func__, endpoint,
 			framesperurb * framesize);
 	stream->type = USB_ISOC;
 	stream->count = 5;
@@ -1035,7 +1029,7 @@
 static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	*ts_type = DVB_USB_FE_TS_TYPE_188;
 	if (dvb_usb_mxl111sf_isoc)
@@ -1076,7 +1070,7 @@
 static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	*ts_type = DVB_USB_FE_TS_TYPE_188;
 	if (dvb_usb_mxl111sf_isoc)
@@ -1117,7 +1111,7 @@
 static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	*ts_type = DVB_USB_FE_TS_TYPE_RAW;
 	if (dvb_usb_mxl111sf_isoc)
@@ -1158,7 +1152,7 @@
 static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	if (fe->id == 0) {
 		*ts_type = DVB_USB_FE_TS_TYPE_188;
@@ -1184,7 +1178,7 @@
 
 static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff)
 {
-	deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+	pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
 
 	if (fe->id == 0)
 		return mxl111sf_ep6_streaming_ctrl(fe, onoff);
@@ -1228,7 +1222,7 @@
 static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	if (fe->id == 0) {
 		*ts_type = DVB_USB_FE_TS_TYPE_188;
@@ -1260,7 +1254,7 @@
 
 static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff)
 {
-	deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+	pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
 
 	if (fe->id == 0)
 		return mxl111sf_ep6_streaming_ctrl(fe, onoff);
@@ -1306,7 +1300,7 @@
 static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe,
 		u8 *ts_type, struct usb_data_stream_properties *stream)
 {
-	deb_info("%s: fe=%d\n", __func__, fe->id);
+	pr_debug("%s: fe=%d\n", __func__, fe->id);
 
 	if (fe->id == 0) {
 		*ts_type = DVB_USB_FE_TS_TYPE_188;
@@ -1332,7 +1326,7 @@
 
 static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff)
 {
-	deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
+	pr_debug("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
 
 	if (fe->id == 0)
 		return mxl111sf_ep4_streaming_ctrl(fe, onoff);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index 2cc8ec7..c0cd084 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1041,67 +1041,34 @@
 static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
 {
 	int ret;
-	u8 val;
 
 	dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
 
 	if (onoff) {
-		/* set output values */
-		ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
+		/* GPIO3=1, GPIO4=0 */
+		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x08, 0x18);
 		if (ret)
 			goto err;
 
-		val |= 0x08;
-		val &= 0xef;
-
-		ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
+		/* suspend? */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL1, 0x00, 0x10);
 		if (ret)
 			goto err;
 
-		/* demod_ctl_1 */
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
+		/* enable PLL */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x80, 0x80);
 		if (ret)
 			goto err;
 
-		val &= 0xef;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
-		if (ret)
-			goto err;
-
-		/* demod control */
-		/* PLL enable */
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
-		if (ret)
-			goto err;
-
-		/* bit 7 to 1 */
-		val |= 0x80;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
-		if (ret)
-			goto err;
-
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
-		if (ret)
-			goto err;
-
-		val |= 0x20;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+		/* disable reset */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x20, 0x20);
 		if (ret)
 			goto err;
 
 		mdelay(5);
 
-		/*enable ADC_Q and ADC_I */
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
-		if (ret)
-			goto err;
-
-		val |= 0x48;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+		/* enable ADC */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x48, 0x48);
 		if (ret)
 			goto err;
 
@@ -1114,36 +1081,18 @@
 		if (ret)
 			goto err;
 	} else {
-		/* demod_ctl_1 */
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
+		/* GPIO4=1 */
+		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x10, 0x10);
 		if (ret)
 			goto err;
 
-		val |= 0x0c;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
+		/* disable ADC */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x48);
 		if (ret)
 			goto err;
 
-		/* set output values */
-		ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
-		if (ret)
-				goto err;
-
-		val |= 0x10;
-
-		ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
-		if (ret)
-			goto err;
-
-		/* demod control */
-		ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
-		if (ret)
-			goto err;
-
-		val &= 0x37;
-
-		ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
+		/* disable PLL */
+		ret = rtl28xx_wr_reg_mask(d, SYS_DEMOD_CTL, 0x00, 0x80);
 		if (ret)
 			goto err;
 
@@ -1242,42 +1191,47 @@
 
 	return 0;
 }
-#else
-	#define rtl2831u_get_rc_config NULL
-#endif
 
-#if IS_ENABLED(CONFIG_RC_CORE)
 static int rtl2832u_rc_query(struct dvb_usb_device *d)
 {
-	int ret, i;
+	int ret, i, len;
 	struct rtl28xxu_priv *priv = d->priv;
+	struct ir_raw_event ev;
 	u8 buf[128];
-	int len;
-	struct rtl28xxu_reg_val rc_nec_tab[] = {
-		{ IR_RX_CTRL,             0x20 },
-		{ IR_RX_BUF_CTRL,         0x80 },
-		{ IR_RX_IF,               0xff },
-		{ IR_RX_IE,               0xff },
-		{ IR_MAX_DURATION0,       0xd0 },
-		{ IR_MAX_DURATION1,       0x07 },
-		{ IR_IDLE_LEN0,           0xc0 },
-		{ IR_IDLE_LEN1,           0x00 },
-		{ IR_GLITCH_LEN,          0x03 },
-		{ IR_RX_CLK,              0x09 },
-		{ IR_RX_CFG,              0x1c },
-		{ IR_MAX_H_TOL_LEN,       0x1e },
-		{ IR_MAX_L_TOL_LEN,       0x1e },
-		{ IR_RX_CTRL,             0x80 },
+	static const struct rtl28xxu_reg_val_mask refresh_tab[] = {
+		{IR_RX_IF,               0x03, 0xff},
+		{IR_RX_BUF_CTRL,         0x80, 0xff},
+		{IR_RX_CTRL,             0x80, 0xff},
 	};
 
 	/* init remote controller */
 	if (!priv->rc_active) {
-		for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
-			ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
-					rc_nec_tab[i].val);
+		static const struct rtl28xxu_reg_val_mask init_tab[] = {
+			{SYS_DEMOD_CTL1,         0x00, 0x04},
+			{SYS_DEMOD_CTL1,         0x00, 0x08},
+			{USB_CTRL,               0x20, 0x20},
+			{SYS_GPIO_DIR,           0x00, 0x08},
+			{SYS_GPIO_OUT_EN,        0x08, 0x08},
+			{SYS_GPIO_OUT_VAL,       0x08, 0x08},
+			{IR_MAX_DURATION0,       0xd0, 0xff},
+			{IR_MAX_DURATION1,       0x07, 0xff},
+			{IR_IDLE_LEN0,           0xc0, 0xff},
+			{IR_IDLE_LEN1,           0x00, 0xff},
+			{IR_GLITCH_LEN,          0x03, 0xff},
+			{IR_RX_CLK,              0x09, 0xff},
+			{IR_RX_CFG,              0x1c, 0xff},
+			{IR_MAX_H_TOL_LEN,       0x1e, 0xff},
+			{IR_MAX_L_TOL_LEN,       0x1e, 0xff},
+			{IR_RX_CTRL,             0x80, 0xff},
+		};
+
+		for (i = 0; i < ARRAY_SIZE(init_tab); i++) {
+			ret = rtl28xx_wr_reg_mask(d, init_tab[i].reg,
+					init_tab[i].val, init_tab[i].mask);
 			if (ret)
 				goto err;
 		}
+
 		priv->rc_active = true;
 	}
 
@@ -1293,14 +1247,32 @@
 		goto err;
 
 	len = buf[0];
+
+	/* read raw code from hw */
 	ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
+	if (ret)
+		goto err;
 
-	/* TODO: pass raw IR to Kernel IR decoder */
+	/* let hw receive new code */
+	for (i = 0; i < ARRAY_SIZE(refresh_tab); i++) {
+		ret = rtl28xx_wr_reg_mask(d, refresh_tab[i].reg,
+				refresh_tab[i].val, refresh_tab[i].mask);
+		if (ret)
+			goto err;
+	}
 
-	ret = rtl28xx_wr_reg(d, IR_RX_IF, 0x03);
-	ret = rtl28xx_wr_reg(d, IR_RX_BUF_CTRL, 0x80);
-	ret = rtl28xx_wr_reg(d, IR_RX_CTRL, 0x80);
+	/* pass data to Kernel IR decoder */
+	init_ir_raw_event(&ev);
 
+	for (i = 0; i < len; i++) {
+		ev.pulse = buf[i] >> 7;
+		ev.duration = 50800 * (buf[i] & 0x7f);
+		ir_raw_event_store_with_filter(d->rc_dev, &ev);
+	}
+
+	/* 'flush' ir_raw_event_store_with_filter() */
+	ir_raw_event_set_idle(d->rc_dev, true);
+	ir_raw_event_handle(d->rc_dev);
 exit:
 	return ret;
 err:
@@ -1311,15 +1283,19 @@
 static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
 		struct dvb_usb_rc *rc)
 {
-	rc->map_name = RC_MAP_EMPTY;
-	rc->allowed_protos = RC_BIT_NEC;
+	/* load empty to enable rc */
+	if (!rc->map_name)
+		rc->map_name = RC_MAP_EMPTY;
+	rc->allowed_protos = RC_BIT_ALL;
+	rc->driver_type = RC_DRIVER_IR_RAW;
 	rc->query = rtl2832u_rc_query;
 	rc->interval = 400;
 
 	return 0;
 }
 #else
-	#define rtl2832u_get_rc_config NULL
+#define rtl2831u_get_rc_config NULL
+#define rtl2832u_get_rc_config NULL
 #endif
 
 static const struct dvb_usb_device_properties rtl2831u_props = {
@@ -1379,7 +1355,7 @@
 	{ DVB_USB_DEVICE(USB_VID_REALTEK, 0x2838,
 		&rtl2832u_props, "Realtek RTL2832U reference design", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1,
-		&rtl2832u_props, "TerraTec Cinergy T Stick Black", NULL) },
+		&rtl2832u_props, "TerraTec Cinergy T Stick Black", RC_MAP_TERRATEC_SLIM) },
 	{ DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_DELOCK_USB2_DVBT,
 		&rtl2832u_props, "G-Tek Electronics Group Lifeview LV5TDLX DVB-T", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK,
@@ -1403,11 +1379,15 @@
 	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd393,
 		&rtl2832u_props, "GIGABYTE U7300", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1104,
-		&rtl2832u_props, "Digivox Micro Hd", NULL) },
+		&rtl2832u_props, "MSI DIGIVOX Micro HD", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_COMPRO, 0x0620,
 		&rtl2832u_props, "Compro VideoMate U620F", NULL) },
 	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, 0xd394,
 		&rtl2832u_props, "MaxMedia HU394-T", NULL) },
+	{ DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a03,
+		&rtl2832u_props, "Leadtek WinFast DTV Dongle mini", NULL) },
+	{ DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_CPYTO_REDI_PC50A,
+		&rtl2832u_props, "Crypto ReDi PC 50 A", NULL) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
index 533a331..729b354 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
@@ -97,6 +97,12 @@
 	u8 val;
 };
 
+struct rtl28xxu_reg_val_mask {
+	u16 reg;
+	u8 val;
+	u8 mask;
+};
+
 /*
  * memory map
  *
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
index 91e0119..ea2d5ee 100644
--- a/drivers/media/usb/dvb-usb/az6027.c
+++ b/drivers/media/usb/dvb-usb/az6027.c
@@ -264,7 +264,7 @@
 	.demod_address 		= 0xd0, /* 0x68, 0xd0 >> 1 */
 
 	.xtal_freq		= 27000000,
-	.inversion		= IQ_SWAP_ON, /* 1 */
+	.inversion		= IQ_SWAP_ON,
 
 	.lo_clk			= 76500000,
 	.hi_clk			= 99000000,
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index d1ddfa1..449a996 100644
--- a/drivers/media/usb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -828,7 +828,7 @@
 	.block_sync_mode = STB0899_SYNC_FORCED, /* ? */
 
 	.xtal_freq       = 27000000,	 /* Assume Hz ? */
-	.inversion       = IQ_SWAP_ON,       /* ? */
+	.inversion       = IQ_SWAP_ON,
 
 	.lo_clk	  = 76500000,
 	.hi_clk	  = 99000000,
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 83bfbe4..dc65742 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -37,7 +37,6 @@
 #include <media/i2c-addr.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-chip-ident.h>
 
 #include "em28xx.h"
 
@@ -83,26 +82,26 @@
 
 /* Reset for the most [analog] boards */
 static struct em28xx_reg_seq default_analog[] = {
-	{EM28XX_R08_GPIO,	0x6d,   ~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6d,   ~EM_GPIO_4,	10},
 	{	-1,		-1,	-1,		-1},
 };
 
 /* Reset for the most [digital] boards */
 static struct em28xx_reg_seq default_digital[] = {
-	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
 	{	-1,		-1,	-1,		-1},
 };
 
 /* Board Hauppauge WinTV HVR 900 analog */
 static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = {
-	{EM28XX_R08_GPIO,	0x2d,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x2d,	~EM_GPIO_4,	10},
 	{0x05,			0xff,	0x10,		10},
 	{  -1,			-1,	-1,		-1},
 };
 
 /* Board Hauppauge WinTV HVR 900 digital */
 static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = {
-	{EM28XX_R08_GPIO,	0x2e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x2e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x04,	0x0f,		10},
 	{EM2880_R04_GPO,	0x0c,	0x0f,		10},
 	{ -1,			-1,	-1,		-1},
@@ -110,14 +109,14 @@
 
 /* Board Hauppauge WinTV HVR 900 (R2) digital */
 static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = {
-	{EM28XX_R08_GPIO,	0x2e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x2e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x0c,	0x0f,		10},
 	{ -1,			-1,	-1,		-1},
 };
 
 /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
 static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
-	{EM28XX_R08_GPIO,       0x69,   ~EM_GPIO_4,	 10},
+	{EM2820_R08_GPIO_CTRL,       0x69,   ~EM_GPIO_4,	 10},
 	{	-1,		-1,	-1,		 -1},
 };
 
@@ -128,11 +127,11 @@
 
 /* Board - EM2882 Kworld 315U digital */
 static struct em28xx_reg_seq em2882_kworld_315u_digital[] = {
-	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
-	{EM28XX_R08_GPIO,	0xfe,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
 	{EM2880_R04_GPO,	0x04,	0xff,		10},
 	{EM2880_R04_GPO,	0x0c,	0xff,		10},
-	{EM28XX_R08_GPIO,	0x7e,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0x7e,	0xff,		10},
 	{  -1,			-1,	-1,		-1},
 };
 
@@ -145,13 +144,13 @@
 };
 
 static struct em28xx_reg_seq kworld_330u_analog[] = {
-	{EM28XX_R08_GPIO,	0x6d,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6d,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x00,	0xff,		10},
 	{ -1,			-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq kworld_330u_digital[] = {
-	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x08,	0xff,		10},
 	{ -1,			-1,	-1,		-1},
 };
@@ -163,12 +162,12 @@
    GOP3  - s5h1409 reset
  */
 static struct em28xx_reg_seq evga_indtube_analog[] = {
-	{EM28XX_R08_GPIO,	0x79,   0xff,		60},
+	{EM2820_R08_GPIO_CTRL,	0x79,   0xff,		60},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq evga_indtube_digital[] = {
-	{EM28XX_R08_GPIO,	0x7a,	0xff,		 1},
+	{EM2820_R08_GPIO_CTRL,	0x7a,	0xff,		 1},
 	{EM2880_R04_GPO,	0x04,	0xff,		10},
 	{EM2880_R04_GPO,	0x0c,	0xff,		 1},
 	{ -1,			-1,	-1,		-1},
@@ -186,31 +185,31 @@
  * EM_GPIO_7 - currently unknown
  */
 static struct em28xx_reg_seq kworld_a340_digital[] = {
-	{EM28XX_R08_GPIO,	0x6d,		~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6d,		~EM_GPIO_4,	10},
 	{ -1,			-1,		-1,		-1},
 };
 
 /* Pinnacle Hybrid Pro eb1a:2881 */
 static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = {
-	{EM28XX_R08_GPIO,	0xfd,   ~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0xfd,   ~EM_GPIO_4,	10},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
-	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x04,	0xff,	       100},/* zl10353 reset */
 	{EM2880_R04_GPO,	0x0c,	0xff,		 1},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = {
-	{EM28XX_R08_GPIO,	0x6d,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6d,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x00,	0xff,		10},
 	{ -1,			-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = {
-	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x08,	0xff,		10},
 	{ -1,			-1,	-1,		-1},
 };
@@ -219,66 +218,66 @@
    GPIO4 - CU1216L NIM
    Other GPIOs seems to be don't care. */
 static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = {
-	{EM28XX_R08_GPIO,	0xfe,	0xff,		10},
-	{EM28XX_R08_GPIO,	0xde,	0xff,		10},
-	{EM28XX_R08_GPIO,	0xfe,	0xff,		10},
-	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
-	{EM28XX_R08_GPIO,	0x7f,	0xff,		10},
-	{EM28XX_R08_GPIO,	0x6f,	0xff,		10},
-	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xde,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xfe,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0x7f,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0x6f,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
 	{-1,			-1,	-1,		-1},
 };
 
 /* Callback for the most boards */
 static struct em28xx_reg_seq default_tuner_gpio[] = {
-	{EM28XX_R08_GPIO,	EM_GPIO_4,	EM_GPIO_4,	10},
-	{EM28XX_R08_GPIO,	0,		EM_GPIO_4,	10},
-	{EM28XX_R08_GPIO,	EM_GPIO_4,	EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	EM_GPIO_4,	EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0,		EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	EM_GPIO_4,	EM_GPIO_4,	10},
 	{  -1,			-1,		-1,		-1},
 };
 
 /* Mute/unmute */
 static struct em28xx_reg_seq compro_unmute_tv_gpio[] = {
-	{EM28XX_R08_GPIO,	5,		7,		10},
+	{EM2820_R08_GPIO_CTRL,	5,		7,		10},
 	{  -1,			-1,		-1,		-1},
 };
 
 static struct em28xx_reg_seq compro_unmute_svid_gpio[] = {
-	{EM28XX_R08_GPIO,	4,		7,		10},
+	{EM2820_R08_GPIO_CTRL,	4,		7,		10},
 	{  -1,			-1,		-1,		-1},
 };
 
 static struct em28xx_reg_seq compro_mute_gpio[] = {
-	{EM28XX_R08_GPIO,	6,		7,		10},
+	{EM2820_R08_GPIO_CTRL,	6,		7,		10},
 	{  -1,			-1,		-1,		-1},
 };
 
 /* Terratec AV350 */
 static struct em28xx_reg_seq terratec_av350_mute_gpio[] = {
-	{EM28XX_R08_GPIO,	0xff,	0x7f,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0x7f,		10},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = {
-	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq silvercrest_reg_seq[] = {
-	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
-	{EM28XX_R08_GPIO,	0x01,	0xf7,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0xff,		10},
+	{EM2820_R08_GPIO_CTRL,	0x01,	0xf7,		10},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq vc211a_enable[] = {
-	{EM28XX_R08_GPIO,	0xff,	0x07,		10},
-	{EM28XX_R08_GPIO,	0xff,	0x0f,		10},
-	{EM28XX_R08_GPIO,	0xff,	0x0b,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0x07,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0x0f,		10},
+	{EM2820_R08_GPIO_CTRL,	0xff,	0x0b,		10},
 	{	-1,		-1,	-1,		-1},
 };
 
 static struct em28xx_reg_seq dikom_dk300_digital[] = {
-	{EM28XX_R08_GPIO,	0x6e,	~EM_GPIO_4,	10},
+	{EM2820_R08_GPIO_CTRL,	0x6e,	~EM_GPIO_4,	10},
 	{EM2880_R04_GPO,	0x08,	0xff,		10},
 	{ -1,			-1,	-1,		-1},
 };
@@ -286,14 +285,14 @@
 
 /* Reset for the most [digital] boards */
 static struct em28xx_reg_seq leadership_digital[] = {
-	{EM2874_R80_GPIO,	0x70,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0x70,	0xff,	10},
 	{	-1,		-1,	-1,	-1},
 };
 
 static struct em28xx_reg_seq leadership_reset[] = {
-	{EM2874_R80_GPIO,	0xf0,	0xff,	10},
-	{EM2874_R80_GPIO,	0xb0,	0xff,	10},
-	{EM2874_R80_GPIO,	0xf0,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf0,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xb0,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf0,	0xff,	10},
 	{	-1,		-1,	-1,	-1},
 };
 
@@ -302,25 +301,25 @@
  * GPIO_7 - LED
  */
 static struct em28xx_reg_seq pctv_290e[] = {
-	{EM2874_R80_GPIO,	0x00,	0xff,		80},
-	{EM2874_R80_GPIO,	0x40,	0xff,		80}, /* GPIO_6 = 1 */
-	{EM2874_R80_GPIO,	0xc0,	0xff,		80}, /* GPIO_7 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL,	0x00,	0xff,	80},
+	{EM2874_R80_GPIO_P0_CTRL,	0x40,	0xff,	80}, /* GPIO_6 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL,	0xc0,	0xff,	80}, /* GPIO_7 = 1 */
 	{-1,			-1,	-1,		-1},
 };
 
 #if 0
 static struct em28xx_reg_seq terratec_h5_gpio[] = {
-	{EM28XX_R08_GPIO,	0xff,	0xff,	10},
-	{EM2874_R80_GPIO,	0xf6,	0xff,	100},
-	{EM2874_R80_GPIO,	0xf2,	0xff,	50},
-	{EM2874_R80_GPIO,	0xf6,	0xff,	50},
+	{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf2,	0xff,	50},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	50},
 	{ -1,			-1,	-1,	-1},
 };
 
 static struct em28xx_reg_seq terratec_h5_digital[] = {
-	{EM2874_R80_GPIO,	0xf6,	0xff,	10},
-	{EM2874_R80_GPIO,	0xe6,	0xff,	100},
-	{EM2874_R80_GPIO,	0xa6,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
+	{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	10},
 	{ -1,			-1,	-1,	-1},
 };
 #endif
@@ -336,51 +335,52 @@
  * GPIO_7 - LED (green LED)
  */
 static struct em28xx_reg_seq pctv_460e[] = {
-	{EM2874_R80_GPIO, 0x01, 0xff,  50},
+	{EM2874_R80_GPIO_P0_CTRL, 0x01, 0xff,  50},
 	{0x0d,            0xff, 0xff,  50},
-	{EM2874_R80_GPIO, 0x41, 0xff,  50}, /* GPIO_6=1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x41, 0xff,  50}, /* GPIO_6=1 */
 	{0x0d,            0x42, 0xff,  50},
-	{EM2874_R80_GPIO, 0x61, 0xff,  50}, /* GPIO_5=1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x61, 0xff,  50}, /* GPIO_5=1 */
 	{             -1,   -1,   -1,  -1},
 };
 
 static struct em28xx_reg_seq c3tech_digital_duo_digital[] = {
-	{EM2874_R80_GPIO,	0xff,	0xff,	10},
-	{EM2874_R80_GPIO,	0xfd,	0xff,	10}, /* xc5000 reset */
-	{EM2874_R80_GPIO,	0xf9,	0xff,	35},
-	{EM2874_R80_GPIO,	0xfd,	0xff,	10},
-	{EM2874_R80_GPIO,	0xff,	0xff,	10},
-	{EM2874_R80_GPIO,	0xfe,	0xff,	10},
-	{EM2874_R80_GPIO,	0xbe,	0xff,	10},
-	{EM2874_R80_GPIO,	0xfe,	0xff,	20},
+	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	10}, /* xc5000 reset */
+	{EM2874_R80_GPIO_P0_CTRL,	0xf9,	0xff,	35},
+	{EM2874_R80_GPIO_P0_CTRL,	0xfd,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xbe,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xfe,	0xff,	20},
 	{ -1,			-1,	-1,	-1},
 };
 
 #if 0
 static struct em28xx_reg_seq hauppauge_930c_gpio[] = {
-	{EM2874_R80_GPIO,	0x6f,	0xff,	10},
-	{EM2874_R80_GPIO,	0x4f,	0xff,	10}, /* xc5000 reset */
-	{EM2874_R80_GPIO,	0x6f,	0xff,	10},
-	{EM2874_R80_GPIO,	0x4f,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0x6f,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0x4f,	0xff,	10}, /* xc5000 reset */
+	{EM2874_R80_GPIO_P0_CTRL,	0x6f,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0x4f,	0xff,	10},
 	{ -1,			-1,	-1,	-1},
 };
 
 static struct em28xx_reg_seq hauppauge_930c_digital[] = {
-	{EM2874_R80_GPIO,	0xf6,	0xff,	10},
-	{EM2874_R80_GPIO,	0xe6,	0xff,	100},
-	{EM2874_R80_GPIO,	0xa6,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	10},
+	{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
+	{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	10},
 	{ -1,			-1,	-1,	-1},
 };
 #endif
 
 /* 1b80:e425 MaxMedia UB425-TC
+ * 1b80:e1cc Delock 61959
  * GPIO_6 - demod reset, 0=active
  * GPIO_7 - LED, 0=active
  */
 static struct em28xx_reg_seq maxmedia_ub425_tc[] = {
-	{EM2874_R80_GPIO,  0x83,  0xff,  100},
-	{EM2874_R80_GPIO,  0xc3,  0xff,  100}, /* GPIO_6 = 1 */
-	{EM2874_R80_GPIO,  0x43,  0xff,  000}, /* GPIO_7 = 0 */
+	{EM2874_R80_GPIO_P0_CTRL,  0x83,  0xff,  100},
+	{EM2874_R80_GPIO_P0_CTRL,  0xc3,  0xff,  100}, /* GPIO_6 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL,  0x43,  0xff,  000}, /* GPIO_7 = 0 */
 	{-1,                 -1,    -1,   -1},
 };
 
@@ -391,9 +391,9 @@
  * GPIO_7: LED, 1=active
  */
 static struct em28xx_reg_seq pctv_510e[] = {
-	{EM2874_R80_GPIO, 0x10, 0xff, 100},
-	{EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
-	{EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100},
+	{EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
 	{             -1,   -1,   -1,  -1},
 };
 
@@ -404,10 +404,10 @@
  * GPIO_7: LED, 1=active
  */
 static struct em28xx_reg_seq pctv_520e[] = {
-	{EM2874_R80_GPIO, 0x10, 0xff, 100},
-	{EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
-	{EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
-	{EM2874_R80_GPIO, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x10, 0xff, 100},
+	{EM2874_R80_GPIO_P0_CTRL, 0x14, 0xff, 100}, /* GPIO_2 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0x54, 0xff, 050}, /* GPIO_6 = 1 */
+	{EM2874_R80_GPIO_P0_CTRL, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */
 	{             -1,   -1,   -1,  -1},
 };
 
@@ -2017,6 +2017,19 @@
 		.i2c_speed    = EM28XX_I2C_CLK_WAIT_ENABLE |
 				EM28XX_I2C_FREQ_400_KHZ,
 	},
+	/* 1b80:e1cc Delock 61959
+	 * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2
+         * mostly the same as MaxMedia UB-425-TC but different remote */
+	[EM2874_BOARD_DELOCK_61959] = {
+		.name          = "Delock 61959",
+		.tuner_type    = TUNER_ABSENT,
+		.tuner_gpio    = maxmedia_ub425_tc,
+		.has_dvb       = 1,
+		.ir_codes      = RC_MAP_DELOCK_61959,
+		.def_i2c_bus   = 1,
+		.i2c_speed     = EM28XX_I2C_CLK_WAIT_ENABLE |
+				EM28XX_I2C_FREQ_400_KHZ,
+	},
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
@@ -2178,6 +2191,8 @@
 			.driver_info = EM2884_BOARD_PCTV_510E },
 	{ USB_DEVICE(0x2013, 0x0251),
 			.driver_info = EM2884_BOARD_PCTV_520E },
+	{ USB_DEVICE(0x1b80, 0xe1cc),
+			.driver_info = EM2874_BOARD_DELOCK_61959 },
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -2284,9 +2299,9 @@
 		break;
 	case EM2861_BOARD_KWORLD_PVRTV_300U:
 	case EM2880_BOARD_KWORLD_DVB_305U:
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x6d);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x6d);
 		msleep(10);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x7d);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0x7d);
 		msleep(10);
 		break;
 	case EM2870_BOARD_COMPRO_VIDEOMATE:
@@ -2296,45 +2311,45 @@
 		msleep(10);
 		em28xx_write_reg(dev, EM2880_R04_GPO, 0x01);
 		msleep(10);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xdc);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xdc);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfc);
 		mdelay(70);
 		break;
 	case EM2870_BOARD_TERRATEC_XS_MT2060:
 		/* this device needs some gpio writes to get the DVB-T
 		   demod work */
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		mdelay(70);
 		break;
 	case EM2870_BOARD_PINNACLE_PCTV_DVB:
 		/* this device needs some gpio writes to get the
 		   DVB-T demod work */
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xde);
 		mdelay(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		mdelay(70);
 		break;
 	case EM2820_BOARD_GADMEI_UTV310:
 	case EM2820_BOARD_MSI_VOX_USB_2:
 		/* enables audio for that devices */
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
 		break;
 
 	case EM2882_BOARD_KWORLD_ATSC_315U:
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
 		msleep(10);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		msleep(10);
 		em28xx_write_reg(dev, EM2880_R04_GPO, 0x00);
 		msleep(10);
@@ -2360,13 +2375,13 @@
 		break;
 
 	case EM2820_BOARD_IODATA_GVMVP_SZ:
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
 		msleep(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
 		msleep(10);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfe);
 		msleep(70);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
 		msleep(70);
 		break;
 	}
@@ -2653,7 +2668,7 @@
 
 		dev->tuner_type = tv.tuner_type;
 
-		if (tv.audio_processor == V4L2_IDENT_MSPX4XX) {
+		if (tv.audio_processor == TVEEPROM_AUDPROC_MSP) {
 			dev->i2s_speed = 2048000;
 			dev->board.has_msp34xx = 1;
 		}
@@ -2662,12 +2677,12 @@
 	case EM2882_BOARD_KWORLD_ATSC_315U:
 		em28xx_write_reg(dev, 0x0d, 0x42);
 		msleep(10);
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xfd);
 		msleep(10);
 		break;
 	case EM2820_BOARD_KWORLD_PVRTV2800RF:
 		/* GPIO enables sound on KWORLD PVR TV 2800RF */
-		em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9);
+		em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf9);
 		break;
 	case EM2820_BOARD_UNKNOWN:
 	case EM2800_BOARD_UNKNOWN:
@@ -2881,10 +2896,6 @@
 
 	em28xx_set_model(dev);
 
-	/* Set the default GPO/GPIO for legacy devices */
-	dev->reg_gpo_num = EM2880_R04_GPO;
-	dev->reg_gpio_num = EM28XX_R08_GPIO;
-
 	dev->wait_after_write = 5;
 
 	/* Based on the Chip ID, set the device configuration */
@@ -2932,13 +2943,11 @@
 			break;
 		case CHIP_ID_EM2874:
 			chip_name = "em2874";
-			dev->reg_gpio_num = EM2874_R80_GPIO;
 			dev->wait_after_write = 0;
 			dev->eeprom_addrwidth_16bit = 1;
 			break;
 		case CHIP_ID_EM28174:
 			chip_name = "em28174";
-			dev->reg_gpio_num = EM2874_R80_GPIO;
 			dev->wait_after_write = 0;
 			dev->eeprom_addrwidth_16bit = 1;
 			break;
@@ -2948,7 +2957,6 @@
 			break;
 		case CHIP_ID_EM2884:
 			chip_name = "em2884";
-			dev->reg_gpio_num = EM2874_R80_GPIO;
 			dev->wait_after_write = 0;
 			dev->eeprom_addrwidth_16bit = 1;
 			break;
@@ -2977,11 +2985,6 @@
 		return 0;
 	}
 
-	/* Prepopulate cached GPO register content */
-	retval = em28xx_read_reg(dev, dev->reg_gpo_num);
-	if (retval >= 0)
-		dev->reg_gpo = retval;
-
 	em28xx_pre_card_setup(dev);
 
 	if (!dev->board.is_em2800) {
@@ -3071,7 +3074,7 @@
 
 	if (dev->board.has_msp34xx) {
 		/* Send a reset to other chips via gpio */
-		retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
+		retval = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
 		if (retval < 0) {
 			em28xx_errdev("%s: em28xx_write_reg - "
 				      "msp34xx(1) failed! error [%d]\n",
@@ -3080,7 +3083,7 @@
 		}
 		msleep(3);
 
-		retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+		retval = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
 		if (retval < 0) {
 			em28xx_errdev("%s: em28xx_write_reg - "
 				      "msp34xx(2) failed! error [%d]\n",
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index a802128..fc157af 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -193,23 +193,7 @@
 
 int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
 {
-	int rc;
-
-	rc = em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
-
-	/* Stores GPO/GPIO values at the cache, if changed
-	   Only write values should be stored, since input on a GPIO
-	   register will return the input bits.
-	   Not sure what happens on reading GPO register.
-	 */
-	if (rc >= 0) {
-		if (reg == dev->reg_gpo_num)
-			dev->reg_gpo = buf[0];
-		else if (reg == dev->reg_gpio_num)
-			dev->reg_gpio = buf[0];
-	}
-
-	return rc;
+	return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
 }
 EXPORT_SYMBOL_GPL(em28xx_write_regs);
 
@@ -231,14 +215,7 @@
 	int oldval;
 	u8 newval;
 
-	/* Uses cache for gpo/gpio registers */
-	if (reg == dev->reg_gpo_num)
-		oldval = dev->reg_gpo;
-	else if (reg == dev->reg_gpio_num)
-		oldval = dev->reg_gpio;
-	else
-		oldval = em28xx_read_reg(dev, reg);
-
+	oldval = em28xx_read_reg(dev, reg);
 	if (oldval < 0)
 		return oldval;
 
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index b22f8fe..bb1e8dc 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -421,23 +421,23 @@
 	int i;
 
 	struct em28xx_reg_seq hauppauge_hvr930c_init[] = {
-		{EM2874_R80_GPIO,	0xff,	0xff,	0x65},
-		{EM2874_R80_GPIO,	0xfb,	0xff,	0x32},
-		{EM2874_R80_GPIO,	0xff,	0xff,	0xb8},
+		{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	0x65},
+		{EM2874_R80_GPIO_P0_CTRL,	0xfb,	0xff,	0x32},
+		{EM2874_R80_GPIO_P0_CTRL,	0xff,	0xff,	0xb8},
 		{ -1,                   -1,     -1,     -1},
 	};
 	struct em28xx_reg_seq hauppauge_hvr930c_end[] = {
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x01},
-		{EM2874_R80_GPIO,	0xaf,	0xff,	0x65},
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x76},
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x01},
-		{EM2874_R80_GPIO,	0xcf,	0xff,	0x0b},
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x40},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x01},
+		{EM2874_R80_GPIO_P0_CTRL,	0xaf,	0xff,	0x65},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x76},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x01},
+		{EM2874_R80_GPIO_P0_CTRL,	0xcf,	0xff,	0x0b},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x40},
 
-		{EM2874_R80_GPIO,	0xcf,	0xff,	0x65},
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x65},
-		{EM2874_R80_GPIO,	0xcf,	0xff,	0x0b},
-		{EM2874_R80_GPIO,	0xef,	0xff,	0x65},
+		{EM2874_R80_GPIO_P0_CTRL,	0xcf,	0xff,	0x65},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x65},
+		{EM2874_R80_GPIO_P0_CTRL,	0xcf,	0xff,	0x0b},
+		{EM2874_R80_GPIO_P0_CTRL,	0xef,	0xff,	0x65},
 
 		{ -1,                   -1,     -1,     -1},
 	};
@@ -487,16 +487,16 @@
 {
 	int i;
 	struct em28xx_reg_seq terratec_h5_init[] = {
-		{EM28XX_R08_GPIO,	0xff,	0xff,	10},
-		{EM2874_R80_GPIO,	0xf6,	0xff,	100},
-		{EM2874_R80_GPIO,	0xf2,	0xff,	50},
-		{EM2874_R80_GPIO,	0xf6,	0xff,	100},
+		{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf2,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
 		{ -1,                   -1,     -1,     -1},
 	};
 	struct em28xx_reg_seq terratec_h5_end[] = {
-		{EM2874_R80_GPIO,	0xe6,	0xff,	100},
-		{EM2874_R80_GPIO,	0xa6,	0xff,	50},
-		{EM2874_R80_GPIO,	0xe6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
 		{ -1,                   -1,     -1,     -1},
 	};
 	struct {
@@ -543,15 +543,15 @@
 	 * 0xb6: unknown (does not affect DVB-T).
 	 */
 	struct em28xx_reg_seq terratec_htc_stick_init[] = {
-		{EM28XX_R08_GPIO,	0xff,	0xff,	10},
-		{EM2874_R80_GPIO,	0xf6,	0xff,	100},
-		{EM2874_R80_GPIO,	0xe6,	0xff,	50},
-		{EM2874_R80_GPIO,	0xf6,	0xff,	100},
+		{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	100},
 		{ -1,                   -1,     -1,     -1},
 	};
 	struct em28xx_reg_seq terratec_htc_stick_end[] = {
-		{EM2874_R80_GPIO,	0xb6,	0xff,	100},
-		{EM2874_R80_GPIO,	0xf6,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xb6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xf6,	0xff,	50},
 		{ -1,                   -1,     -1,     -1},
 	};
 
@@ -590,16 +590,16 @@
 	int i;
 
 	struct em28xx_reg_seq terratec_htc_usb_xs_init[] = {
-		{EM28XX_R08_GPIO,	0xff,	0xff,	10},
-		{EM2874_R80_GPIO,	0xb2,	0xff,	100},
-		{EM2874_R80_GPIO,	0xb2,	0xff,	50},
-		{EM2874_R80_GPIO,	0xb6,	0xff,	100},
+		{EM2820_R08_GPIO_CTRL,		0xff,	0xff,	10},
+		{EM2874_R80_GPIO_P0_CTRL,	0xb2,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xb2,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xb6,	0xff,	100},
 		{ -1,                   -1,     -1,     -1},
 	};
 	struct em28xx_reg_seq terratec_htc_usb_xs_end[] = {
-		{EM2874_R80_GPIO,	0xa6,	0xff,	100},
-		{EM2874_R80_GPIO,	0xa6,	0xff,	50},
-		{EM2874_R80_GPIO,	0xe6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	100},
+		{EM2874_R80_GPIO_P0_CTRL,	0xa6,	0xff,	50},
+		{EM2874_R80_GPIO_P0_CTRL,	0xe6,	0xff,	100},
 		{ -1,                   -1,     -1,     -1},
 	};
 
@@ -1216,6 +1216,7 @@
 			dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus],
 				&em28xx_a8293_config);
 		break;
+	case EM2874_BOARD_DELOCK_61959:
 	case EM2874_BOARD_MAXMEDIA_UB425_TC:
 		/* attach demodulator */
 		dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk,
@@ -1235,8 +1236,8 @@
 		}
 
 		/* TODO: we need drx-3913k firmware in order to support DVB-T */
-		em28xx_info("MaxMedia UB425-TC: only DVB-C supported by that " \
-				"driver version\n");
+		em28xx_info("MaxMedia UB425-TC/Delock 61959: only DVB-C " \
+				"supported by that driver version\n");
 
 		break;
 	case EM2884_BOARD_PCTV_510E:
diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c
index 466b19d..ea181e4 100644
--- a/drivers/media/usb/em28xx/em28xx-input.c
+++ b/drivers/media/usb/em28xx/em28xx-input.c
@@ -32,7 +32,6 @@
 
 #define EM28XX_SNAPSHOT_KEY KEY_CAMERA
 #define EM28XX_SBUTTON_QUERY_INTERVAL 500
-#define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20
 
 static unsigned int ir_debug;
 module_param(ir_debug, int, 0644);
diff --git a/drivers/media/usb/em28xx/em28xx-reg.h b/drivers/media/usb/em28xx/em28xx-reg.h
index 622871d..0e04778 100644
--- a/drivers/media/usb/em28xx/em28xx-reg.h
+++ b/drivers/media/usb/em28xx/em28xx-reg.h
@@ -49,8 +49,9 @@
 
 
 /* GPIO/GPO registers */
-#define EM2880_R04_GPO	0x04    /* em2880-em2883 only */
-#define EM28XX_R08_GPIO	0x08	/* em2820 or upper */
+#define EM2880_R04_GPO		0x04    /* em2880-em2883 only */
+#define EM2820_R08_GPIO_CTRL	0x08	/* em2820-em2873/83 only */
+#define EM2820_R09_GPIO_STATE	0x09	/* em2820-em2873/83 only */
 
 #define EM28XX_R06_I2C_CLK	0x06
 
@@ -67,7 +68,8 @@
 
 
 #define EM28XX_R0A_CHIPID	0x0a
-#define EM28XX_R0C_USBSUSP	0x0c	/* */
+#define EM28XX_R0C_USBSUSP	0x0c
+#define   EM28XX_R0C_USBSUSP_SNAPSHOT	0x20 /* 1=button pressed, needs reset */
 
 #define EM28XX_R0E_AUDIOSRC	0x0e
 #define EM28XX_R0F_XCLK	0x0f
@@ -193,7 +195,20 @@
 #define EM2874_R50_IR_CONFIG    0x50
 #define EM2874_R51_IR           0x51
 #define EM2874_R5F_TS_ENABLE    0x5f
-#define EM2874_R80_GPIO         0x80
+
+/* em2874/174/84, em25xx, em276x/7x/8x GPIO registers */
+/*
+ * NOTE: not all ports are bonded out;
+ * Some ports are multiplexed with special function I/O
+ */
+#define EM2874_R80_GPIO_P0_CTRL    0x80
+#define EM2874_R81_GPIO_P1_CTRL    0x81
+#define EM2874_R82_GPIO_P2_CTRL    0x82
+#define EM2874_R83_GPIO_P3_CTRL    0x83
+#define EM2874_R84_GPIO_P0_STATE   0x84
+#define EM2874_R85_GPIO_P1_STATE   0x85
+#define EM2874_R86_GPIO_P2_STATE   0x86
+#define EM2874_R87_GPIO_P3_STATE   0x87
 
 /* em2874 IR config register (0x50) */
 #define EM2874_IR_NEC           0x00
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 32d60e5..1a577ed 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -41,7 +41,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/msp3400.h>
 #include <media/tuner.h>
 
@@ -1309,28 +1308,6 @@
 	return 0;
 }
 
-static int vidioc_g_chip_ident(struct file *file, void *priv,
-	       struct v4l2_dbg_chip_ident *chip)
-{
-	struct em28xx_fh      *fh  = priv;
-	struct em28xx         *dev = fh->dev;
-
-	chip->ident = V4L2_IDENT_NONE;
-	chip->revision = 0;
-	if (chip->match.type == V4L2_CHIP_MATCH_BRIDGE) {
-		if (chip->match.addr > 1)
-			return -EINVAL;
-		return 0;
-	}
-	if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
-	    chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
-		return -EINVAL;
-
-	v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
-
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int vidioc_g_chip_info(struct file *file, void *priv,
 	       struct v4l2_dbg_chip_info *chip)
@@ -1366,14 +1343,9 @@
 	struct em28xx         *dev = fh->dev;
 	int ret;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_BRIDGE:
-		if (reg->match.addr > 1)
-			return -EINVAL;
-		if (!reg->match.addr)
-			break;
-		/* fall-through */
-	case V4L2_CHIP_MATCH_AC97:
+	if (reg->match.addr > 1)
+		return -EINVAL;
+	if (reg->match.addr) {
 		ret = em28xx_read_ac97(dev, reg->reg);
 		if (ret < 0)
 			return ret;
@@ -1381,15 +1353,6 @@
 		reg->val = ret;
 		reg->size = 1;
 		return 0;
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/* TODO: is this correct? */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
-		return 0;
-	default:
-		return -EINVAL;
 	}
 
 	/* Match host */
@@ -1421,25 +1384,10 @@
 	struct em28xx         *dev = fh->dev;
 	__le16 buf;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_BRIDGE:
-		if (reg->match.addr > 1)
-			return -EINVAL;
-		if (!reg->match.addr)
-			break;
-		/* fall-through */
-	case V4L2_CHIP_MATCH_AC97:
-		return em28xx_write_ac97(dev, reg->reg, reg->val);
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/* TODO: is this correct? */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
-		return 0;
-	default:
+	if (reg->match.addr > 1)
 		return -EINVAL;
-	}
+	if (reg->match.addr)
+		return em28xx_write_ac97(dev, reg->reg, reg->val);
 
 	/* Match host */
 	buf = cpu_to_le16(reg->val);
@@ -1795,7 +1743,6 @@
 	.vidioc_s_frequency         = vidioc_s_frequency,
 	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident        = vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_chip_info         = vidioc_g_chip_info,
 	.vidioc_g_register          = vidioc_g_register,
@@ -1826,7 +1773,6 @@
 	.vidioc_s_frequency   = vidioc_s_frequency,
 	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident  = vidioc_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_chip_info   = vidioc_g_chip_info,
 	.vidioc_g_register    = vidioc_g_register,
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index a9323b6..205e903 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -130,6 +130,7 @@
 #define EM2884_BOARD_PCTV_520E			  86
 #define EM2884_BOARD_TERRATEC_HTC_USB_XS	  87
 #define EM2884_BOARD_C3TECH_DIGITAL_DUO		  88
+#define EM2874_BOARD_DELOCK_61959		  89
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
@@ -636,12 +637,6 @@
 
 	enum em28xx_mode mode;
 
-	/* register numbers for GPO/GPIO registers */
-	u16 reg_gpo_num, reg_gpio_num;
-
-	/* Caches GPO and GPIO registers */
-	unsigned char	reg_gpo, reg_gpio;
-
 	/* Snapshot button */
 	char snapshot_button_path[30];	/* path of the input dev */
 	struct input_dev *sbutton_input_dev;
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index 5995ec4..b7ae872 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -1029,8 +1029,19 @@
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_chip_info(struct file *file, void *priv,
+				struct v4l2_dbg_chip_info *chip)
+{
+	struct gspca_dev *gspca_dev = video_drvdata(file);
+
+	gspca_dev->usb_err = 0;
+	if (gspca_dev->sd_desc->get_chip_info)
+		return gspca_dev->sd_desc->get_chip_info(gspca_dev, chip);
+	return chip->match.addr ? -EINVAL : 0;
+}
+
 static int vidioc_g_register(struct file *file, void *priv,
-			struct v4l2_dbg_register *reg)
+		struct v4l2_dbg_register *reg)
 {
 	struct gspca_dev *gspca_dev = video_drvdata(file);
 
@@ -1039,7 +1050,7 @@
 }
 
 static int vidioc_s_register(struct file *file, void *priv,
-			const struct v4l2_dbg_register *reg)
+		const struct v4l2_dbg_register *reg)
 {
 	struct gspca_dev *gspca_dev = video_drvdata(file);
 
@@ -1048,15 +1059,6 @@
 }
 #endif
 
-static int vidioc_g_chip_ident(struct file *file, void *priv,
-			struct v4l2_dbg_chip_ident *chip)
-{
-	struct gspca_dev *gspca_dev = video_drvdata(file);
-
-	gspca_dev->usb_err = 0;
-	return gspca_dev->sd_desc->get_chip_ident(gspca_dev, chip);
-}
-
 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 				struct v4l2_fmtdesc *fmtdesc)
 {
@@ -1974,10 +1976,10 @@
 	.vidioc_enum_framesizes = vidioc_enum_framesizes,
 	.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_chip_info	= vidioc_g_chip_info,
 	.vidioc_g_register	= vidioc_g_register,
 	.vidioc_s_register	= vidioc_s_register,
 #endif
-	.vidioc_g_chip_ident	= vidioc_g_chip_ident,
 	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
@@ -2086,14 +2088,10 @@
 	v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_DQBUF);
 	v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QBUF);
 	v4l2_disable_ioctl_locking(&gspca_dev->vdev, VIDIOC_QUERYBUF);
-	if (!gspca_dev->sd_desc->get_chip_ident)
-		v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_CHIP_IDENT);
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	if (!gspca_dev->sd_desc->get_chip_ident ||
-	    !gspca_dev->sd_desc->get_register)
+	if (!gspca_dev->sd_desc->get_register)
 		v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_G_REGISTER);
-	if (!gspca_dev->sd_desc->get_chip_ident ||
-	    !gspca_dev->sd_desc->set_register)
+	if (!gspca_dev->sd_desc->set_register)
 		v4l2_disable_ioctl(&gspca_dev->vdev, VIDIOC_DBG_S_REGISTER);
 #endif
 	if (!gspca_dev->sd_desc->get_jcomp)
diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h
index ef8efeb..ac0b11f 100644
--- a/drivers/media/usb/gspca/gspca.h
+++ b/drivers/media/usb/gspca/gspca.h
@@ -78,8 +78,8 @@
 				struct v4l2_dbg_register *);
 typedef int (*cam_set_reg_op) (struct gspca_dev *,
 				const struct v4l2_dbg_register *);
-typedef int (*cam_ident_op) (struct gspca_dev *,
-				struct v4l2_dbg_chip_ident *);
+typedef int (*cam_chip_info_op) (struct gspca_dev *,
+				struct v4l2_dbg_chip_info *);
 typedef void (*cam_streamparm_op) (struct gspca_dev *,
 				  struct v4l2_streamparm *);
 typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
@@ -112,8 +112,8 @@
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	cam_set_reg_op set_register;
 	cam_get_reg_op get_register;
+	cam_chip_info_op get_chip_info;
 #endif
-	cam_ident_op get_chip_ident;
 #if IS_ENABLED(CONFIG_INPUT)
 	cam_int_pkt_op int_pkt_scan;
 	/* other_input makes the gspca core create gspca_dev->input even when
diff --git a/drivers/media/usb/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c
index 6008c8d..a915096 100644
--- a/drivers/media/usb/gspca/pac7302.c
+++ b/drivers/media/usb/gspca/pac7302.c
@@ -93,7 +93,6 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/input.h>
-#include <media/v4l2-chip-ident.h>
 #include "gspca.h"
 /* Include pac common sof detection functions */
 #include "pac_common.h"
@@ -849,8 +848,7 @@
 	 * reg->reg: bit0..15: reserved for register index (wIndex is 16bit
 	 *		       long on the USB bus)
 	 */
-	if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
-	    reg->match.addr == 0 &&
+	if (reg->match.addr == 0 &&
 	    (reg->reg < 0x000000ff) &&
 	    (reg->val <= 0x000000ff)
 	) {
@@ -871,20 +869,6 @@
 	}
 	return gspca_dev->usb_err;
 }
-
-static int sd_chip_ident(struct gspca_dev *gspca_dev,
-			struct v4l2_dbg_chip_ident *chip)
-{
-	int ret = -EINVAL;
-
-	if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
-	    chip->match.addr == 0) {
-		chip->revision = 0;
-		chip->ident = V4L2_IDENT_UNKNOWN;
-		ret = 0;
-	}
-	return ret;
-}
 #endif
 
 #if IS_ENABLED(CONFIG_INPUT)
@@ -931,7 +915,6 @@
 	.dq_callback = do_autogain,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.set_register = sd_dbg_s_register,
-	.get_chip_ident = sd_chip_ident,
 #endif
 #if IS_ENABLED(CONFIG_INPUT)
 	.int_pkt_scan = sd_int_pkt_scan,
diff --git a/drivers/media/usb/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c
index ead9a1f..f4453d5 100644
--- a/drivers/media/usb/gspca/sn9c20x.c
+++ b/drivers/media/usb/gspca/sn9c20x.c
@@ -27,7 +27,6 @@
 #include "gspca.h"
 #include "jpeg.h"
 
-#include <media/v4l2-chip-ident.h>
 #include <linux/dmi.h>
 
 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
@@ -582,22 +581,6 @@
 	4,   2,   0,  -1,  -3,  -5,  -7,  -9, -11
 };
 
-static const u16 i2c_ident[] = {
-	V4L2_IDENT_OV9650,
-	V4L2_IDENT_OV9655,
-	V4L2_IDENT_SOI968,
-	V4L2_IDENT_OV7660,
-	V4L2_IDENT_OV7670,
-	V4L2_IDENT_MT9V011,
-	V4L2_IDENT_MT9V111,
-	V4L2_IDENT_MT9V112,
-	V4L2_IDENT_MT9M001C12ST,
-	V4L2_IDENT_MT9M111,
-	V4L2_IDENT_MT9M112,
-	V4L2_IDENT_HV7131R,
-[SENSOR_MT9VPRB] = V4L2_IDENT_UNKNOWN,
-};
-
 static const u16 bridge_init[][2] = {
 	{0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
 	{0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
@@ -1574,21 +1557,19 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		if (reg->match.addr != 0)
-			return -EINVAL;
+	reg->size = 1;
+	switch (reg->match.addr) {
+	case 0:
 		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
 			return -EINVAL;
 		reg_r(gspca_dev, reg->reg, 1);
 		reg->val = gspca_dev->usb_buf[0];
 		return gspca_dev->usb_err;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		if (reg->match.addr != sd->i2c_addr)
-			return -EINVAL;
+	case 1:
 		if (sd->sensor >= SENSOR_MT9V011 &&
 		    sd->sensor <= SENSOR_MT9M112) {
 			i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
+			reg->size = 2;
 		} else {
 			i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
 		}
@@ -1602,17 +1583,13 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		if (reg->match.addr != 0)
-			return -EINVAL;
+	switch (reg->match.addr) {
+	case 0:
 		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
 			return -EINVAL;
 		reg_w1(gspca_dev, reg->reg, reg->val);
 		return gspca_dev->usb_err;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		if (reg->match.addr != sd->i2c_addr)
-			return -EINVAL;
+	case 1:
 		if (sd->sensor >= SENSOR_MT9V011 &&
 		    sd->sensor <= SENSOR_MT9M112) {
 			i2c_w2(gspca_dev, reg->reg, reg->val);
@@ -1623,29 +1600,17 @@
 	}
 	return -EINVAL;
 }
-#endif
 
-static int sd_chip_ident(struct gspca_dev *gspca_dev,
-			struct v4l2_dbg_chip_ident *chip)
+static int sd_chip_info(struct gspca_dev *gspca_dev,
+			struct v4l2_dbg_chip_info *chip)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
-
-	switch (chip->match.type) {
-	case V4L2_CHIP_MATCH_HOST:
-		if (chip->match.addr != 0)
-			return -EINVAL;
-		chip->revision = 0;
-		chip->ident = V4L2_IDENT_SN9C20X;
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		if (chip->match.addr != sd->i2c_addr)
-			return -EINVAL;
-		chip->revision = 0;
-		chip->ident = i2c_ident[sd->sensor];
-		return 0;
-	}
-	return -EINVAL;
+	if (chip->match.addr > 1)
+		return -EINVAL;
+	if (chip->match.addr == 1)
+		strlcpy(chip->name, "sensor", sizeof(chip->name));
+	return 0;
 }
+#endif
 
 static int sd_config(struct gspca_dev *gspca_dev,
 			const struct usb_device_id *id)
@@ -2356,8 +2321,8 @@
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.set_register = sd_dbg_s_register,
 	.get_register = sd_dbg_g_register,
+	.get_chip_info = sd_chip_info,
 #endif
-	.get_chip_ident = sd_chip_ident,
 };
 
 #define SN9C20X(sensor, i2c_addr, flags) \
diff --git a/drivers/media/usb/hdpvr/Kconfig b/drivers/media/usb/hdpvr/Kconfig
index de247f3..d73d9a1 100644
--- a/drivers/media/usb/hdpvr/Kconfig
+++ b/drivers/media/usb/hdpvr/Kconfig
@@ -1,7 +1,7 @@
 
 config VIDEO_HDPVR
 	tristate "Hauppauge HD PVR support"
-	depends on VIDEO_DEV
+	depends on VIDEO_DEV && VIDEO_V4L2
 	---help---
 	  This is a video4linux driver for Hauppauge's HD PVR USB device.
 
diff --git a/drivers/media/usb/hdpvr/hdpvr-control.c b/drivers/media/usb/hdpvr/hdpvr-control.c
index ae8f229..6053661 100644
--- a/drivers/media/usb/hdpvr/hdpvr-control.c
+++ b/drivers/media/usb/hdpvr/hdpvr-control.c
@@ -45,20 +45,11 @@
 	return ret < 0 ? ret : 0;
 }
 
-struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
+int get_video_info(struct hdpvr_device *dev, struct hdpvr_video_info *vidinf)
 {
-	struct hdpvr_video_info *vidinf = NULL;
-#ifdef HDPVR_DEBUG
-	char print_buf[15];
-#endif
 	int ret;
 
-	vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);
-	if (!vidinf) {
-		v4l2_err(&dev->v4l2_dev, "out of memory\n");
-		goto err;
-	}
-
+	vidinf->valid = false;
 	mutex_lock(&dev->usbc_mutex);
 	ret = usb_control_msg(dev->udev,
 			      usb_rcvctrlpipe(dev->udev, 0),
@@ -66,14 +57,10 @@
 			      0x1400, 0x0003,
 			      dev->usbc_buf, 5,
 			      1000);
-	if (ret == 5) {
-		vidinf->width	= dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
-		vidinf->height	= dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
-		vidinf->fps	= dev->usbc_buf[4];
-	}
 
 #ifdef HDPVR_DEBUG
 	if (hdpvr_debug & MSG_INFO) {
+		char print_buf[15];
 		hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf,
 				   sizeof(print_buf), 0);
 		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
@@ -82,12 +69,15 @@
 #endif
 	mutex_unlock(&dev->usbc_mutex);
 
-	if (!vidinf->width || !vidinf->height || !vidinf->fps) {
-		kfree(vidinf);
-		vidinf = NULL;
-	}
-err:
-	return vidinf;
+	if (ret < 0)
+		return ret;
+
+	vidinf->width	= dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
+	vidinf->height	= dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
+	vidinf->fps	= dev->usbc_buf[4];
+	vidinf->valid   = vidinf->width && vidinf->height && vidinf->fps;
+
+	return 0;
 }
 
 int get_input_lines_info(struct hdpvr_device *dev)
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c
index 8247c19..cb69405 100644
--- a/drivers/media/usb/hdpvr/hdpvr-core.c
+++ b/drivers/media/usb/hdpvr/hdpvr-core.c
@@ -220,7 +220,6 @@
 {
 	int ret;
 	u8 *buf;
-	struct hdpvr_video_info *vidinf;
 
 	if (device_authorization(dev))
 		return -EACCES;
@@ -242,13 +241,6 @@
 		 "control request returned %d\n", ret);
 	mutex_unlock(&dev->usbc_mutex);
 
-	vidinf = get_video_info(dev);
-	if (!vidinf)
-		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
-			"no valid video signal or device init failed\n");
-	else
-		kfree(vidinf);
-
 	/* enable fan and bling leds */
 	mutex_lock(&dev->usbc_mutex);
 	buf[0] = 0x1;
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
index 774ba0e..4f8567a 100644
--- a/drivers/media/usb/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -277,44 +277,50 @@
 static int hdpvr_start_streaming(struct hdpvr_device *dev)
 {
 	int ret;
-	struct hdpvr_video_info *vidinf;
+	struct hdpvr_video_info vidinf;
 
 	if (dev->status == STATUS_STREAMING)
 		return 0;
-	else if (dev->status != STATUS_IDLE)
+	if (dev->status != STATUS_IDLE)
 		return -EAGAIN;
 
-	vidinf = get_video_info(dev);
+	ret = get_video_info(dev, &vidinf);
+	if (ret < 0)
+		return ret;
 
-	if (vidinf) {
-		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
-			 "video signal: %dx%d@%dhz\n", vidinf->width,
-			 vidinf->height, vidinf->fps);
-		kfree(vidinf);
-
-		/* start streaming 2 request */
-		ret = usb_control_msg(dev->udev,
-				      usb_sndctrlpipe(dev->udev, 0),
-				      0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
-		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
-			 "encoder start control request returned %d\n", ret);
-
-		hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
-
-		dev->status = STATUS_STREAMING;
-
-		INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
-		queue_work(dev->workqueue, &dev->worker);
-
-		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
-			 "streaming started\n");
-
-		return 0;
+	if (!vidinf.valid) {
+		msleep(250);
+		v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+				"no video signal at input %d\n", dev->options.video_input);
+		return -EAGAIN;
 	}
-	msleep(250);
-	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
-		 "no video signal at input %d\n", dev->options.video_input);
-	return -EAGAIN;
+
+	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+			"video signal: %dx%d@%dhz\n", vidinf.width,
+			vidinf.height, vidinf.fps);
+
+	/* start streaming 2 request */
+	ret = usb_control_msg(dev->udev,
+			usb_sndctrlpipe(dev->udev, 0),
+			0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
+	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+			"encoder start control request returned %d\n", ret);
+	if (ret < 0)
+		return ret;
+
+	ret = hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
+	if (ret)
+		return ret;
+
+	dev->status = STATUS_STREAMING;
+
+	INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
+	queue_work(dev->workqueue, &dev->worker);
+
+	v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+			"streaming started\n");
+
+	return 0;
 }
 
 
@@ -606,22 +612,20 @@
 static int vidioc_querystd(struct file *file, void *_fh, v4l2_std_id *a)
 {
 	struct hdpvr_device *dev = video_drvdata(file);
-	struct hdpvr_video_info *vid_info;
+	struct hdpvr_video_info vid_info;
 	struct hdpvr_fh *fh = _fh;
+	int ret;
 
-	*a = V4L2_STD_ALL;
+	*a = V4L2_STD_UNKNOWN;
 	if (dev->options.video_input == HDPVR_COMPONENT)
 		return fh->legacy_mode ? 0 : -ENODATA;
-	vid_info = get_video_info(dev);
-	if (vid_info == NULL)
-		return 0;
-	if (vid_info->width == 720 &&
-	    (vid_info->height == 480 || vid_info->height == 576)) {
-		*a = (vid_info->height == 480) ?
+	ret = get_video_info(dev, &vid_info);
+	if (vid_info.valid && vid_info.width == 720 &&
+	    (vid_info.height == 480 || vid_info.height == 576)) {
+		*a = (vid_info.height == 480) ?
 			V4L2_STD_525_60 : V4L2_STD_625_50;
 	}
-	kfree(vid_info);
-	return 0;
+	return ret;
 }
 
 static int vidioc_s_dv_timings(struct file *file, void *_fh,
@@ -665,7 +669,7 @@
 {
 	struct hdpvr_device *dev = video_drvdata(file);
 	struct hdpvr_fh *fh = _fh;
-	struct hdpvr_video_info *vid_info;
+	struct hdpvr_video_info vid_info;
 	bool interlaced;
 	int ret = 0;
 	int i;
@@ -673,10 +677,12 @@
 	fh->legacy_mode = false;
 	if (dev->options.video_input)
 		return -ENODATA;
-	vid_info = get_video_info(dev);
-	if (vid_info == NULL)
+	ret = get_video_info(dev, &vid_info);
+	if (ret)
+		return ret;
+	if (!vid_info.valid)
 		return -ENOLCK;
-	interlaced = vid_info->fps <= 30;
+	interlaced = vid_info.fps <= 30;
 	for (i = 0; i < ARRAY_SIZE(hdpvr_dv_timings); i++) {
 		const struct v4l2_bt_timings *bt = &hdpvr_dv_timings[i].bt;
 		unsigned hsize;
@@ -688,17 +694,17 @@
 			bt->il_vfrontporch + bt->il_vsync + bt->il_vbackporch +
 			bt->height;
 		fps = (unsigned)bt->pixelclock / (hsize * vsize);
-		if (bt->width != vid_info->width ||
-		    bt->height != vid_info->height ||
+		if (bt->width != vid_info.width ||
+		    bt->height != vid_info.height ||
 		    bt->interlaced != interlaced ||
-		    (fps != vid_info->fps && fps + 1 != vid_info->fps))
+		    (fps != vid_info.fps && fps + 1 != vid_info.fps))
 			continue;
 		*timings = hdpvr_dv_timings[i];
 		break;
 	}
 	if (i == ARRAY_SIZE(hdpvr_dv_timings))
 		ret = -ERANGE;
-	kfree(vid_info);
+
 	return ret;
 }
 
@@ -988,6 +994,7 @@
 {
 	struct hdpvr_device *dev = video_drvdata(file);
 	struct hdpvr_fh *fh = _fh;
+	int ret;
 
 	/*
 	 * The original driver would always returns the current detected
@@ -1000,14 +1007,15 @@
 	 * last set format.
 	 */
 	if (fh->legacy_mode) {
-		struct hdpvr_video_info *vid_info;
+		struct hdpvr_video_info vid_info;
 
-		vid_info = get_video_info(dev);
-		if (!vid_info)
+		ret = get_video_info(dev, &vid_info);
+		if (ret < 0)
+			return ret;
+		if (!vid_info.valid)
 			return -EFAULT;
-		f->fmt.pix.width = vid_info->width;
-		f->fmt.pix.height = vid_info->height;
-		kfree(vid_info);
+		f->fmt.pix.width = vid_info.width;
+		f->fmt.pix.height = vid_info.height;
 	} else {
 		f->fmt.pix.width = dev->width;
 		f->fmt.pix.height = dev->height;
diff --git a/drivers/media/usb/hdpvr/hdpvr.h b/drivers/media/usb/hdpvr/hdpvr.h
index 1478f3d..dc685d4 100644
--- a/drivers/media/usb/hdpvr/hdpvr.h
+++ b/drivers/media/usb/hdpvr/hdpvr.h
@@ -154,6 +154,7 @@
 	u16	width;
 	u16	height;
 	u8	fps;
+	bool	valid;
 };
 
 enum {
@@ -303,7 +304,7 @@
 int hdpvr_config_call(struct hdpvr_device *dev, uint value,
 		      unsigned char valbuf);
 
-struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev);
+int get_video_info(struct hdpvr_device *dev, struct hdpvr_video_info *vid_info);
 
 /* :0 s b8 81 1800 0003 0003 3 < */
 /* :0 0 3 = 0301ff */
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index e11267f..c4d51d7 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -2704,6 +2704,10 @@
 	pvr2_hdw_render_useless(hdw);
 }
 
+void pvr2_hdw_set_v4l2_dev(struct pvr2_hdw *hdw, struct video_device *vdev)
+{
+	vdev->v4l2_dev = &hdw->v4l2_dev;
+}
 
 /* Destroy hardware interaction structure */
 void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
@@ -5162,41 +5166,3 @@
 	} while(0); LOCK_GIVE(hdw->ctl_lock);
 	return result;
 }
-
-
-int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
-			     const struct v4l2_dbg_match *match, u64 reg_id,
-			     int setFl, u64 *val_ptr)
-{
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	struct v4l2_dbg_register req;
-	int stat = 0;
-	int okFl = 0;
-
-	if (!capable(CAP_SYS_ADMIN)) return -EPERM;
-
-	req.match = *match;
-	req.reg = reg_id;
-	if (setFl) req.val = *val_ptr;
-	/* It would be nice to know if a sub-device answered the request */
-	v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req);
-	if (!setFl) *val_ptr = req.val;
-	if (okFl) {
-		return stat;
-	}
-	return -EINVAL;
-#else
-	return -ENOSYS;
-#endif
-}
-
-
-/*
-  Stuff for Emacs to see, in order to encourage consistent editing style:
-  *** Local Variables: ***
-  *** mode: c ***
-  *** fill-column: 75 ***
-  *** tab-width: 8 ***
-  *** c-basic-offset: 8 ***
-  *** End: ***
-  */
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.h b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
index 91bae93..4184707 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.h
@@ -22,6 +22,7 @@
 
 #include <linux/usb.h>
 #include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
 #include "pvrusb2-io.h"
 #include "pvrusb2-ctrl.h"
 
@@ -138,6 +139,9 @@
 /* Called when hardware has been unplugged */
 void pvr2_hdw_disconnect(struct pvr2_hdw *);
 
+/* Sets v4l2_dev of a video_device struct */
+void pvr2_hdw_set_v4l2_dev(struct pvr2_hdw *, struct video_device *);
+
 /* Get the number of defined controls */
 unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *);
 
@@ -234,15 +238,6 @@
 void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
 				     enum pvr2_v4l_type index,int);
 
-/* Direct read/write access to chip's registers:
-   match - specify criteria to identify target chip (this is a v4l dbg struct)
-   reg_id  - register number to access
-   setFl   - true to set the register, false to read it
-   val_ptr - storage location for source / result. */
-int pvr2_hdw_register_access(struct pvr2_hdw *,
-			     const struct v4l2_dbg_match *match, u64 reg_id,
-			     int setFl, u64 *val_ptr);
-
 /* The following entry points are all lower level things you normally don't
    want to worry about. */
 
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-io.c b/drivers/media/usb/pvrusb2/pvrusb2-io.c
index 20b6ae0..1e35474 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-io.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-io.c
@@ -354,9 +354,9 @@
 		if (scnt < sp->buffer_slot_count) {
 			struct pvr2_buffer **nb = NULL;
 			if (scnt) {
-				nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
+				nb = kmemdup(sp->buffers, scnt * sizeof(*nb),
+					     GFP_KERNEL);
 				if (!nb) return -ENOMEM;
-				memcpy(nb,sp->buffers,scnt * sizeof(*nb));
 			}
 			kfree(sp->buffers);
 			sp->buffers = nb;
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
index a8a65fa..7c280f3 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -31,6 +31,7 @@
 #include <linux/videodev2.h>
 #include <linux/module.h>
 #include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 
@@ -800,36 +801,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-static int pvr2_g_register(struct file *file, void *priv, struct v4l2_dbg_register *req)
-{
-	struct pvr2_v4l2_fh *fh = file->private_data;
-	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-	u64 val;
-	int ret;
-
-	ret = pvr2_hdw_register_access(
-			hdw, &req->match, req->reg,
-			0, &val);
-	req->val = val;
-	return ret;
-}
-
-static int pvr2_s_register(struct file *file, void *priv, const struct v4l2_dbg_register *req)
-{
-	struct pvr2_v4l2_fh *fh = file->private_data;
-	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
-	u64 val;
-	int ret;
-
-	val = req->val;
-	ret = pvr2_hdw_register_access(
-			hdw, &req->match, req->reg,
-			1, &val);
-	return ret;
-}
-#endif
-
 static const struct v4l2_ioctl_ops pvr2_ioctl_ops = {
 	.vidioc_querycap		    = pvr2_querycap,
 	.vidioc_g_priority		    = pvr2_g_priority,
@@ -864,10 +835,6 @@
 	.vidioc_g_ext_ctrls		    = pvr2_g_ext_ctrls,
 	.vidioc_s_ext_ctrls		    = pvr2_s_ext_ctrls,
 	.vidioc_try_ext_ctrls		    = pvr2_try_ext_ctrls,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register		    = pvr2_g_register,
-	.vidioc_s_register		    = pvr2_s_register,
-#endif
 };
 
 static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
@@ -904,8 +871,8 @@
 static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
 {
 	if (!dip) return;
-	if (!dip->devbase.parent) return;
-	dip->devbase.parent = NULL;
+	if (!dip->devbase.v4l2_dev->dev) return;
+	dip->devbase.v4l2_dev->dev = NULL;
 	device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
 }
 
@@ -1298,7 +1265,6 @@
 			       struct pvr2_v4l2 *vp,
 			       int v4l_type)
 {
-	struct usb_device *usbdev;
 	int mindevnum;
 	int unit_number;
 	struct pvr2_hdw *hdw;
@@ -1306,7 +1272,6 @@
 	dip->v4lp = vp;
 
 	hdw = vp->channel.mc_head->hdw;
-	usbdev = pvr2_hdw_get_dev(hdw);
 	dip->v4l_type = v4l_type;
 	switch (v4l_type) {
 	case VFL_TYPE_GRABBER:
@@ -1355,7 +1320,7 @@
 	if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
 		mindevnum = nr_ptr[unit_number];
 	}
-	dip->devbase.parent = &usbdev->dev;
+	pvr2_hdw_set_v4l2_dev(hdw, &dip->devbase);
 	if ((video_register_device(&dip->devbase,
 				   dip->v4l_type, mindevnum) < 0) &&
 	    (video_register_device(&dip->devbase,
diff --git a/drivers/media/usb/sn9c102/sn9c102.h b/drivers/media/usb/sn9c102/sn9c102.h
index 2bc153e..8a917f06 100644
--- a/drivers/media/usb/sn9c102/sn9c102.h
+++ b/drivers/media/usb/sn9c102/sn9c102.h
@@ -25,6 +25,7 @@
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
@@ -100,6 +101,8 @@
 struct sn9c102_device {
 	struct video_device* v4ldev;
 
+	struct v4l2_device v4l2_dev;
+
 	enum sn9c102_bridge bridge;
 	struct sn9c102_sensor sensor;
 
diff --git a/drivers/media/usb/sn9c102/sn9c102_core.c b/drivers/media/usb/sn9c102/sn9c102_core.c
index c957e9a..2cb44de 100644
--- a/drivers/media/usb/sn9c102/sn9c102_core.c
+++ b/drivers/media/usb/sn9c102/sn9c102_core.c
@@ -1737,6 +1737,7 @@
 	    video_device_node_name(cam->v4ldev));
 	video_set_drvdata(cam->v4ldev, NULL);
 	video_unregister_device(cam->v4ldev);
+	v4l2_device_unregister(&cam->v4l2_dev);
 	usb_put_dev(cam->usbdev);
 	kfree(cam->control_buffer);
 	kfree(cam);
@@ -3254,6 +3255,13 @@
 
 	cam->usbdev = udev;
 
+	/* register v4l2_device early so it can be used for printks */
+	if (v4l2_device_register(&intf->dev, &cam->v4l2_dev)) {
+		dev_err(&intf->dev, "v4l2_device_register failed\n");
+		err = -ENOMEM;
+		goto fail;
+	}
+
 	if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) {
 		DBG(1, "kzalloc() failed");
 		err = -ENOMEM;
@@ -3325,7 +3333,7 @@
 	strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
 	cam->v4ldev->fops = &sn9c102_fops;
 	cam->v4ldev->release = video_device_release;
-	cam->v4ldev->parent = &udev->dev;
+	cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
 
 	init_completion(&cam->probe);
 
@@ -3377,6 +3385,7 @@
 		kfree(cam->control_buffer);
 		if (cam->v4ldev)
 			video_device_release(cam->v4ldev);
+		v4l2_device_unregister(&cam->v4l2_dev);
 		kfree(cam);
 	}
 	return err;
@@ -3407,6 +3416,8 @@
 
 	wake_up_interruptible_all(&cam->wait_open);
 
+	v4l2_device_disconnect(&cam->v4l2_dev);
+
 	kref_put(&cam->kref, sn9c102_release_resources);
 
 	up_write(&sn9c102_dev_lock);
diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c
index a59153d2..876fc26 100644
--- a/drivers/media/usb/stk1160/stk1160-v4l.c
+++ b/drivers/media/usb/stk1160/stk1160-v4l.c
@@ -31,7 +31,6 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-fh.h>
 #include <media/v4l2-event.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/videobuf2-vmalloc.h>
 
 #include <media/saa7115.h>
@@ -454,19 +453,6 @@
 	return 0;
 }
 
-static int vidioc_g_chip_ident(struct file *file, void *priv,
-	       struct v4l2_dbg_chip_ident *chip)
-{
-	switch (chip->match.type) {
-	case V4L2_CHIP_MATCH_BRIDGE:
-		chip->ident = V4L2_IDENT_NONE;
-		chip->revision = 0;
-		return 0;
-	default:
-		return -EINVAL;
-	}
-}
-
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 static int vidioc_g_register(struct file *file, void *priv,
 			     struct v4l2_dbg_register *reg)
@@ -475,19 +461,6 @@
 	int rc;
 	u8 val;
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/* TODO: is this correct? */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
-		return 0;
-	default:
-		if (!v4l2_chip_match_host(&reg->match))
-			return -EINVAL;
-	}
-
 	/* Match host */
 	rc = stk1160_read_reg(dev, reg->reg, &val);
 	reg->val = val;
@@ -501,19 +474,6 @@
 {
 	struct stk1160 *dev = video_drvdata(file);
 
-	switch (reg->match.type) {
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
-		return 0;
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/* TODO: is this correct? */
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
-		return 0;
-	default:
-		if (!v4l2_chip_match_host(&reg->match))
-			return -EINVAL;
-	}
-
 	/* Match host */
 	return stk1160_write_reg(dev, reg->reg, cpu_to_le16(reg->val));
 }
@@ -543,7 +503,6 @@
 	.vidioc_log_status  = v4l2_ctrl_log_status,
 	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-	.vidioc_g_chip_ident = vidioc_g_chip_ident,
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register = vidioc_g_register,
diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c
index 307d8c5..1ccaadd 100644
--- a/drivers/media/usb/tm6000/tm6000-cards.c
+++ b/drivers/media/usb/tm6000/tm6000-cards.c
@@ -1114,7 +1114,7 @@
 	/* Default values for STD and resolutions */
 	dev->width = 720;
 	dev->height = 480;
-	dev->norm = V4L2_STD_PAL_M;
+	dev->norm = V4L2_STD_NTSC_M;
 
 	/* Configure tuner */
 	tm6000_config_tuner(dev);
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index a78de1d..cc1aa14 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -1076,6 +1076,15 @@
 	return 0;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+	struct tm6000_fh *fh = priv;
+	struct tm6000_core *dev = fh->dev;
+
+	*norm = dev->norm;
+	return 0;
+}
+
 static const char *iname[] = {
 	[TM6000_INPUT_TV] = "Television",
 	[TM6000_INPUT_COMPOSITE1] = "Composite 1",
@@ -1134,7 +1143,7 @@
 
 	dev->input = i;
 
-	rc = vidioc_s_std(file, priv, dev->vfd->current_norm);
+	rc = vidioc_s_std(file, priv, dev->norm);
 
 	return rc;
 }
@@ -1547,6 +1556,7 @@
 	.vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
 	.vidioc_s_std             = vidioc_s_std,
+	.vidioc_g_std             = vidioc_g_std,
 	.vidioc_enum_input        = vidioc_enum_input,
 	.vidioc_g_input           = vidioc_g_input,
 	.vidioc_s_input           = vidioc_s_input,
@@ -1570,7 +1580,6 @@
 	.ioctl_ops      = &video_ioctl_ops,
 	.release	= video_device_release,
 	.tvnorms        = TM6000_STD,
-	.current_norm   = V4L2_STD_NTSC_M,
 };
 
 static const struct v4l2_file_operations radio_fops = {
diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
index 21b9049..f8a60c1 100644
--- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
@@ -1768,6 +1768,8 @@
 	i2c_del_adapter(&ttusb->i2c_adap);
 err_unregister_adapter:
 	dvb_unregister_adapter (&ttusb->adapter);
+	ttusb_free_iso_urbs(ttusb);
+	kfree(ttusb);
 	return result;
 }
 
diff --git a/drivers/media/usb/usbtv/Kconfig b/drivers/media/usb/usbtv/Kconfig
new file mode 100644
index 0000000..8864436
--- /dev/null
+++ b/drivers/media/usb/usbtv/Kconfig
@@ -0,0 +1,10 @@
+config VIDEO_USBTV
+        tristate "USBTV007 video capture support"
+        depends on VIDEO_DEV
+        select VIDEOBUF2_VMALLOC
+
+        ---help---
+          This is a video4linux2 driver for USBTV007 based video capture devices.
+
+          To compile this driver as a module, choose M here: the
+          module will be called usbtv
diff --git a/drivers/media/usb/usbtv/Makefile b/drivers/media/usb/usbtv/Makefile
new file mode 100644
index 0000000..28b872f
--- /dev/null
+++ b/drivers/media/usb/usbtv/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_USBTV) += usbtv.o
diff --git a/drivers/media/usb/usbtv/usbtv.c b/drivers/media/usb/usbtv/usbtv.c
new file mode 100644
index 0000000..bf43f87
--- /dev/null
+++ b/drivers/media/usb/usbtv/usbtv.c
@@ -0,0 +1,696 @@
+/*
+ * Fushicai USBTV007 Video Grabber Driver
+ *
+ * Product web site:
+ * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
+ *
+ * Following LWN articles were very useful in construction of this driver:
+ * Video4Linux2 API series: http://lwn.net/Articles/203924/
+ * videobuf2 API explanation: http://lwn.net/Articles/447435/
+ * Thanks go to Jonathan Corbet for providing this quality documentation.
+ * He is awesome.
+ *
+ * Copyright (c) 2013 Lubomir Rintel
+ * All rights reserved.
+ * No physical hardware was harmed running Windows during the
+ * reverse-engineering activity
+ *
+ * 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,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/version.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-vmalloc.h>
+
+/* Hardware. */
+#define USBTV_VIDEO_ENDP	0x81
+#define USBTV_BASE		0xc000
+#define USBTV_REQUEST_REG	12
+
+/* Number of concurrent isochronous urbs submitted.
+ * Higher numbers was seen to overly saturate the USB bus. */
+#define USBTV_ISOC_TRANSFERS	16
+#define USBTV_ISOC_PACKETS	8
+
+#define USBTV_WIDTH		720
+#define USBTV_HEIGHT		480
+
+#define USBTV_CHUNK_SIZE	256
+#define USBTV_CHUNK		240
+#define USBTV_CHUNKS		(USBTV_WIDTH * USBTV_HEIGHT \
+					/ 2 / USBTV_CHUNK)
+
+/* Chunk header. */
+#define USBTV_MAGIC_OK(chunk)	((be32_to_cpu(chunk[0]) & 0xff000000) \
+							== 0x88000000)
+#define USBTV_FRAME_ID(chunk)	((be32_to_cpu(chunk[0]) & 0x00ff0000) >> 16)
+#define USBTV_ODD(chunk)	((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15)
+#define USBTV_CHUNK_NO(chunk)	(be32_to_cpu(chunk[0]) & 0x00000fff)
+
+/* A single videobuf2 frame buffer. */
+struct usbtv_buf {
+	struct vb2_buffer vb;
+	struct list_head list;
+};
+
+/* Per-device structure. */
+struct usbtv {
+	struct device *dev;
+	struct usb_device *udev;
+	struct v4l2_device v4l2_dev;
+	struct video_device vdev;
+	struct vb2_queue vb2q;
+	struct mutex v4l2_lock;
+	struct mutex vb2q_lock;
+
+	/* List of videobuf2 buffers protected by a lock. */
+	spinlock_t buflock;
+	struct list_head bufs;
+
+	/* Number of currently processed frame, useful find
+	 * out when a new one begins. */
+	u32 frame_id;
+
+	int iso_size;
+	unsigned int sequence;
+	struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS];
+};
+
+static int usbtv_setup_capture(struct usbtv *usbtv)
+{
+	int ret;
+	int pipe = usb_rcvctrlpipe(usbtv->udev, 0);
+	int i;
+	static const u16 protoregs[][2] = {
+		/* These seem to enable the device. */
+		{ USBTV_BASE + 0x0008, 0x0001 },
+		{ USBTV_BASE + 0x01d0, 0x00ff },
+		{ USBTV_BASE + 0x01d9, 0x0002 },
+
+		/* These seem to influence color parameters, such as
+		 * brightness, etc. */
+		{ USBTV_BASE + 0x0239, 0x0040 },
+		{ USBTV_BASE + 0x0240, 0x0000 },
+		{ USBTV_BASE + 0x0241, 0x0000 },
+		{ USBTV_BASE + 0x0242, 0x0002 },
+		{ USBTV_BASE + 0x0243, 0x0080 },
+		{ USBTV_BASE + 0x0244, 0x0012 },
+		{ USBTV_BASE + 0x0245, 0x0090 },
+		{ USBTV_BASE + 0x0246, 0x0000 },
+
+		{ USBTV_BASE + 0x0278, 0x002d },
+		{ USBTV_BASE + 0x0279, 0x000a },
+		{ USBTV_BASE + 0x027a, 0x0032 },
+		{ 0xf890, 0x000c },
+		{ 0xf894, 0x0086 },
+
+		{ USBTV_BASE + 0x00ac, 0x00c0 },
+		{ USBTV_BASE + 0x00ad, 0x0000 },
+		{ USBTV_BASE + 0x00a2, 0x0012 },
+		{ USBTV_BASE + 0x00a3, 0x00e0 },
+		{ USBTV_BASE + 0x00a4, 0x0028 },
+		{ USBTV_BASE + 0x00a5, 0x0082 },
+		{ USBTV_BASE + 0x00a7, 0x0080 },
+		{ USBTV_BASE + 0x0000, 0x0014 },
+		{ USBTV_BASE + 0x0006, 0x0003 },
+		{ USBTV_BASE + 0x0090, 0x0099 },
+		{ USBTV_BASE + 0x0091, 0x0090 },
+		{ USBTV_BASE + 0x0094, 0x0068 },
+		{ USBTV_BASE + 0x0095, 0x0070 },
+		{ USBTV_BASE + 0x009c, 0x0030 },
+		{ USBTV_BASE + 0x009d, 0x00c0 },
+		{ USBTV_BASE + 0x009e, 0x00e0 },
+		{ USBTV_BASE + 0x0019, 0x0006 },
+		{ USBTV_BASE + 0x008c, 0x00ba },
+		{ USBTV_BASE + 0x0101, 0x00ff },
+		{ USBTV_BASE + 0x010c, 0x00b3 },
+		{ USBTV_BASE + 0x01b2, 0x0080 },
+		{ USBTV_BASE + 0x01b4, 0x00a0 },
+		{ USBTV_BASE + 0x014c, 0x00ff },
+		{ USBTV_BASE + 0x014d, 0x00ca },
+		{ USBTV_BASE + 0x0113, 0x0053 },
+		{ USBTV_BASE + 0x0119, 0x008a },
+		{ USBTV_BASE + 0x013c, 0x0003 },
+		{ USBTV_BASE + 0x0150, 0x009c },
+		{ USBTV_BASE + 0x0151, 0x0071 },
+		{ USBTV_BASE + 0x0152, 0x00c6 },
+		{ USBTV_BASE + 0x0153, 0x0084 },
+		{ USBTV_BASE + 0x0154, 0x00bc },
+		{ USBTV_BASE + 0x0155, 0x00a0 },
+		{ USBTV_BASE + 0x0156, 0x00a0 },
+		{ USBTV_BASE + 0x0157, 0x009c },
+		{ USBTV_BASE + 0x0158, 0x001f },
+		{ USBTV_BASE + 0x0159, 0x0006 },
+		{ USBTV_BASE + 0x015d, 0x0000 },
+
+		{ USBTV_BASE + 0x0284, 0x0088 },
+		{ USBTV_BASE + 0x0003, 0x0004 },
+		{ USBTV_BASE + 0x001a, 0x0079 },
+		{ USBTV_BASE + 0x0100, 0x00d3 },
+		{ USBTV_BASE + 0x010e, 0x0068 },
+		{ USBTV_BASE + 0x010f, 0x009c },
+		{ USBTV_BASE + 0x0112, 0x00f0 },
+		{ USBTV_BASE + 0x0115, 0x0015 },
+		{ USBTV_BASE + 0x0117, 0x0000 },
+		{ USBTV_BASE + 0x0118, 0x00fc },
+		{ USBTV_BASE + 0x012d, 0x0004 },
+		{ USBTV_BASE + 0x012f, 0x0008 },
+		{ USBTV_BASE + 0x0220, 0x002e },
+		{ USBTV_BASE + 0x0225, 0x0008 },
+		{ USBTV_BASE + 0x024e, 0x0002 },
+		{ USBTV_BASE + 0x024f, 0x0001 },
+		{ USBTV_BASE + 0x0254, 0x005f },
+		{ USBTV_BASE + 0x025a, 0x0012 },
+		{ USBTV_BASE + 0x025b, 0x0001 },
+		{ USBTV_BASE + 0x0263, 0x001c },
+		{ USBTV_BASE + 0x0266, 0x0011 },
+		{ USBTV_BASE + 0x0267, 0x0005 },
+		{ USBTV_BASE + 0x024e, 0x0002 },
+		{ USBTV_BASE + 0x024f, 0x0002 },
+	};
+
+	for (i = 0; i < ARRAY_SIZE(protoregs); i++) {
+		u16 index = protoregs[i][0];
+		u16 value = protoregs[i][1];
+
+		ret = usb_control_msg(usbtv->udev, pipe, USBTV_REQUEST_REG,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			value, index, NULL, 0, 0);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+/* Called for each 256-byte image chunk.
+ * First word identifies the chunk, followed by 240 words of image
+ * data and padding. */
+static void usbtv_image_chunk(struct usbtv *usbtv, u32 *chunk)
+{
+	int frame_id, odd, chunk_no;
+	u32 *frame;
+	struct usbtv_buf *buf;
+	unsigned long flags;
+
+	/* Ignore corrupted lines. */
+	if (!USBTV_MAGIC_OK(chunk))
+		return;
+	frame_id = USBTV_FRAME_ID(chunk);
+	odd = USBTV_ODD(chunk);
+	chunk_no = USBTV_CHUNK_NO(chunk);
+
+	/* Deinterlace. TODO: Use interlaced frame format. */
+	chunk_no = (chunk_no - chunk_no % 3) * 2 + chunk_no % 3;
+	chunk_no += !odd * 3;
+
+	if (chunk_no >= USBTV_CHUNKS)
+		return;
+
+	/* Beginning of a frame. */
+	if (chunk_no == 0)
+		usbtv->frame_id = frame_id;
+
+	spin_lock_irqsave(&usbtv->buflock, flags);
+	if (list_empty(&usbtv->bufs)) {
+		/* No free buffers. Userspace likely too slow. */
+		spin_unlock_irqrestore(&usbtv->buflock, flags);
+		return;
+	}
+
+	/* First available buffer. */
+	buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list);
+	frame = vb2_plane_vaddr(&buf->vb, 0);
+
+	/* Copy the chunk. */
+	memcpy(&frame[chunk_no * USBTV_CHUNK], &chunk[1],
+			USBTV_CHUNK * sizeof(chunk[1]));
+
+	/* Last chunk in a frame, signalling an end */
+	if (usbtv->frame_id && chunk_no == USBTV_CHUNKS-1) {
+		int size = vb2_plane_size(&buf->vb, 0);
+
+		buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
+		buf->vb.v4l2_buf.sequence = usbtv->sequence++;
+		v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
+		vb2_set_plane_payload(&buf->vb, 0, size);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
+		list_del(&buf->list);
+	}
+
+	spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+/* Got image data. Each packet contains a number of 256-word chunks we
+ * compose the image from. */
+static void usbtv_iso_cb(struct urb *ip)
+{
+	int ret;
+	int i;
+	struct usbtv *usbtv = (struct usbtv *)ip->context;
+
+	switch (ip->status) {
+	/* All fine. */
+	case 0:
+		break;
+	/* Device disconnected or capture stopped? */
+	case -ENODEV:
+	case -ENOENT:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		return;
+	/* Unknown error. Retry. */
+	default:
+		dev_warn(usbtv->dev, "Bad response for ISO request.\n");
+		goto resubmit;
+	}
+
+	for (i = 0; i < ip->number_of_packets; i++) {
+		int size = ip->iso_frame_desc[i].actual_length;
+		unsigned char *data = ip->transfer_buffer +
+				ip->iso_frame_desc[i].offset;
+		int offset;
+
+		for (offset = 0; USBTV_CHUNK_SIZE * offset < size; offset++)
+			usbtv_image_chunk(usbtv,
+				(u32 *)&data[USBTV_CHUNK_SIZE * offset]);
+	}
+
+resubmit:
+	ret = usb_submit_urb(ip, GFP_ATOMIC);
+	if (ret < 0)
+		dev_warn(usbtv->dev, "Could not resubmit ISO URB\n");
+}
+
+static struct urb *usbtv_setup_iso_transfer(struct usbtv *usbtv)
+{
+	struct urb *ip;
+	int size = usbtv->iso_size;
+	int i;
+
+	ip = usb_alloc_urb(USBTV_ISOC_PACKETS, GFP_KERNEL);
+	if (ip == NULL)
+		return NULL;
+
+	ip->dev = usbtv->udev;
+	ip->context = usbtv;
+	ip->pipe = usb_rcvisocpipe(usbtv->udev, USBTV_VIDEO_ENDP);
+	ip->interval = 1;
+	ip->transfer_flags = URB_ISO_ASAP;
+	ip->transfer_buffer = kzalloc(size * USBTV_ISOC_PACKETS,
+						GFP_KERNEL);
+	ip->complete = usbtv_iso_cb;
+	ip->number_of_packets = USBTV_ISOC_PACKETS;
+	ip->transfer_buffer_length = size * USBTV_ISOC_PACKETS;
+	for (i = 0; i < USBTV_ISOC_PACKETS; i++) {
+		ip->iso_frame_desc[i].offset = size * i;
+		ip->iso_frame_desc[i].length = size;
+	}
+
+	return ip;
+}
+
+static void usbtv_stop(struct usbtv *usbtv)
+{
+	int i;
+	unsigned long flags;
+
+	/* Cancel running transfers. */
+	for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {
+		struct urb *ip = usbtv->isoc_urbs[i];
+		if (ip == NULL)
+			continue;
+		usb_kill_urb(ip);
+		kfree(ip->transfer_buffer);
+		usb_free_urb(ip);
+		usbtv->isoc_urbs[i] = NULL;
+	}
+
+	/* Return buffers to userspace. */
+	spin_lock_irqsave(&usbtv->buflock, flags);
+	while (!list_empty(&usbtv->bufs)) {
+		struct usbtv_buf *buf = list_first_entry(&usbtv->bufs,
+						struct usbtv_buf, list);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+		list_del(&buf->list);
+	}
+	spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+static int usbtv_start(struct usbtv *usbtv)
+{
+	int i;
+	int ret;
+
+	ret = usb_set_interface(usbtv->udev, 0, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = usbtv_setup_capture(usbtv);
+	if (ret < 0)
+		return ret;
+
+	ret = usb_set_interface(usbtv->udev, 0, 1);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) {
+		struct urb *ip;
+
+		ip = usbtv_setup_iso_transfer(usbtv);
+		if (ip == NULL) {
+			ret = -ENOMEM;
+			goto start_fail;
+		}
+		usbtv->isoc_urbs[i] = ip;
+
+		ret = usb_submit_urb(ip, GFP_KERNEL);
+		if (ret < 0)
+			goto start_fail;
+	}
+
+	return 0;
+
+start_fail:
+	usbtv_stop(usbtv);
+	return ret;
+}
+
+struct usb_device_id usbtv_id_table[] = {
+	{ USB_DEVICE(0x1b71, 0x3002) },
+	{}
+};
+MODULE_DEVICE_TABLE(usb, usbtv_id_table);
+
+static int usbtv_querycap(struct file *file, void *priv,
+				struct v4l2_capability *cap)
+{
+	struct usbtv *dev = video_drvdata(file);
+
+	strlcpy(cap->driver, "usbtv", sizeof(cap->driver));
+	strlcpy(cap->card, "usbtv", sizeof(cap->card));
+	usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE;
+	cap->device_caps |= V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+	return 0;
+}
+
+static int usbtv_enum_input(struct file *file, void *priv,
+					struct v4l2_input *i)
+{
+	if (i->index > 0)
+		return -EINVAL;
+
+	strlcpy(i->name, "Composite", sizeof(i->name));
+	i->type = V4L2_INPUT_TYPE_CAMERA;
+	i->std = V4L2_STD_525_60;
+	return 0;
+}
+
+static int usbtv_enum_fmt_vid_cap(struct file *file, void  *priv,
+					struct v4l2_fmtdesc *f)
+{
+	if (f->index > 0)
+		return -EINVAL;
+
+	strlcpy(f->description, "16 bpp YUY2, 4:2:2, packed",
+					sizeof(f->description));
+	f->pixelformat = V4L2_PIX_FMT_YUYV;
+	return 0;
+}
+
+static int usbtv_fmt_vid_cap(struct file *file, void *priv,
+					struct v4l2_format *f)
+{
+	f->fmt.pix.width = USBTV_WIDTH;
+	f->fmt.pix.height = USBTV_HEIGHT;
+	f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+	f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+	f->fmt.pix.bytesperline = USBTV_WIDTH * 2;
+	f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height);
+	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+	f->fmt.pix.priv = 0;
+	return 0;
+}
+
+static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+	*norm = V4L2_STD_525_60;
+	return 0;
+}
+
+static int usbtv_g_input(struct file *file, void *priv, unsigned int *i)
+{
+	*i = 0;
+	return 0;
+}
+
+static int usbtv_s_input(struct file *file, void *priv, unsigned int i)
+{
+	if (i > 0)
+		return -EINVAL;
+	return 0;
+}
+
+static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm)
+{
+	if (norm & V4L2_STD_525_60)
+		return 0;
+	return -EINVAL;
+}
+
+struct v4l2_ioctl_ops usbtv_ioctl_ops = {
+	.vidioc_querycap = usbtv_querycap,
+	.vidioc_enum_input = usbtv_enum_input,
+	.vidioc_enum_fmt_vid_cap = usbtv_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = usbtv_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = usbtv_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = usbtv_fmt_vid_cap,
+	.vidioc_g_std = usbtv_g_std,
+	.vidioc_s_std = usbtv_s_std,
+	.vidioc_g_input = usbtv_g_input,
+	.vidioc_s_input = usbtv_s_input,
+
+	.vidioc_reqbufs = vb2_ioctl_reqbufs,
+	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf = vb2_ioctl_querybuf,
+	.vidioc_create_bufs = vb2_ioctl_create_bufs,
+	.vidioc_qbuf = vb2_ioctl_qbuf,
+	.vidioc_dqbuf = vb2_ioctl_dqbuf,
+	.vidioc_streamon = vb2_ioctl_streamon,
+	.vidioc_streamoff = vb2_ioctl_streamoff,
+};
+
+struct v4l2_file_operations usbtv_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = video_ioctl2,
+	.mmap = vb2_fop_mmap,
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
+	.read = vb2_fop_read,
+	.poll = vb2_fop_poll,
+};
+
+static int usbtv_queue_setup(struct vb2_queue *vq,
+	const struct v4l2_format *v4l_fmt, unsigned int *nbuffers,
+	unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
+{
+	if (*nbuffers < 2)
+		*nbuffers = 2;
+	*nplanes = 1;
+	sizes[0] = USBTV_CHUNK * USBTV_CHUNKS * sizeof(u32);
+
+	return 0;
+}
+
+static void usbtv_buf_queue(struct vb2_buffer *vb)
+{
+	struct usbtv *usbtv = vb2_get_drv_priv(vb->vb2_queue);
+	struct usbtv_buf *buf = container_of(vb, struct usbtv_buf, vb);
+	unsigned long flags;
+
+	if (usbtv->udev == NULL) {
+		vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+		return;
+	}
+
+	spin_lock_irqsave(&usbtv->buflock, flags);
+	list_add_tail(&buf->list, &usbtv->bufs);
+	spin_unlock_irqrestore(&usbtv->buflock, flags);
+}
+
+static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
+	if (usbtv->udev == NULL)
+		return -ENODEV;
+
+	return usbtv_start(usbtv);
+}
+
+static int usbtv_stop_streaming(struct vb2_queue *vq)
+{
+	struct usbtv *usbtv = vb2_get_drv_priv(vq);
+
+	if (usbtv->udev == NULL)
+		return -ENODEV;
+
+	usbtv_stop(usbtv);
+	return 0;
+}
+
+struct vb2_ops usbtv_vb2_ops = {
+	.queue_setup = usbtv_queue_setup,
+	.buf_queue = usbtv_buf_queue,
+	.start_streaming = usbtv_start_streaming,
+	.stop_streaming = usbtv_stop_streaming,
+};
+
+static void usbtv_release(struct v4l2_device *v4l2_dev)
+{
+	struct usbtv *usbtv = container_of(v4l2_dev, struct usbtv, v4l2_dev);
+
+	v4l2_device_unregister(&usbtv->v4l2_dev);
+	vb2_queue_release(&usbtv->vb2q);
+	kfree(usbtv);
+}
+
+static int usbtv_probe(struct usb_interface *intf,
+	const struct usb_device_id *id)
+{
+	int ret;
+	int size;
+	struct device *dev = &intf->dev;
+	struct usbtv *usbtv;
+
+	/* Checks that the device is what we think it is. */
+	if (intf->num_altsetting != 2)
+		return -ENODEV;
+	if (intf->altsetting[1].desc.bNumEndpoints != 4)
+		return -ENODEV;
+
+	/* Packet size is split into 11 bits of base size and count of
+	 * extra multiplies of it.*/
+	size = usb_endpoint_maxp(&intf->altsetting[1].endpoint[0].desc);
+	size = (size & 0x07ff) * (((size & 0x1800) >> 11) + 1);
+
+	/* Device structure */
+	usbtv = kzalloc(sizeof(struct usbtv), GFP_KERNEL);
+	if (usbtv == NULL)
+		return -ENOMEM;
+	usbtv->dev = dev;
+	usbtv->udev = usb_get_dev(interface_to_usbdev(intf));
+	usbtv->iso_size = size;
+	spin_lock_init(&usbtv->buflock);
+	mutex_init(&usbtv->v4l2_lock);
+	mutex_init(&usbtv->vb2q_lock);
+	INIT_LIST_HEAD(&usbtv->bufs);
+
+	/* videobuf2 structure */
+	usbtv->vb2q.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	usbtv->vb2q.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+	usbtv->vb2q.drv_priv = usbtv;
+	usbtv->vb2q.buf_struct_size = sizeof(struct usbtv_buf);
+	usbtv->vb2q.ops = &usbtv_vb2_ops;
+	usbtv->vb2q.mem_ops = &vb2_vmalloc_memops;
+	usbtv->vb2q.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	usbtv->vb2q.lock = &usbtv->vb2q_lock;
+	ret = vb2_queue_init(&usbtv->vb2q);
+	if (ret < 0) {
+		dev_warn(dev, "Could not initialize videobuf2 queue\n");
+		goto usbtv_fail;
+	}
+
+	/* v4l2 structure */
+	usbtv->v4l2_dev.release = usbtv_release;
+	ret = v4l2_device_register(dev, &usbtv->v4l2_dev);
+	if (ret < 0) {
+		dev_warn(dev, "Could not register v4l2 device\n");
+		goto v4l2_fail;
+	}
+
+	usb_set_intfdata(intf, usbtv);
+
+	/* Video structure */
+	strlcpy(usbtv->vdev.name, "usbtv", sizeof(usbtv->vdev.name));
+	usbtv->vdev.v4l2_dev = &usbtv->v4l2_dev;
+	usbtv->vdev.release = video_device_release_empty;
+	usbtv->vdev.fops = &usbtv_fops;
+	usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops;
+	usbtv->vdev.tvnorms = V4L2_STD_525_60;
+	usbtv->vdev.queue = &usbtv->vb2q;
+	usbtv->vdev.lock = &usbtv->v4l2_lock;
+	set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags);
+	video_set_drvdata(&usbtv->vdev, usbtv);
+	ret = video_register_device(&usbtv->vdev, VFL_TYPE_GRABBER, -1);
+	if (ret < 0) {
+		dev_warn(dev, "Could not register video device\n");
+		goto vdev_fail;
+	}
+
+	dev_info(dev, "Fushicai USBTV007 Video Grabber\n");
+	return 0;
+
+vdev_fail:
+	v4l2_device_unregister(&usbtv->v4l2_dev);
+v4l2_fail:
+	vb2_queue_release(&usbtv->vb2q);
+usbtv_fail:
+	kfree(usbtv);
+
+	return ret;
+}
+
+static void usbtv_disconnect(struct usb_interface *intf)
+{
+	struct usbtv *usbtv = usb_get_intfdata(intf);
+
+	mutex_lock(&usbtv->vb2q_lock);
+	mutex_lock(&usbtv->v4l2_lock);
+
+	usbtv_stop(usbtv);
+	usb_set_intfdata(intf, NULL);
+	video_unregister_device(&usbtv->vdev);
+	v4l2_device_disconnect(&usbtv->v4l2_dev);
+	usb_put_dev(usbtv->udev);
+	usbtv->udev = NULL;
+
+	mutex_unlock(&usbtv->v4l2_lock);
+	mutex_unlock(&usbtv->vb2q_lock);
+
+	v4l2_device_put(&usbtv->v4l2_dev);
+}
+
+MODULE_AUTHOR("Lubomir Rintel");
+MODULE_DESCRIPTION("Fushicai USBTV007 Video Grabber Driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+struct usb_driver usbtv_usb_driver = {
+	.name = "usbtv",
+	.id_table = usbtv_id_table,
+	.probe = usbtv_probe,
+	.disconnect = usbtv_disconnect,
+};
+
+module_usb_driver(usbtv_usb_driver);
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index d34c2af..5c9e312 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -467,8 +467,6 @@
 	struct usb_usbvision *usbvision = video_drvdata(file);
 	int err_code;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
 	/* NT100x has a 8-bit register space */
 	err_code = usbvision_read_reg(usbvision, reg->reg&0xff);
 	if (err_code < 0) {
@@ -488,8 +486,6 @@
 	struct usb_usbvision *usbvision = video_drvdata(file);
 	int err_code;
 
-	if (!v4l2_chip_match_host(&reg->match))
-		return -EINVAL;
 	/* NT100x has a 8-bit register space */
 	err_code = usbvision_write_reg(usbvision, reg->reg & 0xff, reg->val);
 	if (err_code < 0) {
@@ -608,6 +604,14 @@
 	return 0;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+	struct usb_usbvision *usbvision = video_drvdata(file);
+
+	*id = usbvision->tvnorm_id;
+	return 0;
+}
+
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *vt)
 {
@@ -1248,6 +1252,7 @@
 	.vidioc_qbuf          = vidioc_qbuf,
 	.vidioc_dqbuf         = vidioc_dqbuf,
 	.vidioc_s_std         = vidioc_s_std,
+	.vidioc_g_std         = vidioc_g_std,
 	.vidioc_enum_input    = vidioc_enum_input,
 	.vidioc_g_input       = vidioc_g_input,
 	.vidioc_s_input       = vidioc_s_input,
@@ -1274,7 +1279,6 @@
 	.name           = "usbvision-video",
 	.release	= video_device_release,
 	.tvnorms        = USBVISION_NORMS,
-	.current_norm   = V4L2_STD_PAL
 };
 
 
@@ -1307,9 +1311,6 @@
 	.name		= "usbvision-radio",
 	.release	= video_device_release,
 	.ioctl_ops	= &usbvision_radio_ioctl_ops,
-
-	.tvnorms              = USBVISION_NORMS,
-	.current_norm         = V4L2_STD_PAL
 };
 
 
@@ -1459,6 +1460,7 @@
 
 	usbvision_remove_sysfs(usbvision->vdev);
 	usbvision_unregister_video(usbvision);
+	kfree(usbvision->alt_max_pkt_size);
 
 	usb_free_urb(usbvision->ctrl_urb);
 
@@ -1574,6 +1576,7 @@
 	usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL);
 	if (usbvision->alt_max_pkt_size == NULL) {
 		dev_err(&intf->dev, "usbvision: out of memory!\n");
+		usbvision_release(usbvision);
 		return -ENOMEM;
 	}
 
diff --git a/drivers/media/usb/uvc/Kconfig b/drivers/media/usb/uvc/Kconfig
index 541c9f1..6ed85efa 100644
--- a/drivers/media/usb/uvc/Kconfig
+++ b/drivers/media/usb/uvc/Kconfig
@@ -1,5 +1,6 @@
 config USB_VIDEO_CLASS
 	tristate "USB Video Class (UVC)"
+	depends on VIDEO_V4L2
 	select VIDEOBUF2_VMALLOC
 	---help---
 	  Support for the USB Video Class (UVC).  Currently only video
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 5dbefa6..81695d4 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1836,8 +1836,8 @@
 	INIT_LIST_HEAD(&dev->chains);
 	INIT_LIST_HEAD(&dev->streams);
 	atomic_set(&dev->nstreams, 0);
-	atomic_set(&dev->users, 0);
 	atomic_set(&dev->nmappings, 0);
+	mutex_init(&dev->lock);
 
 	dev->udev = usb_get_dev(udev);
 	dev->intf = usb_get_intf(intf);
@@ -1950,8 +1950,13 @@
 
 	/* Controls are cached on the fly so they don't need to be saved. */
 	if (intf->cur_altsetting->desc.bInterfaceSubClass ==
-	    UVC_SC_VIDEOCONTROL)
-		return uvc_status_suspend(dev);
+	    UVC_SC_VIDEOCONTROL) {
+		mutex_lock(&dev->lock);
+		if (dev->users)
+			uvc_status_stop(dev);
+		mutex_unlock(&dev->lock);
+		return 0;
+	}
 
 	list_for_each_entry(stream, &dev->streams, list) {
 		if (stream->intf == intf)
@@ -1973,14 +1978,20 @@
 
 	if (intf->cur_altsetting->desc.bInterfaceSubClass ==
 	    UVC_SC_VIDEOCONTROL) {
-		if (reset) {
-			int ret = uvc_ctrl_resume_device(dev);
+		int ret = 0;
 
+		if (reset) {
+			ret = uvc_ctrl_resume_device(dev);
 			if (ret < 0)
 				return ret;
 		}
 
-		return uvc_status_resume(dev);
+		mutex_lock(&dev->lock);
+		if (dev->users)
+			ret = uvc_status_start(dev, GFP_NOIO);
+		mutex_unlock(&dev->lock);
+
+		return ret;
 	}
 
 	list_for_each_entry(stream, &dev->streams, list) {
@@ -2163,6 +2174,24 @@
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info 		= UVC_QUIRK_PROBE_DEF },
+	/* Dell Alienware X51 */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x05a9,
+	  .idProduct		= 0x2643,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info	= UVC_QUIRK_PROBE_DEF },
+	/* Dell Studio Hybrid 140g (OmniVision webcam) */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x05a9,
+	  .idProduct		= 0x264a,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_DEF },
 	/* Apple Built-In iSight */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c
index b749277..f552ab9 100644
--- a/drivers/media/usb/uvc/uvc_status.c
+++ b/drivers/media/usb/uvc/uvc_status.c
@@ -206,32 +206,15 @@
 	uvc_input_cleanup(dev);
 }
 
-int uvc_status_start(struct uvc_device *dev)
+int uvc_status_start(struct uvc_device *dev, gfp_t flags)
 {
 	if (dev->int_urb == NULL)
 		return 0;
 
-	return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+	return usb_submit_urb(dev->int_urb, flags);
 }
 
 void uvc_status_stop(struct uvc_device *dev)
 {
 	usb_kill_urb(dev->int_urb);
 }
-
-int uvc_status_suspend(struct uvc_device *dev)
-{
-	if (atomic_read(&dev->users))
-		usb_kill_urb(dev->int_urb);
-
-	return 0;
-}
-
-int uvc_status_resume(struct uvc_device *dev)
-{
-	if (dev->int_urb == NULL || atomic_read(&dev->users) == 0)
-		return 0;
-
-	return usb_submit_urb(dev->int_urb, GFP_NOIO);
-}
-
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index b2dc326..3afff92 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -498,16 +498,20 @@
 		return -ENOMEM;
 	}
 
-	if (atomic_inc_return(&stream->dev->users) == 1) {
-		ret = uvc_status_start(stream->dev);
+	mutex_lock(&stream->dev->lock);
+	if (stream->dev->users == 0) {
+		ret = uvc_status_start(stream->dev, GFP_KERNEL);
 		if (ret < 0) {
-			atomic_dec(&stream->dev->users);
+			mutex_unlock(&stream->dev->lock);
 			usb_autopm_put_interface(stream->dev->intf);
 			kfree(handle);
 			return ret;
 		}
 	}
 
+	stream->dev->users++;
+	mutex_unlock(&stream->dev->lock);
+
 	v4l2_fh_init(&handle->vfh, stream->vdev);
 	v4l2_fh_add(&handle->vfh);
 	handle->chain = stream->chain;
@@ -538,8 +542,10 @@
 	kfree(handle);
 	file->private_data = NULL;
 
-	if (atomic_dec_return(&stream->dev->users) == 0)
+	mutex_lock(&stream->dev->lock);
+	if (--stream->dev->users == 0)
 		uvc_status_stop(stream->dev);
+	mutex_unlock(&stream->dev->lock);
 
 	usb_autopm_put_interface(stream->dev->intf);
 	return 0;
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index af505fd..9e35982 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -514,7 +514,8 @@
 	char name[32];
 
 	enum uvc_device_state state;
-	atomic_t users;
+	struct mutex lock;		/* Protects users */
+	unsigned int users;
 	atomic_t nmappings;
 
 	/* Video control interface */
@@ -660,10 +661,8 @@
 /* Status */
 extern int uvc_status_init(struct uvc_device *dev);
 extern void uvc_status_cleanup(struct uvc_device *dev);
-extern int uvc_status_start(struct uvc_device *dev);
+extern int uvc_status_start(struct uvc_device *dev, gfp_t flags);
 extern void uvc_status_stop(struct uvc_device *dev);
-extern int uvc_status_suspend(struct uvc_device *dev);
-extern int uvc_status_resume(struct uvc_device *dev);
 
 /* Controls */
 extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops;
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index aa50c46..4c33b8d 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -5,7 +5,8 @@
 tuner-objs	:=	tuner-core.o
 
 videodev-objs	:=	v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
-			v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
+			v4l2-event.o v4l2-ctrls.o v4l2-subdev.o v4l2-clk.o \
+			v4l2-async.o
 ifeq ($(CONFIG_COMPAT),y)
   videodev-objs += v4l2-compat-ioctl32.o
 endif
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
new file mode 100644
index 0000000..aae2417
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -0,0 +1,284 @@
+/*
+ * V4L2 asynchronous subdevice registration API
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <media/v4l2-async.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
+{
+#if IS_ENABLED(CONFIG_I2C)
+	struct i2c_client *client = i2c_verify_client(dev);
+	return client &&
+		asd->bus_type == V4L2_ASYNC_BUS_I2C &&
+		asd->match.i2c.adapter_id == client->adapter->nr &&
+		asd->match.i2c.address == client->addr;
+#else
+	return false;
+#endif
+}
+
+static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd)
+{
+	return asd->bus_type == V4L2_ASYNC_BUS_PLATFORM &&
+		!strcmp(asd->match.platform.name, dev_name(dev));
+}
+
+static LIST_HEAD(subdev_list);
+static LIST_HEAD(notifier_list);
+static DEFINE_MUTEX(list_lock);
+
+static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier,
+						    struct v4l2_async_subdev_list *asdl)
+{
+	struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+	struct v4l2_async_subdev *asd;
+	bool (*match)(struct device *,
+		      struct v4l2_async_subdev *);
+
+	list_for_each_entry(asd, &notifier->waiting, list) {
+		/* bus_type has been verified valid before */
+		switch (asd->bus_type) {
+		case V4L2_ASYNC_BUS_CUSTOM:
+			match = asd->match.custom.match;
+			if (!match)
+				/* Match always */
+				return asd;
+			break;
+		case V4L2_ASYNC_BUS_PLATFORM:
+			match = match_platform;
+			break;
+		case V4L2_ASYNC_BUS_I2C:
+			match = match_i2c;
+			break;
+		default:
+			/* Cannot happen, unless someone breaks us */
+			WARN_ON(true);
+			return NULL;
+		}
+
+		/* match cannot be NULL here */
+		if (match(sd->dev, asd))
+			return asd;
+	}
+
+	return NULL;
+}
+
+static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier,
+				  struct v4l2_async_subdev_list *asdl,
+				  struct v4l2_async_subdev *asd)
+{
+	struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+	int ret;
+
+	/* Remove from the waiting list */
+	list_del(&asd->list);
+	asdl->asd = asd;
+	asdl->notifier = notifier;
+
+	if (notifier->bound) {
+		ret = notifier->bound(notifier, sd, asd);
+		if (ret < 0)
+			return ret;
+	}
+	/* Move from the global subdevice list to notifier's done */
+	list_move(&asdl->list, &notifier->done);
+
+	ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd);
+	if (ret < 0) {
+		if (notifier->unbind)
+			notifier->unbind(notifier, sd, asd);
+		return ret;
+	}
+
+	if (list_empty(&notifier->waiting) && notifier->complete)
+		return notifier->complete(notifier);
+
+	return 0;
+}
+
+static void v4l2_async_cleanup(struct v4l2_async_subdev_list *asdl)
+{
+	struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+
+	v4l2_device_unregister_subdev(sd);
+	/* Subdevice driver will reprobe and put asdl back onto the list */
+	list_del_init(&asdl->list);
+	asdl->asd = NULL;
+	sd->dev = NULL;
+}
+
+int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+				 struct v4l2_async_notifier *notifier)
+{
+	struct v4l2_async_subdev_list *asdl, *tmp;
+	struct v4l2_async_subdev *asd;
+	int i;
+
+	if (!notifier->num_subdevs || notifier->num_subdevs > V4L2_MAX_SUBDEVS)
+		return -EINVAL;
+
+	notifier->v4l2_dev = v4l2_dev;
+	INIT_LIST_HEAD(&notifier->waiting);
+	INIT_LIST_HEAD(&notifier->done);
+
+	for (i = 0; i < notifier->num_subdevs; i++) {
+		asd = notifier->subdev[i];
+
+		switch (asd->bus_type) {
+		case V4L2_ASYNC_BUS_CUSTOM:
+		case V4L2_ASYNC_BUS_PLATFORM:
+		case V4L2_ASYNC_BUS_I2C:
+			break;
+		default:
+			dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
+				"Invalid bus-type %u on %p\n",
+				asd->bus_type, asd);
+			return -EINVAL;
+		}
+		list_add_tail(&asd->list, &notifier->waiting);
+	}
+
+	mutex_lock(&list_lock);
+
+	/* Keep also completed notifiers on the list */
+	list_add(&notifier->list, &notifier_list);
+
+	list_for_each_entry_safe(asdl, tmp, &subdev_list, list) {
+		int ret;
+
+		asd = v4l2_async_belongs(notifier, asdl);
+		if (!asd)
+			continue;
+
+		ret = v4l2_async_test_notify(notifier, asdl, asd);
+		if (ret < 0) {
+			mutex_unlock(&list_lock);
+			return ret;
+		}
+	}
+
+	mutex_unlock(&list_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(v4l2_async_notifier_register);
+
+void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
+{
+	struct v4l2_async_subdev_list *asdl, *tmp;
+	unsigned int notif_n_subdev = notifier->num_subdevs;
+	unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS);
+	struct device *dev[n_subdev];
+	int i = 0;
+
+	mutex_lock(&list_lock);
+
+	list_del(&notifier->list);
+
+	list_for_each_entry_safe(asdl, tmp, &notifier->done, list) {
+		struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
+
+		dev[i] = get_device(sd->dev);
+
+		v4l2_async_cleanup(asdl);
+
+		/* If we handled USB devices, we'd have to lock the parent too */
+		device_release_driver(dev[i++]);
+
+		if (notifier->unbind)
+			notifier->unbind(notifier, sd, sd->asdl.asd);
+	}
+
+	mutex_unlock(&list_lock);
+
+	while (i--) {
+		struct device *d = dev[i];
+
+		if (d && device_attach(d) < 0) {
+			const char *name = "(none)";
+			int lock = device_trylock(d);
+
+			if (lock && d->driver)
+				name = d->driver->name;
+			dev_err(d, "Failed to re-probe to %s\n", name);
+			if (lock)
+				device_unlock(d);
+		}
+		put_device(d);
+	}
+	/*
+	 * Don't care about the waiting list, it is initialised and populated
+	 * upon notifier registration.
+	 */
+}
+EXPORT_SYMBOL(v4l2_async_notifier_unregister);
+
+int v4l2_async_register_subdev(struct v4l2_subdev *sd)
+{
+	struct v4l2_async_subdev_list *asdl = &sd->asdl;
+	struct v4l2_async_notifier *notifier;
+
+	mutex_lock(&list_lock);
+
+	INIT_LIST_HEAD(&asdl->list);
+
+	list_for_each_entry(notifier, &notifier_list, list) {
+		struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, asdl);
+		if (asd) {
+			int ret = v4l2_async_test_notify(notifier, asdl, asd);
+			mutex_unlock(&list_lock);
+			return ret;
+		}
+	}
+
+	/* None matched, wait for hot-plugging */
+	list_add(&asdl->list, &subdev_list);
+
+	mutex_unlock(&list_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(v4l2_async_register_subdev);
+
+void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
+{
+	struct v4l2_async_subdev_list *asdl = &sd->asdl;
+	struct v4l2_async_notifier *notifier = asdl->notifier;
+
+	if (!asdl->asd) {
+		if (!list_empty(&asdl->list))
+			v4l2_async_cleanup(asdl);
+		return;
+	}
+
+	mutex_lock(&list_lock);
+
+	list_add(&asdl->asd->list, &notifier->waiting);
+
+	v4l2_async_cleanup(asdl);
+
+	if (notifier->unbind)
+		notifier->unbind(notifier, sd, sd->asdl.asd);
+
+	mutex_unlock(&list_lock);
+}
+EXPORT_SYMBOL(v4l2_async_unregister_subdev);
diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c
new file mode 100644
index 0000000..b67de86
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-clk.c
@@ -0,0 +1,242 @@
+/*
+ * V4L2 clock service
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/atomic.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <media/v4l2-clk.h>
+#include <media/v4l2-subdev.h>
+
+static DEFINE_MUTEX(clk_lock);
+static LIST_HEAD(clk_list);
+
+static struct v4l2_clk *v4l2_clk_find(const char *dev_id, const char *id)
+{
+	struct v4l2_clk *clk;
+
+	list_for_each_entry(clk, &clk_list, list) {
+		if (strcmp(dev_id, clk->dev_id))
+			continue;
+
+		if (!id || !clk->id || !strcmp(clk->id, id))
+			return clk;
+	}
+
+	return ERR_PTR(-ENODEV);
+}
+
+struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id)
+{
+	struct v4l2_clk *clk;
+
+	mutex_lock(&clk_lock);
+	clk = v4l2_clk_find(dev_name(dev), id);
+
+	if (!IS_ERR(clk))
+		atomic_inc(&clk->use_count);
+	mutex_unlock(&clk_lock);
+
+	return clk;
+}
+EXPORT_SYMBOL(v4l2_clk_get);
+
+void v4l2_clk_put(struct v4l2_clk *clk)
+{
+	struct v4l2_clk *tmp;
+
+	if (IS_ERR(clk))
+		return;
+
+	mutex_lock(&clk_lock);
+
+	list_for_each_entry(tmp, &clk_list, list)
+		if (tmp == clk)
+			atomic_dec(&clk->use_count);
+
+	mutex_unlock(&clk_lock);
+}
+EXPORT_SYMBOL(v4l2_clk_put);
+
+static int v4l2_clk_lock_driver(struct v4l2_clk *clk)
+{
+	struct v4l2_clk *tmp;
+	int ret = -ENODEV;
+
+	mutex_lock(&clk_lock);
+
+	list_for_each_entry(tmp, &clk_list, list)
+		if (tmp == clk) {
+			ret = !try_module_get(clk->ops->owner);
+			if (ret)
+				ret = -EFAULT;
+			break;
+		}
+
+	mutex_unlock(&clk_lock);
+
+	return ret;
+}
+
+static void v4l2_clk_unlock_driver(struct v4l2_clk *clk)
+{
+	module_put(clk->ops->owner);
+}
+
+int v4l2_clk_enable(struct v4l2_clk *clk)
+{
+	int ret = v4l2_clk_lock_driver(clk);
+
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&clk->lock);
+
+	if (++clk->enable == 1 && clk->ops->enable) {
+		ret = clk->ops->enable(clk);
+		if (ret < 0)
+			clk->enable--;
+	}
+
+	mutex_unlock(&clk->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(v4l2_clk_enable);
+
+/*
+ * You might Oops if you try to disabled a disabled clock, because then the
+ * driver isn't locked and could have been unloaded by now, so, don't do that
+ */
+void v4l2_clk_disable(struct v4l2_clk *clk)
+{
+	int enable;
+
+	mutex_lock(&clk->lock);
+
+	enable = --clk->enable;
+	if (WARN(enable < 0, "Unbalanced %s() on %s:%s!\n", __func__,
+		 clk->dev_id, clk->id))
+		clk->enable++;
+	else if (!enable && clk->ops->disable)
+		clk->ops->disable(clk);
+
+	mutex_unlock(&clk->lock);
+
+	v4l2_clk_unlock_driver(clk);
+}
+EXPORT_SYMBOL(v4l2_clk_disable);
+
+unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk)
+{
+	int ret = v4l2_clk_lock_driver(clk);
+
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&clk->lock);
+	if (!clk->ops->get_rate)
+		ret = -ENOSYS;
+	else
+		ret = clk->ops->get_rate(clk);
+	mutex_unlock(&clk->lock);
+
+	v4l2_clk_unlock_driver(clk);
+
+	return ret;
+}
+EXPORT_SYMBOL(v4l2_clk_get_rate);
+
+int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate)
+{
+	int ret = v4l2_clk_lock_driver(clk);
+
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&clk->lock);
+	if (!clk->ops->set_rate)
+		ret = -ENOSYS;
+	else
+		ret = clk->ops->set_rate(clk, rate);
+	mutex_unlock(&clk->lock);
+
+	v4l2_clk_unlock_driver(clk);
+
+	return ret;
+}
+EXPORT_SYMBOL(v4l2_clk_set_rate);
+
+struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops,
+				   const char *dev_id,
+				   const char *id, void *priv)
+{
+	struct v4l2_clk *clk;
+	int ret;
+
+	if (!ops || !dev_id)
+		return ERR_PTR(-EINVAL);
+
+	clk = kzalloc(sizeof(struct v4l2_clk), GFP_KERNEL);
+	if (!clk)
+		return ERR_PTR(-ENOMEM);
+
+	clk->id = kstrdup(id, GFP_KERNEL);
+	clk->dev_id = kstrdup(dev_id, GFP_KERNEL);
+	if ((id && !clk->id) || !clk->dev_id) {
+		ret = -ENOMEM;
+		goto ealloc;
+	}
+	clk->ops = ops;
+	clk->priv = priv;
+	atomic_set(&clk->use_count, 0);
+	mutex_init(&clk->lock);
+
+	mutex_lock(&clk_lock);
+	if (!IS_ERR(v4l2_clk_find(dev_id, id))) {
+		mutex_unlock(&clk_lock);
+		ret = -EEXIST;
+		goto eexist;
+	}
+	list_add_tail(&clk->list, &clk_list);
+	mutex_unlock(&clk_lock);
+
+	return clk;
+
+eexist:
+ealloc:
+	kfree(clk->id);
+	kfree(clk->dev_id);
+	kfree(clk);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(v4l2_clk_register);
+
+void v4l2_clk_unregister(struct v4l2_clk *clk)
+{
+	if (WARN(atomic_read(&clk->use_count),
+		 "%s(): Refusing to unregister ref-counted %s:%s clock!\n",
+		 __func__, clk->dev_id, clk->id))
+		return;
+
+	mutex_lock(&clk_lock);
+	list_del(&clk->list);
+	mutex_unlock(&clk_lock);
+
+	kfree(clk->id);
+	kfree(clk->dev_id);
+	kfree(clk);
+}
+EXPORT_SYMBOL(v4l2_clk_unregister);
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 3fed63f..a95e5e2 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -61,7 +61,6 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-chip-ident.h>
 
 #include <linux/videodev2.h>
 
@@ -227,62 +226,9 @@
 }
 EXPORT_SYMBOL(v4l2_ctrl_next);
 
-int v4l2_chip_match_host(const struct v4l2_dbg_match *match)
-{
-	switch (match->type) {
-	case V4L2_CHIP_MATCH_BRIDGE:
-		return match->addr == 0;
-	default:
-		return 0;
-	}
-}
-EXPORT_SYMBOL(v4l2_chip_match_host);
-
-#if IS_ENABLED(CONFIG_I2C)
-int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match)
-{
-	int len;
-
-	if (c == NULL || match == NULL)
-		return 0;
-
-	switch (match->type) {
-	case V4L2_CHIP_MATCH_I2C_DRIVER:
-		if (c->driver == NULL || c->driver->driver.name == NULL)
-			return 0;
-		len = strlen(c->driver->driver.name);
-		return len && !strncmp(c->driver->driver.name, match->name, len);
-	case V4L2_CHIP_MATCH_I2C_ADDR:
-		return c->addr == match->addr;
-	case V4L2_CHIP_MATCH_SUBDEV:
-		return 1;
-	default:
-		return 0;
-	}
-}
-EXPORT_SYMBOL(v4l2_chip_match_i2c_client);
-
-int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip,
-		u32 ident, u32 revision)
-{
-	if (!v4l2_chip_match_i2c_client(c, &chip->match))
-		return 0;
-	if (chip->ident == V4L2_IDENT_NONE) {
-		chip->ident = ident;
-		chip->revision = revision;
-	}
-	else {
-		chip->ident = V4L2_IDENT_AMBIGUOUS;
-		chip->revision = 0;
-	}
-	return 0;
-}
-EXPORT_SYMBOL(v4l2_chip_ident_i2c_client);
-
-/* ----------------------------------------------------------------- */
-
 /* I2C Helper functions */
 
+#if IS_ENABLED(CONFIG_I2C)
 
 void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
 		const struct v4l2_subdev_ops *ops)
@@ -291,6 +237,7 @@
 	sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
 	/* the owner is the same as the i2c_client's driver owner */
 	sd->owner = client->driver->driver.owner;
+	sd->dev = &client->dev;
 	/* i2c_client and v4l2_subdev point to one another */
 	v4l2_set_subdevdata(sd, client);
 	i2c_set_clientdata(client, sd);
@@ -301,8 +248,6 @@
 }
 EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
 
-
-
 /* Load an i2c sub-device. */
 struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
 		struct i2c_adapter *adapter, struct i2c_board_info *info,
@@ -426,6 +371,7 @@
 	sd->flags |= V4L2_SUBDEV_FL_IS_SPI;
 	/* the owner is the same as the spi_device's driver owner */
 	sd->owner = spi->dev.driver->owner;
+	sd->dev = &spi->dev;
 	/* spi_device and v4l2_subdev point to one another */
 	v4l2_set_subdevdata(sd, spi);
 	spi_set_drvdata(spi, sd);
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index f129551..8f7a6a4 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -1074,7 +1074,6 @@
 	case VIDIOC_TRY_DECODER_CMD:
 	case VIDIOC_DBG_S_REGISTER:
 	case VIDIOC_DBG_G_REGISTER:
-	case VIDIOC_DBG_G_CHIP_IDENT:
 	case VIDIOC_S_HW_FREQ_SEEK:
 	case VIDIOC_S_DV_TIMINGS:
 	case VIDIOC_G_DV_TIMINGS:
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 5923c5d..c8859d6 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -495,8 +495,8 @@
 };
 
 /**
- * get_index - assign stream index number based on parent device
- * @vdev: video_device to assign index number to, vdev->parent should be assigned
+ * get_index - assign stream index number based on v4l2_dev
+ * @vdev: video_device to assign index number to, vdev->v4l2_dev should be assigned
  *
  * Note that when this is called the new device has not yet been registered
  * in the video_device array, but it was able to obtain a minor number.
@@ -514,15 +514,11 @@
 	static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
 	int i;
 
-	/* Some drivers do not set the parent. In that case always return 0. */
-	if (vdev->parent == NULL)
-		return 0;
-
 	bitmap_zero(used, VIDEO_NUM_DEVICES);
 
 	for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
 		if (video_device[i] != NULL &&
-		    video_device[i]->parent == vdev->parent) {
+		    video_device[i]->v4l2_dev == vdev->v4l2_dev) {
 			set_bit(video_device[i]->index, used);
 		}
 	}
@@ -596,7 +592,6 @@
 	set_bit(_IOC_NR(VIDIOC_DBG_G_REGISTER), valid_ioctls);
 	set_bit(_IOC_NR(VIDIOC_DBG_S_REGISTER), valid_ioctls);
 #endif
-	SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident);
 	/* yes, really vidioc_subscribe_event */
 	SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event);
 	SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event);
@@ -675,9 +670,8 @@
 		SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf);
 		if (ops->vidioc_s_std)
 			set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls);
-		if (ops->vidioc_g_std || vdev->current_norm)
-			set_bit(_IOC_NR(VIDIOC_G_STD), valid_ioctls);
 		SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std);
+		SET_VALID_IOCTL(ops, VIDIOC_G_STD, vidioc_g_std);
 		if (is_rx) {
 			SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd);
 			SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input);
@@ -705,7 +699,7 @@
 		if (ops->vidioc_cropcap || ops->vidioc_g_selection)
 			set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls);
 		if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER &&
-					(ops->vidioc_g_std || vdev->current_norm)))
+					ops->vidioc_g_std))
 			set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls);
 		SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm);
 		SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings);
@@ -777,6 +771,9 @@
 	/* the release callback MUST be present */
 	if (WARN_ON(!vdev->release))
 		return -EINVAL;
+	/* the v4l2_dev pointer MUST be present */
+	if (WARN_ON(!vdev->v4l2_dev))
+		return -EINVAL;
 
 	/* v4l2_fh support */
 	spin_lock_init(&vdev->fh_lock);
@@ -804,16 +801,14 @@
 
 	vdev->vfl_type = type;
 	vdev->cdev = NULL;
-	if (vdev->v4l2_dev) {
-		if (vdev->v4l2_dev->dev)
-			vdev->parent = vdev->v4l2_dev->dev;
-		if (vdev->ctrl_handler == NULL)
-			vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
-		/* If the prio state pointer is NULL, then use the v4l2_device
-		   prio state. */
-		if (vdev->prio == NULL)
-			vdev->prio = &vdev->v4l2_dev->prio;
-	}
+	if (vdev->dev_parent == NULL)
+		vdev->dev_parent = vdev->v4l2_dev->dev;
+	if (vdev->ctrl_handler == NULL)
+		vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
+	/* If the prio state pointer is NULL, then use the v4l2_device
+	   prio state. */
+	if (vdev->prio == NULL)
+		vdev->prio = &vdev->v4l2_dev->prio;
 
 	/* Part 2: find a free minor, device node number and device index. */
 #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
@@ -898,8 +893,7 @@
 	/* Part 4: register the device with sysfs */
 	vdev->dev.class = &video_class;
 	vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
-	if (vdev->parent)
-		vdev->dev.parent = vdev->parent;
+	vdev->dev.parent = vdev->dev_parent;
 	dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
 	ret = device_register(&vdev->dev);
 	if (ret < 0) {
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
index 8ed5da2..02d1b63 100644
--- a/drivers/media/v4l2-core/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -44,7 +44,8 @@
 	v4l2_dev->dev = dev;
 	if (dev == NULL) {
 		/* If dev == NULL, then name must be filled in by the caller */
-		WARN_ON(!v4l2_dev->name[0]);
+		if (WARN_ON(!v4l2_dev->name[0]))
+			return -EINVAL;
 		return 0;
 	}
 
@@ -105,7 +106,9 @@
 {
 	struct v4l2_subdev *sd, *next;
 
-	if (v4l2_dev == NULL)
+	/* Just return if v4l2_dev is NULL or if it was already
+	 * unregistered before. */
+	if (v4l2_dev == NULL || !v4l2_dev->name[0])
 		return;
 	v4l2_device_disconnect(v4l2_dev);
 
@@ -135,6 +138,8 @@
 		}
 #endif
 	}
+	/* Mark as unregistered, thus preventing duplicate unregistrations */
+	v4l2_dev->name[0] = '\0';
 }
 EXPORT_SYMBOL_GPL(v4l2_device_unregister);
 
@@ -269,8 +274,10 @@
 	sd->v4l2_dev = NULL;
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
-	if (v4l2_dev->mdev)
+	if (v4l2_dev->mdev) {
+		media_entity_remove_links(&sd->entity);
 		media_device_unregister_entity(&sd->entity);
+	}
 #endif
 	video_unregister_device(sd->devnode);
 	module_put(sd->owner);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 7658586..68e6b5e 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -26,7 +26,6 @@
 #include <media/v4l2-fh.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-device.h>
-#include <media/v4l2-chip-ident.h>
 #include <media/videobuf2-core.h>
 
 /* Zero out the end of the struct pointed to by p.  Everything after, but
@@ -619,20 +618,6 @@
 		pr_info("pts=%llu\n", p->stop.pts);
 }
 
-static void v4l_print_dbg_chip_ident(const void *arg, bool write_only)
-{
-	const struct v4l2_dbg_chip_ident *p = arg;
-
-	pr_cont("type=%u, ", p->match.type);
-	if (p->match.type == V4L2_CHIP_MATCH_I2C_DRIVER)
-		pr_cont("name=%.*s, ",
-				(int)sizeof(p->match.name), p->match.name);
-	else
-		pr_cont("addr=%u, ", p->match.addr);
-	pr_cont("chip_ident=%u, revision=0x%x\n",
-			p->ident, p->revision);
-}
-
 static void v4l_print_dbg_chip_info(const void *arg, bool write_only)
 {
 	const struct v4l2_dbg_chip_info *p = arg;
@@ -1359,40 +1344,18 @@
 	return 0;
 }
 
-static int v4l_g_std(const struct v4l2_ioctl_ops *ops,
-				struct file *file, void *fh, void *arg)
-{
-	struct video_device *vfd = video_devdata(file);
-	v4l2_std_id *id = arg;
-
-	/* Calls the specific handler */
-	if (ops->vidioc_g_std)
-		return ops->vidioc_g_std(file, fh, arg);
-	if (vfd->current_norm) {
-		*id = vfd->current_norm;
-		return 0;
-	}
-	return -ENOTTY;
-}
-
 static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
 	struct video_device *vfd = video_devdata(file);
 	v4l2_std_id id = *(v4l2_std_id *)arg, norm;
-	int ret;
 
 	norm = id & vfd->tvnorms;
 	if (vfd->tvnorms && !norm)	/* Check if std is supported */
 		return -EINVAL;
 
 	/* Calls the specific handler */
-	ret = ops->vidioc_s_std(file, fh, norm);
-
-	/* Updates standard information */
-	if (ret >= 0)
-		vfd->current_norm = norm;
-	return ret;
+	return ops->vidioc_s_std(file, fh, norm);
 }
 
 static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
@@ -1402,10 +1365,10 @@
 	v4l2_std_id *p = arg;
 
 	/*
-	 * If nothing detected, it should return all supported
-	 * standard.
-	 * Drivers just need to mask the std argument, in order
-	 * to remove the standards that don't apply from the mask.
+	 * If no signal is detected, then the driver should return
+	 * V4L2_STD_UNKNOWN. Otherwise it should return tvnorms with
+	 * any standards that do not apply removed.
+	 *
 	 * This means that tuners, audio and video decoders can join
 	 * their efforts to improve the standards detection.
 	 */
@@ -1495,7 +1458,6 @@
 static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
-	struct video_device *vfd = video_devdata(file);
 	struct v4l2_streamparm *p = arg;
 	v4l2_std_id std;
 	int ret = check_fmt(file, p->type);
@@ -1504,16 +1466,13 @@
 		return ret;
 	if (ops->vidioc_g_parm)
 		return ops->vidioc_g_parm(file, fh, p);
-	std = vfd->current_norm;
 	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
 	    p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
 		return -EINVAL;
 	p->parm.capture.readbuffers = 2;
-	if (is_valid_ioctl(vfd, VIDIOC_G_STD) && ops->vidioc_g_std)
-		ret = ops->vidioc_g_std(file, fh, &std);
+	ret = ops->vidioc_g_std(file, fh, &std);
 	if (ret == 0)
-		v4l2_video_std_frame_period(std,
-			    &p->parm.capture.timeperframe);
+		v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
 	return ret;
 }
 
@@ -1802,7 +1761,8 @@
 				return v4l2_subdev_call(sd, core, g_register, p);
 		return -EINVAL;
 	}
-	if (ops->vidioc_g_register)
+	if (ops->vidioc_g_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
+	    (ops->vidioc_g_chip_info || p->match.addr == 0))
 		return ops->vidioc_g_register(file, fh, p);
 	return -EINVAL;
 #else
@@ -1829,7 +1789,8 @@
 				return v4l2_subdev_call(sd, core, s_register, p);
 		return -EINVAL;
 	}
-	if (ops->vidioc_s_register)
+	if (ops->vidioc_s_register && p->match.type == V4L2_CHIP_MATCH_BRIDGE &&
+	    (ops->vidioc_g_chip_info || p->match.addr == 0))
 		return ops->vidioc_s_register(file, fh, p);
 	return -EINVAL;
 #else
@@ -1837,18 +1798,6 @@
 #endif
 }
 
-static int v4l_dbg_g_chip_ident(const struct v4l2_ioctl_ops *ops,
-				struct file *file, void *fh, void *arg)
-{
-	struct v4l2_dbg_chip_ident *p = arg;
-
-	p->ident = V4L2_IDENT_NONE;
-	p->revision = 0;
-	if (p->match.type == V4L2_CHIP_MATCH_SUBDEV)
-		return -EINVAL;
-	return ops->vidioc_g_chip_ident(file, fh, p);
-}
-
 static int v4l_dbg_g_chip_info(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
@@ -1864,12 +1813,7 @@
 			p->flags |= V4L2_CHIP_FL_WRITABLE;
 		if (ops->vidioc_g_register)
 			p->flags |= V4L2_CHIP_FL_READABLE;
-		if (vfd->v4l2_dev)
-			strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
-		else if (vfd->parent)
-			strlcpy(p->name, vfd->parent->driver->name, sizeof(p->name));
-		else
-			strlcpy(p->name, "bridge", sizeof(p->name));
+		strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name));
 		if (ops->vidioc_g_chip_info)
 			return ops->vidioc_g_chip_info(file, fh, arg);
 		if (p->match.addr)
@@ -2048,7 +1992,7 @@
 	IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO | INFO_FL_QUEUE),
 	IOCTL_INFO_FNC(VIDIOC_G_PARM, v4l_g_parm, v4l_print_streamparm, INFO_FL_CLEAR(v4l2_streamparm, type)),
 	IOCTL_INFO_FNC(VIDIOC_S_PARM, v4l_s_parm, v4l_print_streamparm, INFO_FL_PRIO),
-	IOCTL_INFO_FNC(VIDIOC_G_STD, v4l_g_std, v4l_print_std, 0),
+	IOCTL_INFO_STD(VIDIOC_G_STD, vidioc_g_std, v4l_print_std, 0),
 	IOCTL_INFO_FNC(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
 	IOCTL_INFO_FNC(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
 	IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
@@ -2098,7 +2042,6 @@
 	IOCTL_INFO_STD(VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd, v4l_print_decoder_cmd, 0),
 	IOCTL_INFO_FNC(VIDIOC_DBG_S_REGISTER, v4l_dbg_s_register, v4l_print_dbg_register, 0),
 	IOCTL_INFO_FNC(VIDIOC_DBG_G_REGISTER, v4l_dbg_g_register, v4l_print_dbg_register, 0),
-	IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_IDENT, v4l_dbg_g_chip_ident, v4l_print_dbg_chip_ident, 0),
 	IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
 	IOCTL_INFO_STD(VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings, v4l_print_dv_timings, INFO_FL_PRIO),
 	IOCTL_INFO_STD(VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings, v4l_print_dv_timings, 0),
diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c
index 67f572c..65411adc 100644
--- a/drivers/media/v4l2-core/videobuf-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf-dma-contig.c
@@ -66,11 +66,14 @@
 static void videobuf_vm_open(struct vm_area_struct *vma)
 {
 	struct videobuf_mapping *map = vma->vm_private_data;
+	struct videobuf_queue *q = map->q;
 
-	dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
+	dev_dbg(q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
 		map, map->count, vma->vm_start, vma->vm_end);
 
+	videobuf_queue_lock(q);
 	map->count++;
+	videobuf_queue_unlock(q);
 }
 
 static void videobuf_vm_close(struct vm_area_struct *vma)
@@ -82,12 +85,11 @@
 	dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
 		map, map->count, vma->vm_start, vma->vm_end);
 
-	map->count--;
-	if (0 == map->count) {
+	videobuf_queue_lock(q);
+	if (!--map->count) {
 		struct videobuf_dma_contig_memory *mem;
 
 		dev_dbg(q->dev, "munmap %p q=%p\n", map, q);
-		videobuf_queue_lock(q);
 
 		/* We need first to cancel streams, before unmapping */
 		if (q->streaming)
@@ -126,8 +128,8 @@
 
 		kfree(map);
 
-		videobuf_queue_unlock(q);
 	}
+	videobuf_queue_unlock(q);
 }
 
 static const struct vm_operations_struct videobuf_vm_ops = {
@@ -303,14 +305,9 @@
 		goto error;
 
 	/* Try to remap memory */
-
 	size = vma->vm_end - vma->vm_start;
-	size = (size < mem->size) ? size : mem->size;
-
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-	retval = remap_pfn_range(vma, vma->vm_start,
-				 mem->dma_handle >> PAGE_SHIFT,
-				 size, vma->vm_page_prot);
+	retval = vm_iomap_memory(vma, vma->vm_start, size);
 	if (retval) {
 		dev_err(q->dev, "mmap: remap failed with error %d. ",
 			retval);
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c
index 828e7c1..9db674c 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -338,11 +338,14 @@
 static void videobuf_vm_open(struct vm_area_struct *vma)
 {
 	struct videobuf_mapping *map = vma->vm_private_data;
+	struct videobuf_queue *q = map->q;
 
 	dprintk(2, "vm_open %p [count=%d,vma=%08lx-%08lx]\n", map,
 		map->count, vma->vm_start, vma->vm_end);
 
+	videobuf_queue_lock(q);
 	map->count++;
+	videobuf_queue_unlock(q);
 }
 
 static void videobuf_vm_close(struct vm_area_struct *vma)
@@ -355,10 +358,9 @@
 	dprintk(2, "vm_close %p [count=%d,vma=%08lx-%08lx]\n", map,
 		map->count, vma->vm_start, vma->vm_end);
 
-	map->count--;
-	if (0 == map->count) {
+	videobuf_queue_lock(q);
+	if (!--map->count) {
 		dprintk(1, "munmap %p q=%p\n", map, q);
-		videobuf_queue_lock(q);
 		for (i = 0; i < VIDEO_MAX_FRAME; i++) {
 			if (NULL == q->bufs[i])
 				continue;
@@ -374,9 +376,9 @@
 			q->bufs[i]->baddr = 0;
 			q->ops->buf_release(q, q->bufs[i]);
 		}
-		videobuf_queue_unlock(q);
 		kfree(map);
 	}
+	videobuf_queue_unlock(q);
 	return;
 }
 
diff --git a/drivers/media/v4l2-core/videobuf-vmalloc.c b/drivers/media/v4l2-core/videobuf-vmalloc.c
index 2ff7fcc..1365c65 100644
--- a/drivers/media/v4l2-core/videobuf-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf-vmalloc.c
@@ -54,11 +54,14 @@
 static void videobuf_vm_open(struct vm_area_struct *vma)
 {
 	struct videobuf_mapping *map = vma->vm_private_data;
+	struct videobuf_queue *q = map->q;
 
 	dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map,
 		map->count, vma->vm_start, vma->vm_end);
 
+	videobuf_queue_lock(q);
 	map->count++;
+	videobuf_queue_unlock(q);
 }
 
 static void videobuf_vm_close(struct vm_area_struct *vma)
@@ -70,12 +73,11 @@
 	dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map,
 		map->count, vma->vm_start, vma->vm_end);
 
-	map->count--;
-	if (0 == map->count) {
+	videobuf_queue_lock(q);
+	if (!--map->count) {
 		struct videobuf_vmalloc_memory *mem;
 
 		dprintk(1, "munmap %p q=%p\n", map, q);
-		videobuf_queue_lock(q);
 
 		/* We need first to cancel streams, before unmapping */
 		if (q->streaming)
@@ -114,8 +116,8 @@
 
 		kfree(map);
 
-		videobuf_queue_unlock(q);
 	}
+	videobuf_queue_unlock(q);
 
 	return;
 }
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index e3bdc3b..9fc4bab 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -2194,8 +2194,10 @@
 	 */
 	for (i = 0; i < q->num_buffers; i++) {
 		fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
-		if (fileio->bufs[i].vaddr == NULL)
+		if (fileio->bufs[i].vaddr == NULL) {
+			ret = -EINVAL;
 			goto err_reqbufs;
+		}
 		fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
 	}
 
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index 05673ed..766a071 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -1751,10 +1751,10 @@
  */
 void vpfe_ipipe_unregister_entities(struct vpfe_ipipe_device *vpfe_ipipe)
 {
-	/* cleanup entity */
-	media_entity_cleanup(&vpfe_ipipe->subdev.entity);
 	/* unregister subdev */
 	v4l2_device_unregister_subdev(&vpfe_ipipe->subdev);
+	/* cleanup entity */
+	media_entity_cleanup(&vpfe_ipipe->subdev.entity);
 }
 
 /*
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index b2f4ef8..59540cd 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -947,10 +947,10 @@
 	/* unregister video device */
 	vpfe_video_unregister(&ipipeif->video_in);
 
-	/* cleanup entity */
-	media_entity_cleanup(&ipipeif->subdev.entity);
 	/* unregister subdev */
 	v4l2_device_unregister_subdev(&ipipeif->subdev);
+	/* cleanup entity */
+	media_entity_cleanup(&ipipeif->subdev.entity);
 }
 
 int
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index 5829360f..ff48fce 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -1750,10 +1750,10 @@
 void vpfe_isif_unregister_entities(struct vpfe_isif_device *isif)
 {
 	vpfe_video_unregister(&isif->video_out);
-	/* cleanup entity */
-	media_entity_cleanup(&isif->subdev.entity);
 	/* unregister subdev */
 	v4l2_device_unregister_subdev(&isif->subdev);
+	/* cleanup entity */
+	media_entity_cleanup(&isif->subdev.entity);
 }
 
 static void isif_restore_defaults(struct vpfe_isif_device *isif)
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 126f84c..8e13bd4 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1777,14 +1777,14 @@
 	vpfe_video_unregister(&vpfe_rsz->resizer_a.video_out);
 	vpfe_video_unregister(&vpfe_rsz->resizer_b.video_out);
 
-	/* cleanup entity */
-	media_entity_cleanup(&vpfe_rsz->crop_resizer.subdev.entity);
-	media_entity_cleanup(&vpfe_rsz->resizer_a.subdev.entity);
-	media_entity_cleanup(&vpfe_rsz->resizer_b.subdev.entity);
 	/* unregister subdev */
 	v4l2_device_unregister_subdev(&vpfe_rsz->crop_resizer.subdev);
 	v4l2_device_unregister_subdev(&vpfe_rsz->resizer_a.subdev);
 	v4l2_device_unregister_subdev(&vpfe_rsz->resizer_b.subdev);
+	/* cleanup entity */
+	media_entity_cleanup(&vpfe_rsz->crop_resizer.subdev.entity);
+	media_entity_cleanup(&vpfe_rsz->resizer_a.subdev.entity);
+	media_entity_cleanup(&vpfe_rsz->resizer_b.subdev.entity);
 }
 
 /*
@@ -1865,12 +1865,12 @@
 	vpfe_video_unregister(&resizer->resizer_b.video_out);
 out_video_out2_register:
 	vpfe_video_unregister(&resizer->resizer_a.video_out);
-	media_entity_cleanup(&resizer->crop_resizer.subdev.entity);
-	media_entity_cleanup(&resizer->resizer_a.subdev.entity);
-	media_entity_cleanup(&resizer->resizer_b.subdev.entity);
 	v4l2_device_unregister_subdev(&resizer->crop_resizer.subdev);
 	v4l2_device_unregister_subdev(&resizer->resizer_a.subdev);
 	v4l2_device_unregister_subdev(&resizer->resizer_b.subdev);
+	media_entity_cleanup(&resizer->crop_resizer.subdev.entity);
+	media_entity_cleanup(&resizer->resizer_a.subdev.entity);
+	media_entity_cleanup(&resizer->resizer_b.subdev.entity);
 	return ret;
 }
 
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index ba913f1..24d98a6 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -39,7 +39,7 @@
 	struct vpfe_device *vpfe_dev = video->vpfe_dev;
 	struct media_pad *remote;
 
-	remote = media_entity_remote_source(&vpfe_dev->vpfe_isif.pads[0]);
+	remote = media_entity_remote_pad(&vpfe_dev->vpfe_isif.pads[0]);
 	if (remote == NULL) {
 		pr_err("Invalid media connection to isif/ccdc\n");
 		return NULL;
@@ -56,7 +56,7 @@
 	struct media_pad *remote;
 	int i;
 
-	remote = media_entity_remote_source(&vpfe_dev->vpfe_isif.pads[0]);
+	remote = media_entity_remote_pad(&vpfe_dev->vpfe_isif.pads[0]);
 	if (remote == NULL) {
 		pr_err("Invalid media connection to isif/ccdc\n");
 		return -EINVAL;
@@ -89,7 +89,7 @@
 static struct v4l2_subdev *
 vpfe_video_remote_subdev(struct vpfe_video_device *video, u32 *pad)
 {
-	struct media_pad *remote = media_entity_remote_source(&video->pad);
+	struct media_pad *remote = media_entity_remote_pad(&video->pad);
 
 	if (remote == NULL || remote->entity->type != MEDIA_ENT_T_V4L2_SUBDEV)
 		return NULL;
@@ -114,7 +114,7 @@
 		return -EINVAL;
 
 	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-	remote = media_entity_remote_source(&video->pad);
+	remote = media_entity_remote_pad(&video->pad);
 	fmt.pad = remote->index;
 
 	ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
@@ -245,7 +245,7 @@
 			return -EPIPE;
 
 		/* Retrieve the source format */
-		pad = media_entity_remote_source(pad);
+		pad = media_entity_remote_pad(pad);
 		if (pad == NULL ||
 			pad->entity->type != MEDIA_ENT_T_V4L2_SUBDEV)
 			break;
@@ -667,7 +667,7 @@
 		return -EINVAL;
 	}
 	/* get the remote pad */
-	remote = media_entity_remote_source(&video->pad);
+	remote = media_entity_remote_pad(&video->pad);
 	if (remote == NULL) {
 		v4l2_err(&vpfe_dev->v4l2_dev,
 			 "invalid remote pad for video node\n");
@@ -1614,7 +1614,7 @@
 void vpfe_video_unregister(struct vpfe_video_device *video)
 {
 	if (video_is_registered(&video->video_dev)) {
-		media_entity_cleanup(&video->video_dev.entity);
 		video_unregister_device(&video->video_dev);
+		media_entity_cleanup(&video->video_dev.entity);
 	}
 }
diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c
index c32e0ac..90d6ac4 100644
--- a/drivers/staging/media/dt3155v4l/dt3155v4l.c
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c
@@ -829,7 +829,6 @@
 	.minor = -1,
 	.release = video_device_release,
 	.tvnorms = DT3155_CURRENT_NORM,
-	.current_norm = DT3155_CURRENT_NORM,
 };
 
 /* same as in drivers/base/dma-coherent.c */
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 50066e0..46ed832 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -1124,7 +1124,7 @@
 	case GO7007_BOARDID_LIFEVIEW_LR192:
 		printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra "
 				"is not supported.  Sorry!\n");
-		return 0;
+		return -ENODEV;
 		name = "Lifeview TV Walker Ultra";
 		board = &board_lifeview_lr192;
 		break;
@@ -1140,7 +1140,7 @@
 	default:
 		printk(KERN_ERR "go7007-usb: unknown board ID %d!\n",
 				(unsigned int)id->driver_info);
-		return 0;
+		return -ENODEV;
 	}
 
 	go = go7007_alloc(&board->main_info, &intf->dev);
diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
index 0a2c45d..4afa7da 100644
--- a/drivers/staging/media/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
@@ -911,8 +911,8 @@
 	if (retval) {
 		dev_err(dev, "%s: usb_submit_urb failed for intf0 (%d)\n",
 			__func__, retval);
-		mutex_unlock(&context->ctx_lock);
-		goto exit;
+		alloc_status = 8;
+		goto unlock;
 	}
 
 	usb_set_intfdata(interface, context);
@@ -937,6 +937,8 @@
 alloc_status_switch:
 
 	switch (alloc_status) {
+	case 8:
+		lirc_unregister_driver(driver->minor);
 	case 7:
 		usb_free_urb(tx_urb);
 	case 6:
@@ -959,7 +961,6 @@
 		retval = 0;
 	}
 
-exit:
 	mutex_unlock(&driver_lock);
 
 	return retval;
diff --git a/drivers/staging/media/solo6x10/solo6x10-tw28.c b/drivers/staging/media/solo6x10/solo6x10-tw28.c
index ad00e2b..af65ea6 100644
--- a/drivers/staging/media/solo6x10/solo6x10-tw28.c
+++ b/drivers/staging/media/solo6x10/solo6x10-tw28.c
@@ -513,62 +513,82 @@
 #define FIRST_ACTIVE_LINE	0x0008
 #define LAST_ACTIVE_LINE	0x0102
 
-static void saa7128_setup(struct solo_dev *solo_dev)
+static void saa712x_write_regs(struct solo_dev *dev, const uint8_t *vals,
+		int start, int n)
 {
-	int i;
-	unsigned char regs[128] = {
-		0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+	for (;start < n; start++, vals++) {
+		/* Skip read-only registers */
+		switch (start) {
+		/* case 0x00 ... 0x25: */
+		case 0x2e ... 0x37:
+		case 0x60:
+		case 0x7d:
+			continue;
+		}
+		solo_i2c_writebyte(dev, SOLO_I2C_SAA, 0x46, start, *vals);
+	}
+}
+
+#define SAA712x_reg7c (0x80 | ((LAST_ACTIVE_LINE & 0x100) >> 2) \
+		| ((FIRST_ACTIVE_LINE & 0x100) >> 4))
+
+static void saa712x_setup(struct solo_dev *dev)
+{
+	const int reg_start = 0x26;
+	const uint8_t saa7128_regs_ntsc[] = {
+	/* :0x26 */
+		0x0d, 0x00,
+	/* :0x28 */
+		0x59, 0x1d, 0x75, 0x3f, 0x06, 0x3f,
+	/* :0x2e XXX: read-only */
+		0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x1C, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
-		0x59, 0x1d, 0x75, 0x3f, 0x06, 0x3f, 0x00, 0x00,
-		0x1c, 0x33, 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00,
+	/* :0x38 */
 		0x1a, 0x1a, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* :0x40 */
 		0x00, 0x00, 0x00, 0x68, 0x10, 0x97, 0x4c, 0x18,
 		0x9b, 0x93, 0x9f, 0xff, 0x7c, 0x34, 0x3f, 0x3f,
+	/* :0x50 */
 		0x3f, 0x83, 0x83, 0x80, 0x0d, 0x0f, 0xc3, 0x06,
 		0x02, 0x80, 0x71, 0x77, 0xa7, 0x67, 0x66, 0x2e,
+	/* :0x60 */
 		0x7b, 0x11, 0x4f, 0x1f, 0x7c, 0xf0, 0x21, 0x77,
-		0x41, 0x88, 0x41, 0x12, 0xed, 0x10, 0x10, 0x00,
+		0x41, 0x88, 0x41, 0x52, 0xed, 0x10, 0x10, 0x00,
+	/* :0x70 */
 		0x41, 0xc3, 0x00, 0x3e, 0xb8, 0x02, 0x00, 0x00,
-		0x00, 0x00, 0x08, 0xff, 0x80, 0x00, 0xff, 0xff,
+		0x00, 0x00, FIRST_ACTIVE_LINE, LAST_ACTIVE_LINE & 0xff,
+		SAA712x_reg7c, 0x00, 0xff, 0xff,
+	}, saa7128_regs_pal[] = {
+	/* :0x26 */
+		0x0d, 0x00,
+	/* :0x28 */
+		0xe1, 0x1d, 0x75, 0x3f, 0x06, 0x3f,
+	/* :0x2e XXX: read-only */
+		0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* :0x38 */
+		0x1a, 0x1a, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* :0x40 */
+		0x00, 0x00, 0x00, 0x68, 0x10, 0x97, 0x4c, 0x18,
+		0x9b, 0x93, 0x9f, 0xff, 0x7c, 0x34, 0x3f, 0x3f,
+	/* :0x50 */
+		0x3f, 0x83, 0x83, 0x80, 0x0d, 0x0f, 0xc3, 0x06,
+		0x02, 0x80, 0x0f, 0x77, 0xa7, 0x67, 0x66, 0x2e,
+	/* :0x60 */
+		0x7b, 0x02, 0x35, 0xcb, 0x8a, 0x09, 0x2a, 0x77,
+		0x41, 0x88, 0x41, 0x52, 0xf1, 0x10, 0x20, 0x00,
+	/* :0x70 */
+		0x41, 0xc3, 0x00, 0x3e, 0xb8, 0x02, 0x00, 0x00,
+		0x00, 0x00, 0x12, 0x30,
+		SAA712x_reg7c | 0x40, 0x00, 0xff, 0xff,
 	};
 
-	regs[0x7A] = FIRST_ACTIVE_LINE & 0xff;
-	regs[0x7B] = LAST_ACTIVE_LINE & 0xff;
-	regs[0x7C] = ((1 << 7) |
-			(((LAST_ACTIVE_LINE >> 8) & 1) << 6) |
-			(((FIRST_ACTIVE_LINE >> 8) & 1) << 4));
-
-	/* PAL: XXX: We could do a second set of regs to avoid this */
-	if (solo_dev->video_type != SOLO_VO_FMT_TYPE_NTSC) {
-		regs[0x28] = 0xE1;
-
-		regs[0x5A] = 0x0F;
-		regs[0x61] = 0x02;
-		regs[0x62] = 0x35;
-		regs[0x63] = 0xCB;
-		regs[0x64] = 0x8A;
-		regs[0x65] = 0x09;
-		regs[0x66] = 0x2A;
-
-		regs[0x6C] = 0xf1;
-		regs[0x6E] = 0x20;
-
-		regs[0x7A] = 0x06 + 12;
-		regs[0x7b] = 0x24 + 12;
-		regs[0x7c] |= 1 << 6;
-	}
-
-	/* First 0x25 bytes are read-only? */
-	for (i = 0x26; i < 128; i++) {
-		if (i == 0x60 || i == 0x7D)
-			continue;
-		solo_i2c_writebyte(solo_dev, SOLO_I2C_SAA, 0x46, i, regs[i]);
-	}
-
-	return;
+	if (dev->video_type == SOLO_VO_FMT_TYPE_PAL)
+		saa712x_write_regs(dev, saa7128_regs_pal, reg_start,
+				sizeof(saa7128_regs_pal));
+	else
+		saa712x_write_regs(dev, saa7128_regs_ntsc, reg_start,
+				sizeof(saa7128_regs_ntsc));
 }
 
 int solo_tw28_init(struct solo_dev *solo_dev)
@@ -609,7 +629,7 @@
 		return -EINVAL;
 	}
 
-	saa7128_setup(solo_dev);
+	saa712x_setup(solo_dev);
 
 	for (i = 0; i < solo_dev->tw28_cnt; i++) {
 		if ((solo_dev->tw2865 & (1 << i)))
diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
index 98e2902..a4c5896 100644
--- a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c
@@ -996,12 +996,11 @@
 		       struct v4l2_streamparm *sp)
 {
 	struct solo_enc_dev *solo_enc = video_drvdata(file);
-	struct solo_dev *solo_dev = solo_enc->solo_dev;
 	struct v4l2_captureparm *cp = &sp->parm.capture;
 
 	cp->capability = V4L2_CAP_TIMEPERFRAME;
 	cp->timeperframe.numerator = solo_enc->interval;
-	cp->timeperframe.denominator = solo_dev->fps;
+	cp->timeperframe.denominator = solo_enc->solo_dev->fps;
 	cp->capturemode = 0;
 	/* XXX: Shouldn't we be able to get/set this from videobuf? */
 	cp->readbuffers = 2;
@@ -1009,36 +1008,29 @@
 	return 0;
 }
 
+static inline int calc_interval(u8 fps, u32 n, u32 d)
+{
+	if (!n || !d)
+		return 1;
+	if (d == fps)
+		return n;
+	n *= fps;
+	return min(15U, n / d + (n % d >= (fps >> 1)));
+}
+
 static int solo_s_parm(struct file *file, void *priv,
 		       struct v4l2_streamparm *sp)
 {
 	struct solo_enc_dev *solo_enc = video_drvdata(file);
-	struct solo_dev *solo_dev = solo_enc->solo_dev;
-	struct v4l2_captureparm *cp = &sp->parm.capture;
+	struct v4l2_fract *t = &sp->parm.capture.timeperframe;
+	u8 fps = solo_enc->solo_dev->fps;
 
 	if (vb2_is_streaming(&solo_enc->vidq))
 		return -EBUSY;
 
-	if ((cp->timeperframe.numerator == 0) ||
-	    (cp->timeperframe.denominator == 0)) {
-		/* reset framerate */
-		cp->timeperframe.numerator = 1;
-		cp->timeperframe.denominator = solo_dev->fps;
-	}
-
-	if (cp->timeperframe.denominator != solo_dev->fps)
-		cp->timeperframe.denominator = solo_dev->fps;
-
-	if (cp->timeperframe.numerator > 15)
-		cp->timeperframe.numerator = 15;
-
-	solo_enc->interval = cp->timeperframe.numerator;
-
-	cp->capability = V4L2_CAP_TIMEPERFRAME;
-	cp->readbuffers = 2;
-
+	solo_enc->interval = calc_interval(fps, t->numerator, t->denominator);
 	solo_update_mode(solo_enc);
-	return 0;
+	return solo_g_parm(file, priv, sp);
 }
 
 static long solo_enc_default(struct file *file, void *fh,
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index 5f91c7a..e2a1f50 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -406,7 +406,7 @@
 	if (video == NULL)
 		return -ENOMEM;
 
-	video->parent = &cdev->gadget->dev;
+	video->v4l2_dev = &uvc->v4l2_dev;
 	video->fops = &uvc_v4l2_fops;
 	video->release = video_device_release;
 	strlcpy(video->name, cdev->gadget->name, sizeof(video->name));
@@ -563,6 +563,7 @@
 	INFO(cdev, "uvc_function_unbind\n");
 
 	video_unregister_device(uvc->vdev);
+	v4l2_device_unregister(&uvc->v4l2_dev);
 	uvc->control_ep->driver_data = NULL;
 	uvc->video.ep->driver_data = NULL;
 
@@ -690,6 +691,11 @@
 	if ((ret = usb_function_deactivate(f)) < 0)
 		goto error;
 
+	if (v4l2_device_register(&cdev->gadget->dev, &uvc->v4l2_dev)) {
+		printk(KERN_INFO "v4l2_device_register failed\n");
+		goto error;
+	}
+
 	/* Initialise video. */
 	ret = uvc_video_init(&uvc->video);
 	if (ret < 0)
@@ -705,6 +711,7 @@
 	return 0;
 
 error:
+	v4l2_device_unregister(&uvc->v4l2_dev);
 	if (uvc->vdev)
 		video_device_release(uvc->vdev);
 
diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h
index 817e9e1..7a9111d 100644
--- a/drivers/usb/gadget/uvc.h
+++ b/drivers/usb/gadget/uvc.h
@@ -57,6 +57,7 @@
 #include <linux/videodev2.h>
 #include <linux/version.h>
 #include <media/v4l2-fh.h>
+#include <media/v4l2-device.h>
 
 #include "uvc_queue.h"
 
@@ -145,6 +146,7 @@
 struct uvc_device
 {
 	struct video_device *vdev;
+	struct v4l2_device v4l2_dev;
 	enum uvc_state state;
 	struct usb_function func;
 	struct uvc_video video;
diff --git a/include/media/davinci/vpbe_osd.h b/include/media/davinci/vpbe_osd.h
index 42628fc..de59364 100644
--- a/include/media/davinci/vpbe_osd.h
+++ b/include/media/davinci/vpbe_osd.h
@@ -82,9 +82,9 @@
 	PIXFMT_4BPP,
 	PIXFMT_8BPP,
 	PIXFMT_RGB565,
-	PIXFMT_YCbCrI,
+	PIXFMT_YCBCRI,
 	PIXFMT_RGB888,
-	PIXFMT_YCrCbI,
+	PIXFMT_YCRCBI,
 	PIXFMT_NV12,
 	PIXFMT_OSD_ATTR,
 };
diff --git a/include/media/media-device.h b/include/media/media-device.h
index eaade98..12155a9 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -45,6 +45,7 @@
  * @entities:	List of registered entities
  * @lock:	Entities list lock
  * @graph_mutex: Entities graph operation lock
+ * @link_notify: Link state change notification callback
  *
  * This structure represents an abstract high-level media device. It allows easy
  * access to entities and provides basic media device-level support. The
@@ -75,10 +76,14 @@
 	/* Serializes graph operations. */
 	struct mutex graph_mutex;
 
-	int (*link_notify)(struct media_pad *source,
-			   struct media_pad *sink, u32 flags);
+	int (*link_notify)(struct media_link *link, u32 flags,
+			   unsigned int notification);
 };
 
+/* Supported link_notify @notification values. */
+#define MEDIA_DEV_NOTIFY_PRE_LINK_CH	0
+#define MEDIA_DEV_NOTIFY_POST_LINK_CH	1
+
 /* media_devnode to media_device */
 #define to_media_device(node) container_of(node, struct media_device, devnode)
 
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 0c16f51..06bacf9 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -128,11 +128,14 @@
 
 int media_entity_create_link(struct media_entity *source, u16 source_pad,
 		struct media_entity *sink, u16 sink_pad, u32 flags);
+void __media_entity_remove_links(struct media_entity *entity);
+void media_entity_remove_links(struct media_entity *entity);
+
 int __media_entity_setup_link(struct media_link *link, u32 flags);
 int media_entity_setup_link(struct media_link *link, u32 flags);
 struct media_link *media_entity_find_link(struct media_pad *source,
 		struct media_pad *sink);
-struct media_pad *media_entity_remote_source(struct media_pad *pad);
+struct media_pad *media_entity_remote_pad(struct media_pad *pad);
 
 struct media_entity *media_entity_get(struct media_entity *entity);
 void media_entity_put(struct media_entity *entity);
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 5d5d3a3..6628f5d 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -111,6 +111,7 @@
 #define RC_MAP_BUDGET_CI_OLD             "rc-budget-ci-old"
 #define RC_MAP_CINERGY_1400              "rc-cinergy-1400"
 #define RC_MAP_CINERGY                   "rc-cinergy"
+#define RC_MAP_DELOCK_61959              "rc-delock-61959"
 #define RC_MAP_DIB0700_NEC_TABLE         "rc-dib0700-nec"
 #define RC_MAP_DIB0700_RC5_TABLE         "rc-dib0700-rc5"
 #define RC_MAP_DIGITALNOW_TINYTWIN       "rc-digitalnow-tinytwin"
diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h
index f509690..b975c28 100644
--- a/include/media/s5p_fimc.h
+++ b/include/media/s5p_fimc.h
@@ -13,6 +13,7 @@
 #define S5P_FIMC_H_
 
 #include <media/media-entity.h>
+#include <media/v4l2-dev.h>
 #include <media/v4l2-mediabus.h>
 
 /*
@@ -115,6 +116,7 @@
  * @color: the driver's private color format id
  * @memplanes: number of physically non-contiguous data planes
  * @colplanes: number of physically contiguous data planes
+ * @colorspace: v4l2 colorspace (V4L2_COLORSPACE_*)
  * @depth: per plane driver's private 'number of bits per pixel'
  * @mdataplanes: bitmask indicating meta data plane(s), (1 << plane_no)
  * @flags: flags indicating which operation mode format applies to
@@ -126,6 +128,7 @@
 	u32	color;
 	u16	memplanes;
 	u16	colplanes;
+	u8	colorspace;
 	u8	depth[FIMC_MAX_PLANES];
 	u16	mdataplanes;
 	u16	flags;
@@ -140,37 +143,40 @@
 #define FMT_FLAGS_YUV		(1 << 7)
 };
 
-enum fimc_subdev_index {
-	IDX_SENSOR,
-	IDX_CSIS,
-	IDX_FLITE,
-	IDX_IS_ISP,
-	IDX_FIMC,
-	IDX_MAX,
-};
-
-struct media_pipeline;
-struct v4l2_subdev;
-
-struct fimc_pipeline {
-	struct v4l2_subdev *subdevs[IDX_MAX];
-	struct media_pipeline *m_pipeline;
-};
+struct exynos_media_pipeline;
 
 /*
- * Media pipeline operations to be called from within the fimc(-lite)
- * video node when it is the last entity of the pipeline. Implemented
- * by corresponding media device driver.
+ * Media pipeline operations to be called from within a video node,  i.e. the
+ * last entity within the pipeline. Implemented by related media device driver.
  */
-struct fimc_pipeline_ops {
-	int (*open)(struct fimc_pipeline *p, struct media_entity *me,
-			  bool resume);
-	int (*close)(struct fimc_pipeline *p);
-	int (*set_stream)(struct fimc_pipeline *p, bool state);
+struct exynos_media_pipeline_ops {
+	int (*prepare)(struct exynos_media_pipeline *p,
+						struct media_entity *me);
+	int (*unprepare)(struct exynos_media_pipeline *p);
+	int (*open)(struct exynos_media_pipeline *p, struct media_entity *me,
+							bool resume);
+	int (*close)(struct exynos_media_pipeline *p);
+	int (*set_stream)(struct exynos_media_pipeline *p, bool state);
 };
 
-#define fimc_pipeline_call(f, op, p, args...)				\
-	(!(f) ? -ENODEV : (((f)->pipeline_ops && (f)->pipeline_ops->op) ? \
-			    (f)->pipeline_ops->op((p), ##args) : -ENOIOCTLCMD))
+struct exynos_video_entity {
+	struct video_device vdev;
+	struct exynos_media_pipeline *pipe;
+};
+
+struct exynos_media_pipeline {
+	struct media_pipeline mp;
+	const struct exynos_media_pipeline_ops *ops;
+};
+
+static inline struct exynos_video_entity *vdev_to_exynos_video_entity(
+					struct video_device *vdev)
+{
+	return container_of(vdev, struct exynos_video_entity, vdev);
+}
+
+#define fimc_pipeline_call(ent, op, args...)				  \
+	(!(ent) ? -ENOENT : (((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
+	(ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD))	  \
 
 #endif /* S5P_FIMC_H_ */
diff --git a/include/media/sh_mobile_ceu.h b/include/media/sh_mobile_ceu.h
index 6fdb6ad..7f57056 100644
--- a/include/media/sh_mobile_ceu.h
+++ b/include/media/sh_mobile_ceu.h
@@ -22,6 +22,8 @@
 	int max_width;
 	int max_height;
 	struct sh_mobile_ceu_companion *csi2;
+	struct v4l2_async_subdev **asd;	/* Flat array, arranged in groups */
+	unsigned int *asd_sizes;	/* 0-terminated array pf asd group sizes */
 };
 
 #endif /* __ASM_SH_MOBILE_CEU_H__ */
diff --git a/include/media/sh_mobile_csi2.h b/include/media/sh_mobile_csi2.h
index c586c4f..14030db 100644
--- a/include/media/sh_mobile_csi2.h
+++ b/include/media/sh_mobile_csi2.h
@@ -33,6 +33,7 @@
 	unsigned char lanes;		/* bitmask[3:0] */
 	unsigned char channel;		/* 0..3 */
 	struct platform_device *pdev;	/* client platform device */
+	const char *name;		/* async matching: client name */
 };
 
 struct v4l2_device;
@@ -42,7 +43,6 @@
 	unsigned int flags;
 	struct sh_csi2_client_config *clients;
 	int num_clients;
-	struct v4l2_device *v4l2_dev;
 };
 
 #endif
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index ff77d08..34d2414 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -19,11 +19,13 @@
 #include <linux/videodev2.h>
 #include <media/videobuf-core.h>
 #include <media/videobuf2-core.h>
+#include <media/v4l2-async.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 
 struct file;
 struct soc_camera_desc;
+struct soc_camera_async_client;
 
 struct soc_camera_device {
 	struct list_head list;		/* list of all registered devices */
@@ -49,6 +51,10 @@
 	/* soc_camera.c private count. Only accessed with .host_lock held */
 	int use_count;
 	struct file *streamer;		/* stream owner */
+	struct v4l2_clk *clk;
+	/* Asynchronous subdevice management */
+	struct soc_camera_async_client *sasc;
+	/* video buffer queue */
 	union {
 		struct videobuf_queue vb_vidq;
 		struct vb2_queue vb2_vidq;
@@ -58,21 +64,38 @@
 /* Host supports programmable stride */
 #define SOCAM_HOST_CAP_STRIDE		(1 << 0)
 
+enum soc_camera_subdev_role {
+	SOCAM_SUBDEV_DATA_SOURCE = 1,
+	SOCAM_SUBDEV_DATA_SINK,
+	SOCAM_SUBDEV_DATA_PROCESSOR,
+};
+
+struct soc_camera_async_subdev {
+	struct v4l2_async_subdev asd;
+	enum soc_camera_subdev_role role;
+};
+
 struct soc_camera_host {
 	struct v4l2_device v4l2_dev;
 	struct list_head list;
-	struct mutex host_lock;		/* Protect pipeline modifications */
+	struct mutex host_lock;		/* Main synchronisation lock */
+	struct mutex clk_lock;		/* Protect pipeline modifications */
 	unsigned char nr;		/* Host number */
 	u32 capabilities;
+	struct soc_camera_device *icd;	/* Currently attached client */
 	void *priv;
 	const char *drv_name;
 	struct soc_camera_host_ops *ops;
+	struct v4l2_async_subdev **asd;	/* Flat array, arranged in groups */
+	unsigned int *asd_sizes;	/* 0-terminated array of asd group sizes */
 };
 
 struct soc_camera_host_ops {
 	struct module *owner;
 	int (*add)(struct soc_camera_device *);
 	void (*remove)(struct soc_camera_device *);
+	int (*clock_start)(struct soc_camera_host *);
+	void (*clock_stop)(struct soc_camera_host *);
 	/*
 	 * .get_formats() is called for each client device format, but
 	 * .put_formats() is only called once. Further, if any of the calls to
@@ -157,6 +180,7 @@
 };
 
 /*
+ * Platform data for "soc-camera-pdrv"
  * This MUST be kept binary-identical to struct soc_camera_link below, until
  * it is completely replaced by this one, after which we can split it into its
  * two components.
@@ -322,14 +346,17 @@
 unsigned long soc_camera_apply_board_flags(struct soc_camera_subdev_desc *ssdd,
 					   const struct v4l2_mbus_config *cfg);
 
-int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd);
-int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd);
+int soc_camera_power_init(struct device *dev, struct soc_camera_subdev_desc *ssdd);
+int soc_camera_power_on(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+			struct v4l2_clk *clk);
+int soc_camera_power_off(struct device *dev, struct soc_camera_subdev_desc *ssdd,
+			 struct v4l2_clk *clk);
 
 static inline int soc_camera_set_power(struct device *dev,
-				struct soc_camera_subdev_desc *ssdd, bool on)
+		struct soc_camera_subdev_desc *ssdd, struct v4l2_clk *clk, bool on)
 {
-	return on ? soc_camera_power_on(dev, ssdd)
-		  : soc_camera_power_off(dev, ssdd);
+	return on ? soc_camera_power_on(dev, ssdd, clk)
+		  : soc_camera_power_off(dev, ssdd, clk);
 }
 
 /* This is only temporary here - until v4l2-subdev begins to link to video_device */
@@ -346,9 +373,9 @@
 	return client->dev.platform_data;
 }
 
-static inline struct v4l2_subdev *soc_camera_vdev_to_subdev(const struct video_device *vdev)
+static inline struct v4l2_subdev *soc_camera_vdev_to_subdev(struct video_device *vdev)
 {
-	struct soc_camera_device *icd = dev_get_drvdata(vdev->parent);
+	struct soc_camera_device *icd = video_get_drvdata(vdev);
 	return soc_camera_to_subdev(icd);
 }
 
diff --git a/include/media/ths7303.h b/include/media/ths7303.h
index 980ec51..a7b4929 100644
--- a/include/media/ths7303.h
+++ b/include/media/ths7303.h
@@ -30,13 +30,11 @@
  * @ch_1: Bias value for channel one.
  * @ch_2: Bias value for channel two.
  * @ch_3: Bias value for channel three.
- * @init_enable: initalize on init.
  */
 struct ths7303_platform_data {
 	u8 ch_1;
 	u8 ch_2;
 	u8 ch_3;
-	u8 init_enable;
 };
 
 #endif
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h
index a8ad75a..4a1191a 100644
--- a/include/media/tveeprom.h
+++ b/include/media/tveeprom.h
@@ -1,6 +1,17 @@
 /*
  */
 
+enum tveeprom_audio_processor {
+	/* No audio processor present */
+	TVEEPROM_AUDPROC_NONE,
+	/* The audio processor is internal to the video processor */
+	TVEEPROM_AUDPROC_INTERNAL,
+	/* The audio processor is a MSPXXXX device */
+	TVEEPROM_AUDPROC_MSP,
+	/* The audio processor is another device */
+	TVEEPROM_AUDPROC_OTHER,
+};
+
 struct tveeprom {
 	u32 has_radio;
 	/* If has_ir == 0, then it is unknown what the IR capabilities are,
diff --git a/include/media/tvp7002.h b/include/media/tvp7002.h
index ee43534..fadb6af 100644
--- a/include/media/tvp7002.h
+++ b/include/media/tvp7002.h
@@ -26,31 +26,29 @@
 #ifndef _TVP7002_H_
 #define _TVP7002_H_
 
-/* Platform-dependent data
- *
- * clk_polarity:
- * 			0 -> data clocked out on rising edge of DATACLK signal
- * 			1 -> data clocked out on falling edge of DATACLK signal
- * hs_polarity:
- * 			0 -> active low HSYNC output
- * 			1 -> active high HSYNC output
- * sog_polarity:
- * 			0 -> normal operation
- * 			1 -> operation with polarity inverted
- * vs_polarity:
- * 			0 -> active low VSYNC output
- * 			1 -> active high VSYNC output
- * fid_polarity:
- *			0 -> the field ID output is set to logic 1 for an odd
- *			     field (field 1) and set to logic 0 for an even
- *			     field (field 0).
- *			1 -> operation with polarity inverted.
+#define TVP7002_MODULE_NAME "tvp7002"
+
+/**
+ * struct tvp7002_config - Platform dependent data
+ *@clk_polarity: Clock polarity
+ *		0 - Data clocked out on rising edge of DATACLK signal
+ *		1 - Data clocked out on falling edge of DATACLK signal
+ *@hs_polarity:  HSYNC polarity
+ *		0 - Active low HSYNC output, 1 - Active high HSYNC output
+ *@vs_polarity: VSYNC Polarity
+ *		0 - Active low VSYNC output, 1 - Active high VSYNC output
+ *@fid_polarity: Active-high Field ID polarity.
+ *		0 - The field ID output is set to logic 1 for an odd field
+ *		    (field 1) and set to logic 0 for an even field (field 0).
+ *		1 - Operation with polarity inverted.
+ *@sog_polarity: Active high Sync on Green output polarity.
+ *		0 - Normal operation, 1 - Operation with polarity inverted
  */
 struct tvp7002_config {
-	u8 clk_polarity;
-	u8 hs_polarity;
-	u8 vs_polarity;
-	u8 fid_polarity;
-	u8 sog_polarity;
+	bool clk_polarity;
+	bool hs_polarity;
+	bool vs_polarity;
+	bool fid_polarity;
+	bool sog_polarity;
 };
 #endif
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
new file mode 100644
index 0000000..c3ec6ac
--- /dev/null
+++ b/include/media/v4l2-async.h
@@ -0,0 +1,105 @@
+/*
+ * V4L2 asynchronous subdevice registration API
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef V4L2_ASYNC_H
+#define V4L2_ASYNC_H
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+
+struct device;
+struct v4l2_device;
+struct v4l2_subdev;
+struct v4l2_async_notifier;
+
+/* A random max subdevice number, used to allocate an array on stack */
+#define V4L2_MAX_SUBDEVS 128U
+
+enum v4l2_async_bus_type {
+	V4L2_ASYNC_BUS_CUSTOM,
+	V4L2_ASYNC_BUS_PLATFORM,
+	V4L2_ASYNC_BUS_I2C,
+};
+
+/**
+ * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge
+ * @bus_type:	subdevice bus type to select the appropriate matching method
+ * @match:	union of per-bus type matching data sets
+ * @list:	used to link struct v4l2_async_subdev objects, waiting to be
+ *		probed, to a notifier->waiting list
+ */
+struct v4l2_async_subdev {
+	enum v4l2_async_bus_type bus_type;
+	union {
+		struct {
+			const char *name;
+		} platform;
+		struct {
+			int adapter_id;
+			unsigned short address;
+		} i2c;
+		struct {
+			bool (*match)(struct device *,
+				      struct v4l2_async_subdev *);
+			void *priv;
+		} custom;
+	} match;
+
+	/* v4l2-async core private: not to be used by drivers */
+	struct list_head list;
+};
+
+/**
+ * v4l2_async_subdev_list - provided by subdevices
+ * @list:	links struct v4l2_async_subdev_list objects to a global list
+ *		before probing, and onto notifier->done after probing
+ * @asd:	pointer to respective struct v4l2_async_subdev
+ * @notifier:	pointer to managing notifier
+ */
+struct v4l2_async_subdev_list {
+	struct list_head list;
+	struct v4l2_async_subdev *asd;
+	struct v4l2_async_notifier *notifier;
+};
+
+/**
+ * v4l2_async_notifier - v4l2_device notifier data
+ * @num_subdevs:number of subdevices
+ * @subdev:	array of pointers to subdevice descriptors
+ * @v4l2_dev:	pointer to struct v4l2_device
+ * @waiting:	list of struct v4l2_async_subdev, waiting for their drivers
+ * @done:	list of struct v4l2_async_subdev_list, already probed
+ * @list:	member in a global list of notifiers
+ * @bound:	a subdevice driver has successfully probed one of subdevices
+ * @complete:	all subdevices have been probed successfully
+ * @unbind:	a subdevice is leaving
+ */
+struct v4l2_async_notifier {
+	unsigned int num_subdevs;
+	struct v4l2_async_subdev **subdev;
+	struct v4l2_device *v4l2_dev;
+	struct list_head waiting;
+	struct list_head done;
+	struct list_head list;
+	int (*bound)(struct v4l2_async_notifier *notifier,
+		     struct v4l2_subdev *subdev,
+		     struct v4l2_async_subdev *asd);
+	int (*complete)(struct v4l2_async_notifier *notifier);
+	void (*unbind)(struct v4l2_async_notifier *notifier,
+		       struct v4l2_subdev *subdev,
+		       struct v4l2_async_subdev *asd);
+};
+
+int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
+				 struct v4l2_async_notifier *notifier);
+void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
+int v4l2_async_register_subdev(struct v4l2_subdev *sd);
+void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
+#endif
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
deleted file mode 100644
index c259b36..0000000
--- a/include/media/v4l2-chip-ident.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
-    v4l2 chip identifiers header
-
-    This header provides a list of chip identifiers that can be returned
-    through the VIDIOC_DBG_G_CHIP_IDENT ioctl.
-
-    Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef V4L2_CHIP_IDENT_H_
-#define V4L2_CHIP_IDENT_H_
-
-/* VIDIOC_DBG_G_CHIP_IDENT: identifies the actual chip installed on the board */
-
-/* KEEP THIS LIST ORDERED BY ID!
-   Otherwise it will be hard to see which ranges are already in use when
-   adding support to a new chip family. */
-enum {
-	/* general idents: reserved range 0-49 */
-	V4L2_IDENT_NONE      = 0,       /* No chip matched */
-	V4L2_IDENT_AMBIGUOUS = 1,       /* Match too general, multiple chips matched */
-	V4L2_IDENT_UNKNOWN   = 2,       /* Chip found, but cannot identify */
-
-	/* module tvaudio: reserved range 50-99 */
-	V4L2_IDENT_TVAUDIO = 50,	/* A tvaudio chip, unknown which it is exactly */
-
-	/* Sony IMX074 */
-	V4L2_IDENT_IMX074 = 74,
-
-	/* module saa7110: just ident 100 */
-	V4L2_IDENT_SAA7110 = 100,
-
-	/* module saa7115: reserved range 101-149 */
-	V4L2_IDENT_SAA7111 = 101,
-	V4L2_IDENT_SAA7111A = 102,
-	V4L2_IDENT_SAA7113 = 103,
-	V4L2_IDENT_SAA7114 = 104,
-	V4L2_IDENT_SAA7115 = 105,
-	V4L2_IDENT_SAA7118 = 108,
-
-	/* module saa7127: reserved range 150-199 */
-	V4L2_IDENT_SAA7127 = 157,
-	V4L2_IDENT_SAA7129 = 159,
-
-	/* module cx25840: reserved range 200-249 */
-	V4L2_IDENT_CX25836 = 236,
-	V4L2_IDENT_CX25837 = 237,
-	V4L2_IDENT_CX25840 = 240,
-	V4L2_IDENT_CX25841 = 241,
-	V4L2_IDENT_CX25842 = 242,
-	V4L2_IDENT_CX25843 = 243,
-
-	/* OmniVision sensors: reserved range 250-299 */
-	V4L2_IDENT_OV7670 = 250,
-	V4L2_IDENT_OV7720 = 251,
-	V4L2_IDENT_OV7725 = 252,
-	V4L2_IDENT_OV7660 = 253,
-	V4L2_IDENT_OV9650 = 254,
-	V4L2_IDENT_OV9655 = 255,
-	V4L2_IDENT_SOI968 = 256,
-	V4L2_IDENT_OV9640 = 257,
-	V4L2_IDENT_OV6650 = 258,
-	V4L2_IDENT_OV2640 = 259,
-	V4L2_IDENT_OV9740 = 260,
-	V4L2_IDENT_OV5642 = 261,
-
-	/* module saa7146: reserved range 300-309 */
-	V4L2_IDENT_SAA7146 = 300,
-
-	/* Conexant MPEG encoder/decoders: reserved range 400-420 */
-	V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */
-	V4L2_IDENT_CX23415 = 415,
-	V4L2_IDENT_CX23416 = 416,
-	V4L2_IDENT_CX23417 = 417,
-	V4L2_IDENT_CX23418 = 418,
-
-	/* module bt819: reserved range 810-819 */
-	V4L2_IDENT_BT815A = 815,
-	V4L2_IDENT_BT817A = 817,
-	V4L2_IDENT_BT819A = 819,
-
-	/* module au0828 */
-	V4L2_IDENT_AU0828 = 828,
-
-	/* module bttv: ident 848 + 849 */
-	V4L2_IDENT_BT848 = 848,
-	V4L2_IDENT_BT849 = 849,
-
-	/* module bt856: just ident 856 */
-	V4L2_IDENT_BT856 = 856,
-
-	/* module bt866: just ident 866 */
-	V4L2_IDENT_BT866 = 866,
-
-	/* module bttv: ident 878 + 879 */
-	V4L2_IDENT_BT878 = 878,
-	V4L2_IDENT_BT879 = 879,
-
-	/* module ks0127: reserved range 1120-1129 */
-	V4L2_IDENT_KS0122S = 1122,
-	V4L2_IDENT_KS0127  = 1127,
-	V4L2_IDENT_KS0127B = 1128,
-
-	/* module indycam: just ident 2000 */
-	V4L2_IDENT_INDYCAM = 2000,
-
-	/* module vp27smpx: just ident 2700 */
-	V4L2_IDENT_VP27SMPX = 2700,
-
-	/* module vpx3220: reserved range: 3210-3229 */
-	V4L2_IDENT_VPX3214C = 3214,
-	V4L2_IDENT_VPX3216B = 3216,
-	V4L2_IDENT_VPX3220A = 3220,
-
-	/* VX855 just ident 3409 */
-	/* Other via devs could use 3314, 3324, 3327, 3336, 3364, 3353 */
-	V4L2_IDENT_VIA_VX855 = 3409,
-
-	/* module tvp5150 */
-	V4L2_IDENT_TVP5150 = 5150,
-
-	/* module saa5246a: just ident 5246 */
-	V4L2_IDENT_SAA5246A = 5246,
-
-	/* module saa5249: just ident 5249 */
-	V4L2_IDENT_SAA5249 = 5249,
-
-	/* module cs5345: just ident 5345 */
-	V4L2_IDENT_CS5345 = 5345,
-
-	/* module tea6415c: just ident 6415 */
-	V4L2_IDENT_TEA6415C = 6415,
-
-	/* module tea6420: just ident 6420 */
-	V4L2_IDENT_TEA6420 = 6420,
-
-	/* module saa6588: just ident 6588 */
-	V4L2_IDENT_SAA6588 = 6588,
-
-	/* module vs6624: just ident 6624 */
-	V4L2_IDENT_VS6624 = 6624,
-
-	/* module saa6752hs: reserved range 6750-6759 */
-	V4L2_IDENT_SAA6752HS = 6752,
-	V4L2_IDENT_SAA6752HS_AC3 = 6753,
-
-	/* modules tef6862: just ident 6862 */
-	V4L2_IDENT_TEF6862 = 6862,
-
-	/* module tvp7002: just ident 7002 */
-	V4L2_IDENT_TVP7002 = 7002,
-
-	/* module adv7170: just ident 7170 */
-	V4L2_IDENT_ADV7170 = 7170,
-
-	/* module adv7175: just ident 7175 */
-	V4L2_IDENT_ADV7175 = 7175,
-
-	/* module adv7180: just ident 7180 */
-	V4L2_IDENT_ADV7180 = 7180,
-
-	/* module adv7183: just ident 7183 */
-	V4L2_IDENT_ADV7183 = 7183,
-
-	/* module saa7185: just ident 7185 */
-	V4L2_IDENT_SAA7185 = 7185,
-
-	/* module saa7191: just ident 7191 */
-	V4L2_IDENT_SAA7191 = 7191,
-
-	/* module ths7303: just ident 7303 */
-	V4L2_IDENT_THS7303 = 7303,
-
-	/* module adv7343: just ident 7343 */
-	V4L2_IDENT_ADV7343 = 7343,
-
-	/* module ths7353: just ident 7353 */
-	V4L2_IDENT_THS7353 = 7353,
-
-	/* module adv7393: just ident 7393 */
-	V4L2_IDENT_ADV7393 = 7393,
-
-	/* module adv7604: just ident 7604 */
-	V4L2_IDENT_ADV7604 = 7604,
-
-	/* module saa7706h: just ident 7706 */
-	V4L2_IDENT_SAA7706H = 7706,
-
-	/* module mt9v011, just ident 8243 */
-	V4L2_IDENT_MT9V011 = 8243,
-
-	/* module wm8739: just ident 8739 */
-	V4L2_IDENT_WM8739 = 8739,
-
-	/* module wm8775: just ident 8775 */
-	V4L2_IDENT_WM8775 = 8775,
-
-	/* Marvell controllers starting at 8801 */
-	V4L2_IDENT_CAFE = 8801,
-	V4L2_IDENT_ARMADA610 = 8802,
-
-	/* AKM AK8813/AK8814 */
-	V4L2_IDENT_AK8813 = 8813,
-	V4L2_IDENT_AK8814 = 8814,
-
-	/* module cx23885 and cx25840 */
-	V4L2_IDENT_CX23885    = 8850,
-	V4L2_IDENT_CX23885_AV = 8851, /* Integrated A/V decoder */
-	V4L2_IDENT_CX23887    = 8870,
-	V4L2_IDENT_CX23887_AV = 8871, /* Integrated A/V decoder */
-	V4L2_IDENT_CX23888    = 8880,
-	V4L2_IDENT_CX23888_AV = 8881, /* Integrated A/V decoder */
-	V4L2_IDENT_CX23888_IR = 8882, /* Integrated infrared controller */
-
-	/* module ad9389b: just ident 9389 */
-	V4L2_IDENT_AD9389B = 9389,
-
-	/* module tda9840: just ident 9840 */
-	V4L2_IDENT_TDA9840 = 9840,
-
-	/* module tw9910: just ident 9910 */
-	V4L2_IDENT_TW9910 = 9910,
-
-	/* module sn9c20x: just ident 10000 */
-	V4L2_IDENT_SN9C20X = 10000,
-
-	/* module cx231xx and cx25840 */
-	V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */
-	V4L2_IDENT_CX23100    = 23100,
-	V4L2_IDENT_CX23101    = 23101,
-	V4L2_IDENT_CX23102    = 23102,
-
-	/* module msp3400: reserved range 34000-34999 for msp34xx */
-	V4L2_IDENT_MSPX4XX  = 34000, /* generic MSPX4XX identifier, only
-					use internally (tveeprom.c). */
-
-	V4L2_IDENT_MSP3400B = 34002,
-	V4L2_IDENT_MSP3400C = 34003,
-	V4L2_IDENT_MSP3400D = 34004,
-	V4L2_IDENT_MSP3400G = 34007,
-	V4L2_IDENT_MSP3401G = 34017,
-	V4L2_IDENT_MSP3402G = 34027,
-	V4L2_IDENT_MSP3405D = 34054,
-	V4L2_IDENT_MSP3405G = 34057,
-	V4L2_IDENT_MSP3407D = 34074,
-	V4L2_IDENT_MSP3407G = 34077,
-
-	V4L2_IDENT_MSP3410B = 34102,
-	V4L2_IDENT_MSP3410C = 34103,
-	V4L2_IDENT_MSP3410D = 34104,
-	V4L2_IDENT_MSP3410G = 34107,
-	V4L2_IDENT_MSP3411G = 34117,
-	V4L2_IDENT_MSP3412G = 34127,
-	V4L2_IDENT_MSP3415D = 34154,
-	V4L2_IDENT_MSP3415G = 34157,
-	V4L2_IDENT_MSP3417D = 34174,
-	V4L2_IDENT_MSP3417G = 34177,
-
-	V4L2_IDENT_MSP3420G = 34207,
-	V4L2_IDENT_MSP3421G = 34217,
-	V4L2_IDENT_MSP3422G = 34227,
-	V4L2_IDENT_MSP3425G = 34257,
-	V4L2_IDENT_MSP3427G = 34277,
-
-	V4L2_IDENT_MSP3430G = 34307,
-	V4L2_IDENT_MSP3431G = 34317,
-	V4L2_IDENT_MSP3435G = 34357,
-	V4L2_IDENT_MSP3437G = 34377,
-
-	V4L2_IDENT_MSP3440G = 34407,
-	V4L2_IDENT_MSP3441G = 34417,
-	V4L2_IDENT_MSP3442G = 34427,
-	V4L2_IDENT_MSP3445G = 34457,
-	V4L2_IDENT_MSP3447G = 34477,
-
-	V4L2_IDENT_MSP3450G = 34507,
-	V4L2_IDENT_MSP3451G = 34517,
-	V4L2_IDENT_MSP3452G = 34527,
-	V4L2_IDENT_MSP3455G = 34557,
-	V4L2_IDENT_MSP3457G = 34577,
-
-	V4L2_IDENT_MSP3460G = 34607,
-	V4L2_IDENT_MSP3461G = 34617,
-	V4L2_IDENT_MSP3465G = 34657,
-	V4L2_IDENT_MSP3467G = 34677,
-
-	/* module msp3400: reserved range 44000-44999 for msp44xx */
-	V4L2_IDENT_MSP4400G = 44007,
-	V4L2_IDENT_MSP4408G = 44087,
-	V4L2_IDENT_MSP4410G = 44107,
-	V4L2_IDENT_MSP4418G = 44187,
-	V4L2_IDENT_MSP4420G = 44207,
-	V4L2_IDENT_MSP4428G = 44287,
-	V4L2_IDENT_MSP4440G = 44407,
-	V4L2_IDENT_MSP4448G = 44487,
-	V4L2_IDENT_MSP4450G = 44507,
-	V4L2_IDENT_MSP4458G = 44587,
-
-	/* Micron CMOS sensor chips: 45000-45099 */
-	V4L2_IDENT_MT9M001C12ST		= 45000,
-	V4L2_IDENT_MT9M001C12STM	= 45005,
-	V4L2_IDENT_MT9M111		= 45007,
-	V4L2_IDENT_MT9M112		= 45008,
-	V4L2_IDENT_MT9V022IX7ATC	= 45010, /* No way to detect "normal" I77ATx */
-	V4L2_IDENT_MT9V022IX7ATM	= 45015, /* and "lead free" IA7ATx chips */
-	V4L2_IDENT_MT9T031		= 45020,
-	V4L2_IDENT_MT9T111		= 45021,
-	V4L2_IDENT_MT9T112		= 45022,
-	V4L2_IDENT_MT9V111		= 45031,
-	V4L2_IDENT_MT9V112		= 45032,
-
-	/* HV7131R CMOS sensor: just ident 46000 */
-	V4L2_IDENT_HV7131R		= 46000,
-
-	/* Sharp RJ54N1CB0C, 0xCB0C = 51980 */
-	V4L2_IDENT_RJ54N1CB0C = 51980,
-
-	/* module m52790: just ident 52790 */
-	V4L2_IDENT_M52790 = 52790,
-
-	/* module cs53132a: just ident 53132 */
-	V4L2_IDENT_CS53l32A = 53132,
-
-	/* modules upd61151 MPEG2 encoder: just ident 54000 */
-	V4L2_IDENT_UPD61161 = 54000,
-	/* modules upd61152 MPEG2 encoder with AC3: just ident 54001 */
-	V4L2_IDENT_UPD61162 = 54001,
-
-	/* module upd64031a: just ident 64031 */
-	V4L2_IDENT_UPD64031A = 64031,
-
-	/* module upd64083: just ident 64083 */
-	V4L2_IDENT_UPD64083 = 64083,
-
-	/* Don't just add new IDs at the end: KEEP THIS LIST ORDERED BY ID! */
-};
-
-#endif
diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h
new file mode 100644
index 0000000..0503a90
--- /dev/null
+++ b/include/media/v4l2-clk.h
@@ -0,0 +1,54 @@
+/*
+ * V4L2 clock service
+ *
+ * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ATTENTION: This is a temporary API and it shall be replaced by the generic
+ * clock API, when the latter becomes widely available.
+ */
+
+#ifndef MEDIA_V4L2_CLK_H
+#define MEDIA_V4L2_CLK_H
+
+#include <linux/atomic.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+
+struct module;
+struct device;
+
+struct v4l2_clk {
+	struct list_head list;
+	const struct v4l2_clk_ops *ops;
+	const char *dev_id;
+	const char *id;
+	int enable;
+	struct mutex lock; /* Protect the enable count */
+	atomic_t use_count;
+	void *priv;
+};
+
+struct v4l2_clk_ops {
+	struct module	*owner;
+	int		(*enable)(struct v4l2_clk *clk);
+	void		(*disable)(struct v4l2_clk *clk);
+	unsigned long	(*get_rate)(struct v4l2_clk *clk);
+	int		(*set_rate)(struct v4l2_clk *clk, unsigned long);
+};
+
+struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops,
+				   const char *dev_name,
+				   const char *name, void *priv);
+void v4l2_clk_unregister(struct v4l2_clk *clk);
+struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id);
+void v4l2_clk_put(struct v4l2_clk *clk);
+int v4l2_clk_enable(struct v4l2_clk *clk);
+void v4l2_clk_disable(struct v4l2_clk *clk);
+unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk);
+int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate);
+
+#endif
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 1d93c48..015ff82 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -100,16 +100,6 @@
 
 /* ------------------------------------------------------------------------- */
 
-/* Register/chip ident helper function */
-
-struct i2c_client; /* forward reference */
-int v4l2_chip_match_i2c_client(struct i2c_client *c, const struct v4l2_dbg_match *match);
-int v4l2_chip_ident_i2c_client(struct i2c_client *c, struct v4l2_dbg_chip_ident *chip,
-		u32 ident, u32 revision);
-int v4l2_chip_match_host(const struct v4l2_dbg_match *match);
-
-/* ------------------------------------------------------------------------- */
-
 /* I2C Helper functions */
 
 struct i2c_driver;
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 95d1c91..c768c9f 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -96,9 +96,9 @@
 	struct device dev;		/* v4l device */
 	struct cdev *cdev;		/* character device */
 
-	/* Set either parent or v4l2_dev if your driver uses v4l2_device */
-	struct device *parent;		/* device parent */
 	struct v4l2_device *v4l2_dev;	/* v4l2_device parent */
+	/* Only set parent if that can't be deduced from v4l2_dev */
+	struct device *dev_parent;	/* device parent */
 
 	/* Control handler associated with this device node. May be NULL. */
 	struct v4l2_ctrl_handler *ctrl_handler;
@@ -129,7 +129,6 @@
 
 	/* Video standard vars */
 	v4l2_std_id tvnorms;		/* Supported tv norms */
-	v4l2_std_id current_norm;	/* Current tvnorm */
 
 	/* callbacks */
 	void (*release)(struct video_device *vdev);
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
index e6aa231..0286c95 100644
--- a/include/media/v4l2-int-device.h
+++ b/include/media/v4l2-int-device.h
@@ -220,8 +220,6 @@
 	vidioc_int_reset_num,
 	/* VIDIOC_INT_INIT */
 	vidioc_int_init_num,
-	/* VIDIOC_DBG_G_CHIP_IDENT */
-	vidioc_int_g_chip_ident_num,
 
 	/*
 	 *
@@ -303,6 +301,5 @@
 
 V4L2_INT_WRAPPER_0(reset);
 V4L2_INT_WRAPPER_0(init);
-V4L2_INT_WRAPPER_1(g_chip_ident, int, *);
 
 #endif
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 931652f..e0b74a4 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -247,8 +247,6 @@
 	int (*vidioc_g_chip_info)      (struct file *file, void *fh,
 					struct v4l2_dbg_chip_info *chip);
 #endif
-	int (*vidioc_g_chip_ident)     (struct file *file, void *fh,
-					struct v4l2_dbg_chip_ident *chip);
 
 	int (*vidioc_enum_framesizes)   (struct file *file, void *fh,
 					 struct v4l2_frmsizeenum *fsize);
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 5298d67..3250cc5 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 #include <linux/v4l2-subdev.h>
 #include <media/media-entity.h>
+#include <media/v4l2-async.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-fh.h>
@@ -88,7 +89,6 @@
 
 /* Core ops: it is highly recommended to implement at least these ops:
 
-   g_chip_ident
    log_status
    g_register
    s_register
@@ -145,7 +145,6 @@
 	performed later.  It must not sleep.  *Called from an IRQ context*.
  */
 struct v4l2_subdev_core_ops {
-	int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
 	int (*log_status)(struct v4l2_subdev *sd);
 	int (*s_io_pin_config)(struct v4l2_subdev *sd, size_t n,
 				      struct v4l2_subdev_io_pin_config *pincfg);
@@ -585,8 +584,17 @@
 	void *host_priv;
 	/* subdev device node */
 	struct video_device *devnode;
+	/* pointer to the physical device, if any */
+	struct device *dev;
+	struct v4l2_async_subdev_list asdl;
 };
 
+static inline struct v4l2_subdev *v4l2_async_to_subdev(
+			struct v4l2_async_subdev_list *asdl)
+{
+	return container_of(asdl, struct v4l2_subdev, asdl);
+}
+
 #define media_entity_to_v4l2_subdev(ent) \
 	container_of(ent, struct v4l2_subdev, entity)
 #define vdev_to_v4l2_subdev(vdev) \
@@ -660,7 +668,7 @@
 /* Call an ops of a v4l2_subdev, doing the right checks against
    NULL pointers.
 
-   Example: err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
+   Example: err = v4l2_subdev_call(sd, core, s_std, norm);
  */
 #define v4l2_subdev_call(sd, o, f, args...)				\
 	(!(sd) ? -ENODEV : (((sd)->ops->o && (sd)->ops->o->f) ?	\
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index 69bd5bb..e90a88a 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -53,13 +53,13 @@
 #define V4L2_CTRL_CLASS_USER		0x00980000	/* Old-style 'user' controls */
 #define V4L2_CTRL_CLASS_MPEG		0x00990000	/* MPEG-compression controls */
 #define V4L2_CTRL_CLASS_CAMERA		0x009a0000	/* Camera class controls */
-#define V4L2_CTRL_CLASS_FM_TX		0x009b0000	/* FM Modulator control class */
+#define V4L2_CTRL_CLASS_FM_TX		0x009b0000	/* FM Modulator controls */
 #define V4L2_CTRL_CLASS_FLASH		0x009c0000	/* Camera flash controls */
 #define V4L2_CTRL_CLASS_JPEG		0x009d0000	/* JPEG-compression controls */
 #define V4L2_CTRL_CLASS_IMAGE_SOURCE	0x009e0000	/* Image source controls */
 #define V4L2_CTRL_CLASS_IMAGE_PROC	0x009f0000	/* Image processing controls */
 #define V4L2_CTRL_CLASS_DV		0x00a00000	/* Digital Video controls */
-#define V4L2_CTRL_CLASS_FM_RX		0x00a10000	/* Digital Video controls */
+#define V4L2_CTRL_CLASS_FM_RX		0x00a10000	/* FM Receiver controls */
 
 /* User-class control IDs */
 
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index f40b41c..95ef455 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -395,7 +395,7 @@
 #define V4L2_PIX_FMT_H263     v4l2_fourcc('H', '2', '6', '3') /* H263          */
 #define V4L2_PIX_FMT_MPEG1    v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES     */
 #define V4L2_PIX_FMT_MPEG2    v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES     */
-#define V4L2_PIX_FMT_MPEG4    v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 ES     */
+#define V4L2_PIX_FMT_MPEG4    v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 part 2 ES */
 #define V4L2_PIX_FMT_XVID     v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid           */
 #define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */
 #define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */
@@ -555,7 +555,7 @@
 	__u32 jpeg_markers;     /* Which markers should go into the JPEG
 				 * output. Unless you exactly know what
 				 * you do, leave them untouched.
-				 * Inluding less markers will make the
+				 * Including less markers will make the
 				 * resulting code smaller, but there will
 				 * be fewer applications which can read it.
 				 * The presence of the APP and COM marker
@@ -567,7 +567,7 @@
 #define V4L2_JPEG_MARKER_DRI (1<<5)    /* Define Restart Interval */
 #define V4L2_JPEG_MARKER_COM (1<<6)    /* Comment segment */
 #define V4L2_JPEG_MARKER_APP (1<<7)    /* App segment, driver will
-					* allways use APP0 */
+					* always use APP0 */
 };
 
 /*
@@ -900,7 +900,7 @@
 /*
  * "Common" PAL - This macro is there to be compatible with the old
  * V4L1 concept of "PAL": /BGDKHI.
- * Several PAL standards are mising here: /M, /N and /Nc
+ * Several PAL standards are missing here: /M, /N and /Nc
  */
 #define V4L2_STD_PAL		(V4L2_STD_PAL_BG	|\
 				 V4L2_STD_PAL_DK	|\
@@ -1787,11 +1787,13 @@
 /* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
 
 #define V4L2_CHIP_MATCH_BRIDGE      0  /* Match against chip ID on the bridge (0 for the bridge) */
+#define V4L2_CHIP_MATCH_SUBDEV      4  /* Match against subdev index */
+
+/* The following four defines are no longer in use */
 #define V4L2_CHIP_MATCH_HOST V4L2_CHIP_MATCH_BRIDGE
 #define V4L2_CHIP_MATCH_I2C_DRIVER  1  /* Match against I2C driver name */
 #define V4L2_CHIP_MATCH_I2C_ADDR    2  /* Match against I2C 7-bit address */
-#define V4L2_CHIP_MATCH_AC97        3  /* Match against anciliary AC97 chip */
-#define V4L2_CHIP_MATCH_SUBDEV      4  /* Match against subdev index */
+#define V4L2_CHIP_MATCH_AC97        3  /* Match against ancillary AC97 chip */
 
 struct v4l2_dbg_match {
 	__u32 type; /* Match type */
@@ -1808,13 +1810,6 @@
 	__u64 val;
 } __attribute__ ((packed));
 
-/* VIDIOC_DBG_G_CHIP_IDENT */
-struct v4l2_dbg_chip_ident {
-	struct v4l2_dbg_match match;
-	__u32 ident;       /* chip identifier as specified in <media/v4l2-chip-ident.h> */
-	__u32 revision;    /* chip revision, chip specific */
-} __attribute__ ((packed));
-
 #define V4L2_CHIP_FL_READABLE (1 << 0)
 #define V4L2_CHIP_FL_WRITABLE (1 << 1)
 
@@ -1915,12 +1910,6 @@
 #define	VIDIOC_DBG_S_REGISTER 	 _IOW('V', 79, struct v4l2_dbg_register)
 #define	VIDIOC_DBG_G_REGISTER 	_IOWR('V', 80, struct v4l2_dbg_register)
 
-/* Experimental, meant for debugging, testing and internal use.
-   Never use this ioctl in applications!
-   Note: this ioctl is deprecated in favor of VIDIOC_DBG_G_CHIP_INFO and
-   will go away in the future. */
-#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident)
-
 #define VIDIOC_S_HW_FREQ_SEEK	 _IOW('V', 82, struct v4l2_hw_freq_seek)
 
 #define	VIDIOC_S_DV_TIMINGS	_IOWR('V', 87, struct v4l2_dv_timings)