Merge tag 'media/v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:

 - a new sensor driver for ov5675

 - a new platform driver for Allwinner A10 sensor interface

 - some new remote controller keymaps

 - some cosmetic changes at V4L2 core in order to avoid #ifdefs and to
   merge two core modules into one

 - removal of bcm2048 radio driver from staging

 - removal of davinci_vpfe video driver from staging

 - regression fix since Kernel 5.1 at the legacy VideoBuffer version 1
   core

 - added some documentation for remote controller protocols

 - pixel format documentation was split on two files

 - lots of other driver improvements and cleanups

* tag 'media/v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (321 commits)
  media: videobuf-core.c: poll_wait needs a non-NULL buf pointer
  media: sun4i: Make sun4i_csi_formats static
  media: imx: remove unused including <linux/version.h>
  media: stm32-dcmi: Delete an unnecessary of_node_put() call in dcmi_probe()
  media: pvrusb2: qctrl.flag will be uninitlaized if cx2341x_ctrl_query() returns error code
  media: em28xx: Fix exception handling in em28xx_alloc_urbs()
  media: don't do a 31 bit shift on a signed int
  media: use the BIT() macro
  media: ov9650: add a sanity check
  media: aspeed-video: address a protential usage of an unitialized var
  media: vicodec: make life easier for static analyzers
  media: remove include stdarg.h from some drivers
  v4l2-core: fix coding style for the two new c files
  media: v4l2-core: Remove BUG() from i2c and spi helpers
  media: v4l2-core: introduce a helper to unregister a i2c subdev
  media: v4l2-core: introduce a helper to unregister a spi subdev
  media: v4l2-core: move i2c helpers out of v4l2-common.c
  media: v4l2-core: move spi helpers out of v4l2-common.c
  media: v4l2-core: Module re-organization
  media: usbvision: Remove dead code
  ...
diff --git a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
new file mode 100644
index 0000000..27f38ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/allwinner,sun4i-a10-csi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A10 CMOS Sensor Interface (CSI) Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+description: |-
+  The Allwinner A10 and later has a CMOS Sensor Interface to retrieve
+  frames from a parallel or BT656 sensor.
+
+properties:
+  compatible:
+    const: allwinner,sun7i-a20-csi0
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: The CSI interface clock
+      - description: The CSI module clock
+      - description: The CSI ISP clock
+      - description: The CSI DRAM clock
+
+  clock-names:
+    items:
+      - const: bus
+      - const: mod
+      - const: isp
+      - const: ram
+
+  resets:
+    maxItems: 1
+
+  # See ./video-interfaces.txt for details
+  port:
+    type: object
+    additionalProperties: false
+
+    properties:
+      endpoint:
+        type: object
+
+        properties:
+          bus-width:
+            enum: [8, 16]
+
+          data-active: true
+          hsync-active: true
+          pclk-sample: true
+          remote-endpoint: true
+          vsync-active: true
+
+        required:
+          - bus-width
+          - data-active
+          - hsync-active
+          - pclk-sample
+          - remote-endpoint
+          - vsync-active
+
+    required:
+      - endpoint
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/sun7i-a20-ccu.h>
+    #include <dt-bindings/reset/sun4i-a10-ccu.h>
+
+    csi0: csi@1c09000 {
+        compatible = "allwinner,sun7i-a20-csi0";
+        reg = <0x01c09000 0x1000>;
+        interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&ccu CLK_AHB_CSI0>, <&ccu CLK_CSI0>,
+                 <&ccu CLK_CSI_SCLK>, <&ccu CLK_DRAM_CSI0>;
+        clock-names = "bus", "mod", "isp", "ram";
+        resets = <&ccu RST_CSI0>;
+
+        port {
+            csi_from_ov5640: endpoint {
+                remote-endpoint = <&ov5640_to_csi>;
+                bus-width = <8>;
+                hsync-active = <1>; /* Active high */
+                vsync-active = <0>; /* Active low */
+                data-active = <1>;  /* Active high */
+                pclk-sample = <1>;  /* Rising */
+            };
+        };
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-ir.yaml b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-ir.yaml
new file mode 100644
index 0000000..98c1bdd
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-ir.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/allwinner,sun4i-a10-ir.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A10 Infrared Controller Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+allOf:
+  - $ref: "rc.yaml#"
+
+properties:
+  compatible:
+    oneOf:
+      - const: allwinner,sun4i-a10-ir
+      - const: allwinner,sun5i-a13-ir
+      - items:
+          - const: allwinner,sun8i-a83t-ir
+          - const: allwinner,sun6i-a31-ir
+      - const: allwinner,sun6i-a31-ir
+      - items:
+          - const: allwinner,sun50i-a64-ir
+          - const: allwinner,sun6i-a31-ir
+      - items:
+          - const: allwinner,sun50i-h6-ir
+          - const: allwinner,sun6i-a31-ir
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Bus Clock
+      - description: Module Clock
+
+  clock-names:
+    items:
+      - const: apb
+      - const: ir
+
+  resets:
+    maxItems: 1
+
+  clock-frequency:
+    default: 8000000
+    description:
+      IR Receiver clock frequency, in Hertz.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+# FIXME: We should set it, but it would report all the generic
+# properties as additional properties.
+# additionalProperties: false
+
+examples:
+  - |
+      ir0: ir@1c21800 {
+          compatible = "allwinner,sun4i-a10-ir";
+          clocks = <&apb0_gates 6>, <&ir0_clk>;
+          clock-names = "apb", "ir";
+          clock-frequency = <3000000>;
+          resets = <&apb0_rst 1>;
+          interrupts = <0 5 1>;
+          reg = <0x01C21800 0x40>;
+          linux,rc-map-name = "rc-rc6-mce";
+      };
+
+...
diff --git a/Documentation/devicetree/bindings/media/cdns,csi2tx.txt b/Documentation/devicetree/bindings/media/cdns,csi2tx.txt
index 459c6e3..751b9ed 100644
--- a/Documentation/devicetree/bindings/media/cdns,csi2tx.txt
+++ b/Documentation/devicetree/bindings/media/cdns,csi2tx.txt
@@ -5,7 +5,8 @@
 4 CSI lanes in output, and up to 4 different pixel streams in input.
 
 Required properties:
-  - compatible: must be set to "cdns,csi2tx"
+  - compatible: must be set to "cdns,csi2tx" or "cdns,csi2tx-1.3"
+    for version 1.3 of the controller, "cdns,csi2tx-2.1" for v2.1
   - reg: base address and size of the memory mapped region
   - clocks: phandles to the clocks driving the controller
   - clock-names: must contain:
diff --git a/Documentation/devicetree/bindings/media/imx7-csi.txt b/Documentation/devicetree/bindings/media/imx7-csi.txt
index 443aef07..d80ceef 100644
--- a/Documentation/devicetree/bindings/media/imx7-csi.txt
+++ b/Documentation/devicetree/bindings/media/imx7-csi.txt
@@ -9,7 +9,7 @@
 
 Required properties:
 
-- compatible    : "fsl,imx7-csi";
+- compatible    : "fsl,imx7-csi" or "fsl,imx6ul-csi";
 - reg           : base address and length of the register set for the device;
 - interrupts    : should contain CSI interrupt;
 - clocks        : list of clock specifiers, see
diff --git a/Documentation/devicetree/bindings/media/meson-ao-cec.txt b/Documentation/devicetree/bindings/media/meson-ao-cec.txt
index c67fc41..ad92ee4 100644
--- a/Documentation/devicetree/bindings/media/meson-ao-cec.txt
+++ b/Documentation/devicetree/bindings/media/meson-ao-cec.txt
@@ -5,10 +5,12 @@
 
 Required properties:
   - compatible : value should be following depending on the SoC :
-	For GXBB, GXL, GXM and G12A (AO_CEC_A module) :
+	For GXBB, GXL, GXM, G12A and SM1 (AO_CEC_A module) :
 	"amlogic,meson-gx-ao-cec"
 	For G12A (AO_CEC_B module) :
 	"amlogic,meson-g12a-ao-cec"
+	For SM1 (AO_CEC_B module) :
+	"amlogic,meson-sm1-ao-cec"
 
   - reg : Physical base address of the IP registers and length of memory
 	  mapped region.
@@ -16,9 +18,9 @@
   - interrupts : AO-CEC interrupt number to the CPU.
   - clocks : from common clock binding: handle to AO-CEC clock.
   - clock-names : from common clock binding, must contain :
-		For GXBB, GXL, GXM and G12A (AO_CEC_A module) :
+		For GXBB, GXL, GXM, G12A and SM1 (AO_CEC_A module) :
 		- "core"
-		For G12A (AO_CEC_B module) :
+		For G12A, SM1 (AO_CEC_B module) :
 		- "oscin"
 		corresponding to entry in the clocks property.
   - hdmi-phandle: phandle to the HDMI controller
diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
index 7302e94..602169b 100644
--- a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
+++ b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
@@ -35,6 +35,7 @@
 - resets : Must contain an entry for each entry in reset-names.
 - reset-names : Must include the following entries:
   - mc
+- iommus: Must contain phandle to the IOMMU device node.
 
 Example:
 
@@ -59,4 +60,5 @@
 	clocks = <&tegra_car TEGRA20_CLK_VDE>;
 	reset-names = "vde", "mc";
 	resets = <&tegra_car 61>, <&mc TEGRA20_MC_RESET_VDE>;
+	iommus = <&mc TEGRA_SWGROUP_VDE>;
 };
diff --git a/Documentation/devicetree/bindings/media/rc.txt b/Documentation/devicetree/bindings/media/rc.txt
index d3e7a01..be629f7 100644
--- a/Documentation/devicetree/bindings/media/rc.txt
+++ b/Documentation/devicetree/bindings/media/rc.txt
@@ -1,117 +1 @@
-The following properties are common to the infrared remote controllers:
-
-- linux,rc-map-name: string, specifies the scancode/key mapping table
-  defined in-kernel for the remote controller. Support values are:
-  * "rc-adstech-dvb-t-pci"
-  * "rc-alink-dtu-m"
-  * "rc-anysee"
-  * "rc-apac-viewcomp"
-  * "rc-asus-pc39"
-  * "rc-asus-ps3-100"
-  * "rc-ati-tv-wonder-hd-600"
-  * "rc-ati-x10"
-  * "rc-avermedia-a16d"
-  * "rc-avermedia-cardbus"
-  * "rc-avermedia-dvbt"
-  * "rc-avermedia-m135a"
-  * "rc-avermedia-m733a-rm-k6"
-  * "rc-avermedia-rm-ks"
-  * "rc-avermedia"
-  * "rc-avertv-303"
-  * "rc-azurewave-ad-tu700"
-  * "rc-behold-columbus"
-  * "rc-behold"
-  * "rc-budget-ci-old"
-  * "rc-cec"
-  * "rc-cinergy-1400"
-  * "rc-cinergy"
-  * "rc-delock-61959"
-  * "rc-dib0700-nec"
-  * "rc-dib0700-rc5"
-  * "rc-digitalnow-tinytwin"
-  * "rc-digittrade"
-  * "rc-dm1105-nec"
-  * "rc-dntv-live-dvbt-pro"
-  * "rc-dntv-live-dvb-t"
-  * "rc-dtt200u"
-  * "rc-dvbsky"
-  * "rc-empty"
-  * "rc-em-terratec"
-  * "rc-encore-enltv2"
-  * "rc-encore-enltv-fm53"
-  * "rc-encore-enltv"
-  * "rc-evga-indtube"
-  * "rc-eztv"
-  * "rc-flydvb"
-  * "rc-flyvideo"
-  * "rc-fusionhdtv-mce"
-  * "rc-gadmei-rm008z"
-  * "rc-geekbox"
-  * "rc-genius-tvgo-a11mce"
-  * "rc-gotview7135"
-  * "rc-hauppauge"
-  * "rc-imon-mce"
-  * "rc-imon-pad"
-  * "rc-iodata-bctv7e"
-  * "rc-it913x-v1"
-  * "rc-it913x-v2"
-  * "rc-kaiomy"
-  * "rc-kworld-315u"
-  * "rc-kworld-pc150u"
-  * "rc-kworld-plus-tv-analog"
-  * "rc-leadtek-y04g0051"
-  * "rc-lirc"
-  * "rc-lme2510"
-  * "rc-manli"
-  * "rc-medion-x10"
-  * "rc-medion-x10-digitainer"
-  * "rc-medion-x10-or2x"
-  * "rc-msi-digivox-ii"
-  * "rc-msi-digivox-iii"
-  * "rc-msi-tvanywhere-plus"
-  * "rc-msi-tvanywhere"
-  * "rc-nebula"
-  * "rc-nec-terratec-cinergy-xs"
-  * "rc-norwood"
-  * "rc-npgtech"
-  * "rc-pctv-sedna"
-  * "rc-pinnacle-color"
-  * "rc-pinnacle-grey"
-  * "rc-pinnacle-pctv-hd"
-  * "rc-pixelview-new"
-  * "rc-pixelview"
-  * "rc-pixelview-002t"
-  * "rc-pixelview-mk12"
-  * "rc-powercolor-real-angel"
-  * "rc-proteus-2309"
-  * "rc-purpletv"
-  * "rc-pv951"
-  * "rc-hauppauge"
-  * "rc-rc5-tv"
-  * "rc-rc6-mce"
-  * "rc-real-audio-220-32-keys"
-  * "rc-reddo"
-  * "rc-snapstream-firefly"
-  * "rc-streamzap"
-  * "rc-tbs-nec"
-  * "rc-technisat-ts35"
-  * "rc-technisat-usb2"
-  * "rc-terratec-cinergy-c-pci"
-  * "rc-terratec-cinergy-s2-hd"
-  * "rc-terratec-cinergy-xs"
-  * "rc-terratec-slim"
-  * "rc-terratec-slim-2"
-  * "rc-tevii-nec"
-  * "rc-tivo"
-  * "rc-total-media-in-hand"
-  * "rc-total-media-in-hand-02"
-  * "rc-trekstor"
-  * "rc-tt-1500"
-  * "rc-twinhan-dtv-cab-ci"
-  * "rc-twinhan1027"
-  * "rc-videomate-k100"
-  * "rc-videomate-s350"
-  * "rc-videomate-tv-pvr"
-  * "rc-winfast"
-  * "rc-winfast-usbii-deluxe"
-  * "rc-su3000"
+This file has been moved to rc.yaml.
diff --git a/Documentation/devicetree/bindings/media/rc.yaml b/Documentation/devicetree/bindings/media/rc.yaml
new file mode 100644
index 0000000..3d5c154
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/rc.yaml
@@ -0,0 +1,145 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/rc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic Infrared Remote Controller Device Tree Bindings
+
+maintainers:
+  - Mauro Carvalho Chehab <mchehab@kernel.org>
+  - Sean Young <sean@mess.org>
+
+properties:
+  $nodename:
+    pattern: "^ir(@[a-f0-9]+)?$"
+
+  linux,rc-map-name:
+    description:
+      Specifies the scancode/key mapping table defined in-kernel for
+      the remote controller.
+    allOf:
+      - $ref: '/schemas/types.yaml#/definitions/string'
+      - enum:
+          - rc-adstech-dvb-t-pci
+          - rc-alink-dtu-m
+          - rc-anysee
+          - rc-apac-viewcomp
+          - rc-astrometa-t2hybrid
+          - rc-asus-pc39
+          - rc-asus-ps3-100
+          - rc-ati-tv-wonder-hd-600
+          - rc-ati-x10
+          - rc-avermedia
+          - rc-avermedia-a16d
+          - rc-avermedia-cardbus
+          - rc-avermedia-dvbt
+          - rc-avermedia-m135a
+          - rc-avermedia-m733a-rm-k6
+          - rc-avermedia-rm-ks
+          - rc-avertv-303
+          - rc-azurewave-ad-tu700
+          - rc-behold
+          - rc-behold-columbus
+          - rc-budget-ci-old
+          - rc-cec
+          - rc-cinergy
+          - rc-cinergy-1400
+          - rc-d680-dmb
+          - rc-delock-61959
+          - rc-dib0700-nec
+          - rc-dib0700-rc5
+          - rc-digitalnow-tinytwin
+          - rc-digittrade
+          - rc-dm1105-nec
+          - rc-dntv-live-dvb-t
+          - rc-dntv-live-dvbt-pro
+          - rc-dtt200u
+          - rc-dvbsky
+          - rc-dvico-mce
+          - rc-dvico-portable
+          - rc-em-terratec
+          - rc-empty
+          - rc-encore-enltv
+          - rc-encore-enltv-fm53
+          - rc-encore-enltv2
+          - rc-evga-indtube
+          - rc-eztv
+          - rc-flydvb
+          - rc-flyvideo
+          - rc-fusionhdtv-mce
+          - rc-gadmei-rm008z
+          - rc-geekbox
+          - rc-genius-tvgo-a11mce
+          - rc-gotview7135
+          - rc-hauppauge
+          - rc-hauppauge
+          - rc-hisi-poplar
+          - rc-hisi-tv-demo
+          - rc-imon-mce
+          - rc-imon-pad
+          - rc-imon-rsc
+          - rc-iodata-bctv7e
+          - rc-it913x-v1
+          - rc-it913x-v2
+          - rc-kaiomy
+          - rc-kworld-315u
+          - rc-kworld-pc150u
+          - rc-kworld-plus-tv-analog
+          - rc-leadtek-y04g0051
+          - rc-lme2510
+          - rc-manli
+          - rc-medion-x10
+          - rc-medion-x10-digitainer
+          - rc-medion-x10-or2x
+          - rc-msi-digivox-ii
+          - rc-msi-digivox-iii
+          - rc-msi-tvanywhere
+          - rc-msi-tvanywhere-plus
+          - rc-nebula
+          - rc-nec-terratec-cinergy-xs
+          - rc-norwood
+          - rc-npgtech
+          - rc-pctv-sedna
+          - rc-pinnacle-color
+          - rc-pinnacle-grey
+          - rc-pinnacle-pctv-hd
+          - rc-pixelview
+          - rc-pixelview-002t
+          - rc-pixelview-mk12
+          - rc-pixelview-new
+          - rc-powercolor-real-angel
+          - rc-proteus-2309
+          - rc-purpletv
+          - rc-pv951
+          - rc-rc5-tv
+          - rc-rc6-mce
+          - rc-real-audio-220-32-keys
+          - rc-reddo
+          - rc-snapstream-firefly
+          - rc-streamzap
+          - rc-su3000
+          - rc-tango
+          - rc-tbs-nec
+          - rc-technisat-ts35
+          - rc-technisat-usb2
+          - rc-terratec-cinergy-c-pci
+          - rc-terratec-cinergy-s2-hd
+          - rc-terratec-cinergy-xs
+          - rc-terratec-slim
+          - rc-terratec-slim-2
+          - rc-tevii-nec
+          - rc-tivo
+          - rc-total-media-in-hand
+          - rc-total-media-in-hand-02
+          - rc-trekstor
+          - rc-tt-1500
+          - rc-twinhan-dtv-cab-ci
+          - rc-twinhan1027
+          - rc-videomate-k100
+          - rc-videomate-s350
+          - rc-videomate-tv-pvr
+          - rc-winfast
+          - rc-winfast-usbii-deluxe
+          - rc-xbox-dvd
+          - rc-zx-irdec
diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.txt b/Documentation/devicetree/bindings/media/rockchip-vpu.txt
index 35dc464..339252d 100644
--- a/Documentation/devicetree/bindings/media/rockchip-vpu.txt
+++ b/Documentation/devicetree/bindings/media/rockchip-vpu.txt
@@ -1,14 +1,17 @@
 device-tree bindings for rockchip VPU codec
 
 Rockchip (Video Processing Unit) present in various Rockchip platforms,
-such as RK3288 and RK3399.
+such as RK3288, RK3328 and RK3399.
 
 Required properties:
 - compatible: value should be one of the following
 		"rockchip,rk3288-vpu";
+		"rockchip,rk3328-vpu";
 		"rockchip,rk3399-vpu";
 - interrupts: encoding and decoding interrupt specifiers
-- interrupt-names: should be "vepu" and "vdpu"
+- interrupt-names: should be
+		"vepu", "vdpu" on RK3288 and RK3399,
+		"vdpu" on RK3328.
 - clocks: phandle to VPU aclk, hclk clocks
 - clock-names: should be "aclk" and "hclk"
 - power-domains: phandle to power domain node
@@ -27,3 +30,14 @@
 		power-domains = <&power RK3288_PD_VIDEO>;
 		iommus = <&vpu_mmu>;
 	};
+
+	vpu: video-codec@ff350000 {
+		compatible = "rockchip,rk3328-vpu";
+		reg = <0x0 0xff350000 0x0 0x800>;
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vdpu";
+		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+		clock-names = "aclk", "hclk";
+		power-domains = <&power RK3328_PD_VPU>;
+		iommus = <&vpu_mmu>;
+	};
diff --git a/Documentation/devicetree/bindings/media/sunxi-ir.txt b/Documentation/devicetree/bindings/media/sunxi-ir.txt
deleted file mode 100644
index 2780989..0000000
--- a/Documentation/devicetree/bindings/media/sunxi-ir.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Device-Tree bindings for SUNXI IR controller found in sunXi SoC family
-
-Required properties:
-- compatible	    : "allwinner,sun4i-a10-ir" or "allwinner,sun5i-a13-ir"
-- clocks	    : list of clock specifiers, corresponding to
-		      entries in clock-names property;
-- clock-names	    : should contain "apb" and "ir" entries;
-- interrupts	    : should contain IR IRQ number;
-- reg		    : should contain IO map address for IR.
-
-Optional properties:
-- linux,rc-map-name: see rc.txt file in the same directory.
-- resets : phandle + reset specifier pair
-- clock-frequency  : IR Receiver clock frequency, in Hertz. Defaults to 8 MHz
-		     if missing.
-
-Example:
-
-ir0: ir@1c21800 {
-	compatible = "allwinner,sun4i-a10-ir";
-	clocks = <&apb0_gates 6>, <&ir0_clk>;
-	clock-names = "apb", "ir";
-	clock-frequency = <3000000>;
-	resets = <&apb0_rst 1>;
-	interrupts = <0 5 1>;
-	reg = <0x01C21800 0x40>;
-	linux,rc-map-name = "rc-rc6-mce";
-};
diff --git a/Documentation/media/kapi/csi2.rst b/Documentation/media/kapi/csi2.rst
index a7e75e2..030a5c4 100644
--- a/Documentation/media/kapi/csi2.rst
+++ b/Documentation/media/kapi/csi2.rst
@@ -49,9 +49,13 @@
 
 The transmitter drivers must, if possible, configure the CSI-2
 transmitter to *LP-11 mode* whenever the transmitter is powered on but
-not active. Some transmitters do this automatically but some have to
-be explicitly programmed to do so, and some are unable to do so
-altogether due to hardware constraints.
+not active, and maintain *LP-11 mode* until stream on. Only at stream
+on should the transmitter activate the clock on the clock lane and
+transition to *HS mode*.
+
+Some transmitters do this automatically but some have to be explicitly
+programmed to do so, and some are unable to do so altogether due to
+hardware constraints.
 
 Stopping the transmitter
 ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,3 +76,10 @@
 :c:type:`v4l2_subdev_core_ops`->s_power() callback. This may take
 place either indirectly by using :c:func:`v4l2_pipeline_pm_use` or
 directly.
+
+Formats
+-------
+
+The media bus pixel codes document parallel formats. Should the pixel data be
+transported over a serial bus, the media bus pixel code that describes a
+parallel format that transfers a sample on a single clock cycle is used.
diff --git a/Documentation/media/kapi/v4l2-dev.rst b/Documentation/media/kapi/v4l2-dev.rst
index b359f18..4c5a15c 100644
--- a/Documentation/media/kapi/v4l2-dev.rst
+++ b/Documentation/media/kapi/v4l2-dev.rst
@@ -288,6 +288,7 @@
 0x08  Log the read and write file operations and the VIDIOC_QBUF and
       VIDIOC_DQBUF ioctls.
 0x10  Log the poll file operation.
+0x20  Log error and messages in the control operations.
 ===== ================================================================
 
 Video device cleanup
diff --git a/Documentation/media/uapi/rc/lirc-dev-intro.rst b/Documentation/media/uapi/rc/lirc-dev-intro.rst
index 1a901d8..b68c016 100644
--- a/Documentation/media/uapi/rc/lirc-dev-intro.rst
+++ b/Documentation/media/uapi/rc/lirc-dev-intro.rst
@@ -20,6 +20,9 @@
 file_operations defined on it. With respect to transporting raw IR and
 decoded scancodes to and fro, the essential fops are read, write and ioctl.
 
+It is also possible to attach a BPF program to a LIRC device for decoding
+raw IR into scancodes.
+
 Example dmesg output upon a driver registering w/LIRC:
 
 .. code-block:: none
@@ -34,6 +37,16 @@
     $ ls -l /dev/lirc*
     crw-rw---- 1 root root 248, 0 Jul 2 22:20 /dev/lirc0
 
+Note that the package `v4l-utils <https://git.linuxtv.org/v4l-utils.git/>`_
+contains tools for working with LIRC devices:
+
+ - ir-ctl: can receive raw IR and transmit IR, as well as query LIRC
+   device features.
+
+ - ir-keytable: can load keymaps; allows you to set IR kernel protocols; load
+   BPF IR decoders and test IR decoding. Some BPF IR decoders are also
+   provided.
+
 .. _lirc_modes:
 
 **********
@@ -53,11 +66,12 @@
 
     For transmitting (aka sending), create a ``struct lirc_scancode`` with
     the desired scancode set in the ``scancode`` member, :c:type:`rc_proto`
-    set the IR protocol, and all other members set to 0. Write this struct to
-    the lirc device.
+    set to the :ref:`IR protocol <Remote_controllers_Protocols>`, and all other
+    members set to 0. Write this struct to the lirc device.
 
-    For receiving, you read ``struct lirc_scancode`` from the lirc device,
-    with ``scancode`` set to the received scancode and the IR protocol
+    For receiving, you read ``struct lirc_scancode`` from the LIRC device.
+    The ``scancode`` field is set to the received scancode and the
+    :ref:`IR protocol <Remote_controllers_Protocols>` is set in
     :c:type:`rc_proto`. If the scancode maps to a valid key code, this is set
     in the ``keycode`` field, else it is set to ``KEY_RESERVED``.
 
@@ -129,12 +143,29 @@
 
     This mode is used only for IR send.
 
+********************
+BPF based IR decoder
+********************
 
-**************************
-Remote Controller protocol
-**************************
+The kernel has support for decoding the most common
+:ref:`IR protocols <Remote_controllers_Protocols>`, but there
+are many protocols which are not supported. To support these, it is possible
+to load an BPF program which does the decoding. This can only be done on
+LIRC devices which support reading raw IR.
 
-An enum :c:type:`rc_proto` in the :ref:`lirc_header` lists all the
-supported IR protocols:
+First, using the `bpf(2)`_ syscall with the ``BPF_LOAD_PROG`` argument,
+program must be loaded of type ``BPF_PROG_TYPE_LIRC_MODE2``. Once attached
+to the LIRC device, this program will be called for each pulse, space or
+timeout event on the LIRC device. The context for the BPF program is a
+pointer to a unsigned int, which is a :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`
+value. When the program has decoded the scancode, it can be submitted using
+the BPF functions ``bpf_rc_keydown()`` or ``bpf_rc_repeat()``. Mouse or pointer
+movements can be reported using ``bpf_rc_pointer_rel()``.
 
-.. kernel-doc:: include/uapi/linux/lirc.h
+Once you have the file descriptor for the ``BPF_PROG_TYPE_LIRC_MODE2`` BPF
+program, it can be attached to the LIRC device using the `bpf(2)`_ syscall.
+The target must be the file descriptor for the LIRC device, and the
+attach type must be ``BPF_LIRC_MODE2``. No more than 64 BPF programs can be
+attached to a single LIRC device at a time.
+
+.. _bpf(2): http://man7.org/linux/man-pages/man2/bpf.2.html
diff --git a/Documentation/media/uapi/rc/lirc-read.rst b/Documentation/media/uapi/rc/lirc-read.rst
index a8fedfa..256e520 100644
--- a/Documentation/media/uapi/rc/lirc-read.rst
+++ b/Documentation/media/uapi/rc/lirc-read.rst
@@ -62,7 +62,8 @@
 Alternatively, :ref:`LIRC_MODE_SCANCODE <lirc-mode-scancode>` can be available,
 in this mode scancodes which are either decoded by software decoders, or
 by hardware decoders. The :c:type:`rc_proto` member is set to the
-protocol used for transmission, and ``scancode`` to the decoded scancode,
+:ref:`IR protocol <Remote_controllers_Protocols>`
+used for transmission, and ``scancode`` to the decoded scancode,
 and the ``keycode`` set to the keycode or ``KEY_RESERVED``.
 
 
diff --git a/Documentation/media/uapi/rc/lirc-write.rst b/Documentation/media/uapi/rc/lirc-write.rst
index 6adf5dd..eafe132 100644
--- a/Documentation/media/uapi/rc/lirc-write.rst
+++ b/Documentation/media/uapi/rc/lirc-write.rst
@@ -64,7 +64,8 @@
 When in :ref:`LIRC_MODE_SCANCODE <lirc-mode-scancode>` mode, one
 ``struct lirc_scancode`` must be written to the chardev at a time, else
 ``EINVAL`` is returned. Set the desired scancode in the ``scancode`` member,
-and the protocol in the :c:type:`rc_proto`: member. All other members must be
+and the :ref:`IR protocol <Remote_controllers_Protocols>` in the
+:c:type:`rc_proto`: member. All other members must be
 set to 0, else ``EINVAL`` is returned. If there is no protocol encoder
 for the protocol or the scancode is not valid for the specified protocol,
 ``EINVAL`` is returned. The write function blocks until the scancode
diff --git a/Documentation/media/uapi/rc/rc-protos.rst b/Documentation/media/uapi/rc/rc-protos.rst
new file mode 100644
index 0000000..b250ebe3
--- /dev/null
+++ b/Documentation/media/uapi/rc/rc-protos.rst
@@ -0,0 +1,456 @@
+.. SPDX-License-Identifier: GPL-2.0
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _Remote_controllers_Protocols:
+
+*****************************************
+Remote Controller Protocols and Scancodes
+*****************************************
+
+IR is encoded as a series of pulses and spaces, using a protocol. These
+protocols can encode e.g. an address (which device should respond) and a
+command: what it should do. The values for these are not always consistent
+across different devices for a given protocol.
+
+Therefore out the output of the IR decoder is a scancode; a single u32
+value. Using keymap tables this can be mapped to linux key codes.
+
+Other things can be encoded too. Some IR protocols encode a toggle bit; this
+is to distinguish whether the same button is being held down, or has been
+released and pressed again. If has been released and pressed again, the
+toggle bit will invert from one IR message to the next.
+
+Some remotes have a pointer-type device which can used to control the
+mouse; some air conditioning systems can have their target temperature
+target set in IR.
+
+The following are the protocols the kernel knows about and also lists
+how scancodes are encoded for each protocol.
+
+rc-5 (RC_PROTO_RC5)
+-------------------
+
+This IR protocol uses manchester encoding to encode 14 bits. There is a
+detailed description here https://www.sbprojects.net/knowledge/ir/rc5.php.
+
+The scancode encoding is *not* consistent with the lirc daemon (lircd) rc5
+protocol, or the manchester BPF decoder.
+
+.. flat-table:: rc5 bits scancode mapping
+   :widths:       1 1 2
+
+   * - rc-5 bit
+
+     - scancode bit
+
+     - description
+
+   * - 1
+
+     - none
+
+     - Start bit, always set
+
+   * - 1
+
+     - 6 (inverted)
+
+     - 2nd start bit in rc5,  re-used as 6th command bit
+
+   * - 1
+
+     - none
+
+     - Toggle bit
+
+   * - 5
+
+     - 8 to 13
+
+     - Address
+
+   * - 6
+
+     - 0 to 5
+
+     - Command
+
+There is a variant of rc5 called either rc5x or extended rc5
+where there the second stop bit is the 6th commmand bit, but inverted.
+This is done so it the scancodes and encoding is compatible with existing
+schemes. This bit is stored in bit 6 of the scancode, inverted. This is
+done to keep it compatible with plain rc-5 where there are two start bits.
+
+rc-5-sz (RC_PROTO_RC5_SZ)
+-------------------------
+This is much like rc-5 but one bit longer. The scancode is encoded
+differently.
+
+.. flat-table:: rc-5-sz bits scancode mapping
+   :widths:       1 1 2
+
+   * - rc-5-sz bits
+
+     - scancode bit
+
+     - description
+
+   * - 1
+
+     - none
+
+     - Start bit, always set
+
+   * - 1
+
+     - 13
+
+     - Address bit
+
+   * - 1
+
+     - none
+
+     - Toggle bit
+
+   * - 6
+
+     - 6 to 11
+
+     - Address
+
+   * - 6
+
+     - 0 to 5
+
+     - Command
+
+rc-5x-20 (RC_PROTO_RC5X_20)
+---------------------------
+
+This rc-5 extended to encoded 20 bits. The is a 3555 microseconds space
+after the 8th bit.
+
+.. flat-table:: rc-5x-20 bits scancode mapping
+   :widths:       1 1 2
+
+   * - rc-5-sz bits
+
+     - scancode bit
+
+     - description
+
+   * - 1
+
+     - none
+
+     - Start bit, always set
+
+   * - 1
+
+     - 14
+
+     - Address bit
+
+   * - 1
+
+     - none
+
+     - Toggle bit
+
+   * - 5
+
+     - 16 to 20
+
+     - Address
+
+   * - 6
+
+     - 8 to 13
+
+     - Address
+
+   * - 6
+
+     - 0 to 5
+
+     - Command
+
+
+jvc (RC_PROTO_JVC)
+------------------
+
+The jvc protocol is much like nec, without the inverted values. It is
+described here https://www.sbprojects.net/knowledge/ir/jvc.php.
+
+The scancode is a 16 bits value, where the address is the lower 8 bits
+and the command the higher 8 bits; this is reversed from IR order.
+
+sony-12 (RC_PROTO_SONY12)
+-------------------------
+
+The sony protocol is a pulse-width encoding. There are three variants,
+which just differ in number of bits and scancode encoding.
+
+.. flat-table:: sony-12 bits scancode mapping
+   :widths:       1 1 2
+
+   * - sony-12 bits
+
+     - scancode bit
+
+     - description
+
+   * - 5
+
+     - 16 to 20
+
+     - device
+
+   * - 7
+
+     - 0 to 6
+
+     - function
+
+sony-15 (RC_PROTO_SONY15)
+-------------------------
+
+The sony protocol is a pulse-width encoding. There are three variants,
+which just differ in number of bits and scancode encoding.
+
+.. flat-table:: sony-12 bits scancode mapping
+   :widths:       1 1 2
+
+   * - sony-12 bits
+
+     - scancode bit
+
+     - description
+
+   * - 8
+
+     - 16 to 23
+
+     - device
+
+   * - 7
+
+     - 0 to 6
+
+     - function
+
+sony-20 (RC_PROTO_SONY20)
+-------------------------
+
+The sony protocol is a pulse-width encoding. There are three variants,
+which just differ in number of bits and scancode encoding.
+
+.. flat-table:: sony-20 bits scancode mapping
+   :widths:       1 1 2
+
+   * - sony-20 bits
+
+     - scancode bit
+
+     - description
+
+   * - 5
+
+     - 16 to 20
+
+     - device
+
+   * - 7
+
+     - 0 to 7
+
+     - device
+
+   * - 8
+
+     - 8 to 15
+
+     - extended bits
+
+nec (RC_PROTO_NEC)
+------------------
+
+The nec protocol encodes an 8 bit address and an 8 bit command. It is
+described here https://www.sbprojects.net/knowledge/ir/nec.php. Note
+that the protocol sends least significant bit first.
+
+As a check, the nec protocol sends the address and command twice; the
+second time it is inverted. This is done for verification.
+
+A plain nec IR message has 16 bits; the high 8 bits are the address
+and the low 8 bits are the command.
+
+nec-x (RC_PROTO_NECX)
+---------------------
+
+Extended nec has a 16 bit address and a 8 bit command. This is encoded
+as a 24 bit value as you would expect, with the lower 8 bits the command
+and the upper 16 bits the address.
+
+nec-32 (RC_PROTO_NEC32)
+-----------------------
+
+nec-32 does not send an inverted address or an inverted command; the
+entire message, all 32 bits, are used.
+
+For this to be decoded correctly, the second 8 bits must not be the
+inverted value of the first, and also the last 8 bits must not be the
+inverted value of the third 8 bit value.
+
+The scancode has a somewhat unusual encoding.
+
+.. flat-table:: nec-32 bits scancode mapping
+
+   * - nec-32 bits
+
+     - scancode bit
+
+   * - First 8 bits
+
+     - 16 to 23
+
+   * - Second 8 bits
+
+     - 24 to 31
+
+   * - Third 8 bits
+
+     - 0 to 7
+
+   * - Fourth 8 bits
+
+     - 8 to 15
+
+sanyo (RC_PROTO_SANYO)
+----------------------
+
+The sanyo protocol is like the nec protocol, but with 13 bits address
+rather than 8 bits. Both the address and the command are followed by
+their inverted versions, but these are not present in the scancodes.
+
+Bis 8 to 20 of the scancode is the 13 bits address, and the lower 8
+bits are the command.
+
+mcir2-kbd (RC_PROTO_MCIR2_KBD)
+------------------------------
+
+This protocol is generated by the Microsoft MCE keyboard for keyboard
+events. Refer to the ir-mce_kbd-decoder.c to see how it is encoded.
+
+mcir2-mse (RC_PROTO_MCIR2_MSE)
+------------------------------
+
+This protocol is generated by the Microsoft MCE keyboard for pointer
+events. Refer to the ir-mce_kbd-decoder.c to see how it is encoded.
+
+rc-6-0 (RC_PROTO_RC6_0)
+-----------------------
+
+This is the rc-6 in mode 0. rc-6 is described here
+https://www.sbprojects.net/knowledge/ir/rc6.php.
+The scancode is the exact 16 bits as in the protocol. There is also a
+toggle bit.
+
+rc-6-6a-20 (RC_PROTO_RC6_6A_20)
+-------------------------------
+
+This is the rc-6 in mode 6a, 20 bits. rc-6 is described here
+https://www.sbprojects.net/knowledge/ir/rc6.php.
+The scancode is the exact 20 bits
+as in the protocol. There is also a toggle bit.
+
+rc-6-6a-24 (RC_PROTO_RC6_6A_24)
+-------------------------------
+
+This is the rc-6 in mode 6a, 24 bits. rc-6 is described here
+https://www.sbprojects.net/knowledge/ir/rc6.php.
+The scancode is the exact 24 bits
+as in the protocol. There is also a toggle bit.
+
+rc-6-6a-32 (RC_PROTO_RC6_6A_32)
+-------------------------------
+
+This is the rc-6 in mode 6a, 32 bits. rc-6 is described here
+https://www.sbprojects.net/knowledge/ir/rc6.php.
+The upper 16 bits are the vendor,
+and the lower 16 bits are the vendor-specific bits. This protocol is
+for the non-Microsoft MCE variant (vendor != 0x800f).
+
+
+rc-6-mce (RC_PROTO_RC6_MCE)
+---------------------------
+
+This is the rc-6 in mode 6a, 32 bits. The upper 16 bits are the vendor,
+and the lower 16 bits are the vendor-specific bits. This protocol is
+for the Microsoft MCE variant (vendor = 0x800f). The toggle bit in the
+protocol itself is ignored, and the 16th bit should be takes as the toggle
+bit.
+
+sharp (RC_PROTO_SHARP)
+----------------------
+
+This is a protocol used by Sharp VCRs, is described here
+https://www.sbprojects.net/knowledge/ir/sharp.php. There is a very long
+(40ms) space between the normal and inverted values, and some IR receivers
+cannot decode this.
+
+There is a 5 bit address and a 8 bit command. In the scancode the address is
+in bits 8 to 12, and the command in bits 0 to 7.
+
+xmp (RC_PROTO_XMP)
+------------------
+
+This protocol has several versions and only version 1 is supported. Refer
+to the decoder (ir-xmp-decoder.c) to see how it is encoded.
+
+
+cec (RC_PROTO_CEC)
+------------------
+
+This is not an IR protocol, this is a protocol over CEC. The CEC
+infrastructure uses rc-core for handling CEC commands, so that they
+can easily be remapped.
+
+imon (RC_PROTO_IMON)
+--------------------
+
+This protocol is used by Antec Veris/SoundGraph iMON remotes.
+
+The protocol
+describes both button presses and pointer movements. The protocol encodes
+31 bits, and the scancode is simply the 31 bits with the top bit always 0.
+
+rc-mm-12 (RC_PROTO_RCMM12)
+--------------------------
+
+The rc-mm protocol is described here
+https://www.sbprojects.net/knowledge/ir/rcmm.php. The scancode is simply
+the 12 bits.
+
+rc-mm-24 (RC_PROTO_RCMM24)
+--------------------------
+
+The rc-mm protocol is described here
+https://www.sbprojects.net/knowledge/ir/rcmm.php. The scancode is simply
+the 24 bits.
+
+rc-mm-32 (RC_PROTO_RCMM32)
+--------------------------
+
+The rc-mm protocol is described here
+https://www.sbprojects.net/knowledge/ir/rcmm.php. The scancode is simply
+the 32 bits.
+
+xbox-dvd (RC_PROTO_XBOX_DVD)
+----------------------------
+
+This protocol is used by XBox DVD Remote, which was made for the original
+XBox. There is no in-kernel decoder or encoder for this protocol. The usb
+device decodes the protocol. There is a BPF decoder available in v4l-utils.
diff --git a/Documentation/media/uapi/rc/remote_controllers.rst b/Documentation/media/uapi/rc/remote_controllers.rst
index 3051f7a..20e0f98 100644
--- a/Documentation/media/uapi/rc/remote_controllers.rst
+++ b/Documentation/media/uapi/rc/remote_controllers.rst
@@ -27,6 +27,7 @@
 
     rc-intro
     rc-sysfs-nodes
+    rc-protos
     rc-tables
     rc-table-change
     lirc-dev
diff --git a/Documentation/media/uapi/v4l/biblio.rst b/Documentation/media/uapi/v4l/biblio.rst
index 8f4eb88..ad2ff25 100644
--- a/Documentation/media/uapi/v4l/biblio.rst
+++ b/Documentation/media/uapi/v4l/biblio.rst
@@ -395,3 +395,13 @@
 :title:     Color Imaging: Fundamentals and Applications
 
 :author:    Erik Reinhard et al.
+
+.. _vp8:
+
+VP8
+===
+
+
+:title:     RFC 6386: "VP8 Data Format and Decoding Guide"
+
+:author:    J. Bankoski et al.
diff --git a/Documentation/media/uapi/v4l/control.rst b/Documentation/media/uapi/v4l/control.rst
index 71417bb..ef62e08 100644
--- a/Documentation/media/uapi/v4l/control.rst
+++ b/Documentation/media/uapi/v4l/control.rst
@@ -295,7 +295,7 @@
     Sets the alpha color component. When a capture device (or capture
     queue of a mem-to-mem device) produces a frame format that includes
     an alpha component (e.g.
-    :ref:`packed RGB image formats <rgb-formats>`) and the alpha value
+    :ref:`packed RGB image formats <pixfmt-rgb>`) and the alpha value
     is not defined by the device or the mem-to-mem input data this
     control lets you select the alpha component value of all pixels.
     When an output device (or output queue of a mem-to-mem device)
diff --git a/Documentation/media/uapi/v4l/dev-decoder.rst b/Documentation/media/uapi/v4l/dev-decoder.rst
new file mode 100644
index 0000000..606b549
--- /dev/null
+++ b/Documentation/media/uapi/v4l/dev-decoder.rst
@@ -0,0 +1,1101 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _decoder:
+
+*************************************************
+Memory-to-Memory Stateful Video Decoder Interface
+*************************************************
+
+A stateful video decoder takes complete chunks of the bytestream (e.g. Annex-B
+H.264/HEVC stream, raw VP8/9 stream) and decodes them into raw video frames in
+display order. The decoder is expected not to require any additional information
+from the client to process these buffers.
+
+Performing software parsing, processing etc. of the stream in the driver in
+order to support this interface is strongly discouraged. In case such
+operations are needed, use of the Stateless Video Decoder Interface (in
+development) is strongly advised.
+
+Conventions and Notations Used in This Document
+===============================================
+
+1. The general V4L2 API rules apply if not specified in this document
+   otherwise.
+
+2. The meaning of words "must", "may", "should", etc. is as per `RFC
+   2119 <https://tools.ietf.org/html/rfc2119>`_.
+
+3. All steps not marked "optional" are required.
+
+4. :c:func:`VIDIOC_G_EXT_CTRLS` and :c:func:`VIDIOC_S_EXT_CTRLS` may be used
+   interchangeably with :c:func:`VIDIOC_G_CTRL` and :c:func:`VIDIOC_S_CTRL`,
+   unless specified otherwise.
+
+5. Single-planar API (see :ref:`planar-apis`) and applicable structures may be
+   used interchangeably with multi-planar API, unless specified otherwise,
+   depending on decoder capabilities and following the general V4L2 guidelines.
+
+6. i = [a..b]: sequence of integers from a to b, inclusive, i.e. i =
+   [0..2]: i = 0, 1, 2.
+
+7. Given an ``OUTPUT`` buffer A, then A’ represents a buffer on the ``CAPTURE``
+   queue containing data that resulted from processing buffer A.
+
+.. _decoder-glossary:
+
+Glossary
+========
+
+CAPTURE
+   the destination buffer queue; for decoders, the queue of buffers containing
+   decoded frames; for encoders, the queue of buffers containing an encoded
+   bytestream; ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` or
+   ``V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE``; data is captured from the hardware
+   into ``CAPTURE`` buffers.
+
+client
+   the application communicating with the decoder or encoder implementing
+   this interface.
+
+coded format
+   encoded/compressed video bytestream format (e.g. H.264, VP8, etc.); see
+   also: raw format.
+
+coded height
+   height for given coded resolution.
+
+coded resolution
+   stream resolution in pixels aligned to codec and hardware requirements;
+   typically visible resolution rounded up to full macroblocks;
+   see also: visible resolution.
+
+coded width
+   width for given coded resolution.
+
+decode order
+   the order in which frames are decoded; may differ from display order if the
+   coded format includes a feature of frame reordering; for decoders,
+   ``OUTPUT`` buffers must be queued by the client in decode order; for
+   encoders ``CAPTURE`` buffers must be returned by the encoder in decode order.
+
+destination
+   data resulting from the decode process; see ``CAPTURE``.
+
+display order
+   the order in which frames must be displayed; for encoders, ``OUTPUT``
+   buffers must be queued by the client in display order; for decoders,
+   ``CAPTURE`` buffers must be returned by the decoder in display order.
+
+DPB
+   Decoded Picture Buffer; an H.264/HEVC term for a buffer that stores a decoded
+   raw frame available for reference in further decoding steps.
+
+EOS
+   end of stream.
+
+IDR
+   Instantaneous Decoder Refresh; a type of a keyframe in an H.264/HEVC-encoded
+   stream, which clears the list of earlier reference frames (DPBs).
+
+keyframe
+   an encoded frame that does not reference frames decoded earlier, i.e.
+   can be decoded fully on its own.
+
+macroblock
+   a processing unit in image and video compression formats based on linear
+   block transforms (e.g. H.264, VP8, VP9); codec-specific, but for most of
+   popular codecs the size is 16x16 samples (pixels).
+
+OUTPUT
+   the source buffer queue; for decoders, the queue of buffers containing
+   an encoded bytestream; for encoders, the queue of buffers containing raw
+   frames; ``V4L2_BUF_TYPE_VIDEO_OUTPUT`` or
+   ``V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE``; the hardware is fed with data
+   from ``OUTPUT`` buffers.
+
+PPS
+   Picture Parameter Set; a type of metadata entity in an H.264/HEVC bytestream.
+
+raw format
+   uncompressed format containing raw pixel data (e.g. YUV, RGB formats).
+
+resume point
+   a point in the bytestream from which decoding may start/continue, without
+   any previous state/data present, e.g.: a keyframe (VP8/VP9) or
+   SPS/PPS/IDR sequence (H.264/HEVC); a resume point is required to start decode
+   of a new stream, or to resume decoding after a seek.
+
+source
+   data fed to the decoder or encoder; see ``OUTPUT``.
+
+source height
+   height in pixels for given source resolution; relevant to encoders only.
+
+source resolution
+   resolution in pixels of source frames being source to the encoder and
+   subject to further cropping to the bounds of visible resolution; relevant to
+   encoders only.
+
+source width
+   width in pixels for given source resolution; relevant to encoders only.
+
+SPS
+   Sequence Parameter Set; a type of metadata entity in an H.264/HEVC bytestream.
+
+stream metadata
+   additional (non-visual) information contained inside encoded bytestream;
+   for example: coded resolution, visible resolution, codec profile.
+
+visible height
+   height for given visible resolution; display height.
+
+visible resolution
+   stream resolution of the visible picture, in pixels, to be used for
+   display purposes; must be smaller or equal to coded resolution;
+   display resolution.
+
+visible width
+   width for given visible resolution; display width.
+
+State Machine
+=============
+
+.. kernel-render:: DOT
+   :alt: DOT digraph of decoder state machine
+   :caption: Decoder State Machine
+
+   digraph decoder_state_machine {
+       node [shape = doublecircle, label="Decoding"] Decoding;
+
+       node [shape = circle, label="Initialization"] Initialization;
+       node [shape = circle, label="Capture\nsetup"] CaptureSetup;
+       node [shape = circle, label="Dynamic\nResolution\nChange"] ResChange;
+       node [shape = circle, label="Stopped"] Stopped;
+       node [shape = circle, label="Drain"] Drain;
+       node [shape = circle, label="Seek"] Seek;
+       node [shape = circle, label="End of Stream"] EoS;
+
+       node [shape = point]; qi
+       qi -> Initialization [ label = "open()" ];
+
+       Initialization -> CaptureSetup [ label = "CAPTURE\nformat\nestablished" ];
+
+       CaptureSetup -> Stopped [ label = "CAPTURE\nbuffers\nready" ];
+
+       Decoding -> ResChange [ label = "Stream\nresolution\nchange" ];
+       Decoding -> Drain [ label = "V4L2_DEC_CMD_STOP" ];
+       Decoding -> EoS [ label = "EoS mark\nin the stream" ];
+       Decoding -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
+       Decoding -> Stopped [ label = "VIDIOC_STREAMOFF(CAPTURE)" ];
+       Decoding -> Decoding;
+
+       ResChange -> CaptureSetup [ label = "CAPTURE\nformat\nestablished" ];
+       ResChange -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
+
+       EoS -> Drain [ label = "Implicit\ndrain" ];
+
+       Drain -> Stopped [ label = "All CAPTURE\nbuffers dequeued\nor\nVIDIOC_STREAMOFF(CAPTURE)" ];
+       Drain -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
+
+       Seek -> Decoding [ label = "VIDIOC_STREAMON(OUTPUT)" ];
+       Seek -> Initialization [ label = "VIDIOC_REQBUFS(OUTPUT, 0)" ];
+
+       Stopped -> Decoding [ label = "V4L2_DEC_CMD_START\nor\nVIDIOC_STREAMON(CAPTURE)" ];
+       Stopped -> Seek [ label = "VIDIOC_STREAMOFF(OUTPUT)" ];
+   }
+
+Querying Capabilities
+=====================
+
+1. To enumerate the set of coded formats supported by the decoder, the
+   client may call :c:func:`VIDIOC_ENUM_FMT` on ``OUTPUT``.
+
+   * The full set of supported formats will be returned, regardless of the
+     format set on ``CAPTURE``.
+   * Check the flags field of :c:type:`v4l2_fmtdesc` for more information
+     about the decoder's capabilities with respect to each coded format.
+     In particular whether or not the decoder has a full-fledged bytestream
+     parser and if the decoder supports dynamic resolution changes.
+
+2. To enumerate the set of supported raw formats, the client may call
+   :c:func:`VIDIOC_ENUM_FMT` on ``CAPTURE``.
+
+   * Only the formats supported for the format currently active on ``OUTPUT``
+     will be returned.
+
+   * In order to enumerate raw formats supported by a given coded format,
+     the client must first set that coded format on ``OUTPUT`` and then
+     enumerate formats on ``CAPTURE``.
+
+3. The client may use :c:func:`VIDIOC_ENUM_FRAMESIZES` to detect supported
+   resolutions for a given format, passing desired pixel format in
+   :c:type:`v4l2_frmsizeenum` ``pixel_format``.
+
+   * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a coded pixel
+     format will include all possible coded resolutions supported by the
+     decoder for given coded pixel format.
+
+   * Values returned by :c:func:`VIDIOC_ENUM_FRAMESIZES` for a raw pixel format
+     will include all possible frame buffer resolutions supported by the
+     decoder for given raw pixel format and the coded format currently set on
+     ``OUTPUT``.
+
+4. Supported profiles and levels for the coded format currently set on
+   ``OUTPUT``, if applicable, may be queried using their respective controls
+   via :c:func:`VIDIOC_QUERYCTRL`.
+
+Initialization
+==============
+
+1. Set the coded format on ``OUTPUT`` via :c:func:`VIDIOC_S_FMT`
+
+   * **Required fields:**
+
+     ``type``
+         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+     ``pixelformat``
+         a coded pixel format.
+
+     ``width``, ``height``
+         coded resolution of the stream; required only if it cannot be parsed
+         from the stream for the given coded format; otherwise the decoder will
+         use this resolution as a placeholder resolution that will likely change
+         as soon as it can parse the actual coded resolution from the stream.
+
+     ``sizeimage``
+         desired size of ``OUTPUT`` buffers; the decoder may adjust it to
+         match hardware requirements.
+
+     other fields
+         follow standard semantics.
+
+   * **Return fields:**
+
+     ``sizeimage``
+         adjusted size of ``OUTPUT`` buffers.
+
+   * The ``CAPTURE`` format will be updated with an appropriate frame buffer
+     resolution instantly based on the width and height returned by
+     :c:func:`VIDIOC_S_FMT`.
+     However, for coded formats that include stream resolution information,
+     after the decoder is done parsing the information from the stream, it will
+     update the ``CAPTURE`` format with new values and signal a source change
+     event, regardless of whether they match the values set by the client or
+     not.
+
+   .. important::
+
+      Changing the ``OUTPUT`` format may change the currently set ``CAPTURE``
+      format. How the new ``CAPTURE`` format is determined is up to the decoder
+      and the client must ensure it matches its needs afterwards.
+
+2.  Allocate source (bytestream) buffers via :c:func:`VIDIOC_REQBUFS` on
+    ``OUTPUT``.
+
+    * **Required fields:**
+
+      ``count``
+          requested number of buffers to allocate; greater than zero.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+      ``memory``
+          follows standard semantics.
+
+    * **Return fields:**
+
+      ``count``
+          the actual number of buffers allocated.
+
+    .. warning::
+
+       The actual number of allocated buffers may differ from the ``count``
+       given. The client must check the updated value of ``count`` after the
+       call returns.
+
+    Alternatively, :c:func:`VIDIOC_CREATE_BUFS` on the ``OUTPUT`` queue can be
+    used to have more control over buffer allocation.
+
+    * **Required fields:**
+
+      ``count``
+          requested number of buffers to allocate; greater than zero.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+      ``memory``
+          follows standard semantics.
+
+      ``format``
+          follows standard semantics.
+
+    * **Return fields:**
+
+      ``count``
+          adjusted to the number of allocated buffers.
+
+    .. warning::
+
+       The actual number of allocated buffers may differ from the ``count``
+       given. The client must check the updated value of ``count`` after the
+       call returns.
+
+3.  Start streaming on the ``OUTPUT`` queue via :c:func:`VIDIOC_STREAMON`.
+
+4.  **This step only applies to coded formats that contain resolution information
+    in the stream.** Continue queuing/dequeuing bytestream buffers to/from the
+    ``OUTPUT`` queue via :c:func:`VIDIOC_QBUF` and :c:func:`VIDIOC_DQBUF`. The
+    buffers will be processed and returned to the client in order, until
+    required metadata to configure the ``CAPTURE`` queue are found. This is
+    indicated by the decoder sending a ``V4L2_EVENT_SOURCE_CHANGE`` event with
+    ``changes`` set to ``V4L2_EVENT_SRC_CH_RESOLUTION``.
+
+    * It is not an error if the first buffer does not contain enough data for
+      this to occur. Processing of the buffers will continue as long as more
+      data is needed.
+
+    * If data in a buffer that triggers the event is required to decode the
+      first frame, it will not be returned to the client, until the
+      initialization sequence completes and the frame is decoded.
+
+    * If the client has not set the coded resolution of the stream on its own,
+      calling :c:func:`VIDIOC_G_FMT`, :c:func:`VIDIOC_S_FMT`,
+      :c:func:`VIDIOC_TRY_FMT` or :c:func:`VIDIOC_REQBUFS` on the ``CAPTURE``
+      queue will not return the real values for the stream until a
+      ``V4L2_EVENT_SOURCE_CHANGE`` event with ``changes`` set to
+      ``V4L2_EVENT_SRC_CH_RESOLUTION`` is signaled.
+
+    .. important::
+
+       Any client query issued after the decoder queues the event will return
+       values applying to the just parsed stream, including queue formats,
+       selection rectangles and controls.
+
+    .. note::
+
+       A client capable of acquiring stream parameters from the bytestream on
+       its own may attempt to set the width and height of the ``OUTPUT`` format
+       to non-zero values matching the coded size of the stream, skip this step
+       and continue with the `Capture Setup` sequence. However, it must not
+       rely on any driver queries regarding stream parameters, such as
+       selection rectangles and controls, since the decoder has not parsed them
+       from the stream yet. If the values configured by the client do not match
+       those parsed by the decoder, a `Dynamic Resolution Change` will be
+       triggered to reconfigure them.
+
+    .. note::
+
+       No decoded frames are produced during this phase.
+
+5.  Continue with the `Capture Setup` sequence.
+
+Capture Setup
+=============
+
+1.  Call :c:func:`VIDIOC_G_FMT` on the ``CAPTURE`` queue to get format for the
+    destination buffers parsed/decoded from the bytestream.
+
+    * **Required fields:**
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+    * **Return fields:**
+
+      ``width``, ``height``
+          frame buffer resolution for the decoded frames.
+
+      ``pixelformat``
+          pixel format for decoded frames.
+
+      ``num_planes`` (for _MPLANE ``type`` only)
+          number of planes for pixelformat.
+
+      ``sizeimage``, ``bytesperline``
+          as per standard semantics; matching frame buffer format.
+
+    .. note::
+
+       The value of ``pixelformat`` may be any pixel format supported by the
+       decoder for the current stream. The decoder should choose a
+       preferred/optimal format for the default configuration. For example, a
+       YUV format may be preferred over an RGB format if an additional
+       conversion step would be required for the latter.
+
+2.  **Optional.** Acquire the visible resolution via
+    :c:func:`VIDIOC_G_SELECTION`.
+
+    * **Required fields:**
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``target``
+          set to ``V4L2_SEL_TGT_COMPOSE``.
+
+    * **Return fields:**
+
+      ``r.left``, ``r.top``, ``r.width``, ``r.height``
+          the visible rectangle; it must fit within the frame buffer resolution
+          returned by :c:func:`VIDIOC_G_FMT` on ``CAPTURE``.
+
+    * The following selection targets are supported on ``CAPTURE``:
+
+      ``V4L2_SEL_TGT_CROP_BOUNDS``
+          corresponds to the coded resolution of the stream.
+
+      ``V4L2_SEL_TGT_CROP_DEFAULT``
+          the rectangle covering the part of the ``CAPTURE`` buffer that
+          contains meaningful picture data (visible area); width and height
+          will be equal to the visible resolution of the stream.
+
+      ``V4L2_SEL_TGT_CROP``
+          the rectangle within the coded resolution to be output to
+          ``CAPTURE``; defaults to ``V4L2_SEL_TGT_CROP_DEFAULT``; read-only on
+          hardware without additional compose/scaling capabilities.
+
+      ``V4L2_SEL_TGT_COMPOSE_BOUNDS``
+          the maximum rectangle within a ``CAPTURE`` buffer, which the cropped
+          frame can be composed into; equal to ``V4L2_SEL_TGT_CROP`` if the
+          hardware does not support compose/scaling.
+
+      ``V4L2_SEL_TGT_COMPOSE_DEFAULT``
+          equal to ``V4L2_SEL_TGT_CROP``.
+
+      ``V4L2_SEL_TGT_COMPOSE``
+          the rectangle inside a ``CAPTURE`` buffer into which the cropped
+          frame is written; defaults to ``V4L2_SEL_TGT_COMPOSE_DEFAULT``;
+          read-only on hardware without additional compose/scaling capabilities.
+
+      ``V4L2_SEL_TGT_COMPOSE_PADDED``
+          the rectangle inside a ``CAPTURE`` buffer which is overwritten by the
+          hardware; equal to ``V4L2_SEL_TGT_COMPOSE`` if the hardware does not
+          write padding pixels.
+
+    .. warning::
+
+       The values are guaranteed to be meaningful only after the decoder
+       successfully parses the stream metadata. The client must not rely on the
+       query before that happens.
+
+3.  **Optional.** Enumerate ``CAPTURE`` formats via :c:func:`VIDIOC_ENUM_FMT` on
+    the ``CAPTURE`` queue. Once the stream information is parsed and known, the
+    client may use this ioctl to discover which raw formats are supported for
+    given stream and select one of them via :c:func:`VIDIOC_S_FMT`.
+
+    .. important::
+
+       The decoder will return only formats supported for the currently
+       established coded format, as per the ``OUTPUT`` format and/or stream
+       metadata parsed in this initialization sequence, even if more formats
+       may be supported by the decoder in general. In other words, the set
+       returned will be a subset of the initial query mentioned in the
+       `Querying Capabilities` section.
+
+       For example, a decoder may support YUV and RGB formats for resolutions
+       1920x1088 and lower, but only YUV for higher resolutions (due to
+       hardware limitations). After parsing a resolution of 1920x1088 or lower,
+       :c:func:`VIDIOC_ENUM_FMT` may return a set of YUV and RGB pixel formats,
+       but after parsing resolution higher than 1920x1088, the decoder will not
+       return RGB, unsupported for this resolution.
+
+       However, subsequent resolution change event triggered after
+       discovering a resolution change within the same stream may switch
+       the stream into a lower resolution and :c:func:`VIDIOC_ENUM_FMT`
+       would return RGB formats again in that case.
+
+4.  **Optional.** Set the ``CAPTURE`` format via :c:func:`VIDIOC_S_FMT` on the
+    ``CAPTURE`` queue. The client may choose a different format than
+    selected/suggested by the decoder in :c:func:`VIDIOC_G_FMT`.
+
+    * **Required fields:**
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``pixelformat``
+          a raw pixel format.
+
+      ``width``, ``height``
+         frame buffer resolution of the decoded stream; typically unchanged from
+	 what was returned with :c:func:`VIDIOC_G_FMT`, but it may be different
+	 if the hardware supports composition and/or scaling.
+
+   * Setting the ``CAPTURE`` format will reset the compose selection rectangles
+     to their default values, based on the new resolution, as described in the
+     previous step.
+
+5. **Optional.** Set the compose rectangle via :c:func:`VIDIOC_S_SELECTION` on
+   the ``CAPTURE`` queue if it is desired and if the decoder has compose and/or
+   scaling capabilities.
+
+   * **Required fields:**
+
+     ``type``
+         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+     ``target``
+         set to ``V4L2_SEL_TGT_COMPOSE``.
+
+     ``r.left``, ``r.top``, ``r.width``, ``r.height``
+         the rectangle inside a ``CAPTURE`` buffer into which the cropped
+         frame is written; defaults to ``V4L2_SEL_TGT_COMPOSE_DEFAULT``;
+         read-only on hardware without additional compose/scaling capabilities.
+
+   * **Return fields:**
+
+     ``r.left``, ``r.top``, ``r.width``, ``r.height``
+         the visible rectangle; it must fit within the frame buffer resolution
+         returned by :c:func:`VIDIOC_G_FMT` on ``CAPTURE``.
+
+   .. warning::
+
+      The decoder may adjust the compose rectangle to the nearest
+      supported one to meet codec and hardware requirements. The client needs
+      to check the adjusted rectangle returned by :c:func:`VIDIOC_S_SELECTION`.
+
+6.  If all the following conditions are met, the client may resume the decoding
+    instantly:
+
+    * ``sizeimage`` of the new format (determined in previous steps) is less
+      than or equal to the size of currently allocated buffers,
+
+    * the number of buffers currently allocated is greater than or equal to the
+      minimum number of buffers acquired in previous steps. To fulfill this
+      requirement, the client may use :c:func:`VIDIOC_CREATE_BUFS` to add new
+      buffers.
+
+    In that case, the remaining steps do not apply and the client may resume
+    the decoding by one of the following actions:
+
+    * if the ``CAPTURE`` queue is streaming, call :c:func:`VIDIOC_DECODER_CMD`
+      with the ``V4L2_DEC_CMD_START`` command,
+
+    * if the ``CAPTURE`` queue is not streaming, call :c:func:`VIDIOC_STREAMON`
+      on the ``CAPTURE`` queue.
+
+    However, if the client intends to change the buffer set, to lower
+    memory usage or for any other reasons, it may be achieved by following
+    the steps below.
+
+7.  **If the** ``CAPTURE`` **queue is streaming,** keep queuing and dequeuing
+    buffers on the ``CAPTURE`` queue until a buffer marked with the
+    ``V4L2_BUF_FLAG_LAST`` flag is dequeued.
+
+8.  **If the** ``CAPTURE`` **queue is streaming,** call :c:func:`VIDIOC_STREAMOFF`
+    on the ``CAPTURE`` queue to stop streaming.
+
+    .. warning::
+
+       The ``OUTPUT`` queue must remain streaming. Calling
+       :c:func:`VIDIOC_STREAMOFF` on it would abort the sequence and trigger a
+       seek.
+
+9.  **If the** ``CAPTURE`` **queue has buffers allocated,** free the ``CAPTURE``
+    buffers using :c:func:`VIDIOC_REQBUFS`.
+
+    * **Required fields:**
+
+      ``count``
+          set to 0.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``memory``
+          follows standard semantics.
+
+10. Allocate ``CAPTURE`` buffers via :c:func:`VIDIOC_REQBUFS` on the
+    ``CAPTURE`` queue.
+
+    * **Required fields:**
+
+      ``count``
+          requested number of buffers to allocate; greater than zero.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``memory``
+          follows standard semantics.
+
+    * **Return fields:**
+
+      ``count``
+          actual number of buffers allocated.
+
+    .. warning::
+
+       The actual number of allocated buffers may differ from the ``count``
+       given. The client must check the updated value of ``count`` after the
+       call returns.
+
+    .. note::
+
+       To allocate more than the minimum number of buffers (for pipeline
+       depth), the client may query the ``V4L2_CID_MIN_BUFFERS_FOR_CAPTURE``
+       control to get the minimum number of buffers required, and pass the
+       obtained value plus the number of additional buffers needed in the
+       ``count`` field to :c:func:`VIDIOC_REQBUFS`.
+
+    Alternatively, :c:func:`VIDIOC_CREATE_BUFS` on the ``CAPTURE`` queue can be
+    used to have more control over buffer allocation. For example, by
+    allocating buffers larger than the current ``CAPTURE`` format, future
+    resolution changes can be accommodated.
+
+    * **Required fields:**
+
+      ``count``
+          requested number of buffers to allocate; greater than zero.
+
+      ``type``
+          a ``V4L2_BUF_TYPE_*`` enum appropriate for ``CAPTURE``.
+
+      ``memory``
+          follows standard semantics.
+
+      ``format``
+          a format representing the maximum framebuffer resolution to be
+          accommodated by newly allocated buffers.
+
+    * **Return fields:**
+
+      ``count``
+          adjusted to the number of allocated buffers.
+
+    .. warning::
+
+        The actual number of allocated buffers may differ from the ``count``
+        given. The client must check the updated value of ``count`` after the
+        call returns.
+
+    .. note::
+
+       To allocate buffers for a format different than parsed from the stream
+       metadata, the client must proceed as follows, before the metadata
+       parsing is initiated:
+
+       * set width and height of the ``OUTPUT`` format to desired coded resolution to
+         let the decoder configure the ``CAPTURE`` format appropriately,
+
+       * query the ``CAPTURE`` format using :c:func:`VIDIOC_G_FMT` and save it
+         until this step.
+
+       The format obtained in the query may be then used with
+       :c:func:`VIDIOC_CREATE_BUFS` in this step to allocate the buffers.
+
+11. Call :c:func:`VIDIOC_STREAMON` on the ``CAPTURE`` queue to start decoding
+    frames.
+
+Decoding
+========
+
+This state is reached after the `Capture Setup` sequence finishes successfully.
+In this state, the client queues and dequeues buffers to both queues via
+:c:func:`VIDIOC_QBUF` and :c:func:`VIDIOC_DQBUF`, following the standard
+semantics.
+
+The content of the source ``OUTPUT`` buffers depends on the active coded pixel
+format and may be affected by codec-specific extended controls, as stated in
+the documentation of each format.
+
+Both queues operate independently, following the standard behavior of V4L2
+buffer queues and memory-to-memory devices. In addition, the order of decoded
+frames dequeued from the ``CAPTURE`` queue may differ from the order of queuing
+coded frames to the ``OUTPUT`` queue, due to properties of the selected coded
+format, e.g. frame reordering.
+
+The client must not assume any direct relationship between ``CAPTURE``
+and ``OUTPUT`` buffers and any specific timing of buffers becoming
+available to dequeue. Specifically:
+
+* a buffer queued to ``OUTPUT`` may result in no buffers being produced
+  on ``CAPTURE`` (e.g. if it does not contain encoded data, or if only
+  metadata syntax structures are present in it),
+
+* a buffer queued to ``OUTPUT`` may result in more than one buffer produced
+  on ``CAPTURE`` (if the encoded data contained more than one frame, or if
+  returning a decoded frame allowed the decoder to return a frame that
+  preceded it in decode, but succeeded it in the display order),
+
+* a buffer queued to ``OUTPUT`` may result in a buffer being produced on
+  ``CAPTURE`` later into decode process, and/or after processing further
+  ``OUTPUT`` buffers, or be returned out of order, e.g. if display
+  reordering is used,
+
+* buffers may become available on the ``CAPTURE`` queue without additional
+  buffers queued to ``OUTPUT`` (e.g. during drain or ``EOS``), because of the
+  ``OUTPUT`` buffers queued in the past whose decoding results are only
+  available at later time, due to specifics of the decoding process.
+
+.. note::
+
+   To allow matching decoded ``CAPTURE`` buffers with ``OUTPUT`` buffers they
+   originated from, the client can set the ``timestamp`` field of the
+   :c:type:`v4l2_buffer` struct when queuing an ``OUTPUT`` buffer. The
+   ``CAPTURE`` buffer(s), which resulted from decoding that ``OUTPUT`` buffer
+   will have their ``timestamp`` field set to the same value when dequeued.
+
+   In addition to the straightforward case of one ``OUTPUT`` buffer producing
+   one ``CAPTURE`` buffer, the following cases are defined:
+
+   * one ``OUTPUT`` buffer generates multiple ``CAPTURE`` buffers: the same
+     ``OUTPUT`` timestamp will be copied to multiple ``CAPTURE`` buffers.
+
+   * multiple ``OUTPUT`` buffers generate one ``CAPTURE`` buffer: timestamp of
+     the ``OUTPUT`` buffer queued first will be copied.
+
+   * the decoding order differs from the display order (i.e. the ``CAPTURE``
+     buffers are out-of-order compared to the ``OUTPUT`` buffers): ``CAPTURE``
+     timestamps will not retain the order of ``OUTPUT`` timestamps.
+
+During the decoding, the decoder may initiate one of the special sequences, as
+listed below. The sequences will result in the decoder returning all the
+``CAPTURE`` buffers that originated from all the ``OUTPUT`` buffers processed
+before the sequence started. Last of the buffers will have the
+``V4L2_BUF_FLAG_LAST`` flag set. To determine the sequence to follow, the client
+must check if there is any pending event and:
+
+* if a ``V4L2_EVENT_SOURCE_CHANGE`` event with ``changes`` set to
+  ``V4L2_EVENT_SRC_CH_RESOLUTION`` is pending, the `Dynamic Resolution
+  Change` sequence needs to be followed,
+
+* if a ``V4L2_EVENT_EOS`` event is pending, the `End of Stream` sequence needs
+  to be followed.
+
+Some of the sequences can be intermixed with each other and need to be handled
+as they happen. The exact operation is documented for each sequence.
+
+Should a decoding error occur, it will be reported to the client with the level
+of details depending on the decoder capabilities. Specifically:
+
+* the CAPTURE buffer that contains the results of the failed decode operation
+  will be returned with the V4L2_BUF_FLAG_ERROR flag set,
+
+* if the decoder is able to precisely report the OUTPUT buffer that triggered
+  the error, such buffer will be returned with the V4L2_BUF_FLAG_ERROR flag
+  set.
+
+In case of a fatal failure that does not allow the decoding to continue, any
+further operations on corresponding decoder file handle will return the -EIO
+error code. The client may close the file handle and open a new one, or
+alternatively reinitialize the instance by stopping streaming on both queues,
+releasing all buffers and performing the Initialization sequence again.
+
+Seek
+====
+
+Seek is controlled by the ``OUTPUT`` queue, as it is the source of coded data.
+The seek does not require any specific operation on the ``CAPTURE`` queue, but
+it may be affected as per normal decoder operation.
+
+1. Stop the ``OUTPUT`` queue to begin the seek sequence via
+   :c:func:`VIDIOC_STREAMOFF`.
+
+   * **Required fields:**
+
+     ``type``
+         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+   * The decoder will drop all the pending ``OUTPUT`` buffers and they must be
+     treated as returned to the client (following standard semantics).
+
+2. Restart the ``OUTPUT`` queue via :c:func:`VIDIOC_STREAMON`
+
+   * **Required fields:**
+
+     ``type``
+         a ``V4L2_BUF_TYPE_*`` enum appropriate for ``OUTPUT``.
+
+   * The decoder will start accepting new source bytestream buffers after the
+     call returns.
+
+3. Start queuing buffers containing coded data after the seek to the ``OUTPUT``
+   queue until a suitable resume point is found.
+
+   .. note::
+
+      There is no requirement to begin queuing coded data starting exactly
+      from a resume point (e.g. SPS or a keyframe). Any queued ``OUTPUT``
+      buffers will be processed and returned to the client until a suitable
+      resume point is found.  While looking for a resume point, the decoder
+      should not produce any decoded frames into ``CAPTURE`` buffers.
+
+      Some hardware is known to mishandle seeks to a non-resume point. Such an
+      operation may result in an unspecified number of corrupted decoded frames
+      being made available on the ``CAPTURE`` queue. Drivers must ensure that
+      no fatal decoding errors or crashes occur, and implement any necessary
+      handling and workarounds for hardware issues related to seek operations.
+
+   .. warning::
+
+      In case of the H.264/HEVC codec, the client must take care not to seek
+      over a change of SPS/PPS. Even though the target frame could be a
+      keyframe, the stale SPS/PPS inside decoder state would lead to undefined
+      results when decoding. Although the decoder must handle that case without
+      a crash or a fatal decode error, the client must not expect a sensible
+      decode output.
+
+      If the hardware can detect such corrupted decoded frames, then
+      corresponding buffers will be returned to the client with the
+      V4L2_BUF_FLAG_ERROR set. See the `Decoding` section for further
+      description of decode error reporting.
+
+4. After a resume point is found, the decoder will start returning ``CAPTURE``
+   buffers containing decoded frames.
+
+.. important::
+
+   A seek may result in the `Dynamic Resolution Change` sequence being
+   initiated, due to the seek target having decoding parameters different from
+   the part of the stream decoded before the seek. The sequence must be handled
+   as per normal decoder operation.
+
+.. warning::
+
+   It is not specified when the ``CAPTURE`` queue starts producing buffers
+   containing decoded data from the ``OUTPUT`` buffers queued after the seek,
+   as it operates independently from the ``OUTPUT`` queue.
+
+   The decoder may return a number of remaining ``CAPTURE`` buffers containing
+   decoded frames originating from the ``OUTPUT`` buffers queued before the
+   seek sequence is performed.
+
+   The ``VIDIOC_STREAMOFF`` operation discards any remaining queued
+   ``OUTPUT`` buffers, which means that not all of the ``OUTPUT`` buffers
+   queued before the seek sequence may have matching ``CAPTURE`` buffers
+   produced.  For example, given the sequence of operations on the
+   ``OUTPUT`` queue:
+
+     QBUF(A), QBUF(B), STREAMOFF(), STREAMON(), QBUF(G), QBUF(H),
+
+   any of the following results on the ``CAPTURE`` queue is allowed:
+
+     {A’, B’, G’, H’}, {A’, G’, H’}, {G’, H’}.
+
+   To determine the CAPTURE buffer containing the first decoded frame after the
+   seek, the client may observe the timestamps to match the CAPTURE and OUTPUT
+   buffers or use V4L2_DEC_CMD_STOP and V4L2_DEC_CMD_START to drain the
+   decoder.
+
+.. note::
+
+   To achieve instantaneous seek, the client may restart streaming on the
+   ``CAPTURE`` queue too to discard decoded, but not yet dequeued buffers.
+
+Dynamic Resolution Change
+=========================
+
+Streams that include resolution metadata in the bytestream may require switching
+to a different resolution during the decoding.
+
+.. note::
+
+   Not all decoders can detect resolution changes. Those that do set the
+   ``V4L2_FMT_FLAG_DYN_RESOLUTION`` flag for the coded format when
+   :c:func:`VIDIOC_ENUM_FMT` is called.
+
+The sequence starts when the decoder detects a coded frame with one or more of
+the following parameters different from those previously established (and
+reflected by corresponding queries):
+
+* coded resolution (``OUTPUT`` width and height),
+
+* visible resolution (selection rectangles),
+
+* the minimum number of buffers needed for decoding.
+
+Whenever that happens, the decoder must proceed as follows:
+
+1.  After encountering a resolution change in the stream, the decoder sends a
+    ``V4L2_EVENT_SOURCE_CHANGE`` event with ``changes`` set to
+    ``V4L2_EVENT_SRC_CH_RESOLUTION``.
+
+    .. important::
+
+       Any client query issued after the decoder queues the event will return
+       values applying to the stream after the resolution change, including
+       queue formats, selection rectangles and controls.
+
+2.  The decoder will then process and decode all remaining buffers from before
+    the resolution change point.
+
+    * The last buffer from before the change must be marked with the
+      ``V4L2_BUF_FLAG_LAST`` flag, similarly to the `Drain` sequence above.
+
+    .. warning::
+
+       The last buffer may be empty (with :c:type:`v4l2_buffer` ``bytesused``
+       = 0) and in that case it must be ignored by the client, as it does not
+       contain a decoded frame.
+
+    .. note::
+
+       Any attempt to dequeue more ``CAPTURE`` buffers beyond the buffer marked
+       with ``V4L2_BUF_FLAG_LAST`` will result in a -EPIPE error from
+       :c:func:`VIDIOC_DQBUF`.
+
+The client must continue the sequence as described below to continue the
+decoding process.
+
+1.  Dequeue the source change event.
+
+    .. important::
+
+       A source change triggers an implicit decoder drain, similar to the
+       explicit `Drain` sequence. The decoder is stopped after it completes.
+       The decoding process must be resumed with either a pair of calls to
+       :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
+       ``CAPTURE`` queue, or a call to :c:func:`VIDIOC_DECODER_CMD` with the
+       ``V4L2_DEC_CMD_START`` command.
+
+2.  Continue with the `Capture Setup` sequence.
+
+.. note::
+
+   During the resolution change sequence, the ``OUTPUT`` queue must remain
+   streaming. Calling :c:func:`VIDIOC_STREAMOFF` on the ``OUTPUT`` queue would
+   abort the sequence and initiate a seek.
+
+   In principle, the ``OUTPUT`` queue operates separately from the ``CAPTURE``
+   queue and this remains true for the duration of the entire resolution change
+   sequence as well.
+
+   The client should, for best performance and simplicity, keep queuing/dequeuing
+   buffers to/from the ``OUTPUT`` queue even while processing this sequence.
+
+Drain
+=====
+
+To ensure that all queued ``OUTPUT`` buffers have been processed and related
+``CAPTURE`` buffers are given to the client, the client must follow the drain
+sequence described below. After the drain sequence ends, the client has
+received all decoded frames for all ``OUTPUT`` buffers queued before the
+sequence was started.
+
+1. Begin drain by issuing :c:func:`VIDIOC_DECODER_CMD`.
+
+   * **Required fields:**
+
+     ``cmd``
+         set to ``V4L2_DEC_CMD_STOP``.
+
+     ``flags``
+         set to 0.
+
+     ``pts``
+         set to 0.
+
+   .. warning::
+
+      The sequence can be only initiated if both ``OUTPUT`` and ``CAPTURE``
+      queues are streaming. For compatibility reasons, the call to
+      :c:func:`VIDIOC_DECODER_CMD` will not fail even if any of the queues is
+      not streaming, but at the same time it will not initiate the `Drain`
+      sequence and so the steps described below would not be applicable.
+
+2. Any ``OUTPUT`` buffers queued by the client before the
+   :c:func:`VIDIOC_DECODER_CMD` was issued will be processed and decoded as
+   normal. The client must continue to handle both queues independently,
+   similarly to normal decode operation. This includes:
+
+   * handling any operations triggered as a result of processing those buffers,
+     such as the `Dynamic Resolution Change` sequence, before continuing with
+     the drain sequence,
+
+   * queuing and dequeuing ``CAPTURE`` buffers, until a buffer marked with the
+     ``V4L2_BUF_FLAG_LAST`` flag is dequeued,
+
+     .. warning::
+
+        The last buffer may be empty (with :c:type:`v4l2_buffer`
+        ``bytesused`` = 0) and in that case it must be ignored by the client,
+        as it does not contain a decoded frame.
+
+     .. note::
+
+        Any attempt to dequeue more ``CAPTURE`` buffers beyond the buffer
+        marked with ``V4L2_BUF_FLAG_LAST`` will result in a -EPIPE error from
+        :c:func:`VIDIOC_DQBUF`.
+
+   * dequeuing processed ``OUTPUT`` buffers, until all the buffers queued
+     before the ``V4L2_DEC_CMD_STOP`` command are dequeued,
+
+   * dequeuing the ``V4L2_EVENT_EOS`` event, if the client subscribed to it.
+
+   .. note::
+
+      For backwards compatibility, the decoder will signal a ``V4L2_EVENT_EOS``
+      event when the last frame has been decoded and all frames are ready to be
+      dequeued. It is a deprecated behavior and the client must not rely on it.
+      The ``V4L2_BUF_FLAG_LAST`` buffer flag should be used instead.
+
+3. Once all the ``OUTPUT`` buffers queued before the ``V4L2_DEC_CMD_STOP`` call
+   are dequeued and the last ``CAPTURE`` buffer is dequeued, the decoder is
+   stopped and it will accept, but not process, any newly queued ``OUTPUT``
+   buffers until the client issues any of the following operations:
+
+   * ``V4L2_DEC_CMD_START`` - the decoder will not be reset and will resume
+     operation normally, with all the state from before the drain,
+
+   * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
+     ``CAPTURE`` queue - the decoder will resume the operation normally,
+     however any ``CAPTURE`` buffers still in the queue will be returned to the
+     client,
+
+   * a pair of :c:func:`VIDIOC_STREAMOFF` and :c:func:`VIDIOC_STREAMON` on the
+     ``OUTPUT`` queue - any pending source buffers will be returned to the
+     client and the `Seek` sequence will be triggered.
+
+.. note::
+
+   Once the drain sequence is initiated, the client needs to drive it to
+   completion, as described by the steps above, unless it aborts the process by
+   issuing :c:func:`VIDIOC_STREAMOFF` on any of the ``OUTPUT`` or ``CAPTURE``
+   queues.  The client is not allowed to issue ``V4L2_DEC_CMD_START`` or
+   ``V4L2_DEC_CMD_STOP`` again while the drain sequence is in progress and they
+   will fail with -EBUSY error code if attempted.
+
+   Although mandatory, the availability of decoder commands may be queried
+   using :c:func:`VIDIOC_TRY_DECODER_CMD`.
+
+End of Stream
+=============
+
+If the decoder encounters an end of stream marking in the stream, the decoder
+will initiate the `Drain` sequence, which the client must handle as described
+above, skipping the initial :c:func:`VIDIOC_DECODER_CMD`.
+
+Commit Points
+=============
+
+Setting formats and allocating buffers trigger changes in the behavior of the
+decoder.
+
+1. Setting the format on the ``OUTPUT`` queue may change the set of formats
+   supported/advertised on the ``CAPTURE`` queue. In particular, it also means
+   that the ``CAPTURE`` format may be reset and the client must not rely on the
+   previously set format being preserved.
+
+2. Enumerating formats on the ``CAPTURE`` queue always returns only formats
+   supported for the current ``OUTPUT`` format.
+
+3. Setting the format on the ``CAPTURE`` queue does not change the list of
+   formats available on the ``OUTPUT`` queue. An attempt to set a ``CAPTURE``
+   format that is not supported for the currently selected ``OUTPUT`` format
+   will result in the decoder adjusting the requested ``CAPTURE`` format to a
+   supported one.
+
+4. Enumerating formats on the ``OUTPUT`` queue always returns the full set of
+   supported coded formats, irrespectively of the current ``CAPTURE`` format.
+
+5. While buffers are allocated on any of the ``OUTPUT`` or ``CAPTURE`` queues,
+   the client must not change the format on the ``OUTPUT`` queue. Drivers will
+   return the -EBUSY error code for any such format change attempt.
+
+To summarize, setting formats and allocation must always start with the
+``OUTPUT`` queue and the ``OUTPUT`` queue is the master that governs the
+set of supported formats for the ``CAPTURE`` queue.
diff --git a/Documentation/media/uapi/v4l/dev-mem2mem.rst b/Documentation/media/uapi/v4l/dev-mem2mem.rst
index 67a9808..caa05f5 100644
--- a/Documentation/media/uapi/v4l/dev-mem2mem.rst
+++ b/Documentation/media/uapi/v4l/dev-mem2mem.rst
@@ -39,4 +39,10 @@
 One of the most common memory-to-memory device is the codec. Codecs
 are more complicated than most and require additional setup for
 their codec parameters. This is done through codec controls.
-See :ref:`mpeg-controls`.
+See :ref:`mpeg-controls`. More details on how to use codec memory-to-memory
+devices are given in the following sections.
+
+.. toctree::
+    :maxdepth: 1
+
+    dev-decoder
diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
index d6ea2ff..bc5dd8e 100644
--- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
+++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
@@ -1748,6 +1748,14 @@
       - ``size``
       -
     * - __u32
+      - ``start_byte_offset``
+        Offset (in bytes) from the beginning of the OUTPUT buffer to the start
+        of the slice. If the slice starts with a start code, then this is the
+        offset to such start code. When operating in slice-based decoding mode
+        (see :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field should
+        be set to 0. When operating in frame-based decoding mode, this field
+        should be 0 for the first slice.
+    * - __u32
       - ``header_bit_size``
       -
     * - __u16
@@ -1930,19 +1938,13 @@
       -
     * - __u16
       - ``num_slices``
-      - Number of slices needed to decode the current frame
+      - Number of slices needed to decode the current frame/field. When
+        operating in slice-based decoding mode (see
+        :c:type:`v4l2_mpeg_video_h264_decode_mode`), this field
+        should always be set to one.
     * - __u16
       - ``nal_ref_idc``
       - NAL reference ID value coming from the NAL Unit header
-    * - __u8
-      - ``ref_pic_list_p0[32]``
-      - Backward reference list used by P-frames in the original bitstream order
-    * - __u8
-      - ``ref_pic_list_b0[32]``
-      - Backward reference list used by B-frames in the original bitstream order
-    * - __u8
-      - ``ref_pic_list_b1[32]``
-      - Forward reference list used by B-frames in the original bitstream order
     * - __s32
       - ``top_field_order_cnt``
       - Picture Order Count for the coded top field
@@ -2021,6 +2023,83 @@
       - 0x00000004
       - The DPB entry is a long term reference frame
 
+``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE (enum)``
+    Specifies the decoding mode to use. Currently exposes slice-based and
+    frame-based decoding but new modes might be added later on.
+    This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE
+    pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE
+    are required to set this control in order to specify the decoding mode
+    that is expected for the buffer.
+    Drivers may expose a single or multiple decoding modes, depending
+    on what they can support.
+
+    .. note::
+
+       This menu control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_mpeg_video_h264_decode_mode
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED``
+      - 0
+      - Decoding is done at the slice granularity.
+        In this mode, ``num_slices`` field in struct
+        :c:type:`v4l2_ctrl_h264_decode_params` should be set to 1,
+        and ``start_byte_offset`` in struct
+        :c:type:`v4l2_ctrl_h264_slice_params` should be set to 0.
+        The OUTPUT buffer must contain a single slice.
+    * - ``V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED``
+      - 1
+      - Decoding is done at the frame granularity.
+        In this mode, ``num_slices`` field in struct
+        :c:type:`v4l2_ctrl_h264_decode_params` should be set to the number
+        of slices in the frame, and ``start_byte_offset`` in struct
+        :c:type:`v4l2_ctrl_h264_slice_params` should be set accordingly
+        for each slice. For the first slice, ``start_byte_offset`` should
+        be zero.
+        The OUTPUT buffer must contain all slices needed to decode the
+        frame. The OUTPUT buffer must also contain both fields.
+
+``V4L2_CID_MPEG_VIDEO_H264_START_CODE (enum)``
+    Specifies the H264 slice start code expected for each slice.
+    This control is used as a modifier for V4L2_PIX_FMT_H264_SLICE
+    pixel format. Applications that support V4L2_PIX_FMT_H264_SLICE
+    are required to set this control in order to specify the start code
+    that is expected for the buffer.
+    Drivers may expose a single or multiple start codes, depending
+    on what they can support.
+
+    .. note::
+
+       This menu control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_mpeg_video_h264_start_code
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_MPEG_VIDEO_H264_START_CODE_NONE``
+      - 0
+      - Selecting this value specifies that H264 slices are passed
+        to the driver without any start code.
+    * - ``V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B``
+      - 1
+      - Selecting this value specifies that H264 slices are expected
+        to be prefixed by Annex B start codes. According to :ref:`h264`
+        valid start codes can be 3-bytes 0x000001 or 4-bytes 0x00000001.
+
 .. _v4l2-mpeg-mpeg2:
 
 ``V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS (struct)``
@@ -2234,6 +2313,329 @@
     Quantization parameter for a P frame for FWHT. Valid range: from 1
     to 31.
 
+.. _v4l2-mpeg-vp8:
+
+``V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER (struct)``
+    Specifies the frame parameters for the associated VP8 parsed frame data.
+    This includes the necessary parameters for
+    configuring a stateless hardware decoding pipeline for VP8.
+    The bitstream parameters are defined according to :ref:`vp8`.
+
+    .. note::
+
+       This compound control is not yet part of the public kernel API and
+       it is expected to change.
+
+.. c:type:: v4l2_ctrl_vp8_frame_header
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{5.8cm}|p{4.8cm}|p{6.6cm}|
+
+.. flat-table:: struct v4l2_ctrl_vp8_frame_header
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - struct :c:type:`v4l2_vp8_segment_header`
+      - ``segment_header``
+      - Structure with segment-based adjustments metadata.
+    * - struct :c:type:`v4l2_vp8_loopfilter_header`
+      - ``loopfilter_header``
+      - Structure with loop filter level adjustments metadata.
+    * - struct :c:type:`v4l2_vp8_quantization_header`
+      - ``quant_header``
+      - Structure with VP8 dequantization indices metadata.
+    * - struct :c:type:`v4l2_vp8_entropy_header`
+      - ``entropy_header``
+      - Structure with VP8 entropy coder probabilities metadata.
+    * - struct :c:type:`v4l2_vp8_entropy_coder_state`
+      - ``coder_state``
+      - Structure with VP8 entropy coder state.
+    * - __u16
+      - ``width``
+      - The width of the frame. Must be set for all frames.
+    * - __u16
+      - ``height``
+      - The height of the frame. Must be set for all frames.
+    * - __u8
+      - ``horizontal_scale``
+      - Horizontal scaling factor.
+    * - __u8
+      - ``vertical_scaling factor``
+      - Vertical scale.
+    * - __u8
+      - ``version``
+      - Bitstream version.
+    * - __u8
+      - ``prob_skip_false``
+      - Indicates the probability that the macroblock is not skipped.
+    * - __u8
+      - ``prob_intra``
+      - Indicates the probability that a macroblock is intra-predicted.
+    * - __u8
+      - ``prob_last``
+      - Indicates the probability that the last reference frame is used
+        for inter-prediction
+    * - __u8
+      - ``prob_gf``
+      - Indicates the probability that the golden reference frame is used
+        for inter-prediction
+    * - __u8
+      - ``num_dct_parts``
+      - Number of DCT coefficients partitions. Must be one of: 1, 2, 4, or 8.
+    * - __u32
+      - ``first_part_size``
+      - Size of the first partition, i.e. the control partition.
+    * - __u32
+      - ``first_part_header_bits``
+      - Size in bits of the first partition header portion.
+    * - __u32
+      - ``dct_part_sizes[8]``
+      - DCT coefficients sizes.
+    * - __u64
+      - ``last_frame_ts``
+      - Timestamp for the V4L2 capture buffer to use as last reference frame, used
+        with inter-coded frames. The timestamp refers to the ``timestamp`` field in
+	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+	function to convert the struct :c:type:`timeval` in struct
+	:c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``golden_frame_ts``
+      - Timestamp for the V4L2 capture buffer to use as last reference frame, used
+        with inter-coded frames. The timestamp refers to the ``timestamp`` field in
+	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+	function to convert the struct :c:type:`timeval` in struct
+	:c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``alt_frame_ts``
+      - Timestamp for the V4L2 capture buffer to use as alternate reference frame, used
+        with inter-coded frames. The timestamp refers to the ``timestamp`` field in
+	struct :c:type:`v4l2_buffer`. Use the :c:func:`v4l2_timeval_to_ns()`
+	function to convert the struct :c:type:`timeval` in struct
+	:c:type:`v4l2_buffer` to a __u64.
+    * - __u64
+      - ``flags``
+      - See :ref:`Frame Header Flags <vp8_frame_header_flags>`
+
+.. _vp8_frame_header_flags:
+
+``Frame Header Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME``
+      - 0x01
+      - Indicates if the frame is a key frame.
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_EXPERIMENTAL``
+      - 0x02
+      - Experimental bitstream.
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_SHOW_FRAME``
+      - 0x04
+      - Show frame flag, indicates if the frame is for display.
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF``
+      - 0x08
+      - Enable/disable skipping of macroblocks with no non-zero coefficients.
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN``
+      - 0x10
+      - Sign of motion vectors when the golden frame is referenced.
+    * - ``V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT``
+      - 0x20
+      - Sign of motion vectors when the alt frame is referenced.
+
+.. c:type:: v4l2_vp8_entropy_coder_state
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp8_entropy_coder_state
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``range``
+      -
+    * - __u8
+      - ``value``
+      -
+    * - __u8
+      - ``bit_count``
+      -
+    * - __u8
+      - ``padding``
+      - Applications and drivers must set this to zero.
+
+.. c:type:: v4l2_vp8_segment_header
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp8_segment_header
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __s8
+      - ``quant_update[4]``
+      - Signed quantizer value update.
+    * - __s8
+      - ``lf_update[4]``
+      - Signed loop filter level value update.
+    * - __u8
+      - ``segment_probs[3]``
+      - Segment probabilities.
+    * - __u8
+      - ``padding``
+      - Applications and drivers must set this to zero.
+    * - __u32
+      - ``flags``
+      - See :ref:`Segment Header Flags <vp8_segment_header_flags>`
+
+.. _vp8_segment_header_flags:
+
+``Segment Header Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED``
+      - 0x01
+      - Enable/disable segment-based adjustments.
+    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP``
+      - 0x02
+      - Indicates if the macroblock segmentation map is updated in this frame.
+    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_FEATURE_DATA``
+      - 0x04
+      - Indicates if the segment feature data is updated in this frame.
+    * - ``V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE``
+      - 0x08
+      - If is set, the segment feature data mode is delta-value.
+        If cleared, it's absolute-value.
+
+.. c:type:: v4l2_vp8_loopfilter_header
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp8_loopfilter_header
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __s8
+      - ``ref_frm_delta[4]``
+      - Reference adjustment (signed) delta value.
+    * - __s8
+      - ``mb_mode_delta[4]``
+      - Macroblock prediction mode adjustment (signed) delta value.
+    * - __u8
+      - ``sharpness_level``
+      - Sharpness level
+    * - __u8
+      - ``level``
+      - Filter level
+    * - __u16
+      - ``padding``
+      - Applications and drivers must set this to zero.
+    * - __u32
+      - ``flags``
+      - See :ref:`Loopfilter Header Flags <vp8_loopfilter_header_flags>`
+
+.. _vp8_loopfilter_header_flags:
+
+``Loopfilter Header Flags``
+
+.. cssclass:: longtable
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - ``V4L2_VP8_LF_HEADER_ADJ_ENABLE``
+      - 0x01
+      - Enable/disable macroblock-level loop filter adjustment.
+    * - ``V4L2_VP8_LF_HEADER_DELTA_UPDATE``
+      - 0x02
+      - Indicates if the delta values used in an adjustment are updated.
+    * - ``V4L2_VP8_LF_FILTER_TYPE_SIMPLE``
+      - 0x04
+      - If set, indicates the filter type is simple.
+        If cleared, the filter type is normal.
+
+.. c:type:: v4l2_vp8_quantization_header
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp8_quantization_header
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``y_ac_qi``
+      - Luma AC coefficient table index.
+    * - __s8
+      - ``y_dc_delta``
+      - Luma DC delta vaue.
+    * - __s8
+      - ``y2_dc_delta``
+      - Y2 block DC delta value.
+    * - __s8
+      - ``y2_ac_delta``
+      - Y2 block AC delta value.
+    * - __s8
+      - ``uv_dc_delta``
+      - Chroma DC delta value.
+    * - __s8
+      - ``uv_ac_delta``
+      - Chroma AC delta value.
+    * - __u16
+      - ``padding``
+      - Applications and drivers must set this to zero.
+
+.. c:type:: v4l2_vp8_entropy_header
+
+.. cssclass:: longtable
+
+.. tabularcolumns:: |p{1.5cm}|p{6.3cm}|p{9.4cm}|
+
+.. flat-table:: struct v4l2_vp8_entropy_header
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       1 1 2
+
+    * - __u8
+      - ``coeff_probs[4][8][3][11]``
+      - Coefficient update probabilities.
+    * - __u8
+      - ``y_mode_probs[4]``
+      - Luma mode update probabilities.
+    * - __u8
+      - ``uv_mode_probs[3]``
+      - Chroma mode update probabilities.
+    * - __u8
+      - ``mv_probs[2][19]``
+      - MV decoding update probabilities.
+    * - __u8
+      - ``padding[3]``
+      - Applications and drivers must set this to zero.
+
 .. raw:: latex
 
     \normalsize
diff --git a/Documentation/media/uapi/v4l/hist-v4l2.rst b/Documentation/media/uapi/v4l/hist-v4l2.rst
index 7d8e9ef..9e097f3 100644
--- a/Documentation/media/uapi/v4l/hist-v4l2.rst
+++ b/Documentation/media/uapi/v4l/hist-v4l2.rst
@@ -900,7 +900,7 @@
    :ref:`VIDIOC_ENUM_FRAMEINTERVALS`
    were added.
 
-3. A new pixel format ``V4L2_PIX_FMT_RGB444`` (:ref:`rgb-formats`) was
+3. A new pixel format ``V4L2_PIX_FMT_RGB444`` (:ref:`pixfmt-rgb`) was
    added.
 
 
diff --git a/Documentation/media/uapi/v4l/pixfmt-bayer.rst b/Documentation/media/uapi/v4l/pixfmt-bayer.rst
new file mode 100644
index 0000000..cfa2f4e
--- /dev/null
+++ b/Documentation/media/uapi/v4l/pixfmt-bayer.rst
@@ -0,0 +1,38 @@
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.1 or any later version published by the Free Software
+.. Foundation, with no Invariant Sections, no Front-Cover Texts
+.. and no Back-Cover Texts. A copy of the license is included at
+.. Documentation/media/uapi/fdl-appendix.rst.
+..
+.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
+
+.. _pixfmt-bayer:
+
+*****************
+Raw Bayer Formats
+*****************
+
+Description
+===========
+
+The raw Bayer formats are used by image sensors before much if any processing is
+performed on the image. The formats contain green, red and blue components, with
+alternating lines of red and green, and blue and green pixels in different
+orders. See also `the Wikipedia article on Bayer filter
+<https://en.wikipedia.org/wiki/Bayer_filter>`__.
+
+
+.. toctree::
+    :maxdepth: 1
+
+    pixfmt-srggb8
+    pixfmt-srggb10
+    pixfmt-srggb10p
+    pixfmt-srggb10alaw8
+    pixfmt-srggb10dpcm8
+    pixfmt-srggb10-ipu3
+    pixfmt-srggb12
+    pixfmt-srggb12p
+    pixfmt-srggb14p
+    pixfmt-srggb16
diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
index 4b701fc..292fdc1 100644
--- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
+++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
@@ -41,7 +41,12 @@
 
       - ``V4L2_PIX_FMT_H264``
       - 'H264'
-      - H264 video elementary stream with start codes.
+      - H264 Access Unit.
+	The decoder expects one Access Unit per buffer.
+	The encoder generates one Access Unit per buffer.
+	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+	then the decoder has no requirements since it can parse all the
+	information from the raw bytestream.
     * .. _V4L2-PIX-FMT-H264-NO-SC:
 
       - ``V4L2_PIX_FMT_H264_NO_SC``
@@ -52,16 +57,19 @@
       - ``V4L2_PIX_FMT_H264_MVC``
       - 'M264'
       - H264 MVC video elementary stream.
-    * .. _V4L2-PIX-FMT-H264-SLICE-RAW:
+    * .. _V4L2-PIX-FMT-H264-SLICE:
 
-      - ``V4L2_PIX_FMT_H264_SLICE_RAW``
+      - ``V4L2_PIX_FMT_H264_SLICE``
       - 'S264'
       - H264 parsed slice data, without the start code and as
 	extracted from the H264 bitstream.  This format is adapted for
 	stateless video decoders that implement an H264 pipeline
 	(using the :ref:`mem2mem` and :ref:`media-request-api`).
-	Metadata associated with the frame to decode are required to
-	be passed through the ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
+	This pixelformat has two modifiers that must be set at least once
+	through the ``V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE``
+        and ``V4L2_CID_MPEG_VIDEO_H264_START_CODE`` controls.
+	In addition, metadata associated with the frame to decode are
+	required to be passed through the ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
 	``V4L2_CID_MPEG_VIDEO_H264_PPS``,
 	``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX``,
 	``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` and
@@ -86,12 +94,20 @@
 
       - ``V4L2_PIX_FMT_MPEG1``
       - 'MPG1'
-      - MPEG1 video elementary stream.
+      - MPEG1 Picture. Each buffer starts with a Picture header, followed
+	by other headers as needed and ending with the Picture data.
+	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+	then the decoder has no requirements since it can parse all the
+	information from the raw bytestream.
     * .. _V4L2-PIX-FMT-MPEG2:
 
       - ``V4L2_PIX_FMT_MPEG2``
       - 'MPG2'
-      - MPEG2 video elementary stream.
+      - MPEG2 Picture. Each buffer starts with a Picture header, followed
+	by other headers as needed and ending with the Picture data.
+	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+	then the decoder has no requirements since it can parse all the
+	information from the raw bytestream.
     * .. _V4L2-PIX-FMT-MPEG2-SLICE:
 
       - ``V4L2_PIX_FMT_MPEG2_SLICE``
@@ -132,17 +148,46 @@
 
       - ``V4L2_PIX_FMT_VP8``
       - 'VP80'
-      - VP8 video elementary stream.
+      - VP8 compressed video frame. The encoder generates one
+	compressed frame per buffer, and the decoder requires one
+	compressed frame per buffer.
+    * .. _V4L2-PIX-FMT-VP8-FRAME:
+
+      - ``V4L2_PIX_FMT_VP8_FRAME``
+      - 'VP8F'
+      - VP8 parsed frame, as extracted from the container.
+	This format is adapted for stateless video decoders that implement a
+	VP8 pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`).
+	Metadata associated with the frame to decode is required to be passed
+	through the ``V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER`` control.
+	See the :ref:`associated Codec Control IDs <v4l2-mpeg-vp8>`.
+	Exactly one output and one capture buffer must be provided for use with
+	this pixel format. The output buffer must contain the appropriate number
+	of macroblocks to decode a full corresponding frame to the matching
+	capture buffer.
+
+	.. note::
+
+	   This format is not yet part of the public kernel API and it
+	   is expected to change.
+
     * .. _V4L2-PIX-FMT-VP9:
 
       - ``V4L2_PIX_FMT_VP9``
       - 'VP90'
-      - VP9 video elementary stream.
+      - VP9 compressed video frame. The encoder generates one
+	compressed frame per buffer, and the decoder requires one
+	compressed frame per buffer.
     * .. _V4L2-PIX-FMT-HEVC:
 
       - ``V4L2_PIX_FMT_HEVC``
       - 'HEVC'
-      - HEVC/H.265 video elementary stream.
+      - HEVC/H.265 Access Unit.
+	The decoder expects one Access Unit per buffer.
+	The encoder generates one Access Unit per buffer.
+	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+	then the decoder has no	requirements since it can parse all the
+	information from the raw bytestream.
     * .. _V4L2-PIX-FMT-FWHT:
 
       - ``V4L2_PIX_FMT_FWHT``
@@ -150,6 +195,8 @@
       - Video elementary stream using a codec based on the Fast Walsh Hadamard
         Transform. This codec is implemented by the vicodec ('Virtual Codec')
 	driver. See the codec-fwht.h header for more details.
+	:ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+	since the decoder can parse all the information from the raw bytestream.
     * .. _V4L2-PIX-FMT-FWHT-STATELESS:
 
       - ``V4L2_PIX_FMT_FWHT_STATELESS``
diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst
deleted file mode 100644
index 738bb14..0000000
--- a/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst
+++ /dev/null
@@ -1,1306 +0,0 @@
-.. Permission is granted to copy, distribute and/or modify this
-.. document under the terms of the GNU Free Documentation License,
-.. Version 1.1 or any later version published by the Free Software
-.. Foundation, with no Invariant Sections, no Front-Cover Texts
-.. and no Back-Cover Texts. A copy of the license is included at
-.. Documentation/media/uapi/fdl-appendix.rst.
-..
-.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections
-
-.. _packed-rgb:
-
-******************
-Packed RGB formats
-******************
-
-Description
-===========
-
-These formats are designed to match the pixel formats of typical PC
-graphics frame buffers. They occupy 8, 16, 24 or 32 bits per pixel.
-These are all packed-pixel formats, meaning all the data for a pixel lie
-next to each other in memory.
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{2.8cm}|p{2.0cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-
-.. _rgb-formats:
-
-.. flat-table:: Packed RGB Image Formats
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-      - :cspan:`7` Byte 0 in memory
-      - :cspan:`7` Byte 1
-      - :cspan:`7` Byte 2
-      - :cspan:`7` Byte 3
-    * -
-      -
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _V4L2-PIX-FMT-RGB332:
-
-      - ``V4L2_PIX_FMT_RGB332``
-      - 'RGB1'
-
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-ARGB444:
-
-      - ``V4L2_PIX_FMT_ARGB444``
-      - 'AR12'
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-XRGB444:
-
-      - ``V4L2_PIX_FMT_XRGB444``
-      - 'XR12'
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      -
-      -
-      -
-      -
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-RGBA444:
-
-      - ``V4L2_PIX_FMT_RGBA444``
-      - 'RA12'
-
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-RGBX444:
-
-      - ``V4L2_PIX_FMT_RGBX444``
-      - 'RX12'
-
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-      -
-      -
-      -
-
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-ABGR444:
-
-      - ``V4L2_PIX_FMT_ABGR444``
-      - 'AB12'
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-XBGR444:
-
-      - ``V4L2_PIX_FMT_XBGR444``
-      - 'XB12'
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      -
-      -
-      -
-      -
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-BGRA444:
-
-      - ``V4L2_PIX_FMT_BGRA444``
-      - 'BA12'
-
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-BGRX444:
-
-      - ``V4L2_PIX_FMT_BGRX444``
-      - 'BX12'
-
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-      -
-      -
-      -
-
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-ARGB555:
-
-      - ``V4L2_PIX_FMT_ARGB555``
-      - 'AR15'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - a
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-XRGB555:
-
-      - ``V4L2_PIX_FMT_XRGB555``
-      - 'XR15'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      -
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-RGBA555:
-
-      - ``V4L2_PIX_FMT_RGBA555``
-      - 'RA15'
-
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - a
-
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      -
-    * .. _V4L2-PIX-FMT-RGBX555:
-
-      - ``V4L2_PIX_FMT_RGBX555``
-      - 'RX15'
-
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      -
-    * .. _V4L2-PIX-FMT-ABGR555:
-
-      - ``V4L2_PIX_FMT_ABGR555``
-      - 'AB15'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - a
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-XBGR555:
-
-      - ``V4L2_PIX_FMT_XBGR555``
-      - 'XB15'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      -
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-BGRA555:
-
-      - ``V4L2_PIX_FMT_BGRA555``
-      - 'BA15'
-
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - a
-
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      -
-    * .. _V4L2-PIX-FMT-BGRX555:
-
-      - ``V4L2_PIX_FMT_BGRX555``
-      - 'BX15'
-
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      -
-    * .. _V4L2-PIX-FMT-RGB565:
-
-      - ``V4L2_PIX_FMT_RGB565``
-      - 'RGBP'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-ARGB555X:
-
-      - ``V4L2_PIX_FMT_ARGB555X``
-      - 'AR15' | (1 << 31)
-
-      - a
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-XRGB555X:
-
-      - ``V4L2_PIX_FMT_XRGB555X``
-      - 'XR15' | (1 << 31)
-
-      -
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-RGB565X:
-
-      - ``V4L2_PIX_FMT_RGB565X``
-      - 'RGBR'
-
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-BGR24:
-
-      - ``V4L2_PIX_FMT_BGR24``
-      - 'BGR3'
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-RGB24:
-
-      - ``V4L2_PIX_FMT_RGB24``
-      - 'RGB3'
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-BGR666:
-
-      - ``V4L2_PIX_FMT_BGR666``
-      - 'BGRH'
-
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-      -
-      -
-      -
-      -
-      -
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-    * .. _V4L2-PIX-FMT-ABGR32:
-
-      - ``V4L2_PIX_FMT_ABGR32``
-      - 'AR24'
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-    * .. _V4L2-PIX-FMT-XBGR32:
-
-      - ``V4L2_PIX_FMT_XBGR32``
-      - 'XR24'
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-    * .. _V4L2-PIX-FMT-BGRA32:
-
-      - ``V4L2_PIX_FMT_BGRA32``
-      - 'RA24'
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _V4L2-PIX-FMT-BGRX32:
-
-      - ``V4L2_PIX_FMT_BGRX32``
-      - 'RX24'
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-    * .. _V4L2-PIX-FMT-RGBA32:
-
-      - ``V4L2_PIX_FMT_RGBA32``
-      - 'AB24'
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-    * .. _V4L2-PIX-FMT-RGBX32:
-
-      - ``V4L2_PIX_FMT_RGBX32``
-      - 'XB24'
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-    * .. _V4L2-PIX-FMT-ARGB32:
-
-      - ``V4L2_PIX_FMT_ARGB32``
-      - 'BA24'
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-    * .. _V4L2-PIX-FMT-XRGB32:
-
-      - ``V4L2_PIX_FMT_XRGB32``
-      - 'BX24'
-
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-      -
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-.. raw:: latex
-
-    \endgroup
-
-.. note:: Bit 7 is the most significant bit.
-
-The usage and value of the alpha bits (a) in the ARGB and ABGR formats
-(collectively referred to as alpha formats) depend on the device type
-and hardware operation. :ref:`Capture <capture>` devices (including
-capture queues of mem-to-mem devices) fill the alpha component in
-memory. When the device outputs an alpha channel the alpha component
-will have a meaningful value. Otherwise, when the device doesn't output
-an alpha channel but can set the alpha bit to a user-configurable value,
-the :ref:`V4L2_CID_ALPHA_COMPONENT <v4l2-alpha-component>` control
-is used to specify that alpha value, and the alpha component of all
-pixels will be set to the value specified by that control. Otherwise a
-corresponding format without an alpha component (XRGB or XBGR) must be
-used instead of an alpha format.
-
-:ref:`Output <output>` devices (including output queues of mem-to-mem
-devices and :ref:`video output overlay <osd>` devices) read the alpha
-component from memory. When the device processes the alpha channel the
-alpha component must be filled with meaningful values by applications.
-Otherwise a corresponding format without an alpha component (XRGB or
-XBGR) must be used instead of an alpha format.
-
-The XRGB and XBGR formats contain undefined bits (-). Applications,
-devices and drivers must ignore those bits, for both
-:ref:`capture` and :ref:`output` devices.
-
-**Byte Order.**
-Each cell is one byte.
-
-
-.. raw:: latex
-
-    \small
-
-.. tabularcolumns:: |p{3.1cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|
-
-.. flat-table:: RGB byte order
-    :header-rows:  0
-    :stub-columns: 0
-    :widths:       11 3 3 3 3 3 3 3 3 3 3 3 3
-
-    * - start + 0:
-      - B\ :sub:`00`
-      - G\ :sub:`00`
-      - R\ :sub:`00`
-      - B\ :sub:`01`
-      - G\ :sub:`01`
-      - R\ :sub:`01`
-      - B\ :sub:`02`
-      - G\ :sub:`02`
-      - R\ :sub:`02`
-      - B\ :sub:`03`
-      - G\ :sub:`03`
-      - R\ :sub:`03`
-    * - start + 12:
-      - B\ :sub:`10`
-      - G\ :sub:`10`
-      - R\ :sub:`10`
-      - B\ :sub:`11`
-      - G\ :sub:`11`
-      - R\ :sub:`11`
-      - B\ :sub:`12`
-      - G\ :sub:`12`
-      - R\ :sub:`12`
-      - B\ :sub:`13`
-      - G\ :sub:`13`
-      - R\ :sub:`13`
-    * - start + 24:
-      - B\ :sub:`20`
-      - G\ :sub:`20`
-      - R\ :sub:`20`
-      - B\ :sub:`21`
-      - G\ :sub:`21`
-      - R\ :sub:`21`
-      - B\ :sub:`22`
-      - G\ :sub:`22`
-      - R\ :sub:`22`
-      - B\ :sub:`23`
-      - G\ :sub:`23`
-      - R\ :sub:`23`
-    * - start + 36:
-      - B\ :sub:`30`
-      - G\ :sub:`30`
-      - R\ :sub:`30`
-      - B\ :sub:`31`
-      - G\ :sub:`31`
-      - R\ :sub:`31`
-      - B\ :sub:`32`
-      - G\ :sub:`32`
-      - R\ :sub:`32`
-      - B\ :sub:`33`
-      - G\ :sub:`33`
-      - R\ :sub:`33`
-
-.. raw:: latex
-
-    \normalsize
-
-Formats defined in :ref:`rgb-formats-deprecated` are deprecated and
-must not be used by new drivers. They are documented here for reference.
-The meaning of their alpha bits ``(a)`` are ill-defined and interpreted as in
-either the corresponding ARGB or XRGB format, depending on the driver.
-
-
-.. raw:: latex
-
-    \begingroup
-    \tiny
-    \setlength{\tabcolsep}{2pt}
-
-.. tabularcolumns:: |p{2.6cm}|p{0.70cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
-
-.. _rgb-formats-deprecated:
-
-.. flat-table:: Deprecated Packed RGB Image Formats
-    :header-rows:  2
-    :stub-columns: 0
-
-    * - Identifier
-      - Code
-      - :cspan:`7` Byte 0 in memory
-
-      - :cspan:`7` Byte 1
-
-      - :cspan:`7` Byte 2
-
-      - :cspan:`7` Byte 3
-    * -
-      -
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-
-      - 7
-      - 6
-      - 5
-      - 4
-      - 3
-      - 2
-      - 1
-      - 0
-    * .. _V4L2-PIX-FMT-RGB444:
-
-      - ``V4L2_PIX_FMT_RGB444``
-      - 'R444'
-
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-RGB555:
-
-      - ``V4L2_PIX_FMT_RGB555``
-      - 'RGBO'
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - a
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      -
-    * .. _V4L2-PIX-FMT-RGB555X:
-
-      - ``V4L2_PIX_FMT_RGB555X``
-      - 'RGBQ'
-
-      - a
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-      -
-    * .. _V4L2-PIX-FMT-BGR32:
-
-      - ``V4L2_PIX_FMT_BGR32``
-      - 'BGR4'
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-    * .. _V4L2-PIX-FMT-RGB32:
-
-      - ``V4L2_PIX_FMT_RGB32``
-      - 'RGB4'
-
-      - a\ :sub:`7`
-      - a\ :sub:`6`
-      - a\ :sub:`5`
-      - a\ :sub:`4`
-      - a\ :sub:`3`
-      - a\ :sub:`2`
-      - a\ :sub:`1`
-      - a\ :sub:`0`
-
-      - r\ :sub:`7`
-      - r\ :sub:`6`
-      - r\ :sub:`5`
-      - r\ :sub:`4`
-      - r\ :sub:`3`
-      - r\ :sub:`2`
-      - r\ :sub:`1`
-      - r\ :sub:`0`
-
-      - g\ :sub:`7`
-      - g\ :sub:`6`
-      - g\ :sub:`5`
-      - g\ :sub:`4`
-      - g\ :sub:`3`
-      - g\ :sub:`2`
-      - g\ :sub:`1`
-      - g\ :sub:`0`
-
-      - b\ :sub:`7`
-      - b\ :sub:`6`
-      - b\ :sub:`5`
-      - b\ :sub:`4`
-      - b\ :sub:`3`
-      - b\ :sub:`2`
-      - b\ :sub:`1`
-      - b\ :sub:`0`
-
-.. raw:: latex
-
-    \endgroup
-
-A test utility to determine which RGB formats a driver actually supports
-is available from the LinuxTV v4l-dvb repository. See
-`https://linuxtv.org/repo/ <https://linuxtv.org/repo/>`__ for access
-instructions.
diff --git a/Documentation/media/uapi/v4l/pixfmt-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-rgb.rst
index 48ab800..4ce305c 100644
--- a/Documentation/media/uapi/v4l/pixfmt-rgb.rst
+++ b/Documentation/media/uapi/v4l/pixfmt-rgb.rst
@@ -13,18 +13,1292 @@
 RGB Formats
 ***********
 
+Description
+===========
 
-.. toctree::
-    :maxdepth: 1
+These formats are designed to match the pixel formats of typical PC
+graphics frame buffers. They occupy 8, 16, 24 or 32 bits per pixel.
+These are all packed-pixel formats, meaning all the data for a pixel lie
+next to each other in memory.
 
-    pixfmt-packed-rgb
-    pixfmt-srggb8
-    pixfmt-srggb10
-    pixfmt-srggb10p
-    pixfmt-srggb10alaw8
-    pixfmt-srggb10dpcm8
-    pixfmt-srggb10-ipu3
-    pixfmt-srggb12
-    pixfmt-srggb12p
-    pixfmt-srggb14p
-    pixfmt-srggb16
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{2.8cm}|p{2.0cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+
+.. flat-table:: RGB Image Formats
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      - :cspan:`7` Byte 0 in memory
+      - :cspan:`7` Byte 1
+      - :cspan:`7` Byte 2
+      - :cspan:`7` Byte 3
+    * -
+      -
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _V4L2-PIX-FMT-RGB332:
+
+      - ``V4L2_PIX_FMT_RGB332``
+      - 'RGB1'
+
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-ARGB444:
+
+      - ``V4L2_PIX_FMT_ARGB444``
+      - 'AR12'
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-XRGB444:
+
+      - ``V4L2_PIX_FMT_XRGB444``
+      - 'XR12'
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      -
+      -
+      -
+      -
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-RGBA444:
+
+      - ``V4L2_PIX_FMT_RGBA444``
+      - 'RA12'
+
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-RGBX444:
+
+      - ``V4L2_PIX_FMT_RGBX444``
+      - 'RX12'
+
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+      -
+      -
+      -
+
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-ABGR444:
+
+      - ``V4L2_PIX_FMT_ABGR444``
+      - 'AB12'
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-XBGR444:
+
+      - ``V4L2_PIX_FMT_XBGR444``
+      - 'XB12'
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      -
+      -
+      -
+      -
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-BGRA444:
+
+      - ``V4L2_PIX_FMT_BGRA444``
+      - 'BA12'
+
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-BGRX444:
+
+      - ``V4L2_PIX_FMT_BGRX444``
+      - 'BX12'
+
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+      -
+      -
+      -
+
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-ARGB555:
+
+      - ``V4L2_PIX_FMT_ARGB555``
+      - 'AR15'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - a
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-XRGB555:
+
+      - ``V4L2_PIX_FMT_XRGB555``
+      - 'XR15'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      -
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-RGBA555:
+
+      - ``V4L2_PIX_FMT_RGBA555``
+      - 'RA15'
+
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - a
+
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      -
+    * .. _V4L2-PIX-FMT-RGBX555:
+
+      - ``V4L2_PIX_FMT_RGBX555``
+      - 'RX15'
+
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      -
+    * .. _V4L2-PIX-FMT-ABGR555:
+
+      - ``V4L2_PIX_FMT_ABGR555``
+      - 'AB15'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - a
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-XBGR555:
+
+      - ``V4L2_PIX_FMT_XBGR555``
+      - 'XB15'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      -
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-BGRA555:
+
+      - ``V4L2_PIX_FMT_BGRA555``
+      - 'BA15'
+
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - a
+
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      -
+    * .. _V4L2-PIX-FMT-BGRX555:
+
+      - ``V4L2_PIX_FMT_BGRX555``
+      - 'BX15'
+
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      -
+    * .. _V4L2-PIX-FMT-RGB565:
+
+      - ``V4L2_PIX_FMT_RGB565``
+      - 'RGBP'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-ARGB555X:
+
+      - ``V4L2_PIX_FMT_ARGB555X``
+      - 'AR15' | (1 << 31)
+
+      - a
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-XRGB555X:
+
+      - ``V4L2_PIX_FMT_XRGB555X``
+      - 'XR15' | (1 << 31)
+
+      -
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-RGB565X:
+
+      - ``V4L2_PIX_FMT_RGB565X``
+      - 'RGBR'
+
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-BGR24:
+
+      - ``V4L2_PIX_FMT_BGR24``
+      - 'BGR3'
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-RGB24:
+
+      - ``V4L2_PIX_FMT_RGB24``
+      - 'RGB3'
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-BGR666:
+
+      - ``V4L2_PIX_FMT_BGR666``
+      - 'BGRH'
+
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+      -
+      -
+      -
+      -
+      -
+
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+    * .. _V4L2-PIX-FMT-ABGR32:
+
+      - ``V4L2_PIX_FMT_ABGR32``
+      - 'AR24'
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+    * .. _V4L2-PIX-FMT-XBGR32:
+
+      - ``V4L2_PIX_FMT_XBGR32``
+      - 'XR24'
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+    * .. _V4L2-PIX-FMT-BGRA32:
+
+      - ``V4L2_PIX_FMT_BGRA32``
+      - 'RA24'
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _V4L2-PIX-FMT-BGRX32:
+
+      - ``V4L2_PIX_FMT_BGRX32``
+      - 'RX24'
+
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+    * .. _V4L2-PIX-FMT-RGBA32:
+
+      - ``V4L2_PIX_FMT_RGBA32``
+      - 'AB24'
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+    * .. _V4L2-PIX-FMT-RGBX32:
+
+      - ``V4L2_PIX_FMT_RGBX32``
+      - 'XB24'
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+    * .. _V4L2-PIX-FMT-ARGB32:
+
+      - ``V4L2_PIX_FMT_ARGB32``
+      - 'BA24'
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+    * .. _V4L2-PIX-FMT-XRGB32:
+
+      - ``V4L2_PIX_FMT_XRGB32``
+      - 'BX24'
+
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+      -
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+.. raw:: latex
+
+    \endgroup
+
+.. note:: Bit 7 is the most significant bit.
+
+The usage and value of the alpha bits (a) in the ARGB and ABGR formats
+(collectively referred to as alpha formats) depend on the device type
+and hardware operation. :ref:`Capture <capture>` devices (including
+capture queues of mem-to-mem devices) fill the alpha component in
+memory. When the device outputs an alpha channel the alpha component
+will have a meaningful value. Otherwise, when the device doesn't output
+an alpha channel but can set the alpha bit to a user-configurable value,
+the :ref:`V4L2_CID_ALPHA_COMPONENT <v4l2-alpha-component>` control
+is used to specify that alpha value, and the alpha component of all
+pixels will be set to the value specified by that control. Otherwise a
+corresponding format without an alpha component (XRGB or XBGR) must be
+used instead of an alpha format.
+
+:ref:`Output <output>` devices (including output queues of mem-to-mem
+devices and :ref:`video output overlay <osd>` devices) read the alpha
+component from memory. When the device processes the alpha channel the
+alpha component must be filled with meaningful values by applications.
+Otherwise a corresponding format without an alpha component (XRGB or
+XBGR) must be used instead of an alpha format.
+
+The XRGB and XBGR formats contain undefined bits (-). Applications,
+devices and drivers must ignore those bits, for both
+:ref:`capture` and :ref:`output` devices.
+
+**Byte Order.**
+Each cell is one byte.
+
+
+.. raw:: latex
+
+    \small
+
+.. tabularcolumns:: |p{3.1cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|
+
+.. flat-table:: RGB byte order
+    :header-rows:  0
+    :stub-columns: 0
+    :widths:       11 3 3 3 3 3 3 3 3 3 3 3 3
+
+    * - start + 0:
+      - B\ :sub:`00`
+      - G\ :sub:`00`
+      - R\ :sub:`00`
+      - B\ :sub:`01`
+      - G\ :sub:`01`
+      - R\ :sub:`01`
+      - B\ :sub:`02`
+      - G\ :sub:`02`
+      - R\ :sub:`02`
+      - B\ :sub:`03`
+      - G\ :sub:`03`
+      - R\ :sub:`03`
+    * - start + 12:
+      - B\ :sub:`10`
+      - G\ :sub:`10`
+      - R\ :sub:`10`
+      - B\ :sub:`11`
+      - G\ :sub:`11`
+      - R\ :sub:`11`
+      - B\ :sub:`12`
+      - G\ :sub:`12`
+      - R\ :sub:`12`
+      - B\ :sub:`13`
+      - G\ :sub:`13`
+      - R\ :sub:`13`
+    * - start + 24:
+      - B\ :sub:`20`
+      - G\ :sub:`20`
+      - R\ :sub:`20`
+      - B\ :sub:`21`
+      - G\ :sub:`21`
+      - R\ :sub:`21`
+      - B\ :sub:`22`
+      - G\ :sub:`22`
+      - R\ :sub:`22`
+      - B\ :sub:`23`
+      - G\ :sub:`23`
+      - R\ :sub:`23`
+    * - start + 36:
+      - B\ :sub:`30`
+      - G\ :sub:`30`
+      - R\ :sub:`30`
+      - B\ :sub:`31`
+      - G\ :sub:`31`
+      - R\ :sub:`31`
+      - B\ :sub:`32`
+      - G\ :sub:`32`
+      - R\ :sub:`32`
+      - B\ :sub:`33`
+      - G\ :sub:`33`
+      - R\ :sub:`33`
+
+.. raw:: latex
+
+    \normalsize
+
+Formats defined in :ref:`pixfmt-rgb-deprecated` are deprecated and
+must not be used by new drivers. They are documented here for reference.
+The meaning of their alpha bits ``(a)`` are ill-defined and interpreted as in
+either the corresponding ARGB or XRGB format, depending on the driver.
+
+
+.. raw:: latex
+
+    \begingroup
+    \tiny
+    \setlength{\tabcolsep}{2pt}
+
+.. tabularcolumns:: |p{2.6cm}|p{0.70cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|
+
+.. _pixfmt-rgb-deprecated:
+
+.. flat-table:: Deprecated Packed RGB Image Formats
+    :header-rows:  2
+    :stub-columns: 0
+
+    * - Identifier
+      - Code
+      - :cspan:`7` Byte 0 in memory
+
+      - :cspan:`7` Byte 1
+
+      - :cspan:`7` Byte 2
+
+      - :cspan:`7` Byte 3
+    * -
+      -
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+
+      - 7
+      - 6
+      - 5
+      - 4
+      - 3
+      - 2
+      - 1
+      - 0
+    * .. _V4L2-PIX-FMT-RGB444:
+
+      - ``V4L2_PIX_FMT_RGB444``
+      - 'R444'
+
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-RGB555:
+
+      - ``V4L2_PIX_FMT_RGB555``
+      - 'RGBO'
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - a
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      -
+    * .. _V4L2-PIX-FMT-RGB555X:
+
+      - ``V4L2_PIX_FMT_RGB555X``
+      - 'RGBQ'
+
+      - a
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+      -
+    * .. _V4L2-PIX-FMT-BGR32:
+
+      - ``V4L2_PIX_FMT_BGR32``
+      - 'BGR4'
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+    * .. _V4L2-PIX-FMT-RGB32:
+
+      - ``V4L2_PIX_FMT_RGB32``
+      - 'RGB4'
+
+      - a\ :sub:`7`
+      - a\ :sub:`6`
+      - a\ :sub:`5`
+      - a\ :sub:`4`
+      - a\ :sub:`3`
+      - a\ :sub:`2`
+      - a\ :sub:`1`
+      - a\ :sub:`0`
+
+      - r\ :sub:`7`
+      - r\ :sub:`6`
+      - r\ :sub:`5`
+      - r\ :sub:`4`
+      - r\ :sub:`3`
+      - r\ :sub:`2`
+      - r\ :sub:`1`
+      - r\ :sub:`0`
+
+      - g\ :sub:`7`
+      - g\ :sub:`6`
+      - g\ :sub:`5`
+      - g\ :sub:`4`
+      - g\ :sub:`3`
+      - g\ :sub:`2`
+      - g\ :sub:`1`
+      - g\ :sub:`0`
+
+      - b\ :sub:`7`
+      - b\ :sub:`6`
+      - b\ :sub:`5`
+      - b\ :sub:`4`
+      - b\ :sub:`3`
+      - b\ :sub:`2`
+      - b\ :sub:`1`
+      - b\ :sub:`0`
+
+.. raw:: latex
+
+    \endgroup
+
+A test utility to determine which RGB formats a driver actually supports
+is available from the LinuxTV v4l-dvb repository. See
+`https://linuxtv.org/repo/ <https://linuxtv.org/repo/>`__ for access
+instructions.
diff --git a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
index da6da2e..a8321c3 100644
--- a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
+++ b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst
@@ -39,12 +39,17 @@
 	to a multiple of the scale factor of any smaller planes. For
 	example when the image format is YUV 4:2:0, ``width`` and
 	``height`` must be multiples of two.
+
+	For compressed formats that contain the resolution information encoded
+	inside the stream, when fed to a stateful mem2mem decoder, the fields
+	may be zero to rely on the decoder to detect the right values. For more
+	details see :ref:`decoder` and format descriptions.
     * - __u32
       - ``pixelformat``
       - The pixel format or type of compression, set by the application.
 	This is a little endian
 	:ref:`four character code <v4l2-fourcc>`. V4L2 defines standard
-	RGB formats in :ref:`rgb-formats`, YUV formats in
+	RGB formats in :ref:`pixfmt-rgb`, YUV formats in
 	:ref:`yuv-formats`, and reserved codes in
 	:ref:`reserved-formats`
     * - __u32
diff --git a/Documentation/media/uapi/v4l/pixfmt.rst b/Documentation/media/uapi/v4l/pixfmt.rst
index 29be001..a7d4cd4 100644
--- a/Documentation/media/uapi/v4l/pixfmt.rst
+++ b/Documentation/media/uapi/v4l/pixfmt.rst
@@ -31,6 +31,7 @@
     pixfmt-intro
     pixfmt-indexed
     pixfmt-rgb
+    pixfmt-bayer
     yuv-formats
     hsv-formats
     depth-formats
diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst
index ab1a48a..7b8e17c 100644
--- a/Documentation/media/uapi/v4l/subdev-formats.rst
+++ b/Documentation/media/uapi/v4l/subdev-formats.rst
@@ -85,6 +85,14 @@
 JPEG just by storing it to memory), there is no one-to-one
 correspondence between them.
 
+The media bus pixel codes document parallel formats. Should the pixel data be
+transported over a serial bus, the media bus pixel code that describes a
+parallel format that transfers a sample on a single clock cycle is used. For
+instance, both MEDIA_BUS_FMT_BGR888_1X24 and MEDIA_BUS_FMT_BGR888_3X8 are used
+on parallel busses for transferring an 8 bits per sample BGR data, whereas on
+serial busses the data in this format is only referred to using
+MEDIA_BUS_FMT_BGR888_1X24. This is because there is effectively only a single
+way to transport that format on the serial busses.
 
 Packed RGB Formats
 ^^^^^^^^^^^^^^^^^^
diff --git a/Documentation/media/uapi/v4l/v4l2.rst b/Documentation/media/uapi/v4l/v4l2.rst
index 004ec00..97015b9b40 100644
--- a/Documentation/media/uapi/v4l/v4l2.rst
+++ b/Documentation/media/uapi/v4l/v4l2.rst
@@ -60,6 +60,10 @@
 
   - Original author of the V4L2 API and documentation.
 
+- Figa, Tomasz <tfiga@chromium.org>
+
+  - Documented the memory-to-memory decoder interface.
+
 - H Schimek, Michael <mschimek@gmx.at>
 
   - Original author of the V4L2 API and documentation.
@@ -68,6 +72,10 @@
 
   - Documented the Digital Video timings API.
 
+- Osciak, Pawel <posciak@chromium.org>
+
+  - Documented the memory-to-memory decoder interface.
+
 - Osciak, Pawel <pawel@osciak.com>
 
   - Designed and documented the multi-planar API.
@@ -92,7 +100,7 @@
 
   - Designed and documented the VIDIOC_LOG_STATUS ioctl, the extended control ioctls, major parts of the sliced VBI API, the MPEG encoder and decoder APIs and the DV Timings API.
 
-**Copyright** |copy| 1999-2016: Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab, Pawel Osciak, Sakari Ailus & Antti Palosaari.
+**Copyright** |copy| 1999-2018: Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab, Pawel Osciak, Sakari Ailus & Antti Palosaari, Tomasz Figa
 
 Except when explicitly stated as GPL, programming examples within this
 part can be used and distributed without restrictions.
diff --git a/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst b/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst
index ccf83b0..57f0066 100644
--- a/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst
+++ b/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst
@@ -56,14 +56,16 @@
 
 A :ref:`write() <func-write>` or :ref:`VIDIOC_STREAMON`
 call sends an implicit START command to the decoder if it has not been
-started yet.
+started yet. Applies to both queues of mem2mem decoders.
 
 A :ref:`close() <func-close>` or :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
 call of a streaming file descriptor sends an implicit immediate STOP
-command to the decoder, and all buffered data is discarded.
+command to the decoder, and all buffered data is discarded. Applies to both
+queues of mem2mem decoders.
 
-These ioctls are optional, not all drivers may support them. They were
-introduced in Linux 3.3.
+In principle, these ioctls are optional, not all drivers may support them. They were
+introduced in Linux 3.3. They are, however, mandatory for stateful mem2mem decoders
+(as further documented in :ref:`decoder`).
 
 
 .. tabularcolumns:: |p{1.1cm}|p{2.4cm}|p{1.2cm}|p{1.6cm}|p{10.6cm}|
@@ -167,26 +169,32 @@
 	``V4L2_DEC_CMD_RESUME`` for that. This command has one flag:
 	``V4L2_DEC_CMD_START_MUTE_AUDIO``. If set, then audio will be
 	muted when playing back at a non-standard speed.
+
+	For a device implementing the :ref:`decoder`, once the drain sequence
+	is initiated with the ``V4L2_DEC_CMD_STOP`` command, it must be driven
+	to completion before this command can be invoked.  Any attempt to
+	invoke the command while the drain sequence is in progress will trigger
+	an ``EBUSY`` error code.  The command may be also used to restart the
+	decoder in case of an implicit stop initiated by the decoder itself,
+	without the ``V4L2_DEC_CMD_STOP`` being called explicitly. See
+	:ref:`decoder` for more details.
     * - ``V4L2_DEC_CMD_STOP``
       - 1
       - Stop the decoder. When the decoder is already stopped, this
 	command does nothing. This command has two flags: if
 	``V4L2_DEC_CMD_STOP_TO_BLACK`` is set, then the decoder will set
 	the picture to black after it stopped decoding. Otherwise the last
-	image will repeat. mem2mem decoders will stop producing new frames
-	altogether. They will send a ``V4L2_EVENT_EOS`` event when the
-	last frame has been decoded and all frames are ready to be
-	dequeued and will set the ``V4L2_BUF_FLAG_LAST`` buffer flag on
-	the last buffer of the capture queue to indicate there will be no
-	new buffers produced to dequeue. This buffer may be empty,
-	indicated by the driver setting the ``bytesused`` field to 0. Once
-	the ``V4L2_BUF_FLAG_LAST`` flag was set, the
-	:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl will not block anymore,
-	but return an ``EPIPE`` error code. If
+	image will repeat. If
 	``V4L2_DEC_CMD_STOP_IMMEDIATELY`` is set, then the decoder stops
 	immediately (ignoring the ``pts`` value), otherwise it will keep
 	decoding until timestamp >= pts or until the last of the pending
 	data from its internal buffers was decoded.
+
+	For a device implementing the :ref:`decoder`, the command will initiate
+	the drain sequence as documented in :ref:`decoder`.  No flags or other
+	arguments are accepted in this case. Any attempt to invoke the command
+	again before the sequence completes will trigger an ``EBUSY`` error
+	code.
     * - ``V4L2_DEC_CMD_PAUSE``
       - 2
       - Pause the decoder. When the decoder has not been started yet, the
@@ -209,6 +217,11 @@
 appropriately. The generic error codes are described at the
 :ref:`Generic Error Codes <gen-errors>` chapter.
 
+EBUSY
+    A drain sequence of a device implementing the :ref:`decoder` is still in
+    progress. It is not allowed to issue another decoder command until it
+    completes.
+
 EINVAL
     The ``cmd`` field is invalid.
 
diff --git a/Documentation/media/uapi/v4l/vidioc-dqevent.rst b/Documentation/media/uapi/v4l/vidioc-dqevent.rst
index dea9c0c..42659a3 100644
--- a/Documentation/media/uapi/v4l/vidioc-dqevent.rst
+++ b/Documentation/media/uapi/v4l/vidioc-dqevent.rst
@@ -389,14 +389,19 @@
 	decoder. Applications will have to query the new resolution (if
 	any, the signal may also have been lost).
 
+	For stateful decoders follow the guidelines in :ref:`decoder`.
+	Video Capture devices have to query the new timings using
+	:ref:`VIDIOC_QUERY_DV_TIMINGS` or
+	:ref:`VIDIOC_QUERYSTD <VIDIOC_QUERYSTD>`.
+
 	*Important*: even if the new video timings appear identical to the old
 	ones, receiving this event indicates that there was an issue with the
 	video signal and you must stop and restart streaming
 	(:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`
 	followed by :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>`). The reason is
-	that many devices are not able to recover from a temporary loss of
-	signal and so restarting streaming I/O is required in order for the
-	hardware to synchronize to the video signal.
+	that many Video Capture devices are not able to recover from a temporary
+	loss of signal and so restarting streaming I/O is required in order for
+	the hardware to synchronize to the video signal.
 
 
 Return Value
diff --git a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
index 822d673..399ef10 100644
--- a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
+++ b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst
@@ -127,6 +127,22 @@
       - This format is not native to the device but emulated through
 	software (usually libv4l2), where possible try to use a native
 	format instead for better performance.
+    * - ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM``
+      - 0x0004
+      - The hardware decoder for this compressed bytestream format (aka coded
+	format) is capable of parsing a continuous bytestream. Applications do
+	not need to parse the bytestream themselves to find the boundaries
+	between frames/fields. This flag can only be used in combination with
+	the ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to compressed
+	formats only. This flag is valid for stateful decoders only.
+    * - ``V4L2_FMT_FLAG_DYN_RESOLUTION``
+      - 0x0008
+      - Dynamic resolution switching is supported by the device for this
+	compressed bytestream format (aka coded format). It will notify the user
+	via the event ``V4L2_EVENT_SOURCE_CHANGE`` when changes in the video
+	parameters are detected. This flag can only be used in combination
+	with the ``V4L2_FMT_FLAG_COMPRESSED`` flag, since this applies to
+	compressed formats only. It is also only applies to stateful codecs.
 
 
 Return Value
diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
index dc50063..a3d56ff 100644
--- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
+++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
@@ -39,8 +39,8 @@
     File descriptor returned by :ref:`open() <func-open>`.
 
 ``argp``
-    Pointer to struct :c:type:`v4l2_queryctl`, :c:type:`v4l2_query_ext_ctrl`
-    or :c:type`v4l2_querymenu` (depending on the ioctl).
+    Pointer to struct :c:type:`v4l2_queryctrl`, :c:type:`v4l2_query_ext_ctrl`
+    or :c:type:`v4l2_querymenu` (depending on the ioctl).
 
 
 Description
diff --git a/Documentation/media/v4l-drivers/imx7.rst b/Documentation/media/v4l-drivers/imx7.rst
index fe411f6..1e442c9 100644
--- a/Documentation/media/v4l-drivers/imx7.rst
+++ b/Documentation/media/v4l-drivers/imx7.rst
@@ -41,7 +41,7 @@
 virtual channel 0. This module is compliant to previous version of Samsung
 D-phy, and supports two D-PHY Rx Data lanes.
 
-csi_mux
+csi-mux
 -------
 
 This is the video multiplexer. It has two sink pads to select from either camera
@@ -56,7 +56,7 @@
 to store received image pixel data and embedded DMA controllers to transfer data
 from the FIFO through AHB bus.
 
-This entity has one sink pad that receives from the csi_mux entity and a single
+This entity has one sink pad that receives from the csi-mux entity and a single
 source pad that routes video frames directly to memory buffers. This pad is
 routed to a capture device node.
 
@@ -81,14 +81,14 @@
 
    # Setup links
    media-ctl -l "'ov2680 1-0036':0 -> 'imx7-mipi-csis.0':0[1]"
-   media-ctl -l "'imx7-mipi-csis.0':1 -> 'csi_mux':1[1]"
-   media-ctl -l "'csi_mux':2 -> 'csi':0[1]"
+   media-ctl -l "'imx7-mipi-csis.0':1 -> 'csi-mux':1[1]"
+   media-ctl -l "'csi-mux':2 -> 'csi':0[1]"
    media-ctl -l "'csi':1 -> 'csi capture':0[1]"
 
    # Configure pads for pipeline
    media-ctl -V "'ov2680 1-0036':0 [fmt:SBGGR10_1X10/800x600 field:none]"
-   media-ctl -V "'csi_mux':1 [fmt:SBGGR10_1X10/800x600 field:none]"
-   media-ctl -V "'csi_mux':2 [fmt:SBGGR10_1X10/800x600 field:none]"
+   media-ctl -V "'csi-mux':1 [fmt:SBGGR10_1X10/800x600 field:none]"
+   media-ctl -V "'csi-mux':2 [fmt:SBGGR10_1X10/800x600 field:none]"
    media-ctl -V "'imx7-mipi-csis.0':0 [fmt:SBGGR10_1X10/800x600 field:none]"
    media-ctl -V "'csi':0 [fmt:SBGGR10_1X10/800x600 field:none]"
 
@@ -97,64 +97,63 @@
 
 .. code-block:: none
 
-    root@imx7s-warp:~# media-ctl -p
-    Media controller API version 4.17.0
+	# media-ctl -p
+	Media controller API version 5.2.0
 
-    Media device information
-    ------------------------
-    driver          imx-media
-    model           imx-media
-    serial
-    bus info
-    hw revision     0x0
-    driver version  4.17.0
+	Media device information
+	------------------------
+	driver          imx7-csi
+	model           imx-media
+	serial
+	bus info
+	hw revision     0x0
+	driver version  5.2.0
 
-    Device topology
-    - entity 1: csi (2 pads, 2 links)
-		type V4L2 subdev subtype Unknown flags 0
-		device node name /dev/v4l-subdev0
-	    pad0: Sink
-		    [fmt:SBGGR10_1X10/800x600 field:none]
-		    <- "csi_mux":2 [ENABLED]
-	    pad1: Source
-		    [fmt:SBGGR10_1X10/800x600 field:none]
-		    -> "csi capture":0 [ENABLED]
+	Device topology
+	- entity 1: csi (2 pads, 2 links)
+	            type V4L2 subdev subtype Unknown flags 0
+	            device node name /dev/v4l-subdev0
+	        pad0: Sink
+	                [fmt:SBGGR10_1X10/800x600 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
+	                <- "csi-mux":2 [ENABLED]
+	        pad1: Source
+	                [fmt:SBGGR10_1X10/800x600 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
+	                -> "csi capture":0 [ENABLED]
 
-    - entity 4: csi capture (1 pad, 1 link)
-		type Node subtype V4L flags 0
-		device node name /dev/video0
-	    pad0: Sink
-		    <- "csi":1 [ENABLED]
+	- entity 4: csi capture (1 pad, 1 link)
+	            type Node subtype V4L flags 0
+	            device node name /dev/video0
+	        pad0: Sink
+	                <- "csi":1 [ENABLED]
 
-    - entity 10: csi_mux (3 pads, 2 links)
-		type V4L2 subdev subtype Unknown flags 0
-		device node name /dev/v4l-subdev1
-	    pad0: Sink
-		    [fmt:unknown/0x0]
-	    pad1: Sink
-		    [fmt:unknown/800x600 field:none]
-		    <- "imx7-mipi-csis.0":1 [ENABLED]
-	    pad2: Source
-		    [fmt:unknown/800x600 field:none]
-		    -> "csi":0 [ENABLED]
+	- entity 10: csi-mux (3 pads, 2 links)
+	             type V4L2 subdev subtype Unknown flags 0
+	             device node name /dev/v4l-subdev1
+	        pad0: Sink
+	                [fmt:Y8_1X8/1x1 field:none]
+	        pad1: Sink
+	               [fmt:SBGGR10_1X10/800x600 field:none]
+	                <- "imx7-mipi-csis.0":1 [ENABLED]
+	        pad2: Source
+	                [fmt:SBGGR10_1X10/800x600 field:none]
+	                -> "csi":0 [ENABLED]
 
-    - entity 14: imx7-mipi-csis.0 (2 pads, 2 links)
-		type V4L2 subdev subtype Unknown flags 0
-		device node name /dev/v4l-subdev2
-	    pad0: Sink
-		    [fmt:SBGGR10_1X10/800x600 field:none]
-		    <- "ov2680 1-0036":0 [ENABLED]
-	    pad1: Source
-		    [fmt:SBGGR10_1X10/800x600 field:none]
-		    -> "csi_mux":1 [ENABLED]
+	- entity 14: imx7-mipi-csis.0 (2 pads, 2 links)
+	             type V4L2 subdev subtype Unknown flags 0
+	             device node name /dev/v4l-subdev2
+	        pad0: Sink
+	                [fmt:SBGGR10_1X10/800x600 field:none]
+	                <- "ov2680 1-0036":0 [ENABLED]
+	        pad1: Source
+	                [fmt:SBGGR10_1X10/800x600 field:none]
+	                -> "csi-mux":1 [ENABLED]
 
-    - entity 17: ov2680 1-0036 (1 pad, 1 link)
-		type V4L2 subdev subtype Sensor flags 0
-		device node name /dev/v4l-subdev3
-	    pad0: Source
-		    [fmt:SBGGR10_1X10/800x600 field:none]
-		    -> "imx7-mipi-csis.0":0 [ENABLED]
-
+	- entity 17: ov2680 1-0036 (1 pad, 1 link)
+	             type V4L2 subdev subtype Sensor flags 0
+	             device node name /dev/v4l-subdev3
+	        pad0: Source
+	                [fmt:SBGGR10_1X10/800x600@1/30 field:none colorspace:srgb]
+	                -> "imx7-mipi-csis.0":0 [ENABLED]
 
 References
 ----------
diff --git a/Documentation/media/v4l-drivers/vimc.rst b/Documentation/media/v4l-drivers/vimc.rst
index 4628b12..4064176 100644
--- a/Documentation/media/v4l-drivers/vimc.rst
+++ b/Documentation/media/v4l-drivers/vimc.rst
@@ -15,7 +15,7 @@
 .. _vimc_topology_graph:
 
 .. kernel-figure:: vimc.dot
-    :alt:   vimc.dot
+    :alt:   Diagram of the default media pipeline topology
     :align: center
 
     Media pipeline graph on vimc
@@ -96,3 +96,14 @@
         Window size to calculate the mean. Note: the window size needs to be an
         odd number, as the main pixel stays in the center of the window,
         otherwise the next odd number is considered (the default value is 3).
+
+Source code documentation
+-------------------------
+
+vimc-streamer
+~~~~~~~~~~~~~
+
+.. kernel-doc:: drivers/media/platform/vimc/vimc-streamer.h
+   :internal:
+
+.. kernel-doc:: drivers/media/platform/vimc/vimc-streamer.c
diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
index 55cbe32..adeb6b7 100644
--- a/Documentation/media/videodev2.h.rst.exceptions
+++ b/Documentation/media/videodev2.h.rst.exceptions
@@ -180,15 +180,17 @@
 # V4L2 format flags
 replace define V4L2_FMT_FLAG_COMPRESSED fmtdesc-flags
 replace define V4L2_FMT_FLAG_EMULATED fmtdesc-flags
+replace define V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM fmtdesc-flags
+replace define V4L2_FMT_FLAG_DYN_RESOLUTION fmtdesc-flags
 
-# V4L2 tymecode types
+# V4L2 timecode types
 replace define V4L2_TC_TYPE_24FPS timecode-type
 replace define V4L2_TC_TYPE_25FPS timecode-type
 replace define V4L2_TC_TYPE_30FPS timecode-type
 replace define V4L2_TC_TYPE_50FPS timecode-type
 replace define V4L2_TC_TYPE_60FPS timecode-type
 
-# V4L2 tymecode flags
+# V4L2 timecode flags
 replace define V4L2_TC_FLAG_DROPFRAME timecode-flags
 replace define V4L2_TC_FLAG_COLORFRAME timecode-flags
 replace define V4L2_TC_USERBITS_field timecode-flags
diff --git a/MAINTAINERS b/MAINTAINERS
index 9d86877..698f886 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1412,6 +1412,14 @@
 F:	drivers/soc/sunxi/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git
 
+Allwinner A10 CSI driver
+M:	Maxime Ripard <mripard@kernel.org>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+F:	drivers/media/platform/sunxi/sun4i-csi/
+F:	Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
+S:	Maintained
+
 ARM/Amlogic Meson SoC CLOCK FRAMEWORK
 M:	Neil Armstrong <narmstrong@baylibre.com>
 M:	Jerome Brunet <jbrunet@baylibre.com>
@@ -11846,6 +11854,21 @@
 S:	Maintained
 F:	drivers/media/i2c/ov5647.c
 
+OMNIVISION OV5670 SENSOR DRIVER
+M:	Chiranjeevi Rapolu <chiranjeevi.rapolu@intel.com>
+M:	Hyungwoo Yang <hyungwoo.yang@intel.com>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+S:	Maintained
+F:	drivers/media/i2c/ov5670.c
+
+OMNIVISION OV5675 SENSOR DRIVER
+M:	Shawn Tu <shawnx.tu@intel.com>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+S:	Maintained
+F:	drivers/media/i2c/ov5675.c
+
 OMNIVISION OV5695 SENSOR DRIVER
 M:	Shunqian Zheng <zhengsq@rock-chips.com>
 L:	linux-media@vger.kernel.org
@@ -13747,7 +13770,8 @@
 F:	Documentation/ABI/*/sysfs-driver-hid-roccat*
 
 ROCKCHIP RASTER 2D GRAPHIC ACCELERATION UNIT DRIVER
-M:	Jacob chen <jacob2.chen@rock-chips.com>
+M:	Jacob Chen <jacob-chen@iotwrt.com>
+M:	Ezequiel Garcia <ezequiel@collabora.com>
 L:	linux-media@vger.kernel.org
 S:	Maintained
 F:	drivers/media/platform/rockchip/rga/
@@ -13757,7 +13781,7 @@
 M:	Ezequiel Garcia <ezequiel@collabora.com>
 L:	linux-media@vger.kernel.org
 S:	Maintained
-F:	drivers/staging/media/platform/hantro/
+F:	drivers/staging/media/hantro/
 F:	Documentation/devicetree/bindings/media/rockchip-vpu.txt
 
 ROCKER DRIVER
@@ -17822,14 +17846,6 @@
 F:	mm/zpool.c
 F:	include/linux/zpool.h
 
-ZR36067 VIDEO FOR LINUX DRIVER
-L:	mjpeg-users@lists.sourceforge.net
-L:	linux-media@vger.kernel.org
-W:	http://mjpeg.sourceforge.net/driver-zoran/
-T:	hg https://linuxtv.org/hg/v4l-dvb
-S:	Odd Fixes
-F:	drivers/staging/media/zoran/
-
 ZRAM COMPRESSED RAM BLOCK DEVICE DRVIER
 M:	Minchan Kim <minchan@kernel.org>
 M:	Nitin Gupta <ngupta@vflare.org>
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index cc0d08d..5a2e198 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -10,6 +10,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/of.h>
@@ -43,11 +44,17 @@
 };
 #endif
 
+static u64 omap_vout_dma_mask = DMA_BIT_MASK(32);
+
 static struct platform_device omap_vout_device = {
 	.name		= "omap_vout",
 	.num_resources	= ARRAY_SIZE(omap_vout_resource),
 	.resource 	= &omap_vout_resource[0],
 	.id		= -1,
+	.dev		= {
+		.dma_mask		= &omap_vout_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
 };
 
 int __init omap_init_vout(void)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index 00cb1ba..3fd3e86 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -186,7 +186,7 @@
 		.width  = SENSOR_RES_X / 2,
 		.height = SENSOR_RES_Y / 2,
 		.field = V4L2_FIELD_NONE,
-		.colorspace = V4L2_COLORSPACE_SRGB,
+		.colorspace = V4L2_COLORSPACE_RAW,
 		.bytesperline = SENSOR_RES_X / 2,
 		.sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
 	},
@@ -195,7 +195,7 @@
 		.width  = SENSOR_RES_X / 2,
 		.height = SENSOR_RES_Y / 2,
 		.field = V4L2_FIELD_NONE,
-		.colorspace = V4L2_COLORSPACE_SRGB,
+		.colorspace = V4L2_COLORSPACE_RAW,
 		.bytesperline = SENSOR_RES_X / 2,
 		.sizeimage = (SENSOR_RES_X/2) * (SENSOR_RES_Y/2),
 	}
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 21cd9c0..b36a413 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -190,7 +190,7 @@
 	depends on HAS_IOMEM
 	select I2C
 	select I2C_MUX
-	default y
+	default y if !EMBEDDED
 	help
 	  By default, a media driver auto-selects all possible ancillary
 	  devices such as tuners, sensors, video encoders/decoders and
@@ -207,6 +207,11 @@
 
 	  If unsure say Y.
 
+config MEDIA_HIDE_ANCILLARY_SUBDRV
+        bool
+        depends on MEDIA_SUBDRV_AUTOSELECT && !COMPILE_TEST && !EXPERT
+        default y
+
 config MEDIA_ATTACH
 	bool
 	depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index 451c61b..5ef7dae 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -1614,6 +1614,9 @@
 void cec_s_conn_info(struct cec_adapter *adap,
 		     const struct cec_connector_info *conn_info)
 {
+	if (IS_ERR_OR_NULL(adap))
+		return;
+
 	if (!(adap->capabilities & CEC_CAP_CONNECTOR_INFO))
 		return;
 
diff --git a/drivers/media/cec/cec-notifier.c b/drivers/media/cec/cec-notifier.c
index 52a867b..4d82a55 100644
--- a/drivers/media/cec/cec-notifier.c
+++ b/drivers/media/cec/cec-notifier.c
@@ -218,6 +218,8 @@
 
 	mutex_lock(&n->lock);
 	n->callback = NULL;
+	n->cec_adap->notifier = NULL;
+	n->cec_adap = NULL;
 	mutex_unlock(&n->lock);
 	cec_notifier_put(n);
 }
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
index 4c399a4..d161220 100644
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ b/drivers/media/common/saa7146/saa7146_video.c
@@ -20,62 +20,52 @@
 /* format descriptions for capture and preview */
 static struct saa7146_format formats[] = {
 	{
-		.name		= "RGB-8 (3-3-2)",
 		.pixelformat	= V4L2_PIX_FMT_RGB332,
 		.trans		= RGB08_COMPOSED,
 		.depth		= 8,
 		.flags		= 0,
 	}, {
-		.name		= "RGB-16 (5/B-6/G-5/R)",
 		.pixelformat	= V4L2_PIX_FMT_RGB565,
 		.trans		= RGB16_COMPOSED,
 		.depth		= 16,
 		.flags		= 0,
 	}, {
-		.name		= "RGB-24 (B-G-R)",
 		.pixelformat	= V4L2_PIX_FMT_BGR24,
 		.trans		= RGB24_COMPOSED,
 		.depth		= 24,
 		.flags		= 0,
 	}, {
-		.name		= "RGB-32 (B-G-R)",
 		.pixelformat	= V4L2_PIX_FMT_BGR32,
 		.trans		= RGB32_COMPOSED,
 		.depth		= 32,
 		.flags		= 0,
 	}, {
-		.name		= "RGB-32 (R-G-B)",
 		.pixelformat	= V4L2_PIX_FMT_RGB32,
 		.trans		= RGB32_COMPOSED,
 		.depth		= 32,
 		.flags		= 0,
 		.swap		= 0x2,
 	}, {
-		.name		= "Greyscale-8",
 		.pixelformat	= V4L2_PIX_FMT_GREY,
 		.trans		= Y8,
 		.depth		= 8,
 		.flags		= 0,
 	}, {
-		.name		= "YUV 4:2:2 planar (Y-Cb-Cr)",
 		.pixelformat	= V4L2_PIX_FMT_YUV422P,
 		.trans		= YUV422_DECOMPOSED,
 		.depth		= 16,
 		.flags		= FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
 	}, {
-		.name		= "YVU 4:2:0 planar (Y-Cb-Cr)",
 		.pixelformat	= V4L2_PIX_FMT_YVU420,
 		.trans		= YUV420_DECOMPOSED,
 		.depth		= 12,
 		.flags		= FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
 	}, {
-		.name		= "YUV 4:2:0 planar (Y-Cb-Cr)",
 		.pixelformat	= V4L2_PIX_FMT_YUV420,
 		.trans		= YUV420_DECOMPOSED,
 		.depth		= 12,
 		.flags		= FORMAT_IS_PLANAR,
 	}, {
-		.name		= "YUV 4:2:2 (U-Y-V-Y)",
 		.pixelformat	= V4L2_PIX_FMT_UYVY,
 		.trans		= YUV422_COMPOSED,
 		.depth		= 16,
@@ -147,10 +137,10 @@
 	}
 	vv->ov.win = fmt.fmt.win;
 
-	DEB_D("%dx%d+%d+%d %s field=%s\n",
+	DEB_D("%dx%d+%d+%d 0x%08x field=%s\n",
 	      vv->ov.win.w.width, vv->ov.win.w.height,
 	      vv->ov.win.w.left, vv->ov.win.w.top,
-	      vv->ov_fmt->name, v4l2_field_names[vv->ov.win.field]);
+	      vv->ov_fmt->pixelformat, v4l2_field_names[vv->ov.win.field]);
 
 	if (0 != (ret = saa7146_enable_overlay(fh))) {
 		DEB_D("enabling overlay failed: %d\n", ret);
@@ -515,8 +505,6 @@
 {
 	if (f->index >= ARRAY_SIZE(formats))
 		return -EINVAL;
-	strscpy((char *)f->description, formats[f->index].name,
-		sizeof(f->description));
 	f->pixelformat = formats[f->index].pixelformat;
 	return 0;
 }
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
index 07e0629..50f1e0b 100644
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
@@ -217,9 +217,21 @@
 	case V4L2_PIX_FMT_RGB444:
 	case V4L2_PIX_FMT_XRGB444:
 	case V4L2_PIX_FMT_ARGB444:
+	case V4L2_PIX_FMT_RGBX444:
+	case V4L2_PIX_FMT_RGBA444:
+	case V4L2_PIX_FMT_XBGR444:
+	case V4L2_PIX_FMT_ABGR444:
+	case V4L2_PIX_FMT_BGRX444:
+	case V4L2_PIX_FMT_BGRA444:
 	case V4L2_PIX_FMT_RGB555:
 	case V4L2_PIX_FMT_XRGB555:
 	case V4L2_PIX_FMT_ARGB555:
+	case V4L2_PIX_FMT_RGBX555:
+	case V4L2_PIX_FMT_RGBA555:
+	case V4L2_PIX_FMT_XBGR555:
+	case V4L2_PIX_FMT_ABGR555:
+	case V4L2_PIX_FMT_BGRX555:
+	case V4L2_PIX_FMT_BGRA555:
 	case V4L2_PIX_FMT_RGB555X:
 	case V4L2_PIX_FMT_XRGB555X:
 	case V4L2_PIX_FMT_ARGB555X:
@@ -232,6 +244,10 @@
 	case V4L2_PIX_FMT_XBGR32:
 	case V4L2_PIX_FMT_ARGB32:
 	case V4L2_PIX_FMT_ABGR32:
+	case V4L2_PIX_FMT_RGBX32:
+	case V4L2_PIX_FMT_BGRX32:
+	case V4L2_PIX_FMT_RGBA32:
+	case V4L2_PIX_FMT_BGRA32:
 		tpg->color_enc = TGP_COLOR_ENC_RGB;
 		break;
 	case V4L2_PIX_FMT_GREY:
@@ -343,9 +359,21 @@
 	case V4L2_PIX_FMT_RGB444:
 	case V4L2_PIX_FMT_XRGB444:
 	case V4L2_PIX_FMT_ARGB444:
+	case V4L2_PIX_FMT_RGBX444:
+	case V4L2_PIX_FMT_RGBA444:
+	case V4L2_PIX_FMT_XBGR444:
+	case V4L2_PIX_FMT_ABGR444:
+	case V4L2_PIX_FMT_BGRX444:
+	case V4L2_PIX_FMT_BGRA444:
 	case V4L2_PIX_FMT_RGB555:
 	case V4L2_PIX_FMT_XRGB555:
 	case V4L2_PIX_FMT_ARGB555:
+	case V4L2_PIX_FMT_RGBX555:
+	case V4L2_PIX_FMT_RGBA555:
+	case V4L2_PIX_FMT_XBGR555:
+	case V4L2_PIX_FMT_ABGR555:
+	case V4L2_PIX_FMT_BGRX555:
+	case V4L2_PIX_FMT_BGRA555:
 	case V4L2_PIX_FMT_RGB555X:
 	case V4L2_PIX_FMT_XRGB555X:
 	case V4L2_PIX_FMT_ARGB555X:
@@ -375,6 +403,10 @@
 	case V4L2_PIX_FMT_XBGR32:
 	case V4L2_PIX_FMT_ARGB32:
 	case V4L2_PIX_FMT_ABGR32:
+	case V4L2_PIX_FMT_RGBX32:
+	case V4L2_PIX_FMT_BGRX32:
+	case V4L2_PIX_FMT_RGBA32:
+	case V4L2_PIX_FMT_BGRA32:
 	case V4L2_PIX_FMT_YUV32:
 	case V4L2_PIX_FMT_AYUV32:
 	case V4L2_PIX_FMT_XYUV32:
@@ -1007,6 +1039,12 @@
 		case V4L2_PIX_FMT_RGB444:
 		case V4L2_PIX_FMT_XRGB444:
 		case V4L2_PIX_FMT_ARGB444:
+		case V4L2_PIX_FMT_RGBX444:
+		case V4L2_PIX_FMT_RGBA444:
+		case V4L2_PIX_FMT_XBGR444:
+		case V4L2_PIX_FMT_ABGR444:
+		case V4L2_PIX_FMT_BGRX444:
+		case V4L2_PIX_FMT_BGRA444:
 			r >>= 8;
 			g >>= 8;
 			b >>= 8;
@@ -1014,6 +1052,12 @@
 		case V4L2_PIX_FMT_RGB555:
 		case V4L2_PIX_FMT_XRGB555:
 		case V4L2_PIX_FMT_ARGB555:
+		case V4L2_PIX_FMT_RGBX555:
+		case V4L2_PIX_FMT_RGBA555:
+		case V4L2_PIX_FMT_XBGR555:
+		case V4L2_PIX_FMT_ABGR555:
+		case V4L2_PIX_FMT_BGRX555:
+		case V4L2_PIX_FMT_BGRA555:
 		case V4L2_PIX_FMT_RGB555X:
 		case V4L2_PIX_FMT_XRGB555X:
 		case V4L2_PIX_FMT_ARGB555X:
@@ -1237,6 +1281,27 @@
 		buf[0][offset] = (g_u_s << 4) | b_v;
 		buf[0][offset + 1] = (alpha & 0xf0) | r_y_h;
 		break;
+	case V4L2_PIX_FMT_RGBX444:
+		alpha = 0;
+		/* fall through */
+	case V4L2_PIX_FMT_RGBA444:
+		buf[0][offset] = (b_v << 4) | (alpha >> 4);
+		buf[0][offset + 1] = (r_y_h << 4) | g_u_s;
+		break;
+	case V4L2_PIX_FMT_XBGR444:
+		alpha = 0;
+		/* fall through */
+	case V4L2_PIX_FMT_ABGR444:
+		buf[0][offset] = (g_u_s << 4) | r_y_h;
+		buf[0][offset + 1] = (alpha & 0xf0) | b_v;
+		break;
+	case V4L2_PIX_FMT_BGRX444:
+		alpha = 0;
+		/* fall through */
+	case V4L2_PIX_FMT_BGRA444:
+		buf[0][offset] = (r_y_h << 4) | (alpha >> 4);
+		buf[0][offset + 1] = (b_v << 4) | g_u_s;
+		break;
 	case V4L2_PIX_FMT_RGB555:
 	case V4L2_PIX_FMT_XRGB555:
 		alpha = 0;
@@ -1247,6 +1312,30 @@
 		buf[0][offset + 1] = (alpha & 0x80) | (r_y_h << 2)
 						    | (g_u_s >> 3);
 		break;
+	case V4L2_PIX_FMT_RGBX555:
+		alpha = 0;
+		/* fall through */
+	case V4L2_PIX_FMT_RGBA555:
+		buf[0][offset] = (g_u_s << 6) | (b_v << 1) |
+				 ((alpha & 0x80) >> 7);
+		buf[0][offset + 1] = (r_y_h << 3) | (g_u_s >> 2);
+		break;
+	case V4L2_PIX_FMT_XBGR555:
+		alpha = 0;
+		/* fall through */
+	case V4L2_PIX_FMT_ABGR555:
+		buf[0][offset] = (g_u_s << 5) | r_y_h;
+		buf[0][offset + 1] = (alpha & 0x80) | (b_v << 2)
+						    | (g_u_s >> 3);
+		break;
+	case V4L2_PIX_FMT_BGRX555:
+		alpha = 0;
+		/* fall through */
+	case V4L2_PIX_FMT_BGRA555:
+		buf[0][offset] = (g_u_s << 6) | (r_y_h << 1) |
+				 ((alpha & 0x80) >> 7);
+		buf[0][offset + 1] = (b_v << 3) | (g_u_s >> 2);
+		break;
 	case V4L2_PIX_FMT_RGB555X:
 	case V4L2_PIX_FMT_XRGB555X:
 		alpha = 0;
@@ -1286,6 +1375,15 @@
 		buf[0][offset + 2] = g_u_s;
 		buf[0][offset + 3] = b_v;
 		break;
+	case V4L2_PIX_FMT_RGBX32:
+		alpha = 0;
+		/* fall through */
+	case V4L2_PIX_FMT_RGBA32:
+		buf[0][offset] = r_y_h;
+		buf[0][offset + 1] = g_u_s;
+		buf[0][offset + 2] = b_v;
+		buf[0][offset + 3] = alpha;
+		break;
 	case V4L2_PIX_FMT_BGR32:
 	case V4L2_PIX_FMT_XBGR32:
 	case V4L2_PIX_FMT_VUYX32:
@@ -1298,6 +1396,15 @@
 		buf[0][offset + 2] = r_y_h;
 		buf[0][offset + 3] = alpha;
 		break;
+	case V4L2_PIX_FMT_BGRX32:
+		alpha = 0;
+		/* fall through */
+	case V4L2_PIX_FMT_BGRA32:
+		buf[0][offset] = alpha;
+		buf[0][offset + 1] = b_v;
+		buf[0][offset + 2] = g_u_s;
+		buf[0][offset + 3] = r_y_h;
+		break;
 	case V4L2_PIX_FMT_SBGGR8:
 		buf[0][offset] = odd ? g_u_s : b_v;
 		buf[1][offset] = odd ? r_y_h : g_u_s;
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
index 7d77e4d..44cd0e5 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -267,8 +267,14 @@
 
 	/* release the scatterlist cache */
 	if (attach->dma_dir != DMA_NONE)
-		dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
-			attach->dma_dir);
+		/*
+		 * Cache sync can be skipped here, as the vb2_dc memory is
+		 * allocated from device coherent memory, which means the
+		 * memory locations do not require any explicit cache
+		 * maintenance prior or after being used by the device.
+		 */
+		dma_unmap_sg_attrs(db_attach->dev, sgt->sgl, sgt->orig_nents,
+				   attach->dma_dir, DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sgt);
 	kfree(attach);
 	db_attach->priv = NULL;
@@ -293,14 +299,17 @@
 
 	/* release any previous cache */
 	if (attach->dma_dir != DMA_NONE) {
-		dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
-			attach->dma_dir);
+		dma_unmap_sg_attrs(db_attach->dev, sgt->sgl, sgt->orig_nents,
+				   attach->dma_dir, DMA_ATTR_SKIP_CPU_SYNC);
 		attach->dma_dir = DMA_NONE;
 	}
 
-	/* mapping to the client with new direction */
-	sgt->nents = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
-				dma_dir);
+	/*
+	 * mapping to the client with new direction, no cache sync
+	 * required see comment in vb2_dc_dmabuf_ops_detach()
+	 */
+	sgt->nents = dma_map_sg_attrs(db_attach->dev, sgt->sgl, sgt->orig_nents,
+				      dma_dir, DMA_ATTR_SKIP_CPU_SYNC);
 	if (!sgt->nents) {
 		pr_err("failed to map scatterlist\n");
 		mutex_unlock(lock);
diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index 40d76eb..5a9ba38 100644
--- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -872,17 +872,19 @@
 __poll_t vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
 {
 	struct video_device *vfd = video_devdata(file);
-	__poll_t res = 0;
+	__poll_t res;
+
+	res = vb2_core_poll(q, file, wait);
 
 	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
 		struct v4l2_fh *fh = file->private_data;
 
 		poll_wait(file, &fh->wait, wait);
 		if (v4l2_event_pending(fh))
-			res = EPOLLPRI;
+			res |= EPOLLPRI;
 	}
 
-	return res | vb2_core_poll(q, file, wait);
+	return res;
 }
 EXPORT_SYMBOL_GPL(vb2_poll);
 
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 209186c..06ea30a 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -152,6 +152,9 @@
 
 static void dvb_frontend_put(struct dvb_frontend *fe)
 {
+	/* call detach before dropping the reference count */
+	if (fe->ops.detach)
+		fe->ops.detach(fe);
 	/*
 	 * Check if the frontend was registered, as otherwise
 	 * kref was not initialized yet.
@@ -3040,7 +3043,6 @@
 	dvb_frontend_invoke_release(fe, fe->ops.release_sec);
 	dvb_frontend_invoke_release(fe, fe->ops.tuner_ops.release);
 	dvb_frontend_invoke_release(fe, fe->ops.analog_ops.release);
-	dvb_frontend_invoke_release(fe, fe->ops.detach);
 	dvb_frontend_put(fe);
 }
 EXPORT_SYMBOL(dvb_frontend_detach);
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index a3393cd..917fe03 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -339,8 +339,10 @@
 	if (npads) {
 		dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
 				       GFP_KERNEL);
-		if (!dvbdev->pads)
+		if (!dvbdev->pads) {
+			kfree(dvbdev->entity);
 			return -ENOMEM;
+		}
 	}
 
 	switch (type) {
@@ -476,7 +478,7 @@
 		return -ENOMEM;
 	}
 
-	dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
+	dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
 
 	if (!dvbdevfops){
 		kfree (dvbdev);
@@ -492,7 +494,6 @@
 	dvbdev->fops = dvbdevfops;
 	init_waitqueue_head (&dvbdev->wait_queue);
 
-	memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
 	dvbdevfops->owner = adap->module;
 
 	list_add_tail (&dvbdev->list_head, &adap->device_list);
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index dc43749..a29e9ddf 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -1,5 +1,8 @@
+comment "DVB Frontend drivers hidden by 'Autoselect ancillary drivers'"
+	depends on MEDIA_HIDE_ANCILLARY_SUBDRV
+
 menu "Customise DVB Frontends"
-	visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
 
 comment "Multistandard (satellite) frontends"
 	depends on DVB_CORE
diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c
index 42697a5..9fccc90 100644
--- a/drivers/media/dvb-frontends/cx24117.c
+++ b/drivers/media/dvb-frontends/cx24117.c
@@ -619,8 +619,10 @@
 
 	/* send fw */
 	ret = i2c_transfer(state->priv->i2c, &msg, 1);
-	if (ret < 0)
+	if (ret < 0) {
+		kfree(buf);
 		return ret;
+	}
 
 	kfree(buf);
 
diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c
index ac519c3e..3d84ee1 100644
--- a/drivers/media/dvb-frontends/cx24123.c
+++ b/drivers/media/dvb-frontends/cx24123.c
@@ -431,7 +431,7 @@
 	u32 div = a / b;
 	if (a % b >= b / 2)
 		++div;
-	if (div < (1 << 31)) {
+	if (div < (1UL << 31)) {
 		for (exp = 1; div > exp; nearest++)
 			exp += exp;
 	}
diff --git a/drivers/media/dvb-frontends/cxd2099.c b/drivers/media/dvb-frontends/cxd2099.c
index 5264e87..f88b535 100644
--- a/drivers/media/dvb-frontends/cxd2099.c
+++ b/drivers/media/dvb-frontends/cxd2099.c
@@ -594,7 +594,7 @@
 	return ecount;
 }
 
-static struct dvb_ca_en50221 en_templ = {
+static const struct dvb_ca_en50221 en_templ = {
 	.read_attribute_mem  = read_attribute_mem,
 	.write_attribute_mem = write_attribute_mem,
 	.read_cam_control    = read_cam_control,
diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c
index 1f006f8..d137199 100644
--- a/drivers/media/dvb-frontends/cxd2820r_core.c
+++ b/drivers/media/dvb-frontends/cxd2820r_core.c
@@ -632,12 +632,11 @@
 	 * one dummy I2C client in in order to get own I2C client for each
 	 * register bank.
 	 */
-	priv->client[1] = i2c_new_dummy(client->adapter, client->addr | (1 << 1));
-	if (!priv->client[1]) {
-		ret = -ENODEV;
+	priv->client[1] = i2c_new_dummy_device(client->adapter, client->addr | (1 << 1));
+	if (IS_ERR(priv->client[1])) {
+		ret = PTR_ERR(priv->client[1]);
 		dev_err(&client->dev, "I2C registration failed\n");
-		if (ret)
-			goto err_regmap_0_regmap_exit;
+		goto err_regmap_0_regmap_exit;
 	}
 
 	priv->regmap[1] = regmap_init_i2c(priv->client[1], &regmap_config1);
diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c
index 52f5e697..0d22c70 100644
--- a/drivers/media/dvb-frontends/dib7000p.c
+++ b/drivers/media/dvb-frontends/dib7000p.c
@@ -2036,7 +2036,8 @@
 	if (i2c_transfer(i2c_adap, msg, 2) == 2)
 		if (rx[0] == 0x01 && rx[1] == 0xb3) {
 			dprintk("-D-  DiB7000PC detected\n");
-			return 1;
+			ret = 1;
+			goto out;
 		}
 
 	msg[0].addr = msg[1].addr = 0x40;
@@ -2044,11 +2045,13 @@
 	if (i2c_transfer(i2c_adap, msg, 2) == 2)
 		if (rx[0] == 0x01 && rx[1] == 0xb3) {
 			dprintk("-D-  DiB7000PC detected\n");
-			return 1;
+			ret = 1;
+			goto out;
 		}
 
 	dprintk("-D-  DiB7000PC not detected\n");
 
+out:
 	kfree(rx);
 rx_memory_error:
 	kfree(tx);
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index a6876fa..2f5af48 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -12287,7 +12287,8 @@
 	if (state == NULL)
 		goto error;
 
-	demod = kmalloc(sizeof(struct drx_demod_instance), GFP_KERNEL);
+	demod = kmemdup(&drxj_default_demod_g,
+			sizeof(struct drx_demod_instance), GFP_KERNEL);
 	if (demod == NULL)
 		goto error;
 
@@ -12311,8 +12312,6 @@
 	state->demod = demod;
 
 	/* setup the demod data */
-	memcpy(demod, &drxj_default_demod_g, sizeof(struct drx_demod_instance));
-
 	demod->my_i2c_dev_addr = demod_addr;
 	demod->my_common_attr = demod_comm_attr;
 	demod->my_i2c_dev_addr->user_data = state;
diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c
index ba0c491..d45b4dd 100644
--- a/drivers/media/dvb-frontends/dvb-pll.c
+++ b/drivers/media/dvb-frontends/dvb-pll.c
@@ -9,6 +9,7 @@
 
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/idr.h>
 #include <linux/dvb/frontend.h>
 #include <asm/types.h>
 
@@ -34,8 +35,7 @@
 };
 
 #define DVB_PLL_MAX 64
-
-static unsigned int dvb_pll_devcount;
+static DEFINE_IDA(pll_ida);
 
 static int debug;
 module_param(debug, int, 0644);
@@ -787,6 +787,7 @@
 	struct dvb_pll_priv *priv = NULL;
 	int ret;
 	const struct dvb_pll_desc *desc;
+	int nr;
 
 	b1 = kmalloc(1, GFP_KERNEL);
 	if (!b1)
@@ -795,9 +796,14 @@
 	b1[0] = 0;
 	msg.buf = b1;
 
-	if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
-	    (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))
-		pll_desc_id = id[dvb_pll_devcount];
+	nr = ida_simple_get(&pll_ida, 0, DVB_PLL_MAX, GFP_KERNEL);
+	if (nr < 0) {
+		kfree(b1);
+		return NULL;
+	}
+
+	if (id[nr] > DVB_PLL_UNDEFINED && id[nr] < ARRAY_SIZE(pll_list))
+		pll_desc_id = id[nr];
 
 	BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list));
 
@@ -808,24 +814,20 @@
 			fe->ops.i2c_gate_ctrl(fe, 1);
 
 		ret = i2c_transfer (i2c, &msg, 1);
-		if (ret != 1) {
-			kfree(b1);
-			return NULL;
-		}
+		if (ret != 1)
+			goto out;
 		if (fe->ops.i2c_gate_ctrl)
 			     fe->ops.i2c_gate_ctrl(fe, 0);
 	}
 
 	priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
-	if (!priv) {
-		kfree(b1);
-		return NULL;
-	}
+	if (!priv)
+		goto out;
 
 	priv->pll_i2c_address = pll_addr;
 	priv->i2c = i2c;
 	priv->pll_desc = desc;
-	priv->nr = dvb_pll_devcount++;
+	priv->nr = nr;
 
 	memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops,
 	       sizeof(struct dvb_tuner_ops));
@@ -858,6 +860,11 @@
 	kfree(b1);
 
 	return fe;
+out:
+	kfree(b1);
+	ida_simple_remove(&pll_ida, nr);
+
+	return NULL;
 }
 EXPORT_SYMBOL(dvb_pll_attach);
 
@@ -894,9 +901,10 @@
 
 static int dvb_pll_remove(struct i2c_client *client)
 {
-	struct dvb_frontend *fe;
+	struct dvb_frontend *fe = i2c_get_clientdata(client);
+	struct dvb_pll_priv *priv = fe->tuner_priv;
 
-	fe = i2c_get_clientdata(client);
+	ida_simple_remove(&pll_ida, priv->nr);
 	dvb_pll_release(fe);
 	return 0;
 }
diff --git a/drivers/media/dvb-frontends/mn88443x.c b/drivers/media/dvb-frontends/mn88443x.c
index 9ec1aee..e452878 100644
--- a/drivers/media/dvb-frontends/mn88443x.c
+++ b/drivers/media/dvb-frontends/mn88443x.c
@@ -722,9 +722,9 @@
 	 * Chip has two I2C addresses for each satellite/terrestrial system.
 	 * ISDB-T uses address ISDB-S + 4, so we register a dummy client.
 	 */
-	chip->client_t = i2c_new_dummy(client->adapter, client->addr + 4);
-	if (!chip->client_t)
-		return -ENODEV;
+	chip->client_t = i2c_new_dummy_device(client->adapter, client->addr + 4);
+	if (IS_ERR(chip->client_t))
+		return PTR_ERR(chip->client_t);
 
 	chip->regmap_t = devm_regmap_init_i2c(chip->client_t, &regmap_config);
 	if (IS_ERR(chip->regmap_t)) {
diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
index 731b44b..73922fc 100644
--- a/drivers/media/dvb-frontends/mn88472.c
+++ b/drivers/media/dvb-frontends/mn88472.c
@@ -612,12 +612,11 @@
 	 * Also, register bank 2 do not support sequential I/O. Only single
 	 * register write or read is allowed to that bank.
 	 */
-	dev->client[1] = i2c_new_dummy(client->adapter, 0x1a);
-	if (!dev->client[1]) {
-		ret = -ENODEV;
+	dev->client[1] = i2c_new_dummy_device(client->adapter, 0x1a);
+	if (IS_ERR(dev->client[1])) {
+		ret = PTR_ERR(dev->client[1]);
 		dev_err(&client->dev, "I2C registration failed\n");
-		if (ret)
-			goto err_regmap_0_regmap_exit;
+		goto err_regmap_0_regmap_exit;
 	}
 	dev->regmap[1] = regmap_init_i2c(dev->client[1], &regmap_config);
 	if (IS_ERR(dev->regmap[1])) {
@@ -626,12 +625,11 @@
 	}
 	i2c_set_clientdata(dev->client[1], dev);
 
-	dev->client[2] = i2c_new_dummy(client->adapter, 0x1c);
-	if (!dev->client[2]) {
-		ret = -ENODEV;
+	dev->client[2] = i2c_new_dummy_device(client->adapter, 0x1c);
+	if (IS_ERR(dev->client[2])) {
+		ret = PTR_ERR(dev->client[2]);
 		dev_err(&client->dev, "2nd I2C registration failed\n");
-		if (ret)
-			goto err_regmap_1_regmap_exit;
+		goto err_regmap_1_regmap_exit;
 	}
 	dev->regmap[2] = regmap_init_i2c(dev->client[2], &regmap_config);
 	if (IS_ERR(dev->regmap[2])) {
diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c
index 08118b3..4838969 100644
--- a/drivers/media/dvb-frontends/mn88473.c
+++ b/drivers/media/dvb-frontends/mn88473.c
@@ -657,12 +657,11 @@
 	 * Also, register bank 2 do not support sequential I/O. Only single
 	 * register write or read is allowed to that bank.
 	 */
-	dev->client[1] = i2c_new_dummy(client->adapter, 0x1a);
-	if (dev->client[1] == NULL) {
-		ret = -ENODEV;
+	dev->client[1] = i2c_new_dummy_device(client->adapter, 0x1a);
+	if (IS_ERR(dev->client[1])) {
+		ret = PTR_ERR(dev->client[1]);
 		dev_err(&client->dev, "I2C registration failed\n");
-		if (ret)
-			goto err_regmap_0_regmap_exit;
+		goto err_regmap_0_regmap_exit;
 	}
 	dev->regmap[1] = regmap_init_i2c(dev->client[1], &regmap_config);
 	if (IS_ERR(dev->regmap[1])) {
@@ -671,12 +670,11 @@
 	}
 	i2c_set_clientdata(dev->client[1], dev);
 
-	dev->client[2] = i2c_new_dummy(client->adapter, 0x1c);
-	if (dev->client[2] == NULL) {
-		ret = -ENODEV;
+	dev->client[2] = i2c_new_dummy_device(client->adapter, 0x1c);
+	if (IS_ERR(dev->client[2])) {
+		ret = PTR_ERR(dev->client[2]);
 		dev_err(&client->dev, "2nd I2C registration failed\n");
-		if (ret)
-			goto err_regmap_1_regmap_exit;
+		goto err_regmap_1_regmap_exit;
 	}
 	dev->regmap[2] = regmap_init_i2c(dev->client[2], &regmap_config);
 	if (IS_ERR(dev->regmap[2])) {
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c
index e05c21d..60d1e59 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.c
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.c
@@ -81,11 +81,9 @@
 
 static struct rtl2832_sdr_format formats[] = {
 	{
-		.name		= "Complex U8",
 		.pixelformat	= V4L2_SDR_FMT_CU8,
 		.buffersize	= BULK_BUFFER_SIZE,
 	}, {
-		.name		= "Complex U16LE (emulated)",
 		.pixelformat	= V4L2_SDR_FMT_CU16LE,
 		.buffersize	= BULK_BUFFER_SIZE * 2,
 	},
@@ -1116,7 +1114,6 @@
 	if (f->index >= dev->num_formats)
 		return -EINVAL;
 
-	strscpy(f->description, formats[f->index].name, sizeof(f->description));
 	f->pixelformat = formats[f->index].pixelformat;
 
 	return 0;
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 168c503..14b93a7 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -11,6 +11,13 @@
 
 static const struct dvb_frontend_ops si2168_ops;
 
+static void cmd_init(struct si2168_cmd *cmd, const u8 *buf, int wlen, int rlen)
+{
+	memcpy(cmd->args, buf, wlen);
+	cmd->wlen = wlen;
+	cmd->rlen = rlen;
+}
+
 /* execute firmware command */
 static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd)
 {
@@ -82,16 +89,23 @@
 
 	dev_dbg(&client->dev, "%s acquire: %d\n", __func__, acquire);
 
+	/* set manual value */
+	if (dev->ts_mode & SI2168_TS_CLK_MANUAL) {
+		cmd_init(&cmd, "\x14\x00\x0d\x10\xe8\x03", 6, 4);
+		ret = si2168_cmd_execute(client, &cmd);
+		if (ret)
+			return ret;
+	}
 	/* set TS_MODE property */
-	memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6);
+	cmd_init(&cmd, "\x14\x00\x01\x10\x10\x00", 6, 4);
+	if (dev->ts_mode & SI2168_TS_CLK_MANUAL)
+		cmd.args[4] = SI2168_TS_CLK_MANUAL;
 	if (acquire)
 		cmd.args[4] |= dev->ts_mode;
 	else
 		cmd.args[4] |= SI2168_TS_TRISTATE;
 	if (dev->ts_clock_gapped)
 		cmd.args[4] |= 0x40;
-	cmd.wlen = 6;
-	cmd.rlen = 4;
 	ret = si2168_cmd_execute(client, &cmd);
 
 	return ret;
@@ -115,19 +129,13 @@
 
 	switch (c->delivery_system) {
 	case SYS_DVBT:
-		memcpy(cmd.args, "\xa0\x01", 2);
-		cmd.wlen = 2;
-		cmd.rlen = 13;
+		cmd_init(&cmd, "\xa0\x01", 2, 13);
 		break;
 	case SYS_DVBC_ANNEX_A:
-		memcpy(cmd.args, "\x90\x01", 2);
-		cmd.wlen = 2;
-		cmd.rlen = 9;
+		cmd_init(&cmd, "\x90\x01", 2, 9);
 		break;
 	case SYS_DVBT2:
-		memcpy(cmd.args, "\x50\x01", 2);
-		cmd.wlen = 2;
-		cmd.rlen = 14;
+		cmd_init(&cmd, "\x50\x01", 2, 14);
 		break;
 	default:
 		ret = -EINVAL;
@@ -164,9 +172,7 @@
 
 	/* BER */
 	if (*status & FE_HAS_VITERBI) {
-		memcpy(cmd.args, "\x82\x00", 2);
-		cmd.wlen = 2;
-		cmd.rlen = 3;
+		cmd_init(&cmd, "\x82\x00", 2, 3);
 		ret = si2168_cmd_execute(client, &cmd);
 		if (ret)
 			goto err;
@@ -197,9 +203,7 @@
 
 	/* UCB */
 	if (*status & FE_HAS_SYNC) {
-		memcpy(cmd.args, "\x84\x01", 2);
-		cmd.wlen = 2;
-		cmd.rlen = 3;
+		cmd_init(&cmd, "\x84\x01", 2, 3);
 		ret = si2168_cmd_execute(client, &cmd);
 		if (ret)
 			goto err;
@@ -285,22 +289,18 @@
 			goto err;
 	}
 
-	memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5);
-	cmd.wlen = 5;
-	cmd.rlen = 5;
+	cmd_init(&cmd, "\x88\x02\x02\x02\x02", 5, 5);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
 	/* that has no big effect */
 	if (c->delivery_system == SYS_DVBT)
-		memcpy(cmd.args, "\x89\x21\x06\x11\xff\x98", 6);
+		cmd_init(&cmd, "\x89\x21\x06\x11\xff\x98", 6, 3);
 	else if (c->delivery_system == SYS_DVBC_ANNEX_A)
-		memcpy(cmd.args, "\x89\x21\x06\x11\x89\xf0", 6);
+		cmd_init(&cmd, "\x89\x21\x06\x11\x89\xf0", 6, 3);
 	else if (c->delivery_system == SYS_DVBT2)
-		memcpy(cmd.args, "\x89\x21\x06\x11\x89\x20", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 3;
+		cmd_init(&cmd, "\x89\x21\x06\x11\x89\x20", 6, 3);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
@@ -317,103 +317,77 @@
 			goto err;
 	}
 
-	memcpy(cmd.args, "\x51\x03", 2);
-	cmd.wlen = 2;
-	cmd.rlen = 12;
+	cmd_init(&cmd, "\x51\x03", 2, 12);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x12\x08\x04", 3);
-	cmd.wlen = 3;
-	cmd.rlen = 3;
+	cmd_init(&cmd, "\x12\x08\x04", 3, 3);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 4;
+	cmd_init(&cmd, "\x14\x00\x0c\x10\x12\x00", 6, 4);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 4;
+	cmd_init(&cmd, "\x14\x00\x06\x10\x24\x00", 6, 4);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 4;
+	cmd_init(&cmd, "\x14\x00\x07\x10\x00\x24", 6, 4);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
+	cmd_init(&cmd, "\x14\x00\x0a\x10\x00\x00", 6, 4);
 	cmd.args[4] = delivery_system | bandwidth;
 	if (dev->spectral_inversion)
 		cmd.args[5] |= 1;
-	cmd.wlen = 6;
-	cmd.rlen = 4;
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
 	/* set DVB-C symbol rate */
 	if (c->delivery_system == SYS_DVBC_ANNEX_A) {
-		memcpy(cmd.args, "\x14\x00\x02\x11", 4);
+		cmd_init(&cmd, "\x14\x00\x02\x11\x00\x00", 6, 4);
 		cmd.args[4] = ((c->symbol_rate / 1000) >> 0) & 0xff;
 		cmd.args[5] = ((c->symbol_rate / 1000) >> 8) & 0xff;
-		cmd.wlen = 6;
-		cmd.rlen = 4;
 		ret = si2168_cmd_execute(client, &cmd);
 		if (ret)
 			goto err;
 	}
 
-	memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 4;
+	cmd_init(&cmd, "\x14\x00\x0f\x10\x10\x00", 6, 4);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x08", 6);
+	cmd_init(&cmd, "\x14\x00\x09\x10\xe3\x08", 6, 4);
 	cmd.args[5] |= dev->ts_clock_inv ? 0x00 : 0x10;
-	cmd.wlen = 6;
-	cmd.rlen = 4;
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x05", 6);
+	cmd_init(&cmd, "\x14\x00\x08\x10\xd7\x05", 6, 4);
 	cmd.args[5] |= dev->ts_clock_inv ? 0x00 : 0x10;
-	cmd.wlen = 6;
-	cmd.rlen = 4;
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 4;
+	cmd_init(&cmd, "\x14\x00\x01\x12\x00\x00", 6, 4);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x00", 6);
-	cmd.wlen = 6;
-	cmd.rlen = 4;
+	cmd_init(&cmd, "\x14\x00\x01\x03\x0c\x00", 6, 4);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
-	memcpy(cmd.args, "\x85", 1);
-	cmd.wlen = 1;
-	cmd.rlen = 1;
+	cmd_init(&cmd, "\x85", 1, 1);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
@@ -443,26 +417,21 @@
 	dev_dbg(&client->dev, "\n");
 
 	/* initialize */
-	memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
-	cmd.wlen = 13;
-	cmd.rlen = 0;
+	cmd_init(&cmd, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00",
+		 13, 0);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
 	if (dev->warm) {
 		/* resume */
-		memcpy(cmd.args, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8);
-		cmd.wlen = 8;
-		cmd.rlen = 1;
+		cmd_init(&cmd, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8, 1);
 		ret = si2168_cmd_execute(client, &cmd);
 		if (ret)
 			goto err;
 
 		udelay(100);
-		memcpy(cmd.args, "\x85", 1);
-		cmd.wlen = 1;
-		cmd.rlen = 1;
+		cmd_init(&cmd, "\x85", 1, 1);
 		ret = si2168_cmd_execute(client, &cmd);
 		if (ret)
 			goto err;
@@ -471,9 +440,7 @@
 	}
 
 	/* power up */
-	memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
-	cmd.wlen = 8;
-	cmd.rlen = 1;
+	cmd_init(&cmd, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8, 1);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
@@ -511,9 +478,8 @@
 				ret = -EINVAL;
 				break;
 			}
-			memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
-			cmd.wlen = len;
-			cmd.rlen = 1;
+			cmd_init(&cmd, &fw->data[(fw->size - remaining) + 1],
+				 len, 1);
 			ret = si2168_cmd_execute(client, &cmd);
 			if (ret)
 				break;
@@ -521,10 +487,7 @@
 	} else if (fw->size % 8 == 0) {
 		/* firmware is in the old format */
 		for (remaining = fw->size; remaining > 0; remaining -= 8) {
-			len = 8;
-			memcpy(cmd.args, &fw->data[fw->size - remaining], len);
-			cmd.wlen = len;
-			cmd.rlen = 1;
+			cmd_init(&cmd, &fw->data[fw->size - remaining], 8, 1);
 			ret = si2168_cmd_execute(client, &cmd);
 			if (ret)
 				break;
@@ -541,17 +504,13 @@
 
 	release_firmware(fw);
 
-	memcpy(cmd.args, "\x01\x01", 2);
-	cmd.wlen = 2;
-	cmd.rlen = 1;
+	cmd_init(&cmd, "\x01\x01", 2, 1);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
 
 	/* query firmware version */
-	memcpy(cmd.args, "\x11", 1);
-	cmd.wlen = 1;
-	cmd.rlen = 10;
+	cmd_init(&cmd, "\x11", 1, 10);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
@@ -609,9 +568,7 @@
 	if (dev->version > ('B' << 24 | 4 << 16 | 0 << 8 | 11 << 0))
 		dev->warm = false;
 
-	memcpy(cmd.args, "\x13", 1);
-	cmd.wlen = 1;
-	cmd.rlen = 0;
+	cmd_init(&cmd, "\x13", 1, 0);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
@@ -637,9 +594,7 @@
 	struct si2168_cmd cmd;
 
 	/* open I2C gate */
-	memcpy(cmd.args, "\xc0\x0d\x01", 3);
-	cmd.wlen = 3;
-	cmd.rlen = 0;
+	cmd_init(&cmd, "\xc0\x0d\x01", 3, 0);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
@@ -657,9 +612,7 @@
 	struct si2168_cmd cmd;
 
 	/* close I2C gate */
-	memcpy(cmd.args, "\xc0\x0d\x00", 3);
-	cmd.wlen = 3;
-	cmd.rlen = 0;
+	cmd_init(&cmd, "\xc0\x0d\x00", 3, 0);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err;
@@ -730,25 +683,20 @@
 	mutex_init(&dev->i2c_mutex);
 
 	/* Initialize */
-	memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
-	cmd.wlen = 13;
-	cmd.rlen = 0;
+	cmd_init(&cmd, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00",
+		 13, 0);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err_kfree;
 
 	/* Power up */
-	memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
-	cmd.wlen = 8;
-	cmd.rlen = 1;
+	cmd_init(&cmd, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8, 1);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err_kfree;
 
 	/* Query chip revision */
-	memcpy(cmd.args, "\x02", 1);
-	cmd.wlen = 1;
-	cmd.rlen = 13;
+	cmd_init(&cmd, "\x02", 1, 13);
 	ret = si2168_cmd_execute(client, &cmd);
 	if (ret)
 		goto err_kfree;
diff --git a/drivers/media/dvb-frontends/si2168.h b/drivers/media/dvb-frontends/si2168.h
index 3b04f84..50dccb3 100644
--- a/drivers/media/dvb-frontends/si2168.h
+++ b/drivers/media/dvb-frontends/si2168.h
@@ -30,6 +30,7 @@
 #define SI2168_TS_PARALLEL	0x06
 #define SI2168_TS_SERIAL	0x03
 #define SI2168_TS_TRISTATE	0x00
+#define SI2168_TS_CLK_MANUAL	0x20
 	u8 ts_mode;
 
 	/* TS clock inverted */
diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c
index 0c50740..7d93a16 100644
--- a/drivers/media/dvb-frontends/stv0900_core.c
+++ b/drivers/media/dvb-frontends/stv0900_core.c
@@ -270,7 +270,7 @@
 
 static u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
 {
-	u32 mclk = 90000000, div = 0, ad_div = 0;
+	u32 mclk, div, ad_div;
 
 	div = stv0900_get_bits(intp, F0900_M_DIV);
 	ad_div = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
diff --git a/drivers/media/dvb-frontends/zd1301_demod.c b/drivers/media/dvb-frontends/zd1301_demod.c
index 96adbba..bbabe6a 100644
--- a/drivers/media/dvb-frontends/zd1301_demod.c
+++ b/drivers/media/dvb-frontends/zd1301_demod.c
@@ -421,8 +421,7 @@
 	} else {
 		dev_dbg(&pdev->dev, "unknown msg[0].len=%u\n", msg[0].len);
 		ret = -EOPNOTSUPP;
-		if (ret)
-			goto err;
+		goto err;
 	}
 
 	return num;
diff --git a/drivers/media/firewire/firedtv-ci.c b/drivers/media/firewire/firedtv-ci.c
index a960a0c..9363d00 100644
--- a/drivers/media/firewire/firedtv-ci.c
+++ b/drivers/media/firewire/firedtv-ci.c
@@ -217,7 +217,7 @@
 	.llseek		= noop_llseek,
 };
 
-static struct dvb_device fdtv_ca = {
+static const struct dvb_device fdtv_ca = {
 	.users		= 1,
 	.readers	= 1,
 	.writers	= 1,
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 79ce9ec..7eee181 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -22,8 +22,11 @@
 # Encoder / Decoder module configuration
 #
 
+comment "I2C drivers hidden by 'Autoselect ancillary drivers'"
+	depends on MEDIA_HIDE_ANCILLARY_SUBDRV
+
 menu "I2C Encoders, decoders, sensors and other helper chips"
-	visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
 
 comment "Audio decoders, processors and mixers"
 
@@ -723,6 +726,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called ov5670.
 
+config VIDEO_OV5675
+	tristate "OmniVision OV5675 sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_CAMERA_SUPPORT
+	depends on MEDIA_CONTROLLER
+	select V4L2_FWNODE
+	help
+	  This is a Video4Linux2 sensor driver for the OmniVision
+	  OV5675 camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ov5675.
+
 config VIDEO_OV5695
 	tristate "OmniVision OV5695 sensor support"
 	depends on I2C && VIDEO_V4L2
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index fd4ea86..beb170b 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -70,6 +70,7 @@
 obj-$(CONFIG_VIDEO_OV5645) += ov5645.o
 obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
 obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
+obj-$(CONFIG_VIDEO_OV5675) += ov5675.o
 obj-$(CONFIG_VIDEO_OV5695) += ov5695.o
 obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
 obj-$(CONFIG_VIDEO_OV7251) += ov7251.o
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index aa8b04c..8679a44 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -1148,10 +1148,10 @@
 	v4l2_dbg(1, debug, sd, "reg 0x41 0x%x, chip version (reg 0x00) 0x%x\n",
 		 ad9389b_rd(sd, 0x41), state->chip_revision);
 
-	state->edid_i2c_client = i2c_new_dummy(client->adapter, (0x7e>>1));
-	if (state->edid_i2c_client == NULL) {
+	state->edid_i2c_client = i2c_new_dummy_device(client->adapter, (0x7e >> 1));
+	if (IS_ERR(state->edid_i2c_client)) {
 		v4l2_err(sd, "failed to register edid i2c client\n");
-		err = -ENOMEM;
+		err = PTR_ERR(state->edid_i2c_client);
 		goto err_entity;
 	}
 
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 6f3dc88..e780969 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1329,17 +1329,17 @@
 	}
 
 	if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
-		state->csi_client = i2c_new_dummy(client->adapter,
+		state->csi_client = i2c_new_dummy_device(client->adapter,
 				ADV7180_DEFAULT_CSI_I2C_ADDR);
-		if (!state->csi_client)
-			return -ENOMEM;
+		if (IS_ERR(state->csi_client))
+			return PTR_ERR(state->csi_client);
 	}
 
 	if (state->chip_info->flags & ADV7180_FLAG_I2P) {
-		state->vpp_client = i2c_new_dummy(client->adapter,
+		state->vpp_client = i2c_new_dummy_device(client->adapter,
 				ADV7180_DEFAULT_VPP_I2C_ADDR);
-		if (!state->vpp_client) {
-			ret = -ENOMEM;
+		if (IS_ERR(state->vpp_client)) {
+			ret = PTR_ERR(state->vpp_client);
 			goto err_unregister_csi_client;
 		}
 	}
diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index 4a441ee..63e94df 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -428,8 +428,7 @@
 	return pdata;
 }
 
-static int adv7343_probe(struct i2c_client *client,
-				const struct i2c_device_id *id)
+static int adv7343_probe(struct i2c_client *client)
 {
 	struct adv7343_state *state;
 	int err;
@@ -524,7 +523,7 @@
 		.of_match_table = of_match_ptr(adv7343_of_match),
 		.name	= "adv7343",
 	},
-	.probe		= adv7343_probe,
+	.probe_new	= adv7343_probe,
 	.remove		= adv7343_remove,
 	.id_table	= adv7343_id,
 };
diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c
index f57cd77..0a47d47 100644
--- a/drivers/media/i2c/adv748x/adv748x-core.c
+++ b/drivers/media/i2c/adv748x/adv748x-core.c
@@ -668,8 +668,7 @@
 		of_node_put(state->endpoints[i]);
 }
 
-static int adv748x_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id)
+static int adv748x_probe(struct i2c_client *client)
 {
 	struct adv748x_state *state;
 	int ret;
@@ -797,13 +796,6 @@
 	return 0;
 }
 
-static const struct i2c_device_id adv748x_id[] = {
-	{ "adv7481", 0 },
-	{ "adv7482", 0 },
-	{ },
-};
-MODULE_DEVICE_TABLE(i2c, adv748x_id);
-
 static const struct of_device_id adv748x_of_table[] = {
 	{ .compatible = "adi,adv7481", },
 	{ .compatible = "adi,adv7482", },
@@ -816,9 +808,8 @@
 		.name = "adv748x",
 		.of_match_table = adv748x_of_table,
 	},
-	.probe = adv748x_probe,
+	.probe_new = adv748x_probe,
 	.remove = adv748x_remove,
-	.id_table = adv748x_id,
 };
 
 module_i2c_driver(adv748x_driver);
diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c
index 2ad6bdf..62763ec 100644
--- a/drivers/media/i2c/adv7511-v4l2.c
+++ b/drivers/media/i2c/adv7511-v4l2.c
@@ -1872,11 +1872,11 @@
 		goto err_entity;
 	}
 
-	state->i2c_edid = i2c_new_dummy(client->adapter,
+	state->i2c_edid = i2c_new_dummy_device(client->adapter,
 					state->i2c_edid_addr >> 1);
-	if (state->i2c_edid == NULL) {
+	if (IS_ERR(state->i2c_edid)) {
 		v4l2_err(sd, "failed to register edid i2c client\n");
-		err = -ENOMEM;
+		err = PTR_ERR(state->i2c_edid);
 		goto err_entity;
 	}
 
@@ -1889,11 +1889,11 @@
 	}
 
 	if (state->pdata.cec_clk) {
-		state->i2c_cec = i2c_new_dummy(client->adapter,
+		state->i2c_cec = i2c_new_dummy_device(client->adapter,
 					       state->i2c_cec_addr >> 1);
-		if (state->i2c_cec == NULL) {
+		if (IS_ERR(state->i2c_cec)) {
 			v4l2_err(sd, "failed to register cec i2c client\n");
-			err = -ENOMEM;
+			err = PTR_ERR(state->i2c_cec);
 			goto err_unreg_edid;
 		}
 		adv7511_wr(sd, 0xe2, 0x00); /* power up cec section */
@@ -1901,10 +1901,10 @@
 		adv7511_wr(sd, 0xe2, 0x01); /* power down cec section */
 	}
 
-	state->i2c_pktmem = i2c_new_dummy(client->adapter, state->i2c_pktmem_addr >> 1);
-	if (state->i2c_pktmem == NULL) {
+	state->i2c_pktmem = i2c_new_dummy_device(client->adapter, state->i2c_pktmem_addr >> 1);
+	if (IS_ERR(state->i2c_pktmem)) {
 		v4l2_err(sd, "failed to register pktmem i2c client\n");
-		err = -ENOMEM;
+		err = PTR_ERR(state->i2c_pktmem);
 		goto err_unreg_cec;
 	}
 
@@ -1940,8 +1940,7 @@
 err_unreg_pktmem:
 	i2c_unregister_device(state->i2c_pktmem);
 err_unreg_cec:
-	if (state->i2c_cec)
-		i2c_unregister_device(state->i2c_cec);
+	i2c_unregister_device(state->i2c_cec);
 err_unreg_edid:
 	i2c_unregister_device(state->i2c_edid);
 err_entity:
@@ -1967,8 +1966,7 @@
 	adv7511_init_setup(sd);
 	cancel_delayed_work(&state->edid_handler);
 	i2c_unregister_device(state->i2c_edid);
-	if (state->i2c_cec)
-		i2c_unregister_device(state->i2c_cec);
+	i2c_unregister_device(state->i2c_cec);
 	i2c_unregister_device(state->i2c_pktmem);
 	destroy_workqueue(state->work_queue);
 	v4l2_device_unregister_subdev(sd);
@@ -1980,14 +1978,14 @@
 /* ----------------------------------------------------------------------- */
 
 static const struct i2c_device_id adv7511_id[] = {
-	{ "adv7511", 0 },
+	{ "adv7511-v4l2", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, adv7511_id);
 
 static struct i2c_driver adv7511_driver = {
 	.driver = {
-		.name = "adv7511",
+		.name = "adv7511-v4l2",
 	},
 	.probe = adv7511_probe,
 	.remove = adv7511_remove,
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 11ab2df..8856198 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -3351,28 +3351,17 @@
 static void adv7842_unregister_clients(struct v4l2_subdev *sd)
 {
 	struct adv7842_state *state = to_state(sd);
-	if (state->i2c_avlink)
-		i2c_unregister_device(state->i2c_avlink);
-	if (state->i2c_cec)
-		i2c_unregister_device(state->i2c_cec);
-	if (state->i2c_infoframe)
-		i2c_unregister_device(state->i2c_infoframe);
-	if (state->i2c_sdp_io)
-		i2c_unregister_device(state->i2c_sdp_io);
-	if (state->i2c_sdp)
-		i2c_unregister_device(state->i2c_sdp);
-	if (state->i2c_afe)
-		i2c_unregister_device(state->i2c_afe);
-	if (state->i2c_repeater)
-		i2c_unregister_device(state->i2c_repeater);
-	if (state->i2c_edid)
-		i2c_unregister_device(state->i2c_edid);
-	if (state->i2c_hdmi)
-		i2c_unregister_device(state->i2c_hdmi);
-	if (state->i2c_cp)
-		i2c_unregister_device(state->i2c_cp);
-	if (state->i2c_vdp)
-		i2c_unregister_device(state->i2c_vdp);
+	i2c_unregister_device(state->i2c_avlink);
+	i2c_unregister_device(state->i2c_cec);
+	i2c_unregister_device(state->i2c_infoframe);
+	i2c_unregister_device(state->i2c_sdp_io);
+	i2c_unregister_device(state->i2c_sdp);
+	i2c_unregister_device(state->i2c_afe);
+	i2c_unregister_device(state->i2c_repeater);
+	i2c_unregister_device(state->i2c_edid);
+	i2c_unregister_device(state->i2c_hdmi);
+	i2c_unregister_device(state->i2c_cp);
+	i2c_unregister_device(state->i2c_vdp);
 
 	state->i2c_avlink = NULL;
 	state->i2c_cec = NULL;
@@ -3400,9 +3389,12 @@
 		return NULL;
 	}
 
-	cp = i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1);
-	if (!cp)
-		v4l2_err(sd, "register %s on i2c addr 0x%x failed\n", desc, addr);
+	cp = i2c_new_dummy_device(client->adapter, io_read(sd, io_reg) >> 1);
+	if (IS_ERR(cp)) {
+		v4l2_err(sd, "register %s on i2c addr 0x%x failed with %ld\n",
+			 desc, addr, PTR_ERR(cp));
+		cp = NULL;
+	}
 
 	return cp;
 }
diff --git a/drivers/media/i2c/et8ek8/et8ek8_driver.c b/drivers/media/i2c/et8ek8/et8ek8_driver.c
index e6c06cb..256acf7 100644
--- a/drivers/media/i2c/et8ek8/et8ek8_driver.c
+++ b/drivers/media/i2c/et8ek8/et8ek8_driver.c
@@ -1396,8 +1396,7 @@
 	return __et8ek8_set_power(sensor, true);
 }
 
-static int et8ek8_probe(struct i2c_client *client,
-			const struct i2c_device_id *devid)
+static int et8ek8_probe(struct i2c_client *client)
 {
 	struct et8ek8_sensor *sensor;
 	struct device *dev = &client->dev;
@@ -1504,7 +1503,7 @@
 		.pm	= &et8ek8_pm_ops,
 		.of_match_table	= et8ek8_of_table,
 	},
-	.probe		= et8ek8_probe,
+	.probe_new	= et8ek8_probe,
 	.remove		= __exit_p(et8ek8_remove),
 	.id_table	= et8ek8_id_table,
 };
diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c
index f3ff1af..6011cec 100644
--- a/drivers/media/i2c/imx274.c
+++ b/drivers/media/i2c/imx274.c
@@ -1821,8 +1821,7 @@
 };
 MODULE_DEVICE_TABLE(i2c, imx274_id);
 
-static int imx274_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int imx274_probe(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd;
 	struct stimx274 *imx274;
@@ -1984,7 +1983,7 @@
 		.name	= DRIVER_NAME,
 		.of_match_table	= imx274_of_id_table,
 	},
-	.probe		= imx274_probe,
+	.probe_new	= imx274_probe,
 	.remove		= imx274_remove,
 	.id_table	= imx274_id,
 };
diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
index 876d758..e8119ad 100644
--- a/drivers/media/i2c/ir-kbd-i2c.c
+++ b/drivers/media/i2c/ir-kbd-i2c.c
@@ -885,9 +885,11 @@
 	INIT_DELAYED_WORK(&ir->work, ir_work);
 
 	if (probe_tx) {
-		ir->tx_c = i2c_new_dummy(client->adapter, 0x70);
-		if (!ir->tx_c) {
+		ir->tx_c = i2c_new_dummy_device(client->adapter, 0x70);
+		if (IS_ERR(ir->tx_c)) {
 			dev_err(&client->dev, "failed to setup tx i2c address");
+			err = PTR_ERR(ir->tx_c);
+			goto err_out_free;
 		} else if (!zilog_init(ir)) {
 			ir->carrier = 38000;
 			ir->duty_cycle = 40;
@@ -904,7 +906,7 @@
 	return 0;
 
  err_out_free:
-	if (ir->tx_c)
+	if (!IS_ERR(ir->tx_c))
 		i2c_unregister_device(ir->tx_c);
 
 	/* Only frees rc if it were allocated internally */
@@ -916,16 +918,12 @@
 {
 	struct IR_i2c *ir = i2c_get_clientdata(client);
 
-	/* kill outstanding polls */
 	cancel_delayed_work_sync(&ir->work);
 
-	if (ir->tx_c)
-		i2c_unregister_device(ir->tx_c);
+	i2c_unregister_device(ir->tx_c);
 
-	/* unregister device */
 	rc_unregister_device(ir->rc);
 
-	/* free memory */
 	return 0;
 }
 
diff --git a/drivers/media/i2c/max2175.c b/drivers/media/i2c/max2175.c
index 7b226fad..19a3cee 100644
--- a/drivers/media/i2c/max2175.c
+++ b/drivers/media/i2c/max2175.c
@@ -1271,8 +1271,7 @@
 	return 0;
 }
 
-static int max2175_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int max2175_probe(struct i2c_client *client)
 {
 	bool master = true, am_hiz = false;
 	u32 refout_load, refout_bits = 0;	/* REFOUT disabled */
@@ -1433,7 +1432,7 @@
 		.name	= DRIVER_NAME,
 		.of_match_table = max2175_of_ids,
 	},
-	.probe		= max2175_probe,
+	.probe_new	= max2175_probe,
 	.remove		= max2175_remove,
 	.id_table	= max2175_id,
 };
diff --git a/drivers/media/i2c/mt9m001.c b/drivers/media/i2c/mt9m001.c
index 2df743c..5613072 100644
--- a/drivers/media/i2c/mt9m001.c
+++ b/drivers/media/i2c/mt9m001.c
@@ -726,8 +726,7 @@
 	.pad	= &mt9m001_subdev_pad_ops,
 };
 
-static int mt9m001_probe(struct i2c_client *client,
-			 const struct i2c_device_id *did)
+static int mt9m001_probe(struct i2c_client *client)
 {
 	struct mt9m001 *mt9m001;
 	struct i2c_adapter *adapter = client->adapter;
@@ -872,7 +871,7 @@
 		.pm = &mt9m001_pm_ops,
 		.of_match_table = mt9m001_of_match,
 	},
-	.probe		= mt9m001_probe,
+	.probe_new	= mt9m001_probe,
 	.remove		= mt9m001_remove,
 	.id_table	= mt9m001_id,
 };
diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
index 12cb012..17e8253 100644
--- a/drivers/media/i2c/mt9m111.c
+++ b/drivers/media/i2c/mt9m111.c
@@ -533,7 +533,7 @@
 		format->format = *mf;
 		return 0;
 #else
-		return -ENOTTY;
+		return -EINVAL;
 #endif
 	}
 
@@ -1243,8 +1243,7 @@
 	return ret;
 }
 
-static int mt9m111_probe(struct i2c_client *client,
-			 const struct i2c_device_id *did)
+static int mt9m111_probe(struct i2c_client *client)
 {
 	struct mt9m111 *mt9m111;
 	struct i2c_adapter *adapter = client->adapter;
@@ -1388,7 +1387,7 @@
 		.name = "mt9m111",
 		.of_match_table = of_match_ptr(mt9m111_of_match),
 	},
-	.probe		= mt9m111_probe,
+	.probe_new	= mt9m111_probe,
 	.remove		= mt9m111_remove,
 	.id_table	= mt9m111_id,
 };
diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c
index ecd167d..4a4bd5b 100644
--- a/drivers/media/i2c/ov2640.c
+++ b/drivers/media/i2c/ov2640.c
@@ -929,7 +929,7 @@
 		format->format = *mf;
 		return 0;
 #else
-		return -ENOTTY;
+		return -EINVAL;
 #endif
 	}
 
@@ -1190,8 +1190,7 @@
 /*
  * i2c_driver functions
  */
-static int ov2640_probe(struct i2c_client *client,
-			const struct i2c_device_id *did)
+static int ov2640_probe(struct i2c_client *client)
 {
 	struct ov2640_priv	*priv;
 	struct i2c_adapter	*adapter = client->adapter;
@@ -1302,7 +1301,7 @@
 		.name = "ov2640",
 		.of_match_table = of_match_ptr(ov2640_of_match),
 	},
-	.probe    = ov2640_probe,
+	.probe_new = ov2640_probe,
 	.remove   = ov2640_remove,
 	.id_table = ov2640_id,
 };
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 5ed2413..f4ded06 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1055,7 +1055,7 @@
 		mutex_unlock(&ov2659->lock);
 		return 0;
 #else
-	return -ENOTTY;
+		return -EINVAL;
 #endif
 	}
 
@@ -1131,8 +1131,6 @@
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 		mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
 		*mf = fmt->format;
-#else
-		ret = -ENOTTY;
 #endif
 	} else {
 		s64 val;
@@ -1386,8 +1384,7 @@
 	return pdata;
 }
 
-static int ov2659_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int ov2659_probe(struct i2c_client *client)
 {
 	const struct ov2659_platform_data *pdata = ov2659_get_pdata(client);
 	struct v4l2_subdev *sd;
@@ -1515,7 +1512,7 @@
 		.name	= DRIVER_NAME,
 		.of_match_table = of_match_ptr(ov2659_of_match),
 	},
-	.probe		= ov2659_probe,
+	.probe_new	= ov2659_probe,
 	.remove		= ov2659_remove,
 	.id_table	= ov2659_id,
 };
diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
index b10bcfa..59cdbc3 100644
--- a/drivers/media/i2c/ov2680.c
+++ b/drivers/media/i2c/ov2680.c
@@ -675,7 +675,7 @@
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 		fmt = v4l2_subdev_get_try_format(&sensor->sd, cfg, format->pad);
 #else
-		ret = -ENOTTY;
+		ret = -EINVAL;
 #endif
 	} else {
 		fmt = &sensor->fmt;
@@ -723,10 +723,7 @@
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 		try_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
 		format->format = *try_fmt;
-#else
-		ret = -ENOTTY;
 #endif
-
 		goto unlock;
 	}
 
@@ -1023,7 +1020,7 @@
 	return 0;
 }
 
-static int ov2860_parse_dt(struct ov2680_dev *sensor)
+static int ov2680_parse_dt(struct ov2680_dev *sensor)
 {
 	struct device *dev = ov2680_to_dev(sensor);
 	int ret;
@@ -1064,7 +1061,7 @@
 
 	sensor->i2c_client = client;
 
-	ret = ov2860_parse_dt(sensor);
+	ret = ov2680_parse_dt(sensor);
 	if (ret < 0)
 		return -EINVAL;
 
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 759d60c6..500d9bb 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -158,8 +158,8 @@
 /* regulator supplies */
 static const char * const ov5640_supply_name[] = {
 	"DOVDD", /* Digital I/O (1.8V) supply */
-	"DVDD",  /* Digital Core (1.5V) supply */
 	"AVDD",  /* Analog (2.8V) supply */
+	"DVDD",  /* Digital Core (1.5V) supply */
 };
 
 #define OV5640_NUM_SUPPLIES ARRAY_SIZE(ov5640_supply_name)
@@ -2936,8 +2936,7 @@
 	return ret;
 }
 
-static int ov5640_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int ov5640_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
 	struct fwnode_handle *endpoint;
@@ -3022,9 +3021,14 @@
 	/* request optional power down pin */
 	sensor->pwdn_gpio = devm_gpiod_get_optional(dev, "powerdown",
 						    GPIOD_OUT_HIGH);
+	if (IS_ERR(sensor->pwdn_gpio))
+		return PTR_ERR(sensor->pwdn_gpio);
+
 	/* request optional reset pin */
 	sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset",
 						     GPIOD_OUT_HIGH);
+	if (IS_ERR(sensor->reset_gpio))
+		return PTR_ERR(sensor->reset_gpio);
 
 	v4l2_i2c_subdev_init(&sensor->sd, client, &ov5640_subdev_ops);
 
@@ -3050,7 +3054,7 @@
 	if (ret)
 		goto entity_cleanup;
 
-	ret = v4l2_async_register_subdev(&sensor->sd);
+	ret = v4l2_async_register_subdev_sensor_common(&sensor->sd);
 	if (ret)
 		goto free_ctrls;
 
@@ -3095,7 +3099,7 @@
 		.of_match_table	= ov5640_dt_ids,
 	},
 	.id_table = ov5640_id,
-	.probe    = ov5640_probe,
+	.probe_new = ov5640_probe,
 	.remove   = ov5640_remove,
 };
 
diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
index 124c8df..a6c17d1 100644
--- a/drivers/media/i2c/ov5645.c
+++ b/drivers/media/i2c/ov5645.c
@@ -34,10 +34,6 @@
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-subdev.h>
 
-#define OV5645_VOLTAGE_ANALOG               2800000
-#define OV5645_VOLTAGE_DIGITAL_CORE         1500000
-#define OV5645_VOLTAGE_DIGITAL_IO           1800000
-
 #define OV5645_SYSTEM_CTRL0		0x3008
 #define		OV5645_SYSTEM_CTRL0_START	0x02
 #define		OV5645_SYSTEM_CTRL0_STOP	0x42
@@ -45,6 +41,8 @@
 #define		OV5645_CHIP_ID_HIGH_BYTE	0x56
 #define OV5645_CHIP_ID_LOW		0x300b
 #define		OV5645_CHIP_ID_LOW_BYTE		0x45
+#define OV5645_IO_MIPI_CTRL00		0x300e
+#define OV5645_PAD_OUTPUT00		0x3019
 #define OV5645_AWB_MANUAL_CONTROL	0x3406
 #define		OV5645_AWB_MANUAL_ENABLE	BIT(0)
 #define OV5645_AEC_PK_MANUAL		0x3503
@@ -55,6 +53,7 @@
 #define		OV5645_ISP_VFLIP		BIT(2)
 #define OV5645_TIMING_TC_REG21		0x3821
 #define		OV5645_SENSOR_MIRROR		BIT(1)
+#define OV5645_MIPI_CTRL00		0x4800
 #define OV5645_PRE_ISP_TEST_SETTING_1	0x503d
 #define		OV5645_TEST_PATTERN_MASK	0x3
 #define		OV5645_SET_TEST_PATTERN(x)	((x) & OV5645_TEST_PATTERN_MASK)
@@ -62,6 +61,15 @@
 #define OV5645_SDE_SAT_U		0x5583
 #define OV5645_SDE_SAT_V		0x5584
 
+/* regulator supplies */
+static const char * const ov5645_supply_name[] = {
+	"vdddo", /* Digital I/O (1.8V) supply */
+	"vdda",  /* Analog (2.8V) supply */
+	"vddd",  /* Digital Core (1.5V) supply */
+};
+
+#define OV5645_NUM_SUPPLIES ARRAY_SIZE(ov5645_supply_name)
+
 struct reg_value {
 	u16 reg;
 	u8 val;
@@ -86,9 +94,7 @@
 	struct v4l2_rect crop;
 	struct clk *xclk;
 
-	struct regulator *io_regulator;
-	struct regulator *core_regulator;
-	struct regulator *analog_regulator;
+	struct regulator_bulk_data supplies[OV5645_NUM_SUPPLIES];
 
 	const struct ov5645_mode_info *current_mode;
 
@@ -121,7 +127,6 @@
 	{ 0x3503, 0x07 },
 	{ 0x3002, 0x1c },
 	{ 0x3006, 0xc3 },
-	{ 0x300e, 0x45 },
 	{ 0x3017, 0x00 },
 	{ 0x3018, 0x00 },
 	{ 0x302e, 0x0b },
@@ -350,7 +355,10 @@
 	{ 0x3a1f, 0x14 },
 	{ 0x0601, 0x02 },
 	{ 0x3008, 0x42 },
-	{ 0x3008, 0x02 }
+	{ 0x3008, 0x02 },
+	{ OV5645_IO_MIPI_CTRL00, 0x40 },
+	{ OV5645_MIPI_CTRL00, 0x24 },
+	{ OV5645_PAD_OUTPUT00, 0x70 }
 };
 
 static const struct reg_value ov5645_setting_sxga[] = {
@@ -533,55 +541,6 @@
 	},
 };
 
-static int ov5645_regulators_enable(struct ov5645 *ov5645)
-{
-	int ret;
-
-	ret = regulator_enable(ov5645->io_regulator);
-	if (ret < 0) {
-		dev_err(ov5645->dev, "set io voltage failed\n");
-		return ret;
-	}
-
-	ret = regulator_enable(ov5645->analog_regulator);
-	if (ret) {
-		dev_err(ov5645->dev, "set analog voltage failed\n");
-		goto err_disable_io;
-	}
-
-	ret = regulator_enable(ov5645->core_regulator);
-	if (ret) {
-		dev_err(ov5645->dev, "set core voltage failed\n");
-		goto err_disable_analog;
-	}
-
-	return 0;
-
-err_disable_analog:
-	regulator_disable(ov5645->analog_regulator);
-err_disable_io:
-	regulator_disable(ov5645->io_regulator);
-
-	return ret;
-}
-
-static void ov5645_regulators_disable(struct ov5645 *ov5645)
-{
-	int ret;
-
-	ret = regulator_disable(ov5645->core_regulator);
-	if (ret < 0)
-		dev_err(ov5645->dev, "core regulator disable failed\n");
-
-	ret = regulator_disable(ov5645->analog_regulator);
-	if (ret < 0)
-		dev_err(ov5645->dev, "analog regulator disable failed\n");
-
-	ret = regulator_disable(ov5645->io_regulator);
-	if (ret < 0)
-		dev_err(ov5645->dev, "io regulator disable failed\n");
-}
-
 static int ov5645_write_reg(struct ov5645 *ov5645, u16 reg, u8 val)
 {
 	u8 regbuf[3];
@@ -680,15 +639,14 @@
 {
 	int ret;
 
-	ret = ov5645_regulators_enable(ov5645);
-	if (ret < 0) {
+	ret = regulator_bulk_enable(OV5645_NUM_SUPPLIES, ov5645->supplies);
+	if (ret < 0)
 		return ret;
-	}
 
 	ret = clk_prepare_enable(ov5645->xclk);
 	if (ret < 0) {
 		dev_err(ov5645->dev, "clk prepare enable failed\n");
-		ov5645_regulators_disable(ov5645);
+		regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies);
 		return ret;
 	}
 
@@ -708,7 +666,7 @@
 	gpiod_set_value_cansleep(ov5645->rst_gpio, 1);
 	gpiod_set_value_cansleep(ov5645->enable_gpio, 0);
 	clk_disable_unprepare(ov5645->xclk);
-	ov5645_regulators_disable(ov5645);
+	regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies);
 }
 
 static int ov5645_s_power(struct v4l2_subdev *sd, int on)
@@ -737,13 +695,9 @@
 				goto exit;
 			}
 
-			ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,
-					       OV5645_SYSTEM_CTRL0_STOP);
-			if (ret < 0) {
-				ov5645_set_power_off(ov5645);
-				goto exit;
-			}
+			usleep_range(500, 1000);
 		} else {
+			ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x58);
 			ov5645_set_power_off(ov5645);
 		}
 	}
@@ -1049,11 +1003,20 @@
 			dev_err(ov5645->dev, "could not sync v4l2 controls\n");
 			return ret;
 		}
+
+		ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x45);
+		if (ret < 0)
+			return ret;
+
 		ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,
 				       OV5645_SYSTEM_CTRL0_START);
 		if (ret < 0)
 			return ret;
 	} else {
+		ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x40);
+		if (ret < 0)
+			return ret;
+
 		ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,
 				       OV5645_SYSTEM_CTRL0_STOP);
 		if (ret < 0)
@@ -1086,13 +1049,13 @@
 	.pad = &ov5645_subdev_pad_ops,
 };
 
-static int ov5645_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int ov5645_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
 	struct device_node *endpoint;
 	struct ov5645 *ov5645;
 	u8 chip_id_high, chip_id_low;
+	unsigned int i;
 	u32 xclk_freq;
 	int ret;
 
@@ -1150,47 +1113,13 @@
 		return ret;
 	}
 
-	ov5645->io_regulator = devm_regulator_get(dev, "vdddo");
-	if (IS_ERR(ov5645->io_regulator)) {
-		dev_err(dev, "cannot get io regulator\n");
-		return PTR_ERR(ov5645->io_regulator);
-	}
+	for (i = 0; i < OV5645_NUM_SUPPLIES; i++)
+		ov5645->supplies[i].supply = ov5645_supply_name[i];
 
-	ret = regulator_set_voltage(ov5645->io_regulator,
-				    OV5645_VOLTAGE_DIGITAL_IO,
-				    OV5645_VOLTAGE_DIGITAL_IO);
-	if (ret < 0) {
-		dev_err(dev, "cannot set io voltage\n");
+	ret = devm_regulator_bulk_get(dev, OV5645_NUM_SUPPLIES,
+				      ov5645->supplies);
+	if (ret < 0)
 		return ret;
-	}
-
-	ov5645->core_regulator = devm_regulator_get(dev, "vddd");
-	if (IS_ERR(ov5645->core_regulator)) {
-		dev_err(dev, "cannot get core regulator\n");
-		return PTR_ERR(ov5645->core_regulator);
-	}
-
-	ret = regulator_set_voltage(ov5645->core_regulator,
-				    OV5645_VOLTAGE_DIGITAL_CORE,
-				    OV5645_VOLTAGE_DIGITAL_CORE);
-	if (ret < 0) {
-		dev_err(dev, "cannot set core voltage\n");
-		return ret;
-	}
-
-	ov5645->analog_regulator = devm_regulator_get(dev, "vdda");
-	if (IS_ERR(ov5645->analog_regulator)) {
-		dev_err(dev, "cannot get analog regulator\n");
-		return PTR_ERR(ov5645->analog_regulator);
-	}
-
-	ret = regulator_set_voltage(ov5645->analog_regulator,
-				    OV5645_VOLTAGE_ANALOG,
-				    OV5645_VOLTAGE_ANALOG);
-	if (ret < 0) {
-		dev_err(dev, "cannot set analog voltage\n");
-		return ret;
-	}
 
 	ov5645->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
 	if (IS_ERR(ov5645->enable_gpio)) {
@@ -1355,7 +1284,7 @@
 		.of_match_table = of_match_ptr(ov5645_of_match),
 		.name  = "ov5645",
 	},
-	.probe  = ov5645_probe,
+	.probe_new = ov5645_probe,
 	.remove = ov5645_remove,
 	.id_table = ov5645_id,
 };
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 4589631..e7d2e5b 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -547,8 +547,7 @@
 	return ret;
 }
 
-static int ov5647_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int ov5647_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
 	struct ov5647 *sensor;
@@ -644,7 +643,7 @@
 		.of_match_table = of_match_ptr(ov5647_of_match),
 		.name	= SENSOR_NAME,
 	},
-	.probe		= ov5647_probe,
+	.probe_new	= ov5647_probe,
 	.remove		= ov5647_remove,
 	.id_table	= ov5647_id,
 };
diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c
new file mode 100644
index 0000000..1ae2523
--- /dev/null
+++ b/drivers/media/i2c/ov5675.c
@@ -0,0 +1,1183 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2019 Intel Corporation.
+
+#include <asm/unaligned.h>
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+
+#define OV5675_REG_VALUE_08BIT		1
+#define OV5675_REG_VALUE_16BIT		2
+#define OV5675_REG_VALUE_24BIT		3
+
+#define OV5675_LINK_FREQ_450MHZ		450000000ULL
+#define OV5675_SCLK			90000000LL
+#define OV5675_MCLK			19200000
+#define OV5675_DATA_LANES		2
+#define OV5675_RGB_DEPTH		10
+
+#define OV5675_REG_CHIP_ID		0x300a
+#define OV5675_CHIP_ID			0x5675
+
+#define OV5675_REG_MODE_SELECT		0x0100
+#define OV5675_MODE_STANDBY		0x00
+#define OV5675_MODE_STREAMING		0x01
+
+/* vertical-timings from sensor */
+#define OV5675_REG_VTS			0x380e
+#define OV5675_VTS_30FPS		0x07e4
+#define OV5675_VTS_30FPS_MIN		0x07e4
+#define OV5675_VTS_MAX			0x7fff
+
+/* horizontal-timings from sensor */
+#define OV5675_REG_HTS			0x380c
+
+/* Exposure controls from sensor */
+#define OV5675_REG_EXPOSURE		0x3500
+#define	OV5675_EXPOSURE_MIN		4
+#define OV5675_EXPOSURE_MAX_MARGIN	4
+#define	OV5675_EXPOSURE_STEP		1
+
+/* Analog gain controls from sensor */
+#define OV5675_REG_ANALOG_GAIN		0x3508
+#define	OV5675_ANAL_GAIN_MIN		128
+#define	OV5675_ANAL_GAIN_MAX		2047
+#define	OV5675_ANAL_GAIN_STEP		1
+
+/* Digital gain controls from sensor */
+#define OV5675_REG_MWB_R_GAIN		0x5019
+#define OV5675_REG_MWB_G_GAIN		0x501b
+#define OV5675_REG_MWB_B_GAIN		0x501d
+#define OV5675_DGTL_GAIN_MIN		0
+#define OV5675_DGTL_GAIN_MAX		4095
+#define OV5675_DGTL_GAIN_STEP		1
+#define OV5675_DGTL_GAIN_DEFAULT	1024
+
+/* Test Pattern Control */
+#define OV5675_REG_TEST_PATTERN		0x4503
+#define OV5675_TEST_PATTERN_ENABLE	BIT(7)
+#define OV5675_TEST_PATTERN_BAR_SHIFT	2
+
+#define to_ov5675(_sd)			container_of(_sd, struct ov5675, sd)
+
+enum {
+	OV5675_LINK_FREQ_900MBPS,
+};
+
+struct ov5675_reg {
+	u16 address;
+	u8 val;
+};
+
+struct ov5675_reg_list {
+	u32 num_of_regs;
+	const struct ov5675_reg *regs;
+};
+
+struct ov5675_link_freq_config {
+	const struct ov5675_reg_list reg_list;
+};
+
+struct ov5675_mode {
+	/* Frame width in pixels */
+	u32 width;
+
+	/* Frame height in pixels */
+	u32 height;
+
+	/* Horizontal timining size */
+	u32 hts;
+
+	/* Default vertical timining size */
+	u32 vts_def;
+
+	/* Min vertical timining size */
+	u32 vts_min;
+
+	/* Link frequency needed for this resolution */
+	u32 link_freq_index;
+
+	/* Sensor register settings for this resolution */
+	const struct ov5675_reg_list reg_list;
+};
+
+static const struct ov5675_reg mipi_data_rate_900mbps[] = {
+	{0x0103, 0x01},
+	{0x0100, 0x00},
+	{0x0300, 0x04},
+	{0x0302, 0x8d},
+	{0x0303, 0x00},
+	{0x030d, 0x26},
+};
+
+static const struct ov5675_reg mode_2592x1944_regs[] = {
+	{0x3002, 0x21},
+	{0x3107, 0x23},
+	{0x3501, 0x20},
+	{0x3503, 0x0c},
+	{0x3508, 0x03},
+	{0x3509, 0x00},
+	{0x3600, 0x66},
+	{0x3602, 0x30},
+	{0x3610, 0xa5},
+	{0x3612, 0x93},
+	{0x3620, 0x80},
+	{0x3642, 0x0e},
+	{0x3661, 0x00},
+	{0x3662, 0x10},
+	{0x3664, 0xf3},
+	{0x3665, 0x9e},
+	{0x3667, 0xa5},
+	{0x366e, 0x55},
+	{0x366f, 0x55},
+	{0x3670, 0x11},
+	{0x3671, 0x11},
+	{0x3672, 0x11},
+	{0x3673, 0x11},
+	{0x3714, 0x24},
+	{0x371a, 0x3e},
+	{0x3733, 0x10},
+	{0x3734, 0x00},
+	{0x373d, 0x24},
+	{0x3764, 0x20},
+	{0x3765, 0x20},
+	{0x3766, 0x12},
+	{0x37a1, 0x14},
+	{0x37a8, 0x1c},
+	{0x37ab, 0x0f},
+	{0x37c2, 0x04},
+	{0x37cb, 0x00},
+	{0x37cc, 0x00},
+	{0x37cd, 0x00},
+	{0x37ce, 0x00},
+	{0x37d8, 0x02},
+	{0x37d9, 0x08},
+	{0x37dc, 0x04},
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0x04},
+	{0x3804, 0x0a},
+	{0x3805, 0x3f},
+	{0x3806, 0x07},
+	{0x3807, 0xb3},
+	{0x3808, 0x0a},
+	{0x3809, 0x20},
+	{0x380a, 0x07},
+	{0x380b, 0x98},
+	{0x380c, 0x02},
+	{0x380d, 0xee},
+	{0x380e, 0x07},
+	{0x380f, 0xe4},
+	{0x3811, 0x10},
+	{0x3813, 0x0d},
+	{0x3814, 0x01},
+	{0x3815, 0x01},
+	{0x3816, 0x01},
+	{0x3817, 0x01},
+	{0x381e, 0x02},
+	{0x3820, 0x88},
+	{0x3821, 0x01},
+	{0x3832, 0x04},
+	{0x3c80, 0x01},
+	{0x3c82, 0x00},
+	{0x3c83, 0xc8},
+	{0x3c8c, 0x0f},
+	{0x3c8d, 0xa0},
+	{0x3c90, 0x07},
+	{0x3c91, 0x00},
+	{0x3c92, 0x00},
+	{0x3c93, 0x00},
+	{0x3c94, 0xd0},
+	{0x3c95, 0x50},
+	{0x3c96, 0x35},
+	{0x3c97, 0x00},
+	{0x4001, 0xe0},
+	{0x4008, 0x02},
+	{0x4009, 0x0d},
+	{0x400f, 0x80},
+	{0x4013, 0x02},
+	{0x4040, 0x00},
+	{0x4041, 0x07},
+	{0x404c, 0x50},
+	{0x404e, 0x20},
+	{0x4500, 0x06},
+	{0x4503, 0x00},
+	{0x450a, 0x04},
+	{0x4809, 0x04},
+	{0x480c, 0x12},
+	{0x4819, 0x70},
+	{0x4825, 0x32},
+	{0x4826, 0x32},
+	{0x482a, 0x06},
+	{0x4833, 0x08},
+	{0x4837, 0x0d},
+	{0x5000, 0x77},
+	{0x5b00, 0x01},
+	{0x5b01, 0x10},
+	{0x5b02, 0x01},
+	{0x5b03, 0xdb},
+	{0x5b05, 0x6c},
+	{0x5e10, 0xfc},
+	{0x3500, 0x00},
+	{0x3501, 0x3E},
+	{0x3502, 0x60},
+	{0x3503, 0x08},
+	{0x3508, 0x04},
+	{0x3509, 0x00},
+	{0x3832, 0x48},
+	{0x5780, 0x3e},
+	{0x5781, 0x0f},
+	{0x5782, 0x44},
+	{0x5783, 0x02},
+	{0x5784, 0x01},
+	{0x5785, 0x01},
+	{0x5786, 0x00},
+	{0x5787, 0x04},
+	{0x5788, 0x02},
+	{0x5789, 0x0f},
+	{0x578a, 0xfd},
+	{0x578b, 0xf5},
+	{0x578c, 0xf5},
+	{0x578d, 0x03},
+	{0x578e, 0x08},
+	{0x578f, 0x0c},
+	{0x5790, 0x08},
+	{0x5791, 0x06},
+	{0x5792, 0x00},
+	{0x5793, 0x52},
+	{0x5794, 0xa3},
+	{0x4003, 0x40},
+	{0x3107, 0x01},
+	{0x3c80, 0x08},
+	{0x3c83, 0xb1},
+	{0x3c8c, 0x10},
+	{0x3c8d, 0x00},
+	{0x3c90, 0x00},
+	{0x3c94, 0x00},
+	{0x3c95, 0x00},
+	{0x3c96, 0x00},
+	{0x37cb, 0x09},
+	{0x37cc, 0x15},
+	{0x37cd, 0x1f},
+	{0x37ce, 0x1f},
+};
+
+static const struct ov5675_reg mode_1296x972_regs[] = {
+	{0x3002, 0x21},
+	{0x3107, 0x23},
+	{0x3501, 0x20},
+	{0x3503, 0x0c},
+	{0x3508, 0x03},
+	{0x3509, 0x00},
+	{0x3600, 0x66},
+	{0x3602, 0x30},
+	{0x3610, 0xa5},
+	{0x3612, 0x93},
+	{0x3620, 0x80},
+	{0x3642, 0x0e},
+	{0x3661, 0x00},
+	{0x3662, 0x08},
+	{0x3664, 0xf3},
+	{0x3665, 0x9e},
+	{0x3667, 0xa5},
+	{0x366e, 0x55},
+	{0x366f, 0x55},
+	{0x3670, 0x11},
+	{0x3671, 0x11},
+	{0x3672, 0x11},
+	{0x3673, 0x11},
+	{0x3714, 0x28},
+	{0x371a, 0x3e},
+	{0x3733, 0x10},
+	{0x3734, 0x00},
+	{0x373d, 0x24},
+	{0x3764, 0x20},
+	{0x3765, 0x20},
+	{0x3766, 0x12},
+	{0x37a1, 0x14},
+	{0x37a8, 0x1c},
+	{0x37ab, 0x0f},
+	{0x37c2, 0x14},
+	{0x37cb, 0x00},
+	{0x37cc, 0x00},
+	{0x37cd, 0x00},
+	{0x37ce, 0x00},
+	{0x37d8, 0x02},
+	{0x37d9, 0x04},
+	{0x37dc, 0x04},
+	{0x3800, 0x00},
+	{0x3801, 0x00},
+	{0x3802, 0x00},
+	{0x3803, 0xf4},
+	{0x3804, 0x0a},
+	{0x3805, 0x3f},
+	{0x3806, 0x06},
+	{0x3807, 0xb3},
+	{0x3808, 0x05},
+	{0x3809, 0x00},
+	{0x380a, 0x02},
+	{0x380b, 0xd0},
+	{0x380c, 0x02},
+	{0x380d, 0xee},
+	{0x380e, 0x07},
+	{0x380f, 0xe4},
+	{0x3811, 0x10},
+	{0x3813, 0x09},
+	{0x3814, 0x03},
+	{0x3815, 0x01},
+	{0x3816, 0x03},
+	{0x3817, 0x01},
+	{0x381e, 0x02},
+	{0x3820, 0x8b},
+	{0x3821, 0x01},
+	{0x3832, 0x04},
+	{0x3c80, 0x01},
+	{0x3c82, 0x00},
+	{0x3c83, 0xc8},
+	{0x3c8c, 0x0f},
+	{0x3c8d, 0xa0},
+	{0x3c90, 0x07},
+	{0x3c91, 0x00},
+	{0x3c92, 0x00},
+	{0x3c93, 0x00},
+	{0x3c94, 0xd0},
+	{0x3c95, 0x50},
+	{0x3c96, 0x35},
+	{0x3c97, 0x00},
+	{0x4001, 0xe0},
+	{0x4008, 0x00},
+	{0x4009, 0x07},
+	{0x400f, 0x80},
+	{0x4013, 0x02},
+	{0x4040, 0x00},
+	{0x4041, 0x03},
+	{0x404c, 0x50},
+	{0x404e, 0x20},
+	{0x4500, 0x06},
+	{0x4503, 0x00},
+	{0x450a, 0x04},
+	{0x4809, 0x04},
+	{0x480c, 0x12},
+	{0x4819, 0x70},
+	{0x4825, 0x32},
+	{0x4826, 0x32},
+	{0x482a, 0x06},
+	{0x4833, 0x08},
+	{0x4837, 0x0d},
+	{0x5000, 0x77},
+	{0x5b00, 0x01},
+	{0x5b01, 0x10},
+	{0x5b02, 0x01},
+	{0x5b03, 0xdb},
+	{0x5b05, 0x6c},
+	{0x5e10, 0xfc},
+	{0x3500, 0x00},
+	{0x3501, 0x1F},
+	{0x3502, 0x20},
+	{0x3503, 0x08},
+	{0x3508, 0x04},
+	{0x3509, 0x00},
+	{0x3832, 0x48},
+	{0x5780, 0x3e},
+	{0x5781, 0x0f},
+	{0x5782, 0x44},
+	{0x5783, 0x02},
+	{0x5784, 0x01},
+	{0x5785, 0x01},
+	{0x5786, 0x00},
+	{0x5787, 0x04},
+	{0x5788, 0x02},
+	{0x5789, 0x0f},
+	{0x578a, 0xfd},
+	{0x578b, 0xf5},
+	{0x578c, 0xf5},
+	{0x578d, 0x03},
+	{0x578e, 0x08},
+	{0x578f, 0x0c},
+	{0x5790, 0x08},
+	{0x5791, 0x06},
+	{0x5792, 0x00},
+	{0x5793, 0x52},
+	{0x5794, 0xa3},
+	{0x4003, 0x40},
+	{0x3107, 0x01},
+	{0x3c80, 0x08},
+	{0x3c83, 0xb1},
+	{0x3c8c, 0x10},
+	{0x3c8d, 0x00},
+	{0x3c90, 0x00},
+	{0x3c94, 0x00},
+	{0x3c95, 0x00},
+	{0x3c96, 0x00},
+	{0x37cb, 0x09},
+	{0x37cc, 0x15},
+	{0x37cd, 0x1f},
+	{0x37ce, 0x1f},
+};
+
+static const char * const ov5675_test_pattern_menu[] = {
+	"Disabled",
+	"Standard Color Bar",
+	"Top-Bottom Darker Color Bar",
+	"Right-Left Darker Color Bar",
+	"Bottom-Top Darker Color Bar"
+};
+
+static const s64 link_freq_menu_items[] = {
+	OV5675_LINK_FREQ_450MHZ,
+};
+
+static const struct ov5675_link_freq_config link_freq_configs[] = {
+	[OV5675_LINK_FREQ_900MBPS] = {
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mipi_data_rate_900mbps),
+			.regs = mipi_data_rate_900mbps,
+		}
+	}
+};
+
+static const struct ov5675_mode supported_modes[] = {
+	{
+		.width = 2592,
+		.height = 1944,
+		.hts = 1500,
+		.vts_def = OV5675_VTS_30FPS,
+		.vts_min = OV5675_VTS_30FPS_MIN,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_2592x1944_regs),
+			.regs = mode_2592x1944_regs,
+		},
+		.link_freq_index = OV5675_LINK_FREQ_900MBPS,
+	},
+	{
+		.width = 1296,
+		.height = 972,
+		.hts = 1500,
+		.vts_def = OV5675_VTS_30FPS,
+		.vts_min = OV5675_VTS_30FPS_MIN,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_1296x972_regs),
+			.regs = mode_1296x972_regs,
+		},
+		.link_freq_index = OV5675_LINK_FREQ_900MBPS,
+	}
+};
+
+struct ov5675 {
+	struct v4l2_subdev sd;
+	struct media_pad pad;
+	struct v4l2_ctrl_handler ctrl_handler;
+
+	/* V4L2 Controls */
+	struct v4l2_ctrl *link_freq;
+	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *hblank;
+	struct v4l2_ctrl *exposure;
+
+	/* Current mode */
+	const struct ov5675_mode *cur_mode;
+
+	/* To serialize asynchronus callbacks */
+	struct mutex mutex;
+
+	/* Streaming on/off */
+	bool streaming;
+};
+
+static u64 to_pixel_rate(u32 f_index)
+{
+	u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OV5675_DATA_LANES;
+
+	do_div(pixel_rate, OV5675_RGB_DEPTH);
+
+	return pixel_rate;
+}
+
+static u64 to_pixels_per_line(u32 hts, u32 f_index)
+{
+	u64 ppl = hts * to_pixel_rate(f_index);
+
+	do_div(ppl, OV5675_SCLK);
+
+	return ppl;
+}
+
+static int ov5675_read_reg(struct ov5675 *ov5675, u16 reg, u16 len, u32 *val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
+	struct i2c_msg msgs[2];
+	u8 addr_buf[2];
+	u8 data_buf[4] = {0};
+	int ret;
+
+	if (len > 4)
+		return -EINVAL;
+
+	put_unaligned_be16(reg, addr_buf);
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = sizeof(addr_buf);
+	msgs[0].buf = addr_buf;
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_buf[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = get_unaligned_be32(data_buf);
+
+	return 0;
+}
+
+static int ov5675_write_reg(struct ov5675 *ov5675, u16 reg, u16 len, u32 val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
+	u8 buf[6];
+
+	if (len > 4)
+		return -EINVAL;
+
+	put_unaligned_be16(reg, buf);
+	put_unaligned_be32(val << 8 * (4 - len), buf + 2);
+	if (i2c_master_send(client, buf, len + 2) != len + 2)
+		return -EIO;
+
+	return 0;
+}
+
+static int ov5675_write_reg_list(struct ov5675 *ov5675,
+				 const struct ov5675_reg_list *r_list)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < r_list->num_of_regs; i++) {
+		ret = ov5675_write_reg(ov5675, r_list->regs[i].address, 1,
+				       r_list->regs[i].val);
+		if (ret) {
+			dev_err_ratelimited(&client->dev,
+				    "failed to write reg 0x%4.4x. error = %d",
+				    r_list->regs[i].address, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int ov5675_update_digital_gain(struct ov5675 *ov5675, u32 d_gain)
+{
+	int ret;
+
+	ret = ov5675_write_reg(ov5675, OV5675_REG_MWB_R_GAIN,
+			       OV5675_REG_VALUE_16BIT, d_gain);
+	if (ret)
+		return ret;
+
+	ret = ov5675_write_reg(ov5675, OV5675_REG_MWB_G_GAIN,
+			       OV5675_REG_VALUE_16BIT, d_gain);
+	if (ret)
+		return ret;
+
+	return ov5675_write_reg(ov5675, OV5675_REG_MWB_B_GAIN,
+				OV5675_REG_VALUE_16BIT, d_gain);
+}
+
+static int ov5675_test_pattern(struct ov5675 *ov5675, u32 pattern)
+{
+	if (pattern)
+		pattern = (pattern - 1) << OV5675_TEST_PATTERN_BAR_SHIFT |
+			  OV5675_TEST_PATTERN_ENABLE;
+
+	return ov5675_write_reg(ov5675, OV5675_REG_TEST_PATTERN,
+				OV5675_REG_VALUE_08BIT, pattern);
+}
+
+static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ov5675 *ov5675 = container_of(ctrl->handler,
+					     struct ov5675, ctrl_handler);
+	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
+	s64 exposure_max;
+	int ret = 0;
+
+	/* Propagate change of current control to all related controls */
+	if (ctrl->id == V4L2_CID_VBLANK) {
+		/* Update max exposure while meeting expected vblanking */
+		exposure_max = (ov5675->cur_mode->height + ctrl->val -
+			       OV5675_EXPOSURE_MAX_MARGIN) / 2;
+		__v4l2_ctrl_modify_range(ov5675->exposure,
+					 ov5675->exposure->minimum,
+					 exposure_max, ov5675->exposure->step,
+					 exposure_max);
+	}
+
+	/* V4L2 controls values will be applied only when power is already up */
+	if (!pm_runtime_get_if_in_use(&client->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = ov5675_write_reg(ov5675, OV5675_REG_ANALOG_GAIN,
+				       OV5675_REG_VALUE_16BIT, ctrl->val);
+		break;
+
+	case V4L2_CID_DIGITAL_GAIN:
+		ret = ov5675_update_digital_gain(ov5675, ctrl->val);
+		break;
+
+	case V4L2_CID_EXPOSURE:
+		/* 3 least significant bits of expsoure are fractional part */
+		ret = ov5675_write_reg(ov5675, OV5675_REG_EXPOSURE,
+				       OV5675_REG_VALUE_24BIT, ctrl->val << 3);
+		break;
+
+	case V4L2_CID_VBLANK:
+		ret = ov5675_write_reg(ov5675, OV5675_REG_VTS,
+				       OV5675_REG_VALUE_16BIT,
+				       ov5675->cur_mode->height + ctrl->val +
+				       10);
+		break;
+
+	case V4L2_CID_TEST_PATTERN:
+		ret = ov5675_test_pattern(ov5675, ctrl->val);
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops ov5675_ctrl_ops = {
+	.s_ctrl = ov5675_set_ctrl,
+};
+
+static int ov5675_init_controls(struct ov5675 *ov5675)
+{
+	struct v4l2_ctrl_handler *ctrl_hdlr;
+	s64 exposure_max, h_blank;
+	int ret;
+
+	ctrl_hdlr = &ov5675->ctrl_handler;
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
+	if (ret)
+		return ret;
+
+	ctrl_hdlr->lock = &ov5675->mutex;
+	ov5675->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov5675_ctrl_ops,
+					   V4L2_CID_LINK_FREQ,
+					   ARRAY_SIZE(link_freq_menu_items) - 1,
+					   0, link_freq_menu_items);
+	if (ov5675->link_freq)
+		ov5675->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	ov5675->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
+				       V4L2_CID_PIXEL_RATE, 0,
+				       to_pixel_rate(OV5675_LINK_FREQ_900MBPS),
+				       1,
+				       to_pixel_rate(OV5675_LINK_FREQ_900MBPS));
+	ov5675->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
+			  V4L2_CID_VBLANK,
+			  ov5675->cur_mode->vts_min - ov5675->cur_mode->height,
+			  OV5675_VTS_MAX - ov5675->cur_mode->height, 1,
+			  ov5675->cur_mode->vts_def - ov5675->cur_mode->height);
+	h_blank = to_pixels_per_line(ov5675->cur_mode->hts,
+		  ov5675->cur_mode->link_freq_index) - ov5675->cur_mode->width;
+	ov5675->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
+					   V4L2_CID_HBLANK, h_blank, h_blank, 1,
+					   h_blank);
+	if (ov5675->hblank)
+		ov5675->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
+			  OV5675_ANAL_GAIN_MIN, OV5675_ANAL_GAIN_MAX,
+			  OV5675_ANAL_GAIN_STEP, OV5675_ANAL_GAIN_MIN);
+	v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
+			  OV5675_DGTL_GAIN_MIN, OV5675_DGTL_GAIN_MAX,
+			  OV5675_DGTL_GAIN_STEP, OV5675_DGTL_GAIN_DEFAULT);
+	exposure_max = (ov5675->cur_mode->vts_def -
+			OV5675_EXPOSURE_MAX_MARGIN) / 2;
+	ov5675->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov5675_ctrl_ops,
+					     V4L2_CID_EXPOSURE,
+					     OV5675_EXPOSURE_MIN, exposure_max,
+					     OV5675_EXPOSURE_STEP,
+					     exposure_max);
+	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &ov5675_ctrl_ops,
+				     V4L2_CID_TEST_PATTERN,
+				     ARRAY_SIZE(ov5675_test_pattern_menu) - 1,
+				     0, 0, ov5675_test_pattern_menu);
+	if (ctrl_hdlr->error)
+		return ctrl_hdlr->error;
+
+	ov5675->sd.ctrl_handler = ctrl_hdlr;
+
+	return 0;
+}
+
+static void ov5675_update_pad_format(const struct ov5675_mode *mode,
+				     struct v4l2_mbus_framefmt *fmt)
+{
+	fmt->width = mode->width;
+	fmt->height = mode->height;
+	fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+	fmt->field = V4L2_FIELD_NONE;
+}
+
+static int ov5675_start_streaming(struct ov5675 *ov5675)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
+	const struct ov5675_reg_list *reg_list;
+	int link_freq_index, ret;
+
+	link_freq_index = ov5675->cur_mode->link_freq_index;
+	reg_list = &link_freq_configs[link_freq_index].reg_list;
+	ret = ov5675_write_reg_list(ov5675, reg_list);
+	if (ret) {
+		dev_err(&client->dev, "failed to set plls");
+		return ret;
+	}
+
+	reg_list = &ov5675->cur_mode->reg_list;
+	ret = ov5675_write_reg_list(ov5675, reg_list);
+	if (ret) {
+		dev_err(&client->dev, "failed to set mode");
+		return ret;
+	}
+
+	ret = __v4l2_ctrl_handler_setup(ov5675->sd.ctrl_handler);
+	if (ret)
+		return ret;
+
+	ret = ov5675_write_reg(ov5675, OV5675_REG_MODE_SELECT,
+			       OV5675_REG_VALUE_08BIT, OV5675_MODE_STREAMING);
+	if (ret) {
+		dev_err(&client->dev, "failed to set stream");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void ov5675_stop_streaming(struct ov5675 *ov5675)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
+
+	if (ov5675_write_reg(ov5675, OV5675_REG_MODE_SELECT,
+			     OV5675_REG_VALUE_08BIT, OV5675_MODE_STANDBY))
+		dev_err(&client->dev, "failed to set stream");
+}
+
+static int ov5675_set_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct ov5675 *ov5675 = to_ov5675(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret = 0;
+
+	if (ov5675->streaming == enable)
+		return 0;
+
+	mutex_lock(&ov5675->mutex);
+	if (enable) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			mutex_unlock(&ov5675->mutex);
+			return ret;
+		}
+
+		ret = ov5675_start_streaming(ov5675);
+		if (ret) {
+			enable = 0;
+			ov5675_stop_streaming(ov5675);
+			pm_runtime_put(&client->dev);
+		}
+	} else {
+		ov5675_stop_streaming(ov5675);
+		pm_runtime_put(&client->dev);
+	}
+
+	ov5675->streaming = enable;
+	mutex_unlock(&ov5675->mutex);
+
+	return ret;
+}
+
+static int __maybe_unused ov5675_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov5675 *ov5675 = to_ov5675(sd);
+
+	mutex_lock(&ov5675->mutex);
+	if (ov5675->streaming)
+		ov5675_stop_streaming(ov5675);
+
+	mutex_unlock(&ov5675->mutex);
+
+	return 0;
+}
+
+static int __maybe_unused ov5675_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov5675 *ov5675 = to_ov5675(sd);
+	int ret;
+
+	mutex_lock(&ov5675->mutex);
+	if (ov5675->streaming) {
+		ret = ov5675_start_streaming(ov5675);
+		if (ret) {
+			ov5675->streaming = false;
+			ov5675_stop_streaming(ov5675);
+			mutex_unlock(&ov5675->mutex);
+			return ret;
+		}
+	}
+
+	mutex_unlock(&ov5675->mutex);
+
+	return 0;
+}
+
+static int ov5675_set_format(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_pad_config *cfg,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct ov5675 *ov5675 = to_ov5675(sd);
+	const struct ov5675_mode *mode;
+	s32 vblank_def, h_blank;
+
+	mode = v4l2_find_nearest_size(supported_modes,
+				      ARRAY_SIZE(supported_modes), width,
+				      height, fmt->format.width,
+				      fmt->format.height);
+
+	mutex_lock(&ov5675->mutex);
+	ov5675_update_pad_format(mode, &fmt->format);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+	} else {
+		ov5675->cur_mode = mode;
+		__v4l2_ctrl_s_ctrl(ov5675->link_freq, mode->link_freq_index);
+		__v4l2_ctrl_s_ctrl_int64(ov5675->pixel_rate,
+					 to_pixel_rate(mode->link_freq_index));
+
+		/* Update limits and set FPS to default */
+		vblank_def = mode->vts_def - mode->height;
+		__v4l2_ctrl_modify_range(ov5675->vblank,
+					 mode->vts_min - mode->height,
+					 OV5675_VTS_MAX - mode->height, 1,
+					 vblank_def);
+		__v4l2_ctrl_s_ctrl(ov5675->vblank, vblank_def);
+		h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) -
+			  mode->width;
+		__v4l2_ctrl_modify_range(ov5675->hblank, h_blank, h_blank, 1,
+					 h_blank);
+	}
+
+	mutex_unlock(&ov5675->mutex);
+
+	return 0;
+}
+
+static int ov5675_get_format(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_pad_config *cfg,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct ov5675 *ov5675 = to_ov5675(sd);
+
+	mutex_lock(&ov5675->mutex);
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+		fmt->format = *v4l2_subdev_get_try_format(&ov5675->sd, cfg,
+							  fmt->pad);
+	else
+		ov5675_update_pad_format(ov5675->cur_mode, &fmt->format);
+
+	mutex_unlock(&ov5675->mutex);
+
+	return 0;
+}
+
+static int ov5675_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_pad_config *cfg,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index > 0)
+		return -EINVAL;
+
+	code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
+
+	return 0;
+}
+
+static int ov5675_enum_frame_size(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
+		return -EINVAL;
+
+	fse->min_width = supported_modes[fse->index].width;
+	fse->max_width = fse->min_width;
+	fse->min_height = supported_modes[fse->index].height;
+	fse->max_height = fse->min_height;
+
+	return 0;
+}
+
+static int ov5675_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct ov5675 *ov5675 = to_ov5675(sd);
+
+	mutex_lock(&ov5675->mutex);
+	ov5675_update_pad_format(&supported_modes[0],
+				 v4l2_subdev_get_try_format(sd, fh->pad, 0));
+	mutex_unlock(&ov5675->mutex);
+
+	return 0;
+}
+
+static const struct v4l2_subdev_video_ops ov5675_video_ops = {
+	.s_stream = ov5675_set_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ov5675_pad_ops = {
+	.set_fmt = ov5675_set_format,
+	.get_fmt = ov5675_get_format,
+	.enum_mbus_code = ov5675_enum_mbus_code,
+	.enum_frame_size = ov5675_enum_frame_size,
+};
+
+static const struct v4l2_subdev_ops ov5675_subdev_ops = {
+	.video = &ov5675_video_ops,
+	.pad = &ov5675_pad_ops,
+};
+
+static const struct media_entity_operations ov5675_subdev_entity_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+static const struct v4l2_subdev_internal_ops ov5675_internal_ops = {
+	.open = ov5675_open,
+};
+
+static int ov5675_identify_module(struct ov5675 *ov5675)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&ov5675->sd);
+	int ret;
+	u32 val;
+
+	ret = ov5675_read_reg(ov5675, OV5675_REG_CHIP_ID,
+			      OV5675_REG_VALUE_24BIT, &val);
+	if (ret)
+		return ret;
+
+	if (val != OV5675_CHIP_ID) {
+		dev_err(&client->dev, "chip id mismatch: %x!=%x",
+			OV5675_CHIP_ID, val);
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int ov5675_check_hwcfg(struct device *dev)
+{
+	struct fwnode_handle *ep;
+	struct fwnode_handle *fwnode = dev_fwnode(dev);
+	struct v4l2_fwnode_endpoint bus_cfg = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY
+	};
+	u32 mclk;
+	int ret;
+	unsigned int i, j;
+
+	if (!fwnode)
+		return -ENXIO;
+
+	ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
+
+	if (ret) {
+		dev_err(dev, "can't get clock frequency");
+		return ret;
+	}
+
+	if (mclk != OV5675_MCLK) {
+		dev_err(dev, "external clock %d is not supported", mclk);
+		return -EINVAL;
+	}
+
+	ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
+	if (!ep)
+		return -ENXIO;
+
+	ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+	fwnode_handle_put(ep);
+	if (ret)
+		return ret;
+
+	if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV5675_DATA_LANES) {
+		dev_err(dev, "number of CSI2 data lanes %d is not supported",
+			bus_cfg.bus.mipi_csi2.num_data_lanes);
+		ret = -EINVAL;
+		goto check_hwcfg_error;
+	}
+
+	if (!bus_cfg.nr_of_link_frequencies) {
+		dev_err(dev, "no link frequencies defined");
+		ret = -EINVAL;
+		goto check_hwcfg_error;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {
+		for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
+			if (link_freq_menu_items[i] ==
+				bus_cfg.link_frequencies[j])
+				break;
+		}
+
+		if (j == bus_cfg.nr_of_link_frequencies) {
+			dev_err(dev, "no link frequency %lld supported",
+				link_freq_menu_items[i]);
+			ret = -EINVAL;
+			goto check_hwcfg_error;
+		}
+	}
+
+check_hwcfg_error:
+	v4l2_fwnode_endpoint_free(&bus_cfg);
+
+	return ret;
+}
+
+static int ov5675_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov5675 *ov5675 = to_ov5675(sd);
+
+	v4l2_async_unregister_subdev(sd);
+	media_entity_cleanup(&sd->entity);
+	v4l2_ctrl_handler_free(sd->ctrl_handler);
+	pm_runtime_disable(&client->dev);
+	mutex_destroy(&ov5675->mutex);
+
+	return 0;
+}
+
+static int ov5675_probe(struct i2c_client *client)
+{
+	struct ov5675 *ov5675;
+	int ret;
+
+	ret = ov5675_check_hwcfg(&client->dev);
+	if (ret) {
+		dev_err(&client->dev, "failed to check HW configuration: %d",
+			ret);
+		return ret;
+	}
+
+	ov5675 = devm_kzalloc(&client->dev, sizeof(*ov5675), GFP_KERNEL);
+	if (!ov5675)
+		return -ENOMEM;
+
+	v4l2_i2c_subdev_init(&ov5675->sd, client, &ov5675_subdev_ops);
+	ret = ov5675_identify_module(ov5675);
+	if (ret) {
+		dev_err(&client->dev, "failed to find sensor: %d", ret);
+		return ret;
+	}
+
+	mutex_init(&ov5675->mutex);
+	ov5675->cur_mode = &supported_modes[0];
+	ret = ov5675_init_controls(ov5675);
+	if (ret) {
+		dev_err(&client->dev, "failed to init controls: %d", ret);
+		goto probe_error_v4l2_ctrl_handler_free;
+	}
+
+	ov5675->sd.internal_ops = &ov5675_internal_ops;
+	ov5675->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	ov5675->sd.entity.ops = &ov5675_subdev_entity_ops;
+	ov5675->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ov5675->pad.flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_pads_init(&ov5675->sd.entity, 1, &ov5675->pad);
+	if (ret) {
+		dev_err(&client->dev, "failed to init entity pads: %d", ret);
+		goto probe_error_v4l2_ctrl_handler_free;
+	}
+
+	ret = v4l2_async_register_subdev_sensor_common(&ov5675->sd);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+			ret);
+		goto probe_error_media_entity_cleanup;
+	}
+
+	/*
+	 * Device is already turned on by i2c-core with ACPI domain PM.
+	 * Enable runtime PM and turn off the device.
+	 */
+	pm_runtime_set_active(&client->dev);
+	pm_runtime_enable(&client->dev);
+	pm_runtime_idle(&client->dev);
+
+	return 0;
+
+probe_error_media_entity_cleanup:
+	media_entity_cleanup(&ov5675->sd.entity);
+
+probe_error_v4l2_ctrl_handler_free:
+	v4l2_ctrl_handler_free(ov5675->sd.ctrl_handler);
+	mutex_destroy(&ov5675->mutex);
+
+	return ret;
+}
+
+static const struct dev_pm_ops ov5675_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(ov5675_suspend, ov5675_resume)
+};
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id ov5675_acpi_ids[] = {
+	{"OVTI5675"},
+	{}
+};
+
+MODULE_DEVICE_TABLE(acpi, ov5675_acpi_ids);
+#endif
+
+static struct i2c_driver ov5675_i2c_driver = {
+	.driver = {
+		.name = "ov5675",
+		.pm = &ov5675_pm_ops,
+		.acpi_match_table = ACPI_PTR(ov5675_acpi_ids),
+	},
+	.probe_new = ov5675_probe,
+	.remove = ov5675_remove,
+};
+
+module_i2c_driver(ov5675_i2c_driver);
+
+MODULE_AUTHOR("Shawn Tu <shawnx.tu@intel.com>");
+MODULE_DESCRIPTION("OmniVision OV5675 sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/ov5695.c b/drivers/media/i2c/ov5695.c
index e65a943..34b7046 100644
--- a/drivers/media/i2c/ov5695.c
+++ b/drivers/media/i2c/ov5695.c
@@ -823,9 +823,6 @@
 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
-#else
-		mutex_unlock(&ov5695->mutex);
-		return -ENOTTY;
 #endif
 	} else {
 		ov5695->cur_mode = mode;
@@ -856,7 +853,7 @@
 		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
 #else
 		mutex_unlock(&ov5695->mutex);
-		return -ENOTTY;
+		return -EINVAL;
 #endif
 	} else {
 		fmt->format.width = mode->width;
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index 53385c27..b42b289 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -1110,10 +1110,8 @@
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 		mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
 		*mbus_fmt = format->format;
-		return 0;
-#else
-		return -ENOTTY;
 #endif
+		return 0;
 	}
 
 	ret = ov7670_try_fmt_internal(sd, &format->format, &info->fmt, &info->wsize);
@@ -1146,7 +1144,7 @@
 		format->format = *mbus_fmt;
 		return 0;
 #else
-		return -ENOTTY;
+		return -EINVAL;
 #endif
 	} else {
 		format->format = info->format;
diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c
index 2e9a758..2cc6a67 100644
--- a/drivers/media/i2c/ov772x.c
+++ b/drivers/media/i2c/ov772x.c
@@ -1352,8 +1352,7 @@
  * i2c_driver function
  */
 
-static int ov772x_probe(struct i2c_client *client,
-			const struct i2c_device_id *did)
+static int ov772x_probe(struct i2c_client *client)
 {
 	struct ov772x_priv	*priv;
 	int			ret;
@@ -1486,7 +1485,7 @@
 		.name = "ov772x",
 		.of_match_table = ov772x_of_match,
 	},
-	.probe    = ov772x_probe,
+	.probe_new = ov772x_probe,
 	.remove   = ov772x_remove,
 	.id_table = ov772x_id,
 };
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index 70bb870..732655f 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -827,13 +827,9 @@
 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
 		mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
 		*mbus_fmt = format->format;
-
+#endif
 		mutex_unlock(&ov7740->mutex);
 		return 0;
-#else
-		ret = -ENOTTY;
-		goto error;
-#endif
 	}
 
 	ret = ov7740_try_fmt_internal(sd, &format->format, &ovfmt, &fsize);
@@ -868,7 +864,7 @@
 		format->format = *mbus_fmt;
 		ret = 0;
 #else
-		ret = -ENOTTY;
+		ret = -EINVAL;
 #endif
 	} else {
 		format->format = ov7740->format;
@@ -1066,8 +1062,7 @@
 	.max_register	= OV7740_MAX_REGISTER,
 };
 
-static int ov7740_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int ov7740_probe(struct i2c_client *client)
 {
 	struct ov7740 *ov7740;
 	struct v4l2_subdev *sd;
@@ -1229,7 +1224,7 @@
 		.pm = &ov7740_pm_ops,
 		.of_match_table = of_match_ptr(ov7740_of_match),
 	},
-	.probe    = ov7740_probe,
+	.probe_new = ov7740_probe,
 	.remove   = ov7740_remove,
 	.id_table = ov7740_id,
 };
diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c
index cd347d6..8655842 100644
--- a/drivers/media/i2c/ov8856.c
+++ b/drivers/media/i2c/ov8856.c
@@ -1106,7 +1106,10 @@
 	if (!fwnode)
 		return -ENXIO;
 
-	fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
+	ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
+	if (ret)
+		return ret;
+
 	if (mclk != OV8856_MCLK) {
 		dev_err(dev, "external clock %d is not supported", mclk);
 		return -EINVAL;
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 30ab222..4fe68aa5 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -703,6 +703,11 @@
 		for (m = 6; m >= 0; m--)
 			if (gain >= (1 << m) * 16)
 				break;
+
+		/* Sanity check: don't adjust the gain with a negative value */
+		if (m < 0)
+			return -EINVAL;
+
 		rgain = (gain - ((1 << m) * 16)) / (1 << m);
 		rgain |= (((1 << m) - 1) << 4);
 
@@ -1485,8 +1490,7 @@
 	return ret;
 }
 
-static int ov965x_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int ov965x_probe(struct i2c_client *client)
 {
 	const struct ov9650_platform_data *pdata = client->dev.platform_data;
 	struct v4l2_subdev *sd;
@@ -1613,7 +1617,7 @@
 		.name	= DRIVER_NAME,
 		.of_match_table = of_match_ptr(ov965x_of_match),
 	},
-	.probe		= ov965x_probe,
+	.probe_new	= ov965x_probe,
 	.remove		= ov965x_remove,
 	.id_table	= ov965x_id,
 };
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 7633aeb..5b4c4a3 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1650,8 +1650,7 @@
 	return 0;
 }
 
-static int s5c73m3_probe(struct i2c_client *client,
-				const struct i2c_device_id *id)
+static int s5c73m3_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
 	struct v4l2_subdev *sd;
@@ -1806,7 +1805,7 @@
 		.of_match_table = of_match_ptr(s5c73m3_of_match),
 		.name	= DRIVER_NAME,
 	},
-	.probe		= s5c73m3_probe,
+	.probe_new	= s5c73m3_probe,
 	.remove		= s5c73m3_remove,
 	.id_table	= s5c73m3_id,
 };
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 8e6de06..cdfe008ba 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1946,8 +1946,7 @@
 	return ret;
 }
 
-static int s5k5baf_probe(struct i2c_client *c,
-			const struct i2c_device_id *id)
+static int s5k5baf_probe(struct i2c_client *c)
 {
 	struct s5k5baf *state;
 	int ret;
@@ -2046,7 +2045,7 @@
 		.of_match_table = s5k5baf_of_match,
 		.name = S5K5BAF_DRIVER_NAME
 	},
-	.probe		= s5k5baf_probe,
+	.probe_new	= s5k5baf_probe,
 	.remove		= s5k5baf_remove,
 	.id_table	= s5k5baf_id,
 };
diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
index 3b7721f..bc6cc5a 100644
--- a/drivers/media/i2c/s5k6a3.c
+++ b/drivers/media/i2c/s5k6a3.c
@@ -275,8 +275,7 @@
 	.pad = &s5k6a3_pad_ops,
 };
 
-static int s5k6a3_probe(struct i2c_client *client,
-				const struct i2c_device_id *id)
+static int s5k6a3_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
 	struct s5k6a3 *sensor;
@@ -378,7 +377,7 @@
 		.of_match_table	= of_match_ptr(s5k6a3_of_match),
 		.name		= S5K6A3_DRV_NAME,
 	},
-	.probe		= s5k6a3_probe,
+	.probe_new	= s5k6a3_probe,
 	.remove		= s5k6a3_remove,
 	.id_table	= s5k6a3_ids,
 };
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 2d78e84..9adf8e0 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2847,8 +2847,7 @@
 	return NULL;
 }
 
-static int smiapp_probe(struct i2c_client *client,
-			const struct i2c_device_id *devid)
+static int smiapp_probe(struct i2c_client *client)
 {
 	struct smiapp_sensor *sensor;
 	struct smiapp_hwconfig *hwcfg = smiapp_get_hwconfig(&client->dev);
@@ -3172,7 +3171,7 @@
 		.name = SMIAPP_NAME,
 		.pm = &smiapp_pm_ops,
 	},
-	.probe	= smiapp_probe,
+	.probe_new = smiapp_probe,
 	.remove	= smiapp_remove,
 	.id_table = smiapp_id_table,
 };
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index bc2e35e..dbbab75 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -2026,8 +2026,7 @@
 }
 #endif
 
-static int tc358743_probe(struct i2c_client *client,
-			  const struct i2c_device_id *id)
+static int tc358743_probe(struct i2c_client *client)
 {
 	static struct v4l2_dv_timings default_timing =
 		V4L2_DV_BT_CEA_640X480P59_94;
@@ -2222,7 +2221,7 @@
 		.name = "tc358743",
 		.of_match_table = of_match_ptr(tc358743_of_match),
 	},
-	.probe = tc358743_probe,
+	.probe_new = tc358743_probe,
 	.remove = tc358743_remove,
 	.id_table = tc358743_id,
 };
diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c
index a62ede0..5e68182 100644
--- a/drivers/media/i2c/tda1997x.c
+++ b/drivers/media/i2c/tda1997x.c
@@ -2691,7 +2691,13 @@
 	}
 
 	ret = 0x34 + ((io_read(sd, REG_SLAVE_ADDR)>>4) & 0x03);
-	state->client_cec = i2c_new_dummy(client->adapter, ret);
+	state->client_cec = devm_i2c_new_dummy_device(&client->dev,
+						      client->adapter, ret);
+	if (IS_ERR(state->client_cec)) {
+		ret = PTR_ERR(state->client_cec);
+		goto err_free_mutex;
+	}
+
 	v4l_info(client, "CEC slave address 0x%02x\n", ret);
 
 	ret = tda1997x_core_init(sd);
@@ -2798,7 +2804,6 @@
 	media_entity_cleanup(&sd->entity);
 	v4l2_ctrl_handler_free(&state->hdl);
 	regulator_bulk_disable(TDA1997X_NUM_SUPPLIES, state->supplies);
-	i2c_unregister_device(state->client_cec);
 	cancel_delayed_work(&state->delayed_work_enable_hpd);
 	mutex_destroy(&state->page_lock);
 	mutex_destroy(&state->lock);
diff --git a/drivers/media/i2c/ths8200.c b/drivers/media/i2c/ths8200.c
index f5ee280..c52fe84 100644
--- a/drivers/media/i2c/ths8200.c
+++ b/drivers/media/i2c/ths8200.c
@@ -436,8 +436,7 @@
 	.pad = &ths8200_pad_ops,
 };
 
-static int ths8200_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id)
+static int ths8200_probe(struct i2c_client *client)
 {
 	struct ths8200_state *state;
 	struct v4l2_subdev *sd;
@@ -502,7 +501,7 @@
 		.name = "ths8200",
 		.of_match_table = of_match_ptr(ths8200_of_match),
 	},
-	.probe = ths8200_probe,
+	.probe_new = ths8200_probe,
 	.remove = ths8200_remove,
 	.id_table = ths8200_id,
 };
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index eaddd97..edad49c 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -1636,11 +1636,13 @@
 			dev_err(decoder->sd.dev,
 				 "missing type property in node %pOFn\n",
 				 child);
+			of_node_put(child);
 			goto err_connector;
 		}
 
 		if (input_type >= TVP5150_INPUT_NUM) {
 			ret = -EINVAL;
+			of_node_put(child);
 			goto err_connector;
 		}
 
@@ -1651,6 +1653,7 @@
 			dev_err(decoder->sd.dev,
 				 "input %s with same type already exists\n",
 				 input->name);
+			of_node_put(child);
 			ret = -EINVAL;
 			goto err_connector;
 		}
@@ -1672,6 +1675,7 @@
 			dev_err(decoder->sd.dev,
 				 "missing label property in node %pOFn\n",
 				 child);
+			of_node_put(child);
 			goto err_connector;
 		}
 
@@ -1691,8 +1695,7 @@
 	"Black screen"
 };
 
-static int tvp5150_probe(struct i2c_client *c,
-			 const struct i2c_device_id *id)
+static int tvp5150_probe(struct i2c_client *c)
 {
 	struct tvp5150 *core;
 	struct v4l2_subdev *sd;
@@ -1841,7 +1844,7 @@
 		.of_match_table = of_match_ptr(tvp5150_of_match),
 		.name	= "tvp5150",
 	},
-	.probe		= tvp5150_probe,
+	.probe_new	= tvp5150_probe,
 	.remove		= tvp5150_remove,
 	.id_table	= tvp5150_id,
 };
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 1b8175c..de313b130 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -930,7 +930,7 @@
  * Returns zero when successful, -EINVAL if register read fails or
  * -EIO if i2c access is not available.
  */
-static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
+static int tvp7002_probe(struct i2c_client *c)
 {
 	struct tvp7002_config *pdata = tvp7002_get_pdata(c);
 	struct v4l2_subdev *sd;
@@ -1075,7 +1075,7 @@
 		.of_match_table = of_match_ptr(tvp7002_of_match),
 		.name = TVP7002_MODULE_NAME,
 	},
-	.probe = tvp7002_probe,
+	.probe_new = tvp7002_probe,
 	.remove = tvp7002_remove,
 	.id_table = tvp7002_id,
 };
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 612d1c0..a359da7 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -503,77 +503,65 @@
    packed pixel formats must come first */
 static const struct bttv_format formats[] = {
 	{
-		.name     = "8 bpp, gray",
 		.fourcc   = V4L2_PIX_FMT_GREY,
 		.btformat = BT848_COLOR_FMT_Y8,
 		.depth    = 8,
 		.flags    = FORMAT_FLAGS_PACKED,
 	},{
-		.name     = "8 bpp, dithered color",
 		.fourcc   = V4L2_PIX_FMT_HI240,
 		.btformat = BT848_COLOR_FMT_RGB8,
 		.depth    = 8,
 		.flags    = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER,
 	},{
-		.name     = "15 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_RGB555,
 		.btformat = BT848_COLOR_FMT_RGB15,
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	},{
-		.name     = "15 bpp RGB, be",
 		.fourcc   = V4L2_PIX_FMT_RGB555X,
 		.btformat = BT848_COLOR_FMT_RGB15,
 		.btswap   = 0x03, /* byteswap */
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	},{
-		.name     = "16 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_RGB565,
 		.btformat = BT848_COLOR_FMT_RGB16,
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	},{
-		.name     = "16 bpp RGB, be",
 		.fourcc   = V4L2_PIX_FMT_RGB565X,
 		.btformat = BT848_COLOR_FMT_RGB16,
 		.btswap   = 0x03, /* byteswap */
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	},{
-		.name     = "24 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_BGR24,
 		.btformat = BT848_COLOR_FMT_RGB24,
 		.depth    = 24,
 		.flags    = FORMAT_FLAGS_PACKED,
 	},{
-		.name     = "32 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_BGR32,
 		.btformat = BT848_COLOR_FMT_RGB32,
 		.depth    = 32,
 		.flags    = FORMAT_FLAGS_PACKED,
 	},{
-		.name     = "32 bpp RGB, be",
 		.fourcc   = V4L2_PIX_FMT_RGB32,
 		.btformat = BT848_COLOR_FMT_RGB32,
 		.btswap   = 0x0f, /* byte+word swap */
 		.depth    = 32,
 		.flags    = FORMAT_FLAGS_PACKED,
 	},{
-		.name     = "4:2:2, packed, YUYV",
 		.fourcc   = V4L2_PIX_FMT_YUYV,
 		.btformat = BT848_COLOR_FMT_YUY2,
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	},{
-		.name     = "4:2:2, packed, UYVY",
 		.fourcc   = V4L2_PIX_FMT_UYVY,
 		.btformat = BT848_COLOR_FMT_YUY2,
 		.btswap   = 0x03, /* byteswap */
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	},{
-		.name     = "4:2:2, planar, Y-Cb-Cr",
 		.fourcc   = V4L2_PIX_FMT_YUV422P,
 		.btformat = BT848_COLOR_FMT_YCrCb422,
 		.depth    = 16,
@@ -581,7 +569,6 @@
 		.hshift   = 1,
 		.vshift   = 0,
 	},{
-		.name     = "4:2:0, planar, Y-Cb-Cr",
 		.fourcc   = V4L2_PIX_FMT_YUV420,
 		.btformat = BT848_COLOR_FMT_YCrCb422,
 		.depth    = 12,
@@ -589,7 +576,6 @@
 		.hshift   = 1,
 		.vshift   = 1,
 	},{
-		.name     = "4:2:0, planar, Y-Cr-Cb",
 		.fourcc   = V4L2_PIX_FMT_YVU420,
 		.btformat = BT848_COLOR_FMT_YCrCb422,
 		.depth    = 12,
@@ -597,7 +583,6 @@
 		.hshift   = 1,
 		.vshift   = 1,
 	},{
-		.name     = "4:1:1, planar, Y-Cb-Cr",
 		.fourcc   = V4L2_PIX_FMT_YUV411P,
 		.btformat = BT848_COLOR_FMT_YCrCb411,
 		.depth    = 12,
@@ -605,7 +590,6 @@
 		.hshift   = 2,
 		.vshift   = 0,
 	},{
-		.name     = "4:1:0, planar, Y-Cb-Cr",
 		.fourcc   = V4L2_PIX_FMT_YUV410,
 		.btformat = BT848_COLOR_FMT_YCrCb411,
 		.depth    = 9,
@@ -613,7 +597,6 @@
 		.hshift   = 2,
 		.vshift   = 2,
 	},{
-		.name     = "4:1:0, planar, Y-Cr-Cb",
 		.fourcc   = V4L2_PIX_FMT_YVU410,
 		.btformat = BT848_COLOR_FMT_YCrCb411,
 		.depth    = 9,
@@ -621,7 +604,6 @@
 		.hshift   = 2,
 		.vshift   = 2,
 	},{
-		.name     = "raw scanlines",
 		.fourcc   = -1,
 		.btformat = BT848_COLOR_FMT_RAW,
 		.depth    = 8,
@@ -2500,7 +2482,6 @@
 		return -EINVAL;
 
 	f->pixelformat = formats[i].fourcc;
-	strscpy(f->description, formats[i].name, sizeof(f->description));
 
 	return i;
 }
diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c
index 9adfac4d..492bc85 100644
--- a/drivers/media/pci/bt8xx/bttv-input.c
+++ b/drivers/media/pci/bt8xx/bttv-input.c
@@ -84,7 +84,7 @@
 	data = ir_extract_bits(gpio, ir->mask_keycode);
 
 	/* Check if it is keyup */
-	keyup = (gpio & ir->mask_keyup) ? 1 << 31 : 0;
+	keyup = (gpio & ir->mask_keyup) ? 1UL << 31 : 0;
 
 	if ((ir->last_gpio & 0x7f) != data) {
 		dprintk("gpio=0x%x code=%d | %s\n",
@@ -95,7 +95,7 @@
 		if (keyup)
 			rc_keyup(ir->dev);
 	} else {
-		if ((ir->last_gpio & 1 << 31) == keyup)
+		if ((ir->last_gpio & 1UL << 31) == keyup)
 			return;
 
 		dprintk("(cnt) gpio=0x%x code=%d | %s\n",
diff --git a/drivers/media/pci/bt8xx/bttv-risc.c b/drivers/media/pci/bt8xx/bttv-risc.c
index 6b59ca3..fc87080 100644
--- a/drivers/media/pci/bt8xx/bttv-risc.c
+++ b/drivers/media/pci/bt8xx/bttv-risc.c
@@ -699,9 +699,9 @@
 	const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
 	struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 
-	dprintk("%d: buffer field: %s  format: %s  size: %dx%d\n",
+	dprintk("%d: buffer field: %s  format: 0x%08x  size: %dx%d\n",
 		btv->c.nr, v4l2_field_names[buf->vb.field],
-		buf->fmt->name, buf->vb.width, buf->vb.height);
+		buf->fmt->fourcc, buf->vb.width, buf->vb.height);
 
 	/* packed pixel modes */
 	if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
@@ -860,9 +860,9 @@
 		  struct bttv_buffer *buf)
 {
 	/* check interleave, bottom+top fields */
-	dprintk("%d: overlay fields: %s format: %s  size: %dx%d\n",
+	dprintk("%d: overlay fields: %s format: 0x%08x  size: %dx%d\n",
 		btv->c.nr, v4l2_field_names[buf->vb.field],
-		fmt->name, ov->w.width, ov->w.height);
+		fmt->fourcc, ov->w.width, ov->w.height);
 
 	/* calculate geometry */
 	bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h
index b159d6d..4abf436 100644
--- a/drivers/media/pci/bt8xx/bttvp.h
+++ b/drivers/media/pci/bt8xx/bttvp.h
@@ -99,7 +99,6 @@
 extern const struct bttv_tvnorm bttv_tvnorms[];
 
 struct bttv_format {
-	char *name;
 	int  fourcc;          /* video4linux 2      */
 	int  btformat;        /* BT848_COLOR_FMT_*  */
 	int  btswap;          /* BT848_COLOR_CTL_*  */
diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c
index 64df9d4..02ebd43 100644
--- a/drivers/media/pci/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c
@@ -393,7 +393,7 @@
 	.demod_init = advbt771_samsung_tdtc9251dh0_demod_init,
 };
 
-static struct dst_config dst_config = {
+static const struct dst_config dst_config = {
 	.demod_address = 0x55,
 };
 
diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c
index 4885e83..0695078 100644
--- a/drivers/media/pci/cobalt/cobalt-driver.c
+++ b/drivers/media/pci/cobalt/cobalt-driver.c
@@ -186,20 +186,16 @@
 {
 	struct pci_dev *pci_dev = cobalt->pci_dev;
 	struct pci_dev *pci_bus_dev = cobalt->pci_dev->bus->self;
-	int offset;
-	int bus_offset;
 	u32 capa;
 	u16 stat, ctrl;
 
-	offset = pci_find_capability(pci_dev, PCI_CAP_ID_EXP);
-	bus_offset = pci_find_capability(pci_bus_dev, PCI_CAP_ID_EXP);
-	if (!offset || !bus_offset)
+	if (!pci_is_pcie(pci_dev) || !pci_is_pcie(pci_bus_dev))
 		return;
 
 	/* Device */
-	pci_read_config_dword(pci_dev, offset + PCI_EXP_DEVCAP, &capa);
-	pci_read_config_word(pci_dev, offset + PCI_EXP_DEVCTL, &ctrl);
-	pci_read_config_word(pci_dev, offset + PCI_EXP_DEVSTA, &stat);
+	pcie_capability_read_dword(pci_dev, PCI_EXP_DEVCAP, &capa);
+	pcie_capability_read_word(pci_dev, PCI_EXP_DEVCTL, &ctrl);
+	pcie_capability_read_word(pci_dev, PCI_EXP_DEVSTA, &stat);
 	cobalt_info("PCIe device capability 0x%08x: Max payload %d\n",
 		    capa, get_payload_size(capa & PCI_EXP_DEVCAP_PAYLOAD));
 	cobalt_info("PCIe device control 0x%04x: Max payload %d. Max read request %d\n",
@@ -209,9 +205,9 @@
 	cobalt_info("PCIe device status 0x%04x\n", stat);
 
 	/* Link */
-	pci_read_config_dword(pci_dev, offset + PCI_EXP_LNKCAP, &capa);
-	pci_read_config_word(pci_dev, offset + PCI_EXP_LNKCTL, &ctrl);
-	pci_read_config_word(pci_dev, offset + PCI_EXP_LNKSTA, &stat);
+	pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &capa);
+	pcie_capability_read_word(pci_dev, PCI_EXP_LNKCTL, &ctrl);
+	pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &stat);
 	cobalt_info("PCIe link capability 0x%08x: %s per lane and %u lanes\n",
 			capa, get_link_speed(capa),
 			(capa & PCI_EXP_LNKCAP_MLW) >> 4);
@@ -221,15 +217,15 @@
 		    (stat & PCI_EXP_LNKSTA_NLW) >> 4);
 
 	/* Bus */
-	pci_read_config_dword(pci_bus_dev, bus_offset + PCI_EXP_LNKCAP, &capa);
+	pcie_capability_read_dword(pci_bus_dev, PCI_EXP_LNKCAP, &capa);
 	cobalt_info("PCIe bus link capability 0x%08x: %s per lane and %u lanes\n",
 			capa, get_link_speed(capa),
 			(capa & PCI_EXP_LNKCAP_MLW) >> 4);
 
 	/* Slot */
-	pci_read_config_dword(pci_dev, offset + PCI_EXP_SLTCAP, &capa);
-	pci_read_config_word(pci_dev, offset + PCI_EXP_SLTCTL, &ctrl);
-	pci_read_config_word(pci_dev, offset + PCI_EXP_SLTSTA, &stat);
+	pcie_capability_read_dword(pci_dev, PCI_EXP_SLTCAP, &capa);
+	pcie_capability_read_word(pci_dev, PCI_EXP_SLTCTL, &ctrl);
+	pcie_capability_read_word(pci_dev, PCI_EXP_SLTSTA, &stat);
 	cobalt_info("PCIe slot capability 0x%08x\n", capa);
 	cobalt_info("PCIe slot control 0x%04x\n", ctrl);
 	cobalt_info("PCIe slot status 0x%04x\n", stat);
@@ -238,26 +234,22 @@
 static unsigned pcie_link_get_lanes(struct cobalt *cobalt)
 {
 	struct pci_dev *pci_dev = cobalt->pci_dev;
-	unsigned offset;
 	u16 link;
 
-	offset = pci_find_capability(pci_dev, PCI_CAP_ID_EXP);
-	if (!offset)
+	if (!pci_is_pcie(pci_dev))
 		return 0;
-	pci_read_config_word(pci_dev, offset + PCI_EXP_LNKSTA, &link);
+	pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &link);
 	return (link & PCI_EXP_LNKSTA_NLW) >> 4;
 }
 
 static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt)
 {
 	struct pci_dev *pci_dev = cobalt->pci_dev->bus->self;
-	unsigned offset;
 	u32 link;
 
-	offset = pci_find_capability(pci_dev, PCI_CAP_ID_EXP);
-	if (!offset)
+	if (!pci_is_pcie(pci_dev))
 		return 0;
-	pci_read_config_dword(pci_dev, offset + PCI_EXP_LNKCAP, &link);
+	pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &link);
 	return (link & PCI_EXP_LNKCAP_MLW) >> 4;
 }
 
@@ -592,7 +584,7 @@
 		.cec_clk = 12000000,
 	};
 	static struct i2c_board_info adv7511_info = {
-		.type = "adv7511",
+		.type = "adv7511-v4l2",
 		.addr = 0x39, /* 0x39 or 0x3d */
 		.platform_data = &adv7511_pdata,
 	};
diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h
index 429bee4..bca6857 100644
--- a/drivers/media/pci/cobalt/cobalt-driver.h
+++ b/drivers/media/pci/cobalt/cobalt-driver.h
@@ -11,6 +11,7 @@
 #ifndef COBALT_DRIVER_H
 #define COBALT_DRIVER_H
 
+#include <linux/bitops.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
@@ -61,37 +62,37 @@
 #define COBALT_CLK		50000000
 
 /* System status register */
-#define COBALT_SYSSTAT_DIP0_MSK			(1 << 0)
-#define COBALT_SYSSTAT_DIP1_MSK			(1 << 1)
-#define COBALT_SYSSTAT_HSMA_PRSNTN_MSK		(1 << 2)
-#define COBALT_SYSSTAT_FLASH_RDYBSYN_MSK	(1 << 3)
-#define COBALT_SYSSTAT_VI0_5V_MSK		(1 << 4)
-#define COBALT_SYSSTAT_VI0_INT1_MSK		(1 << 5)
-#define COBALT_SYSSTAT_VI0_INT2_MSK		(1 << 6)
-#define COBALT_SYSSTAT_VI0_LOST_DATA_MSK	(1 << 7)
-#define COBALT_SYSSTAT_VI1_5V_MSK		(1 << 8)
-#define COBALT_SYSSTAT_VI1_INT1_MSK		(1 << 9)
-#define COBALT_SYSSTAT_VI1_INT2_MSK		(1 << 10)
-#define COBALT_SYSSTAT_VI1_LOST_DATA_MSK	(1 << 11)
-#define COBALT_SYSSTAT_VI2_5V_MSK		(1 << 12)
-#define COBALT_SYSSTAT_VI2_INT1_MSK		(1 << 13)
-#define COBALT_SYSSTAT_VI2_INT2_MSK		(1 << 14)
-#define COBALT_SYSSTAT_VI2_LOST_DATA_MSK	(1 << 15)
-#define COBALT_SYSSTAT_VI3_5V_MSK		(1 << 16)
-#define COBALT_SYSSTAT_VI3_INT1_MSK		(1 << 17)
-#define COBALT_SYSSTAT_VI3_INT2_MSK		(1 << 18)
-#define COBALT_SYSSTAT_VI3_LOST_DATA_MSK	(1 << 19)
-#define COBALT_SYSSTAT_VIHSMA_5V_MSK		(1 << 20)
-#define COBALT_SYSSTAT_VIHSMA_INT1_MSK		(1 << 21)
-#define COBALT_SYSSTAT_VIHSMA_INT2_MSK		(1 << 22)
-#define COBALT_SYSSTAT_VIHSMA_LOST_DATA_MSK	(1 << 23)
-#define COBALT_SYSSTAT_VOHSMA_INT1_MSK		(1 << 24)
-#define COBALT_SYSSTAT_VOHSMA_PLL_LOCKED_MSK	(1 << 25)
-#define COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK	(1 << 26)
-#define COBALT_SYSSTAT_AUD_PLL_LOCKED_MSK	(1 << 28)
-#define COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK	(1 << 29)
-#define COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK	(1 << 30)
-#define COBALT_SYSSTAT_PCIE_SMBCLK_MSK		(1 << 31)
+#define COBALT_SYSSTAT_DIP0_MSK			BIT(0)
+#define COBALT_SYSSTAT_DIP1_MSK			BIT(1)
+#define COBALT_SYSSTAT_HSMA_PRSNTN_MSK		BIT(2)
+#define COBALT_SYSSTAT_FLASH_RDYBSYN_MSK	BIT(3)
+#define COBALT_SYSSTAT_VI0_5V_MSK		BIT(4)
+#define COBALT_SYSSTAT_VI0_INT1_MSK		BIT(5)
+#define COBALT_SYSSTAT_VI0_INT2_MSK		BIT(6)
+#define COBALT_SYSSTAT_VI0_LOST_DATA_MSK	BIT(7)
+#define COBALT_SYSSTAT_VI1_5V_MSK		BIT(8)
+#define COBALT_SYSSTAT_VI1_INT1_MSK		BIT(9)
+#define COBALT_SYSSTAT_VI1_INT2_MSK		BIT(10)
+#define COBALT_SYSSTAT_VI1_LOST_DATA_MSK	BIT(11)
+#define COBALT_SYSSTAT_VI2_5V_MSK		BIT(12)
+#define COBALT_SYSSTAT_VI2_INT1_MSK		BIT(13)
+#define COBALT_SYSSTAT_VI2_INT2_MSK		BIT(14)
+#define COBALT_SYSSTAT_VI2_LOST_DATA_MSK	BIT(15)
+#define COBALT_SYSSTAT_VI3_5V_MSK		BIT(16)
+#define COBALT_SYSSTAT_VI3_INT1_MSK		BIT(17)
+#define COBALT_SYSSTAT_VI3_INT2_MSK		BIT(18)
+#define COBALT_SYSSTAT_VI3_LOST_DATA_MSK	BIT(19)
+#define COBALT_SYSSTAT_VIHSMA_5V_MSK		BIT(20)
+#define COBALT_SYSSTAT_VIHSMA_INT1_MSK		BIT(21)
+#define COBALT_SYSSTAT_VIHSMA_INT2_MSK		BIT(22)
+#define COBALT_SYSSTAT_VIHSMA_LOST_DATA_MSK	BIT(23)
+#define COBALT_SYSSTAT_VOHSMA_INT1_MSK		BIT(24)
+#define COBALT_SYSSTAT_VOHSMA_PLL_LOCKED_MSK	BIT(25)
+#define COBALT_SYSSTAT_VOHSMA_LOST_DATA_MSK	BIT(26)
+#define COBALT_SYSSTAT_AUD_PLL_LOCKED_MSK	BIT(28)
+#define COBALT_SYSSTAT_AUD_IN_LOST_DATA_MSK	BIT(29)
+#define COBALT_SYSSTAT_AUD_OUT_LOST_DATA_MSK	BIT(30)
+#define COBALT_SYSSTAT_PCIE_SMBCLK_MSK		BIT(31)
 
 /* Cobalt memory map */
 #define COBALT_I2C_0_BASE			0x0
diff --git a/drivers/media/pci/cobalt/cobalt-flash.c b/drivers/media/pci/cobalt/cobalt-flash.c
index ef96e0f..1d3c64b 100644
--- a/drivers/media/pci/cobalt/cobalt-flash.c
+++ b/drivers/media/pci/cobalt/cobalt-flash.c
@@ -69,7 +69,7 @@
 
 	pr_info("%s: offset 0x%x: length %zu\n", __func__, dest, len);
 	while (len) {
-		u16 data = 0xffff;
+		u16 data;
 
 		do {
 			data = *src << (8 * (dest & 1));
diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c b/drivers/media/pci/cobalt/cobalt-v4l2.c
index 39dabd4..c520750 100644
--- a/drivers/media/pci/cobalt/cobalt-v4l2.c
+++ b/drivers/media/pci/cobalt/cobalt-v4l2.c
@@ -688,15 +688,12 @@
 {
 	switch (f->index) {
 	case 0:
-		strscpy(f->description, "YUV 4:2:2", sizeof(f->description));
 		f->pixelformat = V4L2_PIX_FMT_YUYV;
 		break;
 	case 1:
-		strscpy(f->description, "RGB24", sizeof(f->description));
 		f->pixelformat = V4L2_PIX_FMT_RGB24;
 		break;
 	case 2:
-		strscpy(f->description, "RGB32", sizeof(f->description));
 		f->pixelformat = V4L2_PIX_FMT_BGR32;
 		break;
 	default:
@@ -788,7 +785,6 @@
 
 	pix->sizeimage = pix->bytesperline * pix->height;
 	pix->field = V4L2_FIELD_NONE;
-	pix->priv = 0;
 
 	return 0;
 }
@@ -893,11 +889,9 @@
 {
 	switch (f->index) {
 	case 0:
-		strscpy(f->description, "YUV 4:2:2", sizeof(f->description));
 		f->pixelformat = V4L2_PIX_FMT_YUYV;
 		break;
 	case 1:
-		strscpy(f->description, "RGB32", sizeof(f->description));
 		f->pixelformat = V4L2_PIX_FMT_BGR32;
 		break;
 	default:
diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c
index d9ffc9c..85f3e73 100644
--- a/drivers/media/pci/cx18/cx18-ioctl.c
+++ b/drivers/media/pci/cx18/cx18-ioctl.c
@@ -78,7 +78,7 @@
 			return 0;
 	}
 	for (i = 0; i < 32; i++) {
-		if ((1 << i) & set)
+		if (BIT(i) & set)
 			return 1 << i;
 	}
 	return 0;
diff --git a/drivers/media/pci/cx18/cx18-mailbox.c b/drivers/media/pci/cx18/cx18-mailbox.c
index 967ae29..162480e 100644
--- a/drivers/media/pci/cx18/cx18-mailbox.c
+++ b/drivers/media/pci/cx18/cx18-mailbox.c
@@ -6,7 +6,7 @@
  *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
  */
 
-#include <stdarg.h>
+#include <linux/bitops.h>
 
 #include "cx18-driver.h"
 #include "cx18-io.h"
diff --git a/drivers/media/pci/cx23885/cx23885-417.c b/drivers/media/pci/cx23885/cx23885-417.c
index 82f96a4..2327fe6 100644
--- a/drivers/media/pci/cx23885/cx23885-417.c
+++ b/drivers/media/pci/cx23885/cx23885-417.c
@@ -1339,7 +1339,6 @@
 	if (f->index != 0)
 		return -EINVAL;
 
-	strscpy(f->description, "MPEG", sizeof(f->description));
 	f->pixelformat = V4L2_PIX_FMT_MPEG;
 
 	return 0;
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index b254473..8098b15 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -67,7 +67,6 @@
 #define FORMAT_FLAGS_PACKED       0x01
 static struct cx23885_fmt formats[] = {
 	{
-		.name     = "4:2:2, packed, YUYV",
 		.fourcc   = V4L2_PIX_FMT_YUYV,
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
@@ -411,9 +410,9 @@
 	default:
 		BUG();
 	}
-	dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
+	dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp 0x%08x - dma=0x%08lx\n",
 		buf, buf->vb.vb2_buf.index,
-		dev->width, dev->height, dev->fmt->depth, dev->fmt->name,
+		dev->width, dev->height, dev->fmt->depth, dev->fmt->fourcc,
 		(unsigned long)buf->risc.dma);
 	return 0;
 }
@@ -647,8 +646,6 @@
 	if (unlikely(f->index >= ARRAY_SIZE(formats)))
 		return -EINVAL;
 
-	strscpy(f->description, formats[f->index].name,
-		sizeof(f->description));
 	f->pixelformat = formats[f->index].fourcc;
 
 	return 0;
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 9da66fd..a95a2e4 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -127,7 +127,6 @@
 	V4L2_STD_PAL_60 |  V4L2_STD_SECAM_L   |  V4L2_STD_SECAM_DK)
 
 struct cx23885_fmt {
-	char  *name;
 	u32   fourcc;          /* v4l2 format id */
 	int   depth;
 	int   flags;
diff --git a/drivers/media/pci/cx25821/cx25821-video.c b/drivers/media/pci/cx25821/cx25821-video.c
index de76411..a10261d 100644
--- a/drivers/media/pci/cx25821/cx25821-video.c
+++ b/drivers/media/pci/cx25821/cx25821-video.c
@@ -35,12 +35,10 @@
 
 static const struct cx25821_fmt formats[] = {
 	{
-		.name = "4:1:1, packed, Y41P",
 		.fourcc = V4L2_PIX_FMT_Y41P,
 		.depth = 12,
 		.flags = FORMAT_FLAGS_PACKED,
 	}, {
-		.name = "4:2:2, packed, YUYV",
 		.fourcc = V4L2_PIX_FMT_YUYV,
 		.depth = 16,
 		.flags = FORMAT_FLAGS_PACKED,
@@ -215,9 +213,9 @@
 		break;
 	}
 
-	dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
+	dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp 0x%08x - dma=0x%08lx\n",
 		buf, buf->vb.vb2_buf.index, chan->width, chan->height,
-		chan->fmt->depth, chan->fmt->name,
+		chan->fmt->depth, chan->fmt->fourcc,
 		(unsigned long)buf->risc.dma);
 
 	return ret;
@@ -311,7 +309,6 @@
 	if (unlikely(f->index >= ARRAY_SIZE(formats)))
 		return -EINVAL;
 
-	strscpy(f->description, formats[f->index].name, sizeof(f->description));
 	f->pixelformat = formats[f->index].fourcc;
 
 	return 0;
diff --git a/drivers/media/pci/cx25821/cx25821.h b/drivers/media/pci/cx25821/cx25821.h
index 47dbaae..0173079 100644
--- a/drivers/media/pci/cx25821/cx25821.h
+++ b/drivers/media/pci/cx25821/cx25821.h
@@ -83,7 +83,6 @@
 #define VID_CHANNEL_NUM 8
 
 struct cx25821_fmt {
-	char *name;
 	u32 fourcc;		/* v4l2 format id */
 	int depth;
 	int flags;
diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c
index 200d688..d3da7f4 100644
--- a/drivers/media/pci/cx88/cx88-blackbird.c
+++ b/drivers/media/pci/cx88/cx88-blackbird.c
@@ -805,9 +805,7 @@
 	if (f->index != 0)
 		return -EINVAL;
 
-	strscpy(f->description, "MPEG", sizeof(f->description));
 	f->pixelformat = V4L2_PIX_FMT_MPEG;
-	f->flags = V4L2_FMT_FLAG_COMPRESSED;
 	return 0;
 }
 
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index e59a745..dcc0f02 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -69,62 +69,52 @@
 
 static const struct cx8800_fmt formats[] = {
 	{
-		.name     = "8 bpp, gray",
 		.fourcc   = V4L2_PIX_FMT_GREY,
 		.cxformat = ColorFormatY8,
 		.depth    = 8,
 		.flags    = FORMAT_FLAGS_PACKED,
 	}, {
-		.name     = "15 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_RGB555,
 		.cxformat = ColorFormatRGB15,
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	}, {
-		.name     = "15 bpp RGB, be",
 		.fourcc   = V4L2_PIX_FMT_RGB555X,
 		.cxformat = ColorFormatRGB15 | ColorFormatBSWAP,
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	}, {
-		.name     = "16 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_RGB565,
 		.cxformat = ColorFormatRGB16,
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	}, {
-		.name     = "16 bpp RGB, be",
 		.fourcc   = V4L2_PIX_FMT_RGB565X,
 		.cxformat = ColorFormatRGB16 | ColorFormatBSWAP,
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	}, {
-		.name     = "24 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_BGR24,
 		.cxformat = ColorFormatRGB24,
 		.depth    = 24,
 		.flags    = FORMAT_FLAGS_PACKED,
 	}, {
-		.name     = "32 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_BGR32,
 		.cxformat = ColorFormatRGB32,
 		.depth    = 32,
 		.flags    = FORMAT_FLAGS_PACKED,
 	}, {
-		.name     = "32 bpp RGB, be",
 		.fourcc   = V4L2_PIX_FMT_RGB32,
 		.cxformat = ColorFormatRGB32 | ColorFormatBSWAP |
 			    ColorFormatWSWAP,
 		.depth    = 32,
 		.flags    = FORMAT_FLAGS_PACKED,
 	}, {
-		.name     = "4:2:2, packed, YUYV",
 		.fourcc   = V4L2_PIX_FMT_YUYV,
 		.cxformat = ColorFormatYUY2,
 		.depth    = 16,
 		.flags    = FORMAT_FLAGS_PACKED,
 	}, {
-		.name     = "4:2:2, packed, UYVY",
 		.fourcc   = V4L2_PIX_FMT_UYVY,
 		.cxformat = ColorFormatYUY2 | ColorFormatBSWAP,
 		.depth    = 16,
@@ -489,9 +479,9 @@
 		break;
 	}
 	dprintk(2,
-		"[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
-		buf, buf->vb.vb2_buf.index,
-		core->width, core->height, dev->fmt->depth, dev->fmt->name,
+		"[%p/%d] %s - %dx%d %dbpp 0x%08x - dma=0x%08lx\n",
+		buf, buf->vb.vb2_buf.index, __func__,
+		core->width, core->height, dev->fmt->depth, dev->fmt->fourcc,
 		(unsigned long)buf->risc.dma);
 	return 0;
 }
@@ -829,7 +819,6 @@
 	if (unlikely(f->index >= ARRAY_SIZE(formats)))
 		return -EINVAL;
 
-	strscpy(f->description, formats[f->index].name, sizeof(f->description));
 	f->pixelformat = formats[f->index].fourcc;
 
 	return 0;
diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
index a70a50d..744a223 100644
--- a/drivers/media/pci/cx88/cx88.h
+++ b/drivers/media/pci/cx88/cx88.h
@@ -99,7 +99,6 @@
 /* static data                                                 */
 
 struct cx8800_fmt {
-	const char  *name;
 	u32   fourcc;          /* v4l2 format id */
 	int   depth;
 	int   flags;
diff --git a/drivers/media/pci/dt3155/dt3155.c b/drivers/media/pci/dt3155/dt3155.c
index b4cdda5..7480f0d 100644
--- a/drivers/media/pci/dt3155/dt3155.c
+++ b/drivers/media/pci/dt3155/dt3155.c
@@ -306,7 +306,6 @@
 	if (f->index)
 		return -EINVAL;
 	f->pixelformat = V4L2_PIX_FMT_GREY;
-	strscpy(f->description, "8-bit Greyscale", sizeof(f->description));
 	return 0;
 }
 
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
index c1d133e..1adfdc7 100644
--- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
@@ -1475,55 +1475,64 @@
 	.complete = cio2_notifier_complete,
 };
 
-static int cio2_fwnode_parse(struct device *dev,
-			     struct v4l2_fwnode_endpoint *vep,
-			     struct v4l2_async_subdev *asd)
+static int cio2_parse_firmware(struct cio2_device *cio2)
 {
-	struct sensor_async_subdev *s_asd =
-			container_of(asd, struct sensor_async_subdev, asd);
-
-	if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) {
-		dev_err(dev, "Only CSI2 bus type is currently supported\n");
-		return -EINVAL;
-	}
-
-	s_asd->csi2.port = vep->base.port;
-	s_asd->csi2.lanes = vep->bus.mipi_csi2.num_data_lanes;
-
-	return 0;
-}
-
-static int cio2_notifier_init(struct cio2_device *cio2)
-{
+	unsigned int i;
 	int ret;
 
-	v4l2_async_notifier_init(&cio2->notifier);
+	for (i = 0; i < CIO2_NUM_PORTS; i++) {
+		struct v4l2_fwnode_endpoint vep = {
+			.bus_type = V4L2_MBUS_CSI2_DPHY
+		};
+		struct sensor_async_subdev *s_asd = NULL;
+		struct fwnode_handle *ep;
 
-	ret = v4l2_async_notifier_parse_fwnode_endpoints(
-		&cio2->pci_dev->dev, &cio2->notifier,
-		sizeof(struct sensor_async_subdev),
-		cio2_fwnode_parse);
-	if (ret < 0)
+		ep = fwnode_graph_get_endpoint_by_id(
+			dev_fwnode(&cio2->pci_dev->dev), i, 0,
+			FWNODE_GRAPH_ENDPOINT_NEXT);
+
+		if (!ep)
+			continue;
+
+		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+		if (ret)
+			goto err_parse;
+
+		s_asd = kzalloc(sizeof(*s_asd), GFP_KERNEL);
+		if (!s_asd) {
+			ret = -ENOMEM;
+			goto err_parse;
+		}
+
+		s_asd->csi2.port = vep.base.port;
+		s_asd->csi2.lanes = vep.bus.mipi_csi2.num_data_lanes;
+
+		ret = v4l2_async_notifier_add_fwnode_remote_subdev(
+			&cio2->notifier, ep, &s_asd->asd);
+		if (ret)
+			goto err_parse;
+
+		fwnode_handle_put(ep);
+
+		continue;
+
+err_parse:
+		fwnode_handle_put(ep);
+		kfree(s_asd);
 		return ret;
-
-	if (list_empty(&cio2->notifier.asd_list))
-		return -ENODEV;	/* no endpoint */
-
-	cio2->notifier.ops = &cio2_async_ops;
-	ret = v4l2_async_notifier_register(&cio2->v4l2_dev, &cio2->notifier);
-	if (ret) {
-		dev_err(&cio2->pci_dev->dev,
-			"failed to register async notifier : %d\n", ret);
-		v4l2_async_notifier_cleanup(&cio2->notifier);
 	}
 
-	return ret;
-}
+	/*
+	 * Proceed even without sensors connected to allow the device to
+	 * suspend.
+	 */
+	cio2->notifier.ops = &cio2_async_ops;
+	ret = v4l2_async_notifier_register(&cio2->v4l2_dev, &cio2->notifier);
+	if (ret)
+		dev_err(&cio2->pci_dev->dev,
+			"failed to register async notifier : %d\n", ret);
 
-static void cio2_notifier_exit(struct cio2_device *cio2)
-{
-	v4l2_async_notifier_unregister(&cio2->notifier);
-	v4l2_async_notifier_cleanup(&cio2->notifier);
+	return ret;
 }
 
 /**************** Queue initialization ****************/
@@ -1809,17 +1818,18 @@
 	if (r)
 		goto fail_v4l2_device_unregister;
 
+	v4l2_async_notifier_init(&cio2->notifier);
+
 	/* Register notifier for subdevices we care */
-	r = cio2_notifier_init(cio2);
-	/* Proceed without sensors connected to allow the device to suspend. */
-	if (r && r != -ENODEV)
-		goto fail_cio2_queue_exit;
+	r = cio2_parse_firmware(cio2);
+	if (r)
+		goto fail_clean_notifier;
 
 	r = devm_request_irq(&pci_dev->dev, pci_dev->irq, cio2_irq,
 			     IRQF_SHARED, CIO2_NAME, cio2);
 	if (r) {
 		dev_err(&pci_dev->dev, "failed to request IRQ (%d)\n", r);
-		goto fail;
+		goto fail_clean_notifier;
 	}
 
 	pm_runtime_put_noidle(&pci_dev->dev);
@@ -1827,9 +1837,9 @@
 
 	return 0;
 
-fail:
-	cio2_notifier_exit(cio2);
-fail_cio2_queue_exit:
+fail_clean_notifier:
+	v4l2_async_notifier_unregister(&cio2->notifier);
+	v4l2_async_notifier_cleanup(&cio2->notifier);
 	cio2_queues_exit(cio2);
 fail_v4l2_device_unregister:
 	v4l2_device_unregister(&cio2->v4l2_dev);
@@ -1848,7 +1858,8 @@
 	struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
 
 	media_device_unregister(&cio2->media_dev);
-	cio2_notifier_exit(cio2);
+	v4l2_async_notifier_unregister(&cio2->notifier);
+	v4l2_async_notifier_cleanup(&cio2->notifier);
 	cio2_queues_exit(cio2);
 	cio2_fbpt_exit_dummy(cio2);
 	v4l2_device_unregister(&cio2->v4l2_dev);
@@ -2000,8 +2011,7 @@
 
 static int __maybe_unused cio2_resume(struct device *dev)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+	struct cio2_device *cio2 = dev_get_drvdata(dev);
 	int r = 0;
 	struct cio2_queue *q = cio2->cur_queue;
 
diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c
index dd72709..3f3f40e 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.c
+++ b/drivers/media/pci/ivtv/ivtv-driver.c
@@ -910,7 +910,7 @@
 
 	/* check which i2c devices are actually found */
 	for (i = 0; i < 32; i++) {
-		u32 device = 1 << i;
+		u32 device = BIT(i);
 
 		if (!(device & hw))
 			continue;
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index 5595f6a..1378539 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -73,8 +73,8 @@
 			return 0;
 	}
 	for (i = 0; i < 32; i++) {
-		if ((1 << i) & set)
-			return 1 << i;
+		if (BIT(i) & set)
+			return BIT(i);
 	}
 	return 0;
 }
diff --git a/drivers/media/pci/ivtv/ivtv-irq.h b/drivers/media/pci/ivtv/ivtv-irq.h
index 7d2f45e..b8b0703 100644
--- a/drivers/media/pci/ivtv/ivtv-irq.h
+++ b/drivers/media/pci/ivtv/ivtv-irq.h
@@ -10,20 +10,20 @@
 #ifndef IVTV_IRQ_H
 #define IVTV_IRQ_H
 
-#define IVTV_IRQ_ENC_START_CAP		(0x1 << 31)
-#define IVTV_IRQ_ENC_EOS		(0x1 << 30)
-#define IVTV_IRQ_ENC_VBI_CAP		(0x1 << 29)
-#define IVTV_IRQ_ENC_VIM_RST		(0x1 << 28)
-#define IVTV_IRQ_ENC_DMA_COMPLETE	(0x1 << 27)
-#define IVTV_IRQ_ENC_PIO_COMPLETE	(0x1 << 25)
-#define IVTV_IRQ_DEC_AUD_MODE_CHG	(0x1 << 24)
-#define IVTV_IRQ_DEC_DATA_REQ		(0x1 << 22)
-#define IVTV_IRQ_DEC_DMA_COMPLETE	(0x1 << 20)
-#define IVTV_IRQ_DEC_VBI_RE_INSERT	(0x1 << 19)
-#define IVTV_IRQ_DMA_ERR		(0x1 << 18)
-#define IVTV_IRQ_DMA_WRITE		(0x1 << 17)
-#define IVTV_IRQ_DMA_READ		(0x1 << 16)
-#define IVTV_IRQ_DEC_VSYNC		(0x1 << 10)
+#define IVTV_IRQ_ENC_START_CAP		BIT(31)
+#define IVTV_IRQ_ENC_EOS		BIT(30)
+#define IVTV_IRQ_ENC_VBI_CAP		BIT(29)
+#define IVTV_IRQ_ENC_VIM_RST		BIT(28)
+#define IVTV_IRQ_ENC_DMA_COMPLETE	BIT(27)
+#define IVTV_IRQ_ENC_PIO_COMPLETE	BIT(25)
+#define IVTV_IRQ_DEC_AUD_MODE_CHG	BIT(24)
+#define IVTV_IRQ_DEC_DATA_REQ		BIT(22)
+#define IVTV_IRQ_DEC_DMA_COMPLETE	BIT(20)
+#define IVTV_IRQ_DEC_VBI_RE_INSERT	BIT(19)
+#define IVTV_IRQ_DMA_ERR		BIT(18)
+#define IVTV_IRQ_DMA_WRITE		BIT(17)
+#define IVTV_IRQ_DMA_READ		BIT(16)
+#define IVTV_IRQ_DEC_VSYNC		BIT(10)
 
 /* IRQ Masks */
 #define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\
diff --git a/drivers/media/pci/ivtv/ivtv-mailbox.c b/drivers/media/pci/ivtv/ivtv-mailbox.c
index 8393675..d3fdaaa 100644
--- a/drivers/media/pci/ivtv/ivtv-mailbox.c
+++ b/drivers/media/pci/ivtv/ivtv-mailbox.c
@@ -10,8 +10,6 @@
 #include "ivtv-driver.h"
 #include "ivtv-mailbox.h"
 
-#include <stdarg.h>
-
 /* Firmware mailbox flags*/
 #define IVTV_MBOX_FIRMWARE_DONE 0x00000004
 #define IVTV_MBOX_DRIVER_DONE   0x00000002
diff --git a/drivers/media/pci/mantis/mantis_reg.h b/drivers/media/pci/mantis/mantis_reg.h
index 67a80e4..a1e66ef 100644
--- a/drivers/media/pci/mantis/mantis_reg.h
+++ b/drivers/media/pci/mantis/mantis_reg.h
@@ -14,44 +14,44 @@
 #define MANTIS_INT_MASK			0x04
 
 #define MANTIS_INT_RISCSTAT		(0x0f << 28)
-#define MANTIS_INT_RISCEN		(0x01 << 27)
-#define MANTIS_INT_I2CRACK		(0x01 << 26)
+#define MANTIS_INT_RISCEN		BIT(27)
+#define MANTIS_INT_I2CRACK		BIT(26)
 
 /* #define MANTIS_INT_GPIF			(0xff << 12) */
 
-#define MANTIS_INT_PCMCIA7		(0x01 << 19)
-#define MANTIS_INT_PCMCIA6		(0x01 << 18)
-#define MANTIS_INT_PCMCIA5		(0x01 << 17)
-#define MANTIS_INT_PCMCIA4		(0x01 << 16)
-#define MANTIS_INT_PCMCIA3		(0x01 << 15)
-#define MANTIS_INT_PCMCIA2		(0x01 << 14)
-#define MANTIS_INT_PCMCIA1		(0x01 << 13)
-#define MANTIS_INT_PCMCIA0		(0x01 << 12)
-#define MANTIS_INT_IRQ1			(0x01 << 11)
-#define MANTIS_INT_IRQ0			(0x01 << 10)
-#define MANTIS_INT_OCERR		(0x01 <<  8)
-#define MANTIS_INT_PABORT		(0x01 <<  7)
-#define MANTIS_INT_RIPERR		(0x01 <<  6)
-#define MANTIS_INT_PPERR		(0x01 <<  5)
-#define MANTIS_INT_FTRGT		(0x01 <<  3)
-#define MANTIS_INT_RISCI		(0x01 <<  1)
-#define MANTIS_INT_I2CDONE		(0x01 <<  0)
+#define MANTIS_INT_PCMCIA7		BIT(19)
+#define MANTIS_INT_PCMCIA6		BIT(18)
+#define MANTIS_INT_PCMCIA5		BIT(17)
+#define MANTIS_INT_PCMCIA4		BIT(16)
+#define MANTIS_INT_PCMCIA3		BIT(15)
+#define MANTIS_INT_PCMCIA2		BIT(14)
+#define MANTIS_INT_PCMCIA1		BIT(13)
+#define MANTIS_INT_PCMCIA0		BIT(12)
+#define MANTIS_INT_IRQ1			BIT(11)
+#define MANTIS_INT_IRQ0			BIT(10)
+#define MANTIS_INT_OCERR		BIT(8)
+#define MANTIS_INT_PABORT		BIT(7)
+#define MANTIS_INT_RIPERR		BIT(6)
+#define MANTIS_INT_PPERR		BIT(5)
+#define MANTIS_INT_FTRGT		BIT(3)
+#define MANTIS_INT_RISCI		BIT(1)
+#define MANTIS_INT_I2CDONE		BIT(0)
 
 /* DMA */
 #define MANTIS_DMA_CTL			0x08
 #define MANTIS_GPIF_RD			(0xff << 24)
 #define MANTIS_GPIF_WR			(0xff << 16)
-#define MANTIS_CPU_DO			(0x01 << 10)
-#define MANTIS_DRV_DO			(0x01 <<  9)
-#define	MANTIS_I2C_RD			(0x01 <<  7)
-#define MANTIS_I2C_WR			(0x01 <<  6)
-#define MANTIS_DCAP_MODE		(0x01 <<  5)
+#define MANTIS_CPU_DO			BIT(10)
+#define MANTIS_DRV_DO			BIT(9)
+#define	MANTIS_I2C_RD			BIT(7)
+#define MANTIS_I2C_WR			BIT(6)
+#define MANTIS_DCAP_MODE		BIT(5)
 #define MANTIS_FIFO_TP_4		(0x00 <<  3)
 #define MANTIS_FIFO_TP_8		(0x01 <<  3)
 #define MANTIS_FIFO_TP_16		(0x02 <<  3)
-#define MANTIS_FIFO_EN			(0x01 <<  2)
-#define MANTIS_DCAP_EN			(0x01 <<  1)
-#define MANTIS_RISC_EN			(0x01 <<  0)
+#define MANTIS_FIFO_EN			BIT(2)
+#define MANTIS_DCAP_EN			BIT(1)
+#define MANTIS_RISC_EN			BIT(0)
 
 /* DEBUG */
 #define MANTIS_DEBUGREG			0x0c
@@ -68,8 +68,8 @@
 #define MANTIS_I2C_RATE_2		(0x01 <<  6)
 #define MANTIS_I2C_RATE_3		(0x02 <<  6)
 #define MANTIS_I2C_RATE_4		(0x03 <<  6)
-#define MANTIS_I2C_STOP			(0x01 <<  5)
-#define MANTIS_I2C_PGMODE		(0x01 <<  3)
+#define MANTIS_I2C_STOP			BIT(5)
+#define MANTIS_I2C_PGMODE		BIT(3)
 
 /* DATA */
 #define MANTIS_CMD_DATA_R1		0x20
@@ -85,77 +85,77 @@
 #define MANTIS_CMD_DATA_4		(0xff <<  0)
 
 #define MANTIS_CONTROL			0x28
-#define MANTIS_DET			(0x01 <<  7)
-#define MANTIS_DAT_CF_EN		(0x01 <<  6)
+#define MANTIS_DET			BIT(7)
+#define MANTIS_DAT_CF_EN		BIT(6)
 #define MANTIS_ACS			(0x03 <<  4)
-#define MANTIS_VCCEN			(0x01 <<  3)
-#define MANTIS_BYPASS			(0x01 <<  2)
-#define MANTIS_MRST			(0x01 <<  1)
-#define MANTIS_CRST_INT			(0x01 <<  0)
+#define MANTIS_VCCEN			BIT(3)
+#define MANTIS_BYPASS			BIT(2)
+#define MANTIS_MRST			BIT(1)
+#define MANTIS_CRST_INT			BIT(0)
 
 #define MANTIS_GPIF_CFGSLA		0x84
 #define MANTIS_GPIF_WAITSMPL		(0x07 << 28)
-#define MANTIS_GPIF_BYTEADDRSUB		(0x01 << 25)
-#define MANTIS_GPIF_WAITPOL		(0x01 << 24)
+#define MANTIS_GPIF_BYTEADDRSUB		BIT(25)
+#define MANTIS_GPIF_WAITPOL		BIT(24)
 #define MANTIS_GPIF_NCDELAY		(0x07 << 20)
 #define MANTIS_GPIF_RW2CSDELAY		(0x07 << 16)
-#define MANTIS_GPIF_SLFTIMEDMODE	(0x01 << 15)
+#define MANTIS_GPIF_SLFTIMEDMODE	BIT(15)
 #define MANTIS_GPIF_SLFTIMEDDELY	(0x7f <<  8)
 #define MANTIS_GPIF_DEVTYPE		(0x07 <<  4)
-#define MANTIS_GPIF_BIGENDIAN		(0x01 <<  3)
+#define MANTIS_GPIF_BIGENDIAN		BIT(3)
 #define MANTIS_GPIF_FETCHCMD		(0x03 <<  1)
-#define MANTIS_GPIF_HWORDDEV		(0x01 <<  0)
+#define MANTIS_GPIF_HWORDDEV		BIT(0)
 
 #define MANTIS_GPIF_WSTOPER		0x90
-#define MANTIS_GPIF_WSTOPERWREN3	(0x01 << 31)
-#define MANTIS_GPIF_PARBOOTN		(0x01 << 29)
+#define MANTIS_GPIF_WSTOPERWREN3	BIT(31)
+#define MANTIS_GPIF_PARBOOTN		BIT(29)
 #define MANTIS_GPIF_WSTOPERSLID3	(0x1f << 24)
-#define MANTIS_GPIF_WSTOPERWREN2	(0x01 << 23)
+#define MANTIS_GPIF_WSTOPERWREN2	BIT(23)
 #define MANTIS_GPIF_WSTOPERSLID2	(0x1f << 16)
-#define MANTIS_GPIF_WSTOPERWREN1	(0x01 << 15)
+#define MANTIS_GPIF_WSTOPERWREN1	BIT(15)
 #define MANTIS_GPIF_WSTOPERSLID1	(0x1f <<  8)
-#define MANTIS_GPIF_WSTOPERWREN0	(0x01 <<  7)
+#define MANTIS_GPIF_WSTOPERWREN0	BIT(7)
 #define MANTIS_GPIF_WSTOPERSLID0	(0x1f <<  0)
 
 #define MANTIS_GPIF_CS2RW		0x94
-#define MANTIS_GPIF_CS2RWWREN3		(0x01 << 31)
+#define MANTIS_GPIF_CS2RWWREN3		BIT(31)
 #define MANTIS_GPIF_CS2RWDELY3		(0x3f << 24)
-#define MANTIS_GPIF_CS2RWWREN2		(0x01 << 23)
+#define MANTIS_GPIF_CS2RWWREN2		BIT(23)
 #define MANTIS_GPIF_CS2RWDELY2		(0x3f << 16)
-#define MANTIS_GPIF_CS2RWWREN1		(0x01 << 15)
+#define MANTIS_GPIF_CS2RWWREN1		BIT(15)
 #define MANTIS_GPIF_CS2RWDELY1		(0x3f <<  8)
-#define MANTIS_GPIF_CS2RWWREN0		(0x01 <<  7)
+#define MANTIS_GPIF_CS2RWWREN0		BIT(7)
 #define MANTIS_GPIF_CS2RWDELY0		(0x3f <<  0)
 
 #define MANTIS_GPIF_IRQCFG		0x98
-#define MANTIS_GPIF_IRQPOL		(0x01 <<  8)
-#define MANTIS_MASK_WRACK		(0x01 <<  7)
-#define MANTIS_MASK_BRRDY		(0x01 <<  6)
-#define MANTIS_MASK_OVFLW		(0x01 <<  5)
-#define MANTIS_MASK_OTHERR		(0x01 <<  4)
-#define MANTIS_MASK_WSTO		(0x01 <<  3)
-#define MANTIS_MASK_EXTIRQ		(0x01 <<  2)
-#define MANTIS_MASK_PLUGIN		(0x01 <<  1)
-#define MANTIS_MASK_PLUGOUT		(0x01 <<  0)
+#define MANTIS_GPIF_IRQPOL		BIT(8)
+#define MANTIS_MASK_WRACK		BIT(7)
+#define MANTIS_MASK_BRRDY		BIT(6)
+#define MANTIS_MASK_OVFLW		BIT(5)
+#define MANTIS_MASK_OTHERR		BIT(4)
+#define MANTIS_MASK_WSTO		BIT(3)
+#define MANTIS_MASK_EXTIRQ		BIT(2)
+#define MANTIS_MASK_PLUGIN		BIT(1)
+#define MANTIS_MASK_PLUGOUT		BIT(0)
 
 #define MANTIS_GPIF_STATUS		0x9c
-#define MANTIS_SBUF_KILLOP		(0x01 << 15)
-#define MANTIS_SBUF_OPDONE		(0x01 << 14)
-#define MANTIS_SBUF_EMPTY		(0x01 << 13)
-#define MANTIS_GPIF_DETSTAT		(0x01 <<  9)
-#define MANTIS_GPIF_INTSTAT		(0x01 <<  8)
-#define MANTIS_GPIF_WRACK		(0x01 <<  7)
-#define MANTIS_GPIF_BRRDY		(0x01 <<  6)
-#define MANTIS_SBUF_OVFLW		(0x01 <<  5)
-#define MANTIS_GPIF_OTHERR		(0x01 <<  4)
-#define MANTIS_SBUF_WSTO		(0x01 <<  3)
-#define MANTIS_GPIF_EXTIRQ		(0x01 <<  2)
-#define MANTIS_CARD_PLUGIN		(0x01 <<  1)
-#define MANTIS_CARD_PLUGOUT		(0x01 <<  0)
+#define MANTIS_SBUF_KILLOP		BIT(15)
+#define MANTIS_SBUF_OPDONE		BIT(14)
+#define MANTIS_SBUF_EMPTY		BIT(13)
+#define MANTIS_GPIF_DETSTAT		BIT(9)
+#define MANTIS_GPIF_INTSTAT		BIT(8)
+#define MANTIS_GPIF_WRACK		BIT(7)
+#define MANTIS_GPIF_BRRDY		BIT(6)
+#define MANTIS_SBUF_OVFLW		BIT(5)
+#define MANTIS_GPIF_OTHERR		BIT(4)
+#define MANTIS_SBUF_WSTO		BIT(3)
+#define MANTIS_GPIF_EXTIRQ		BIT(2)
+#define MANTIS_CARD_PLUGIN		BIT(1)
+#define MANTIS_CARD_PLUGOUT		BIT(0)
 
 #define MANTIS_GPIF_BRADDR		0xa0
-#define MANTIS_GPIF_PCMCIAREG		(0x01		<< 27)
-#define MANTIS_GPIF_PCMCIAIOM		(0x01		<< 26)
+#define MANTIS_GPIF_PCMCIAREG		BIT(27)
+#define MANTIS_GPIF_PCMCIAIOM		BIT(26)
 #define MANTIS_GPIF_BR_ADDR		(0xfffffff	<<  0)
 
 #define MANTIS_GPIF_BRBYTES		0xa4
@@ -167,9 +167,9 @@
 #define MANTIS_CARD_RESET		0xac
 
 #define MANTIS_GPIF_ADDR		0xb0
-#define MANTIS_GPIF_HIFRDWRN		(0x01		<< 31)
-#define MANTIS_GPIF_PCMCIAREG		(0x01		<< 27)
-#define MANTIS_GPIF_PCMCIAIOM		(0x01		<< 26)
+#define MANTIS_GPIF_HIFRDWRN		BIT(31)
+#define MANTIS_GPIF_PCMCIAREG		BIT(27)
+#define MANTIS_GPIF_PCMCIAIOM		BIT(26)
 #define MANTIS_GPIF_HIFADDR		(0xfffffff	<<  0)
 
 #define MANTIS_GPIF_DOUT		0xb4
diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c
index 8218810..0e61c81 100644
--- a/drivers/media/pci/meye/meye.c
+++ b/drivers/media/pci/meye/meye.c
@@ -1104,12 +1104,9 @@
 	if (f->index == 0) {
 		/* standard YUV 422 capture */
 		f->flags = 0;
-		strscpy(f->description, "YUV422", sizeof(f->description));
 		f->pixelformat = V4L2_PIX_FMT_YUYV;
 	} else {
 		/* compressed MJPEG capture */
-		f->flags = V4L2_FMT_FLAG_COMPRESSED;
-		strscpy(f->description, "MJPEG", sizeof(f->description));
 		f->pixelformat = V4L2_PIX_FMT_MJPEG;
 	}
 
diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c
index b75ab7d..af15ca1 100644
--- a/drivers/media/pci/ngene/ngene-core.c
+++ b/drivers/media/pci/ngene/ngene-core.c
@@ -854,8 +854,6 @@
 	if (!Head)
 		return -ENOMEM;
 
-	memset(Head, 0, MemSize);
-
 	PARingBufferCur = PARingBufferHead;
 	Cur = Head;
 
@@ -907,8 +905,6 @@
 	if (SCListMem == NULL)
 		return -ENOMEM;
 
-	memset(SCListMem, 0, SCListMemSize);
-
 	pRingBuffer->SCListMem = SCListMem;
 	pRingBuffer->PASCListMem = PASCListMem;
 	pRingBuffer->SCListMemSize = SCListMemSize;
diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
index e51c80b..72b191c 100644
--- a/drivers/media/pci/pt1/pt1.c
+++ b/drivers/media/pci/pt1/pt1.c
@@ -1217,8 +1217,7 @@
 
 static int pt1_suspend(struct device *dev)
 {
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct pt1 *pt1 = pci_get_drvdata(pdev);
+	struct pt1 *pt1 = dev_get_drvdata(dev);
 
 	pt1_init_streams(pt1);
 	pt1_disable_ram(pt1);
@@ -1230,8 +1229,7 @@
 
 static int pt1_resume(struct device *dev)
 {
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct pt1 *pt1 = pci_get_drvdata(pdev);
+	struct pt1 *pt1 = dev_get_drvdata(dev);
 	int ret;
 	int i;
 
diff --git a/drivers/media/pci/pt3/pt3.c b/drivers/media/pci/pt3/pt3.c
index 7a7afae..c0bc867 100644
--- a/drivers/media/pci/pt3/pt3.c
+++ b/drivers/media/pci/pt3/pt3.c
@@ -626,8 +626,7 @@
 
 static int pt3_suspend(struct device *dev)
 {
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct pt3_board *pt3 = pci_get_drvdata(pdev);
+	struct pt3_board *pt3 = dev_get_drvdata(dev);
 	int i;
 	struct pt3_adapter *adap;
 
@@ -646,8 +645,7 @@
 
 static int pt3_resume(struct device *dev)
 {
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct pt3_board *pt3 = pci_get_drvdata(pdev);
+	struct pt3_board *pt3 = dev_get_drvdata(dev);
 	int i, ret;
 	struct pt3_adapter *adap;
 
diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c
index eb8377a..f359cd5 100644
--- a/drivers/media/pci/saa7134/saa7134-dvb.c
+++ b/drivers/media/pci/saa7134/saa7134-dvb.c
@@ -1264,6 +1264,20 @@
 					       &medion_cardbus,
 					       &dev->i2c_adap);
 		if (fe0->dvb.frontend) {
+			/*
+			 * The TV tuner on this board is actually NOT
+			 * behind the demod i2c gate.
+			 * However, the demod EEPROM is indeed there and it
+			 * conflicts with the SAA7134 chip config EEPROM
+			 * if the i2c gate is open (since they have same
+			 * bus addresses) resulting in card PCI SVID / SSID
+			 * being garbage after a reboot from time to time.
+			 *
+			 * Let's just leave the gate permanently closed -
+			 * saa7134_i2c_eeprom_md7134_gate() will close it for
+			 * us at probe time if it was open for some reason.
+			 */
+			fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
 			dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 				   &dev->i2c_adap, medion_cardbus.tuner_address,
 				   TUNER_PHILIPS_FMD1216ME_MK3);
diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c
index 1a41a56..cb65d34 100644
--- a/drivers/media/pci/saa7134/saa7134-empress.c
+++ b/drivers/media/pci/saa7134/saa7134-empress.c
@@ -91,9 +91,7 @@
 	if (f->index != 0)
 		return -EINVAL;
 
-	strscpy(f->description, "MPEG TS", sizeof(f->description));
 	f->pixelformat = V4L2_PIX_FMT_MPEG;
-	f->flags = V4L2_FMT_FLAG_COMPRESSED;
 	return 0;
 }
 
diff --git a/drivers/media/pci/saa7134/saa7134-i2c.c b/drivers/media/pci/saa7134/saa7134-i2c.c
index 493b185..04e8576 100644
--- a/drivers/media/pci/saa7134/saa7134-i2c.c
+++ b/drivers/media/pci/saa7134/saa7134-i2c.c
@@ -342,7 +342,11 @@
 
 /* ----------------------------------------------------------- */
 
-/* On Medion 7134 reading EEPROM needs DVB-T demod i2c gate open */
+/*
+ * On Medion 7134 reading the SAA7134 chip config EEPROM needs DVB-T
+ * demod i2c gate closed due to an address clash between this EEPROM
+ * and the demod one.
+ */
 static void saa7134_i2c_eeprom_md7134_gate(struct saa7134_dev *dev)
 {
 	u8 subaddr = 0x7, dmdregval;
@@ -359,14 +363,14 @@
 
 	ret = i2c_transfer(&dev->i2c_adap, i2cgatemsg_r, 2);
 	if ((ret == 2) && (dmdregval & 0x2)) {
-		pr_debug("%s: DVB-T demod i2c gate was left closed\n",
+		pr_debug("%s: DVB-T demod i2c gate was left open\n",
 			 dev->name);
 
 		data[0] = subaddr;
 		data[1] = (dmdregval & ~0x2);
 		if (i2c_transfer(&dev->i2c_adap, i2cgatemsg_w, 1) != 1)
-			pr_err("%s: EEPROM i2c gate open failure\n",
-			  dev->name);
+			pr_err("%s: EEPROM i2c gate close failure\n",
+			       dev->name);
 	}
 }
 
diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c
index 5beff53..79e1afb 100644
--- a/drivers/media/pci/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c
@@ -319,7 +319,6 @@
 	__s32 left,right,value;
 
 	if (!(dev->tvnorm->id & scan->std)) {
-		value = 0;
 		audio_dbg(1, "skipping %d.%03d MHz [%4s]\n",
 			  scan->carr / 1000, scan->carr % 1000, scan->name);
 		return 0;
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 606df51..342cabf4 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -90,70 +90,58 @@
 
 static struct saa7134_format formats[] = {
 	{
-		.name     = "8 bpp gray",
 		.fourcc   = V4L2_PIX_FMT_GREY,
 		.depth    = 8,
 		.pm       = 0x06,
 	},{
-		.name     = "15 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_RGB555,
 		.depth    = 16,
 		.pm       = 0x13 | 0x80,
 	},{
-		.name     = "15 bpp RGB, be",
 		.fourcc   = V4L2_PIX_FMT_RGB555X,
 		.depth    = 16,
 		.pm       = 0x13 | 0x80,
 		.bswap    = 1,
 	},{
-		.name     = "16 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_RGB565,
 		.depth    = 16,
 		.pm       = 0x10 | 0x80,
 	},{
-		.name     = "16 bpp RGB, be",
 		.fourcc   = V4L2_PIX_FMT_RGB565X,
 		.depth    = 16,
 		.pm       = 0x10 | 0x80,
 		.bswap    = 1,
 	},{
-		.name     = "24 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_BGR24,
 		.depth    = 24,
 		.pm       = 0x11,
 	},{
-		.name     = "24 bpp RGB, be",
 		.fourcc   = V4L2_PIX_FMT_RGB24,
 		.depth    = 24,
 		.pm       = 0x11,
 		.bswap    = 1,
 	},{
-		.name     = "32 bpp RGB, le",
 		.fourcc   = V4L2_PIX_FMT_BGR32,
 		.depth    = 32,
 		.pm       = 0x12,
 	},{
-		.name     = "32 bpp RGB, be",
 		.fourcc   = V4L2_PIX_FMT_RGB32,
 		.depth    = 32,
 		.pm       = 0x12,
 		.bswap    = 1,
 		.wswap    = 1,
 	},{
-		.name     = "4:2:2 packed, YUYV",
 		.fourcc   = V4L2_PIX_FMT_YUYV,
 		.depth    = 16,
 		.pm       = 0x00,
 		.bswap    = 1,
 		.yuv      = 1,
 	},{
-		.name     = "4:2:2 packed, UYVY",
 		.fourcc   = V4L2_PIX_FMT_UYVY,
 		.depth    = 16,
 		.pm       = 0x00,
 		.yuv      = 1,
 	},{
-		.name     = "4:2:2 planar, Y-Cb-Cr",
 		.fourcc   = V4L2_PIX_FMT_YUV422P,
 		.depth    = 16,
 		.pm       = 0x09,
@@ -162,7 +150,6 @@
 		.hshift   = 1,
 		.vshift   = 0,
 	},{
-		.name     = "4:2:0 planar, Y-Cb-Cr",
 		.fourcc   = V4L2_PIX_FMT_YUV420,
 		.depth    = 12,
 		.pm       = 0x0a,
@@ -171,7 +158,6 @@
 		.hshift   = 1,
 		.vshift   = 1,
 	},{
-		.name     = "4:2:0 planar, Y-Cb-Cr",
 		.fourcc   = V4L2_PIX_FMT_YVU420,
 		.depth    = 12,
 		.pm       = 0x0a,
@@ -720,10 +706,10 @@
 		return err;
 
 	dev->ovfield = dev->win.field;
-	video_dbg("start_preview %dx%d+%d+%d %s field=%s\n",
-		dev->win.w.width, dev->win.w.height,
-		dev->win.w.left, dev->win.w.top,
-		dev->ovfmt->name, v4l2_field_names[dev->ovfield]);
+	video_dbg("%s %dx%d+%d+%d 0x%08x field=%s\n", __func__,
+		  dev->win.w.width, dev->win.w.height,
+		  dev->win.w.left, dev->win.w.top,
+		  dev->ovfmt->fourcc, v4l2_field_names[dev->ovfield]);
 
 	/* setup window + clipping */
 	set_size(dev, TASK_B, dev->win.w.width, dev->win.w.height,
@@ -1780,9 +1766,6 @@
 	if (f->index >= FORMATS)
 		return -EINVAL;
 
-	strscpy(f->description, formats[f->index].name,
-		sizeof(f->description));
-
 	f->pixelformat = formats[f->index].fourcc;
 
 	return 0;
@@ -1799,9 +1782,6 @@
 	if ((f->index >= FORMATS) || formats[f->index].planar)
 		return -EINVAL;
 
-	strscpy(f->description, formats[f->index].name,
-		sizeof(f->description));
-
 	f->pixelformat = formats[f->index].fourcc;
 
 	return 0;
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index 6324f17..77c325e 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -98,7 +98,6 @@
 };
 
 struct saa7134_format {
-	char           *name;
 	unsigned int   fourcc;
 	unsigned int   depth;
 	unsigned int   pm;
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c
index dca20a3..f962269 100644
--- a/drivers/media/pci/saa7146/hexium_gemini.c
+++ b/drivers/media/pci/saa7146/hexium_gemini.c
@@ -292,6 +292,9 @@
 	ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER);
 	if (ret < 0) {
 		pr_err("cannot register capture v4l2 device. skipping.\n");
+		saa7146_vv_release(dev);
+		i2c_del_adapter(&hexium->i2c_adapter);
+		kfree(hexium);
 		return ret;
 	}
 
diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c
index 43fdaa2..3fca725 100644
--- a/drivers/media/pci/saa7164/saa7164-encoder.c
+++ b/drivers/media/pci/saa7164/saa7164-encoder.c
@@ -503,7 +503,6 @@
 	if (f->index != 0)
 		return -EINVAL;
 
-	strscpy(f->description, "MPEG", sizeof(f->description));
 	f->pixelformat = V4L2_PIX_FMT_MPEG;
 
 	return 0;
diff --git a/drivers/media/pci/solo6x10/solo6x10-gpio.c b/drivers/media/pci/solo6x10/solo6x10-gpio.c
index 5caeca8..526d67c 100644
--- a/drivers/media/pci/solo6x10/solo6x10-gpio.c
+++ b/drivers/media/pci/solo6x10/solo6x10-gpio.c
@@ -39,13 +39,13 @@
 	ret = solo_reg_read(solo_dev, SOLO_GPIO_CONFIG_1);
 
 	for (port = 0; port < 16; port++) {
-		if (!((1 << (port + 16)) & port_mask))
+		if (!((1UL << (port + 16)) & port_mask))
 			continue;
 
 		if (!mode)
-			ret &= ~(1 << port);
+			ret &= ~(1UL << port);
 		else
-			ret |= 1 << port;
+			ret |= 1UL << port;
 	}
 
 	/* Enable GPIO[31:16] */
diff --git a/drivers/media/pci/solo6x10/solo6x10-regs.h b/drivers/media/pci/solo6x10/solo6x10-regs.h
index d88cc02..804505d 100644
--- a/drivers/media/pci/solo6x10/solo6x10-regs.h
+++ b/drivers/media/pci/solo6x10/solo6x10-regs.h
@@ -12,6 +12,8 @@
 #ifndef __SOLO6X10_REGISTERS_H
 #define __SOLO6X10_REGISTERS_H
 
+#include <linux/bitops.h>
+
 #include "solo6x10-offsets.h"
 
 /* Global 6010 system configuration */
@@ -32,17 +34,17 @@
 #define	  SOLO_DMA_CTRL_REFRESH_CYCLE(n)	((n)<<8)
 /* 0=16/32MB, 1=32/64MB, 2=64/128MB, 3=128/256MB */
 #define	  SOLO_DMA_CTRL_SDRAM_SIZE(n)		((n)<<6)
-#define	  SOLO_DMA_CTRL_SDRAM_CLK_INVERT	(1<<5)
-#define	  SOLO_DMA_CTRL_STROBE_SELECT		(1<<4)
-#define	  SOLO_DMA_CTRL_READ_DATA_SELECT	(1<<3)
-#define	  SOLO_DMA_CTRL_READ_CLK_SELECT		(1<<2)
+#define	  SOLO_DMA_CTRL_SDRAM_CLK_INVERT	BIT(5)
+#define	  SOLO_DMA_CTRL_STROBE_SELECT		BIT(4)
+#define	  SOLO_DMA_CTRL_READ_DATA_SELECT	BIT(3)
+#define	  SOLO_DMA_CTRL_READ_CLK_SELECT		BIT(2)
 #define	  SOLO_DMA_CTRL_LATENCY(n)		((n)<<0)
 
 /* Some things we set in this are undocumented. Why Softlogic?!?! */
 #define SOLO_DMA_CTRL1				0x0008
 
 #define SOLO_SYS_VCLK				0x000C
-#define	  SOLO_VCLK_INVERT			(1<<22)
+#define	  SOLO_VCLK_INVERT			BIT(22)
 /* 0=sys_clk/4, 1=sys_clk/2, 2=clk_in/2 of system input */
 #define	  SOLO_VCLK_SELECT(n)			((n)<<20)
 #define	  SOLO_VCLK_VIN1415_DELAY(n)		((n)<<14)
@@ -56,22 +58,22 @@
 
 #define SOLO_IRQ_STAT				0x0010
 #define SOLO_IRQ_MASK				0x0014
-#define	  SOLO_IRQ_P2M(n)			(1<<((n)+17))
-#define	  SOLO_IRQ_GPIO				(1<<16)
-#define	  SOLO_IRQ_VIDEO_LOSS			(1<<15)
-#define	  SOLO_IRQ_VIDEO_IN			(1<<14)
-#define	  SOLO_IRQ_MOTION			(1<<13)
-#define	  SOLO_IRQ_ATA_CMD			(1<<12)
-#define	  SOLO_IRQ_ATA_DIR			(1<<11)
-#define	  SOLO_IRQ_PCI_ERR			(1<<10)
-#define	  SOLO_IRQ_PS2_1			(1<<9)
-#define	  SOLO_IRQ_PS2_0			(1<<8)
-#define	  SOLO_IRQ_SPI				(1<<7)
-#define	  SOLO_IRQ_IIC				(1<<6)
-#define	  SOLO_IRQ_UART(n)			(1<<((n) + 4))
-#define	  SOLO_IRQ_G723				(1<<3)
-#define	  SOLO_IRQ_DECODER			(1<<1)
-#define	  SOLO_IRQ_ENCODER			(1<<0)
+#define	  SOLO_IRQ_P2M(n)			BIT((n) + 17)
+#define	  SOLO_IRQ_GPIO				BIT(16)
+#define	  SOLO_IRQ_VIDEO_LOSS			BIT(15)
+#define	  SOLO_IRQ_VIDEO_IN			BIT(14)
+#define	  SOLO_IRQ_MOTION			BIT(13)
+#define	  SOLO_IRQ_ATA_CMD			BIT(12)
+#define	  SOLO_IRQ_ATA_DIR			BIT(11)
+#define	  SOLO_IRQ_PCI_ERR			BIT(10)
+#define	  SOLO_IRQ_PS2_1			BIT(9)
+#define	  SOLO_IRQ_PS2_0			BIT(8)
+#define	  SOLO_IRQ_SPI				BIT(7)
+#define	  SOLO_IRQ_IIC				BIT(6)
+#define	  SOLO_IRQ_UART(n)			BIT((n) + 4)
+#define	  SOLO_IRQ_G723				BIT(3)
+#define	  SOLO_IRQ_DECODER			BIT(1)
+#define	  SOLO_IRQ_ENCODER			BIT(0)
 
 #define SOLO_CHIP_OPTION			0x001C
 #define   SOLO_CHIP_ID_MASK			0x00000007
@@ -79,11 +81,11 @@
 #define SOLO_PLL_CONFIG				0x0020 /* 6110 Only */
 
 #define SOLO_EEPROM_CTRL			0x0060
-#define	  SOLO_EEPROM_ACCESS_EN			(1<<7)
-#define	  SOLO_EEPROM_CS			(1<<3)
-#define	  SOLO_EEPROM_CLK			(1<<2)
-#define	  SOLO_EEPROM_DO			(1<<1)
-#define	  SOLO_EEPROM_DI			(1<<0)
+#define	  SOLO_EEPROM_ACCESS_EN			BIT(7)
+#define	  SOLO_EEPROM_CS			BIT(3)
+#define	  SOLO_EEPROM_CLK			BIT(2)
+#define	  SOLO_EEPROM_DO			BIT(1)
+#define	  SOLO_EEPROM_DI			BIT(0)
 #define	  SOLO_EEPROM_ENABLE (SOLO_EEPROM_ACCESS_EN | SOLO_EEPROM_CS)
 
 #define SOLO_PCI_ERR				0x0070
@@ -102,13 +104,13 @@
 
 #define SOLO_P2M_CONFIG(n)			(0x0080 + ((n)*0x20))
 #define	  SOLO_P2M_DMA_INTERVAL(n)		((n)<<6)/* N*32 clocks */
-#define	  SOLO_P2M_CSC_BYTE_REORDER		(1<<5)	/* BGR -> RGB */
+#define	  SOLO_P2M_CSC_BYTE_REORDER		BIT(5)	/* BGR -> RGB */
 /* 0:r=[14:10] g=[9:5] b=[4:0], 1:r=[15:11] g=[10:5] b=[4:0] */
-#define	  SOLO_P2M_CSC_16BIT_565		(1<<4)
-#define	  SOLO_P2M_UV_SWAP			(1<<3)
-#define	  SOLO_P2M_PCI_MASTER_MODE		(1<<2)
-#define	  SOLO_P2M_DESC_INTR_OPT		(1<<1)	/* 1:Empty, 0:Each */
-#define	  SOLO_P2M_DESC_MODE			(1<<0)
+#define	  SOLO_P2M_CSC_16BIT_565		BIT(4)
+#define	  SOLO_P2M_UV_SWAP			BIT(3)
+#define	  SOLO_P2M_PCI_MASTER_MODE		BIT(2)
+#define	  SOLO_P2M_DESC_INTR_OPT		BIT(1)	/* 1:Empty, 0:Each */
+#define	  SOLO_P2M_DESC_MODE			BIT(0)
 
 #define SOLO_P2M_DES_ADR(n)			(0x0084 + ((n)*0x20))
 
@@ -116,7 +118,7 @@
 #define	  SOLO_P2M_UPDATE_ID(n)			((n)<<0)
 
 #define SOLO_P2M_STATUS(n)			(0x008C + ((n)*0x20))
-#define	  SOLO_P2M_COMMAND_DONE			(1<<8)
+#define	  SOLO_P2M_COMMAND_DONE			BIT(8)
 #define	  SOLO_P2M_CURRENT_ID(stat)		(0xff & (stat))
 
 #define SOLO_P2M_CONTROL(n)			(0x0090 + ((n)*0x20))
@@ -129,13 +131,13 @@
 #define	    SOLO_P2M_BURST_128			2
 #define	    SOLO_P2M_BURST_64			3
 #define	    SOLO_P2M_BURST_32			4
-#define	  SOLO_P2M_CSC_16BIT			(1<<6)	/* 0:24bit, 1:16bit */
+#define	  SOLO_P2M_CSC_16BIT			BIT(6)	/* 0:24bit, 1:16bit */
 /* 0:Y[0]<-0(OFF), 1:Y[0]<-1(ON), 2:Y[0]<-G[0], 3:Y[0]<-Bit[15] */
 #define	  SOLO_P2M_ALPHA_MODE(n)		((n)<<4)
-#define	  SOLO_P2M_CSC_ON			(1<<3)
-#define	  SOLO_P2M_INTERRUPT_REQ		(1<<2)
-#define	  SOLO_P2M_WRITE			(1<<1)
-#define	  SOLO_P2M_TRANS_ON			(1<<0)
+#define	  SOLO_P2M_CSC_ON			BIT(3)
+#define	  SOLO_P2M_INTERRUPT_REQ		BIT(2)
+#define	  SOLO_P2M_WRITE			BIT(1)
+#define	  SOLO_P2M_TRANS_ON			BIT(0)
 
 #define SOLO_P2M_EXT_CFG(n)			(0x0094 + ((n)*0x20))
 #define	  SOLO_P2M_EXT_INC(n)			((n)<<20)
@@ -157,9 +159,9 @@
 #define	  SOLO_VI_PROG_MASK(n)			((n)<<0)
 
 #define SOLO_VI_FMT_CFG				0x0114
-#define	  SOLO_VI_FMT_CHECK_VCOUNT		(1<<31)
-#define	  SOLO_VI_FMT_CHECK_HCOUNT		(1<<30)
-#define   SOLO_VI_FMT_TEST_SIGNAL		(1<<28)
+#define	  SOLO_VI_FMT_CHECK_VCOUNT		BIT(31)
+#define	  SOLO_VI_FMT_CHECK_HCOUNT		BIT(30)
+#define   SOLO_VI_FMT_TEST_SIGNAL		BIT(28)
 
 #define	SOLO_VI_PAGE_SW				0x0118
 #define	  SOLO_FI_INV_DISP_LIVE(n)		((n)<<8)
@@ -171,7 +173,7 @@
 #define	SOLO_VI_ACT_I_P				0x011C
 #define	SOLO_VI_ACT_I_S				0x0120
 #define	SOLO_VI_ACT_P				0x0124
-#define	  SOLO_VI_FI_INVERT			(1<<31)
+#define	  SOLO_VI_FI_INVERT			BIT(31)
 #define	  SOLO_VI_H_START(n)			((n)<<21)
 #define	  SOLO_VI_V_START(n)			((n)<<11)
 #define	  SOLO_VI_V_STOP(n)			((n)<<0)
@@ -184,8 +186,8 @@
 #define DISP_PAGE(stat)				((stat) & 0x07)
 
 #define SOLO_VI_PB_CONFIG			0x0130
-#define	  SOLO_VI_PB_USER_MODE			(1<<1)
-#define	  SOLO_VI_PB_PAL			(1<<0)
+#define	  SOLO_VI_PB_USER_MODE			BIT(1)
+#define	  SOLO_VI_PB_PAL			BIT(0)
 #define SOLO_VI_PB_RANGE_HV			0x0134
 #define	  SOLO_VI_PB_HSIZE(h)			((h)<<12)
 #define	  SOLO_VI_PB_VSIZE(v)			((v)<<0)
@@ -226,35 +228,35 @@
 #define	SOLO_VI_MOT_CTRL			0x0264
 #define	  SOLO_VI_MOTION_FRAME_COUNT(n)		((n)<<24)
 #define	  SOLO_VI_MOTION_SAMPLE_LENGTH(n)	((n)<<16)
-#define	  SOLO_VI_MOTION_INTR_START_STOP	(1<<15)
-#define	  SOLO_VI_MOTION_FREEZE_DATA		(1<<14)
+#define	  SOLO_VI_MOTION_INTR_START_STOP	BIT(15)
+#define	  SOLO_VI_MOTION_FREEZE_DATA		BIT(14)
 #define	  SOLO_VI_MOTION_SAMPLE_COUNT(n)	((n)<<0)
 #define SOLO_VI_MOT_CLEAR			0x0268
 #define SOLO_VI_MOT_STATUS			0x026C
 #define	  SOLO_VI_MOTION_CNT(n)			((n)<<0)
 #define SOLO_VI_MOTION_BORDER			0x0270
 #define SOLO_VI_MOTION_BAR			0x0274
-#define	  SOLO_VI_MOTION_Y_SET			(1<<29)
-#define	  SOLO_VI_MOTION_Y_ADD			(1<<28)
-#define	  SOLO_VI_MOTION_CB_SET			(1<<27)
-#define	  SOLO_VI_MOTION_CB_ADD			(1<<26)
-#define	  SOLO_VI_MOTION_CR_SET			(1<<25)
-#define	  SOLO_VI_MOTION_CR_ADD			(1<<24)
+#define	  SOLO_VI_MOTION_Y_SET			BIT(29)
+#define	  SOLO_VI_MOTION_Y_ADD			BIT(28)
+#define	  SOLO_VI_MOTION_CB_SET			BIT(27)
+#define	  SOLO_VI_MOTION_CB_ADD			BIT(26)
+#define	  SOLO_VI_MOTION_CR_SET			BIT(25)
+#define	  SOLO_VI_MOTION_CR_ADD			BIT(24)
 #define	  SOLO_VI_MOTION_Y_VALUE(v)		((v)<<16)
 #define	  SOLO_VI_MOTION_CB_VALUE(v)		((v)<<8)
 #define	  SOLO_VI_MOTION_CR_VALUE(v)		((v)<<0)
 
 #define	SOLO_VO_FMT_ENC				0x0300
-#define	  SOLO_VO_SCAN_MODE_PROGRESSIVE		(1<<31)
-#define	  SOLO_VO_FMT_TYPE_PAL			(1<<30)
+#define	  SOLO_VO_SCAN_MODE_PROGRESSIVE		BIT(31)
+#define	  SOLO_VO_FMT_TYPE_PAL			BIT(30)
 #define   SOLO_VO_FMT_TYPE_NTSC			0
-#define	  SOLO_VO_USER_SET			(1<<29)
+#define	  SOLO_VO_USER_SET			BIT(29)
 
-#define	  SOLO_VO_FI_CHANGE			(1<<20)
-#define	  SOLO_VO_USER_COLOR_SET_VSYNC		(1<<19)
-#define	  SOLO_VO_USER_COLOR_SET_HSYNC		(1<<18)
-#define	  SOLO_VO_USER_COLOR_SET_NAH		(1<<17)
-#define	  SOLO_VO_USER_COLOR_SET_NAV		(1<<16)
+#define	  SOLO_VO_FI_CHANGE			BIT(20)
+#define	  SOLO_VO_USER_COLOR_SET_VSYNC		BIT(19)
+#define	  SOLO_VO_USER_COLOR_SET_HSYNC		BIT(18)
+#define	  SOLO_VO_USER_COLOR_SET_NAH		BIT(17)
+#define	  SOLO_VO_USER_COLOR_SET_NAV		BIT(16)
 #define	  SOLO_VO_NA_COLOR_Y(Y)			((Y)<<8)
 #define	  SOLO_VO_NA_COLOR_CB(CB)		(((CB)/16)<<4)
 #define	  SOLO_VO_NA_COLOR_CR(CR)		(((CR)/16)<<0)
@@ -270,32 +272,32 @@
 #define	  SOLO_VO_V_STOP(n)			((n)<<0)
 
 #define	SOLO_VO_RANGE_HV			0x030C
-#define	  SOLO_VO_SYNC_INVERT			(1<<24)
-#define	  SOLO_VO_HSYNC_INVERT			(1<<23)
-#define	  SOLO_VO_VSYNC_INVERT			(1<<22)
+#define	  SOLO_VO_SYNC_INVERT			BIT(24)
+#define	  SOLO_VO_HSYNC_INVERT			BIT(23)
+#define	  SOLO_VO_VSYNC_INVERT			BIT(22)
 #define	  SOLO_VO_H_LEN(n)			((n)<<11)
 #define	  SOLO_VO_V_LEN(n)			((n)<<0)
 
 #define	SOLO_VO_DISP_CTRL			0x0310
-#define	  SOLO_VO_DISP_ON			(1<<31)
+#define	  SOLO_VO_DISP_ON			BIT(31)
 #define	  SOLO_VO_DISP_ERASE_COUNT(n)		((n&0xf)<<24)
-#define	  SOLO_VO_DISP_DOUBLE_SCAN		(1<<22)
-#define	  SOLO_VO_DISP_SINGLE_PAGE		(1<<21)
+#define	  SOLO_VO_DISP_DOUBLE_SCAN		BIT(22)
+#define	  SOLO_VO_DISP_SINGLE_PAGE		BIT(21)
 #define	  SOLO_VO_DISP_BASE(n)			(((n)>>16) & 0xffff)
 
 #define SOLO_VO_DISP_ERASE			0x0314
-#define	  SOLO_VO_DISP_ERASE_ON			(1<<0)
+#define	  SOLO_VO_DISP_ERASE_ON			BIT(0)
 
 #define	SOLO_VO_ZOOM_CTRL			0x0318
-#define	  SOLO_VO_ZOOM_VER_ON			(1<<24)
-#define	  SOLO_VO_ZOOM_HOR_ON			(1<<23)
-#define	  SOLO_VO_ZOOM_V_COMP			(1<<22)
+#define	  SOLO_VO_ZOOM_VER_ON			BIT(24)
+#define	  SOLO_VO_ZOOM_HOR_ON			BIT(23)
+#define	  SOLO_VO_ZOOM_V_COMP			BIT(22)
 #define	  SOLO_VO_ZOOM_SX(h)			(((h)/2)<<11)
 #define	  SOLO_VO_ZOOM_SY(v)			(((v)/2)<<0)
 
 #define SOLO_VO_FREEZE_CTRL			0x031C
-#define	  SOLO_VO_FREEZE_ON			(1<<1)
-#define	  SOLO_VO_FREEZE_INTERPOLATION		(1<<0)
+#define	  SOLO_VO_FREEZE_ON			BIT(1)
+#define	  SOLO_VO_FREEZE_INTERPOLATION		BIT(0)
 
 #define	SOLO_VO_BKG_COLOR			0x0320
 #define	  SOLO_BG_Y(y)				((y)<<16)
@@ -334,8 +336,8 @@
 #define SOLO_VO_EXPANSION(id)			(0x0250+((id)*4))
 
 #define	SOLO_OSG_CONFIG				0x03E0
-#define	  SOLO_VO_OSG_ON			(1<<31)
-#define	  SOLO_VO_OSG_COLOR_MUTE		(1<<28)
+#define	  SOLO_VO_OSG_ON			BIT(31)
+#define	  SOLO_VO_OSG_COLOR_MUTE		BIT(28)
 #define	  SOLO_VO_OSG_ALPHA_RATE(n)		((n)<<22)
 #define	  SOLO_VO_OSG_ALPHA_BG_RATE(n)		((n)<<16)
 #define	  SOLO_VO_OSG_BASE(offset)		(((offset)>>16)&0xffff)
@@ -345,8 +347,8 @@
 #define	  SOLO_OSG_ERASE_OFF			(0x00)
 
 #define SOLO_VO_OSG_BLINK			0x03E8
-#define	  SOLO_VO_OSG_BLINK_ON			(1<<1)
-#define	  SOLO_VO_OSG_BLINK_INTREVAL18		(1<<0)
+#define	  SOLO_VO_OSG_BLINK_ON			BIT(1)
+#define	  SOLO_VO_OSG_BLINK_INTREVAL18		BIT(0)
 
 #define SOLO_CAP_BASE				0x0400
 #define	  SOLO_CAP_MAX_PAGE(n)			((n)<<16)
@@ -374,19 +376,19 @@
 
 
 #define SOLO_VE_CFG0				0x0610
-#define	  SOLO_VE_TWO_PAGE_MODE			(1<<31)
+#define	  SOLO_VE_TWO_PAGE_MODE			BIT(31)
 #define	  SOLO_VE_INTR_CTRL(n)			((n)<<24)
 #define	  SOLO_VE_BLOCK_SIZE(n)			((n)<<16)
 #define	  SOLO_VE_BLOCK_BASE(n)			((n)<<0)
 
 #define SOLO_VE_CFG1				0x0614
 #define	  SOLO_VE_BYTE_ALIGN(n)			((n)<<24)
-#define	  SOLO_VE_INSERT_INDEX			(1<<18)
+#define	  SOLO_VE_INSERT_INDEX			BIT(18)
 #define	  SOLO_VE_MOTION_MODE(n)		((n)<<16)
 #define	  SOLO_VE_MOTION_BASE(n)		((n)<<0)
 #define   SOLO_VE_MPEG_SIZE_H(n)		((n)<<28) /* 6110 Only */
 #define   SOLO_VE_JPEG_SIZE_H(n)		((n)<<20) /* 6110 Only */
-#define   SOLO_VE_INSERT_INDEX_JPEG		(1<<19)   /* 6110 Only */
+#define   SOLO_VE_INSERT_INDEX_JPEG		BIT(19)   /* 6110 Only */
 
 #define SOLO_VE_WMRK_POLY			0x061C
 #define SOLO_VE_VMRK_INIT_KEY			0x0620
@@ -394,8 +396,8 @@
 #define SOLO_VE_ENCRYP_POLY			0x0628
 #define SOLO_VE_ENCRYP_INIT			0x062C
 #define SOLO_VE_ATTR				0x0630
-#define	  SOLO_VE_LITTLE_ENDIAN			(1<<31)
-#define	  SOLO_COMP_ATTR_RN			(1<<30)
+#define	  SOLO_VE_LITTLE_ENDIAN			BIT(31)
+#define	  SOLO_COMP_ATTR_RN			BIT(30)
 #define	  SOLO_COMP_ATTR_FCODE(n)		((n)<<27)
 #define	  SOLO_COMP_TIME_INC(n)			((n)<<25)
 #define	  SOLO_COMP_TIME_WIDTH(n)		((n)<<21)
@@ -416,9 +418,9 @@
 #define SOLO_VE_OSD_BASE			0x0694
 #define SOLO_VE_OSD_CLR				0x0698
 #define SOLO_VE_OSD_OPT				0x069C
-#define   SOLO_VE_OSD_V_DOUBLE			(1<<16) /* 6110 Only */
-#define   SOLO_VE_OSD_H_SHADOW			(1<<15)
-#define   SOLO_VE_OSD_V_SHADOW			(1<<14)
+#define   SOLO_VE_OSD_V_DOUBLE			BIT(16) /* 6110 Only */
+#define   SOLO_VE_OSD_H_SHADOW			BIT(15)
+#define   SOLO_VE_OSD_V_SHADOW			BIT(14)
 #define   SOLO_VE_OSD_H_OFFSET(n)		((n & 0x7f)<<7)
 #define   SOLO_VE_OSD_V_OFFSET(n)		(n & 0x7f)
 
@@ -435,18 +437,18 @@
 #define SOLO_VE_JPEG_QUE(n)			(0x0A04+((n)*8))
 
 #define SOLO_VD_CFG0				0x0900
-#define	  SOLO_VD_CFG_NO_WRITE_NO_WINDOW	(1<<24)
-#define	  SOLO_VD_CFG_BUSY_WIAT_CODE		(1<<23)
-#define	  SOLO_VD_CFG_BUSY_WIAT_REF		(1<<22)
-#define	  SOLO_VD_CFG_BUSY_WIAT_RES		(1<<21)
-#define	  SOLO_VD_CFG_BUSY_WIAT_MS		(1<<20)
-#define	  SOLO_VD_CFG_SINGLE_MODE		(1<<18)
-#define	  SOLO_VD_CFG_SCAL_MANUAL		(1<<17)
-#define	  SOLO_VD_CFG_USER_PAGE_CTRL		(1<<16)
-#define	  SOLO_VD_CFG_LITTLE_ENDIAN		(1<<15)
-#define	  SOLO_VD_CFG_START_FI			(1<<14)
-#define	  SOLO_VD_CFG_ERR_LOCK			(1<<13)
-#define	  SOLO_VD_CFG_ERR_INT_ENA		(1<<12)
+#define	  SOLO_VD_CFG_NO_WRITE_NO_WINDOW	BIT(24)
+#define	  SOLO_VD_CFG_BUSY_WIAT_CODE		BIT(23)
+#define	  SOLO_VD_CFG_BUSY_WIAT_REF		BIT(22)
+#define	  SOLO_VD_CFG_BUSY_WIAT_RES		BIT(21)
+#define	  SOLO_VD_CFG_BUSY_WIAT_MS		BIT(20)
+#define	  SOLO_VD_CFG_SINGLE_MODE		BIT(18)
+#define	  SOLO_VD_CFG_SCAL_MANUAL		BIT(17)
+#define	  SOLO_VD_CFG_USER_PAGE_CTRL		BIT(16)
+#define	  SOLO_VD_CFG_LITTLE_ENDIAN		BIT(15)
+#define	  SOLO_VD_CFG_START_FI			BIT(14)
+#define	  SOLO_VD_CFG_ERR_LOCK			BIT(13)
+#define	  SOLO_VD_CFG_ERR_INT_ENA		BIT(12)
 #define	  SOLO_VD_CFG_TIME_WIDTH(n)		((n)<<8)
 #define	  SOLO_VD_CFG_DCT_INTERVAL(n)		((n)<<0)
 
@@ -459,37 +461,37 @@
 #define SOLO_VD_CODE_ADR			0x090C
 
 #define SOLO_VD_CTRL				0x0910
-#define	  SOLO_VD_OPER_ON			(1<<31)
+#define	  SOLO_VD_OPER_ON			BIT(31)
 #define	  SOLO_VD_MAX_ITEM(n)			((n)<<0)
 
 #define SOLO_VD_STATUS0				0x0920
-#define	  SOLO_VD_STATUS0_INTR_ACK		(1<<22)
-#define	  SOLO_VD_STATUS0_INTR_EMPTY		(1<<21)
-#define	  SOLO_VD_STATUS0_INTR_ERR		(1<<20)
+#define	  SOLO_VD_STATUS0_INTR_ACK		BIT(22)
+#define	  SOLO_VD_STATUS0_INTR_EMPTY		BIT(21)
+#define	  SOLO_VD_STATUS0_INTR_ERR		BIT(20)
 
 #define SOLO_VD_STATUS1				0x0924
 
 #define SOLO_VD_IDX0				0x0930
-#define	  SOLO_VD_IDX_INTERLACE			(1<<30)
+#define	  SOLO_VD_IDX_INTERLACE			BIT(30)
 #define	  SOLO_VD_IDX_CHANNEL(n)		((n)<<24)
 #define	  SOLO_VD_IDX_SIZE(n)			((n)<<0)
 
 #define SOLO_VD_IDX1				0x0934
 #define	  SOLO_VD_IDX_SRC_SCALE(n)		((n)<<28)
 #define	  SOLO_VD_IDX_WINDOW(n)			((n)<<24)
-#define	  SOLO_VD_IDX_DEINTERLACE		(1<<16)
+#define	  SOLO_VD_IDX_DEINTERLACE		BIT(16)
 #define	  SOLO_VD_IDX_H_BLOCK(n)		((n)<<8)
 #define	  SOLO_VD_IDX_V_BLOCK(n)		((n)<<0)
 
 #define SOLO_VD_IDX2				0x0938
-#define	  SOLO_VD_IDX_REF_BASE_SIDE		(1<<31)
+#define	  SOLO_VD_IDX_REF_BASE_SIDE		BIT(31)
 #define	  SOLO_VD_IDX_REF_BASE(n)		(((n)>>16)&0xffff)
 
 #define SOLO_VD_IDX3				0x093C
 #define	  SOLO_VD_IDX_DISP_SCALE(n)		((n)<<28)
-#define	  SOLO_VD_IDX_INTERLACE_WR		(1<<27)
-#define	  SOLO_VD_IDX_INTERPOL			(1<<26)
-#define	  SOLO_VD_IDX_HOR2X			(1<<25)
+#define	  SOLO_VD_IDX_INTERLACE_WR		BIT(27)
+#define	  SOLO_VD_IDX_INTERPOL			BIT(26)
+#define	  SOLO_VD_IDX_HOR2X			BIT(25)
 #define	  SOLO_VD_IDX_OFFSET_X(n)		((n)<<12)
 #define	  SOLO_VD_IDX_OFFSET_Y(n)		((n)<<0)
 
@@ -511,21 +513,21 @@
 
 
 #define SOLO_IIC_CFG				0x0B20
-#define	  SOLO_IIC_ENABLE			(1<<8)
+#define	  SOLO_IIC_ENABLE			BIT(8)
 #define	  SOLO_IIC_PRESCALE(n)			((n)<<0)
 
 #define SOLO_IIC_CTRL				0x0B24
-#define	  SOLO_IIC_AUTO_CLEAR			(1<<20)
-#define	  SOLO_IIC_STATE_RX_ACK			(1<<19)
-#define	  SOLO_IIC_STATE_BUSY			(1<<18)
-#define	  SOLO_IIC_STATE_SIG_ERR		(1<<17)
-#define	  SOLO_IIC_STATE_TRNS			(1<<16)
+#define	  SOLO_IIC_AUTO_CLEAR			BIT(20)
+#define	  SOLO_IIC_STATE_RX_ACK			BIT(19)
+#define	  SOLO_IIC_STATE_BUSY			BIT(18)
+#define	  SOLO_IIC_STATE_SIG_ERR		BIT(17)
+#define	  SOLO_IIC_STATE_TRNS			BIT(16)
 #define	  SOLO_IIC_CH_SET(n)			((n)<<5)
-#define	  SOLO_IIC_ACK_EN			(1<<4)
-#define	  SOLO_IIC_START			(1<<3)
-#define	  SOLO_IIC_STOP				(1<<2)
-#define	  SOLO_IIC_READ				(1<<1)
-#define	  SOLO_IIC_WRITE			(1<<0)
+#define	  SOLO_IIC_ACK_EN			BIT(4)
+#define	  SOLO_IIC_START			BIT(3)
+#define	  SOLO_IIC_STOP				BIT(2)
+#define	  SOLO_IIC_READ				BIT(1)
+#define	  SOLO_IIC_WRITE			BIT(0)
 
 #define SOLO_IIC_TXD				0x0B28
 #define SOLO_IIC_RXD				0x0B2C
@@ -535,15 +537,15 @@
  */
 #define SOLO_UART_CONTROL(n)			(0x0BA0 + ((n)*0x20))
 #define	  SOLO_UART_CLK_DIV(n)			((n)<<24)
-#define	  SOLO_MODEM_CTRL_EN			(1<<20)
-#define	  SOLO_PARITY_ERROR_DROP		(1<<18)
-#define	  SOLO_IRQ_ERR_EN			(1<<17)
-#define	  SOLO_IRQ_RX_EN			(1<<16)
-#define	  SOLO_IRQ_TX_EN			(1<<15)
-#define	  SOLO_RX_EN				(1<<14)
-#define	  SOLO_TX_EN				(1<<13)
-#define	  SOLO_UART_HALF_DUPLEX			(1<<12)
-#define	  SOLO_UART_LOOPBACK			(1<<11)
+#define	  SOLO_MODEM_CTRL_EN			BIT(20)
+#define	  SOLO_PARITY_ERROR_DROP		BIT(18)
+#define	  SOLO_IRQ_ERR_EN			BIT(17)
+#define	  SOLO_IRQ_RX_EN			BIT(16)
+#define	  SOLO_IRQ_TX_EN			BIT(15)
+#define	  SOLO_RX_EN				BIT(14)
+#define	  SOLO_TX_EN				BIT(13)
+#define	  SOLO_UART_HALF_DUPLEX			BIT(12)
+#define	  SOLO_UART_LOOPBACK			BIT(11)
 
 #define	  SOLO_BAUDRATE_230400			((0<<9)|(0<<6))
 #define	  SOLO_BAUDRATE_115200			((0<<9)|(1<<6))
@@ -569,12 +571,12 @@
 #define	  SOLO_UART_PARITY_ODD			(3<<0)
 
 #define SOLO_UART_STATUS(n)			(0x0BA4 + ((n)*0x20))
-#define	  SOLO_UART_CTS				(1<<15)
-#define	  SOLO_UART_RX_BUSY			(1<<14)
-#define	  SOLO_UART_OVERRUN			(1<<13)
-#define	  SOLO_UART_FRAME_ERR			(1<<12)
-#define	  SOLO_UART_PARITY_ERR			(1<<11)
-#define	  SOLO_UART_TX_BUSY			(1<<5)
+#define	  SOLO_UART_CTS				BIT(15)
+#define	  SOLO_UART_RX_BUSY			BIT(14)
+#define	  SOLO_UART_OVERRUN			BIT(13)
+#define	  SOLO_UART_FRAME_ERR			BIT(12)
+#define	  SOLO_UART_PARITY_ERR			BIT(11)
+#define	  SOLO_UART_TX_BUSY			BIT(5)
 
 #define	  SOLO_UART_RX_BUFF_CNT(stat)		(((stat)>>6) & 0x1f)
 #define	  SOLO_UART_RX_BUFF_SIZE		8
@@ -582,9 +584,9 @@
 #define	  SOLO_UART_TX_BUFF_SIZE		8
 
 #define SOLO_UART_TX_DATA(n)			(0x0BA8 + ((n)*0x20))
-#define	  SOLO_UART_TX_DATA_PUSH		(1<<8)
+#define	  SOLO_UART_TX_DATA_PUSH		BIT(8)
 #define SOLO_UART_RX_DATA(n)			(0x0BAC + ((n)*0x20))
-#define	  SOLO_UART_RX_DATA_POP			(1<<8)
+#define	  SOLO_UART_RX_DATA_POP			BIT(8)
 
 #define SOLO_TIMER_CLOCK_NUM			0x0be0
 #define SOLO_TIMER_USEC				0x0be8
@@ -592,19 +594,19 @@
 #define SOLO_TIMER_USEC_LSB			0x0d20 /* 6110 Only */
 
 #define SOLO_AUDIO_CONTROL			0x0D00
-#define	  SOLO_AUDIO_ENABLE			(1<<31)
-#define	  SOLO_AUDIO_MASTER_MODE		(1<<30)
-#define	  SOLO_AUDIO_I2S_MODE			(1<<29)
-#define	  SOLO_AUDIO_I2S_LR_SWAP		(1<<27)
-#define	  SOLO_AUDIO_I2S_8BIT			(1<<26)
+#define	  SOLO_AUDIO_ENABLE			BIT(31)
+#define	  SOLO_AUDIO_MASTER_MODE		BIT(30)
+#define	  SOLO_AUDIO_I2S_MODE			BIT(29)
+#define	  SOLO_AUDIO_I2S_LR_SWAP		BIT(27)
+#define	  SOLO_AUDIO_I2S_8BIT			BIT(26)
 #define	  SOLO_AUDIO_I2S_MULTI(n)		((n)<<24)
-#define	  SOLO_AUDIO_MIX_9TO0			(1<<23)
+#define	  SOLO_AUDIO_MIX_9TO0			BIT(23)
 #define	  SOLO_AUDIO_DEC_9TO0_VOL(n)		((n)<<20)
-#define	  SOLO_AUDIO_MIX_19TO10			(1<<19)
+#define	  SOLO_AUDIO_MIX_19TO10			BIT(19)
 #define	  SOLO_AUDIO_DEC_19TO10_VOL(n)		((n)<<16)
 #define	  SOLO_AUDIO_MODE(n)			((n)<<0)
 #define SOLO_AUDIO_SAMPLE			0x0D04
-#define	  SOLO_AUDIO_EE_MODE_ON			(1<<30)
+#define	  SOLO_AUDIO_EE_MODE_ON			BIT(30)
 #define	  SOLO_AUDIO_EE_ENC_CH(ch)		((ch)<<25)
 #define	  SOLO_AUDIO_BITRATE(n)			((n)<<16)
 #define	  SOLO_AUDIO_CLK_DIV(n)			((n)<<0)
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
index 609100a..476d7f3 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
@@ -822,25 +822,18 @@
 		switch (dev_type) {
 		case SOLO_DEV_6010:
 			f->pixelformat = V4L2_PIX_FMT_MPEG4;
-			strscpy(f->description, "MPEG-4 part 2",
-				sizeof(f->description));
 			break;
 		case SOLO_DEV_6110:
 			f->pixelformat = V4L2_PIX_FMT_H264;
-			strscpy(f->description, "H.264", sizeof(f->description));
 			break;
 		}
 		break;
 	case 1:
 		f->pixelformat = V4L2_PIX_FMT_MJPEG;
-		strscpy(f->description, "MJPEG", sizeof(f->description));
 		break;
 	default:
 		return -EINVAL;
 	}
-
-	f->flags = V4L2_FMT_FLAG_COMPRESSED;
-
 	return 0;
 }
 
@@ -886,7 +879,6 @@
 	pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
 	pix->sizeimage = FRAME_BUF_SIZE;
 	pix->bytesperline = 0;
-	pix->priv = 0;
 
 	return 0;
 }
@@ -941,7 +933,6 @@
 		     V4L2_FIELD_NONE;
 	pix->sizeimage = FRAME_BUF_SIZE;
 	pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
-	pix->priv = 0;
 
 	return 0;
 }
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2.c b/drivers/media/pci/solo6x10/solo6x10-v4l2.c
index a968f75..7879206 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2.c
@@ -458,8 +458,6 @@
 		return -EINVAL;
 
 	f->pixelformat = V4L2_PIX_FMT_UYVY;
-	strscpy(f->description, "UYUV 4:2:2 Packed", sizeof(f->description));
-
 	return 0;
 }
 
@@ -479,7 +477,6 @@
 	pix->field = V4L2_FIELD_INTERLACED;
 	pix->pixelformat = V4L2_PIX_FMT_UYVY;
 	pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
-	pix->priv = 0;
 	return 0;
 }
 
@@ -509,7 +506,6 @@
 	pix->sizeimage = solo_image_size(solo_dev);
 	pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
 	pix->bytesperline = solo_bytesperline(solo_dev);
-	pix->priv = 0;
 
 	return 0;
 }
diff --git a/drivers/media/pci/sta2x11/sta2x11_vip.c b/drivers/media/pci/sta2x11/sta2x11_vip.c
index e52e298..fd3de3b 100644
--- a/drivers/media/pci/sta2x11/sta2x11_vip.c
+++ b/drivers/media/pci/sta2x11/sta2x11_vip.c
@@ -560,9 +560,7 @@
 	if (f->index != 0)
 		return -EINVAL;
 
-	strscpy(f->description, "4:2:2, packed, UYVY", sizeof(f->description));
 	f->pixelformat = V4L2_PIX_FMT_UYVY;
-	f->flags = 0;
 	return 0;
 }
 
diff --git a/drivers/media/pci/ttpci/av7110_hw.c b/drivers/media/pci/ttpci/av7110_hw.c
index 8c2442a..e8a8ec5 100644
--- a/drivers/media/pci/ttpci/av7110_hw.c
+++ b/drivers/media/pci/ttpci/av7110_hw.c
@@ -14,7 +14,6 @@
 /* for debugging ARM communication: */
 //#define COM_DEBUG
 
-#include <stdarg.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
diff --git a/drivers/media/pci/ttpci/av7110_ir.c b/drivers/media/pci/ttpci/av7110_ir.c
index 432789a..a851ba3 100644
--- a/drivers/media/pci/ttpci/av7110_ir.c
+++ b/drivers/media/pci/ttpci/av7110_ir.c
@@ -37,12 +37,10 @@
 			proto = RC_PROTO_RC5;
 			break;
 
-		case IR_RCMM: /* RCMM: ? bits device address, ? bits command */
-			command = ircom & 0xff;
-			addr = (ircom >> 8) & 0x1f;
-			scancode = ircom;
+		case IR_RCMM: /* RCMM: 32 bits scancode */
+			scancode = ircom & ~0x8000;
 			toggle = ircom & 0x8000;
-			proto = RC_PROTO_UNKNOWN;
+			proto = RC_PROTO_RCMM32;
 			break;
 
 		case IR_RC5_EXT:
@@ -83,9 +81,9 @@
 	struct av7110 *av7110 = rcdev->priv;
 	u32 ir_config;
 
-	if (*rc_type & RC_PROTO_BIT_UNKNOWN) {
+	if (*rc_type & RC_PROTO_BIT_RCMM32) {
 		ir_config = IR_RCMM;
-		*rc_type = RC_PROTO_UNKNOWN;
+		*rc_type = RC_PROTO_BIT_RCMM32;
 	} else if (*rc_type & RC_PROTO_BIT_RC5) {
 		if (FW_VERSION(av7110->arm_app) >= 0x2620)
 			ir_config = IR_RC5_EXT;
@@ -133,7 +131,7 @@
 	}
 
 	rcdev->dev.parent = &pci->dev;
-	rcdev->allowed_protocols = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_UNKNOWN;
+	rcdev->allowed_protocols = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RCMM32;
 	rcdev->change_protocol = change_protocol;
 	rcdev->map_name = RC_MAP_HAUPPAUGE;
 	rcdev->priv = av7110;
diff --git a/drivers/media/pci/tw68/tw68-video.c b/drivers/media/pci/tw68/tw68-video.c
index 8e0952d..2fb82d50 100644
--- a/drivers/media/pci/tw68/tw68-video.c
+++ b/drivers/media/pci/tw68/tw68-video.c
@@ -34,53 +34,43 @@
  */
 static const struct tw68_format formats[] = {
 	{
-		.name		= "15 bpp RGB, le",
 		.fourcc		= V4L2_PIX_FMT_RGB555,
 		.depth		= 16,
 		.twformat	= ColorFormatRGB15,
 	}, {
-		.name		= "15 bpp RGB, be",
 		.fourcc		= V4L2_PIX_FMT_RGB555X,
 		.depth		= 16,
 		.twformat	= ColorFormatRGB15 | ColorFormatBSWAP,
 	}, {
-		.name		= "16 bpp RGB, le",
 		.fourcc		= V4L2_PIX_FMT_RGB565,
 		.depth		= 16,
 		.twformat	= ColorFormatRGB16,
 	}, {
-		.name		= "16 bpp RGB, be",
 		.fourcc		= V4L2_PIX_FMT_RGB565X,
 		.depth		= 16,
 		.twformat	= ColorFormatRGB16 | ColorFormatBSWAP,
 	}, {
-		.name		= "24 bpp RGB, le",
 		.fourcc		= V4L2_PIX_FMT_BGR24,
 		.depth		= 24,
 		.twformat	= ColorFormatRGB24,
 	}, {
-		.name		= "24 bpp RGB, be",
 		.fourcc		= V4L2_PIX_FMT_RGB24,
 		.depth		= 24,
 		.twformat	= ColorFormatRGB24 | ColorFormatBSWAP,
 	}, {
-		.name		= "32 bpp RGB, le",
 		.fourcc		= V4L2_PIX_FMT_BGR32,
 		.depth		= 32,
 		.twformat	= ColorFormatRGB32,
 	}, {
-		.name		= "32 bpp RGB, be",
 		.fourcc		= V4L2_PIX_FMT_RGB32,
 		.depth		= 32,
 		.twformat	= ColorFormatRGB32 | ColorFormatBSWAP |
 				  ColorFormatWSWAP,
 	}, {
-		.name		= "4:2:2 packed, YUYV",
 		.fourcc		= V4L2_PIX_FMT_YUYV,
 		.depth		= 16,
 		.twformat	= ColorFormatYUY2,
 	}, {
-		.name		= "4:2:2 packed, UYVY",
 		.fourcc		= V4L2_PIX_FMT_UYVY,
 		.depth		= 16,
 		.twformat	= ColorFormatYUY2 | ColorFormatBSWAP,
@@ -592,7 +582,6 @@
 	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;
 }
 
@@ -774,9 +763,6 @@
 	if (f->index >= FORMATS)
 		return -EINVAL;
 
-	strscpy(f->description, formats[f->index].name,
-		sizeof(f->description));
-
 	f->pixelformat = formats[f->index].fourcc;
 
 	return 0;
diff --git a/drivers/media/pci/tw68/tw68.h b/drivers/media/pci/tw68/tw68.h
index 7021290..a1f422d 100644
--- a/drivers/media/pci/tw68/tw68.h
+++ b/drivers/media/pci/tw68/tw68.h
@@ -85,7 +85,6 @@
 };
 
 struct tw68_format {
-	char	*name;
 	u32	fourcc;
 	u32	depth;
 	u32	twformat;
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 8a19654..83a7850 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -16,7 +16,7 @@
 config VIDEO_VIA_CAMERA
 	tristate "VIAFB camera controller support"
 	depends on FB_VIA
-	select VIDEOBUF_DMA_SG
+	select VIDEOBUF2_DMA_SG
 	select VIDEO_OV7670
 	help
 	   Driver support for the integrated camera controller in VIA
@@ -121,7 +121,7 @@
 
 config VIDEO_STM32_DCMI
 	tristate "STM32 Digital Camera Memory Interface (DCMI) support"
-	depends on VIDEO_V4L2 && OF
+	depends on VIDEO_V4L2 && OF && MEDIA_CONTROLLER
 	depends on ARCH_STM32 || COMPILE_TEST
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_FWNODE
@@ -146,7 +146,7 @@
 source "drivers/media/platform/xilinx/Kconfig"
 source "drivers/media/platform/rcar-vin/Kconfig"
 source "drivers/media/platform/atmel/Kconfig"
-source "drivers/media/platform/sunxi/sun6i-csi/Kconfig"
+source "drivers/media/platform/sunxi/Kconfig"
 
 config VIDEO_TI_CAL
 	tristate "TI CAL (Camera Adaptation Layer) driver"
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 7cbbd92..6ee7eb0d 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -100,4 +100,4 @@
 
 obj-y					+= cros-ec-cec/
 
-obj-$(CONFIG_VIDEO_SUN6I_CSI)		+= sunxi/sun6i-csi/
+obj-y					+= sunxi/
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
index fe7b937..2b42ba1 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -76,7 +76,6 @@
 
 /*
  * struct vpfe_fmt - VPFE media bus format information
- * @name: V4L2 format description
  * @code: V4L2 media bus format code
  * @shifted: V4L2 media bus format code for the same pixel layout but
  *	shifted to be 8 bits per pixel. =0 if format is not shiftable.
@@ -86,7 +85,6 @@
  * @supported: Indicates format supported by subdev
  */
 struct vpfe_fmt {
-	const char *name;
 	u32 fourcc;
 	u32 code;
 	struct bus_format l;
@@ -97,7 +95,6 @@
 
 static struct vpfe_fmt formats[] = {
 	{
-		.name		= "YUV 4:2:2 packed, YCbYCr",
 		.fourcc		= V4L2_PIX_FMT_YUYV,
 		.code		= MEDIA_BUS_FMT_YUYV8_2X8,
 		.l.width	= 10,
@@ -106,7 +103,6 @@
 		.s.bpp		= 2,
 		.supported	= false,
 	}, {
-		.name		= "YUV 4:2:2 packed, CbYCrY",
 		.fourcc		= V4L2_PIX_FMT_UYVY,
 		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
 		.l.width	= 10,
@@ -115,7 +111,6 @@
 		.s.bpp		= 2,
 		.supported	= false,
 	}, {
-		.name		= "YUV 4:2:2 packed, YCrYCb",
 		.fourcc		= V4L2_PIX_FMT_YVYU,
 		.code		= MEDIA_BUS_FMT_YVYU8_2X8,
 		.l.width	= 10,
@@ -124,7 +119,6 @@
 		.s.bpp		= 2,
 		.supported	= false,
 	}, {
-		.name		= "YUV 4:2:2 packed, CrYCbY",
 		.fourcc		= V4L2_PIX_FMT_VYUY,
 		.code		= MEDIA_BUS_FMT_VYUY8_2X8,
 		.l.width	= 10,
@@ -133,7 +127,6 @@
 		.s.bpp		= 2,
 		.supported	= false,
 	}, {
-		.name		= "RAW8 BGGR",
 		.fourcc		= V4L2_PIX_FMT_SBGGR8,
 		.code		= MEDIA_BUS_FMT_SBGGR8_1X8,
 		.l.width	= 10,
@@ -142,7 +135,6 @@
 		.s.bpp		= 1,
 		.supported	= false,
 	}, {
-		.name		= "RAW8 GBRG",
 		.fourcc		= V4L2_PIX_FMT_SGBRG8,
 		.code		= MEDIA_BUS_FMT_SGBRG8_1X8,
 		.l.width	= 10,
@@ -151,7 +143,6 @@
 		.s.bpp		= 1,
 		.supported	= false,
 	}, {
-		.name		= "RAW8 GRBG",
 		.fourcc		= V4L2_PIX_FMT_SGRBG8,
 		.code		= MEDIA_BUS_FMT_SGRBG8_1X8,
 		.l.width	= 10,
@@ -160,7 +151,6 @@
 		.s.bpp		= 1,
 		.supported	= false,
 	}, {
-		.name		= "RAW8 RGGB",
 		.fourcc		= V4L2_PIX_FMT_SRGGB8,
 		.code		= MEDIA_BUS_FMT_SRGGB8_1X8,
 		.l.width	= 10,
@@ -169,7 +159,6 @@
 		.s.bpp		= 1,
 		.supported	= false,
 	}, {
-		.name		= "RGB565 (LE)",
 		.fourcc		= V4L2_PIX_FMT_RGB565,
 		.code		= MEDIA_BUS_FMT_RGB565_2X8_LE,
 		.l.width	= 10,
@@ -178,7 +167,6 @@
 		.s.bpp		= 2,
 		.supported	= false,
 	}, {
-		.name		= "RGB565 (BE)",
 		.fourcc		= V4L2_PIX_FMT_RGB565X,
 		.code		= MEDIA_BUS_FMT_RGB565_2X8_BE,
 		.l.width	= 10,
@@ -1412,10 +1400,6 @@
 	strscpy(cap->card, "TI AM437x VPFE", sizeof(cap->card));
 	snprintf(cap->bus_info, sizeof(cap->bus_info),
 			"platform:%s", vpfe->v4l2_dev.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;
 }
 
@@ -1540,12 +1524,10 @@
 	if (!fmt)
 		return -EINVAL;
 
-	strscpy(f->description, fmt->name, sizeof(f->description));
 	f->pixelformat = fmt->fourcc;
-	f->type = vpfe->fmt.type;
 
-	vpfe_dbg(1, vpfe, "vpfe_enum_format: mbus index: %d code: %x pixelformat: %s [%s]\n",
-		f->index, fmt->code, print_fourcc(fmt->fourcc), fmt->name);
+	vpfe_dbg(1, vpfe, "vpfe_enum_format: mbus index: %d code: %x pixelformat: %s\n",
+		 f->index, fmt->code, print_fourcc(fmt->fourcc));
 
 	return 0;
 }
@@ -2393,6 +2375,8 @@
 	vdev->vfl_dir = VFL_DIR_RX;
 	vdev->queue = q;
 	vdev->lock = &vpfe->lock;
+	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+			    V4L2_CAP_READWRITE;
 	video_set_drvdata(vdev, vpfe);
 	err = video_register_device(&vpfe->video_dev, VFL_TYPE_GRABBER, -1);
 	if (err) {
@@ -2505,10 +2489,9 @@
 		pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev(
 			&vpfe->notifier, of_fwnode_handle(rem),
 			sizeof(struct v4l2_async_subdev));
-		if (IS_ERR(pdata->asd[i])) {
-			of_node_put(rem);
+		of_node_put(rem);
+		if (IS_ERR(pdata->asd[i]))
 			goto cleanup;
-		}
 	}
 
 	of_node_put(endpoint);
@@ -2557,7 +2540,6 @@
 
 	ret = platform_get_irq(pdev, 0);
 	if (ret <= 0) {
-		dev_err(&pdev->dev, "No IRQ resource\n");
 		ret = -ENODEV;
 		goto probe_out_cleanup;
 	}
diff --git a/drivers/media/platform/am437x/am437x-vpfe.h b/drivers/media/platform/am437x/am437x-vpfe.h
index 17d7aa4..4678285 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.h
+++ b/drivers/media/platform/am437x/am437x-vpfe.h
@@ -65,12 +65,6 @@
 #define VPFE_MAX_SUBDEV		1
 #define VPFE_MAX_INPUTS		1
 
-struct vpfe_pixel_format {
-	struct v4l2_fmtdesc fmtdesc;
-	/* bytes per pixel */
-	int bpp;
-};
-
 struct vpfe_std_info {
 	int active_pixels;
 	int active_lines;
diff --git a/drivers/media/platform/am437x/am437x-vpfe_regs.h b/drivers/media/platform/am437x/am437x-vpfe_regs.h
index 4a0ed29..0746c48 100644
--- a/drivers/media/platform/am437x/am437x-vpfe_regs.h
+++ b/drivers/media/platform/am437x/am437x-vpfe_regs.h
@@ -66,13 +66,13 @@
 #define VPFE_PIX_FMT_MASK			3
 #define VPFE_PIX_FMT_SHIFT			12
 #define VPFE_VP2SDR_DISABLE			0xfffbffff
-#define VPFE_WEN_ENABLE				(1 << 17)
+#define VPFE_WEN_ENABLE				BIT(17)
 #define VPFE_SDR2RSZ_DISABLE			0xfff7ffff
-#define VPFE_VDHDEN_ENABLE			(1 << 16)
-#define VPFE_LPF_ENABLE				(1 << 14)
-#define VPFE_ALAW_ENABLE			(1 << 3)
+#define VPFE_VDHDEN_ENABLE			BIT(16)
+#define VPFE_LPF_ENABLE				BIT(14)
+#define VPFE_ALAW_ENABLE			BIT(3)
 #define VPFE_ALAW_GAMMA_WD_MASK			7
-#define VPFE_BLK_CLAMP_ENABLE			(1 << 31)
+#define VPFE_BLK_CLAMP_ENABLE			BIT(31)
 #define VPFE_BLK_SGAIN_MASK			0x1f
 #define VPFE_BLK_ST_PXL_MASK			0x7fff
 #define VPFE_BLK_ST_PXL_SHIFT			10
@@ -85,8 +85,8 @@
 #define VPFE_BLK_COMP_GB_COMP_SHIFT		8
 #define VPFE_BLK_COMP_GR_COMP_SHIFT		16
 #define VPFE_BLK_COMP_R_COMP_SHIFT		24
-#define VPFE_LATCH_ON_VSYNC_DISABLE		(1 << 15)
-#define VPFE_DATA_PACK_ENABLE			(1 << 11)
+#define VPFE_LATCH_ON_VSYNC_DISABLE		BIT(15)
+#define VPFE_DATA_PACK_ENABLE			BIT(11)
 #define VPFE_HORZ_INFO_SPH_SHIFT		16
 #define VPFE_VERT_START_SLV0_SHIFT		16
 #define VPFE_VDINT_VDINT0_SHIFT			16
@@ -114,15 +114,15 @@
 #define VPFE_SYN_FLDMODE_MASK			1
 #define VPFE_SYN_FLDMODE_SHIFT			7
 #define VPFE_REC656IF_BT656_EN			3
-#define VPFE_SYN_MODE_VD_POL_NEGATIVE		(1 << 2)
+#define VPFE_SYN_MODE_VD_POL_NEGATIVE		BIT(2)
 #define VPFE_CCDCFG_Y8POS_SHIFT			11
-#define VPFE_CCDCFG_BW656_10BIT			(1 << 5)
+#define VPFE_CCDCFG_BW656_10BIT			BIT(5)
 #define VPFE_SDOFST_FIELD_INTERLEAVED		0x249
 #define VPFE_NO_CULLING				0xffff00ff
-#define VPFE_VDINT0				(1 << 0)
-#define VPFE_VDINT1				(1 << 1)
-#define VPFE_VDINT2				(1 << 2)
-#define VPFE_DMA_CNTL_OVERFLOW			(1 << 31)
+#define VPFE_VDINT0				BIT(0)
+#define VPFE_VDINT1				BIT(1)
+#define VPFE_VDINT2				BIT(2)
+#define VPFE_DMA_CNTL_OVERFLOW			BIT(31)
 
 #define VPFE_CONFIG_PCLK_INV_SHIFT		0
 #define VPFE_CONFIG_PCLK_INV_MASK		1
diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index f899ac3..eb12f37 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -630,7 +630,7 @@
 	}
 
 	if (hsync_counter < 0 || vsync_counter < 0) {
-		u32 ctrl;
+		u32 ctrl = 0;
 
 		if (hsync_counter < 0) {
 			ctrl = VE_CTRL_HSYNC_POL;
@@ -650,7 +650,8 @@
 				V4L2_DV_VSYNC_POS_POL;
 		}
 
-		aspeed_video_update(video, VE_CTRL, 0, ctrl);
+		if (ctrl)
+			aspeed_video_update(video, VE_CTRL, 0, ctrl);
 	}
 }
 
@@ -1624,6 +1625,7 @@
 	if (!aspeed_video_alloc_buf(video, &video->jpeg,
 				    VE_JPEG_HEADER_SIZE)) {
 		dev_err(dev, "Failed to allocate DMA for JPEG header\n");
+		rc = -ENOMEM;
 		goto err_release_reserved_mem;
 	}
 
diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index d7d94c1..428f117 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -493,7 +493,7 @@
 	spin_unlock_irq(&isi->irqlock);
 
 	if (!isi->enable_preview_path) {
-		timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
+		timeout = jiffies + (FRAME_INTERVAL_MILLI_SEC * HZ) / 1000;
 		/* Wait until the end of the current frame. */
 		while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
 				time_before(jiffies, timeout))
diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
index 266df14..7838165 100644
--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
+++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
@@ -160,11 +160,8 @@
 	}
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		ret = irq;
-		dev_err(dev, "failed to get irq: %d\n", ret);
-		return ret;
-	}
+	if (irq < 0)
+		return irq;
 
 	ret = devm_request_irq(dev, irq, isc_interrupt, 0,
 			       ATMEL_ISC_NAME, isc);
diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c b/drivers/media/platform/cadence/cdns-csi2tx.c
index 5042d05..e4d08ac 100644
--- a/drivers/media/platform/cadence/cdns-csi2tx.c
+++ b/drivers/media/platform/cadence/cdns-csi2tx.c
@@ -2,7 +2,7 @@
 /*
  * Driver for Cadence MIPI-CSI2 TX Controller
  *
- * Copyright (C) 2017-2018 Cadence Design Systems Inc.
+ * Copyright (C) 2017-2019 Cadence Design Systems Inc.
  */
 
 #include <linux/clk.h>
@@ -52,6 +52,17 @@
 #define CSI2TX_STREAM_IF_CFG_REG(n)	(0x100 + (n) * 4)
 #define CSI2TX_STREAM_IF_CFG_FILL_LEVEL(n)	((n) & 0x1f)
 
+/* CSI2TX V2 Registers */
+#define CSI2TX_V2_DPHY_CFG_REG			0x28
+#define CSI2TX_V2_DPHY_CFG_RESET		BIT(16)
+#define CSI2TX_V2_DPHY_CFG_CLOCK_MODE		BIT(10)
+#define CSI2TX_V2_DPHY_CFG_MODE_MASK		GENMASK(9, 8)
+#define CSI2TX_V2_DPHY_CFG_MODE_LPDT		(2 << 8)
+#define CSI2TX_V2_DPHY_CFG_MODE_HS		(1 << 8)
+#define CSI2TX_V2_DPHY_CFG_MODE_ULPS		(0 << 8)
+#define CSI2TX_V2_DPHY_CFG_CLK_ENABLE		BIT(4)
+#define CSI2TX_V2_DPHY_CFG_LANE_ENABLE(n)	BIT(n)
+
 #define CSI2TX_LANES_MAX	4
 #define CSI2TX_STREAMS_MAX	4
 
@@ -70,6 +81,13 @@
 	u32	bpp;
 };
 
+struct csi2tx_priv;
+
+/* CSI2TX Variant Operations */
+struct csi2tx_vops {
+	void (*dphy_setup)(struct csi2tx_priv *csi2tx);
+};
+
 struct csi2tx_priv {
 	struct device			*dev;
 	unsigned int			count;
@@ -82,6 +100,8 @@
 
 	void __iomem			*base;
 
+	struct csi2tx_vops		*vops;
+
 	struct clk			*esc_clk;
 	struct clk			*p_clk;
 	struct clk			*pixel_clk[CSI2TX_STREAMS_MAX];
@@ -209,6 +229,68 @@
 	.set_fmt	= csi2tx_set_pad_format,
 };
 
+/* Set Wake Up value in the D-PHY */
+static void csi2tx_dphy_set_wakeup(struct csi2tx_priv *csi2tx)
+{
+	writel(CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(32),
+	       csi2tx->base + CSI2TX_DPHY_CLK_WAKEUP_REG);
+}
+
+/*
+ * Finishes the D-PHY initialization
+ * reg dphy cfg value to be used
+ */
+static void csi2tx_dphy_init_finish(struct csi2tx_priv *csi2tx, u32 reg)
+{
+	unsigned int i;
+
+	udelay(10);
+
+	/* Enable our (clock and data) lanes */
+	reg |= CSI2TX_DPHY_CFG_CLK_ENABLE;
+	for (i = 0; i < csi2tx->num_lanes; i++)
+		reg |= CSI2TX_DPHY_CFG_LANE_ENABLE(csi2tx->lanes[i] - 1);
+	writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG);
+
+	udelay(10);
+
+	/* Switch to HS mode */
+	reg &= ~CSI2TX_DPHY_CFG_MODE_MASK;
+	writel(reg | CSI2TX_DPHY_CFG_MODE_HS,
+	       csi2tx->base + CSI2TX_DPHY_CFG_REG);
+}
+
+/* Configures D-PHY in CSIv1.3 */
+static void csi2tx_dphy_setup(struct csi2tx_priv *csi2tx)
+{
+	u32 reg;
+	unsigned int i;
+
+	csi2tx_dphy_set_wakeup(csi2tx);
+
+	/* Put our lanes (clock and data) out of reset */
+	reg = CSI2TX_DPHY_CFG_CLK_RESET | CSI2TX_DPHY_CFG_MODE_LPDT;
+	for (i = 0; i < csi2tx->num_lanes; i++)
+		reg |= CSI2TX_DPHY_CFG_LANE_RESET(csi2tx->lanes[i] - 1);
+	writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG);
+
+	csi2tx_dphy_init_finish(csi2tx, reg);
+}
+
+/* Configures D-PHY in CSIv2 */
+static void csi2tx_v2_dphy_setup(struct csi2tx_priv *csi2tx)
+{
+	u32 reg;
+
+	csi2tx_dphy_set_wakeup(csi2tx);
+
+	/* Put our lanes (clock and data) out of reset */
+	reg = CSI2TX_V2_DPHY_CFG_RESET | CSI2TX_V2_DPHY_CFG_MODE_LPDT;
+	writel(reg, csi2tx->base + CSI2TX_V2_DPHY_CFG_REG);
+
+	csi2tx_dphy_init_finish(csi2tx, reg);
+}
+
 static void csi2tx_reset(struct csi2tx_priv *csi2tx)
 {
 	writel(CSI2TX_CONFIG_SRST_REQ, csi2tx->base + CSI2TX_CONFIG_REG);
@@ -221,7 +303,6 @@
 	struct media_entity *entity = &csi2tx->subdev.entity;
 	struct media_link *link;
 	unsigned int i;
-	u32 reg;
 
 	csi2tx_reset(csi2tx);
 
@@ -229,32 +310,10 @@
 
 	udelay(10);
 
-	/* Configure our PPI interface with the D-PHY */
-	writel(CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(32),
-	       csi2tx->base + CSI2TX_DPHY_CLK_WAKEUP_REG);
-
-	/* Put our lanes (clock and data) out of reset */
-	reg = CSI2TX_DPHY_CFG_CLK_RESET | CSI2TX_DPHY_CFG_MODE_LPDT;
-	for (i = 0; i < csi2tx->num_lanes; i++)
-		reg |= CSI2TX_DPHY_CFG_LANE_RESET(csi2tx->lanes[i]);
-	writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG);
-
-	udelay(10);
-
-	/* Enable our (clock and data) lanes */
-	reg |= CSI2TX_DPHY_CFG_CLK_ENABLE;
-	for (i = 0; i < csi2tx->num_lanes; i++)
-		reg |= CSI2TX_DPHY_CFG_LANE_ENABLE(csi2tx->lanes[i]);
-	writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG);
-
-	udelay(10);
-
-	/* Switch to HS mode */
-	reg &= ~CSI2TX_DPHY_CFG_MODE_MASK;
-	writel(reg | CSI2TX_DPHY_CFG_MODE_HS,
-	       csi2tx->base + CSI2TX_DPHY_CFG_REG);
-
-	udelay(10);
+	if (csi2tx->vops && csi2tx->vops->dphy_setup) {
+		csi2tx->vops->dphy_setup(csi2tx);
+		udelay(10);
+	}
 
 	/*
 	 * Create a static mapping between the CSI virtual channels
@@ -434,7 +493,7 @@
 {
 	struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
 	struct device_node *ep;
-	int ret;
+	int ret, i;
 
 	ep = of_graph_get_endpoint_by_regs(csi2tx->dev->of_node, 0, 0);
 	if (!ep)
@@ -461,6 +520,15 @@
 		goto out;
 	}
 
+	for (i = 0; i < csi2tx->num_lanes; i++) {
+		if (v4l2_ep.bus.mipi_csi2.data_lanes[i] < 1) {
+			dev_err(csi2tx->dev, "Invalid lane[%d] number: %u\n",
+				i, v4l2_ep.bus.mipi_csi2.data_lanes[i]);
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
 	memcpy(csi2tx->lanes, v4l2_ep.bus.mipi_csi2.data_lanes,
 	       sizeof(csi2tx->lanes));
 
@@ -469,9 +537,35 @@
 	return ret;
 }
 
+static const struct csi2tx_vops csi2tx_vops = {
+	.dphy_setup = csi2tx_dphy_setup,
+};
+
+static const struct csi2tx_vops csi2tx_v2_vops = {
+	.dphy_setup = csi2tx_v2_dphy_setup,
+};
+
+static const struct of_device_id csi2tx_of_table[] = {
+	{
+		.compatible = "cdns,csi2tx",
+		.data = &csi2tx_vops
+	},
+	{
+		.compatible = "cdns,csi2tx-1.3",
+		.data = &csi2tx_vops
+	},
+	{
+		.compatible = "cdns,csi2tx-2.1",
+		.data = &csi2tx_v2_vops
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, csi2tx_of_table);
+
 static int csi2tx_probe(struct platform_device *pdev)
 {
 	struct csi2tx_priv *csi2tx;
+	const struct of_device_id *of_id;
 	unsigned int i;
 	int ret;
 
@@ -486,6 +580,9 @@
 	if (ret)
 		goto err_free_priv;
 
+	of_id = of_match_node(csi2tx_of_table, pdev->dev.of_node);
+	csi2tx->vops = (struct csi2tx_vops *)of_id->data;
+
 	v4l2_subdev_init(&csi2tx->subdev, &csi2tx_subdev_ops);
 	csi2tx->subdev.owner = THIS_MODULE;
 	csi2tx->subdev.dev = &pdev->dev;
@@ -543,12 +640,6 @@
 	return 0;
 }
 
-static const struct of_device_id csi2tx_of_table[] = {
-	{ .compatible = "cdns,csi2tx" },
-	{ },
-};
-MODULE_DEVICE_TABLE(of, csi2tx_of_table);
-
 static struct platform_driver csi2tx_driver = {
 	.probe	= csi2tx_probe,
 	.remove	= csi2tx_remove,
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index 01428de..73222c0 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -390,9 +390,6 @@
 	strscpy(cap->card, coda_product_name(ctx->dev->devtype->product),
 		sizeof(cap->card));
 	strscpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info));
-	cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-
 	return 0;
 }
 
@@ -2699,6 +2696,7 @@
 	vfd->lock	= &dev->dev_mutex;
 	vfd->v4l2_dev	= &dev->v4l2_dev;
 	vfd->vfl_dir	= VFL_DIR_M2M;
+	vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
 	video_set_drvdata(vfd, dev);
 
 	/* Not applicable, use the selection API instead */
diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
index 068df98..76ab83f 100644
--- a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
+++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c
@@ -206,10 +206,10 @@
  */
 
 struct cec_dmi_match {
-	char *sys_vendor;
-	char *product_name;
-	char *devname;
-	char *conn;
+	const char *sys_vendor;
+	const char *product_name;
+	const char *devname;
+	const char *conn;
 };
 
 static const struct cec_dmi_match cec_dmi_match_table[] = {
@@ -217,8 +217,8 @@
 	{ "Google", "Fizz", "0000:00:02.0", "Port B" },
 };
 
-static int cros_ec_cec_get_notifier(struct device *dev,
-				    struct cec_notifier **notify)
+static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
+						const char **conn)
 {
 	int i;
 
@@ -233,26 +233,25 @@
 			d = bus_find_device_by_name(&pci_bus_type, NULL,
 						    m->devname);
 			if (!d)
-				return -EPROBE_DEFER;
-
-			*notify = cec_notifier_get_conn(d, m->conn);
+				return ERR_PTR(-EPROBE_DEFER);
 			put_device(d);
-			return 0;
+			*conn = m->conn;
+			return d;
 		}
 	}
 
 	/* Hardware support must be added in the cec_dmi_match_table */
 	dev_warn(dev, "CEC notifier not configured for this hardware\n");
 
-	return -ENODEV;
+	return ERR_PTR(-ENODEV);
 }
 
 #else
 
-static int cros_ec_cec_get_notifier(struct device *dev,
-				    struct cec_notifier **notify)
+static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
+						const char **conn)
 {
-	return -ENODEV;
+	return ERR_PTR(-ENODEV);
 }
 
 #endif
@@ -262,8 +261,14 @@
 	struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent);
 	struct cros_ec_device *cros_ec = ec_dev->ec_dev;
 	struct cros_ec_cec *cros_ec_cec;
+	struct device *hdmi_dev;
+	const char *conn = NULL;
 	int ret;
 
+	hdmi_dev = cros_ec_cec_find_hdmi_dev(&pdev->dev, &conn);
+	if (IS_ERR(hdmi_dev))
+		return PTR_ERR(hdmi_dev);
+
 	cros_ec_cec = devm_kzalloc(&pdev->dev, sizeof(*cros_ec_cec),
 				   GFP_KERNEL);
 	if (!cros_ec_cec)
@@ -272,10 +277,6 @@
 	platform_set_drvdata(pdev, cros_ec_cec);
 	cros_ec_cec->cros_ec = cros_ec;
 
-	ret = cros_ec_cec_get_notifier(&pdev->dev, &cros_ec_cec->notify);
-	if (ret)
-		return ret;
-
 	ret = device_init_wakeup(&pdev->dev, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to initialize wakeup\n");
@@ -283,29 +284,39 @@
 	}
 
 	cros_ec_cec->adap = cec_allocate_adapter(&cros_ec_cec_ops, cros_ec_cec,
-						 DRV_NAME, CEC_CAP_DEFAULTS, 1);
+						 DRV_NAME,
+						 CEC_CAP_DEFAULTS |
+						 CEC_CAP_CONNECTOR_INFO, 1);
 	if (IS_ERR(cros_ec_cec->adap))
 		return PTR_ERR(cros_ec_cec->adap);
 
+	cros_ec_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, conn,
+							     cros_ec_cec->adap);
+	if (!cros_ec_cec->notify) {
+		ret = -ENOMEM;
+		goto out_probe_adapter;
+	}
+
 	/* Get CEC events from the EC. */
 	cros_ec_cec->notifier.notifier_call = cros_ec_cec_event;
 	ret = blocking_notifier_chain_register(&cros_ec->event_notifier,
 					       &cros_ec_cec->notifier);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register notifier\n");
-		cec_delete_adapter(cros_ec_cec->adap);
-		return ret;
+		goto out_probe_notify;
 	}
 
 	ret = cec_register_adapter(cros_ec_cec->adap, &pdev->dev);
-	if (ret < 0) {
-		cec_delete_adapter(cros_ec_cec->adap);
-		return ret;
-	}
-
-	cec_register_cec_notifier(cros_ec_cec->adap, cros_ec_cec->notify);
+	if (ret < 0)
+		goto out_probe_notify;
 
 	return 0;
+
+out_probe_notify:
+	cec_notifier_cec_adap_unregister(cros_ec_cec->notify);
+out_probe_adapter:
+	cec_delete_adapter(cros_ec_cec->adap);
+	return ret;
 }
 
 static int cros_ec_cec_remove(struct platform_device *pdev)
@@ -323,11 +334,9 @@
 		return ret;
 	}
 
+	cec_notifier_cec_adap_unregister(cros_ec_cec->notify);
 	cec_unregister_adapter(cros_ec_cec->adap);
 
-	if (cros_ec_cec->notify)
-		cec_notifier_put(cros_ec_cec->notify);
-
 	return 0;
 }
 
diff --git a/drivers/media/platform/davinci/dm644x_ccdc_regs.h b/drivers/media/platform/davinci/dm644x_ccdc_regs.h
index 3ae3013..c4894f6 100644
--- a/drivers/media/platform/davinci/dm644x_ccdc_regs.h
+++ b/drivers/media/platform/davinci/dm644x_ccdc_regs.h
@@ -66,13 +66,13 @@
 #define CCDC_PIX_FMT_MASK			3
 #define CCDC_PIX_FMT_SHIFT			12
 #define CCDC_VP2SDR_DISABLE			0xFFFBFFFF
-#define CCDC_WEN_ENABLE				(1 << 17)
+#define CCDC_WEN_ENABLE				BIT(17)
 #define CCDC_SDR2RSZ_DISABLE			0xFFF7FFFF
-#define CCDC_VDHDEN_ENABLE			(1 << 16)
-#define CCDC_LPF_ENABLE				(1 << 14)
-#define CCDC_ALAW_ENABLE			(1 << 3)
+#define CCDC_VDHDEN_ENABLE			BIT(16)
+#define CCDC_LPF_ENABLE				BIT(14)
+#define CCDC_ALAW_ENABLE			BIT(3)
 #define CCDC_ALAW_GAMMA_WD_MASK			7
-#define CCDC_BLK_CLAMP_ENABLE			(1 << 31)
+#define CCDC_BLK_CLAMP_ENABLE			BIT(31)
 #define CCDC_BLK_SGAIN_MASK			0x1F
 #define CCDC_BLK_ST_PXL_MASK			0x7FFF
 #define CCDC_BLK_ST_PXL_SHIFT			10
@@ -85,11 +85,11 @@
 #define CCDC_BLK_COMP_GB_COMP_SHIFT		8
 #define CCDC_BLK_COMP_GR_COMP_SHIFT		16
 #define CCDC_BLK_COMP_R_COMP_SHIFT		24
-#define CCDC_LATCH_ON_VSYNC_DISABLE		(1 << 15)
-#define CCDC_FPC_ENABLE				(1 << 15)
+#define CCDC_LATCH_ON_VSYNC_DISABLE		BIT(15)
+#define CCDC_FPC_ENABLE				BIT(15)
 #define CCDC_FPC_DISABLE			0
 #define CCDC_FPC_FPC_NUM_MASK			0x7FFF
-#define CCDC_DATA_PACK_ENABLE			(1 << 11)
+#define CCDC_DATA_PACK_ENABLE			BIT(11)
 #define CCDC_FMTCFG_VPIN_MASK			7
 #define CCDC_FMTCFG_VPIN_SHIFT			12
 #define CCDC_FMT_HORZ_FMTLNH_MASK		0x1FFF
@@ -132,9 +132,9 @@
 #define CCDC_SYN_FLDMODE_MASK			1
 #define CCDC_SYN_FLDMODE_SHIFT			7
 #define CCDC_REC656IF_BT656_EN			3
-#define CCDC_SYN_MODE_VD_POL_NEGATIVE		(1 << 2)
+#define CCDC_SYN_MODE_VD_POL_NEGATIVE		BIT(2)
 #define CCDC_CCDCFG_Y8POS_SHIFT			11
-#define CCDC_CCDCFG_BW656_10BIT			(1 << 5)
+#define CCDC_CCDCFG_BW656_10BIT			BIT(5)
 #define CCDC_SDOFST_FIELD_INTERLEAVED		0x249
 #define CCDC_NO_CULLING				0xffff00ff
 #endif
diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 000b191..ae41995 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -19,10 +19,6 @@
 
 #include <asm/pgtable.h>
 
-#ifdef CONFIG_ARCH_DAVINCI
-#include <mach/cputype.h>
-#endif
-
 #include <media/v4l2-dev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
@@ -633,8 +629,6 @@
 	struct vpbe_layer *layer = video_drvdata(file);
 	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
 
-	cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	snprintf(cap->driver, sizeof(cap->driver), "%s",
 		dev_name(vpbe_dev->pdev));
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
@@ -792,7 +786,6 @@
 {
 	struct vpbe_layer *layer = video_drvdata(file);
 	struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev;
-	unsigned int index = 0;
 
 	v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
 				"VIDIOC_ENUM_FMT, layer id = %d\n",
@@ -803,19 +796,10 @@
 	}
 
 	/* Fill in the information about format */
-	index = fmt->index;
-	memset(fmt, 0, sizeof(*fmt));
-	fmt->index = index;
-	fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	if (index == 0) {
-		strscpy(fmt->description, "YUV 4:2:2 - UYVY",
-			sizeof(fmt->description));
+	if (fmt->index == 0)
 		fmt->pixelformat = V4L2_PIX_FMT_UYVY;
-	} else {
-		strscpy(fmt->description, "Y/CbCr 4:2:0",
-			sizeof(fmt->description));
+	else
 		fmt->pixelformat = V4L2_PIX_FMT_NV12;
-	}
 
 	return 0;
 }
@@ -1319,6 +1303,7 @@
 	vbd->v4l2_dev   = &disp_dev->vpbe_dev->v4l2_dev;
 	vbd->lock	= &vpbe_display_layer->opslock;
 	vbd->vfl_dir	= VFL_DIR_TX;
+	vbd->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
 
 	if (disp_dev->vpbe_dev->current_timings.timings_type &
 			VPBE_ENC_STD)
diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c
index 491842e..91b571a0 100644
--- a/drivers/media/platform/davinci/vpbe_osd.c
+++ b/drivers/media/platform/davinci/vpbe_osd.c
@@ -16,11 +16,6 @@
 #include <linux/clk.h>
 #include <linux/slab.h>
 
-#ifdef CONFIG_ARCH_DAVINCI
-#include <mach/cputype.h>
-#include <mach/hardware.h>
-#endif
-
 #include <media/davinci/vpss.h>
 #include <media/v4l2-device.h>
 #include <media/davinci/vpbe_types.h>
diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c
index 425f91f..8caa084 100644
--- a/drivers/media/platform/davinci/vpbe_venc.c
+++ b/drivers/media/platform/davinci/vpbe_venc.c
@@ -14,11 +14,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 
-#ifdef CONFIG_ARCH_DAVINCI
-#include <mach/hardware.h>
-#include <mach/mux.h>
-#endif
-
 #include <linux/platform_data/i2c-davinci.h>
 
 #include <linux/io.h>
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index 295fbf1..916ed74 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -119,57 +119,27 @@
 /* Used when raw Bayer image from ccdc is directly captured to SDRAM */
 static const struct vpfe_pixel_format vpfe_pix_fmts[] = {
 	{
-		.fmtdesc = {
-			.index = 0,
-			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			.description = "Bayer GrRBGb 8bit A-Law compr.",
-			.pixelformat = V4L2_PIX_FMT_SBGGR8,
-		},
+		.pixelformat = V4L2_PIX_FMT_SBGGR8,
 		.bpp = 1,
 	},
 	{
-		.fmtdesc = {
-			.index = 1,
-			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			.description = "Bayer GrRBGb - 16bit",
-			.pixelformat = V4L2_PIX_FMT_SBGGR16,
-		},
+		.pixelformat = V4L2_PIX_FMT_SBGGR16,
 		.bpp = 2,
 	},
 	{
-		.fmtdesc = {
-			.index = 2,
-			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			.description = "Bayer GrRBGb 8bit DPCM compr.",
-			.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
-		},
+		.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
 		.bpp = 1,
 	},
 	{
-		.fmtdesc = {
-			.index = 3,
-			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			.description = "YCbCr 4:2:2 Interleaved UYVY",
-			.pixelformat = V4L2_PIX_FMT_UYVY,
-		},
+		.pixelformat = V4L2_PIX_FMT_UYVY,
 		.bpp = 2,
 	},
 	{
-		.fmtdesc = {
-			.index = 4,
-			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			.description = "YCbCr 4:2:2 Interleaved YUYV",
-			.pixelformat = V4L2_PIX_FMT_YUYV,
-		},
+		.pixelformat = V4L2_PIX_FMT_YUYV,
 		.bpp = 2,
 	},
 	{
-		.fmtdesc = {
-			.index = 5,
-			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-			.description = "Y/CbCr 4:2:0 - Semi planar",
-			.pixelformat = V4L2_PIX_FMT_NV12,
-		},
+		.pixelformat = V4L2_PIX_FMT_NV12,
 		.bpp = 1,
 	},
 };
@@ -183,7 +153,7 @@
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) {
-		if (pix_format == vpfe_pix_fmts[i].fmtdesc.pixelformat)
+		if (pix_format == vpfe_pix_fmts[i].pixelformat)
 			return &vpfe_pix_fmts[i];
 	}
 	return NULL;
@@ -782,7 +752,7 @@
 	temp = 0;
 	found = 0;
 	while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) {
-		if (vpfe_pix_fmt->fmtdesc.pixelformat == pix) {
+		if (vpfe_pix_fmt->pixelformat == pix) {
 			found = 1;
 			break;
 		}
@@ -877,8 +847,6 @@
 
 	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n");
 
-	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	strscpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
 	strscpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
 	strscpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
@@ -901,7 +869,6 @@
 {
 	struct vpfe_device *vpfe_dev = video_drvdata(file);
 	const struct vpfe_pixel_format *pix_fmt;
-	int temp_index;
 	u32 pix;
 
 	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n");
@@ -912,9 +879,7 @@
 	/* Fill in the information about format */
 	pix_fmt = vpfe_lookup_pix_format(pix);
 	if (pix_fmt) {
-		temp_index = fmt->index;
-		*fmt = pix_fmt->fmtdesc;
-		fmt->index = temp_index;
+		fmt->pixelformat = fmt->pixelformat;
 		return 0;
 	}
 	return -EINVAL;
@@ -1785,6 +1750,7 @@
 	vfd->ioctl_ops		= &vpfe_ioctl_ops;
 	vfd->tvnorms		= 0;
 	vfd->v4l2_dev		= &vpfe_dev->v4l2_dev;
+	vfd->device_caps	= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 	snprintf(vfd->name, sizeof(vfd->name),
 		 "%s_V%d.%d.%d",
 		 CAPTURE_DRV_NAME,
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index f0f7ef6..71f4fe8 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -938,17 +938,10 @@
 	}
 
 	/* Fill in the information about format */
-	if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) {
-		fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		strscpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb",
-			sizeof(fmt->description));
+	if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
 		fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
-	} else {
-		fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		strscpy(fmt->description, "YCbCr4:2:2 Semi-Planar",
-			sizeof(fmt->description));
+	else
 		fmt->pixelformat = V4L2_PIX_FMT_NV16;
-	}
 	return 0;
 }
 
@@ -979,7 +972,6 @@
 		pixfmt->bytesperline = common->fmt.fmt.pix.width * 2;
 		pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
 	}
-	pixfmt->priv = 0;
 
 	dev_dbg(vpif_dev, "%s: %d x %d; pitch=%d pixelformat=0x%08x, field=%d, size=%d\n", __func__,
 		pixfmt->width, pixfmt->height,
@@ -1085,8 +1077,6 @@
 {
 	struct vpif_capture_config *config = vpif_dev->platform_data;
 
-	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
 		 dev_name(vpif_dev));
@@ -1473,6 +1463,7 @@
 		vdev->vfl_dir = VFL_DIR_RX;
 		vdev->queue = q;
 		vdev->lock = &common->lock;
+		vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 		video_set_drvdata(&ch->video_dev, ch);
 		err = video_register_device(vdev,
 					    VFL_TYPE_GRABBER, (j ? 1 : 0));
@@ -1511,6 +1502,7 @@
 vpif_capture_get_pdata(struct platform_device *pdev)
 {
 	struct device_node *endpoint = NULL;
+	struct device_node *rem = NULL;
 	struct vpif_capture_config *pdata;
 	struct vpif_subdev_info *sdinfo;
 	struct vpif_capture_chan_config *chan;
@@ -1541,7 +1533,6 @@
 
 	for (i = 0; i < VPIF_CAPTURE_NUM_CHANNELS; i++) {
 		struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
-		struct device_node *rem;
 		unsigned int flags;
 		int err;
 
@@ -1554,7 +1545,6 @@
 		if (!rem) {
 			dev_dbg(&pdev->dev, "Remote device at %pOF not found\n",
 				endpoint);
-			of_node_put(endpoint);
 			goto done;
 		}
 
@@ -1564,11 +1554,8 @@
 					    VPIF_CAPTURE_NUM_CHANNELS,
 					    sizeof(*chan->inputs),
 					    GFP_KERNEL);
-		if (!chan->inputs) {
-			of_node_put(rem);
-			of_node_put(endpoint);
+		if (!chan->inputs)
 			goto err_cleanup;
-		}
 
 		chan->input_count++;
 		chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;
@@ -1577,7 +1564,6 @@
 
 		err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
 						 &bus_cfg);
-		of_node_put(endpoint);
 		if (err) {
 			dev_err(&pdev->dev, "Could not parse the endpoint\n");
 			of_node_put(rem);
@@ -1601,13 +1587,14 @@
 		pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev(
 			&vpif_obj.notifier, of_fwnode_handle(rem),
 			sizeof(struct v4l2_async_subdev));
-		if (IS_ERR(pdata->asd[i])) {
-			of_node_put(rem);
+		if (IS_ERR(pdata->asd[i]))
 			goto err_cleanup;
-		}
+
+		of_node_put(rem);
 	}
 
 done:
+	of_node_put(endpoint);
 	pdata->asd_sizes[0] = i;
 	pdata->subdev_count = i;
 	pdata->card_name = "DA850/OMAP-L138 Video Capture";
@@ -1615,6 +1602,8 @@
 	return pdata;
 
 err_cleanup:
+	of_node_put(rem);
+	of_node_put(endpoint);
 	v4l2_async_notifier_cleanup(&vpif_obj.notifier);
 
 	return NULL;
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index a69897c..abbdbac 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -584,8 +584,6 @@
 {
 	struct vpif_display_config *config = vpif_dev->platform_data;
 
-	cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver));
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
 		 dev_name(vpif_dev));
@@ -601,11 +599,7 @@
 		return -EINVAL;
 
 	/* Fill in the information about format */
-	fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	strscpy(fmt->description, "YCbCr4:2:2 YC Planar",
-		sizeof(fmt->description));
 	fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
-	fmt->flags = 0;
 	return 0;
 }
 
@@ -1218,6 +1212,7 @@
 		vdev->vfl_dir = VFL_DIR_TX;
 		vdev->queue = q;
 		vdev->lock = &common->lock;
+		vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
 		video_set_drvdata(&ch->video_dev, ch);
 		err = video_register_device(vdev, VFL_TYPE_GRABBER,
 					    (j ? 3 : 2));
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c
index 854869f..f6650b4 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -27,21 +27,18 @@
 
 static const struct gsc_fmt gsc_formats[] = {
 	{
-		.name		= "RGB565",
 		.pixelformat	= V4L2_PIX_FMT_RGB565X,
 		.depth		= { 16 },
 		.color		= GSC_RGB,
 		.num_planes	= 1,
 		.num_comp	= 1,
 	}, {
-		.name		= "BGRX-8-8-8-8, 32 bpp",
 		.pixelformat	= V4L2_PIX_FMT_BGR32,
 		.depth		= { 32 },
 		.color		= GSC_RGB,
 		.num_planes	= 1,
 		.num_comp	= 1,
 	}, {
-		.name		= "YUV 4:2:2 packed, YCbYCr",
 		.pixelformat	= V4L2_PIX_FMT_YUYV,
 		.depth		= { 16 },
 		.color		= GSC_YUV422,
@@ -51,7 +48,6 @@
 		.num_comp	= 1,
 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
 	}, {
-		.name		= "YUV 4:2:2 packed, CbYCrY",
 		.pixelformat	= V4L2_PIX_FMT_UYVY,
 		.depth		= { 16 },
 		.color		= GSC_YUV422,
@@ -61,7 +57,6 @@
 		.num_comp	= 1,
 		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
 	}, {
-		.name		= "YUV 4:2:2 packed, CrYCbY",
 		.pixelformat	= V4L2_PIX_FMT_VYUY,
 		.depth		= { 16 },
 		.color		= GSC_YUV422,
@@ -71,7 +66,6 @@
 		.num_comp	= 1,
 		.mbus_code	= MEDIA_BUS_FMT_VYUY8_2X8,
 	}, {
-		.name		= "YUV 4:2:2 packed, YCrYCb",
 		.pixelformat	= V4L2_PIX_FMT_YVYU,
 		.depth		= { 16 },
 		.color		= GSC_YUV422,
@@ -81,7 +75,6 @@
 		.num_comp	= 1,
 		.mbus_code	= MEDIA_BUS_FMT_YVYU8_2X8,
 	}, {
-		.name		= "YUV 4:4:4 planar, YCbYCr",
 		.pixelformat	= V4L2_PIX_FMT_YUV32,
 		.depth		= { 32 },
 		.color		= GSC_YUV444,
@@ -90,7 +83,6 @@
 		.num_planes	= 1,
 		.num_comp	= 1,
 	}, {
-		.name		= "YUV 4:2:2 planar, Y/Cb/Cr",
 		.pixelformat	= V4L2_PIX_FMT_YUV422P,
 		.depth		= { 16 },
 		.color		= GSC_YUV422,
@@ -99,7 +91,6 @@
 		.num_planes	= 1,
 		.num_comp	= 3,
 	}, {
-		.name		= "YUV 4:2:2 planar, Y/CbCr",
 		.pixelformat	= V4L2_PIX_FMT_NV16,
 		.depth		= { 16 },
 		.color		= GSC_YUV422,
@@ -108,7 +99,6 @@
 		.num_planes	= 1,
 		.num_comp	= 2,
 	}, {
-		.name		= "YUV 4:2:2 non-contig, Y/CbCr",
 		.pixelformat	= V4L2_PIX_FMT_NV16M,
 		.depth		= { 8, 8 },
 		.color		= GSC_YUV422,
@@ -117,7 +107,6 @@
 		.num_planes	= 2,
 		.num_comp	= 2,
 	}, {
-		.name		= "YUV 4:2:2 planar, Y/CrCb",
 		.pixelformat	= V4L2_PIX_FMT_NV61,
 		.depth		= { 16 },
 		.color		= GSC_YUV422,
@@ -126,7 +115,6 @@
 		.num_planes	= 1,
 		.num_comp	= 2,
 	}, {
-		.name		= "YUV 4:2:2 non-contig, Y/CrCb",
 		.pixelformat	= V4L2_PIX_FMT_NV61M,
 		.depth		= { 8, 8 },
 		.color		= GSC_YUV422,
@@ -135,7 +123,6 @@
 		.num_planes	= 2,
 		.num_comp	= 2,
 	}, {
-		.name		= "YUV 4:2:0 planar, YCbCr",
 		.pixelformat	= V4L2_PIX_FMT_YUV420,
 		.depth		= { 12 },
 		.color		= GSC_YUV420,
@@ -144,7 +131,6 @@
 		.num_planes	= 1,
 		.num_comp	= 3,
 	}, {
-		.name		= "YUV 4:2:0 planar, YCrCb",
 		.pixelformat	= V4L2_PIX_FMT_YVU420,
 		.depth		= { 12 },
 		.color		= GSC_YUV420,
@@ -154,7 +140,6 @@
 		.num_comp	= 3,
 
 	}, {
-		.name		= "YUV 4:2:0 planar, Y/CbCr",
 		.pixelformat	= V4L2_PIX_FMT_NV12,
 		.depth		= { 12 },
 		.color		= GSC_YUV420,
@@ -163,7 +148,6 @@
 		.num_planes	= 1,
 		.num_comp	= 2,
 	}, {
-		.name		= "YUV 4:2:0 planar, Y/CrCb",
 		.pixelformat	= V4L2_PIX_FMT_NV21,
 		.depth		= { 12 },
 		.color		= GSC_YUV420,
@@ -172,7 +156,6 @@
 		.num_planes	= 1,
 		.num_comp	= 2,
 	}, {
-		.name		= "YUV 4:2:0 non-contig. 2p, Y/CrCb",
 		.pixelformat	= V4L2_PIX_FMT_NV21M,
 		.depth		= { 8, 4 },
 		.color		= GSC_YUV420,
@@ -181,7 +164,6 @@
 		.num_planes	= 2,
 		.num_comp	= 2,
 	}, {
-		.name		= "YUV 4:2:0 non-contig. 2p, Y/CbCr",
 		.pixelformat	= V4L2_PIX_FMT_NV12M,
 		.depth		= { 8, 4 },
 		.color		= GSC_YUV420,
@@ -190,7 +172,6 @@
 		.num_planes	= 2,
 		.num_comp	= 2,
 	}, {
-		.name		= "YUV 4:2:0 non-contig. 3p, Y/Cb/Cr",
 		.pixelformat	= V4L2_PIX_FMT_YUV420M,
 		.depth		= { 8, 2, 2 },
 		.color		= GSC_YUV420,
@@ -199,7 +180,6 @@
 		.num_planes	= 3,
 		.num_comp	= 3,
 	}, {
-		.name		= "YUV 4:2:0 non-contig. 3p, Y/Cr/Cb",
 		.pixelformat	= V4L2_PIX_FMT_YVU420M,
 		.depth		= { 8, 2, 2 },
 		.color		= GSC_YUV420,
@@ -208,7 +188,6 @@
 		.num_planes	= 3,
 		.num_comp	= 3,
 	}, {
-		.name		= "YUV 4:2:0 n.c. 2p, Y/CbCr tiled",
 		.pixelformat	= V4L2_PIX_FMT_NV12MT_16X16,
 		.depth		= { 8, 4 },
 		.color		= GSC_YUV420,
@@ -335,7 +314,6 @@
 	if (!fmt)
 		return -EINVAL;
 
-	strscpy(f->description, fmt->name, sizeof(f->description));
 	f->pixelformat = fmt->pixelformat;
 
 	return 0;
diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h
index 772183b..8e5a9ac 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.h
+++ b/drivers/media/platform/exynos-gsc/gsc-core.h
@@ -103,7 +103,6 @@
 /**
  * struct gsc_fmt - the driver's internal color format data
  * @mbus_code: Media Bus pixel code, -1 if not applicable
- * @name: format description
  * @pixelformat: the fourcc code for this format, 0 if not applicable
  * @yorder: Y/C order
  * @corder: Chrominance order control
@@ -114,7 +113,6 @@
  */
 struct gsc_fmt {
 	u32 mbus_code;
-	char	*name;
 	u32	pixelformat;
 	u32	color;
 	u32	yorder;
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index 6651036..121d609 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -738,10 +738,7 @@
 			       f->index);
 	if (!fmt)
 		return -EINVAL;
-	strscpy(f->description, fmt->name, sizeof(f->description));
 	f->pixelformat = fmt->fourcc;
-	if (fmt->fourcc == MEDIA_BUS_FMT_JPEG_1X8)
-		f->flags |= V4L2_FMT_FLAG_COMPRESSED;
 	return 0;
 }
 
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index 7006f54..cde60fb 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -36,7 +36,6 @@
 
 static struct fimc_fmt fimc_formats[] = {
 	{
-		.name		= "RGB565",
 		.fourcc		= V4L2_PIX_FMT_RGB565,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_RGB565,
@@ -44,7 +43,6 @@
 		.colplanes	= 1,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
-		.name		= "BGR666",
 		.fourcc		= V4L2_PIX_FMT_BGR666,
 		.depth		= { 32 },
 		.color		= FIMC_FMT_RGB666,
@@ -52,7 +50,6 @@
 		.colplanes	= 1,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
-		.name		= "BGRA8888, 32 bpp",
 		.fourcc		= V4L2_PIX_FMT_BGR32,
 		.depth		= { 32 },
 		.color		= FIMC_FMT_RGB888,
@@ -60,7 +57,6 @@
 		.colplanes	= 1,
 		.flags		= FMT_FLAGS_M2M | FMT_HAS_ALPHA,
 	}, {
-		.name		= "ARGB1555",
 		.fourcc		= V4L2_PIX_FMT_RGB555,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_RGB555,
@@ -68,7 +64,6 @@
 		.colplanes	= 1,
 		.flags		= FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
 	}, {
-		.name		= "ARGB4444",
 		.fourcc		= V4L2_PIX_FMT_RGB444,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_RGB444,
@@ -76,11 +71,9 @@
 		.colplanes	= 1,
 		.flags		= FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
 	}, {
-		.name		= "YUV 4:4:4",
 		.mbus_code	= MEDIA_BUS_FMT_YUV10_1X30,
 		.flags		= FMT_FLAGS_WRITEBACK,
 	}, {
-		.name		= "YUV 4:2:2 packed, YCbYCr",
 		.fourcc		= V4L2_PIX_FMT_YUYV,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_YCBYCR422,
@@ -89,7 +82,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
 		.flags		= FMT_FLAGS_M2M | FMT_FLAGS_CAM,
 	}, {
-		.name		= "YUV 4:2:2 packed, CbYCrY",
 		.fourcc		= V4L2_PIX_FMT_UYVY,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_CBYCRY422,
@@ -98,7 +90,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
 		.flags		= FMT_FLAGS_M2M | FMT_FLAGS_CAM,
 	}, {
-		.name		= "YUV 4:2:2 packed, CrYCbY",
 		.fourcc		= V4L2_PIX_FMT_VYUY,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_CRYCBY422,
@@ -107,7 +98,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_VYUY8_2X8,
 		.flags		= FMT_FLAGS_M2M | FMT_FLAGS_CAM,
 	}, {
-		.name		= "YUV 4:2:2 packed, YCrYCb",
 		.fourcc		= V4L2_PIX_FMT_YVYU,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_YCRYCB422,
@@ -116,7 +106,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_YVYU8_2X8,
 		.flags		= FMT_FLAGS_M2M | FMT_FLAGS_CAM,
 	}, {
-		.name		= "YUV 4:2:2 planar, Y/Cb/Cr",
 		.fourcc		= V4L2_PIX_FMT_YUV422P,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_YCBYCR422,
@@ -124,7 +113,6 @@
 		.colplanes	= 3,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
-		.name		= "YUV 4:2:2 planar, Y/CbCr",
 		.fourcc		= V4L2_PIX_FMT_NV16,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_YCBYCR422,
@@ -132,7 +120,6 @@
 		.colplanes	= 2,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
-		.name		= "YUV 4:2:2 planar, Y/CrCb",
 		.fourcc		= V4L2_PIX_FMT_NV61,
 		.depth		= { 16 },
 		.color		= FIMC_FMT_YCRYCB422,
@@ -140,7 +127,6 @@
 		.colplanes	= 2,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
-		.name		= "YUV 4:2:0 planar, YCbCr",
 		.fourcc		= V4L2_PIX_FMT_YUV420,
 		.depth		= { 12 },
 		.color		= FIMC_FMT_YCBCR420,
@@ -148,7 +134,6 @@
 		.colplanes	= 3,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
-		.name		= "YUV 4:2:0 planar, Y/CbCr",
 		.fourcc		= V4L2_PIX_FMT_NV12,
 		.depth		= { 12 },
 		.color		= FIMC_FMT_YCBCR420,
@@ -156,7 +141,6 @@
 		.colplanes	= 2,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
-		.name		= "YUV 4:2:0 non-contig. 2p, Y/CbCr",
 		.fourcc		= V4L2_PIX_FMT_NV12M,
 		.color		= FIMC_FMT_YCBCR420,
 		.depth		= { 8, 4 },
@@ -164,7 +148,6 @@
 		.colplanes	= 2,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
-		.name		= "YUV 4:2:0 non-contig. 3p, Y/Cb/Cr",
 		.fourcc		= V4L2_PIX_FMT_YUV420M,
 		.color		= FIMC_FMT_YCBCR420,
 		.depth		= { 8, 2, 2 },
@@ -172,7 +155,6 @@
 		.colplanes	= 3,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
-		.name		= "YUV 4:2:0 non-contig. 2p, tiled",
 		.fourcc		= V4L2_PIX_FMT_NV12MT,
 		.color		= FIMC_FMT_YCBCR420,
 		.depth		= { 8, 4 },
@@ -180,7 +162,6 @@
 		.colplanes	= 2,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
-		.name		= "JPEG encoded data",
 		.fourcc		= V4L2_PIX_FMT_JPEG,
 		.color		= FIMC_FMT_JPEG,
 		.depth		= { 8 },
@@ -189,7 +170,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_JPEG_1X8,
 		.flags		= FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED,
 	}, {
-		.name		= "S5C73MX interleaved UYVY/JPEG",
 		.fourcc		= V4L2_PIX_FMT_S5C_UYVY_JPG,
 		.color		= FIMC_FMT_YUYV_JPEG,
 		.depth		= { 8 },
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index e043d55..64148b7 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -341,7 +341,6 @@
 		return -ENOMEM;
 
 	is->memory.size = FIMC_IS_CPU_MEM_SIZE;
-	memset(is->memory.vaddr, 0, is->memory.size);
 
 	dev_info(dev, "FIMC-IS CPU memory base: %#x\n", (u32)is->memory.paddr);
 
@@ -806,6 +805,7 @@
 		return -ENODEV;
 
 	is->pmu_regs = of_iomap(node, 0);
+	of_node_put(node);
 	if (!is->pmu_regs)
 		return -ENOMEM;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index a75f932..378cc30 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -362,7 +362,6 @@
 	if (WARN_ON(fmt == NULL))
 		return -EINVAL;
 
-	strscpy(f->description, fmt->name, sizeof(f->description));
 	f->pixelformat = fmt->fourcc;
 
 	return 0;
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index 907b83e..cde0d25 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -33,21 +33,18 @@
 
 static const struct fimc_fmt fimc_isp_formats[FIMC_ISP_NUM_FORMATS] = {
 	{
-		.name		= "RAW8 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG8,
 		.depth		= { 8 },
 		.color		= FIMC_FMT_RAW8,
 		.memplanes	= 1,
 		.mbus_code	= MEDIA_BUS_FMT_SGRBG8_1X8,
 	}, {
-		.name		= "RAW10 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG10,
 		.depth		= { 10 },
 		.color		= FIMC_FMT_RAW10,
 		.memplanes	= 1,
 		.mbus_code	= MEDIA_BUS_FMT_SGRBG10_1X10,
 	}, {
-		.name		= "RAW12 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG12,
 		.depth		= { 12 },
 		.color		= FIMC_FMT_RAW12,
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
index 48f2cf1..c5656e9 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
@@ -6,6 +6,8 @@
 #ifndef FIMC_LITE_REG_H_
 #define FIMC_LITE_REG_H_
 
+#include <linux/bitops.h>
+
 #include "fimc-lite.h"
 
 /* Camera Source size */
@@ -27,27 +29,27 @@
 /* User defined formats. x = 0...15 */
 #define FLITE_REG_CIGCTRL_USER(x)		((0x30 + x - 1) << 24)
 #define FLITE_REG_CIGCTRL_FMT_MASK		(0x3f << 24)
-#define FLITE_REG_CIGCTRL_SHADOWMASK_DISABLE	(1 << 21)
-#define FLITE_REG_CIGCTRL_ODMA_DISABLE		(1 << 20)
-#define FLITE_REG_CIGCTRL_SWRST_REQ		(1 << 19)
-#define FLITE_REG_CIGCTRL_SWRST_RDY		(1 << 18)
-#define FLITE_REG_CIGCTRL_SWRST			(1 << 17)
-#define FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR	(1 << 15)
-#define FLITE_REG_CIGCTRL_INVPOLPCLK		(1 << 14)
-#define FLITE_REG_CIGCTRL_INVPOLVSYNC		(1 << 13)
-#define FLITE_REG_CIGCTRL_INVPOLHREF		(1 << 12)
+#define FLITE_REG_CIGCTRL_SHADOWMASK_DISABLE	BIT(21)
+#define FLITE_REG_CIGCTRL_ODMA_DISABLE		BIT(20)
+#define FLITE_REG_CIGCTRL_SWRST_REQ		BIT(19)
+#define FLITE_REG_CIGCTRL_SWRST_RDY		BIT(18)
+#define FLITE_REG_CIGCTRL_SWRST			BIT(17)
+#define FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR	BIT(15)
+#define FLITE_REG_CIGCTRL_INVPOLPCLK		BIT(14)
+#define FLITE_REG_CIGCTRL_INVPOLVSYNC		BIT(13)
+#define FLITE_REG_CIGCTRL_INVPOLHREF		BIT(12)
 /* Interrupts mask bits (1 disables an interrupt) */
-#define FLITE_REG_CIGCTRL_IRQ_LASTEN		(1 << 8)
-#define FLITE_REG_CIGCTRL_IRQ_ENDEN		(1 << 7)
-#define FLITE_REG_CIGCTRL_IRQ_STARTEN		(1 << 6)
-#define FLITE_REG_CIGCTRL_IRQ_OVFEN		(1 << 5)
+#define FLITE_REG_CIGCTRL_IRQ_LASTEN		BIT(8)
+#define FLITE_REG_CIGCTRL_IRQ_ENDEN		BIT(7)
+#define FLITE_REG_CIGCTRL_IRQ_STARTEN		BIT(6)
+#define FLITE_REG_CIGCTRL_IRQ_OVFEN		BIT(5)
 #define FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK	(0xf << 5)
-#define FLITE_REG_CIGCTRL_SELCAM_MIPI		(1 << 3)
+#define FLITE_REG_CIGCTRL_SELCAM_MIPI		BIT(3)
 
 /* Image Capture Enable */
 #define FLITE_REG_CIIMGCPT			0x08
-#define FLITE_REG_CIIMGCPT_IMGCPTEN		(1 << 31)
-#define FLITE_REG_CIIMGCPT_CPT_FREN		(1 << 25)
+#define FLITE_REG_CIIMGCPT_IMGCPTEN		BIT(31)
+#define FLITE_REG_CIIMGCPT_CPT_FREN		BIT(25)
 #define FLITE_REG_CIIMGCPT_CPT_MOD_FRCNT	(1 << 18)
 #define FLITE_REG_CIIMGCPT_CPT_MOD_FREN		(0 << 18)
 
@@ -56,10 +58,10 @@
 
 /* Camera Window Offset */
 #define FLITE_REG_CIWDOFST			0x10
-#define FLITE_REG_CIWDOFST_WINOFSEN		(1 << 31)
-#define FLITE_REG_CIWDOFST_CLROVIY		(1 << 31)
-#define FLITE_REG_CIWDOFST_CLROVFICB		(1 << 15)
-#define FLITE_REG_CIWDOFST_CLROVFICR		(1 << 14)
+#define FLITE_REG_CIWDOFST_WINOFSEN		BIT(31)
+#define FLITE_REG_CIWDOFST_CLROVIY		BIT(31)
+#define FLITE_REG_CIWDOFST_CLROVFICB		BIT(15)
+#define FLITE_REG_CIWDOFST_CLROVFICR		BIT(14)
 #define FLITE_REG_CIWDOFST_OFST_MASK		((0x1fff << 16) | 0x1fff)
 
 /* Camera Window Offset2 */
@@ -67,8 +69,8 @@
 
 /* Camera Output DMA Format */
 #define FLITE_REG_CIODMAFMT			0x18
-#define FLITE_REG_CIODMAFMT_RAW_CON		(1 << 15)
-#define FLITE_REG_CIODMAFMT_PACK12		(1 << 14)
+#define FLITE_REG_CIODMAFMT_RAW_CON		BIT(15)
+#define FLITE_REG_CIODMAFMT_PACK12		BIT(14)
 #define FLITE_REG_CIODMAFMT_YCBYCR		(0 << 4)
 #define FLITE_REG_CIODMAFMT_YCRYCB		(1 << 4)
 #define FLITE_REG_CIODMAFMT_CBYCRY		(2 << 4)
@@ -88,34 +90,34 @@
 
 /* Camera Status */
 #define FLITE_REG_CISTATUS			0x40
-#define FLITE_REG_CISTATUS_MIPI_VVALID		(1 << 22)
-#define FLITE_REG_CISTATUS_MIPI_HVALID		(1 << 21)
-#define FLITE_REG_CISTATUS_MIPI_DVALID		(1 << 20)
-#define FLITE_REG_CISTATUS_ITU_VSYNC		(1 << 14)
-#define FLITE_REG_CISTATUS_ITU_HREFF		(1 << 13)
-#define FLITE_REG_CISTATUS_OVFIY		(1 << 10)
-#define FLITE_REG_CISTATUS_OVFICB		(1 << 9)
-#define FLITE_REG_CISTATUS_OVFICR		(1 << 8)
-#define FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW	(1 << 7)
-#define FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND	(1 << 6)
-#define FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART	(1 << 5)
-#define FLITE_REG_CISTATUS_IRQ_SRC_FRMEND	(1 << 4)
-#define FLITE_REG_CISTATUS_IRQ_CAM		(1 << 0)
+#define FLITE_REG_CISTATUS_MIPI_VVALID		BIT(22)
+#define FLITE_REG_CISTATUS_MIPI_HVALID		BIT(21)
+#define FLITE_REG_CISTATUS_MIPI_DVALID		BIT(20)
+#define FLITE_REG_CISTATUS_ITU_VSYNC		BIT(14)
+#define FLITE_REG_CISTATUS_ITU_HREFF		BIT(13)
+#define FLITE_REG_CISTATUS_OVFIY		BIT(10)
+#define FLITE_REG_CISTATUS_OVFICB		BIT(9)
+#define FLITE_REG_CISTATUS_OVFICR		BIT(8)
+#define FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW	BIT(7)
+#define FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND	BIT(6)
+#define FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART	BIT(5)
+#define FLITE_REG_CISTATUS_IRQ_SRC_FRMEND	BIT(4)
+#define FLITE_REG_CISTATUS_IRQ_CAM		BIT(0)
 #define FLITE_REG_CISTATUS_IRQ_MASK		(0xf << 4)
 
 /* Camera Status2 */
 #define FLITE_REG_CISTATUS2			0x44
-#define FLITE_REG_CISTATUS2_LASTCAPEND		(1 << 1)
-#define FLITE_REG_CISTATUS2_FRMEND		(1 << 0)
+#define FLITE_REG_CISTATUS2_LASTCAPEND		BIT(1)
+#define FLITE_REG_CISTATUS2_FRMEND		BIT(0)
 
 /* Qos Threshold */
 #define FLITE_REG_CITHOLD			0xf0
-#define FLITE_REG_CITHOLD_W_QOS_EN		(1 << 30)
+#define FLITE_REG_CITHOLD_W_QOS_EN		BIT(30)
 
 /* Camera General Purpose */
 #define FLITE_REG_CIGENERAL			0xfc
 /* b0: 1 - camera B, 0 - camera A */
-#define FLITE_REG_CIGENERAL_CAM_B		(1 << 0)
+#define FLITE_REG_CIGENERAL_CAM_B		BIT(0)
 
 #define FLITE_REG_CIFCNTSEQ			0x100
 #define FLITE_REG_CIOSAN(x)			(0x200 + (4 * (x)))
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index c1f0aee..e87c6a0 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -39,7 +39,6 @@
 
 static const struct fimc_fmt fimc_lite_formats[] = {
 	{
-		.name		= "YUV 4:2:2 packed, YCbYCr",
 		.fourcc		= V4L2_PIX_FMT_YUYV,
 		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
@@ -48,7 +47,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
 		.flags		= FMT_FLAGS_YUV,
 	}, {
-		.name		= "YUV 4:2:2 packed, CbYCrY",
 		.fourcc		= V4L2_PIX_FMT_UYVY,
 		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
@@ -57,7 +55,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
 		.flags		= FMT_FLAGS_YUV,
 	}, {
-		.name		= "YUV 4:2:2 packed, CrYCbY",
 		.fourcc		= V4L2_PIX_FMT_VYUY,
 		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
@@ -66,7 +63,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_VYUY8_2X8,
 		.flags		= FMT_FLAGS_YUV,
 	}, {
-		.name		= "YUV 4:2:2 packed, YCrYCb",
 		.fourcc		= V4L2_PIX_FMT_YVYU,
 		.colorspace	= V4L2_COLORSPACE_JPEG,
 		.depth		= { 16 },
@@ -75,7 +71,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_YVYU8_2X8,
 		.flags		= FMT_FLAGS_YUV,
 	}, {
-		.name		= "RAW8 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG8,
 		.colorspace	= V4L2_COLORSPACE_SRGB,
 		.depth		= { 8 },
@@ -84,7 +79,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_SGRBG8_1X8,
 		.flags		= FMT_FLAGS_RAW_BAYER,
 	}, {
-		.name		= "RAW10 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG10,
 		.colorspace	= V4L2_COLORSPACE_SRGB,
 		.depth		= { 16 },
@@ -93,7 +87,6 @@
 		.mbus_code	= MEDIA_BUS_FMT_SGRBG10_1X10,
 		.flags		= FMT_FLAGS_RAW_BAYER,
 	}, {
-		.name		= "RAW12 (GRBG)",
 		.fourcc		= V4L2_PIX_FMT_SGRBG12,
 		.colorspace	= V4L2_COLORSPACE_SRGB,
 		.depth		= { 16 },
@@ -667,7 +660,6 @@
 		return -EINVAL;
 
 	fmt = &fimc_lite_formats[f->index];
-	strscpy(f->description, fmt->name, sizeof(f->description));
 	f->pixelformat = fmt->fourcc;
 
 	return 0;
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index 62e876f..c70c2cb 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -247,7 +247,6 @@
 	if (!fmt)
 		return -EINVAL;
 
-	strscpy(f->description, fmt->name, sizeof(f->description));
 	f->pixelformat = fmt->fourcc;
 	return 0;
 }
diff --git a/drivers/media/platform/exynos4-is/fimc-reg.h b/drivers/media/platform/exynos4-is/fimc-reg.h
index 03ba6c2..b81826d 100644
--- a/drivers/media/platform/exynos4-is/fimc-reg.h
+++ b/drivers/media/platform/exynos4-is/fimc-reg.h
@@ -8,12 +8,14 @@
 #ifndef FIMC_REG_H_
 #define FIMC_REG_H_
 
+#include <linux/bitops.h>
+
 #include "fimc-core.h"
 
 /* Input source format */
 #define FIMC_REG_CISRCFMT			0x00
-#define FIMC_REG_CISRCFMT_ITU601_8BIT		(1 << 31)
-#define FIMC_REG_CISRCFMT_ITU601_16BIT		(1 << 29)
+#define FIMC_REG_CISRCFMT_ITU601_8BIT		BIT(31)
+#define FIMC_REG_CISRCFMT_ITU601_16BIT		BIT(29)
 #define FIMC_REG_CISRCFMT_ORDER422_YCBYCR	(0 << 14)
 #define FIMC_REG_CISRCFMT_ORDER422_YCRYCB	(1 << 14)
 #define FIMC_REG_CISRCFMT_ORDER422_CBYCRY	(2 << 14)
@@ -21,45 +23,45 @@
 
 /* Window offset */
 #define FIMC_REG_CIWDOFST			0x04
-#define FIMC_REG_CIWDOFST_OFF_EN		(1 << 31)
-#define FIMC_REG_CIWDOFST_CLROVFIY		(1 << 30)
-#define FIMC_REG_CIWDOFST_CLROVRLB		(1 << 29)
+#define FIMC_REG_CIWDOFST_OFF_EN		BIT(31)
+#define FIMC_REG_CIWDOFST_CLROVFIY		BIT(30)
+#define FIMC_REG_CIWDOFST_CLROVRLB		BIT(29)
 #define FIMC_REG_CIWDOFST_HOROFF_MASK		(0x7ff << 16)
-#define FIMC_REG_CIWDOFST_CLROVFICB		(1 << 15)
-#define FIMC_REG_CIWDOFST_CLROVFICR		(1 << 14)
+#define FIMC_REG_CIWDOFST_CLROVFICB		BIT(15)
+#define FIMC_REG_CIWDOFST_CLROVFICR		BIT(14)
 #define FIMC_REG_CIWDOFST_VEROFF_MASK		(0xfff << 0)
 
 /* Global control */
 #define FIMC_REG_CIGCTRL			0x08
-#define FIMC_REG_CIGCTRL_SWRST			(1 << 31)
-#define FIMC_REG_CIGCTRL_CAMRST_A		(1 << 30)
-#define FIMC_REG_CIGCTRL_SELCAM_ITU_A		(1 << 29)
+#define FIMC_REG_CIGCTRL_SWRST			BIT(31)
+#define FIMC_REG_CIGCTRL_CAMRST_A		BIT(30)
+#define FIMC_REG_CIGCTRL_SELCAM_ITU_A		BIT(29)
 #define FIMC_REG_CIGCTRL_TESTPAT_NORMAL		(0 << 27)
 #define FIMC_REG_CIGCTRL_TESTPAT_COLOR_BAR	(1 << 27)
 #define FIMC_REG_CIGCTRL_TESTPAT_HOR_INC	(2 << 27)
 #define FIMC_REG_CIGCTRL_TESTPAT_VER_INC	(3 << 27)
 #define FIMC_REG_CIGCTRL_TESTPAT_MASK		(3 << 27)
 #define FIMC_REG_CIGCTRL_TESTPAT_SHIFT		27
-#define FIMC_REG_CIGCTRL_INVPOLPCLK		(1 << 26)
-#define FIMC_REG_CIGCTRL_INVPOLVSYNC		(1 << 25)
-#define FIMC_REG_CIGCTRL_INVPOLHREF		(1 << 24)
-#define FIMC_REG_CIGCTRL_IRQ_OVFEN		(1 << 22)
-#define FIMC_REG_CIGCTRL_HREF_MASK		(1 << 21)
-#define FIMC_REG_CIGCTRL_IRQ_LEVEL		(1 << 20)
-#define FIMC_REG_CIGCTRL_IRQ_CLR		(1 << 19)
-#define FIMC_REG_CIGCTRL_IRQ_ENABLE		(1 << 16)
-#define FIMC_REG_CIGCTRL_SHDW_DISABLE		(1 << 12)
+#define FIMC_REG_CIGCTRL_INVPOLPCLK		BIT(26)
+#define FIMC_REG_CIGCTRL_INVPOLVSYNC		BIT(25)
+#define FIMC_REG_CIGCTRL_INVPOLHREF		BIT(24)
+#define FIMC_REG_CIGCTRL_IRQ_OVFEN		BIT(22)
+#define FIMC_REG_CIGCTRL_HREF_MASK		BIT(21)
+#define FIMC_REG_CIGCTRL_IRQ_LEVEL		BIT(20)
+#define FIMC_REG_CIGCTRL_IRQ_CLR		BIT(19)
+#define FIMC_REG_CIGCTRL_IRQ_ENABLE		BIT(16)
+#define FIMC_REG_CIGCTRL_SHDW_DISABLE		BIT(12)
 /* 0 - selects Writeback A (LCD), 1 - selects Writeback B (LCD/ISP) */
-#define FIMC_REG_CIGCTRL_SELWB_A		(1 << 10)
-#define FIMC_REG_CIGCTRL_CAM_JPEG		(1 << 8)
-#define FIMC_REG_CIGCTRL_SELCAM_MIPI_A		(1 << 7)
-#define FIMC_REG_CIGCTRL_CAMIF_SELWB		(1 << 6)
+#define FIMC_REG_CIGCTRL_SELWB_A		BIT(10)
+#define FIMC_REG_CIGCTRL_CAM_JPEG		BIT(8)
+#define FIMC_REG_CIGCTRL_SELCAM_MIPI_A		BIT(7)
+#define FIMC_REG_CIGCTRL_CAMIF_SELWB		BIT(6)
 /* 0 - ITU601; 1 - ITU709 */
-#define FIMC_REG_CIGCTRL_CSC_ITU601_709		(1 << 5)
-#define FIMC_REG_CIGCTRL_INVPOLHSYNC		(1 << 4)
-#define FIMC_REG_CIGCTRL_SELCAM_MIPI		(1 << 3)
-#define FIMC_REG_CIGCTRL_INVPOLFIELD		(1 << 1)
-#define FIMC_REG_CIGCTRL_INTERLACE		(1 << 0)
+#define FIMC_REG_CIGCTRL_CSC_ITU601_709		BIT(5)
+#define FIMC_REG_CIGCTRL_INVPOLHSYNC		BIT(4)
+#define FIMC_REG_CIGCTRL_SELCAM_MIPI		BIT(3)
+#define FIMC_REG_CIGCTRL_INVPOLFIELD		BIT(1)
+#define FIMC_REG_CIGCTRL_INTERLACE		BIT(0)
 
 /* Window offset 2 */
 #define FIMC_REG_CIWDOFST2			0x14
@@ -73,7 +75,7 @@
 
 /* Target image format */
 #define FIMC_REG_CITRGFMT			0x48
-#define FIMC_REG_CITRGFMT_INROT90		(1 << 31)
+#define FIMC_REG_CITRGFMT_INROT90		BIT(31)
 #define FIMC_REG_CITRGFMT_YCBCR420		(0 << 29)
 #define FIMC_REG_CITRGFMT_YCBCR422		(1 << 29)
 #define FIMC_REG_CITRGFMT_YCBCR422_1P		(2 << 29)
@@ -86,7 +88,7 @@
 #define FIMC_REG_CITRGFMT_FLIP_Y_MIRROR		(2 << 14)
 #define FIMC_REG_CITRGFMT_FLIP_180		(3 << 14)
 #define FIMC_REG_CITRGFMT_FLIP_MASK		(3 << 14)
-#define FIMC_REG_CITRGFMT_OUTROT90		(1 << 13)
+#define FIMC_REG_CITRGFMT_OUTROT90		BIT(13)
 #define FIMC_REG_CITRGFMT_VSIZE_MASK		(0xfff << 0)
 
 /* Output DMA control */
@@ -96,7 +98,7 @@
 #define FIMC_REG_CIOCTRL_ORDER422_YCRYCB	(1 << 0)
 #define FIMC_REG_CIOCTRL_ORDER422_CBYCRY	(2 << 0)
 #define FIMC_REG_CIOCTRL_ORDER422_CRYCBY	(3 << 0)
-#define FIMC_REG_CIOCTRL_LASTIRQ_ENABLE		(1 << 2)
+#define FIMC_REG_CIOCTRL_LASTIRQ_ENABLE		BIT(2)
 #define FIMC_REG_CIOCTRL_YCBCR_3PLANE		(0 << 3)
 #define FIMC_REG_CIOCTRL_YCBCR_2PLANE		(1 << 3)
 #define FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK	(1 << 3)
@@ -116,14 +118,14 @@
 
 /* Main scaler control */
 #define FIMC_REG_CISCCTRL			0x58
-#define FIMC_REG_CISCCTRL_SCALERBYPASS		(1 << 31)
-#define FIMC_REG_CISCCTRL_SCALEUP_H		(1 << 30)
-#define FIMC_REG_CISCCTRL_SCALEUP_V		(1 << 29)
-#define FIMC_REG_CISCCTRL_CSCR2Y_WIDE		(1 << 28)
-#define FIMC_REG_CISCCTRL_CSCY2R_WIDE		(1 << 27)
-#define FIMC_REG_CISCCTRL_LCDPATHEN_FIFO	(1 << 26)
-#define FIMC_REG_CISCCTRL_INTERLACE		(1 << 25)
-#define FIMC_REG_CISCCTRL_SCALERSTART		(1 << 15)
+#define FIMC_REG_CISCCTRL_SCALERBYPASS		BIT(31)
+#define FIMC_REG_CISCCTRL_SCALEUP_H		BIT(30)
+#define FIMC_REG_CISCCTRL_SCALEUP_V		BIT(29)
+#define FIMC_REG_CISCCTRL_CSCR2Y_WIDE		BIT(28)
+#define FIMC_REG_CISCCTRL_CSCY2R_WIDE		BIT(27)
+#define FIMC_REG_CISCCTRL_LCDPATHEN_FIFO	BIT(26)
+#define FIMC_REG_CISCCTRL_INTERLACE		BIT(25)
+#define FIMC_REG_CISCCTRL_SCALERSTART		BIT(15)
 #define FIMC_REG_CISCCTRL_INRGB_FMT_RGB565	(0 << 13)
 #define FIMC_REG_CISCCTRL_INRGB_FMT_RGB666	(1 << 13)
 #define FIMC_REG_CISCCTRL_INRGB_FMT_RGB888	(2 << 13)
@@ -132,8 +134,8 @@
 #define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666	(1 << 11)
 #define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888	(2 << 11)
 #define FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK	(3 << 11)
-#define FIMC_REG_CISCCTRL_RGB_EXT		(1 << 10)
-#define FIMC_REG_CISCCTRL_ONE2ONE		(1 << 9)
+#define FIMC_REG_CISCCTRL_RGB_EXT		BIT(10)
+#define FIMC_REG_CISCCTRL_ONE2ONE		BIT(9)
 #define FIMC_REG_CISCCTRL_MHRATIO(x)		((x) << 16)
 #define FIMC_REG_CISCCTRL_MVRATIO(x)		((x) << 0)
 #define FIMC_REG_CISCCTRL_MHRATIO_MASK		(0x1ff << 16)
@@ -147,39 +149,39 @@
 
 /* General status */
 #define FIMC_REG_CISTATUS			0x64
-#define FIMC_REG_CISTATUS_OVFIY			(1 << 31)
-#define FIMC_REG_CISTATUS_OVFICB		(1 << 30)
-#define FIMC_REG_CISTATUS_OVFICR		(1 << 29)
-#define FIMC_REG_CISTATUS_VSYNC			(1 << 28)
+#define FIMC_REG_CISTATUS_OVFIY			BIT(31)
+#define FIMC_REG_CISTATUS_OVFICB		BIT(30)
+#define FIMC_REG_CISTATUS_OVFICR		BIT(29)
+#define FIMC_REG_CISTATUS_VSYNC			BIT(28)
 #define FIMC_REG_CISTATUS_FRAMECNT_MASK		(3 << 26)
 #define FIMC_REG_CISTATUS_FRAMECNT_SHIFT	26
-#define FIMC_REG_CISTATUS_WINOFF_EN		(1 << 25)
-#define FIMC_REG_CISTATUS_IMGCPT_EN		(1 << 22)
-#define FIMC_REG_CISTATUS_IMGCPT_SCEN		(1 << 21)
-#define FIMC_REG_CISTATUS_VSYNC_A		(1 << 20)
-#define FIMC_REG_CISTATUS_VSYNC_B		(1 << 19)
-#define FIMC_REG_CISTATUS_OVRLB			(1 << 18)
-#define FIMC_REG_CISTATUS_FRAME_END		(1 << 17)
-#define FIMC_REG_CISTATUS_LASTCAPT_END		(1 << 16)
-#define FIMC_REG_CISTATUS_VVALID_A		(1 << 15)
-#define FIMC_REG_CISTATUS_VVALID_B		(1 << 14)
+#define FIMC_REG_CISTATUS_WINOFF_EN		BIT(25)
+#define FIMC_REG_CISTATUS_IMGCPT_EN		BIT(22)
+#define FIMC_REG_CISTATUS_IMGCPT_SCEN		BIT(21)
+#define FIMC_REG_CISTATUS_VSYNC_A		BIT(20)
+#define FIMC_REG_CISTATUS_VSYNC_B		BIT(19)
+#define FIMC_REG_CISTATUS_OVRLB			BIT(18)
+#define FIMC_REG_CISTATUS_FRAME_END		BIT(17)
+#define FIMC_REG_CISTATUS_LASTCAPT_END		BIT(16)
+#define FIMC_REG_CISTATUS_VVALID_A		BIT(15)
+#define FIMC_REG_CISTATUS_VVALID_B		BIT(14)
 
 /* Indexes to the last and the currently processed buffer. */
 #define FIMC_REG_CISTATUS2			0x68
 
 /* Image capture control */
 #define FIMC_REG_CIIMGCPT			0xc0
-#define FIMC_REG_CIIMGCPT_IMGCPTEN		(1 << 31)
-#define FIMC_REG_CIIMGCPT_IMGCPTEN_SC		(1 << 30)
-#define FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE	(1 << 25)
-#define FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT		(1 << 18)
+#define FIMC_REG_CIIMGCPT_IMGCPTEN		BIT(31)
+#define FIMC_REG_CIIMGCPT_IMGCPTEN_SC		BIT(30)
+#define FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE	BIT(25)
+#define FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT		BIT(18)
 
 /* Frame capture sequence */
 #define FIMC_REG_CICPTSEQ			0xc4
 
 /* Image effect */
 #define FIMC_REG_CIIMGEFF			0xd0
-#define FIMC_REG_CIIMGEFF_IE_ENABLE		(1 << 30)
+#define FIMC_REG_CIIMGEFF_IE_ENABLE		BIT(30)
 #define FIMC_REG_CIIMGEFF_IE_SC_BEFORE		(0 << 29)
 #define FIMC_REG_CIIMGEFF_IE_SC_AFTER		(1 << 29)
 #define FIMC_REG_CIIMGEFF_FIN_BYPASS		(0 << 26)
@@ -198,8 +200,8 @@
 
 /* Real input DMA image size */
 #define FIMC_REG_CIREAL_ISIZE			0xf8
-#define FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN	(1 << 31)
-#define FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS	(1 << 30)
+#define FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN	BIT(31)
+#define FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS	BIT(30)
 
 /* Input DMA control */
 #define FIMC_REG_MSCTRL				0xfc
@@ -215,7 +217,7 @@
 #define FIMC_REG_MSCTRL_FLIP_X_MIRROR		(1 << 13)
 #define FIMC_REG_MSCTRL_FLIP_Y_MIRROR		(2 << 13)
 #define FIMC_REG_MSCTRL_FLIP_180		(3 << 13)
-#define FIMC_REG_MSCTRL_FIFO_CTRL_FULL		(1 << 12)
+#define FIMC_REG_MSCTRL_FIFO_CTRL_FULL		BIT(12)
 #define FIMC_REG_MSCTRL_ORDER422_SHIFT		4
 #define FIMC_REG_MSCTRL_ORDER422_CRYCBY		(0 << 4)
 #define FIMC_REG_MSCTRL_ORDER422_YCRYCB		(1 << 4)
@@ -223,14 +225,14 @@
 #define FIMC_REG_MSCTRL_ORDER422_YCBYCR		(3 << 4)
 #define FIMC_REG_MSCTRL_ORDER422_MASK		(3 << 4)
 #define FIMC_REG_MSCTRL_INPUT_EXTCAM		(0 << 3)
-#define FIMC_REG_MSCTRL_INPUT_MEMORY		(1 << 3)
-#define FIMC_REG_MSCTRL_INPUT_MASK		(1 << 3)
+#define FIMC_REG_MSCTRL_INPUT_MEMORY		BIT(3)
+#define FIMC_REG_MSCTRL_INPUT_MASK		BIT(3)
 #define FIMC_REG_MSCTRL_INFORMAT_YCBCR420	(0 << 1)
 #define FIMC_REG_MSCTRL_INFORMAT_YCBCR422	(1 << 1)
 #define FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P	(2 << 1)
 #define FIMC_REG_MSCTRL_INFORMAT_RGB		(3 << 1)
 #define FIMC_REG_MSCTRL_INFORMAT_MASK		(3 << 1)
-#define FIMC_REG_MSCTRL_ENVID			(1 << 0)
+#define FIMC_REG_MSCTRL_ENVID			BIT(0)
 #define FIMC_REG_MSCTRL_IN_BURST_COUNT(x)	((x) << 24)
 
 /* Output DMA Y/Cb/Cr offset */
@@ -277,10 +279,10 @@
 
 /* SYSREG ISP Writeback register address offsets */
 #define SYSREG_ISPBLK				0x020c
-#define SYSREG_ISPBLK_FIFORST_CAM_BLK		(1 << 7)
+#define SYSREG_ISPBLK_FIFORST_CAM_BLK		BIT(7)
 
 #define SYSREG_CAMBLK				0x0218
-#define SYSREG_CAMBLK_FIFORST_ISP		(1 << 15)
+#define SYSREG_CAMBLK_FIFORST_ISP		BIT(15)
 #define SYSREG_CAMBLK_ISPWB_FULL_EN		(7 << 20)
 
 /*
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index d53427a..a838189 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -501,6 +501,7 @@
 			continue;
 
 		ret = fimc_md_parse_port_node(fmd, port, index);
+		of_node_put(port);
 		if (ret < 0) {
 			of_node_put(node);
 			goto cleanup;
@@ -542,6 +543,7 @@
 	if (!np)
 		return -EINVAL;
 	of_property_read_u32(np, "reg", &reg);
+	of_node_put(np);
 	return reg - FIMC_INPUT_MIPI_CSI2_0;
 }
 
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index 3e9ac60..540151b 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -41,7 +41,7 @@
 /* CSIS global control */
 #define S5PCSIS_CTRL			0x00
 #define S5PCSIS_CTRL_DPDN_DEFAULT	(0 << 31)
-#define S5PCSIS_CTRL_DPDN_SWAP		(1 << 31)
+#define S5PCSIS_CTRL_DPDN_SWAP		(1UL << 31)
 #define S5PCSIS_CTRL_ALIGN_32BIT	(1 << 20)
 #define S5PCSIS_CTRL_UPDATE_SHADOW	(1 << 16)
 #define S5PCSIS_CTRL_WCLK_EXTCLK	(1 << 8)
@@ -65,7 +65,7 @@
 
 /* Interrupt mask */
 #define S5PCSIS_INTMSK			0x10
-#define S5PCSIS_INTMSK_EVEN_BEFORE	(1 << 31)
+#define S5PCSIS_INTMSK_EVEN_BEFORE	(1UL << 31)
 #define S5PCSIS_INTMSK_EVEN_AFTER	(1 << 30)
 #define S5PCSIS_INTMSK_ODD_BEFORE	(1 << 29)
 #define S5PCSIS_INTMSK_ODD_AFTER	(1 << 28)
@@ -83,7 +83,7 @@
 
 /* Interrupt source */
 #define S5PCSIS_INTSRC			0x14
-#define S5PCSIS_INTSRC_EVEN_BEFORE	(1 << 31)
+#define S5PCSIS_INTSRC_EVEN_BEFORE	(1UL << 31)
 #define S5PCSIS_INTSRC_EVEN_AFTER	(1 << 30)
 #define S5PCSIS_INTSRC_EVEN		(0x3 << 30)
 #define S5PCSIS_INTSRC_ODD_BEFORE	(1 << 29)
@@ -803,10 +803,8 @@
 		return PTR_ERR(state->regs);
 
 	state->irq = platform_get_irq(pdev, 0);
-	if (state->irq < 0) {
-		dev_err(dev, "Failed to get irq\n");
+	if (state->irq < 0)
 		return state->irq;
-	}
 
 	for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
 		state->supplies[i].supply = csis_supply_name[i];
diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c
index 691be78..81a8fae 100644
--- a/drivers/media/platform/fsl-viu.c
+++ b/drivers/media/platform/fsl-viu.c
@@ -32,7 +32,7 @@
 #define VIU_VERSION		"0.5.1"
 
 /* Allow building this driver with COMPILE_TEST */
-#ifndef CONFIG_PPC
+#if !defined(CONFIG_PPC) && !defined(CONFIG_MICROBLAZE)
 #define out_be32(v, a)	iowrite32be(a, (void __iomem *)v)
 #define in_be32(a)	ioread32be((void __iomem *)a)
 #endif
@@ -214,7 +214,7 @@
 	FIELD_NO		= 0x01 << 28,	/* Field number */
 	DITHER_ON		= 0x01 << 29,	/* Dithering is on */
 	ROUND_ON		= 0x01 << 30,	/* Round is on */
-	MODE_32BIT		= 0x01 << 31,	/* Data in RGBa888,
+	MODE_32BIT		= 1UL << 31,	/* Data in RGBa888,
 						 * 0 in RGB565
 						 */
 };
@@ -563,11 +563,6 @@
 	strscpy(cap->driver, "viu", sizeof(cap->driver));
 	strscpy(cap->card, "viu", sizeof(cap->card));
 	strscpy(cap->bus_info, "platform:viu", sizeof(cap->bus_info));
-	cap->device_caps =	V4L2_CAP_VIDEO_CAPTURE |
-				V4L2_CAP_STREAMING     |
-				V4L2_CAP_VIDEO_OVERLAY |
-				V4L2_CAP_READWRITE;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -1380,6 +1375,8 @@
 	.release	= video_device_release,
 
 	.tvnorms        = V4L2_STD_NTSC_M | V4L2_STD_PAL,
+	.device_caps	= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+			  V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_READWRITE,
 };
 
 static int viu_of_probe(struct platform_device *op)
diff --git a/drivers/media/platform/imx-pxp.c b/drivers/media/platform/imx-pxp.c
index 8e7ef23..38d9423 100644
--- a/drivers/media/platform/imx-pxp.c
+++ b/drivers/media/platform/imx-pxp.c
@@ -1661,10 +1661,8 @@
 	}
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "Failed to get irq resource: %d\n", irq);
+	if (irq < 0)
 		return irq;
-	}
 
 	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, pxp_irq_handler,
 			IRQF_ONESHOT, dev_name(&pdev->dev), dev);
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index beb7fd7..9ad24c8 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -37,7 +37,6 @@
 	v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
 
 struct deinterlace_fmt {
-	char	*name;
 	u32	fourcc;
 	/* Types the format can be used for */
 	u32	types;
@@ -45,12 +44,10 @@
 
 static struct deinterlace_fmt formats[] = {
 	{
-		.name	= "YUV 4:2:0 Planar",
 		.fourcc	= V4L2_PIX_FMT_YUV420,
 		.types	= MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
 	},
 	{
-		.name	= "YUYV 4:2:2",
 		.fourcc	= V4L2_PIX_FMT_YUYV,
 		.types	= MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
 	},
@@ -135,13 +132,13 @@
 };
 
 struct deinterlace_ctx {
+	struct v4l2_fh		fh;
 	struct deinterlace_dev	*dev;
 
 	/* Abort requested by m2m */
 	int			aborting;
 	enum v4l2_colorspace	colorspace;
 	dma_cookie_t		cookie;
-	struct v4l2_m2m_ctx	*m2m_ctx;
 	struct dma_interleaved_template *xt;
 };
 
@@ -153,9 +150,9 @@
 	struct deinterlace_ctx *ctx = priv;
 	struct deinterlace_dev *pcdev = ctx->dev;
 
-	if ((v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) > 0)
-	    && (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) > 0)
-	    && (atomic_read(&ctx->dev->busy) == 0)) {
+	if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) > 0 &&
+	    v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) > 0 &&
+	    !atomic_read(&ctx->dev->busy)) {
 		dprintk(pcdev, "Task ready\n");
 		return 1;
 	}
@@ -174,7 +171,7 @@
 
 	dprintk(pcdev, "Aborting task\n");
 
-	v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx);
+	v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->fh.m2m_ctx);
 }
 
 static void dma_callback(void *data)
@@ -185,8 +182,8 @@
 
 	atomic_set(&pcdev->busy, 0);
 
-	src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
-	dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
+	src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
+	dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
 
 	dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
 	dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
@@ -197,7 +194,7 @@
 	v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
 	v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
 
-	v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx);
+	v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->fh.m2m_ctx);
 
 	dprintk(pcdev, "dma transfers completed.\n");
 }
@@ -216,8 +213,8 @@
 	dma_addr_t p_in, p_out;
 	enum dma_ctrl_flags flags;
 
-	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
-	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 
 	s_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT);
 	s_width	= s_q_data->width;
@@ -436,16 +433,7 @@
 {
 	strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));
 	strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));
-	strscpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->card));
-	/*
-	 * This is only a mem-to-mem video device. The capture and output
-	 * device capability flags are left only for backward compatibility
-	 * and are scheduled for removal.
-	 */
-	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
-			   V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-
+	strscpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info));
 	return 0;
 }
 
@@ -470,7 +458,6 @@
 	if (i < NUM_FORMATS) {
 		/* Format found */
 		fmt = &formats[i];
-		strscpy(f->description, fmt->name, sizeof(f->description));
 		f->pixelformat = fmt->fourcc;
 		return 0;
 	}
@@ -496,7 +483,7 @@
 	struct vb2_queue *vq;
 	struct deinterlace_q_data *q_data;
 
-	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
 	if (!vq)
 		return -EINVAL;
 
@@ -593,7 +580,7 @@
 	struct deinterlace_q_data *q_data;
 	struct vb2_queue *vq;
 
-	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
 	if (!vq)
 		return -EINVAL;
 
@@ -666,36 +653,6 @@
 	return ret;
 }
 
-static int vidioc_reqbufs(struct file *file, void *priv,
-			  struct v4l2_requestbuffers *reqbufs)
-{
-	struct deinterlace_ctx *ctx = priv;
-
-	return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
-			   struct v4l2_buffer *buf)
-{
-	struct deinterlace_ctx *ctx = priv;
-
-	return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-	struct deinterlace_ctx *ctx = priv;
-
-	return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-	struct deinterlace_ctx *ctx = priv;
-
-	return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
-}
-
 static int vidioc_streamon(struct file *file, void *priv,
 			   enum v4l2_buf_type type)
 {
@@ -736,15 +693,7 @@
 		return -EINVAL;
 	}
 
-	return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv,
-			    enum v4l2_buf_type type)
-{
-	struct deinterlace_ctx *ctx = priv;
-
-	return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
+	return v4l2_m2m_streamon(file, ctx->fh.m2m_ctx, type);
 }
 
 static const struct v4l2_ioctl_ops deinterlace_ioctl_ops = {
@@ -760,14 +709,15 @@
 	.vidioc_try_fmt_vid_out	= vidioc_try_fmt_vid_out,
 	.vidioc_s_fmt_vid_out	= vidioc_s_fmt_vid_out,
 
-	.vidioc_reqbufs		= vidioc_reqbufs,
-	.vidioc_querybuf	= vidioc_querybuf,
-
-	.vidioc_qbuf		= vidioc_qbuf,
-	.vidioc_dqbuf		= vidioc_dqbuf,
+	.vidioc_reqbufs		= v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querybuf	= v4l2_m2m_ioctl_querybuf,
+	.vidioc_qbuf		= v4l2_m2m_ioctl_qbuf,
+	.vidioc_dqbuf		= v4l2_m2m_ioctl_dqbuf,
+	.vidioc_prepare_buf	= v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_expbuf		= v4l2_m2m_ioctl_expbuf,
 
 	.vidioc_streamon	= vidioc_streamon,
-	.vidioc_streamoff	= vidioc_streamoff,
+	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,
 };
 
 
@@ -831,7 +781,7 @@
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct deinterlace_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 
-	v4l2_m2m_buf_queue(ctx->m2m_ctx, vbuf);
+	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
 }
 
 static const struct vb2_ops deinterlace_qops = {
@@ -849,7 +799,7 @@
 	int ret;
 
 	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
 	src_vq->drv_priv = ctx;
 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	src_vq->ops = &deinterlace_qops;
@@ -868,7 +818,7 @@
 		return ret;
 
 	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
 	dst_vq->drv_priv = ctx;
 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	dst_vq->ops = &deinterlace_qops;
@@ -897,12 +847,13 @@
 	if (!ctx)
 		return -ENOMEM;
 
-	file->private_data = ctx;
+	v4l2_fh_init(&ctx->fh, video_devdata(file));
+	file->private_data = &ctx->fh;
 	ctx->dev = pcdev;
 
-	ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
-	if (IS_ERR(ctx->m2m_ctx)) {
-		int ret = PTR_ERR(ctx->m2m_ctx);
+	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
+	if (IS_ERR(ctx->fh.m2m_ctx)) {
+		int ret = PTR_ERR(ctx->fh.m2m_ctx);
 
 		kfree(ctx);
 		return ret;
@@ -916,8 +867,10 @@
 	}
 
 	ctx->colorspace = V4L2_COLORSPACE_REC709;
+	v4l2_fh_add(&ctx->fh);
 
-	dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
+	dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n",
+		ctx, ctx->fh.m2m_ctx);
 
 	return 0;
 }
@@ -929,40 +882,22 @@
 
 	dprintk(pcdev, "Releasing instance %p\n", ctx);
 
-	v4l2_m2m_ctx_release(ctx->m2m_ctx);
+	v4l2_fh_del(&ctx->fh);
+	v4l2_fh_exit(&ctx->fh);
+	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
 	kfree(ctx->xt);
 	kfree(ctx);
 
 	return 0;
 }
 
-static __poll_t deinterlace_poll(struct file *file,
-				 struct poll_table_struct *wait)
-{
-	struct deinterlace_ctx *ctx = file->private_data;
-	__poll_t ret;
-
-	mutex_lock(&ctx->dev->dev_mutex);
-	ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
-	mutex_unlock(&ctx->dev->dev_mutex);
-
-	return ret;
-}
-
-static int deinterlace_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct deinterlace_ctx *ctx = file->private_data;
-
-	return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
-}
-
 static const struct v4l2_file_operations deinterlace_fops = {
 	.owner		= THIS_MODULE,
 	.open		= deinterlace_open,
 	.release	= deinterlace_release,
-	.poll		= deinterlace_poll,
+	.poll		= v4l2_m2m_fop_poll,
 	.unlocked_ioctl	= video_ioctl2,
-	.mmap		= deinterlace_mmap,
+	.mmap		= v4l2_m2m_fop_mmap,
 };
 
 static const struct video_device deinterlace_videodev = {
@@ -972,6 +907,7 @@
 	.minor		= -1,
 	.release	= video_device_release_empty,
 	.vfl_dir	= VFL_DIR_M2M,
+	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
 };
 
 static const struct v4l2_m2m_ops m2m_ops = {
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index dc30c48..803baf9 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -98,56 +98,48 @@
 	container_of(notifier, struct mcam_camera, notifier)
 
 static struct mcam_format_struct {
-	__u8 *desc;
 	__u32 pixelformat;
 	int bpp;   /* Bytes per pixel */
 	bool planar;
 	u32 mbus_code;
 } mcam_formats[] = {
 	{
-		.desc		= "YUYV 4:2:2",
 		.pixelformat	= V4L2_PIX_FMT_YUYV,
 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
 		.bpp		= 2,
 		.planar		= false,
 	},
 	{
-		.desc		= "YVYU 4:2:2",
 		.pixelformat	= V4L2_PIX_FMT_YVYU,
 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
 		.bpp		= 2,
 		.planar		= false,
 	},
 	{
-		.desc		= "YUV 4:2:0 PLANAR",
 		.pixelformat	= V4L2_PIX_FMT_YUV420,
 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
 		.bpp		= 1,
 		.planar		= true,
 	},
 	{
-		.desc		= "YVU 4:2:0 PLANAR",
 		.pixelformat	= V4L2_PIX_FMT_YVU420,
 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
 		.bpp		= 1,
 		.planar		= true,
 	},
 	{
-		.desc		= "XRGB 444",
 		.pixelformat	= V4L2_PIX_FMT_XRGB444,
 		.mbus_code	= MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE,
 		.bpp		= 2,
 		.planar		= false,
 	},
 	{
-		.desc		= "RGB 565",
 		.pixelformat	= V4L2_PIX_FMT_RGB565,
 		.mbus_code	= MEDIA_BUS_FMT_RGB565_2X8_LE,
 		.bpp		= 2,
 		.planar		= false,
 	},
 	{
-		.desc		= "Raw RGB Bayer",
 		.pixelformat	= V4L2_PIX_FMT_SBGGR8,
 		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
 		.bpp		= 1,
@@ -1357,9 +1349,6 @@
 	strscpy(cap->driver, "marvell_ccic", sizeof(cap->driver));
 	strscpy(cap->card, "marvell_ccic", sizeof(cap->card));
 	strscpy(cap->bus_info, cam->bus_info, sizeof(cap->bus_info));
-	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
-		V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -1369,8 +1358,6 @@
 {
 	if (fmt->index >= N_MCAM_FMTS)
 		return -EINVAL;
-	strscpy(fmt->description, mcam_formats[fmt->index].desc,
-		sizeof(fmt->description));
 	fmt->pixelformat = mcam_formats[fmt->index].pixelformat;
 	return 0;
 }
@@ -1698,6 +1685,8 @@
 	.fops = &mcam_v4l_fops,
 	.ioctl_ops = &mcam_v4l_ioctl_ops,
 	.release = video_device_release_empty,
+	.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
+		       V4L2_CAP_STREAMING,
 };
 
 /* ---------------------------------------------------------------------- */
diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c
index 1055949..92b9225 100644
--- a/drivers/media/platform/marvell-ccic/mmp-driver.c
+++ b/drivers/media/platform/marvell-ccic/mmp-driver.c
@@ -372,6 +372,7 @@
 	{ .compatible = "marvell,mmp2-ccic", },
 	{},
 };
+MODULE_DEVICE_TABLE(of, mmpcam_of_match);
 
 static struct platform_driver mmpcam_driver = {
 	.probe		= mmpcam_probe,
diff --git a/drivers/media/platform/meson/ao-cec-g12a.c b/drivers/media/platform/meson/ao-cec-g12a.c
index fb52e5d..3b39e87 100644
--- a/drivers/media/platform/meson/ao-cec-g12a.c
+++ b/drivers/media/platform/meson/ao-cec-g12a.c
@@ -121,6 +121,9 @@
 #define CECB_CTRL_TYPE_NEXT	2
 
 #define CECB_CTRL2		0x01
+
+#define CECB_CTRL2_RISE_DEL_MAX	GENMASK(4, 0)
+
 #define CECB_INTR_MASK		0x02
 #define CECB_LADD_LOW		0x05
 #define CECB_LADD_HIGH		0x06
@@ -165,6 +168,11 @@
 
 #define CECB_WAKEUPCTRL		0x31
 
+struct meson_ao_cec_g12a_data {
+	/* Setup the internal CECB_CTRL2 register */
+	bool				ctrl2_setup;
+};
+
 struct meson_ao_cec_g12a_device {
 	struct platform_device		*pdev;
 	struct regmap			*regmap;
@@ -175,6 +183,7 @@
 	struct cec_msg			rx_msg;
 	struct clk			*oscin;
 	struct clk			*core;
+	const struct meson_ao_cec_g12a_data *data;
 };
 
 static const struct regmap_config meson_ao_cec_g12a_regmap_conf = {
@@ -605,6 +614,10 @@
 	regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
 			   CECB_GEN_CNTL_RESET, 0);
 
+	if (ao_cec->data->ctrl2_setup)
+		regmap_write(ao_cec->regmap_cec, CECB_CTRL2,
+			     FIELD_PREP(CECB_CTRL2_RISE_DEL_MAX, 2));
+
 	meson_ao_cec_g12a_irq_setup(ao_cec, true);
 
 	return 0;
@@ -632,20 +645,28 @@
 	if (!ao_cec)
 		return -ENOMEM;
 
+	ao_cec->data = of_device_get_match_data(&pdev->dev);
+	if (!ao_cec->data) {
+		dev_err(&pdev->dev, "failed to get match data\n");
+		return -ENODEV;
+	}
+
 	spin_lock_init(&ao_cec->cec_reg_lock);
 	ao_cec->pdev = pdev;
 
-	ao_cec->notify = cec_notifier_get(hdmi_dev);
-	if (!ao_cec->notify)
-		return -ENOMEM;
-
 	ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_g12a_ops, ao_cec,
 					    "meson_g12a_ao_cec",
-					    CEC_CAP_DEFAULTS,
+					    CEC_CAP_DEFAULTS |
+					    CEC_CAP_CONNECTOR_INFO,
 					    CEC_MAX_LOG_ADDRS);
-	if (IS_ERR(ao_cec->adap)) {
-		ret = PTR_ERR(ao_cec->adap);
-		goto out_probe_notify;
+	if (IS_ERR(ao_cec->adap))
+		return PTR_ERR(ao_cec->adap);
+
+	ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+							ao_cec->adap);
+	if (!ao_cec->notify) {
+		ret = -ENOMEM;
+		goto out_probe_adapter;
 	}
 
 	ao_cec->adap->owner = THIS_MODULE;
@@ -654,21 +675,21 @@
 	base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(base)) {
 		ret = PTR_ERR(base);
-		goto out_probe_adapter;
+		goto out_probe_notify;
 	}
 
 	ao_cec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
 					       &meson_ao_cec_g12a_regmap_conf);
 	if (IS_ERR(ao_cec->regmap)) {
 		ret = PTR_ERR(ao_cec->regmap);
-		goto out_probe_adapter;
+		goto out_probe_notify;
 	}
 
 	ao_cec->regmap_cec = devm_regmap_init(&pdev->dev, NULL, ao_cec,
 					   &meson_ao_cec_g12a_cec_regmap_conf);
 	if (IS_ERR(ao_cec->regmap_cec)) {
 		ret = PTR_ERR(ao_cec->regmap_cec);
-		goto out_probe_adapter;
+		goto out_probe_notify;
 	}
 
 	irq = platform_get_irq(pdev, 0);
@@ -678,24 +699,24 @@
 					0, NULL, ao_cec);
 	if (ret) {
 		dev_err(&pdev->dev, "irq request failed\n");
-		goto out_probe_adapter;
+		goto out_probe_notify;
 	}
 
 	ao_cec->oscin = devm_clk_get(&pdev->dev, "oscin");
 	if (IS_ERR(ao_cec->oscin)) {
 		dev_err(&pdev->dev, "oscin clock request failed\n");
 		ret = PTR_ERR(ao_cec->oscin);
-		goto out_probe_adapter;
+		goto out_probe_notify;
 	}
 
 	ret = meson_ao_cec_g12a_setup_clk(ao_cec);
 	if (ret)
-		goto out_probe_adapter;
+		goto out_probe_notify;
 
 	ret = clk_prepare_enable(ao_cec->core);
 	if (ret) {
 		dev_err(&pdev->dev, "core clock enable failed\n");
-		goto out_probe_adapter;
+		goto out_probe_notify;
 	}
 
 	device_reset_optional(&pdev->dev);
@@ -703,27 +724,23 @@
 	platform_set_drvdata(pdev, ao_cec);
 
 	ret = cec_register_adapter(ao_cec->adap, &pdev->dev);
-	if (ret < 0) {
-		cec_notifier_put(ao_cec->notify);
+	if (ret < 0)
 		goto out_probe_core_clk;
-	}
 
 	/* Setup Hardware */
 	regmap_write(ao_cec->regmap, CECB_GEN_CNTL_REG, CECB_GEN_CNTL_RESET);
 
-	cec_register_cec_notifier(ao_cec->adap, ao_cec->notify);
-
 	return 0;
 
 out_probe_core_clk:
 	clk_disable_unprepare(ao_cec->core);
 
+out_probe_notify:
+	cec_notifier_cec_adap_unregister(ao_cec->notify);
+
 out_probe_adapter:
 	cec_delete_adapter(ao_cec->adap);
 
-out_probe_notify:
-	cec_notifier_put(ao_cec->notify);
-
 	dev_err(&pdev->dev, "CEC controller registration failed\n");
 
 	return ret;
@@ -735,15 +752,30 @@
 
 	clk_disable_unprepare(ao_cec->core);
 
-	cec_unregister_adapter(ao_cec->adap);
+	cec_notifier_cec_adap_unregister(ao_cec->notify);
 
-	cec_notifier_put(ao_cec->notify);
+	cec_unregister_adapter(ao_cec->adap);
 
 	return 0;
 }
 
+static const struct meson_ao_cec_g12a_data ao_cec_g12a_data = {
+	.ctrl2_setup = false,
+};
+
+static const struct meson_ao_cec_g12a_data ao_cec_sm1_data = {
+	.ctrl2_setup = true,
+};
+
 static const struct of_device_id meson_ao_cec_g12a_of_match[] = {
-	{ .compatible = "amlogic,meson-g12a-ao-cec", },
+	{
+		.compatible = "amlogic,meson-g12a-ao-cec",
+		.data = &ao_cec_g12a_data,
+	},
+	{
+		.compatible = "amlogic,meson-sm1-ao-cec",
+		.data = &ao_cec_sm1_data,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, meson_ao_cec_g12a_of_match);
diff --git a/drivers/media/platform/meson/ao-cec.c b/drivers/media/platform/meson/ao-cec.c
index facf9b0..64ed549 100644
--- a/drivers/media/platform/meson/ao-cec.c
+++ b/drivers/media/platform/meson/ao-cec.c
@@ -616,20 +616,19 @@
 
 	spin_lock_init(&ao_cec->cec_reg_lock);
 
-	ao_cec->notify = cec_notifier_get(hdmi_dev);
-	if (!ao_cec->notify)
-		return -ENOMEM;
-
 	ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_ops, ao_cec,
 					    "meson_ao_cec",
-					    CEC_CAP_LOG_ADDRS |
-					    CEC_CAP_TRANSMIT |
-					    CEC_CAP_RC |
-					    CEC_CAP_PASSTHROUGH,
+					    CEC_CAP_DEFAULTS |
+					    CEC_CAP_CONNECTOR_INFO,
 					    1); /* Use 1 for now */
-	if (IS_ERR(ao_cec->adap)) {
-		ret = PTR_ERR(ao_cec->adap);
-		goto out_probe_notify;
+	if (IS_ERR(ao_cec->adap))
+		return PTR_ERR(ao_cec->adap);
+
+	ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+							ao_cec->adap);
+	if (!ao_cec->notify) {
+		ret = -ENOMEM;
+		goto out_probe_adapter;
 	}
 
 	ao_cec->adap->owner = THIS_MODULE;
@@ -638,7 +637,7 @@
 	ao_cec->base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(ao_cec->base)) {
 		ret = PTR_ERR(ao_cec->base);
-		goto out_probe_adapter;
+		goto out_probe_notify;
 	}
 
 	irq = platform_get_irq(pdev, 0);
@@ -648,20 +647,20 @@
 					0, NULL, ao_cec);
 	if (ret) {
 		dev_err(&pdev->dev, "irq request failed\n");
-		goto out_probe_adapter;
+		goto out_probe_notify;
 	}
 
 	ao_cec->core = devm_clk_get(&pdev->dev, "core");
 	if (IS_ERR(ao_cec->core)) {
 		dev_err(&pdev->dev, "core clock request failed\n");
 		ret = PTR_ERR(ao_cec->core);
-		goto out_probe_adapter;
+		goto out_probe_notify;
 	}
 
 	ret = clk_prepare_enable(ao_cec->core);
 	if (ret) {
 		dev_err(&pdev->dev, "core clock enable failed\n");
-		goto out_probe_adapter;
+		goto out_probe_notify;
 	}
 
 	ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE);
@@ -676,28 +675,24 @@
 	platform_set_drvdata(pdev, ao_cec);
 
 	ret = cec_register_adapter(ao_cec->adap, &pdev->dev);
-	if (ret < 0) {
-		cec_notifier_put(ao_cec->notify);
+	if (ret < 0)
 		goto out_probe_clk;
-	}
 
 	/* Setup Hardware */
 	writel_relaxed(CEC_GEN_CNTL_RESET,
 		       ao_cec->base + CEC_GEN_CNTL_REG);
 
-	cec_register_cec_notifier(ao_cec->adap, ao_cec->notify);
-
 	return 0;
 
 out_probe_clk:
 	clk_disable_unprepare(ao_cec->core);
 
+out_probe_notify:
+	cec_notifier_cec_adap_unregister(ao_cec->notify);
+
 out_probe_adapter:
 	cec_delete_adapter(ao_cec->adap);
 
-out_probe_notify:
-	cec_notifier_put(ao_cec->notify);
-
 	dev_err(&pdev->dev, "CEC controller registration failed\n");
 
 	return ret;
@@ -709,10 +704,9 @@
 
 	clk_disable_unprepare(ao_cec->core);
 
+	cec_notifier_cec_adap_unregister(ao_cec->notify);
 	cec_unregister_adapter(ao_cec->adap);
 
-	cec_notifier_put(ao_cec->notify);
-
 	return 0;
 }
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index fc9faec..c1e29a4 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -110,7 +110,9 @@
 	mutex_init(&mdp->vpulock);
 
 	/* Old dts had the components as child nodes */
-	if (of_get_next_child(dev->of_node, NULL)) {
+	node = of_get_next_child(dev->of_node, NULL);
+	if (node) {
+		of_node_put(node);
 		parent = dev->of_node;
 		dev_warn(dev, "device tree is out of date\n");
 	} else {
@@ -145,13 +147,16 @@
 		comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
 		if (!comp) {
 			ret = -ENOMEM;
+			of_node_put(node);
 			goto err_comp;
 		}
 		mdp->comp[comp_id] = comp;
 
 		ret = mtk_mdp_comp_init(dev, node, comp, comp_id);
-		if (ret)
+		if (ret) {
+			of_node_put(node);
 			goto err_comp;
+		}
 	}
 
 	mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 90d1a67..26a55c3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -29,16 +29,19 @@
 		.fourcc = V4L2_PIX_FMT_H264,
 		.type = MTK_FMT_DEC,
 		.num_planes = 1,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	},
 	{
 		.fourcc = V4L2_PIX_FMT_VP8,
 		.type = MTK_FMT_DEC,
 		.num_planes = 1,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	},
 	{
 		.fourcc = V4L2_PIX_FMT_VP9,
 		.type = MTK_FMT_DEC,
 		.num_planes = 1,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	},
 	{
 		.fourcc = V4L2_PIX_FMT_MT21C,
@@ -948,6 +951,7 @@
 
 	fmt = &mtk_video_formats[i];
 	f->pixelformat = fmt->fourcc;
+	f->flags = fmt->flags;
 
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index c95de5d..9fd56de 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -99,6 +99,7 @@
 	u32	fourcc;
 	enum mtk_fmt_type	type;
 	u32	num_planes;
+	u32	flags;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
index c5f8f1f..49aa85a 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
@@ -29,6 +29,9 @@
 #define H264_MAX_FB_NUM				17
 #define HDR_PARSING_BUF_SZ			1024
 
+#define DEC_ERR_RET(ret)			((ret) >> 16)
+#define H264_ERR_NOT_VALID			3
+
 /**
  * struct h264_fb - h264 decode frame buffer information
  * @vdec_fb_va  : virtual address of struct vdec_fb
@@ -357,8 +360,11 @@
 	buf = (unsigned char *)bs->va;
 	buf_sz = bs->size;
 	nal_start_idx = find_start_code(buf, buf_sz);
-	if (nal_start_idx < 0)
+	if (nal_start_idx < 0) {
+		mtk_vcodec_err(inst, "invalid nal start code");
+		err = -EIO;
 		goto err_free_fb_out;
+	}
 
 	nal_start = buf[nal_start_idx];
 	nal_type = NAL_TYPE(buf[nal_start_idx]);
@@ -382,8 +388,14 @@
 	data[0] = buf_sz;
 	data[1] = nal_start;
 	err = vpu_dec_start(vpu, data, 2);
-	if (err)
+	if (err) {
+		if (err > 0 && (DEC_ERR_RET(err) == H264_ERR_NOT_VALID)) {
+			mtk_vcodec_err(inst, "- error bitstream - err = %d -",
+				       err);
+			err = -EIO;
+		}
 		goto err_free_fb_out;
+	}
 
 	*res_chg = inst->vsi->dec.resolution_changed;
 	if (*res_chg) {
diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c
index 333324c..27779b7 100644
--- a/drivers/media/platform/mx2_emmaprp.c
+++ b/drivers/media/platform/mx2_emmaprp.c
@@ -120,7 +120,7 @@
 #define PRP_CNTL_RZ_FIFO_LEVEL(x)       ((x) << 27)
 #define PRP_CNTL_CH2B1EN        (1 << 29)
 #define PRP_CNTL_CH2B2EN        (1 << 30)
-#define PRP_CNTL_CH2FEN         (1 << 31)
+#define PRP_CNTL_CH2FEN         (1UL << 31)
 
 #define PRP_SIZE_HEIGHT(x)	(x)
 #define PRP_SIZE_WIDTH(x)	((x) << 16)
@@ -145,7 +145,6 @@
 #define PRP_INTR_ST_CH2OVF	(1 << 8)
 
 struct emmaprp_fmt {
-	char	*name;
 	u32	fourcc;
 	/* Types the format can be used for */
 	u32	types;
@@ -153,12 +152,10 @@
 
 static struct emmaprp_fmt formats[] = {
 	{
-		.name	= "YUV 4:2:0 Planar",
 		.fourcc	= V4L2_PIX_FMT_YUV420,
 		.types	= MEM2MEM_CAPTURE,
 	},
 	{
-		.name	= "4:2:2, packed, YUYV",
 		.fourcc	= V4L2_PIX_FMT_YUYV,
 		.types	= MEM2MEM_OUTPUT,
 	},
@@ -210,11 +207,11 @@
 };
 
 struct emmaprp_ctx {
+	struct v4l2_fh		fh;
 	struct emmaprp_dev	*dev;
 	/* Abort requested by m2m */
 	int			aborting;
 	struct emmaprp_q_data	q_data[2];
-	struct v4l2_m2m_ctx	*m2m_ctx;
 };
 
 static struct emmaprp_q_data *get_q_data(struct emmaprp_ctx *ctx,
@@ -243,7 +240,7 @@
 
 	dprintk(pcdev, "Aborting task\n");
 
-	v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx);
+	v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->fh.m2m_ctx);
 }
 
 static inline void emmaprp_dump_regs(struct emmaprp_dev *pcdev)
@@ -278,8 +275,8 @@
 	dma_addr_t p_in, p_out;
 	u32 tmp;
 
-	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
-	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
 
 	s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
 	s_width	= s_q_data->width;
@@ -353,8 +350,8 @@
 			pr_err("PrP bus error occurred, this transfer is probably corrupted\n");
 			writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL);
 		} else if (irqst & PRP_INTR_ST_CH2B1CI) { /* buffer ready */
-			src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
-			dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
+			src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
+			dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
 
 			dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
 			dst_vb->flags &=
@@ -371,7 +368,7 @@
 		}
 	}
 
-	v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx);
+	v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->fh.m2m_ctx);
 	return IRQ_HANDLED;
 }
 
@@ -383,8 +380,6 @@
 {
 	strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));
 	strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));
-	cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -409,7 +404,6 @@
 	if (i < NUM_FORMATS) {
 		/* Format found */
 		fmt = &formats[i];
-		strscpy(f->description, fmt->name, sizeof(f->description) - 1);
 		f->pixelformat = fmt->fourcc;
 		return 0;
 	}
@@ -435,7 +429,7 @@
 	struct vb2_queue *vq;
 	struct emmaprp_q_data *q_data;
 
-	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
 	if (!vq)
 		return -EINVAL;
 
@@ -540,7 +534,7 @@
 	struct vb2_queue *vq;
 	int ret;
 
-	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
 	if (!vq)
 		return -EINVAL;
 
@@ -596,52 +590,6 @@
 	return vidioc_s_fmt(priv, f);
 }
 
-static int vidioc_reqbufs(struct file *file, void *priv,
-			  struct v4l2_requestbuffers *reqbufs)
-{
-	struct emmaprp_ctx *ctx = priv;
-
-	return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv,
-			   struct v4l2_buffer *buf)
-{
-	struct emmaprp_ctx *ctx = priv;
-
-	return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-	struct emmaprp_ctx *ctx = priv;
-
-	return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
-{
-	struct emmaprp_ctx *ctx = priv;
-
-	return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
-}
-
-static int vidioc_streamon(struct file *file, void *priv,
-			   enum v4l2_buf_type type)
-{
-	struct emmaprp_ctx *ctx = priv;
-
-	return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv,
-			    enum v4l2_buf_type type)
-{
-	struct emmaprp_ctx *ctx = priv;
-
-	return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
-}
-
 static const struct v4l2_ioctl_ops emmaprp_ioctl_ops = {
 	.vidioc_querycap	= vidioc_querycap,
 
@@ -655,14 +603,14 @@
 	.vidioc_try_fmt_vid_out	= vidioc_try_fmt_vid_out,
 	.vidioc_s_fmt_vid_out	= vidioc_s_fmt_vid_out,
 
-	.vidioc_reqbufs		= vidioc_reqbufs,
-	.vidioc_querybuf	= vidioc_querybuf,
-
-	.vidioc_qbuf		= vidioc_qbuf,
-	.vidioc_dqbuf		= vidioc_dqbuf,
-
-	.vidioc_streamon	= vidioc_streamon,
-	.vidioc_streamoff	= vidioc_streamoff,
+	.vidioc_reqbufs		= v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querybuf	= v4l2_m2m_ioctl_querybuf,
+	.vidioc_qbuf		= v4l2_m2m_ioctl_qbuf,
+	.vidioc_dqbuf		= v4l2_m2m_ioctl_dqbuf,
+	.vidioc_prepare_buf	= v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_expbuf		= v4l2_m2m_ioctl_expbuf,
+	.vidioc_streamon	= v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff	= v4l2_m2m_ioctl_streamoff,
 };
 
 
@@ -722,7 +670,7 @@
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
-	v4l2_m2m_buf_queue(ctx->m2m_ctx, vbuf);
+	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
 }
 
 static const struct vb2_ops emmaprp_qops = {
@@ -740,7 +688,7 @@
 	int ret;
 
 	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+	src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
 	src_vq->drv_priv = ctx;
 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	src_vq->ops = &emmaprp_qops;
@@ -754,7 +702,7 @@
 		return ret;
 
 	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
 	dst_vq->drv_priv = ctx;
 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 	dst_vq->ops = &emmaprp_qops;
@@ -778,7 +726,8 @@
 	if (!ctx)
 		return -ENOMEM;
 
-	file->private_data = ctx;
+	v4l2_fh_init(&ctx->fh, video_devdata(file));
+	file->private_data = &ctx->fh;
 	ctx->dev = pcdev;
 
 	if (mutex_lock_interruptible(&pcdev->dev_mutex)) {
@@ -786,10 +735,10 @@
 		return -ERESTARTSYS;
 	}
 
-	ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
+	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
 
-	if (IS_ERR(ctx->m2m_ctx)) {
-		int ret = PTR_ERR(ctx->m2m_ctx);
+	if (IS_ERR(ctx->fh.m2m_ctx)) {
+		int ret = PTR_ERR(ctx->fh.m2m_ctx);
 
 		mutex_unlock(&pcdev->dev_mutex);
 		kfree(ctx);
@@ -800,9 +749,10 @@
 	clk_prepare_enable(pcdev->clk_emma_ahb);
 	ctx->q_data[V4L2_M2M_SRC].fmt = &formats[1];
 	ctx->q_data[V4L2_M2M_DST].fmt = &formats[0];
+	v4l2_fh_add(&ctx->fh);
 	mutex_unlock(&pcdev->dev_mutex);
 
-	dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
+	dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->fh.m2m_ctx);
 
 	return 0;
 }
@@ -817,46 +767,22 @@
 	mutex_lock(&pcdev->dev_mutex);
 	clk_disable_unprepare(pcdev->clk_emma_ahb);
 	clk_disable_unprepare(pcdev->clk_emma_ipg);
-	v4l2_m2m_ctx_release(ctx->m2m_ctx);
+	v4l2_fh_del(&ctx->fh);
+	v4l2_fh_exit(&ctx->fh);
+	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
 	mutex_unlock(&pcdev->dev_mutex);
 	kfree(ctx);
 
 	return 0;
 }
 
-static __poll_t emmaprp_poll(struct file *file,
-				 struct poll_table_struct *wait)
-{
-	struct emmaprp_dev *pcdev = video_drvdata(file);
-	struct emmaprp_ctx *ctx = file->private_data;
-	__poll_t res;
-
-	mutex_lock(&pcdev->dev_mutex);
-	res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
-	mutex_unlock(&pcdev->dev_mutex);
-	return res;
-}
-
-static int emmaprp_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct emmaprp_dev *pcdev = video_drvdata(file);
-	struct emmaprp_ctx *ctx = file->private_data;
-	int ret;
-
-	if (mutex_lock_interruptible(&pcdev->dev_mutex))
-		return -ERESTARTSYS;
-	ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
-	mutex_unlock(&pcdev->dev_mutex);
-	return ret;
-}
-
 static const struct v4l2_file_operations emmaprp_fops = {
 	.owner		= THIS_MODULE,
 	.open		= emmaprp_open,
 	.release	= emmaprp_release,
-	.poll		= emmaprp_poll,
+	.poll		= v4l2_m2m_fop_poll,
 	.unlocked_ioctl	= video_ioctl2,
-	.mmap		= emmaprp_mmap,
+	.mmap		= v4l2_m2m_fop_mmap,
 };
 
 static const struct video_device emmaprp_videodev = {
@@ -866,6 +792,7 @@
 	.minor		= -1,
 	.release	= video_device_release,
 	.vfl_dir	= VFL_DIR_M2M,
+	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
 };
 
 static const struct v4l2_m2m_ops m2m_ops = {
diff --git a/drivers/media/platform/omap/Kconfig b/drivers/media/platform/omap/Kconfig
index 1a99dff..f73b589 100644
--- a/drivers/media/platform/omap/Kconfig
+++ b/drivers/media/platform/omap/Kconfig
@@ -10,8 +10,7 @@
 	depends on FB_OMAP2 || (COMPILE_TEST && FB_OMAP2=n)
 	depends on ARCH_OMAP2 || ARCH_OMAP3 || COMPILE_TEST
 	depends on VIDEO_V4L2
-	select VIDEOBUF_GEN
-	select VIDEOBUF_DMA_CONTIG
+	select VIDEOBUF2_DMA_CONTIG
 	select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
 	select FRAME_VECTOR
 	help
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index cb6a9e3..513b99b 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -40,9 +40,9 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 
-#include <media/videobuf-dma-contig.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
 
 #include <video/omapvrfb.h>
 #include <video/omapfb_dss.h>
@@ -63,33 +63,12 @@
 	OMAP_VIDEO2,
 };
 
-static struct videobuf_queue_ops video_vbq_ops;
 /* Variables configurable through module params*/
-static u32 video1_numbuffers = 3;
-static u32 video2_numbuffers = 3;
-static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
-static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
 static bool vid1_static_vrfb_alloc;
 static bool vid2_static_vrfb_alloc;
 static bool debug;
 
 /* Module parameters */
-module_param(video1_numbuffers, uint, S_IRUGO);
-MODULE_PARM_DESC(video1_numbuffers,
-	"Number of buffers to be allocated at init time for Video1 device.");
-
-module_param(video2_numbuffers, uint, S_IRUGO);
-MODULE_PARM_DESC(video2_numbuffers,
-	"Number of buffers to be allocated at init time for Video2 device.");
-
-module_param(video1_bufsize, uint, S_IRUGO);
-MODULE_PARM_DESC(video1_bufsize,
-	"Size of the buffer to be allocated for video1 device");
-
-module_param(video2_bufsize, uint, S_IRUGO);
-MODULE_PARM_DESC(video2_bufsize,
-	"Size of the buffer to be allocated for video2 device");
-
 module_param(vid1_static_vrfb_alloc, bool, S_IRUGO);
 MODULE_PARM_DESC(vid1_static_vrfb_alloc,
 	"Static allocation of the VRFB buffer for video1 device");
@@ -114,14 +93,12 @@
 		 *      Byte 0                    Byte 1
 		 *      g2 g1 g0 b4 b3 b2 b1 b0   r4 r3 r2 r1 r0 g5 g4 g3
 		 */
-		.description = "RGB565, le",
 		.pixelformat = V4L2_PIX_FMT_RGB565,
 	},
 	{
 		/* Note:  V4L2 defines RGB32 as: RGB-8-8-8-8  we use
 		 *  this for RGB24 unpack mode, the last 8 bits are ignored
 		 * */
-		.description = "RGB32, le",
 		.pixelformat = V4L2_PIX_FMT_RGB32,
 	},
 	{
@@ -129,15 +106,12 @@
 		 *        this for RGB24 packed mode
 		 *
 		 */
-		.description = "RGB24, le",
 		.pixelformat = V4L2_PIX_FMT_RGB24,
 	},
 	{
-		.description = "YUYV (YUV 4:2:2), packed",
 		.pixelformat = V4L2_PIX_FMT_YUYV,
 	},
 	{
-		.description = "UYVY, packed",
 		.pixelformat = V4L2_PIX_FMT_UYVY,
 	},
 };
@@ -164,13 +138,13 @@
 		ifmt = 0;
 
 	pix->pixelformat = omap_formats[ifmt].pixelformat;
-	pix->field = V4L2_FIELD_ANY;
+	pix->field = V4L2_FIELD_NONE;
 
 	switch (pix->pixelformat) {
 	case V4L2_PIX_FMT_YUYV:
 	case V4L2_PIX_FMT_UYVY:
 	default:
-		pix->colorspace = V4L2_COLORSPACE_JPEG;
+		pix->colorspace = V4L2_COLORSPACE_SRGB;
 		bpp = YUYV_BPP;
 		break;
 	case V4L2_PIX_FMT_RGB565:
@@ -195,56 +169,6 @@
 }
 
 /*
- * omap_vout_get_userptr: Convert user space virtual address to physical
- * address.
- */
-static int omap_vout_get_userptr(struct videobuf_buffer *vb, long virtp,
-				 u32 *physp)
-{
-	struct frame_vector *vec;
-	int ret;
-
-	/* For kernel direct-mapped memory, take the easy way */
-	if (virtp >= PAGE_OFFSET) {
-		*physp = virt_to_phys((void *)virtp);
-		return 0;
-	}
-
-	vec = frame_vector_create(1);
-	if (!vec)
-		return -ENOMEM;
-
-	ret = get_vaddr_frames(virtp, 1, FOLL_WRITE, vec);
-	if (ret != 1) {
-		frame_vector_destroy(vec);
-		return -EINVAL;
-	}
-	*physp = __pfn_to_phys(frame_vector_pfns(vec)[0]);
-	vb->priv = vec;
-
-	return 0;
-}
-
-/*
- * Free the V4L2 buffers
- */
-void omap_vout_free_buffers(struct omap_vout_device *vout)
-{
-	int i, numbuffers;
-
-	/* Allocate memory for the buffers */
-	numbuffers = (vout->vid) ?  video2_numbuffers : video1_numbuffers;
-	vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize;
-
-	for (i = 0; i < numbuffers; i++) {
-		omap_vout_free_buffer(vout->buf_virt_addr[i],
-				vout->buffer_size);
-		vout->buf_phy_addr[i] = 0;
-		vout->buf_virt_addr[i] = 0;
-	}
-}
-
-/*
  * Convert V4L2 rotation to DSS rotation
  *	V4L2 understand 0, 90, 180, 270.
  *	Convert to 0, 1, 2 and 3 respectively for DSS
@@ -537,9 +461,9 @@
 		if (vout->cur_frm == vout->next_frm)
 			goto err;
 
-		vout->cur_frm->ts = ts;
-		vout->cur_frm->state = VIDEOBUF_DONE;
-		wake_up_interruptible(&vout->cur_frm->done);
+		vout->cur_frm->vbuf.vb2_buf.timestamp = ts;
+		vout->cur_frm->vbuf.sequence = vout->sequence++;
+		vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_DONE);
 		vout->cur_frm = vout->next_frm;
 	} else {
 		if (list_empty(&vout->dma_queue) ||
@@ -562,9 +486,6 @@
 	struct omap_dss_device *cur_display;
 	struct omap_vout_device *vout = (struct omap_vout_device *)arg;
 
-	if (!vout->streaming)
-		return;
-
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
 
@@ -608,9 +529,9 @@
 	}
 
 	if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
-		vout->cur_frm->ts = ts;
-		vout->cur_frm->state = VIDEOBUF_DONE;
-		wake_up_interruptible(&vout->cur_frm->done);
+		vout->cur_frm->vbuf.vb2_buf.timestamp = ts;
+		vout->cur_frm->vbuf.sequence = vout->sequence++;
+		vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_DONE);
 		vout->cur_frm = vout->next_frm;
 	}
 
@@ -619,12 +540,10 @@
 		goto vout_isr_err;
 
 	vout->next_frm = list_entry(vout->dma_queue.next,
-			struct videobuf_buffer, queue);
+			struct omap_vout_buffer, queue);
 	list_del(&vout->next_frm->queue);
 
-	vout->next_frm->state = VIDEOBUF_ACTIVE;
-
-	addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
+	addr = (unsigned long)vout->queued_buf_addr[vout->next_frm->vbuf.vb2_buf.index]
 		+ vout->cropped_offset;
 
 	/* First save the configuration in ovelray structure */
@@ -644,394 +563,6 @@
 	spin_unlock(&vout->vbq_lock);
 }
 
-/* Video buffer call backs */
-
-/*
- * Buffer setup function is called by videobuf layer when REQBUF ioctl is
- * called. This is used to setup buffers and return size and count of
- * buffers allocated. After the call to this buffer, videobuf layer will
- * setup buffer queue depending on the size and count of buffers
- */
-static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
-			  unsigned int *size)
-{
-	int startindex = 0, i, j;
-	u32 phy_addr = 0, virt_addr = 0;
-	struct omap_vout_device *vout = q->priv_data;
-	struct omapvideo_info *ovid = &vout->vid_info;
-	int vid_max_buf_size;
-
-	if (!vout)
-		return -EINVAL;
-
-	vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize :
-		video2_bufsize;
-
-	if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
-		return -EINVAL;
-
-	startindex = (vout->vid == OMAP_VIDEO1) ?
-		video1_numbuffers : video2_numbuffers;
-	if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex)
-		*count = startindex;
-
-	if (ovid->rotation_type == VOUT_ROT_VRFB) {
-		if (omap_vout_vrfb_buffer_setup(vout, count, startindex))
-			return -ENOMEM;
-	}
-
-	if (V4L2_MEMORY_MMAP != vout->memory)
-		return 0;
-
-	/* Now allocated the V4L2 buffers */
-	*size = PAGE_ALIGN(vout->pix.width * vout->pix.height * vout->bpp);
-	startindex = (vout->vid == OMAP_VIDEO1) ?
-		video1_numbuffers : video2_numbuffers;
-
-	/* Check the size of the buffer */
-	if (*size > vid_max_buf_size) {
-		v4l2_err(&vout->vid_dev->v4l2_dev,
-				"buffer allocation mismatch [%u] [%u]\n",
-				*size, vout->buffer_size);
-		return -ENOMEM;
-	}
-
-	for (i = startindex; i < *count; i++) {
-		vout->buffer_size = *size;
-
-		virt_addr = omap_vout_alloc_buffer(vout->buffer_size,
-				&phy_addr);
-		if (!virt_addr) {
-			if (ovid->rotation_type == VOUT_ROT_NONE)
-				break;
-
-			if (!is_rotation_enabled(vout))
-				break;
-
-			/* Free the VRFB buffers if no space for V4L2 buffers */
-			for (j = i; j < *count; j++) {
-				omap_vout_free_buffer(vout->smsshado_virt_addr[j],
-						      vout->smsshado_size);
-				vout->smsshado_virt_addr[j] = 0;
-				vout->smsshado_phy_addr[j] = 0;
-			}
-		}
-		vout->buf_virt_addr[i] = virt_addr;
-		vout->buf_phy_addr[i] = phy_addr;
-	}
-	*count = vout->buffer_allocated = i;
-
-	return 0;
-}
-
-/*
- * Free the V4L2 buffers additionally allocated than default
- * number of buffers
- */
-static void omap_vout_free_extra_buffers(struct omap_vout_device *vout)
-{
-	int num_buffers = 0, i;
-
-	num_buffers = (vout->vid == OMAP_VIDEO1) ?
-		video1_numbuffers : video2_numbuffers;
-
-	for (i = num_buffers; i < vout->buffer_allocated; i++) {
-		if (vout->buf_virt_addr[i])
-			omap_vout_free_buffer(vout->buf_virt_addr[i],
-					vout->buffer_size);
-
-		vout->buf_virt_addr[i] = 0;
-		vout->buf_phy_addr[i] = 0;
-	}
-	vout->buffer_allocated = num_buffers;
-}
-
-/*
- * This function will be called when VIDIOC_QBUF ioctl is called.
- * It prepare buffers before give out for the display. This function
- * converts user space virtual address into physical address if userptr memory
- * exchange mechanism is used. If rotation is enabled, it copies entire
- * buffer into VRFB memory space before giving it to the DSS.
- */
-static int omap_vout_buffer_prepare(struct videobuf_queue *q,
-			struct videobuf_buffer *vb,
-			enum v4l2_field field)
-{
-	struct omap_vout_device *vout = q->priv_data;
-	struct omapvideo_info *ovid = &vout->vid_info;
-
-	if (VIDEOBUF_NEEDS_INIT == vb->state) {
-		vb->width = vout->pix.width;
-		vb->height = vout->pix.height;
-		vb->size = vb->width * vb->height * vout->bpp;
-		vb->field = field;
-	}
-	vb->state = VIDEOBUF_PREPARED;
-	/* if user pointer memory mechanism is used, get the physical
-	 * address of the buffer
-	 */
-	if (V4L2_MEMORY_USERPTR == vb->memory) {
-		int ret;
-
-		if (0 == vb->baddr)
-			return -EINVAL;
-		/* Physical address */
-		ret = omap_vout_get_userptr(vb, vb->baddr,
-				(u32 *)&vout->queued_buf_addr[vb->i]);
-		if (ret < 0)
-			return ret;
-	} else {
-		unsigned long addr, dma_addr;
-		unsigned long size;
-
-		addr = (unsigned long) vout->buf_virt_addr[vb->i];
-		size = (unsigned long) vb->size;
-
-		dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr,
-				size, DMA_TO_DEVICE);
-		if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr))
-			v4l2_err(&vout->vid_dev->v4l2_dev,
-				 "dma_map_single failed\n");
-
-		vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i];
-	}
-
-	if (ovid->rotation_type == VOUT_ROT_VRFB)
-		return omap_vout_prepare_vrfb(vout, vb);
-	else
-		return 0;
-}
-
-/*
- * Buffer queue function will be called from the videobuf layer when _QBUF
- * ioctl is called. It is used to enqueue buffer, which is ready to be
- * displayed.
- */
-static void omap_vout_buffer_queue(struct videobuf_queue *q,
-			  struct videobuf_buffer *vb)
-{
-	struct omap_vout_device *vout = q->priv_data;
-
-	/* Driver is also maintainig a queue. So enqueue buffer in the driver
-	 * queue */
-	list_add_tail(&vb->queue, &vout->dma_queue);
-
-	vb->state = VIDEOBUF_QUEUED;
-}
-
-/*
- * Buffer release function is called from videobuf layer to release buffer
- * which are already allocated
- */
-static void omap_vout_buffer_release(struct videobuf_queue *q,
-			    struct videobuf_buffer *vb)
-{
-	vb->state = VIDEOBUF_NEEDS_INIT;
-	if (vb->memory == V4L2_MEMORY_USERPTR && vb->priv) {
-		struct frame_vector *vec = vb->priv;
-
-		put_vaddr_frames(vec);
-		frame_vector_destroy(vec);
-	}
-}
-
-/*
- *  File operations
- */
-static __poll_t omap_vout_poll(struct file *file,
-				   struct poll_table_struct *wait)
-{
-	struct omap_vout_device *vout = file->private_data;
-	struct videobuf_queue *q = &vout->vbq;
-
-	return videobuf_poll_stream(file, q, wait);
-}
-
-static void omap_vout_vm_open(struct vm_area_struct *vma)
-{
-	struct omap_vout_device *vout = vma->vm_private_data;
-
-	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
-		"vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
-	vout->mmap_count++;
-}
-
-static void omap_vout_vm_close(struct vm_area_struct *vma)
-{
-	struct omap_vout_device *vout = vma->vm_private_data;
-
-	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
-		"vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
-	vout->mmap_count--;
-}
-
-static const struct vm_operations_struct omap_vout_vm_ops = {
-	.open	= omap_vout_vm_open,
-	.close	= omap_vout_vm_close,
-};
-
-static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	int i;
-	void *pos;
-	unsigned long start = vma->vm_start;
-	unsigned long size = (vma->vm_end - vma->vm_start);
-	struct omap_vout_device *vout = file->private_data;
-	struct videobuf_queue *q = &vout->vbq;
-
-	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
-			" %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__,
-			vma->vm_pgoff, vma->vm_start, vma->vm_end);
-
-	/* look for the buffer to map */
-	for (i = 0; i < VIDEO_MAX_FRAME; i++) {
-		if (NULL == q->bufs[i])
-			continue;
-		if (V4L2_MEMORY_MMAP != q->bufs[i]->memory)
-			continue;
-		if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT))
-			break;
-	}
-
-	if (VIDEO_MAX_FRAME == i) {
-		v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
-				"offset invalid [offset=0x%lx]\n",
-				(vma->vm_pgoff << PAGE_SHIFT));
-		return -EINVAL;
-	}
-	/* Check the size of the buffer */
-	if (size > vout->buffer_size) {
-		v4l2_err(&vout->vid_dev->v4l2_dev,
-				"insufficient memory [%lu] [%u]\n",
-				size, vout->buffer_size);
-		return -ENOMEM;
-	}
-
-	q->bufs[i]->baddr = vma->vm_start;
-
-	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
-	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-	vma->vm_ops = &omap_vout_vm_ops;
-	vma->vm_private_data = (void *) vout;
-	pos = (void *)vout->buf_virt_addr[i];
-	vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT;
-	while (size > 0) {
-		unsigned long pfn;
-		pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT;
-		if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
-			return -EAGAIN;
-		start += PAGE_SIZE;
-		pos += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
-	vout->mmap_count++;
-	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
-
-	return 0;
-}
-
-static int omap_vout_release(struct file *file)
-{
-	unsigned int ret, i;
-	struct videobuf_queue *q;
-	struct omapvideo_info *ovid;
-	struct omap_vout_device *vout = file->private_data;
-
-	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
-	ovid = &vout->vid_info;
-
-	if (!vout)
-		return 0;
-
-	q = &vout->vbq;
-	/* Disable all the overlay managers connected with this interface */
-	for (i = 0; i < ovid->num_overlays; i++) {
-		struct omap_overlay *ovl = ovid->overlays[i];
-		struct omap_dss_device *dssdev = ovl->get_device(ovl);
-
-		if (dssdev)
-			ovl->disable(ovl);
-	}
-	/* Turn off the pipeline */
-	ret = omapvid_apply_changes(vout);
-	if (ret)
-		v4l2_warn(&vout->vid_dev->v4l2_dev,
-				"Unable to apply changes\n");
-
-	/* Free all buffers */
-	omap_vout_free_extra_buffers(vout);
-
-	/* Free the VRFB buffers only if they are allocated
-	 * during reqbufs.  Don't free if init time allocated
-	 */
-	if (ovid->rotation_type == VOUT_ROT_VRFB) {
-		if (!vout->vrfb_static_allocation)
-			omap_vout_free_vrfb_buffers(vout);
-	}
-	videobuf_mmap_free(q);
-
-	/* Even if apply changes fails we should continue
-	   freeing allocated memory */
-	if (vout->streaming) {
-		u32 mask = 0;
-
-		mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
-			DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2;
-		omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
-		vout->streaming = false;
-
-		videobuf_streamoff(q);
-		videobuf_queue_cancel(q);
-	}
-
-	if (vout->mmap_count != 0)
-		vout->mmap_count = 0;
-
-	vout->opened -= 1;
-	file->private_data = NULL;
-
-	if (vout->buffer_allocated)
-		videobuf_mmap_free(q);
-
-	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
-	return ret;
-}
-
-static int omap_vout_open(struct file *file)
-{
-	struct videobuf_queue *q;
-	struct omap_vout_device *vout = NULL;
-
-	vout = video_drvdata(file);
-
-	if (vout == NULL)
-		return -ENODEV;
-
-	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
-
-	/* for now, we only support single open */
-	if (vout->opened)
-		return -EBUSY;
-
-	vout->opened += 1;
-
-	file->private_data = vout;
-	vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-
-	q = &vout->vbq;
-	video_vbq_ops.buf_setup = omap_vout_buffer_setup;
-	video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
-	video_vbq_ops.buf_release = omap_vout_buffer_release;
-	video_vbq_ops.buf_queue = omap_vout_buffer_queue;
-	spin_lock_init(&vout->vbq_lock);
-
-	videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev,
-			&vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
-			sizeof(struct videobuf_buffer), vout, NULL);
-
-	v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
-	return 0;
-}
 
 /*
  * V4L2 ioctls
@@ -1039,15 +570,12 @@
 static int vidioc_querycap(struct file *file, void *fh,
 		struct v4l2_capability *cap)
 {
-	struct omap_vout_device *vout = fh;
+	struct omap_vout_device *vout = video_drvdata(file);
 
 	strscpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
 	strscpy(cap->card, vout->vfd->name, sizeof(cap->card));
-	cap->bus_info[0] = '\0';
-	cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
-		V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+		 "platform:%s.%d", VOUT_NAME, vout->vid);
 	return 0;
 }
 
@@ -1060,8 +588,6 @@
 		return -EINVAL;
 
 	fmt->flags = omap_formats[index].flags;
-	strscpy(fmt->description, omap_formats[index].description,
-		sizeof(fmt->description));
 	fmt->pixelformat = omap_formats[index].pixelformat;
 
 	return 0;
@@ -1070,7 +596,7 @@
 static int vidioc_g_fmt_vid_out(struct file *file, void *fh,
 			struct v4l2_format *f)
 {
-	struct omap_vout_device *vout = fh;
+	struct omap_vout_device *vout = video_drvdata(file);
 
 	f->fmt.pix = vout->pix;
 	return 0;
@@ -1083,7 +609,7 @@
 	struct omap_overlay *ovl;
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
-	struct omap_vout_device *vout = fh;
+	struct omap_vout_device *vout = video_drvdata(file);
 	struct omap_dss_device *dssdev;
 
 	ovid = &vout->vid_info;
@@ -1110,14 +636,12 @@
 	struct omap_overlay *ovl;
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
-	struct omap_vout_device *vout = fh;
+	struct omap_vout_device *vout = video_drvdata(file);
 	struct omap_dss_device *dssdev;
 
-	if (vout->streaming)
+	if (vb2_is_busy(&vout->vq))
 		return -EBUSY;
 
-	mutex_lock(&vout->lock);
-
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
 	dssdev = ovl->get_device(ovl);
@@ -1168,7 +692,6 @@
 	ret = 0;
 
 s_fmt_vid_out_exit:
-	mutex_unlock(&vout->lock);
 	return ret;
 }
 
@@ -1176,7 +699,7 @@
 			struct v4l2_format *f)
 {
 	int ret = 0;
-	struct omap_vout_device *vout = fh;
+	struct omap_vout_device *vout = video_drvdata(file);
 	struct omap_overlay *ovl;
 	struct omapvideo_info *ovid;
 	struct v4l2_window *win = &f->fmt.win;
@@ -1186,12 +709,8 @@
 
 	ret = omap_vout_try_window(&vout->fbuf, win);
 
-	if (!ret) {
-		if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
-			win->global_alpha = 255;
-		else
-			win->global_alpha = f->fmt.win.global_alpha;
-	}
+	if (!ret && !(ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA))
+		win->global_alpha = 0;
 
 	return ret;
 }
@@ -1202,35 +721,53 @@
 	int ret = 0;
 	struct omap_overlay *ovl;
 	struct omapvideo_info *ovid;
-	struct omap_vout_device *vout = fh;
+	struct omap_vout_device *vout = video_drvdata(file);
 	struct v4l2_window *win = &f->fmt.win;
 
-	mutex_lock(&vout->lock);
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
 
 	ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
 	if (!ret) {
-		/* Video1 plane does not support global alpha on OMAP3 */
-		if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
-			vout->win.global_alpha = 255;
-		else
-			vout->win.global_alpha = f->fmt.win.global_alpha;
+		enum omap_dss_trans_key_type key_type =
+			OMAP_DSS_COLOR_KEY_GFX_DST;
+		int enable;
 
-		vout->win.chromakey = f->fmt.win.chromakey;
+		/* Video1 plane does not support global alpha on OMAP3 */
+		if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA)
+			vout->win.global_alpha = win->global_alpha;
+		else
+			win->global_alpha = 0;
+		if (vout->fbuf.flags & (V4L2_FBUF_FLAG_CHROMAKEY |
+					V4L2_FBUF_FLAG_SRC_CHROMAKEY))
+			enable = 1;
+		else
+			enable = 0;
+		if (vout->fbuf.flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)
+			key_type = OMAP_DSS_COLOR_KEY_VID_SRC;
+
+		if (ovl->manager && ovl->manager->get_manager_info &&
+		    ovl->manager->set_manager_info) {
+			struct omap_overlay_manager_info info;
+
+			ovl->manager->get_manager_info(ovl->manager, &info);
+			info.trans_enabled = enable;
+			info.trans_key_type = key_type;
+			info.trans_key = vout->win.chromakey;
+
+			if (ovl->manager->set_manager_info(ovl->manager, &info))
+				return -EINVAL;
+		}
 	}
-	mutex_unlock(&vout->lock);
 	return ret;
 }
 
 static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh,
 			struct v4l2_format *f)
 {
-	u32 key_value =  0;
 	struct omap_overlay *ovl;
 	struct omapvideo_info *ovid;
-	struct omap_vout_device *vout = fh;
-	struct omap_overlay_manager_info info;
+	struct omap_vout_device *vout = video_drvdata(file);
 	struct v4l2_window *win = &f->fmt.win;
 
 	ovid = &vout->vid_info;
@@ -1238,19 +775,20 @@
 
 	win->w = vout->win.w;
 	win->field = vout->win.field;
-	win->global_alpha = vout->win.global_alpha;
-
-	if (ovl->manager && ovl->manager->get_manager_info) {
-		ovl->manager->get_manager_info(ovl->manager, &info);
-		key_value = info.trans_key;
-	}
-	win->chromakey = key_value;
+	win->chromakey = vout->win.chromakey;
+	if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA)
+		win->global_alpha = vout->win.global_alpha;
+	else
+		win->global_alpha = 0;
+	win->clips = NULL;
+	win->clipcount = 0;
+	win->bitmap = NULL;
 	return 0;
 }
 
 static int vidioc_g_selection(struct file *file, void *fh, struct v4l2_selection *sel)
 {
-	struct omap_vout_device *vout = fh;
+	struct omap_vout_device *vout = video_drvdata(file);
 	struct v4l2_pix_format *pix = &vout->pix;
 
 	if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -1277,7 +815,7 @@
 static int vidioc_s_selection(struct file *file, void *fh, struct v4l2_selection *sel)
 {
 	int ret = -EINVAL;
-	struct omap_vout_device *vout = fh;
+	struct omap_vout_device *vout = video_drvdata(file);
 	struct omapvideo_info *ovid;
 	struct omap_overlay *ovl;
 	struct omap_video_timings *timing;
@@ -1289,10 +827,9 @@
 	if (sel->target != V4L2_SEL_TGT_CROP)
 		return -EINVAL;
 
-	if (vout->streaming)
+	if (vb2_is_busy(&vout->vq))
 		return -EBUSY;
 
-	mutex_lock(&vout->lock);
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
 	/* get the display device attached to the overlay */
@@ -1317,7 +854,6 @@
 				 &vout->fbuf, &sel->r);
 
 s_crop_err:
-	mutex_unlock(&vout->lock);
 	return ret;
 }
 
@@ -1334,26 +870,21 @@
 
 		ovid = &vout->vid_info;
 
-		mutex_lock(&vout->lock);
 		if (rotation && ovid->rotation_type == VOUT_ROT_NONE) {
-			mutex_unlock(&vout->lock);
 			ret = -ERANGE;
 			break;
 		}
 
 		if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
-			mutex_unlock(&vout->lock);
 			ret = -EINVAL;
 			break;
 		}
 
 		if (v4l2_rot_to_dss_rot(rotation, &vout->rotation,
 							vout->mirror)) {
-			mutex_unlock(&vout->lock);
 			ret = -EINVAL;
 			break;
 		}
-		mutex_unlock(&vout->lock);
 		break;
 	}
 	case V4L2_CID_BG_COLOR:
@@ -1364,9 +895,7 @@
 
 		ovl = vout->vid_info.overlays[0];
 
-		mutex_lock(&vout->lock);
 		if (!ovl->manager || !ovl->manager->get_manager_info) {
-			mutex_unlock(&vout->lock);
 			ret = -EINVAL;
 			break;
 		}
@@ -1374,11 +903,9 @@
 		ovl->manager->get_manager_info(ovl->manager, &info);
 		info.default_color = color;
 		if (ovl->manager->set_manager_info(ovl->manager, &info)) {
-			mutex_unlock(&vout->lock);
 			ret = -EINVAL;
 			break;
 		}
-		mutex_unlock(&vout->lock);
 		break;
 	}
 	case V4L2_CID_VFLIP:
@@ -1388,20 +915,16 @@
 
 		ovid = &vout->vid_info;
 
-		mutex_lock(&vout->lock);
 		if (mirror && ovid->rotation_type == VOUT_ROT_NONE) {
-			mutex_unlock(&vout->lock);
 			ret = -ERANGE;
 			break;
 		}
 
 		if (mirror  && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
-			mutex_unlock(&vout->lock);
 			ret = -EINVAL;
 			break;
 		}
 		vout->mirror = mirror;
-		mutex_unlock(&vout->lock);
 		break;
 	}
 	default:
@@ -1414,185 +937,94 @@
 	.s_ctrl = omap_vout_s_ctrl,
 };
 
-static int vidioc_reqbufs(struct file *file, void *fh,
-			struct v4l2_requestbuffers *req)
+static int omap_vout_vb2_queue_setup(struct vb2_queue *vq,
+				     unsigned int *nbufs,
+				     unsigned int *num_planes, unsigned int sizes[],
+				     struct device *alloc_devs[])
 {
-	int ret = 0;
-	unsigned int i, num_buffers = 0;
-	struct omap_vout_device *vout = fh;
-	struct videobuf_queue *q = &vout->vbq;
+	struct omap_vout_device *vout = vb2_get_drv_priv(vq);
+	int size = vout->pix.sizeimage;
 
-	if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		return -EINVAL;
-	/* if memory is not mmp or userptr
-	   return error */
-	if ((V4L2_MEMORY_MMAP != req->memory) &&
-			(V4L2_MEMORY_USERPTR != req->memory))
-		return -EINVAL;
-
-	mutex_lock(&vout->lock);
-	/* Cannot be requested when streaming is on */
-	if (vout->streaming) {
-		ret = -EBUSY;
-		goto reqbuf_err;
-	}
-
-	/* If buffers are already allocated free them */
-	if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) {
-		if (vout->mmap_count) {
-			ret = -EBUSY;
-			goto reqbuf_err;
-		}
-		num_buffers = (vout->vid == OMAP_VIDEO1) ?
-			video1_numbuffers : video2_numbuffers;
-		for (i = num_buffers; i < vout->buffer_allocated; i++) {
-			omap_vout_free_buffer(vout->buf_virt_addr[i],
-					vout->buffer_size);
-			vout->buf_virt_addr[i] = 0;
-			vout->buf_phy_addr[i] = 0;
-		}
-		vout->buffer_allocated = num_buffers;
-		videobuf_mmap_free(q);
-	} else if (q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) {
-		if (vout->buffer_allocated) {
-			videobuf_mmap_free(q);
-			for (i = 0; i < vout->buffer_allocated; i++) {
-				kfree(q->bufs[i]);
-				q->bufs[i] = NULL;
-			}
-			vout->buffer_allocated = 0;
-		}
-	}
-
-	/*store the memory type in data structure */
-	vout->memory = req->memory;
-
-	INIT_LIST_HEAD(&vout->dma_queue);
-
-	/* call videobuf_reqbufs api */
-	ret = videobuf_reqbufs(q, req);
-	if (ret < 0)
-		goto reqbuf_err;
-
-	vout->buffer_allocated = req->count;
-
-reqbuf_err:
-	mutex_unlock(&vout->lock);
-	return ret;
-}
-
-static int vidioc_querybuf(struct file *file, void *fh,
-			struct v4l2_buffer *b)
-{
-	struct omap_vout_device *vout = fh;
-
-	return videobuf_querybuf(&vout->vbq, b);
-}
-
-static int vidioc_qbuf(struct file *file, void *fh,
-			struct v4l2_buffer *buffer)
-{
-	struct omap_vout_device *vout = fh;
-	struct videobuf_queue *q = &vout->vbq;
-
-	if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) ||
-			(buffer->index >= vout->buffer_allocated) ||
-			(q->bufs[buffer->index]->memory != buffer->memory)) {
-		return -EINVAL;
-	}
-	if (V4L2_MEMORY_USERPTR == buffer->memory) {
-		if ((buffer->length < vout->pix.sizeimage) ||
-				(0 == buffer->m.userptr)) {
+	if (is_rotation_enabled(vout) && vq->num_buffers + *nbufs > VRFB_NUM_BUFS) {
+		*nbufs = VRFB_NUM_BUFS - vq->num_buffers;
+		if (*nbufs == 0)
 			return -EINVAL;
-		}
 	}
 
-	if ((is_rotation_enabled(vout)) &&
-			vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) {
-		v4l2_warn(&vout->vid_dev->v4l2_dev,
-				"DMA Channel not allocated for Rotation\n");
-		return -EINVAL;
-	}
+	if (*num_planes)
+		return sizes[0] < size ? -EINVAL : 0;
 
-	return videobuf_qbuf(q, buffer);
-}
-
-static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
-{
-	struct omap_vout_device *vout = fh;
-	struct videobuf_queue *q = &vout->vbq;
-
-	int ret;
-	u32 addr;
-	unsigned long size;
-	struct videobuf_buffer *vb;
-
-	if (!vout->streaming)
-		return -EINVAL;
-
-	ret = videobuf_dqbuf(q, b, !!(file->f_flags & O_NONBLOCK));
-	if (ret)
-		return ret;
-
-	vb = q->bufs[b->index];
-
-	addr = (unsigned long) vout->buf_phy_addr[vb->i];
-	size = (unsigned long) vb->size;
-	dma_unmap_single(vout->vid_dev->v4l2_dev.dev,  addr,
-				size, DMA_TO_DEVICE);
+	*num_planes = 1;
+	sizes[0] = size;
 	return 0;
 }
 
-static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
+static int omap_vout_vb2_prepare(struct vb2_buffer *vb)
 {
-	int ret = 0, j;
-	u32 addr = 0, mask = 0;
-	struct omap_vout_device *vout = fh;
-	struct videobuf_queue *q = &vout->vbq;
+	struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue);
 	struct omapvideo_info *ovid = &vout->vid_info;
+	struct omap_vout_buffer *voutbuf = vb2_to_omap_vout_buffer(vb);
+	dma_addr_t buf_phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
 
-	mutex_lock(&vout->lock);
-
-	if (vout->streaming) {
-		ret = -EBUSY;
-		goto streamon_err;
+	if (vb2_plane_size(vb, 0) < vout->pix.sizeimage) {
+		v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
+			 "%s data will not fit into plane (%lu < %u)\n",
+			__func__, vb2_plane_size(vb, 0), vout->pix.sizeimage);
+		return -EINVAL;
 	}
 
-	ret = videobuf_streamon(q);
-	if (ret)
-		goto streamon_err;
+	vb2_set_plane_payload(vb, 0, vout->pix.sizeimage);
+	voutbuf->vbuf.field = V4L2_FIELD_NONE;
 
-	if (list_empty(&vout->dma_queue)) {
-		ret = -EIO;
-		goto streamon_err1;
-	}
+	vout->queued_buf_addr[vb->index] = (u8 *)buf_phy_addr;
+	if (ovid->rotation_type == VOUT_ROT_VRFB)
+		return omap_vout_prepare_vrfb(vout, vb);
+	return 0;
+}
+
+static void omap_vout_vb2_queue(struct vb2_buffer *vb)
+{
+	struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue);
+	struct omap_vout_buffer *voutbuf = vb2_to_omap_vout_buffer(vb);
+
+	list_add_tail(&voutbuf->queue, &vout->dma_queue);
+}
+
+static int omap_vout_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct omap_vout_device *vout = vb2_get_drv_priv(vq);
+	struct omapvideo_info *ovid = &vout->vid_info;
+	struct omap_vout_buffer *buf, *tmp;
+	u32 addr = 0, mask = 0;
+	int ret, j;
 
 	/* Get the next frame from the buffer queue */
 	vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next,
-			struct videobuf_buffer, queue);
+			struct omap_vout_buffer, queue);
 	/* Remove buffer from the buffer queue */
 	list_del(&vout->cur_frm->queue);
-	/* Mark state of the current frame to active */
-	vout->cur_frm->state = VIDEOBUF_ACTIVE;
 	/* Initialize field_id and started member */
 	vout->field_id = 0;
-
-	/* set flag here. Next QBUF will start DMA */
-	vout->streaming = true;
-
 	vout->first_int = 1;
+	vout->sequence = 0;
 
 	if (omap_vout_calculate_offset(vout)) {
 		ret = -EINVAL;
-		goto streamon_err1;
+		goto out;
 	}
-	addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i]
+	if (ovid->rotation_type == VOUT_ROT_VRFB)
+		if (omap_vout_vrfb_buffer_setup(vout, &count, 0)) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+	addr = (unsigned long)vout->queued_buf_addr[vout->cur_frm->vbuf.vb2_buf.index]
 		+ vout->cropped_offset;
 
 	mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
 		| DISPC_IRQ_VSYNC2;
 
-	/* First save the configuration in ovelray structure */
+	/* First save the configuration in overlay structure */
 	ret = omapvid_init(vout, addr);
 	if (ret) {
 		v4l2_err(&vout->vid_dev->v4l2_dev,
@@ -1617,28 +1049,9 @@
 				goto streamon_err1;
 		}
 	}
-
-	ret = 0;
+	return 0;
 
 streamon_err1:
-	if (ret)
-		ret = videobuf_streamoff(q);
-streamon_err:
-	mutex_unlock(&vout->lock);
-	return ret;
-}
-
-static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
-{
-	u32 mask = 0;
-	int ret = 0, j;
-	struct omap_vout_device *vout = fh;
-	struct omapvideo_info *ovid = &vout->vid_info;
-
-	if (!vout->streaming)
-		return -EINVAL;
-
-	vout->streaming = false;
 	mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
 		| DISPC_IRQ_VSYNC2;
 
@@ -1651,26 +1064,61 @@
 		if (dssdev)
 			ovl->disable(ovl);
 	}
-
 	/* Turn of the pipeline */
-	ret = omapvid_apply_changes(vout);
-	if (ret)
+	if (omapvid_apply_changes(vout))
 		v4l2_err(&vout->vid_dev->v4l2_dev,
 			 "failed to change mode in streamoff\n");
 
-	INIT_LIST_HEAD(&vout->dma_queue);
-	ret = videobuf_streamoff(&vout->vbq);
-
+out:
+	vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED);
+	list_for_each_entry_safe(buf, tmp, &vout->dma_queue, queue) {
+		list_del(&buf->queue);
+		vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED);
+	}
 	return ret;
 }
 
+static void omap_vout_vb2_stop_streaming(struct vb2_queue *vq)
+{
+	struct omap_vout_device *vout = vb2_get_drv_priv(vq);
+	struct omapvideo_info *ovid = &vout->vid_info;
+	struct omap_vout_buffer *buf, *tmp;
+	u32 mask = 0;
+	int j;
+
+	mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
+		| DISPC_IRQ_VSYNC2;
+
+	omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
+
+	for (j = 0; j < ovid->num_overlays; j++) {
+		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->get_device(ovl);
+
+		if (dssdev)
+			ovl->disable(ovl);
+	}
+	/* Turn of the pipeline */
+	if (omapvid_apply_changes(vout))
+		v4l2_err(&vout->vid_dev->v4l2_dev,
+			 "failed to change mode in streamoff\n");
+
+	if (vout->next_frm != vout->cur_frm)
+		vb2_buffer_done(&vout->next_frm->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
+	vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
+	list_for_each_entry_safe(buf, tmp, &vout->dma_queue, queue) {
+		list_del(&buf->queue);
+		vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
+	}
+}
+
 static int vidioc_s_fbuf(struct file *file, void *fh,
 				const struct v4l2_framebuffer *a)
 {
 	int enable = 0;
 	struct omap_overlay *ovl;
 	struct omapvideo_info *ovid;
-	struct omap_vout_device *vout = fh;
+	struct omap_vout_device *vout = video_drvdata(file);
 	struct omap_overlay_manager_info info;
 	enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
 
@@ -1741,17 +1189,36 @@
 {
 	struct omap_overlay *ovl;
 	struct omapvideo_info *ovid;
-	struct omap_vout_device *vout = fh;
+	struct omap_vout_device *vout = video_drvdata(file);
 	struct omap_overlay_manager_info info;
+	struct omap_video_timings *timing;
+	struct omap_dss_device *dssdev;
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->get_device(ovl);
 
-	/* The video overlay must stay within the framebuffer and can't be
-	   positioned independently. */
-	a->flags = V4L2_FBUF_FLAG_OVERLAY;
-	a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY
-		| V4L2_FBUF_CAP_SRC_CHROMAKEY;
+	if (!dssdev)
+		return -EINVAL;
+
+	timing = &dssdev->panel.timings;
+
+	vout->fbuf.fmt.height = timing->y_res;
+	vout->fbuf.fmt.width = timing->x_res;
+	a->fmt.field = V4L2_FIELD_NONE;
+	a->fmt.colorspace = V4L2_COLORSPACE_SRGB;
+	a->fmt.pixelformat = V4L2_PIX_FMT_RGBA32;
+	a->fmt.height = vout->fbuf.fmt.height;
+	a->fmt.width = vout->fbuf.fmt.width;
+	a->fmt.bytesperline = vout->fbuf.fmt.width * 4;
+	a->fmt.sizeimage = a->fmt.height * a->fmt.bytesperline;
+	a->base = vout->fbuf.base;
+
+	a->flags = vout->fbuf.flags;
+	a->capability = vout->fbuf.capability;
+	a->flags &= ~(V4L2_FBUF_FLAG_SRC_CHROMAKEY | V4L2_FBUF_FLAG_CHROMAKEY |
+		      V4L2_FBUF_FLAG_LOCAL_ALPHA);
 
 	if (ovl->manager && ovl->manager->get_manager_info) {
 		ovl->manager->get_manager_info(ovl->manager, &info);
@@ -1759,9 +1226,6 @@
 			a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
 		if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST)
 			a->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
-	}
-	if (ovl->manager && ovl->manager->get_manager_info) {
-		ovl->manager->get_manager_info(ovl->manager, &info);
 		if (info.partial_alpha_enabled)
 			a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
 	}
@@ -1769,6 +1233,27 @@
 	return 0;
 }
 
+static int vidioc_enum_output(struct file *file, void *priv_fh,
+			      struct v4l2_output *out)
+{
+	if (out->index)
+		return -EINVAL;
+	snprintf(out->name, sizeof(out->name), "Overlay");
+	out->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
+	return 0;
+}
+
+static int vidioc_g_output(struct file *file, void *priv_fh, unsigned int *i)
+{
+	*i = 0;
+	return 0;
+}
+
+static int vidioc_s_output(struct file *file, void *priv_fh, unsigned int i)
+{
+	return i ? -EINVAL : 0;
+}
+
 static const struct v4l2_ioctl_ops vout_ioctl_ops = {
 	.vidioc_querycap			= vidioc_querycap,
 	.vidioc_enum_fmt_vid_out		= vidioc_enum_fmt_vid_out,
@@ -1782,21 +1267,38 @@
 	.vidioc_g_fmt_vid_out_overlay		= vidioc_g_fmt_vid_overlay,
 	.vidioc_g_selection			= vidioc_g_selection,
 	.vidioc_s_selection			= vidioc_s_selection,
-	.vidioc_reqbufs				= vidioc_reqbufs,
-	.vidioc_querybuf			= vidioc_querybuf,
-	.vidioc_qbuf				= vidioc_qbuf,
-	.vidioc_dqbuf				= vidioc_dqbuf,
-	.vidioc_streamon			= vidioc_streamon,
-	.vidioc_streamoff			= vidioc_streamoff,
+	.vidioc_enum_output			= vidioc_enum_output,
+	.vidioc_g_output			= vidioc_g_output,
+	.vidioc_s_output			= vidioc_s_output,
+	.vidioc_reqbufs				= vb2_ioctl_reqbufs,
+	.vidioc_create_bufs			= vb2_ioctl_create_bufs,
+	.vidioc_querybuf			= vb2_ioctl_querybuf,
+	.vidioc_qbuf				= vb2_ioctl_qbuf,
+	.vidioc_dqbuf				= vb2_ioctl_dqbuf,
+	.vidioc_expbuf				= vb2_ioctl_expbuf,
+	.vidioc_streamon			= vb2_ioctl_streamon,
+	.vidioc_streamoff			= vb2_ioctl_streamoff,
+	.vidioc_subscribe_event			= v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event		= v4l2_event_unsubscribe,
 };
 
 static const struct v4l2_file_operations omap_vout_fops = {
 	.owner		= THIS_MODULE,
-	.poll		= omap_vout_poll,
 	.unlocked_ioctl	= video_ioctl2,
-	.mmap		= omap_vout_mmap,
-	.open		= omap_vout_open,
-	.release	= omap_vout_release,
+	.poll		= vb2_fop_poll,
+	.mmap		= vb2_fop_mmap,
+	.open		= v4l2_fh_open,
+	.release	= vb2_fop_release,
+};
+
+static const struct vb2_ops omap_vout_vb2_ops = {
+	.queue_setup		= omap_vout_vb2_queue_setup,
+	.buf_queue		= omap_vout_vb2_queue,
+	.buf_prepare		= omap_vout_vb2_prepare,
+	.start_streaming	= omap_vout_vb2_start_streaming,
+	.stop_streaming		= omap_vout_vb2_stop_streaming,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
 };
 
 /* Init functions used during driver initialization */
@@ -1808,6 +1310,8 @@
 	struct omap_overlay *ovl = vout->vid_info.overlays[0];
 	struct omap_dss_device *display = ovl->get_device(ovl);
 	struct v4l2_ctrl_handler *hdl;
+	struct vb2_queue *vq;
+	int ret;
 
 	/* set the default pix */
 	pix = &vout->pix;
@@ -1818,37 +1322,48 @@
 
 	/* Default pixel format is RGB 5-6-5 */
 	pix->pixelformat = V4L2_PIX_FMT_RGB565;
-	pix->field = V4L2_FIELD_ANY;
+	pix->field = V4L2_FIELD_NONE;
 	pix->bytesperline = pix->width * 2;
 	pix->sizeimage = pix->bytesperline * pix->height;
-	pix->colorspace = V4L2_COLORSPACE_JPEG;
+	pix->colorspace = V4L2_COLORSPACE_SRGB;
 
 	vout->bpp = RGB565_BPP;
 	vout->fbuf.fmt.width  =  display->panel.timings.x_res;
 	vout->fbuf.fmt.height =  display->panel.timings.y_res;
+	vout->cropped_offset = 0;
 
 	/* Set the data structures for the overlay parameters*/
-	vout->win.global_alpha = 255;
-	vout->fbuf.flags = 0;
+	vout->fbuf.flags = V4L2_FBUF_FLAG_OVERLAY;
 	vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA |
-		V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY;
-	vout->win.chromakey = 0;
+		V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY |
+		V4L2_FBUF_CAP_EXTERNOVERLAY;
+	if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) {
+		vout->win.global_alpha = 255;
+		vout->fbuf.capability |= V4L2_FBUF_CAP_GLOBAL_ALPHA;
+		vout->fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
+	} else {
+		vout->win.global_alpha = 0;
+	}
+	vout->win.field = V4L2_FIELD_NONE;
 
 	omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win);
 
 	hdl = &vout->ctrl_handler;
 	v4l2_ctrl_handler_init(hdl, 3);
-	v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
-			  V4L2_CID_ROTATE, 0, 270, 90, 0);
+	if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) {
+		v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
+				  V4L2_CID_ROTATE, 0, 270, 90, 0);
+		v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
+				  V4L2_CID_VFLIP, 0, 1, 1, 0);
+	}
 	v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
 			  V4L2_CID_BG_COLOR, 0, 0xffffff, 1, 0);
-	v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops,
-			  V4L2_CID_VFLIP, 0, 1, 1, 0);
 	if (hdl->error)
 		return hdl->error;
 
 	vout->rotation = 0;
 	vout->mirror = false;
+	INIT_LIST_HEAD(&vout->dma_queue);
 	if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
 		vout->vrfb_bpp = 2;
 
@@ -1870,63 +1385,54 @@
 	vfd->fops = &omap_vout_fops;
 	vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
 	vfd->vfl_dir = VFL_DIR_TX;
+	vfd->minor = -1;
+	vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
+			   V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
 	mutex_init(&vout->lock);
 
-	vfd->minor = -1;
-	return 0;
+	vq = &vout->vq;
+	vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	vq->io_modes = VB2_MMAP | VB2_DMABUF;
+	vq->drv_priv = vout;
+	vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	vq->buf_struct_size = sizeof(struct omap_vout_buffer);
+	vq->dev = vfd->v4l2_dev->dev;
 
+	vq->ops = &omap_vout_vb2_ops;
+	vq->mem_ops = &vb2_dma_contig_memops;
+	vq->lock = &vout->lock;
+	vq->min_buffers_needed = 1;
+	vfd->queue = vq;
+
+	ret = vb2_queue_init(vq);
+	if (ret) {
+		v4l2_ctrl_handler_free(hdl);
+		video_device_release(vfd);
+	}
+	return ret;
 }
 
 /* Setup video buffers */
 static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
 		int vid_num)
 {
-	u32 numbuffers;
-	int ret = 0, i;
 	struct omapvideo_info *ovid;
 	struct omap_vout_device *vout;
 	struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
 	struct omap2video_device *vid_dev =
 		container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
+	int ret = 0;
 
 	vout = vid_dev->vouts[vid_num];
 	ovid = &vout->vid_info;
 
-	numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers;
-	vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize;
-	dev_info(&pdev->dev, "Buffer Size = %d\n", vout->buffer_size);
-
-	for (i = 0; i < numbuffers; i++) {
-		vout->buf_virt_addr[i] =
-			omap_vout_alloc_buffer(vout->buffer_size,
-					(u32 *) &vout->buf_phy_addr[i]);
-		if (!vout->buf_virt_addr[i]) {
-			numbuffers = i;
-			ret = -ENOMEM;
-			goto free_buffers;
-		}
-	}
-
-	vout->cropped_offset = 0;
-
 	if (ovid->rotation_type == VOUT_ROT_VRFB) {
 		bool static_vrfb_allocation = (vid_num == 0) ?
 			vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
 		ret = omap_vout_setup_vrfb_bufs(pdev, vid_num,
 				static_vrfb_allocation);
 	}
-
 	return ret;
-
-free_buffers:
-	for (i = 0; i < numbuffers; i++) {
-		omap_vout_free_buffer(vout->buf_virt_addr[i],
-						vout->buffer_size);
-		vout->buf_virt_addr[i] = 0;
-		vout->buf_phy_addr[i] = 0;
-	}
-	return ret;
-
 }
 
 /* Create video out devices */
@@ -1938,6 +1444,10 @@
 	struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
 	struct omap2video_device *vid_dev = container_of(v4l2_dev,
 			struct omap2video_device, v4l2_dev);
+	struct omap_overlay *ovl = vid_dev->overlays[0];
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
 
 	for (k = 0; k < pdev->num_resources; k++) {
 
@@ -1958,6 +1468,15 @@
 			vout->vid_info.overlays[0] = vid_dev->overlays[k + 1];
 		vout->vid_info.num_overlays = 1;
 		vout->vid_info.id = k + 1;
+		spin_lock_init(&vout->vbq_lock);
+		/*
+		 * Set the framebuffer base, this allows applications to find
+		 * the fb corresponding to this overlay.
+		 *
+		 * To be precise: fbuf.base should match smem_start of
+		 * struct fb_fix_screeninfo.
+		 */
+		vout->fbuf.base = (void *)info.paddr;
 
 		/* Set VRFB as rotation_type for omap2 and omap3 */
 		if (omap_vout_dss_omap24xx() || omap_vout_dss_omap34xx())
@@ -2000,7 +1519,6 @@
 error2:
 		if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
 			omap_vout_release_vrfb(vout);
-		omap_vout_free_buffers(vout);
 error1:
 		video_device_release(vfd);
 error:
@@ -2045,7 +1563,6 @@
 		if (vout->vrfb_static_allocation)
 			omap_vout_free_vrfb_buffers(vout);
 	}
-	omap_vout_free_buffers(vout);
 
 	kfree(vout);
 }
diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c
index 11ec048..6bd672c 100644
--- a/drivers/media/platform/omap/omap_vout_vrfb.c
+++ b/drivers/media/platform/omap/omap_vout_vrfb.c
@@ -14,7 +14,6 @@
 #include <linux/videodev2.h>
 #include <linux/slab.h>
 
-#include <media/videobuf-dma-contig.h>
 #include <media/v4l2-device.h>
 
 #include <video/omapvrfb.h>
@@ -40,7 +39,7 @@
 						&vout->smsshado_phy_addr[i]);
 		}
 		if (!vout->smsshado_virt_addr[i] && startindex != -1) {
-			if (V4L2_MEMORY_MMAP == vout->memory && i >= startindex)
+			if (vout->vq.memory == V4L2_MEMORY_MMAP && i >= startindex)
 				break;
 		}
 		if (!vout->smsshado_virt_addr[i]) {
@@ -109,8 +108,7 @@
 			dev_info(&pdev->dev, ": VRFB allocation failed\n");
 			for (j = 0; j < i; j++)
 				omap_vrfb_release_ctx(&vout->vrfb_context[j]);
-			ret = -ENOMEM;
-			goto free_buffers;
+			return -ENOMEM;
 		}
 	}
 
@@ -155,8 +153,10 @@
 
 	init_waitqueue_head(&vout->vrfb_dma_tx.wait);
 
-	/* statically allocated the VRFB buffer is done through
-	   commands line aruments */
+	/*
+	 * statically allocated the VRFB buffer is done through
+	 * command line arguments
+	 */
 	if (static_vrfb_allocation) {
 		if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) {
 			ret =  -ENOMEM;
@@ -169,9 +169,6 @@
 release_vrfb_ctx:
 	for (j = 0; j < VRFB_NUM_BUFS; j++)
 		omap_vrfb_release_ctx(&vout->vrfb_context[j]);
-free_buffers:
-	omap_vout_free_buffers(vout);
-
 	return ret;
 }
 
@@ -231,13 +228,14 @@
 }
 
 int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
-			   struct videobuf_buffer *vb)
+			   struct vb2_buffer *vb)
 {
 	struct dma_async_tx_descriptor *tx;
 	enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
 	struct dma_chan *chan = vout->vrfb_dma_tx.chan;
 	struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt;
 	dma_cookie_t cookie;
+	dma_addr_t buf_phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
 	enum dma_status status;
 	enum dss_rotation rotation;
 	size_t dst_icg;
@@ -255,8 +253,8 @@
 	pixsize = vout->bpp * vout->vrfb_bpp;
 	dst_icg = MAX_PIXELS_PER_LINE * pixsize - vout->pix.width * vout->bpp;
 
-	xt->src_start = vout->buf_phy_addr[vb->i];
-	xt->dst_start = vout->vrfb_context[vb->i].paddr[0];
+	xt->src_start = buf_phy_addr;
+	xt->dst_start = vout->vrfb_context[vb->index].paddr[0];
 
 	xt->numf = vout->pix.height;
 	xt->frame_size = 1;
@@ -307,8 +305,8 @@
 	/* Store buffers physical address into an array. Addresses
 	 * from this array will be used to configure DSS */
 	rotation = calc_rotation(vout);
-	vout->queued_buf_addr[vb->i] = (u8 *)
-		vout->vrfb_context[vb->i].paddr[rotation];
+	vout->queued_buf_addr[vb->index] = (u8 *)
+		vout->vrfb_context[vb->index].paddr[rotation];
 	return 0;
 }
 
diff --git a/drivers/media/platform/omap/omap_vout_vrfb.h b/drivers/media/platform/omap/omap_vout_vrfb.h
index c976975..40bc9e5 100644
--- a/drivers/media/platform/omap/omap_vout_vrfb.h
+++ b/drivers/media/platform/omap/omap_vout_vrfb.h
@@ -20,7 +20,7 @@
 int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
 			unsigned int *count, unsigned int startindex);
 int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
-			struct videobuf_buffer *vb);
+			struct vb2_buffer *vb);
 void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout);
 #else
 static inline void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) { };
@@ -32,7 +32,7 @@
 			unsigned int *count, unsigned int startindex)
 		{ return 0; };
 static inline int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
-			struct videobuf_buffer *vb)
+			struct vb2_buffer *vb)
 		{ return 0; };
 static inline void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout) { };
 #endif
diff --git a/drivers/media/platform/omap/omap_voutdef.h b/drivers/media/platform/omap/omap_voutdef.h
index c740393..1cff6de 100644
--- a/drivers/media/platform/omap/omap_voutdef.h
+++ b/drivers/media/platform/omap/omap_voutdef.h
@@ -11,6 +11,7 @@
 #ifndef OMAP_VOUTDEF_H
 #define OMAP_VOUTDEF_H
 
+#include <media/videobuf2-dma-contig.h>
 #include <media/v4l2-ctrls.h>
 #include <video/omapfb_dss.h>
 #include <video/omapvrfb.h>
@@ -113,6 +114,20 @@
 	struct omap_overlay_manager *managers[MAX_MANAGERS];
 };
 
+/* buffer for one video frame */
+struct omap_vout_buffer {
+	/* common v4l buffer stuff -- must be first */
+	struct vb2_v4l2_buffer		vbuf;
+	struct list_head		queue;
+};
+
+static inline struct omap_vout_buffer *vb2_to_omap_vout_buffer(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+	return container_of(vbuf, struct omap_vout_buffer, vbuf);
+}
+
 /* per-device data structure */
 struct omap_vout_device {
 
@@ -121,29 +136,12 @@
 	struct omap2video_device *vid_dev;
 	struct v4l2_ctrl_handler ctrl_handler;
 	int vid;
-	int opened;
 
-	/* we don't allow to change image fmt/size once buffer has
-	 * been allocated
-	 */
-	int buffer_allocated;
 	/* allow to reuse previously allocated buffer which is big enough */
 	int buffer_size;
-	/* keep buffer info across opens */
-	unsigned long buf_virt_addr[VIDEO_MAX_FRAME];
-	unsigned long buf_phy_addr[VIDEO_MAX_FRAME];
 	enum omap_color_mode dss_mode;
 
-	/* we don't allow to request new buffer when old buffers are
-	 * still mmapped
-	 */
-	int mmap_count;
-
-	spinlock_t vbq_lock;		/* spinlock for videobuf queues */
-	unsigned long field_count;	/* field counter for videobuf_buffer */
-
-	/* non-NULL means streaming is in progress. */
-	bool streaming;
+	u32 sequence;
 
 	struct v4l2_pix_format pix;
 	struct v4l2_rect crop;
@@ -169,19 +167,14 @@
 	unsigned char pos;
 
 	int ps, vr_ps, line_length, first_int, field_id;
-	enum v4l2_memory memory;
-	struct videobuf_buffer *cur_frm, *next_frm;
+	struct omap_vout_buffer *cur_frm, *next_frm;
+	spinlock_t vbq_lock;            /* spinlock for dma_queue */
 	struct list_head dma_queue;
 	u8 *queued_buf_addr[VIDEO_MAX_FRAME];
 	u32 cropped_offset;
 	s32 tv_field1_offset;
 	void *isr_handle;
-
-	/* Buffer queue variables */
-	struct omap_vout_device *vout;
-	enum v4l2_buf_type type;
-	struct videobuf_queue vbq;
-	int io_allowed;
+	struct vb2_queue vq;
 
 };
 
diff --git a/drivers/media/platform/omap/omap_voutlib.c b/drivers/media/platform/omap/omap_voutlib.c
index 58a25fd..480a7e9 100644
--- a/drivers/media/platform/omap/omap_voutlib.c
+++ b/drivers/media/platform/omap/omap_voutlib.c
@@ -95,7 +95,11 @@
 
 	/* We now have a valid preview window, so go with it */
 	new_win->w = try_win;
-	new_win->field = V4L2_FIELD_ANY;
+	new_win->field = V4L2_FIELD_NONE;
+	new_win->clips = NULL;
+	new_win->clipcount = 0;
+	new_win->bitmap = NULL;
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(omap_vout_try_window);
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 83216fc..327c571 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -719,6 +719,10 @@
 					s_stream, mode);
 			pipe->do_propagation = true;
 		}
+
+		/* Stop at the first external sub-device. */
+		if (subdev->dev != isp->dev)
+			break;
 	}
 
 	return 0;
@@ -833,6 +837,10 @@
 						      &subdev->entity);
 			failure = -ETIMEDOUT;
 		}
+
+		/* Stop at the first external sub-device. */
+		if (subdev->dev != isp->dev)
+			break;
 	}
 
 	return failure;
@@ -2014,136 +2022,6 @@
 	ISP_OF_PHY_CSIPHY2,
 };
 
-static int isp_fwnode_parse(struct device *dev,
-			    struct v4l2_fwnode_endpoint *vep,
-			    struct v4l2_async_subdev *asd)
-{
-	struct isp_async_subdev *isd =
-		container_of(asd, struct isp_async_subdev, asd);
-	struct isp_bus_cfg *buscfg = &isd->bus;
-	bool csi1 = false;
-	unsigned int i;
-
-	dev_dbg(dev, "parsing endpoint %pOF, interface %u\n",
-		to_of_node(vep->base.local_fwnode), vep->base.port);
-
-	switch (vep->base.port) {
-	case ISP_OF_PHY_PARALLEL:
-		buscfg->interface = ISP_INTERFACE_PARALLEL;
-		buscfg->bus.parallel.data_lane_shift =
-			vep->bus.parallel.data_shift;
-		buscfg->bus.parallel.clk_pol =
-			!!(vep->bus.parallel.flags
-			   & V4L2_MBUS_PCLK_SAMPLE_FALLING);
-		buscfg->bus.parallel.hs_pol =
-			!!(vep->bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
-		buscfg->bus.parallel.vs_pol =
-			!!(vep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
-		buscfg->bus.parallel.fld_pol =
-			!!(vep->bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
-		buscfg->bus.parallel.data_pol =
-			!!(vep->bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
-		buscfg->bus.parallel.bt656 = vep->bus_type == V4L2_MBUS_BT656;
-		break;
-
-	case ISP_OF_PHY_CSIPHY1:
-	case ISP_OF_PHY_CSIPHY2:
-		switch (vep->bus_type) {
-		case V4L2_MBUS_CCP2:
-		case V4L2_MBUS_CSI1:
-			dev_dbg(dev, "CSI-1/CCP-2 configuration\n");
-			csi1 = true;
-			break;
-		case V4L2_MBUS_CSI2_DPHY:
-			dev_dbg(dev, "CSI-2 configuration\n");
-			csi1 = false;
-			break;
-		default:
-			dev_err(dev, "unsupported bus type %u\n",
-				vep->bus_type);
-			return -EINVAL;
-		}
-
-		switch (vep->base.port) {
-		case ISP_OF_PHY_CSIPHY1:
-			if (csi1)
-				buscfg->interface = ISP_INTERFACE_CCP2B_PHY1;
-			else
-				buscfg->interface = ISP_INTERFACE_CSI2C_PHY1;
-			break;
-		case ISP_OF_PHY_CSIPHY2:
-			if (csi1)
-				buscfg->interface = ISP_INTERFACE_CCP2B_PHY2;
-			else
-				buscfg->interface = ISP_INTERFACE_CSI2A_PHY2;
-			break;
-		}
-		if (csi1) {
-			buscfg->bus.ccp2.lanecfg.clk.pos =
-				vep->bus.mipi_csi1.clock_lane;
-			buscfg->bus.ccp2.lanecfg.clk.pol =
-				vep->bus.mipi_csi1.lane_polarity[0];
-			dev_dbg(dev, "clock lane polarity %u, pos %u\n",
-				buscfg->bus.ccp2.lanecfg.clk.pol,
-				buscfg->bus.ccp2.lanecfg.clk.pos);
-
-			buscfg->bus.ccp2.lanecfg.data[0].pos =
-				vep->bus.mipi_csi1.data_lane;
-			buscfg->bus.ccp2.lanecfg.data[0].pol =
-				vep->bus.mipi_csi1.lane_polarity[1];
-
-			dev_dbg(dev, "data lane polarity %u, pos %u\n",
-				buscfg->bus.ccp2.lanecfg.data[0].pol,
-				buscfg->bus.ccp2.lanecfg.data[0].pos);
-
-			buscfg->bus.ccp2.strobe_clk_pol =
-				vep->bus.mipi_csi1.clock_inv;
-			buscfg->bus.ccp2.phy_layer = vep->bus.mipi_csi1.strobe;
-			buscfg->bus.ccp2.ccp2_mode =
-				vep->bus_type == V4L2_MBUS_CCP2;
-			buscfg->bus.ccp2.vp_clk_pol = 1;
-
-			buscfg->bus.ccp2.crc = 1;
-		} else {
-			buscfg->bus.csi2.lanecfg.clk.pos =
-				vep->bus.mipi_csi2.clock_lane;
-			buscfg->bus.csi2.lanecfg.clk.pol =
-				vep->bus.mipi_csi2.lane_polarities[0];
-			dev_dbg(dev, "clock lane polarity %u, pos %u\n",
-				buscfg->bus.csi2.lanecfg.clk.pol,
-				buscfg->bus.csi2.lanecfg.clk.pos);
-
-			buscfg->bus.csi2.num_data_lanes =
-				vep->bus.mipi_csi2.num_data_lanes;
-
-			for (i = 0; i < buscfg->bus.csi2.num_data_lanes; i++) {
-				buscfg->bus.csi2.lanecfg.data[i].pos =
-					vep->bus.mipi_csi2.data_lanes[i];
-				buscfg->bus.csi2.lanecfg.data[i].pol =
-					vep->bus.mipi_csi2.lane_polarities[i + 1];
-				dev_dbg(dev,
-					"data lane %u polarity %u, pos %u\n", i,
-					buscfg->bus.csi2.lanecfg.data[i].pol,
-					buscfg->bus.csi2.lanecfg.data[i].pos);
-			}
-			/*
-			 * FIXME: now we assume the CRC is always there.
-			 * Implement a way to obtain this information from the
-			 * sensor. Frame descriptors, perhaps?
-			 */
-			buscfg->bus.csi2.crc = 1;
-		}
-		break;
-
-	default:
-		dev_warn(dev, "%pOF: invalid interface %u\n",
-			 to_of_node(vep->base.local_fwnode), vep->base.port);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
 {
 	struct isp_device *isp = container_of(async, struct isp_device,
@@ -2173,6 +2051,201 @@
 	return media_device_register(&isp->media_dev);
 }
 
+static void isp_parse_of_parallel_endpoint(struct device *dev,
+					   struct v4l2_fwnode_endpoint *vep,
+					   struct isp_bus_cfg *buscfg)
+{
+	buscfg->interface = ISP_INTERFACE_PARALLEL;
+	buscfg->bus.parallel.data_lane_shift = vep->bus.parallel.data_shift;
+	buscfg->bus.parallel.clk_pol =
+		!!(vep->bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING);
+	buscfg->bus.parallel.hs_pol =
+		!!(vep->bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
+	buscfg->bus.parallel.vs_pol =
+		!!(vep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
+	buscfg->bus.parallel.fld_pol =
+		!!(vep->bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
+	buscfg->bus.parallel.data_pol =
+		!!(vep->bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
+	buscfg->bus.parallel.bt656 = vep->bus_type == V4L2_MBUS_BT656;
+}
+
+static void isp_parse_of_csi2_endpoint(struct device *dev,
+				       struct v4l2_fwnode_endpoint *vep,
+				       struct isp_bus_cfg *buscfg)
+{
+	unsigned int i;
+
+	buscfg->bus.csi2.lanecfg.clk.pos = vep->bus.mipi_csi2.clock_lane;
+	buscfg->bus.csi2.lanecfg.clk.pol =
+		vep->bus.mipi_csi2.lane_polarities[0];
+	dev_dbg(dev, "clock lane polarity %u, pos %u\n",
+		buscfg->bus.csi2.lanecfg.clk.pol,
+		buscfg->bus.csi2.lanecfg.clk.pos);
+
+	buscfg->bus.csi2.num_data_lanes = vep->bus.mipi_csi2.num_data_lanes;
+
+	for (i = 0; i < buscfg->bus.csi2.num_data_lanes; i++) {
+		buscfg->bus.csi2.lanecfg.data[i].pos =
+			vep->bus.mipi_csi2.data_lanes[i];
+		buscfg->bus.csi2.lanecfg.data[i].pol =
+			vep->bus.mipi_csi2.lane_polarities[i + 1];
+		dev_dbg(dev,
+			"data lane %u polarity %u, pos %u\n", i,
+			buscfg->bus.csi2.lanecfg.data[i].pol,
+			buscfg->bus.csi2.lanecfg.data[i].pos);
+	}
+	/*
+	 * FIXME: now we assume the CRC is always there. Implement a way to
+	 * obtain this information from the sensor. Frame descriptors, perhaps?
+	 */
+	buscfg->bus.csi2.crc = 1;
+}
+
+static void isp_parse_of_csi1_endpoint(struct device *dev,
+				       struct v4l2_fwnode_endpoint *vep,
+				       struct isp_bus_cfg *buscfg)
+{
+	buscfg->bus.ccp2.lanecfg.clk.pos = vep->bus.mipi_csi1.clock_lane;
+	buscfg->bus.ccp2.lanecfg.clk.pol = vep->bus.mipi_csi1.lane_polarity[0];
+	dev_dbg(dev, "clock lane polarity %u, pos %u\n",
+		buscfg->bus.ccp2.lanecfg.clk.pol,
+	buscfg->bus.ccp2.lanecfg.clk.pos);
+
+	buscfg->bus.ccp2.lanecfg.data[0].pos = vep->bus.mipi_csi1.data_lane;
+	buscfg->bus.ccp2.lanecfg.data[0].pol =
+		vep->bus.mipi_csi1.lane_polarity[1];
+
+	dev_dbg(dev, "data lane polarity %u, pos %u\n",
+		buscfg->bus.ccp2.lanecfg.data[0].pol,
+		buscfg->bus.ccp2.lanecfg.data[0].pos);
+
+	buscfg->bus.ccp2.strobe_clk_pol = vep->bus.mipi_csi1.clock_inv;
+	buscfg->bus.ccp2.phy_layer = vep->bus.mipi_csi1.strobe;
+	buscfg->bus.ccp2.ccp2_mode = vep->bus_type == V4L2_MBUS_CCP2;
+	buscfg->bus.ccp2.vp_clk_pol = 1;
+
+	buscfg->bus.ccp2.crc = 1;
+}
+
+static int isp_alloc_isd(struct isp_async_subdev **isd,
+			 struct isp_bus_cfg **buscfg)
+{
+	struct isp_async_subdev *__isd;
+
+	__isd = kzalloc(sizeof(*__isd), GFP_KERNEL);
+	if (!__isd)
+		return -ENOMEM;
+
+	*isd = __isd;
+	*buscfg = &__isd->bus;
+
+	return 0;
+}
+
+static struct {
+	u32 phy;
+	u32 csi2_if;
+	u32 csi1_if;
+} isp_bus_interfaces[2] = {
+	{ ISP_OF_PHY_CSIPHY1,
+	  ISP_INTERFACE_CSI2C_PHY1, ISP_INTERFACE_CCP2B_PHY1 },
+	{ ISP_OF_PHY_CSIPHY2,
+	  ISP_INTERFACE_CSI2A_PHY2, ISP_INTERFACE_CCP2B_PHY2 },
+};
+
+static int isp_parse_of_endpoints(struct isp_device *isp)
+{
+	struct fwnode_handle *ep;
+	struct isp_async_subdev *isd = NULL;
+	struct isp_bus_cfg *buscfg;
+	unsigned int i;
+
+	ep = fwnode_graph_get_endpoint_by_id(
+		dev_fwnode(isp->dev), ISP_OF_PHY_PARALLEL, 0,
+		FWNODE_GRAPH_ENDPOINT_NEXT);
+
+	if (ep) {
+		struct v4l2_fwnode_endpoint vep = {
+			.bus_type = V4L2_MBUS_PARALLEL
+		};
+		int ret;
+
+		dev_dbg(isp->dev, "parsing parallel interface\n");
+
+		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+
+		if (!ret) {
+			ret = isp_alloc_isd(&isd, &buscfg);
+			if (ret)
+				return ret;
+		}
+
+		if (!ret) {
+			isp_parse_of_parallel_endpoint(isp->dev, &vep, buscfg);
+			ret = v4l2_async_notifier_add_fwnode_remote_subdev(
+				&isp->notifier, ep, &isd->asd);
+		}
+
+		fwnode_handle_put(ep);
+		if (ret)
+			kfree(isd);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(isp_bus_interfaces); i++) {
+		struct v4l2_fwnode_endpoint vep = {
+			.bus_type = V4L2_MBUS_CSI2_DPHY
+		};
+		int ret;
+
+		ep = fwnode_graph_get_endpoint_by_id(
+			dev_fwnode(isp->dev), isp_bus_interfaces[i].phy, 0,
+			FWNODE_GRAPH_ENDPOINT_NEXT);
+
+		if (!ep)
+			continue;
+
+		dev_dbg(isp->dev, "parsing serial interface %u, node %pOF\n", i,
+			to_of_node(ep));
+
+		ret = isp_alloc_isd(&isd, &buscfg);
+		if (ret)
+			return ret;
+
+		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+		if (!ret) {
+			buscfg->interface = isp_bus_interfaces[i].csi2_if;
+			isp_parse_of_csi2_endpoint(isp->dev, &vep, buscfg);
+		} else if (ret == -ENXIO) {
+			vep = (struct v4l2_fwnode_endpoint)
+				{ .bus_type = V4L2_MBUS_CSI1 };
+			ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+
+			if (ret == -ENXIO) {
+				vep = (struct v4l2_fwnode_endpoint)
+					{ .bus_type = V4L2_MBUS_CCP2 };
+				ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+			}
+			if (!ret) {
+				buscfg->interface =
+					isp_bus_interfaces[i].csi1_if;
+				isp_parse_of_csi1_endpoint(isp->dev, &vep,
+							   buscfg);
+			}
+		}
+
+		if (!ret)
+			ret = v4l2_async_notifier_add_fwnode_remote_subdev(
+				&isp->notifier, ep, &isd->asd);
+
+		fwnode_handle_put(ep);
+		if (ret)
+			kfree(isd);
+	}
+
+	return 0;
+}
+
 static const struct v4l2_async_notifier_operations isp_subdev_notifier_ops = {
 	.complete = isp_subdev_notifier_complete,
 };
@@ -2223,14 +2296,12 @@
 	mutex_init(&isp->isp_mutex);
 	spin_lock_init(&isp->stat_lock);
 	v4l2_async_notifier_init(&isp->notifier);
+	isp->dev = &pdev->dev;
 
-	ret = v4l2_async_notifier_parse_fwnode_endpoints(
-		&pdev->dev, &isp->notifier, sizeof(struct isp_async_subdev),
-		isp_fwnode_parse);
+	ret = isp_parse_of_endpoints(isp);
 	if (ret < 0)
 		goto error;
 
-	isp->dev = &pdev->dev;
 	isp->ref_count = 0;
 
 	ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32));
@@ -2324,7 +2395,6 @@
 	/* Interrupt */
 	ret = platform_get_irq(pdev, 0);
 	if (ret <= 0) {
-		dev_err(isp->dev, "No IRQ resource\n");
 		ret = -ENODEV;
 		goto error_iommu;
 	}
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 1ba8a5b..e2f336c 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2602,6 +2602,7 @@
 	int ret;
 
 	/* Register the subdev and video node. */
+	ccdc->subdev.dev = vdev->mdev->dev;
 	ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
 	if (ret < 0)
 		goto error;
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index efca45b..d0a49cd 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1031,6 +1031,7 @@
 	int ret;
 
 	/* Register the subdev and video nodes. */
+	ccp2->subdev.dev = vdev->mdev->dev;
 	ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
 	if (ret < 0)
 		goto error;
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index e85917f..fd493c5 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1198,6 +1198,7 @@
 	int ret;
 
 	/* Register the subdev and video nodes. */
+	csi2->subdev.dev = vdev->mdev->dev;
 	ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
 	if (ret < 0)
 		goto error;
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index 40e2240..97d6606 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2225,6 +2225,7 @@
 	int ret;
 
 	/* Register the subdev and video nodes. */
+	prev->subdev.dev = vdev->mdev->dev;
 	ret = v4l2_device_register_subdev(vdev, &prev->subdev);
 	if (ret < 0)
 		goto error;
diff --git a/drivers/media/platform/omap3isp/ispreg.h b/drivers/media/platform/omap3isp/ispreg.h
index 38e2b99b..86b6ebb 100644
--- a/drivers/media/platform/omap3isp/ispreg.h
+++ b/drivers/media/platform/omap3isp/ispreg.h
@@ -45,7 +45,7 @@
 
 #define ISPCCP2_REVISION		(0x000)
 #define ISPCCP2_SYSCONFIG		(0x004)
-#define ISPCCP2_SYSCONFIG_SOFT_RESET	(1 << 1)
+#define ISPCCP2_SYSCONFIG_SOFT_RESET	BIT(1)
 #define ISPCCP2_SYSCONFIG_AUTO_IDLE		0x1
 #define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT	12
 #define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_FORCE	\
@@ -55,44 +55,44 @@
 #define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART	\
 	(0x2 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
 #define ISPCCP2_SYSSTATUS		(0x008)
-#define ISPCCP2_SYSSTATUS_RESET_DONE	(1 << 0)
+#define ISPCCP2_SYSSTATUS_RESET_DONE	BIT(0)
 #define ISPCCP2_LC01_IRQENABLE		(0x00C)
 #define ISPCCP2_LC01_IRQSTATUS		(0x010)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ	(1 << 11)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_LE_IRQ	(1 << 10)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_LS_IRQ	(1 << 9)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FE_IRQ	(1 << 8)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_COUNT_IRQ	(1 << 7)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ	(1 << 5)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ	(1 << 4)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ	(1 << 3)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ	(1 << 2)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ	(1 << 1)
-#define ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ	(1 << 0)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ	BIT(11)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_LE_IRQ	BIT(10)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_LS_IRQ	BIT(9)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_FE_IRQ	BIT(8)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_COUNT_IRQ	BIT(7)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ	BIT(5)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ	BIT(4)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ	BIT(3)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ	BIT(2)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ	BIT(1)
+#define ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ	BIT(0)
 
 #define ISPCCP2_LC23_IRQENABLE		(0x014)
 #define ISPCCP2_LC23_IRQSTATUS		(0x018)
 #define ISPCCP2_LCM_IRQENABLE		(0x02C)
-#define ISPCCP2_LCM_IRQSTATUS_EOF_IRQ		(1 << 0)
-#define ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ	(1 << 1)
+#define ISPCCP2_LCM_IRQSTATUS_EOF_IRQ		BIT(0)
+#define ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ	BIT(1)
 #define ISPCCP2_LCM_IRQSTATUS		(0x030)
 #define ISPCCP2_CTRL			(0x040)
-#define ISPCCP2_CTRL_IF_EN		(1 << 0)
-#define ISPCCP2_CTRL_PHY_SEL		(1 << 1)
+#define ISPCCP2_CTRL_IF_EN		BIT(0)
+#define ISPCCP2_CTRL_PHY_SEL		BIT(1)
 #define ISPCCP2_CTRL_PHY_SEL_CLOCK	(0 << 1)
 #define ISPCCP2_CTRL_PHY_SEL_STROBE	(1 << 1)
 #define ISPCCP2_CTRL_PHY_SEL_MASK	0x1
 #define ISPCCP2_CTRL_PHY_SEL_SHIFT	1
-#define ISPCCP2_CTRL_IO_OUT_SEL		(1 << 2)
+#define ISPCCP2_CTRL_IO_OUT_SEL		BIT(2)
 #define ISPCCP2_CTRL_IO_OUT_SEL_MASK	0x1
 #define ISPCCP2_CTRL_IO_OUT_SEL_SHIFT	2
-#define ISPCCP2_CTRL_MODE		(1 << 4)
-#define ISPCCP2_CTRL_VP_CLK_FORCE_ON	(1 << 9)
-#define ISPCCP2_CTRL_INV		(1 << 10)
+#define ISPCCP2_CTRL_MODE		BIT(4)
+#define ISPCCP2_CTRL_VP_CLK_FORCE_ON	BIT(9)
+#define ISPCCP2_CTRL_INV		BIT(10)
 #define ISPCCP2_CTRL_INV_MASK		0x1
 #define ISPCCP2_CTRL_INV_SHIFT		10
-#define ISPCCP2_CTRL_VP_ONLY_EN		(1 << 11)
-#define ISPCCP2_CTRL_VP_CLK_POL		(1 << 12)
+#define ISPCCP2_CTRL_VP_ONLY_EN		BIT(11)
+#define ISPCCP2_CTRL_VP_CLK_POL		BIT(12)
 #define ISPCCP2_CTRL_VP_CLK_POL_MASK	0x1
 #define ISPCCP2_CTRL_VP_CLK_POL_SHIFT	12
 #define ISPCCP2_CTRL_VPCLK_DIV_SHIFT	15
@@ -102,12 +102,12 @@
 #define ISPCCP2_DBG			(0x044)
 #define ISPCCP2_GNQ			(0x048)
 #define ISPCCP2_LCx_CTRL(x)			((0x050)+0x30*(x))
-#define ISPCCP2_LCx_CTRL_CHAN_EN		(1 << 0)
-#define ISPCCP2_LCx_CTRL_CRC_EN			(1 << 19)
+#define ISPCCP2_LCx_CTRL_CHAN_EN		BIT(0)
+#define ISPCCP2_LCx_CTRL_CRC_EN			BIT(19)
 #define ISPCCP2_LCx_CTRL_CRC_MASK		0x1
 #define ISPCCP2_LCx_CTRL_CRC_SHIFT		2
 #define ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0		19
-#define ISPCCP2_LCx_CTRL_REGION_EN		(1 << 1)
+#define ISPCCP2_LCx_CTRL_REGION_EN		BIT(1)
 #define ISPCCP2_LCx_CTRL_REGION_MASK		0x1
 #define ISPCCP2_LCx_CTRL_REGION_SHIFT		1
 #define ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0	0x3f
@@ -127,8 +127,8 @@
 #define ISPCCP2_LCx_DAT_PONG_ADDR(x)	((0x074)+0x30*(x))
 #define ISPCCP2_LCx_DAT_OFST(x)		((0x078)+0x30*(x))
 #define ISPCCP2_LCM_CTRL		(0x1D0)
-#define ISPCCP2_LCM_CTRL_CHAN_EN               (1 << 0)
-#define ISPCCP2_LCM_CTRL_DST_PORT              (1 << 2)
+#define ISPCCP2_LCM_CTRL_CHAN_EN               BIT(0)
+#define ISPCCP2_LCM_CTRL_DST_PORT              BIT(2)
 #define ISPCCP2_LCM_CTRL_DST_PORT_SHIFT		2
 #define ISPCCP2_LCM_CTRL_READ_THROTTLE_SHIFT	3
 #define ISPCCP2_LCM_CTRL_READ_THROTTLE_MASK	0x11
@@ -138,8 +138,8 @@
 #define ISPCCP2_LCM_CTRL_SRC_FORMAT_MASK	0x7
 #define ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT	20
 #define ISPCCP2_LCM_CTRL_SRC_DECOMPR_MASK	0x3
-#define ISPCCP2_LCM_CTRL_SRC_DPCM_PRED		(1 << 22)
-#define ISPCCP2_LCM_CTRL_SRC_PACK		(1 << 23)
+#define ISPCCP2_LCM_CTRL_SRC_DPCM_PRED		BIT(22)
+#define ISPCCP2_LCM_CTRL_SRC_PACK		BIT(23)
 #define ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT	24
 #define ISPCCP2_LCM_CTRL_DST_FORMAT_MASK	0x7
 #define ISPCCP2_LCM_VSIZE		(0x1D4)
@@ -201,19 +201,19 @@
 
 /* SBL */
 #define ISPSBL_PCR			0x4
-#define ISPSBL_PCR_H3A_AEAWB_WBL_OVF	(1 << 16)
-#define ISPSBL_PCR_H3A_AF_WBL_OVF	(1 << 17)
-#define ISPSBL_PCR_RSZ4_WBL_OVF		(1 << 18)
-#define ISPSBL_PCR_RSZ3_WBL_OVF		(1 << 19)
-#define ISPSBL_PCR_RSZ2_WBL_OVF		(1 << 20)
-#define ISPSBL_PCR_RSZ1_WBL_OVF		(1 << 21)
-#define ISPSBL_PCR_PRV_WBL_OVF		(1 << 22)
-#define ISPSBL_PCR_CCDC_WBL_OVF		(1 << 23)
-#define ISPSBL_PCR_CCDCPRV_2_RSZ_OVF	(1 << 24)
-#define ISPSBL_PCR_CSIA_WBL_OVF		(1 << 25)
-#define ISPSBL_PCR_CSIB_WBL_OVF		(1 << 26)
+#define ISPSBL_PCR_H3A_AEAWB_WBL_OVF	BIT(16)
+#define ISPSBL_PCR_H3A_AF_WBL_OVF	BIT(17)
+#define ISPSBL_PCR_RSZ4_WBL_OVF		BIT(18)
+#define ISPSBL_PCR_RSZ3_WBL_OVF		BIT(19)
+#define ISPSBL_PCR_RSZ2_WBL_OVF		BIT(20)
+#define ISPSBL_PCR_RSZ1_WBL_OVF		BIT(21)
+#define ISPSBL_PCR_PRV_WBL_OVF		BIT(22)
+#define ISPSBL_PCR_CCDC_WBL_OVF		BIT(23)
+#define ISPSBL_PCR_CCDCPRV_2_RSZ_OVF	BIT(24)
+#define ISPSBL_PCR_CSIA_WBL_OVF		BIT(25)
+#define ISPSBL_PCR_CSIB_WBL_OVF		BIT(26)
 #define ISPSBL_CCDC_WR_0		(0x028)
-#define ISPSBL_CCDC_WR_0_DATA_READY	(1 << 21)
+#define ISPSBL_CCDC_WR_0_DATA_READY	BIT(21)
 #define ISPSBL_CCDC_WR_1		(0x02C)
 #define ISPSBL_CCDC_WR_2		(0x030)
 #define ISPSBL_CCDC_WR_3		(0x034)
@@ -366,16 +366,16 @@
 
 #define ISP_INT_CLR			0xFF113F11
 #define ISPPRV_PCR_EN			1
-#define ISPPRV_PCR_BUSY			(1 << 1)
-#define ISPPRV_PCR_SOURCE		(1 << 2)
-#define ISPPRV_PCR_ONESHOT		(1 << 3)
-#define ISPPRV_PCR_WIDTH		(1 << 4)
-#define ISPPRV_PCR_INVALAW		(1 << 5)
-#define ISPPRV_PCR_DRKFEN		(1 << 6)
-#define ISPPRV_PCR_DRKFCAP		(1 << 7)
-#define ISPPRV_PCR_HMEDEN		(1 << 8)
-#define ISPPRV_PCR_NFEN			(1 << 9)
-#define ISPPRV_PCR_CFAEN		(1 << 10)
+#define ISPPRV_PCR_BUSY			BIT(1)
+#define ISPPRV_PCR_SOURCE		BIT(2)
+#define ISPPRV_PCR_ONESHOT		BIT(3)
+#define ISPPRV_PCR_WIDTH		BIT(4)
+#define ISPPRV_PCR_INVALAW		BIT(5)
+#define ISPPRV_PCR_DRKFEN		BIT(6)
+#define ISPPRV_PCR_DRKFCAP		BIT(7)
+#define ISPPRV_PCR_HMEDEN		BIT(8)
+#define ISPPRV_PCR_NFEN			BIT(9)
+#define ISPPRV_PCR_CFAEN		BIT(10)
 #define ISPPRV_PCR_CFAFMT_SHIFT		11
 #define ISPPRV_PCR_CFAFMT_MASK		0x7800
 #define ISPPRV_PCR_CFAFMT_BAYER		(0 << 11)
@@ -384,22 +384,22 @@
 #define ISPPRV_PCR_CFAFMT_DNSPL		(3 << 11)
 #define ISPPRV_PCR_CFAFMT_HONEYCOMB	(4 << 11)
 #define ISPPRV_PCR_CFAFMT_RRGGBBFOVEON	(5 << 11)
-#define ISPPRV_PCR_YNENHEN		(1 << 15)
-#define ISPPRV_PCR_SUPEN		(1 << 16)
+#define ISPPRV_PCR_YNENHEN		BIT(15)
+#define ISPPRV_PCR_SUPEN		BIT(16)
 #define ISPPRV_PCR_YCPOS_SHIFT		17
 #define ISPPRV_PCR_YCPOS_YCrYCb		(0 << 17)
 #define ISPPRV_PCR_YCPOS_YCbYCr		(1 << 17)
 #define ISPPRV_PCR_YCPOS_CbYCrY		(2 << 17)
 #define ISPPRV_PCR_YCPOS_CrYCbY		(3 << 17)
-#define ISPPRV_PCR_RSZPORT		(1 << 19)
-#define ISPPRV_PCR_SDRPORT		(1 << 20)
-#define ISPPRV_PCR_SCOMP_EN		(1 << 21)
+#define ISPPRV_PCR_RSZPORT		BIT(19)
+#define ISPPRV_PCR_SDRPORT		BIT(20)
+#define ISPPRV_PCR_SCOMP_EN		BIT(21)
 #define ISPPRV_PCR_SCOMP_SFT_SHIFT	(22)
 #define ISPPRV_PCR_SCOMP_SFT_MASK	(7 << 22)
-#define ISPPRV_PCR_GAMMA_BYPASS		(1 << 26)
-#define ISPPRV_PCR_DCOREN		(1 << 27)
-#define ISPPRV_PCR_DCCOUP		(1 << 28)
-#define ISPPRV_PCR_DRK_FAIL		(1 << 31)
+#define ISPPRV_PCR_GAMMA_BYPASS		BIT(26)
+#define ISPPRV_PCR_DCOREN		BIT(27)
+#define ISPPRV_PCR_DCCOUP		BIT(28)
+#define ISPPRV_PCR_DRK_FAIL		BIT(31)
 
 #define ISPPRV_HORZ_INFO_EPH_SHIFT	0
 #define ISPPRV_HORZ_INFO_EPH_MASK	0x3fff
@@ -423,8 +423,8 @@
 #define ISPPRV_AVE_ODDDIST_4		0x3
 
 #define ISPPRV_HMED_THRESHOLD_SHIFT	0
-#define ISPPRV_HMED_EVENDIST		(1 << 8)
-#define ISPPRV_HMED_ODDDIST		(1 << 9)
+#define ISPPRV_HMED_EVENDIST		BIT(8)
+#define ISPPRV_HMED_ODDDIST		BIT(9)
 
 #define ISPPRV_WBGAIN_COEF0_SHIFT	0
 #define ISPPRV_WBGAIN_COEF1_SHIFT	8
@@ -517,8 +517,8 @@
 /* Define bit fields within selected registers */
 #define ISP_REVISION_SHIFT			0
 
-#define ISP_SYSCONFIG_AUTOIDLE			(1 << 0)
-#define ISP_SYSCONFIG_SOFTRESET			(1 << 1)
+#define ISP_SYSCONFIG_AUTOIDLE			BIT(0)
+#define ISP_SYSCONFIG_SOFTRESET			BIT(1)
 #define ISP_SYSCONFIG_MIDLEMODE_SHIFT		12
 #define ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY	0x0
 #define ISP_SYSCONFIG_MIDLEMODE_NOSTANBY	0x1
@@ -526,68 +526,68 @@
 
 #define ISP_SYSSTATUS_RESETDONE			0
 
-#define IRQ0ENABLE_CSIA_IRQ			(1 << 0)
-#define IRQ0ENABLE_CSIC_IRQ			(1 << 1)
-#define IRQ0ENABLE_CCP2_LCM_IRQ			(1 << 3)
-#define IRQ0ENABLE_CCP2_LC0_IRQ			(1 << 4)
-#define IRQ0ENABLE_CCP2_LC1_IRQ			(1 << 5)
-#define IRQ0ENABLE_CCP2_LC2_IRQ			(1 << 6)
-#define IRQ0ENABLE_CCP2_LC3_IRQ			(1 << 7)
+#define IRQ0ENABLE_CSIA_IRQ			BIT(0)
+#define IRQ0ENABLE_CSIC_IRQ			BIT(1)
+#define IRQ0ENABLE_CCP2_LCM_IRQ			BIT(3)
+#define IRQ0ENABLE_CCP2_LC0_IRQ			BIT(4)
+#define IRQ0ENABLE_CCP2_LC1_IRQ			BIT(5)
+#define IRQ0ENABLE_CCP2_LC2_IRQ			BIT(6)
+#define IRQ0ENABLE_CCP2_LC3_IRQ			BIT(7)
 #define IRQ0ENABLE_CSIB_IRQ			(IRQ0ENABLE_CCP2_LCM_IRQ | \
 						IRQ0ENABLE_CCP2_LC0_IRQ | \
 						IRQ0ENABLE_CCP2_LC1_IRQ | \
 						IRQ0ENABLE_CCP2_LC2_IRQ | \
 						IRQ0ENABLE_CCP2_LC3_IRQ)
 
-#define IRQ0ENABLE_CCDC_VD0_IRQ			(1 << 8)
-#define IRQ0ENABLE_CCDC_VD1_IRQ			(1 << 9)
-#define IRQ0ENABLE_CCDC_VD2_IRQ			(1 << 10)
-#define IRQ0ENABLE_CCDC_ERR_IRQ			(1 << 11)
-#define IRQ0ENABLE_H3A_AF_DONE_IRQ		(1 << 12)
-#define IRQ0ENABLE_H3A_AWB_DONE_IRQ		(1 << 13)
-#define IRQ0ENABLE_HIST_DONE_IRQ		(1 << 16)
-#define IRQ0ENABLE_CCDC_LSC_DONE_IRQ		(1 << 17)
-#define IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ	(1 << 18)
-#define IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ	(1 << 19)
-#define IRQ0ENABLE_PRV_DONE_IRQ			(1 << 20)
-#define IRQ0ENABLE_RSZ_DONE_IRQ			(1 << 24)
-#define IRQ0ENABLE_OVF_IRQ			(1 << 25)
-#define IRQ0ENABLE_PING_IRQ			(1 << 26)
-#define IRQ0ENABLE_PONG_IRQ			(1 << 27)
-#define IRQ0ENABLE_MMU_ERR_IRQ			(1 << 28)
-#define IRQ0ENABLE_OCP_ERR_IRQ			(1 << 29)
-#define IRQ0ENABLE_SEC_ERR_IRQ			(1 << 30)
-#define IRQ0ENABLE_HS_VS_IRQ			(1 << 31)
+#define IRQ0ENABLE_CCDC_VD0_IRQ			BIT(8)
+#define IRQ0ENABLE_CCDC_VD1_IRQ			BIT(9)
+#define IRQ0ENABLE_CCDC_VD2_IRQ			BIT(10)
+#define IRQ0ENABLE_CCDC_ERR_IRQ			BIT(11)
+#define IRQ0ENABLE_H3A_AF_DONE_IRQ		BIT(12)
+#define IRQ0ENABLE_H3A_AWB_DONE_IRQ		BIT(13)
+#define IRQ0ENABLE_HIST_DONE_IRQ		BIT(16)
+#define IRQ0ENABLE_CCDC_LSC_DONE_IRQ		BIT(17)
+#define IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ	BIT(18)
+#define IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ	BIT(19)
+#define IRQ0ENABLE_PRV_DONE_IRQ			BIT(20)
+#define IRQ0ENABLE_RSZ_DONE_IRQ			BIT(24)
+#define IRQ0ENABLE_OVF_IRQ			BIT(25)
+#define IRQ0ENABLE_PING_IRQ			BIT(26)
+#define IRQ0ENABLE_PONG_IRQ			BIT(27)
+#define IRQ0ENABLE_MMU_ERR_IRQ			BIT(28)
+#define IRQ0ENABLE_OCP_ERR_IRQ			BIT(29)
+#define IRQ0ENABLE_SEC_ERR_IRQ			BIT(30)
+#define IRQ0ENABLE_HS_VS_IRQ			BIT(31)
 
-#define IRQ0STATUS_CSIA_IRQ			(1 << 0)
-#define IRQ0STATUS_CSI2C_IRQ			(1 << 1)
-#define IRQ0STATUS_CCP2_LCM_IRQ			(1 << 3)
-#define IRQ0STATUS_CCP2_LC0_IRQ			(1 << 4)
+#define IRQ0STATUS_CSIA_IRQ			BIT(0)
+#define IRQ0STATUS_CSI2C_IRQ			BIT(1)
+#define IRQ0STATUS_CCP2_LCM_IRQ			BIT(3)
+#define IRQ0STATUS_CCP2_LC0_IRQ			BIT(4)
 #define IRQ0STATUS_CSIB_IRQ			(IRQ0STATUS_CCP2_LCM_IRQ | \
 						IRQ0STATUS_CCP2_LC0_IRQ)
 
-#define IRQ0STATUS_CSIB_LC1_IRQ			(1 << 5)
-#define IRQ0STATUS_CSIB_LC2_IRQ			(1 << 6)
-#define IRQ0STATUS_CSIB_LC3_IRQ			(1 << 7)
-#define IRQ0STATUS_CCDC_VD0_IRQ			(1 << 8)
-#define IRQ0STATUS_CCDC_VD1_IRQ			(1 << 9)
-#define IRQ0STATUS_CCDC_VD2_IRQ			(1 << 10)
-#define IRQ0STATUS_CCDC_ERR_IRQ			(1 << 11)
-#define IRQ0STATUS_H3A_AF_DONE_IRQ		(1 << 12)
-#define IRQ0STATUS_H3A_AWB_DONE_IRQ		(1 << 13)
-#define IRQ0STATUS_HIST_DONE_IRQ		(1 << 16)
-#define IRQ0STATUS_CCDC_LSC_DONE_IRQ		(1 << 17)
-#define IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ	(1 << 18)
-#define IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ	(1 << 19)
-#define IRQ0STATUS_PRV_DONE_IRQ			(1 << 20)
-#define IRQ0STATUS_RSZ_DONE_IRQ			(1 << 24)
-#define IRQ0STATUS_OVF_IRQ			(1 << 25)
-#define IRQ0STATUS_PING_IRQ			(1 << 26)
-#define IRQ0STATUS_PONG_IRQ			(1 << 27)
-#define IRQ0STATUS_MMU_ERR_IRQ			(1 << 28)
-#define IRQ0STATUS_OCP_ERR_IRQ			(1 << 29)
-#define IRQ0STATUS_SEC_ERR_IRQ			(1 << 30)
-#define IRQ0STATUS_HS_VS_IRQ			(1 << 31)
+#define IRQ0STATUS_CSIB_LC1_IRQ			BIT(5)
+#define IRQ0STATUS_CSIB_LC2_IRQ			BIT(6)
+#define IRQ0STATUS_CSIB_LC3_IRQ			BIT(7)
+#define IRQ0STATUS_CCDC_VD0_IRQ			BIT(8)
+#define IRQ0STATUS_CCDC_VD1_IRQ			BIT(9)
+#define IRQ0STATUS_CCDC_VD2_IRQ			BIT(10)
+#define IRQ0STATUS_CCDC_ERR_IRQ			BIT(11)
+#define IRQ0STATUS_H3A_AF_DONE_IRQ		BIT(12)
+#define IRQ0STATUS_H3A_AWB_DONE_IRQ		BIT(13)
+#define IRQ0STATUS_HIST_DONE_IRQ		BIT(16)
+#define IRQ0STATUS_CCDC_LSC_DONE_IRQ		BIT(17)
+#define IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ	BIT(18)
+#define IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ	BIT(19)
+#define IRQ0STATUS_PRV_DONE_IRQ			BIT(20)
+#define IRQ0STATUS_RSZ_DONE_IRQ			BIT(24)
+#define IRQ0STATUS_OVF_IRQ			BIT(25)
+#define IRQ0STATUS_PING_IRQ			BIT(26)
+#define IRQ0STATUS_PONG_IRQ			BIT(27)
+#define IRQ0STATUS_MMU_ERR_IRQ			BIT(28)
+#define IRQ0STATUS_OCP_ERR_IRQ			BIT(29)
+#define IRQ0STATUS_SEC_ERR_IRQ			BIT(30)
+#define IRQ0STATUS_HS_VS_IRQ			BIT(31)
 
 #define TCTRL_GRESET_LEN			0
 
@@ -607,20 +607,20 @@
 #define ISPCTRL_PAR_BRIDGE_MASK			(0x3 << 2)
 
 #define ISPCTRL_PAR_CLK_POL_SHIFT		4
-#define ISPCTRL_PAR_CLK_POL_INV			(1 << 4)
-#define ISPCTRL_PING_PONG_EN			(1 << 5)
+#define ISPCTRL_PAR_CLK_POL_INV			BIT(4)
+#define ISPCTRL_PING_PONG_EN			BIT(5)
 #define ISPCTRL_SHIFT_SHIFT			6
 #define ISPCTRL_SHIFT_0				(0x0 << 6)
 #define ISPCTRL_SHIFT_2				(0x1 << 6)
 #define ISPCTRL_SHIFT_4				(0x2 << 6)
 #define ISPCTRL_SHIFT_MASK			(0x3 << 6)
 
-#define ISPCTRL_CCDC_CLK_EN			(1 << 8)
-#define ISPCTRL_SCMP_CLK_EN			(1 << 9)
-#define ISPCTRL_H3A_CLK_EN			(1 << 10)
-#define ISPCTRL_HIST_CLK_EN			(1 << 11)
-#define ISPCTRL_PREV_CLK_EN			(1 << 12)
-#define ISPCTRL_RSZ_CLK_EN			(1 << 13)
+#define ISPCTRL_CCDC_CLK_EN			BIT(8)
+#define ISPCTRL_SCMP_CLK_EN			BIT(9)
+#define ISPCTRL_H3A_CLK_EN			BIT(10)
+#define ISPCTRL_HIST_CLK_EN			BIT(11)
+#define ISPCTRL_PREV_CLK_EN			BIT(12)
+#define ISPCTRL_RSZ_CLK_EN			BIT(13)
 #define ISPCTRL_SYNC_DETECT_SHIFT		14
 #define ISPCTRL_SYNC_DETECT_HSFALL	(0x0 << ISPCTRL_SYNC_DETECT_SHIFT)
 #define ISPCTRL_SYNC_DETECT_HSRISE	(0x1 << ISPCTRL_SYNC_DETECT_SHIFT)
@@ -628,17 +628,17 @@
 #define ISPCTRL_SYNC_DETECT_VSRISE	(0x3 << ISPCTRL_SYNC_DETECT_SHIFT)
 #define ISPCTRL_SYNC_DETECT_MASK	(0x3 << ISPCTRL_SYNC_DETECT_SHIFT)
 
-#define ISPCTRL_CCDC_RAM_EN		(1 << 16)
-#define ISPCTRL_PREV_RAM_EN		(1 << 17)
-#define ISPCTRL_SBL_RD_RAM_EN		(1 << 18)
-#define ISPCTRL_SBL_WR1_RAM_EN		(1 << 19)
-#define ISPCTRL_SBL_WR0_RAM_EN		(1 << 20)
-#define ISPCTRL_SBL_AUTOIDLE		(1 << 21)
-#define ISPCTRL_SBL_SHARED_WPORTC	(1 << 26)
-#define ISPCTRL_SBL_SHARED_RPORTA	(1 << 27)
-#define ISPCTRL_SBL_SHARED_RPORTB	(1 << 28)
-#define ISPCTRL_JPEG_FLUSH		(1 << 30)
-#define ISPCTRL_CCDC_FLUSH		(1 << 31)
+#define ISPCTRL_CCDC_RAM_EN		BIT(16)
+#define ISPCTRL_PREV_RAM_EN		BIT(17)
+#define ISPCTRL_SBL_RD_RAM_EN		BIT(18)
+#define ISPCTRL_SBL_WR1_RAM_EN		BIT(19)
+#define ISPCTRL_SBL_WR0_RAM_EN		BIT(20)
+#define ISPCTRL_SBL_AUTOIDLE		BIT(21)
+#define ISPCTRL_SBL_SHARED_WPORTC	BIT(26)
+#define ISPCTRL_SBL_SHARED_RPORTA	BIT(27)
+#define ISPCTRL_SBL_SHARED_RPORTB	BIT(28)
+#define ISPCTRL_JPEG_FLUSH		BIT(30)
+#define ISPCTRL_CCDC_FLUSH		BIT(31)
 
 #define ISPSECURE_SECUREMODE		0
 
@@ -655,20 +655,20 @@
 #define ISPTCTRL_CTRL_DIVC_SHIFT	10
 #define ISPTCTRL_CTRL_DIVC_NOCLOCK	(0x0 << 10)
 
-#define ISPTCTRL_CTRL_SHUTEN		(1 << 21)
-#define ISPTCTRL_CTRL_PSTRBEN		(1 << 22)
-#define ISPTCTRL_CTRL_STRBEN		(1 << 23)
-#define ISPTCTRL_CTRL_SHUTPOL		(1 << 24)
-#define ISPTCTRL_CTRL_STRBPSTRBPOL	(1 << 26)
+#define ISPTCTRL_CTRL_SHUTEN		BIT(21)
+#define ISPTCTRL_CTRL_PSTRBEN		BIT(22)
+#define ISPTCTRL_CTRL_STRBEN		BIT(23)
+#define ISPTCTRL_CTRL_SHUTPOL		BIT(24)
+#define ISPTCTRL_CTRL_STRBPSTRBPOL	BIT(26)
 
 #define ISPTCTRL_CTRL_INSEL_SHIFT	27
 #define ISPTCTRL_CTRL_INSEL_PARALLEL	(0x0 << 27)
 #define ISPTCTRL_CTRL_INSEL_CSIA	(0x1 << 27)
 #define ISPTCTRL_CTRL_INSEL_CSIB	(0x2 << 27)
 
-#define ISPTCTRL_CTRL_GRESETEn		(1 << 29)
-#define ISPTCTRL_CTRL_GRESETPOL		(1 << 30)
-#define ISPTCTRL_CTRL_GRESETDIR		(1 << 31)
+#define ISPTCTRL_CTRL_GRESETEn		BIT(29)
+#define ISPTCTRL_CTRL_GRESETPOL		BIT(30)
+#define ISPTCTRL_CTRL_GRESETDIR		BIT(31)
 
 #define ISPTCTRL_FRAME_SHUT_SHIFT		0
 #define ISPTCTRL_FRAME_PSTRB_SHIFT		6
@@ -679,33 +679,33 @@
 #define ISPCCDC_PID_TID_SHIFT			16
 
 #define ISPCCDC_PCR_EN				1
-#define ISPCCDC_PCR_BUSY			(1 << 1)
+#define ISPCCDC_PCR_BUSY			BIT(1)
 
 #define ISPCCDC_SYN_MODE_VDHDOUT		0x1
-#define ISPCCDC_SYN_MODE_FLDOUT			(1 << 1)
-#define ISPCCDC_SYN_MODE_VDPOL			(1 << 2)
-#define ISPCCDC_SYN_MODE_HDPOL			(1 << 3)
-#define ISPCCDC_SYN_MODE_FLDPOL			(1 << 4)
-#define ISPCCDC_SYN_MODE_EXWEN			(1 << 5)
-#define ISPCCDC_SYN_MODE_DATAPOL		(1 << 6)
-#define ISPCCDC_SYN_MODE_FLDMODE		(1 << 7)
+#define ISPCCDC_SYN_MODE_FLDOUT			BIT(1)
+#define ISPCCDC_SYN_MODE_VDPOL			BIT(2)
+#define ISPCCDC_SYN_MODE_HDPOL			BIT(3)
+#define ISPCCDC_SYN_MODE_FLDPOL			BIT(4)
+#define ISPCCDC_SYN_MODE_EXWEN			BIT(5)
+#define ISPCCDC_SYN_MODE_DATAPOL		BIT(6)
+#define ISPCCDC_SYN_MODE_FLDMODE		BIT(7)
 #define ISPCCDC_SYN_MODE_DATSIZ_MASK		(0x7 << 8)
 #define ISPCCDC_SYN_MODE_DATSIZ_8_16		(0x0 << 8)
 #define ISPCCDC_SYN_MODE_DATSIZ_12		(0x4 << 8)
 #define ISPCCDC_SYN_MODE_DATSIZ_11		(0x5 << 8)
 #define ISPCCDC_SYN_MODE_DATSIZ_10		(0x6 << 8)
 #define ISPCCDC_SYN_MODE_DATSIZ_8		(0x7 << 8)
-#define ISPCCDC_SYN_MODE_PACK8			(1 << 11)
+#define ISPCCDC_SYN_MODE_PACK8			BIT(11)
 #define ISPCCDC_SYN_MODE_INPMOD_MASK		(3 << 12)
 #define ISPCCDC_SYN_MODE_INPMOD_RAW		(0 << 12)
 #define ISPCCDC_SYN_MODE_INPMOD_YCBCR16		(1 << 12)
 #define ISPCCDC_SYN_MODE_INPMOD_YCBCR8		(2 << 12)
-#define ISPCCDC_SYN_MODE_LPF			(1 << 14)
-#define ISPCCDC_SYN_MODE_FLDSTAT		(1 << 15)
-#define ISPCCDC_SYN_MODE_VDHDEN			(1 << 16)
-#define ISPCCDC_SYN_MODE_WEN			(1 << 17)
-#define ISPCCDC_SYN_MODE_VP2SDR			(1 << 18)
-#define ISPCCDC_SYN_MODE_SDR2RSZ		(1 << 19)
+#define ISPCCDC_SYN_MODE_LPF			BIT(14)
+#define ISPCCDC_SYN_MODE_FLDSTAT		BIT(15)
+#define ISPCCDC_SYN_MODE_VDHDEN			BIT(16)
+#define ISPCCDC_SYN_MODE_WEN			BIT(17)
+#define ISPCCDC_SYN_MODE_VP2SDR			BIT(18)
+#define ISPCCDC_SYN_MODE_SDR2RSZ		BIT(19)
 
 #define ISPCCDC_HD_VD_WID_VDW_SHIFT		0
 #define ISPCCDC_HD_VD_WID_HDW_SHIFT		16
@@ -731,7 +731,7 @@
 
 #define ISPCCDC_HSIZE_OFF_SHIFT			0
 
-#define ISPCCDC_SDOFST_FIINV			(1 << 14)
+#define ISPCCDC_SDOFST_FIINV			BIT(14)
 #define ISPCCDC_SDOFST_FOFST_SHIFT		12
 #define ISPCCDC_SDOFST_FOFST_MASK		(3 << 12)
 #define ISPCCDC_SDOFST_LOFST3_SHIFT		0
@@ -743,7 +743,7 @@
 #define ISPCCDC_CLAMP_OBST_SHIFT		10
 #define ISPCCDC_CLAMP_OBSLN_SHIFT		25
 #define ISPCCDC_CLAMP_OBSLEN_SHIFT		28
-#define ISPCCDC_CLAMP_CLAMPEN			(1 << 31)
+#define ISPCCDC_CLAMP_CLAMPEN			BIT(31)
 
 #define ISPCCDC_COLPTN_R_Ye			0x0
 #define ISPCCDC_COLPTN_Gr_Cy			0x1
@@ -772,8 +772,8 @@
 #define ISPCCDC_BLKCMP_R_YE_SHIFT		24
 
 #define ISPCCDC_FPC_FPNUM_SHIFT			0
-#define ISPCCDC_FPC_FPCEN			(1 << 15)
-#define ISPCCDC_FPC_FPERR			(1 << 16)
+#define ISPCCDC_FPC_FPCEN			BIT(15)
+#define ISPCCDC_FPC_FPERR			BIT(16)
 
 #define ISPCCDC_VDINT_1_SHIFT			0
 #define ISPCCDC_VDINT_1_MASK			0x00007fff
@@ -784,23 +784,23 @@
 #define ISPCCDC_ALAW_GWDI_11_2			(0x4 << 0)
 #define ISPCCDC_ALAW_GWDI_10_1			(0x5 << 0)
 #define ISPCCDC_ALAW_GWDI_9_0			(0x6 << 0)
-#define ISPCCDC_ALAW_CCDTBL			(1 << 3)
+#define ISPCCDC_ALAW_CCDTBL			BIT(3)
 
 #define ISPCCDC_REC656IF_R656ON			1
-#define ISPCCDC_REC656IF_ECCFVH			(1 << 1)
+#define ISPCCDC_REC656IF_ECCFVH			BIT(1)
 
-#define ISPCCDC_CFG_BW656			(1 << 5)
+#define ISPCCDC_CFG_BW656			BIT(5)
 #define ISPCCDC_CFG_FIDMD_SHIFT			6
-#define ISPCCDC_CFG_WENLOG			(1 << 8)
+#define ISPCCDC_CFG_WENLOG			BIT(8)
 #define ISPCCDC_CFG_WENLOG_AND			(0 << 8)
 #define ISPCCDC_CFG_WENLOG_OR			(1 << 8)
-#define ISPCCDC_CFG_Y8POS			(1 << 11)
-#define ISPCCDC_CFG_BSWD			(1 << 12)
-#define ISPCCDC_CFG_MSBINVI			(1 << 13)
-#define ISPCCDC_CFG_VDLC			(1 << 15)
+#define ISPCCDC_CFG_Y8POS			BIT(11)
+#define ISPCCDC_CFG_BSWD			BIT(12)
+#define ISPCCDC_CFG_MSBINVI			BIT(13)
+#define ISPCCDC_CFG_VDLC			BIT(15)
 
 #define ISPCCDC_FMTCFG_FMTEN			0x1
-#define ISPCCDC_FMTCFG_LNALT			(1 << 1)
+#define ISPCCDC_FMTCFG_LNALT			BIT(1)
 #define ISPCCDC_FMTCFG_LNUM_SHIFT		2
 #define ISPCCDC_FMTCFG_PLEN_ODD_SHIFT		4
 #define ISPCCDC_FMTCFG_PLEN_EVEN_SHIFT		8
@@ -809,7 +809,7 @@
 #define ISPCCDC_FMTCFG_VPIN_11_2		(0x4 << 12)
 #define ISPCCDC_FMTCFG_VPIN_10_1		(0x5 << 12)
 #define ISPCCDC_FMTCFG_VPIN_9_0			(0x6 << 12)
-#define ISPCCDC_FMTCFG_VPEN			(1 << 15)
+#define ISPCCDC_FMTCFG_VPEN			BIT(15)
 
 #define ISPCCDC_FMTCFG_VPIF_FRQ_MASK		0x003f0000
 #define ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT		16
@@ -839,9 +839,9 @@
 #define ISPRSZ_PID_CID_SHIFT			8
 #define ISPRSZ_PID_TID_SHIFT			16
 
-#define ISPRSZ_PCR_ENABLE			(1 << 0)
-#define ISPRSZ_PCR_BUSY				(1 << 1)
-#define ISPRSZ_PCR_ONESHOT			(1 << 2)
+#define ISPRSZ_PCR_ENABLE			BIT(0)
+#define ISPRSZ_PCR_BUSY				BIT(1)
+#define ISPRSZ_PCR_ONESHOT			BIT(2)
 
 #define ISPRSZ_CNT_HRSZ_SHIFT			0
 #define ISPRSZ_CNT_HRSZ_MASK			\
@@ -853,10 +853,10 @@
 #define ISPRSZ_CNT_HSTPH_MASK			(0x7 << ISPRSZ_CNT_HSTPH_SHIFT)
 #define ISPRSZ_CNT_VSTPH_SHIFT			23
 #define ISPRSZ_CNT_VSTPH_MASK			(0x7 << ISPRSZ_CNT_VSTPH_SHIFT)
-#define ISPRSZ_CNT_YCPOS			(1 << 26)
-#define ISPRSZ_CNT_INPTYP			(1 << 27)
-#define ISPRSZ_CNT_INPSRC			(1 << 28)
-#define ISPRSZ_CNT_CBILIN			(1 << 29)
+#define ISPRSZ_CNT_YCPOS			BIT(26)
+#define ISPRSZ_CNT_INPTYP			BIT(27)
+#define ISPRSZ_CNT_INPSRC			BIT(28)
+#define ISPRSZ_CNT_CBILIN			BIT(29)
 
 #define ISPRSZ_OUT_SIZE_HORZ_SHIFT		0
 #define ISPRSZ_OUT_SIZE_HORZ_MASK		\
@@ -1081,8 +1081,8 @@
 #define ISPH3A_PCR_AF_RGBPOS_SHIFT		11
 #define ISPH3A_PCR_AEW_AVE2LMT_SHIFT		22
 #define ISPH3A_PCR_AEW_AVE2LMT_MASK		0xFFC00000
-#define ISPH3A_PCR_BUSYAF			(1 << 15)
-#define ISPH3A_PCR_BUSYAEAWB			(1 << 18)
+#define ISPH3A_PCR_BUSYAF			BIT(15)
+#define ISPH3A_PCR_BUSYAEAWB			BIT(18)
 
 #define ISPH3A_AEWWIN1_WINHC_SHIFT		0
 #define ISPH3A_AEWWIN1_WINHC_MASK		0x3F
@@ -1166,15 +1166,15 @@
 
 #define ISPHIST_HV_INFO_MASK			0x3FFF3FFF
 
-#define ISPCCDC_LSC_ENABLE			1
-#define ISPCCDC_LSC_BUSY			(1 << 7)
+#define ISPCCDC_LSC_ENABLE			BIT(0)
+#define ISPCCDC_LSC_BUSY			BIT(7)
 #define ISPCCDC_LSC_GAIN_MODE_N_MASK		0x700
 #define ISPCCDC_LSC_GAIN_MODE_N_SHIFT		8
 #define ISPCCDC_LSC_GAIN_MODE_M_MASK		0x3800
 #define ISPCCDC_LSC_GAIN_MODE_M_SHIFT		12
 #define ISPCCDC_LSC_GAIN_FORMAT_MASK		0xE
 #define ISPCCDC_LSC_GAIN_FORMAT_SHIFT		1
-#define ISPCCDC_LSC_AFTER_REFORMATTER_MASK	(1<<6)
+#define ISPCCDC_LSC_AFTER_REFORMATTER_MASK	BIT(6)
 
 #define ISPCCDC_LSC_INITIAL_X_MASK		0x3F
 #define ISPCCDC_LSC_INITIAL_X_SHIFT		0
@@ -1196,43 +1196,43 @@
 	(0x1 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
 #define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART	\
 	(0x2 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
-#define ISPCSI2_SYSCONFIG_SOFT_RESET		(1 << 1)
-#define ISPCSI2_SYSCONFIG_AUTO_IDLE		(1 << 0)
+#define ISPCSI2_SYSCONFIG_SOFT_RESET		BIT(1)
+#define ISPCSI2_SYSCONFIG_AUTO_IDLE		BIT(0)
 
 #define ISPCSI2_SYSSTATUS			(0x014)
-#define ISPCSI2_SYSSTATUS_RESET_DONE		(1 << 0)
+#define ISPCSI2_SYSSTATUS_RESET_DONE		BIT(0)
 
 #define ISPCSI2_IRQSTATUS			(0x018)
-#define ISPCSI2_IRQSTATUS_OCP_ERR_IRQ		(1 << 14)
-#define ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ	(1 << 13)
-#define ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ	(1 << 12)
-#define ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ	(1 << 11)
-#define ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ	(1 << 10)
-#define ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ	(1 << 9)
-#define ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ		(1 << 8)
-#define ISPCSI2_IRQSTATUS_CONTEXT(n)		(1 << (n))
+#define ISPCSI2_IRQSTATUS_OCP_ERR_IRQ		BIT(14)
+#define ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ	BIT(13)
+#define ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ	BIT(12)
+#define ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ	BIT(11)
+#define ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ	BIT(10)
+#define ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ	BIT(9)
+#define ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ		BIT(8)
+#define ISPCSI2_IRQSTATUS_CONTEXT(n)		BIT(n)
 
 #define ISPCSI2_IRQENABLE			(0x01c)
 #define ISPCSI2_CTRL				(0x040)
-#define ISPCSI2_CTRL_VP_CLK_EN			(1 << 15)
-#define ISPCSI2_CTRL_VP_ONLY_EN			(1 << 11)
+#define ISPCSI2_CTRL_VP_CLK_EN			BIT(15)
+#define ISPCSI2_CTRL_VP_ONLY_EN			BIT(11)
 #define ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT		8
 #define ISPCSI2_CTRL_VP_OUT_CTRL_MASK		\
 	(3 << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT)
-#define ISPCSI2_CTRL_DBG_EN			(1 << 7)
+#define ISPCSI2_CTRL_DBG_EN			BIT(7)
 #define ISPCSI2_CTRL_BURST_SIZE_SHIFT		5
 #define ISPCSI2_CTRL_BURST_SIZE_MASK		\
 	(3 << ISPCSI2_CTRL_BURST_SIZE_SHIFT)
-#define ISPCSI2_CTRL_FRAME			(1 << 3)
-#define ISPCSI2_CTRL_ECC_EN			(1 << 2)
-#define ISPCSI2_CTRL_SECURE			(1 << 1)
-#define ISPCSI2_CTRL_IF_EN			(1 << 0)
+#define ISPCSI2_CTRL_FRAME			BIT(3)
+#define ISPCSI2_CTRL_ECC_EN			BIT(2)
+#define ISPCSI2_CTRL_SECURE			BIT(1)
+#define ISPCSI2_CTRL_IF_EN			BIT(0)
 
 #define ISPCSI2_DBG_H				(0x044)
 #define ISPCSI2_GNQ				(0x048)
 #define ISPCSI2_PHY_CFG				(0x050)
-#define ISPCSI2_PHY_CFG_RESET_CTRL		(1 << 30)
-#define ISPCSI2_PHY_CFG_RESET_DONE		(1 << 29)
+#define ISPCSI2_PHY_CFG_RESET_CTRL		BIT(30)
+#define ISPCSI2_PHY_CFG_RESET_DONE		BIT(29)
 #define ISPCSI2_PHY_CFG_PWR_CMD_SHIFT		27
 #define ISPCSI2_PHY_CFG_PWR_CMD_MASK		\
 	(0x3 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
@@ -1251,7 +1251,7 @@
 	(0x1 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
 #define ISPCSI2_PHY_CFG_PWR_STATUS_ULPW		\
 	(0x2 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
-#define ISPCSI2_PHY_CFG_PWR_AUTO		(1 << 24)
+#define ISPCSI2_PHY_CFG_PWR_AUTO		BIT(24)
 
 #define ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n)	(3 + ((n) * 4))
 #define ISPCSI2_PHY_CFG_DATA_POL_MASK(n)	\
@@ -1300,63 +1300,63 @@
 	(0x5 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
 
 #define ISPCSI2_PHY_IRQSTATUS			(0x054)
-#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMEXIT	(1 << 26)
-#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMENTER	(1 << 25)
-#define ISPCSI2_PHY_IRQSTATUS_STATEULPM5	(1 << 24)
-#define ISPCSI2_PHY_IRQSTATUS_STATEULPM4	(1 << 23)
-#define ISPCSI2_PHY_IRQSTATUS_STATEULPM3	(1 << 22)
-#define ISPCSI2_PHY_IRQSTATUS_STATEULPM2	(1 << 21)
-#define ISPCSI2_PHY_IRQSTATUS_STATEULPM1	(1 << 20)
-#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL5	(1 << 19)
-#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL4	(1 << 18)
-#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL3	(1 << 17)
-#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL2	(1 << 16)
-#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL1	(1 << 15)
-#define ISPCSI2_PHY_IRQSTATUS_ERRESC5		(1 << 14)
-#define ISPCSI2_PHY_IRQSTATUS_ERRESC4		(1 << 13)
-#define ISPCSI2_PHY_IRQSTATUS_ERRESC3		(1 << 12)
-#define ISPCSI2_PHY_IRQSTATUS_ERRESC2		(1 << 11)
-#define ISPCSI2_PHY_IRQSTATUS_ERRESC1		(1 << 10)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS5	(1 << 9)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS4	(1 << 8)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS3	(1 << 7)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS2	(1 << 6)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS1	(1 << 5)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS5		(1 << 4)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS4		(1 << 3)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS3		(1 << 2)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS2		(1 << 1)
-#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS1		1
+#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMEXIT	BIT(26)
+#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMENTER	BIT(25)
+#define ISPCSI2_PHY_IRQSTATUS_STATEULPM5	BIT(24)
+#define ISPCSI2_PHY_IRQSTATUS_STATEULPM4	BIT(23)
+#define ISPCSI2_PHY_IRQSTATUS_STATEULPM3	BIT(22)
+#define ISPCSI2_PHY_IRQSTATUS_STATEULPM2	BIT(21)
+#define ISPCSI2_PHY_IRQSTATUS_STATEULPM1	BIT(20)
+#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL5	BIT(19)
+#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL4	BIT(18)
+#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL3	BIT(17)
+#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL2	BIT(16)
+#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL1	BIT(15)
+#define ISPCSI2_PHY_IRQSTATUS_ERRESC5		BIT(14)
+#define ISPCSI2_PHY_IRQSTATUS_ERRESC4		BIT(13)
+#define ISPCSI2_PHY_IRQSTATUS_ERRESC3		BIT(12)
+#define ISPCSI2_PHY_IRQSTATUS_ERRESC2		BIT(11)
+#define ISPCSI2_PHY_IRQSTATUS_ERRESC1		BIT(10)
+#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS5	BIT(9)
+#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS4	BIT(8)
+#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS3	BIT(7)
+#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS2	BIT(6)
+#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS1	BIT(5)
+#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS5		BIT(4)
+#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS4		BIT(3)
+#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS3		BIT(2)
+#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS2		BIT(1)
+#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS1		BIT(0)
 
 #define ISPCSI2_SHORT_PACKET			(0x05c)
 #define ISPCSI2_PHY_IRQENABLE			(0x060)
-#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT	(1 << 26)
-#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER	(1 << 25)
-#define ISPCSI2_PHY_IRQENABLE_STATEULPM5	(1 << 24)
-#define ISPCSI2_PHY_IRQENABLE_STATEULPM4	(1 << 23)
-#define ISPCSI2_PHY_IRQENABLE_STATEULPM3	(1 << 22)
-#define ISPCSI2_PHY_IRQENABLE_STATEULPM2	(1 << 21)
-#define ISPCSI2_PHY_IRQENABLE_STATEULPM1	(1 << 20)
-#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL5	(1 << 19)
-#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL4	(1 << 18)
-#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL3	(1 << 17)
-#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL2	(1 << 16)
-#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL1	(1 << 15)
-#define ISPCSI2_PHY_IRQENABLE_ERRESC5		(1 << 14)
-#define ISPCSI2_PHY_IRQENABLE_ERRESC4		(1 << 13)
-#define ISPCSI2_PHY_IRQENABLE_ERRESC3		(1 << 12)
-#define ISPCSI2_PHY_IRQENABLE_ERRESC2		(1 << 11)
-#define ISPCSI2_PHY_IRQENABLE_ERRESC1		(1 << 10)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5	(1 << 9)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4	(1 << 8)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3	(1 << 7)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2	(1 << 6)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1	(1 << 5)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS5		(1 << 4)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS4		(1 << 3)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS3		(1 << 2)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS2		(1 << 1)
-#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS1		(1 << 0)
+#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT	BIT(26)
+#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER	BIT(25)
+#define ISPCSI2_PHY_IRQENABLE_STATEULPM5	BIT(24)
+#define ISPCSI2_PHY_IRQENABLE_STATEULPM4	BIT(23)
+#define ISPCSI2_PHY_IRQENABLE_STATEULPM3	BIT(22)
+#define ISPCSI2_PHY_IRQENABLE_STATEULPM2	BIT(21)
+#define ISPCSI2_PHY_IRQENABLE_STATEULPM1	BIT(20)
+#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL5	BIT(19)
+#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL4	BIT(18)
+#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL3	BIT(17)
+#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL2	BIT(16)
+#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL1	BIT(15)
+#define ISPCSI2_PHY_IRQENABLE_ERRESC5		BIT(14)
+#define ISPCSI2_PHY_IRQENABLE_ERRESC4		BIT(13)
+#define ISPCSI2_PHY_IRQENABLE_ERRESC3		BIT(12)
+#define ISPCSI2_PHY_IRQENABLE_ERRESC2		BIT(11)
+#define ISPCSI2_PHY_IRQENABLE_ERRESC1		BIT(10)
+#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5	BIT(9)
+#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4	BIT(8)
+#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3	BIT(7)
+#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2	BIT(6)
+#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1	BIT(5)
+#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS5		BIT(4)
+#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS4		BIT(3)
+#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS3		BIT(2)
+#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS2		BIT(1)
+#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS1		BIT(0)
 
 #define ISPCSI2_DBG_P				(0x068)
 #define ISPCSI2_TIMING				(0x06c)
@@ -1371,12 +1371,12 @@
 #define ISPCSI2_CTX_CTRL1_COUNT_SHIFT		8
 #define ISPCSI2_CTX_CTRL1_COUNT_MASK		\
 	(0xff << ISPCSI2_CTX_CTRL1_COUNT_SHIFT)
-#define ISPCSI2_CTX_CTRL1_EOF_EN		(1 << 7)
-#define ISPCSI2_CTX_CTRL1_EOL_EN		(1 << 6)
-#define ISPCSI2_CTX_CTRL1_CS_EN			(1 << 5)
-#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK		(1 << 4)
-#define ISPCSI2_CTX_CTRL1_PING_PONG		(1 << 3)
-#define ISPCSI2_CTX_CTRL1_CTX_EN		(1 << 0)
+#define ISPCSI2_CTX_CTRL1_EOF_EN		BIT(7)
+#define ISPCSI2_CTX_CTRL1_EOL_EN		BIT(6)
+#define ISPCSI2_CTX_CTRL1_CS_EN			BIT(5)
+#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK		BIT(4)
+#define ISPCSI2_CTX_CTRL1_PING_PONG		BIT(3)
+#define ISPCSI2_CTX_CTRL1_CTX_EN		BIT(0)
 
 #define ISPCSI2_CTX_CTRL2(n)			((0x074) + 0x20 * (n))
 #define ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT	13
@@ -1385,7 +1385,7 @@
 #define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT	11
 #define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK	\
 	(0x3 <<	ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT)
-#define ISPCSI2_CTX_CTRL2_DPCM_PRED		(1 << 10)
+#define ISPCSI2_CTX_CTRL2_DPCM_PRED		BIT(10)
 #define ISPCSI2_CTX_CTRL2_FORMAT_SHIFT		0
 #define ISPCSI2_CTX_CTRL2_FORMAT_MASK		\
 	(0x3ff << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT)
@@ -1401,24 +1401,24 @@
 #define ISPCSI2_CTX_DAT_PING_ADDR(n)		((0x07c) + 0x20 * (n))
 #define ISPCSI2_CTX_DAT_PONG_ADDR(n)		((0x080) + 0x20 * (n))
 #define ISPCSI2_CTX_IRQENABLE(n)		((0x084) + 0x20 * (n))
-#define ISPCSI2_CTX_IRQENABLE_ECC_CORRECTION_IRQ	(1 << 8)
-#define ISPCSI2_CTX_IRQENABLE_LINE_NUMBER_IRQ	(1 << 7)
-#define ISPCSI2_CTX_IRQENABLE_FRAME_NUMBER_IRQ	(1 << 6)
-#define ISPCSI2_CTX_IRQENABLE_CS_IRQ		(1 << 5)
-#define ISPCSI2_CTX_IRQENABLE_LE_IRQ		(1 << 3)
-#define ISPCSI2_CTX_IRQENABLE_LS_IRQ		(1 << 2)
-#define ISPCSI2_CTX_IRQENABLE_FE_IRQ		(1 << 1)
-#define ISPCSI2_CTX_IRQENABLE_FS_IRQ		(1 << 0)
+#define ISPCSI2_CTX_IRQENABLE_ECC_CORRECTION_IRQ	BIT(8)
+#define ISPCSI2_CTX_IRQENABLE_LINE_NUMBER_IRQ	BIT(7)
+#define ISPCSI2_CTX_IRQENABLE_FRAME_NUMBER_IRQ	BIT(6)
+#define ISPCSI2_CTX_IRQENABLE_CS_IRQ		BIT(5)
+#define ISPCSI2_CTX_IRQENABLE_LE_IRQ		BIT(3)
+#define ISPCSI2_CTX_IRQENABLE_LS_IRQ		BIT(2)
+#define ISPCSI2_CTX_IRQENABLE_FE_IRQ		BIT(1)
+#define ISPCSI2_CTX_IRQENABLE_FS_IRQ		BIT(0)
 
 #define ISPCSI2_CTX_IRQSTATUS(n)		((0x088) + 0x20 * (n))
-#define ISPCSI2_CTX_IRQSTATUS_ECC_CORRECTION_IRQ	(1 << 8)
-#define ISPCSI2_CTX_IRQSTATUS_LINE_NUMBER_IRQ	(1 << 7)
-#define ISPCSI2_CTX_IRQSTATUS_FRAME_NUMBER_IRQ	(1 << 6)
-#define ISPCSI2_CTX_IRQSTATUS_CS_IRQ		(1 << 5)
-#define ISPCSI2_CTX_IRQSTATUS_LE_IRQ		(1 << 3)
-#define ISPCSI2_CTX_IRQSTATUS_LS_IRQ		(1 << 2)
-#define ISPCSI2_CTX_IRQSTATUS_FE_IRQ		(1 << 1)
-#define ISPCSI2_CTX_IRQSTATUS_FS_IRQ		(1 << 0)
+#define ISPCSI2_CTX_IRQSTATUS_ECC_CORRECTION_IRQ	BIT(8)
+#define ISPCSI2_CTX_IRQSTATUS_LINE_NUMBER_IRQ	BIT(7)
+#define ISPCSI2_CTX_IRQSTATUS_FRAME_NUMBER_IRQ	BIT(6)
+#define ISPCSI2_CTX_IRQSTATUS_CS_IRQ		BIT(5)
+#define ISPCSI2_CTX_IRQSTATUS_LE_IRQ		BIT(3)
+#define ISPCSI2_CTX_IRQSTATUS_LS_IRQ		BIT(2)
+#define ISPCSI2_CTX_IRQSTATUS_FE_IRQ		BIT(1)
+#define ISPCSI2_CTX_IRQSTATUS_FS_IRQ		BIT(0)
 
 #define ISPCSI2_CTX_CTRL3(n)			((0x08c) + 0x20 * (n))
 #define ISPCSI2_CTX_CTRL3_ALPHA_SHIFT		5
@@ -1454,9 +1454,9 @@
 	(0xff << ISPCSIPHY_REG0_THS_SETTLE_SHIFT)
 
 #define ISPCSIPHY_REG1					(0x004)
-#define ISPCSIPHY_REG1_RESET_DONE_CTRLCLK		(1 << 29)
+#define ISPCSIPHY_REG1_RESET_DONE_CTRLCLK		BIT(29)
 /* This field is for OMAP3630 only */
-#define ISPCSIPHY_REG1_CLOCK_MISS_DETECTOR_STATUS	(1 << 25)
+#define ISPCSIPHY_REG1_CLOCK_MISS_DETECTOR_STATUS	BIT(25)
 #define ISPCSIPHY_REG1_TCLK_TERM_SHIFT			18
 #define ISPCSIPHY_REG1_TCLK_TERM_MASK			\
 	(0x7f << ISPCSIPHY_REG1_TCLK_TERM_SHIFT)
@@ -1498,11 +1498,11 @@
  */
 
 /* OMAP343X_CONTROL_CSIRXFE */
-#define OMAP343X_CONTROL_CSIRXFE_CSIB_INV	(1 << 7)
-#define OMAP343X_CONTROL_CSIRXFE_RESENABLE	(1 << 8)
-#define OMAP343X_CONTROL_CSIRXFE_SELFORM	(1 << 10)
-#define OMAP343X_CONTROL_CSIRXFE_PWRDNZ		(1 << 12)
-#define OMAP343X_CONTROL_CSIRXFE_RESET		(1 << 13)
+#define OMAP343X_CONTROL_CSIRXFE_CSIB_INV	BIT(7)
+#define OMAP343X_CONTROL_CSIRXFE_RESENABLE	BIT(8)
+#define OMAP343X_CONTROL_CSIRXFE_SELFORM	BIT(10)
+#define OMAP343X_CONTROL_CSIRXFE_PWRDNZ		BIT(12)
+#define OMAP343X_CONTROL_CSIRXFE_RESET		BIT(13)
 
 /* OMAP3630_CONTROL_CAMERA_PHY_CTRL */
 #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY1_SHIFT	2
@@ -1513,6 +1513,6 @@
 #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_GPI		0x3
 #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK		0x3
 /* CCP2B: set to receive data from PHY2 instead of PHY1 */
-#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CSI1_RX_SEL_PHY2	(1 << 4)
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CSI1_RX_SEL_PHY2	BIT(4)
 
 #endif	/* OMAP3_ISP_REG_H */
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 21ca695..78d9dd7 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1681,6 +1681,7 @@
 	int ret;
 
 	/* Register the subdev and video nodes. */
+	res->subdev.dev = vdev->mdev->dev;
 	ret = v4l2_device_register_subdev(vdev, &res->subdev);
 	if (ret < 0)
 		goto error;
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index 62b2eac..5b9b57f 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -1026,6 +1026,8 @@
 int omap3isp_stat_register_entities(struct ispstat *stat,
 				    struct v4l2_device *vdev)
 {
+	stat->subdev.dev = vdev->mdev->dev;
+
 	return v4l2_device_register_subdev(vdev, &stat->subdev);
 }
 
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 499a728..ee183c3 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -658,10 +658,6 @@
 	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
 		| V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS;
 
-	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-	else
-		cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
 
 	return 0;
 }
@@ -1024,8 +1020,8 @@
 
 	ctrls.count = 1;
 	ctrls.controls = &ctrl;
-
-	ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, NULL, &ctrls);
+	ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &video->video,
+			       NULL, &ctrls);
 	if (ret < 0) {
 		dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
 			 pipe->external->name);
@@ -1460,6 +1456,13 @@
 	video->video.vfl_type = VFL_TYPE_GRABBER;
 	video->video.release = video_device_release_empty;
 	video->video.ioctl_ops = &isp_video_ioctl_ops;
+	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		video->video.device_caps = V4L2_CAP_VIDEO_CAPTURE
+					 | V4L2_CAP_STREAMING;
+	else
+		video->video.device_caps = V4L2_CAP_VIDEO_OUTPUT
+					 | V4L2_CAP_STREAMING;
+
 	video->pipe.stream_state = ISP_PIPELINE_STREAM_STOPPED;
 
 	video_set_drvdata(&video->video, video);
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index 1c9bfaa..8d47ea0 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -64,7 +64,7 @@
 #define CIBR1		0x0030
 #define CIBR2		0x0038
 
-#define CICR0_DMAEN	(1 << 31)	/* DMA request enable */
+#define CICR0_DMAEN	(1UL << 31)	/* DMA request enable */
 #define CICR0_PAR_EN	(1 << 30)	/* Parity enable */
 #define CICR0_SL_CAP_EN	(1 << 29)	/* Capture enable for slave mode */
 #define CICR0_ENB	(1 << 28)	/* Camera interface enable */
@@ -81,7 +81,7 @@
 #define CICR0_EOFM	(1 << 1)	/* End-of-frame mask */
 #define CICR0_FOM	(1 << 0)	/* FIFO-overrun mask */
 
-#define CICR1_TBIT	(1 << 31)	/* Transparency bit */
+#define CICR1_TBIT	(1UL << 31)	/* Transparency bit */
 #define CICR1_RGBT_CONV	(0x3 << 29)	/* RGBT conversion mask */
 #define CICR1_PPL	(0x7ff << 15)	/* Pixels per line mask */
 #define CICR1_RGB_CONV	(0x7 << 12)	/* RGB conversion mask */
@@ -1992,9 +1992,6 @@
 	strscpy(cap->bus_info, "platform:pxa-camera", sizeof(cap->bus_info));
 	strscpy(cap->driver, PXA_CAM_DRV_NAME, sizeof(cap->driver));
 	strscpy(cap->card, pxa_cam_driver_description, sizeof(cap->card));
-	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-
 	return 0;
 }
 
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 63da187..3fdc9f9 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -486,9 +486,9 @@
 		asd = v4l2_async_notifier_add_fwnode_subdev(
 			&camss->notifier, of_fwnode_handle(remote),
 			sizeof(*csd));
+		of_node_put(remote);
 		if (IS_ERR(asd)) {
 			ret = PTR_ERR(asd);
-			of_node_put(remote);
 			goto err_cleanup;
 		}
 
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 0acc757..e6eff51 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -198,7 +198,7 @@
 		goto err;
 
 	for (i = 0; i < MAX_CODEC_NUM; i++) {
-		codec = (1 << i) & codecs;
+		codec = (1UL << i) & codecs;
 		if (!codec)
 			continue;
 
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index 9ab95fd..922cb7e 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -46,6 +46,7 @@
 	u32 pixfmt;
 	unsigned int num_planes;
 	u32 type;
+	u32 flags;
 };
 
 #define MAX_PLANES		4
@@ -209,6 +210,25 @@
 
 #define to_venus_buffer(ptr)	container_of(ptr, struct venus_buffer, vb)
 
+enum venus_dec_state {
+	VENUS_DEC_STATE_DEINIT		= 0,
+	VENUS_DEC_STATE_INIT		= 1,
+	VENUS_DEC_STATE_CAPTURE_SETUP	= 2,
+	VENUS_DEC_STATE_STOPPED		= 3,
+	VENUS_DEC_STATE_SEEK		= 4,
+	VENUS_DEC_STATE_DRAIN		= 5,
+	VENUS_DEC_STATE_DECODING	= 6,
+	VENUS_DEC_STATE_DRC		= 7
+};
+
+struct venus_ts_metadata {
+	bool used;
+	u64 ts_ns;
+	u64 ts_us;
+	u32 flags;
+	struct v4l2_timecode tc;
+};
+
 /**
  * struct venus_inst - holds per instance parameters
  *
@@ -232,6 +252,10 @@
  * @colorspace:	current color space
  * @quantization:	current quantization
  * @xfer_func:	current xfer function
+ * @codec_state:	current codec API state (see DEC/ENC_STATE_)
+ * @reconf_wait:	wait queue for resolution change event
+ * @subscriptions:	used to hold current events subscriptions
+ * @buf_count:		used to count number of buffers (reqbuf(0))
  * @fps:		holds current FPS
  * @timeperframe:	holds current time per frame structure
  * @fmt_out:	a reference to output format structure
@@ -246,8 +270,6 @@
  * @opb_buftype:	output picture buffer type
  * @opb_fmt:		output picture buffer raw format
  * @reconfig:	a flag raised by decoder when the stream resolution changed
- * @reconfig_width:	holds the new width
- * @reconfig_height:	holds the new height
  * @hfi_codec:		current codec for this instance in HFI space
  * @sequence_cap:	a sequence counter for capture queue
  * @sequence_out:	a sequence counter for output queue
@@ -287,6 +309,11 @@
 	u8 ycbcr_enc;
 	u8 quantization;
 	u8 xfer_func;
+	enum venus_dec_state codec_state;
+	wait_queue_head_t reconf_wait;
+	unsigned int subscriptions;
+	int buf_count;
+	struct venus_ts_metadata tss[VIDEO_MAX_FRAME];
 	u64 fps;
 	struct v4l2_fract timeperframe;
 	const struct venus_format *fmt_out;
@@ -301,8 +328,6 @@
 	u32 opb_buftype;
 	u32 opb_fmt;
 	bool reconfig;
-	u32 reconfig_width;
-	u32 reconfig_height;
 	u32 hfi_codec;
 	u32 sequence_cap;
 	u32 sequence_out;
diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
index 71b06df..1ad96c2 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -79,7 +79,7 @@
 }
 EXPORT_SYMBOL_GPL(venus_helper_check_codec);
 
-static int venus_helper_queue_dpb_bufs(struct venus_inst *inst)
+int venus_helper_queue_dpb_bufs(struct venus_inst *inst)
 {
 	struct intbuf *buf;
 	int ret = 0;
@@ -100,6 +100,7 @@
 fail:
 	return ret;
 }
+EXPORT_SYMBOL_GPL(venus_helper_queue_dpb_bufs);
 
 int venus_helper_free_dpb_bufs(struct venus_inst *inst)
 {
@@ -278,7 +279,7 @@
 	HFI_BUFFER_INTERNAL_PERSIST_1,
 };
 
-static int intbufs_alloc(struct venus_inst *inst)
+int venus_helper_intbufs_alloc(struct venus_inst *inst)
 {
 	const unsigned int *intbuf;
 	size_t arr_sz, i;
@@ -304,11 +305,59 @@
 	intbufs_unset_buffers(inst);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(venus_helper_intbufs_alloc);
 
-static int intbufs_free(struct venus_inst *inst)
+int venus_helper_intbufs_free(struct venus_inst *inst)
 {
 	return intbufs_unset_buffers(inst);
 }
+EXPORT_SYMBOL_GPL(venus_helper_intbufs_free);
+
+int venus_helper_intbufs_realloc(struct venus_inst *inst)
+{
+	enum hfi_version ver = inst->core->res->hfi_version;
+	struct hfi_buffer_desc bd;
+	struct intbuf *buf, *n;
+	int ret;
+
+	list_for_each_entry_safe(buf, n, &inst->internalbufs, list) {
+		if (buf->type == HFI_BUFFER_INTERNAL_PERSIST ||
+		    buf->type == HFI_BUFFER_INTERNAL_PERSIST_1)
+			continue;
+
+		memset(&bd, 0, sizeof(bd));
+		bd.buffer_size = buf->size;
+		bd.buffer_type = buf->type;
+		bd.num_buffers = 1;
+		bd.device_addr = buf->da;
+		bd.response_required = true;
+
+		ret = hfi_session_unset_buffers(inst, &bd);
+
+		dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,
+			       buf->attrs);
+
+		list_del_init(&buf->list);
+		kfree(buf);
+	}
+
+	ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH(ver));
+	if (ret)
+		goto err;
+
+	ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_1(ver));
+	if (ret)
+		goto err;
+
+	ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_2(ver));
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(venus_helper_intbufs_realloc);
 
 static u32 load_per_instance(struct venus_inst *inst)
 {
@@ -339,7 +388,7 @@
 	return mbs_per_sec;
 }
 
-static int load_scale_clocks(struct venus_core *core)
+int venus_helper_load_scale_clocks(struct venus_core *core)
 {
 	const struct freq_tbl *table = core->res->freq_tbl;
 	unsigned int num_rows = core->res->freq_tbl_size;
@@ -388,6 +437,7 @@
 	dev_err(dev, "failed to set clock rate %lu (%d)\n", freq, ret);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(venus_helper_load_scale_clocks);
 
 static void fill_buffer_desc(const struct venus_buffer *buf,
 			     struct hfi_buffer_desc *bd, bool response)
@@ -413,6 +463,57 @@
 	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
 }
 
+static void
+put_ts_metadata(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	struct vb2_buffer *vb = &vbuf->vb2_buf;
+	unsigned int i;
+	int slot = -1;
+	u64 ts_us = vb->timestamp;
+
+	for (i = 0; i < ARRAY_SIZE(inst->tss); i++) {
+		if (!inst->tss[i].used) {
+			slot = i;
+			break;
+		}
+	}
+
+	if (slot == -1) {
+		dev_dbg(inst->core->dev, "%s: no free slot\n", __func__);
+		return;
+	}
+
+	do_div(ts_us, NSEC_PER_USEC);
+
+	inst->tss[slot].used = true;
+	inst->tss[slot].flags = vbuf->flags;
+	inst->tss[slot].tc = vbuf->timecode;
+	inst->tss[slot].ts_us = ts_us;
+	inst->tss[slot].ts_ns = vb->timestamp;
+}
+
+void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us,
+				  struct vb2_v4l2_buffer *vbuf)
+{
+	struct vb2_buffer *vb = &vbuf->vb2_buf;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(inst->tss); ++i) {
+		if (!inst->tss[i].used)
+			continue;
+
+		if (inst->tss[i].ts_us != timestamp_us)
+			continue;
+
+		inst->tss[i].used = false;
+		vbuf->flags |= inst->tss[i].flags;
+		vbuf->timecode = inst->tss[i].tc;
+		vb->timestamp = inst->tss[i].ts_ns;
+		break;
+	}
+}
+EXPORT_SYMBOL_GPL(venus_helper_get_ts_metadata);
+
 static int
 session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf)
 {
@@ -437,6 +538,9 @@
 
 		if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len)
 			fdata.flags |= HFI_BUFFERFLAG_EOS;
+
+		if (inst->session_type == VIDC_SESSION_TYPE_DEC)
+			put_ts_metadata(inst, vbuf);
 	} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		if (inst->session_type == VIDC_SESSION_TYPE_ENC)
 			fdata.buffer_type = HFI_BUFFER_OUTPUT;
@@ -472,7 +576,7 @@
 	return caps->cap_bufs_mode_dynamic;
 }
 
-static int session_unregister_bufs(struct venus_inst *inst)
+int venus_helper_unregister_bufs(struct venus_inst *inst)
 {
 	struct venus_buffer *buf, *n;
 	struct hfi_buffer_desc bd;
@@ -489,6 +593,7 @@
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(venus_helper_unregister_bufs);
 
 static int session_register_bufs(struct venus_inst *inst)
 {
@@ -947,6 +1052,17 @@
 {
 	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
 	unsigned int out_buf_size = venus_helper_get_opb_size(inst);
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+	if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
+		if (vbuf->field == V4L2_FIELD_ANY)
+			vbuf->field = V4L2_FIELD_NONE;
+		if (vbuf->field != V4L2_FIELD_NONE) {
+			dev_err(inst->core->dev, "%s field isn't supported\n",
+				__func__);
+			return -EINVAL;
+		}
+	}
 
 	if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
 	    vb2_plane_size(vb, 0) < out_buf_size)
@@ -970,16 +1086,19 @@
 
 	v4l2_m2m_buf_queue(m2m_ctx, vbuf);
 
-	if (!(inst->streamon_out & inst->streamon_cap))
+	if (inst->session_type == VIDC_SESSION_TYPE_ENC &&
+	    !(inst->streamon_out && inst->streamon_cap))
 		goto unlock;
 
-	ret = is_buf_refed(inst, vbuf);
-	if (ret)
-		goto unlock;
+	if (vb2_start_streaming_called(vb->vb2_queue)) {
+		ret = is_buf_refed(inst, vbuf);
+		if (ret)
+			goto unlock;
 
-	ret = session_process_buf(inst, vbuf);
-	if (ret)
-		return_buf_error(inst, vbuf);
+		ret = session_process_buf(inst, vbuf);
+		if (ret)
+			return_buf_error(inst, vbuf);
+	}
 
 unlock:
 	mutex_unlock(&inst->lock);
@@ -1009,8 +1128,8 @@
 	if (inst->streamon_out & inst->streamon_cap) {
 		ret = hfi_session_stop(inst);
 		ret |= hfi_session_unload_res(inst);
-		ret |= session_unregister_bufs(inst);
-		ret |= intbufs_free(inst);
+		ret |= venus_helper_unregister_bufs(inst);
+		ret |= venus_helper_intbufs_free(inst);
 		ret |= hfi_session_deinit(inst);
 
 		if (inst->session_error || core->sys_error)
@@ -1021,7 +1140,7 @@
 
 		venus_helper_free_dpb_bufs(inst);
 
-		load_scale_clocks(core);
+		venus_helper_load_scale_clocks(core);
 		INIT_LIST_HEAD(&inst->registeredbufs);
 	}
 
@@ -1036,12 +1155,48 @@
 }
 EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming);
 
+int venus_helper_process_initial_cap_bufs(struct venus_inst *inst)
+{
+	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
+	struct v4l2_m2m_buffer *buf, *n;
+	int ret;
+
+	v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) {
+		ret = session_process_buf(inst, &buf->vb);
+		if (ret) {
+			return_buf_error(inst, &buf->vb);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(venus_helper_process_initial_cap_bufs);
+
+int venus_helper_process_initial_out_bufs(struct venus_inst *inst)
+{
+	struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx;
+	struct v4l2_m2m_buffer *buf, *n;
+	int ret;
+
+	v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) {
+		ret = session_process_buf(inst, &buf->vb);
+		if (ret) {
+			return_buf_error(inst, &buf->vb);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(venus_helper_process_initial_out_bufs);
+
 int venus_helper_vb2_start_streaming(struct venus_inst *inst)
 {
 	struct venus_core *core = inst->core;
 	int ret;
 
-	ret = intbufs_alloc(inst);
+	ret = venus_helper_intbufs_alloc(inst);
 	if (ret)
 		return ret;
 
@@ -1049,7 +1204,7 @@
 	if (ret)
 		goto err_bufs_free;
 
-	load_scale_clocks(core);
+	venus_helper_load_scale_clocks(core);
 
 	ret = hfi_session_load_res(inst);
 	if (ret)
@@ -1059,20 +1214,14 @@
 	if (ret)
 		goto err_unload_res;
 
-	ret = venus_helper_queue_dpb_bufs(inst);
-	if (ret)
-		goto err_session_stop;
-
 	return 0;
 
-err_session_stop:
-	hfi_session_stop(inst);
 err_unload_res:
 	hfi_session_unload_res(inst);
 err_unreg_bufs:
-	session_unregister_bufs(inst);
+	venus_helper_unregister_bufs(inst);
 err_bufs_free:
-	intbufs_free(inst);
+	venus_helper_intbufs_free(inst);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(venus_helper_vb2_start_streaming);
diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h
index 1537836..01f411b 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -9,6 +9,7 @@
 #include <media/videobuf2-v4l2.h>
 
 struct venus_inst;
+struct venus_core;
 
 bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt);
 struct vb2_v4l2_buffer *venus_helper_find_buf(struct venus_inst *inst,
@@ -53,4 +54,14 @@
 int venus_helper_free_dpb_bufs(struct venus_inst *inst);
 int venus_helper_power_enable(struct venus_core *core, u32 session_type,
 			      bool enable);
+int venus_helper_intbufs_alloc(struct venus_inst *inst);
+int venus_helper_intbufs_free(struct venus_inst *inst);
+int venus_helper_intbufs_realloc(struct venus_inst *inst);
+int venus_helper_queue_dpb_bufs(struct venus_inst *inst);
+int venus_helper_unregister_bufs(struct venus_inst *inst);
+int venus_helper_load_scale_clocks(struct venus_core *core);
+int venus_helper_process_initial_cap_bufs(struct venus_inst *inst);
+int venus_helper_process_initial_out_bufs(struct venus_inst *inst);
+void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us,
+				  struct vb2_v4l2_buffer *vbuf);
 #endif
diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c
index 6ad0c17..3d8b1284 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -198,6 +198,9 @@
 	const struct hfi_ops *ops = core->ops;
 	int ret;
 
+	if (inst->state != INST_UNINIT)
+		return -EINVAL;
+
 	inst->hfi_codec = to_codec_type(pixfmt);
 	reinit_completion(&inst->done);
 
@@ -276,6 +279,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hfi_session_start);
 
 int hfi_session_stop(struct venus_inst *inst)
 {
@@ -299,6 +303,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hfi_session_stop);
 
 int hfi_session_continue(struct venus_inst *inst)
 {
@@ -328,6 +333,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hfi_session_abort);
 
 int hfi_session_load_res(struct venus_inst *inst)
 {
@@ -374,15 +380,16 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hfi_session_unload_res);
 
-int hfi_session_flush(struct venus_inst *inst)
+int hfi_session_flush(struct venus_inst *inst, u32 type)
 {
 	const struct hfi_ops *ops = inst->core->ops;
 	int ret;
 
 	reinit_completion(&inst->done);
 
-	ret = ops->session_flush(inst, HFI_FLUSH_ALL);
+	ret = ops->session_flush(inst, type);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/qcom/venus/hfi.h b/drivers/media/platform/qcom/venus/hfi.h
index b121cb1..855822c 100644
--- a/drivers/media/platform/qcom/venus/hfi.h
+++ b/drivers/media/platform/qcom/venus/hfi.h
@@ -161,7 +161,7 @@
 int hfi_session_abort(struct venus_inst *inst);
 int hfi_session_load_res(struct venus_inst *inst);
 int hfi_session_unload_res(struct venus_inst *inst);
-int hfi_session_flush(struct venus_inst *inst);
+int hfi_session_flush(struct venus_inst *inst, u32 type);
 int hfi_session_set_buffers(struct venus_inst *inst,
 			    struct hfi_buffer_desc *bd);
 int hfi_session_unset_buffers(struct venus_inst *inst,
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index e1f9986..7f46605 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -37,42 +37,52 @@
 		.pixfmt = V4L2_PIX_FMT_MPEG4,
 		.num_planes = 1,
 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	}, {
 		.pixfmt = V4L2_PIX_FMT_MPEG2,
 		.num_planes = 1,
 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	}, {
 		.pixfmt = V4L2_PIX_FMT_H263,
 		.num_planes = 1,
 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	}, {
 		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
 		.num_planes = 1,
 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	}, {
 		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
 		.num_planes = 1,
 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	}, {
 		.pixfmt = V4L2_PIX_FMT_H264,
 		.num_planes = 1,
 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	}, {
 		.pixfmt = V4L2_PIX_FMT_VP8,
 		.num_planes = 1,
 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	}, {
 		.pixfmt = V4L2_PIX_FMT_VP9,
 		.num_planes = 1,
 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	}, {
 		.pixfmt = V4L2_PIX_FMT_XVID,
 		.num_planes = 1,
 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	}, {
 		.pixfmt = V4L2_PIX_FMT_HEVC,
 		.num_planes = 1,
 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION,
 	},
 };
 
@@ -133,6 +143,7 @@
 	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
 	struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;
 	const struct venus_format *fmt;
+	u32 szimage;
 
 	memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));
 	memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
@@ -161,14 +172,17 @@
 	pixmp->num_planes = fmt->num_planes;
 	pixmp->flags = 0;
 
-	pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat,
-						     pixmp->width,
-						     pixmp->height);
+	szimage = venus_helper_get_framesz(pixmp->pixelformat, pixmp->width,
+					   pixmp->height);
 
-	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		pfmt[0].sizeimage = szimage;
 		pfmt[0].bytesperline = ALIGN(pixmp->width, 128);
-	else
+	} else {
+		pfmt[0].sizeimage = clamp_t(u32, pfmt[0].sizeimage, 0, SZ_8M);
+		pfmt[0].sizeimage = max(pfmt[0].sizeimage, szimage);
 		pfmt[0].bytesperline = 0;
+	}
 
 	return fmt;
 }
@@ -182,33 +196,56 @@
 	return 0;
 }
 
+static int vdec_check_src_change(struct venus_inst *inst)
+{
+	int ret;
+
+	if (inst->subscriptions & V4L2_EVENT_SOURCE_CHANGE &&
+	    inst->codec_state == VENUS_DEC_STATE_INIT &&
+	    !inst->reconfig)
+		return -EINVAL;
+
+	if (inst->subscriptions & V4L2_EVENT_SOURCE_CHANGE)
+		return 0;
+
+	/*
+	 * The code snippet below is a workaround for backward compatibility
+	 * with applications which doesn't support V4L2 events. It will be
+	 * dropped in future once those applications are fixed.
+	 */
+
+	if (inst->codec_state != VENUS_DEC_STATE_INIT)
+		goto done;
+
+	ret = wait_event_timeout(inst->reconf_wait, inst->reconfig,
+				 msecs_to_jiffies(100));
+	if (!ret)
+		return -EINVAL;
+
+	if (!(inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) ||
+	    !inst->reconfig)
+		dev_dbg(inst->core->dev, "%s: wrong state\n", __func__);
+
+done:
+	return 0;
+}
+
 static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
 {
 	struct venus_inst *inst = to_inst(file);
 	const struct venus_format *fmt = NULL;
 	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	int ret;
 
 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
 		fmt = inst->fmt_cap;
 	else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 		fmt = inst->fmt_out;
 
-	if (inst->reconfig) {
-		struct v4l2_format format = {};
-
-		inst->out_width = inst->reconfig_width;
-		inst->out_height = inst->reconfig_height;
-		inst->reconfig = false;
-
-		format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-		format.fmt.pix_mp.pixelformat = inst->fmt_cap->pixfmt;
-		format.fmt.pix_mp.width = inst->out_width;
-		format.fmt.pix_mp.height = inst->out_height;
-
-		vdec_try_fmt_common(inst, &format);
-
-		inst->width = format.fmt.pix_mp.width;
-		inst->height = format.fmt.pix_mp.height;
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+		ret = vdec_check_src_change(inst);
+		if (ret)
+			return ret;
 	}
 
 	pixmp->pixelformat = fmt->pixfmt;
@@ -266,6 +303,7 @@
 		inst->ycbcr_enc = pixmp->ycbcr_enc;
 		inst->quantization = pixmp->quantization;
 		inst->xfer_func = pixmp->xfer_func;
+		inst->input_buf_size = pixmp->plane_fmt[0].sizeimage;
 	}
 
 	memset(&format, 0, sizeof(format));
@@ -351,6 +389,7 @@
 		return -EINVAL;
 
 	f->pixelformat = fmt->pixfmt;
+	f->flags = fmt->flags;
 
 	return 0;
 }
@@ -422,11 +461,18 @@
 static int vdec_subscribe_event(struct v4l2_fh *fh,
 				const struct v4l2_event_subscription *sub)
 {
+	struct venus_inst *inst = container_of(fh, struct venus_inst, fh);
+	int ret;
+
 	switch (sub->type) {
 	case V4L2_EVENT_EOS:
 		return v4l2_event_subscribe(fh, sub, 2, NULL);
 	case V4L2_EVENT_SOURCE_CHANGE:
-		return v4l2_src_change_event_subscribe(fh, sub);
+		ret = v4l2_src_change_event_subscribe(fh, sub);
+		if (ret)
+			return ret;
+		inst->subscriptions |= V4L2_EVENT_SOURCE_CHANGE;
+		return 0;
 	case V4L2_EVENT_CTRL:
 		return v4l2_ctrl_subscribe_event(fh, sub);
 	default:
@@ -435,45 +481,35 @@
 }
 
 static int
-vdec_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
-{
-	switch (cmd->cmd) {
-	case V4L2_DEC_CMD_STOP:
-		if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK)
-			return -EINVAL;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int
 vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
 {
 	struct venus_inst *inst = to_inst(file);
 	struct hfi_frame_data fdata = {0};
 	int ret;
 
-	ret = vdec_try_decoder_cmd(file, fh, cmd);
+	ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
 	if (ret)
 		return ret;
 
 	mutex_lock(&inst->lock);
 
-	/*
-	 * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on decoder
-	 * input to signal EOS.
-	 */
-	if (!(inst->streamon_out & inst->streamon_cap))
-		goto unlock;
+	if (cmd->cmd == V4L2_DEC_CMD_STOP) {
+		/*
+		 * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on
+		 * decoder input to signal EOS.
+		 */
+		if (!(inst->streamon_out && inst->streamon_cap))
+			goto unlock;
 
-	fdata.buffer_type = HFI_BUFFER_INPUT;
-	fdata.flags |= HFI_BUFFERFLAG_EOS;
-	fdata.device_addr = 0xdeadbeef;
+		fdata.buffer_type = HFI_BUFFER_INPUT;
+		fdata.flags |= HFI_BUFFERFLAG_EOS;
+		fdata.device_addr = 0xdeadb000;
 
-	ret = hfi_session_process_buf(inst, &fdata);
+		ret = hfi_session_process_buf(inst, &fdata);
+
+		if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING)
+			inst->codec_state = VENUS_DEC_STATE_DRAIN;
+	}
 
 unlock:
 	mutex_unlock(&inst->lock);
@@ -504,7 +540,7 @@
 	.vidioc_enum_framesizes = vdec_enum_framesizes,
 	.vidioc_subscribe_event = vdec_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
-	.vidioc_try_decoder_cmd = vdec_try_decoder_cmd,
+	.vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd,
 	.vidioc_decoder_cmd = vdec_decoder_cmd,
 };
 
@@ -634,20 +670,18 @@
 	return 0;
 }
 
-static int vdec_init_session(struct venus_inst *inst)
+static int vdec_session_init(struct venus_inst *inst)
 {
 	int ret;
 
 	ret = hfi_session_init(inst, inst->fmt_out->pixfmt);
-	if (ret)
+	if (ret == -EINVAL)
+		return 0;
+	else if (ret)
 		return ret;
 
-	ret = venus_helper_set_input_resolution(inst, inst->out_width,
-						inst->out_height);
-	if (ret)
-		goto deinit;
-
-	ret = venus_helper_set_color_format(inst, inst->fmt_cap->pixfmt);
+	ret = venus_helper_set_input_resolution(inst, frame_width_min(inst),
+						frame_height_min(inst));
 	if (ret)
 		goto deinit;
 
@@ -666,26 +700,19 @@
 
 	*in_num = *out_num = 0;
 
-	ret = vdec_init_session(inst);
-	if (ret)
-		return ret;
-
 	ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq);
 	if (ret)
-		goto deinit;
+		return ret;
 
 	*in_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver);
 
 	ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
 	if (ret)
-		goto deinit;
+		return ret;
 
 	*out_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver);
 
-deinit:
-	hfi_session_deinit(inst);
-
-	return ret;
+	return 0;
 }
 
 static int vdec_queue_setup(struct vb2_queue *q,
@@ -718,6 +745,10 @@
 		return 0;
 	}
 
+	ret = vdec_session_init(inst);
+	if (ret)
+		return ret;
+
 	ret = vdec_num_buffers(inst, &in_num, &out_num);
 	if (ret)
 		return ret;
@@ -728,6 +759,7 @@
 		sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt,
 						    inst->out_width,
 						    inst->out_height);
+		sizes[0] = max(sizes[0], inst->input_buf_size);
 		inst->input_buf_size = sizes[0];
 		*num_buffers = max(*num_buffers, in_num);
 		inst->num_input_bufs = *num_buffers;
@@ -741,6 +773,11 @@
 		inst->output_buf_size = sizes[0];
 		*num_buffers = max(*num_buffers, out_num);
 		inst->num_output_bufs = *num_buffers;
+
+		mutex_lock(&inst->lock);
+		if (inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP)
+			inst->codec_state = VENUS_DEC_STATE_STOPPED;
+		mutex_unlock(&inst->lock);
 		break;
 	default:
 		ret = -EINVAL;
@@ -777,6 +814,131 @@
 	return 0;
 }
 
+static int vdec_start_capture(struct venus_inst *inst)
+{
+	int ret;
+
+	if (!inst->streamon_out)
+		return 0;
+
+	if (inst->codec_state == VENUS_DEC_STATE_DECODING) {
+		if (inst->reconfig)
+			goto reconfigure;
+
+		venus_helper_queue_dpb_bufs(inst);
+		venus_helper_process_initial_cap_bufs(inst);
+		inst->streamon_cap = 1;
+		return 0;
+	}
+
+	if (inst->codec_state != VENUS_DEC_STATE_STOPPED)
+		return 0;
+
+reconfigure:
+	ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT);
+	if (ret)
+		return ret;
+
+	ret = vdec_output_conf(inst);
+	if (ret)
+		return ret;
+
+	ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
+					VB2_MAX_FRAME, VB2_MAX_FRAME);
+	if (ret)
+		return ret;
+
+	ret = venus_helper_intbufs_realloc(inst);
+	if (ret)
+		goto err;
+
+	ret = venus_helper_alloc_dpb_bufs(inst);
+	if (ret)
+		goto err;
+
+	ret = venus_helper_queue_dpb_bufs(inst);
+	if (ret)
+		goto free_dpb_bufs;
+
+	ret = venus_helper_process_initial_cap_bufs(inst);
+	if (ret)
+		goto free_dpb_bufs;
+
+	venus_helper_load_scale_clocks(inst->core);
+
+	ret = hfi_session_continue(inst);
+	if (ret)
+		goto free_dpb_bufs;
+
+	inst->codec_state = VENUS_DEC_STATE_DECODING;
+
+	inst->streamon_cap = 1;
+	inst->sequence_cap = 0;
+	inst->reconfig = false;
+
+	return 0;
+
+free_dpb_bufs:
+	venus_helper_free_dpb_bufs(inst);
+err:
+	return ret;
+}
+
+static int vdec_start_output(struct venus_inst *inst)
+{
+	int ret;
+
+	if (inst->codec_state == VENUS_DEC_STATE_SEEK) {
+		ret = venus_helper_process_initial_out_bufs(inst);
+		inst->codec_state = VENUS_DEC_STATE_DECODING;
+		goto done;
+	}
+
+	if (inst->codec_state == VENUS_DEC_STATE_INIT ||
+	    inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) {
+		ret = venus_helper_process_initial_out_bufs(inst);
+		goto done;
+	}
+
+	if (inst->codec_state != VENUS_DEC_STATE_DEINIT)
+		return -EINVAL;
+
+	venus_helper_init_instance(inst);
+	inst->sequence_out = 0;
+	inst->reconfig = false;
+
+	ret = vdec_set_properties(inst);
+	if (ret)
+		return ret;
+
+	ret = vdec_output_conf(inst);
+	if (ret)
+		return ret;
+
+	ret = vdec_verify_conf(inst);
+	if (ret)
+		return ret;
+
+	ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
+					VB2_MAX_FRAME, VB2_MAX_FRAME);
+	if (ret)
+		return ret;
+
+	ret = venus_helper_vb2_start_streaming(inst);
+	if (ret)
+		return ret;
+
+	ret = venus_helper_process_initial_out_bufs(inst);
+	if (ret)
+		return ret;
+
+	inst->codec_state = VENUS_DEC_STATE_INIT;
+
+done:
+	inst->streamon_out = 1;
+	return ret;
+}
+
 static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
 {
 	struct venus_inst *inst = vb2_get_drv_priv(q);
@@ -784,73 +946,163 @@
 
 	mutex_lock(&inst->lock);
 
-	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
-		inst->streamon_out = 1;
+	if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		ret = vdec_start_capture(inst);
 	else
-		inst->streamon_cap = 1;
+		ret = vdec_start_output(inst);
 
-	if (!(inst->streamon_out & inst->streamon_cap)) {
-		mutex_unlock(&inst->lock);
-		return 0;
-	}
-
-	venus_helper_init_instance(inst);
-
-	inst->reconfig = false;
-	inst->sequence_cap = 0;
-	inst->sequence_out = 0;
-
-	ret = vdec_init_session(inst);
 	if (ret)
-		goto bufs_done;
-
-	ret = vdec_set_properties(inst);
-	if (ret)
-		goto deinit_sess;
-
-	ret = vdec_output_conf(inst);
-	if (ret)
-		goto deinit_sess;
-
-	ret = vdec_verify_conf(inst);
-	if (ret)
-		goto deinit_sess;
-
-	ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
-					VB2_MAX_FRAME, VB2_MAX_FRAME);
-	if (ret)
-		goto deinit_sess;
-
-	ret = venus_helper_alloc_dpb_bufs(inst);
-	if (ret)
-		goto deinit_sess;
-
-	ret = venus_helper_vb2_start_streaming(inst);
-	if (ret)
-		goto deinit_sess;
+		goto error;
 
 	mutex_unlock(&inst->lock);
-
 	return 0;
 
-deinit_sess:
-	hfi_session_deinit(inst);
-bufs_done:
+error:
 	venus_helper_buffers_done(inst, VB2_BUF_STATE_QUEUED);
-	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
-		inst->streamon_out = 0;
-	else
-		inst->streamon_cap = 0;
 	mutex_unlock(&inst->lock);
 	return ret;
 }
 
+static void vdec_cancel_dst_buffers(struct venus_inst *inst)
+{
+	struct vb2_v4l2_buffer *buf;
+
+	while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx)))
+		v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR);
+}
+
+static int vdec_stop_capture(struct venus_inst *inst)
+{
+	int ret = 0;
+
+	switch (inst->codec_state) {
+	case VENUS_DEC_STATE_DECODING:
+		ret = hfi_session_flush(inst, HFI_FLUSH_ALL);
+		/* fallthrough */
+	case VENUS_DEC_STATE_DRAIN:
+		vdec_cancel_dst_buffers(inst);
+		inst->codec_state = VENUS_DEC_STATE_STOPPED;
+		break;
+	case VENUS_DEC_STATE_DRC:
+		ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT);
+		vdec_cancel_dst_buffers(inst);
+		inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
+		INIT_LIST_HEAD(&inst->registeredbufs);
+		venus_helper_free_dpb_bufs(inst);
+		break;
+	default:
+		return 0;
+	}
+
+	return ret;
+}
+
+static int vdec_stop_output(struct venus_inst *inst)
+{
+	int ret = 0;
+
+	switch (inst->codec_state) {
+	case VENUS_DEC_STATE_DECODING:
+	case VENUS_DEC_STATE_DRAIN:
+	case VENUS_DEC_STATE_STOPPED:
+		ret = hfi_session_flush(inst, HFI_FLUSH_ALL);
+		inst->codec_state = VENUS_DEC_STATE_SEEK;
+		break;
+	case VENUS_DEC_STATE_INIT:
+	case VENUS_DEC_STATE_CAPTURE_SETUP:
+		ret = hfi_session_flush(inst, HFI_FLUSH_INPUT);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static void vdec_stop_streaming(struct vb2_queue *q)
+{
+	struct venus_inst *inst = vb2_get_drv_priv(q);
+	int ret = -EINVAL;
+
+	mutex_lock(&inst->lock);
+
+	if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		ret = vdec_stop_capture(inst);
+	else
+		ret = vdec_stop_output(inst);
+
+	venus_helper_buffers_done(inst, VB2_BUF_STATE_ERROR);
+
+	if (ret)
+		goto unlock;
+
+	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		inst->streamon_out = 0;
+	else
+		inst->streamon_cap = 0;
+
+unlock:
+	mutex_unlock(&inst->lock);
+}
+
+static void vdec_session_release(struct venus_inst *inst)
+{
+	struct venus_core *core = inst->core;
+	int ret, abort = 0;
+
+	mutex_lock(&inst->lock);
+
+	inst->codec_state = VENUS_DEC_STATE_DEINIT;
+
+	ret = hfi_session_stop(inst);
+	abort = (ret && ret != -EINVAL) ? 1 : 0;
+	ret = hfi_session_unload_res(inst);
+	abort = (ret && ret != -EINVAL) ? 1 : 0;
+	ret = venus_helper_unregister_bufs(inst);
+	abort = (ret && ret != -EINVAL) ? 1 : 0;
+	ret = venus_helper_intbufs_free(inst);
+	abort = (ret && ret != -EINVAL) ? 1 : 0;
+	ret = hfi_session_deinit(inst);
+	abort = (ret && ret != -EINVAL) ? 1 : 0;
+
+	if (inst->session_error || core->sys_error)
+		abort = 1;
+
+	if (abort)
+		hfi_session_abort(inst);
+
+	venus_helper_free_dpb_bufs(inst);
+	venus_helper_load_scale_clocks(core);
+	INIT_LIST_HEAD(&inst->registeredbufs);
+
+	mutex_unlock(&inst->lock);
+}
+
+static int vdec_buf_init(struct vb2_buffer *vb)
+{
+	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+
+	inst->buf_count++;
+
+	return venus_helper_vb2_buf_init(vb);
+}
+
+static void vdec_buf_cleanup(struct vb2_buffer *vb)
+{
+	struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+
+	inst->buf_count--;
+	if (!inst->buf_count)
+		vdec_session_release(inst);
+}
+
 static const struct vb2_ops vdec_vb2_ops = {
 	.queue_setup = vdec_queue_setup,
-	.buf_init = venus_helper_vb2_buf_init,
+	.buf_init = vdec_buf_init,
+	.buf_cleanup = vdec_buf_cleanup,
 	.buf_prepare = venus_helper_vb2_buf_prepare,
 	.start_streaming = vdec_start_streaming,
-	.stop_streaming = venus_helper_vb2_stop_streaming,
+	.stop_streaming = vdec_stop_streaming,
 	.buf_queue = venus_helper_vb2_buf_queue,
 };
 
@@ -874,9 +1126,9 @@
 
 	vbuf->flags = flags;
 	vbuf->field = V4L2_FIELD_NONE;
+	vb = &vbuf->vb2_buf;
 
 	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
-		vb = &vbuf->vb2_buf;
 		vb2_set_plane_payload(vb, 0, bytesused);
 		vb->planes[0].data_offset = data_offset;
 		vb->timestamp = timestamp_us * NSEC_PER_USEC;
@@ -886,28 +1138,85 @@
 			const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
 
 			v4l2_event_queue_fh(&inst->fh, &ev);
+
+			if (inst->codec_state == VENUS_DEC_STATE_DRAIN)
+				inst->codec_state = VENUS_DEC_STATE_STOPPED;
 		}
 	} else {
 		vbuf->sequence = inst->sequence_out++;
 	}
 
+	venus_helper_get_ts_metadata(inst, timestamp_us, vbuf);
+
 	if (hfi_flags & HFI_BUFFERFLAG_READONLY)
 		venus_helper_acquire_buf_ref(vbuf);
 
 	if (hfi_flags & HFI_BUFFERFLAG_DATACORRUPT)
 		state = VB2_BUF_STATE_ERROR;
 
+	if (hfi_flags & HFI_BUFFERFLAG_DROP_FRAME) {
+		state = VB2_BUF_STATE_ERROR;
+		vb2_set_plane_payload(vb, 0, 0);
+		vb->timestamp = 0;
+	}
+
 	v4l2_m2m_buf_done(vbuf, state);
 }
 
+static void vdec_event_change(struct venus_inst *inst,
+			      struct hfi_event_data *ev_data, bool sufficient)
+{
+	static const struct v4l2_event ev = {
+		.type = V4L2_EVENT_SOURCE_CHANGE,
+		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION };
+	struct device *dev = inst->core->dev_dec;
+	struct v4l2_format format = {};
+
+	mutex_lock(&inst->lock);
+
+	format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	format.fmt.pix_mp.pixelformat = inst->fmt_cap->pixfmt;
+	format.fmt.pix_mp.width = ev_data->width;
+	format.fmt.pix_mp.height = ev_data->height;
+
+	vdec_try_fmt_common(inst, &format);
+
+	inst->width = format.fmt.pix_mp.width;
+	inst->height = format.fmt.pix_mp.height;
+
+	inst->out_width = ev_data->width;
+	inst->out_height = ev_data->height;
+
+	dev_dbg(dev, "event %s sufficient resources (%ux%u)\n",
+		sufficient ? "" : "not", ev_data->width, ev_data->height);
+
+	if (sufficient) {
+		hfi_session_continue(inst);
+	} else {
+		switch (inst->codec_state) {
+		case VENUS_DEC_STATE_INIT:
+			inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP;
+			break;
+		case VENUS_DEC_STATE_DECODING:
+			inst->codec_state = VENUS_DEC_STATE_DRC;
+			break;
+		default:
+			break;
+		}
+	}
+
+	inst->reconfig = true;
+	v4l2_event_queue_fh(&inst->fh, &ev);
+	wake_up(&inst->reconf_wait);
+
+	mutex_unlock(&inst->lock);
+}
+
 static void vdec_event_notify(struct venus_inst *inst, u32 event,
 			      struct hfi_event_data *data)
 {
 	struct venus_core *core = inst->core;
 	struct device *dev = core->dev_dec;
-	static const struct v4l2_event ev = {
-		.type = V4L2_EVENT_SOURCE_CHANGE,
-		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION };
 
 	switch (event) {
 	case EVT_SESSION_ERROR:
@@ -917,18 +1226,10 @@
 	case EVT_SYS_EVENT_CHANGE:
 		switch (data->event_type) {
 		case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES:
-			hfi_session_continue(inst);
-			dev_dbg(dev, "event sufficient resources\n");
+			vdec_event_change(inst, data, true);
 			break;
 		case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES:
-			inst->reconfig_height = data->height;
-			inst->reconfig_width = data->width;
-			inst->reconfig = true;
-
-			v4l2_event_queue_fh(&inst->fh, &ev);
-
-			dev_dbg(dev, "event not sufficient resources (%ux%u)\n",
-				data->width, data->height);
+			vdec_event_change(inst, data, false);
 			break;
 		case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
 			venus_helper_release_buf_ref(inst, data->tag);
@@ -949,20 +1250,25 @@
 
 static void vdec_inst_init(struct venus_inst *inst)
 {
+	inst->hfi_codec = HFI_VIDEO_CODEC_H264;
 	inst->fmt_out = &vdec_formats[6];
 	inst->fmt_cap = &vdec_formats[0];
-	inst->width = 1280;
-	inst->height = ALIGN(720, 32);
-	inst->out_width = 1280;
-	inst->out_height = 720;
+	inst->width = frame_width_min(inst);
+	inst->height = ALIGN(frame_height_min(inst), 32);
+	inst->out_width = frame_width_min(inst);
+	inst->out_height = frame_height_min(inst);
 	inst->fps = 30;
 	inst->timeperframe.numerator = 1;
 	inst->timeperframe.denominator = 30;
-	inst->hfi_codec = HFI_VIDEO_CODEC_H264;
+	inst->opb_buftype = HFI_BUFFER_OUTPUT;
+}
+
+static void vdec_m2m_device_run(void *priv)
+{
 }
 
 static const struct v4l2_m2m_ops vdec_m2m_ops = {
-	.device_run = venus_helper_m2m_device_run,
+	.device_run = vdec_m2m_device_run,
 	.job_abort = venus_helper_m2m_job_abort,
 };
 
@@ -980,7 +1286,7 @@
 	src_vq->drv_priv = inst;
 	src_vq->buf_struct_size = sizeof(struct venus_buffer);
 	src_vq->allow_zero_bytesused = 1;
-	src_vq->min_buffers_needed = 1;
+	src_vq->min_buffers_needed = 0;
 	src_vq->dev = inst->core->dev;
 	ret = vb2_queue_init(src_vq);
 	if (ret)
@@ -994,7 +1300,7 @@
 	dst_vq->drv_priv = inst;
 	dst_vq->buf_struct_size = sizeof(struct venus_buffer);
 	dst_vq->allow_zero_bytesused = 1;
-	dst_vq->min_buffers_needed = 1;
+	dst_vq->min_buffers_needed = 0;
 	dst_vq->dev = inst->core->dev;
 	ret = vb2_queue_init(dst_vq);
 	if (ret) {
@@ -1024,7 +1330,9 @@
 	inst->core = core;
 	inst->session_type = VIDC_SESSION_TYPE_DEC;
 	inst->num_output_bufs = 1;
-
+	inst->codec_state = VENUS_DEC_STATE_DEINIT;
+	inst->buf_count = 0;
+	init_waitqueue_head(&inst->reconf_wait);
 	venus_helper_init_instance(inst);
 
 	ret = pm_runtime_get_sync(core->dev_dec);
diff --git a/drivers/media/platform/qcom/venus/vdec_ctrls.c b/drivers/media/platform/qcom/venus/vdec_ctrls.c
index 300350b..3a963cb 100644
--- a/drivers/media/platform/qcom/venus/vdec_ctrls.c
+++ b/drivers/media/platform/qcom/venus/vdec_ctrls.c
@@ -7,6 +7,7 @@
 #include <media/v4l2-ctrls.h>
 
 #include "core.h"
+#include "helpers.h"
 #include "vdec.h"
 
 static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -38,7 +39,9 @@
 {
 	struct venus_inst *inst = ctrl_to_inst(ctrl);
 	struct vdec_controls *ctr = &inst->controls.dec;
+	struct hfi_buffer_requirements bufreq;
 	union hfi_get_property hprop;
+	enum hfi_version ver = inst->core->res->hfi_version;
 	u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
 	int ret;
 
@@ -62,7 +65,9 @@
 		ctrl->val = ctr->post_loop_deb_mode;
 		break;
 	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
-		ctrl->val = inst->num_output_bufs;
+		ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
+		if (!ret)
+			ctrl->val = HFI_BUFREQ_COUNT_MIN(&bufreq, ver);
 		break;
 	default:
 		return -EINVAL;
diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
index a5f3d2c4..1b7fb2d58 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -294,6 +294,7 @@
 	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
 	struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;
 	const struct venus_format *fmt;
+	u32 sizeimage;
 
 	memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));
 	memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
@@ -325,9 +326,10 @@
 	pixmp->num_planes = fmt->num_planes;
 	pixmp->flags = 0;
 
-	pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat,
-						     pixmp->width,
-						     pixmp->height);
+	sizeimage = venus_helper_get_framesz(pixmp->pixelformat,
+					     pixmp->width,
+					     pixmp->height);
+	pfmt[0].sizeimage = max(ALIGN(pfmt[0].sizeimage, SZ_4K), sizeimage);
 
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 		pfmt[0].bytesperline = ALIGN(pixmp->width, 128);
@@ -399,8 +401,10 @@
 
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 		inst->fmt_out = fmt;
-	else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+	else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		inst->fmt_cap = fmt;
+		inst->output_buf_size = pixmp->plane_fmt[0].sizeimage;
+	}
 
 	return 0;
 }
@@ -918,6 +922,7 @@
 		sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt,
 						    inst->width,
 						    inst->height);
+		sizes[0] = max(sizes[0], inst->output_buf_size);
 		inst->output_buf_size = sizes[0];
 		break;
 	default:
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 64f9cf7..6993484 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -390,6 +390,28 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * Controls
+ */
+
+static int rvin_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct rvin_dev *vin =
+		container_of(ctrl->handler, struct rvin_dev, ctrl_handler);
+
+	switch (ctrl->id) {
+	case V4L2_CID_ALPHA_COMPONENT:
+		rvin_set_alpha(vin, ctrl->val);
+		break;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops rvin_ctrl_ops = {
+	.s_ctrl = rvin_s_ctrl,
+};
+
+/* -----------------------------------------------------------------------------
  * Async notifier
  */
 
@@ -478,6 +500,15 @@
 	if (ret < 0)
 		return ret;
 
+	v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
+			  V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
+
+	if (vin->ctrl_handler.error) {
+		ret = vin->ctrl_handler.error;
+		v4l2_ctrl_handler_free(&vin->ctrl_handler);
+		return ret;
+	}
+
 	ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler,
 				    NULL, true);
 	if (ret < 0) {
@@ -633,7 +664,7 @@
 	ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
 	if (ret < 0) {
 		vin_err(vin, "Notifier registration failed\n");
-		v4l2_async_notifier_cleanup(&vin->group->notifier);
+		v4l2_async_notifier_cleanup(&vin->notifier);
 		return ret;
 	}
 
@@ -870,6 +901,21 @@
 	if (ret)
 		rvin_group_put(vin);
 
+	ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 1);
+	if (ret < 0)
+		return ret;
+
+	v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
+			  V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
+
+	if (vin->ctrl_handler.error) {
+		ret = vin->ctrl_handler.error;
+		v4l2_ctrl_handler_free(&vin->ctrl_handler);
+		return ret;
+	}
+
+	vin->vdev.ctrl_handler = &vin->ctrl_handler;
+
 	return ret;
 }
 
@@ -1245,6 +1291,7 @@
 
 	vin->dev = &pdev->dev;
 	vin->info = of_device_get_match_data(&pdev->dev);
+	vin->alpha = 0xff;
 
 	/*
 	 * Special care is needed on r8a7795 ES1.x since it
@@ -1288,6 +1335,8 @@
 	return 0;
 
 error_group_unregister:
+	v4l2_ctrl_handler_free(&vin->ctrl_handler);
+
 	if (vin->info->use_mc) {
 		mutex_lock(&vin->group->lock);
 		if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
@@ -1323,10 +1372,10 @@
 		}
 		mutex_unlock(&vin->group->lock);
 		rvin_group_put(vin);
-	} else {
-		v4l2_ctrl_handler_free(&vin->ctrl_handler);
 	}
 
+	v4l2_ctrl_handler_free(&vin->ctrl_handler);
+
 	rvin_dma_unregister(vin);
 
 	return 0;
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index 91ab064..3cb29b2 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -111,10 +111,13 @@
 #define VNIE_EFE		(1 << 1)
 
 /* Video n Data Mode Register bits */
+#define VNDMR_A8BIT(n)		(((n) & 0xff) << 24)
+#define VNDMR_A8BIT_MASK	(0xff << 24)
 #define VNDMR_EXRGB		(1 << 8)
 #define VNDMR_BPSM		(1 << 4)
+#define VNDMR_ABIT		(1 << 2)
 #define VNDMR_DTMD_YCSEP	(1 << 1)
-#define VNDMR_DTMD_ARGB1555	(1 << 0)
+#define VNDMR_DTMD_ARGB		(1 << 0)
 
 /* Video n Data Mode Register 2 bits */
 #define VNDMR2_VPS		(1 << 30)
@@ -574,6 +577,9 @@
 
 void rvin_crop_scale_comp(struct rvin_dev *vin)
 {
+	const struct rvin_video_format *fmt;
+	u32 stride;
+
 	/* Set Start/End Pixel/Line Pre-Clip */
 	rvin_write(vin, vin->crop.left, VNSPPRC_REG);
 	rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
@@ -597,10 +603,9 @@
 	if (vin->info->model != RCAR_GEN3)
 		rvin_crop_scale_comp_gen2(vin);
 
-	if (vin->format.pixelformat == V4L2_PIX_FMT_NV16)
-		rvin_write(vin, ALIGN(vin->format.width, 0x20), VNIS_REG);
-	else
-		rvin_write(vin, ALIGN(vin->format.width, 0x10), VNIS_REG);
+	fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
+	stride = vin->format.bytesperline / fmt->bpp;
+	rvin_write(vin, stride, VNIS_REG);
 }
 
 /* -----------------------------------------------------------------------------
@@ -721,7 +726,7 @@
 		output_is_yuv = true;
 		break;
 	case V4L2_PIX_FMT_XRGB555:
-		dmr = VNDMR_DTMD_ARGB1555;
+		dmr = VNDMR_DTMD_ARGB;
 		break;
 	case V4L2_PIX_FMT_RGB565:
 		dmr = 0;
@@ -730,6 +735,12 @@
 		/* Note: not supported on M1 */
 		dmr = VNDMR_EXRGB;
 		break;
+	case V4L2_PIX_FMT_ARGB555:
+		dmr = (vin->alpha ? VNDMR_ABIT : 0) | VNDMR_DTMD_ARGB;
+		break;
+	case V4L2_PIX_FMT_ABGR32:
+		dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB;
+		break;
 	default:
 		vin_err(vin, "Invalid pixelformat (0x%x)\n",
 			vin->format.pixelformat);
@@ -794,7 +805,7 @@
 	int offsetx, offsety;
 	dma_addr_t offset;
 
-	fmt = rvin_format_from_pixel(vin->format.pixelformat);
+	fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
 
 	/*
 	 * There is no HW support for composition do the beast we can
@@ -1343,3 +1354,34 @@
 
 	return 0;
 }
+
+void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha)
+{
+	unsigned long flags;
+	u32 dmr;
+
+	spin_lock_irqsave(&vin->qlock, flags);
+
+	vin->alpha = alpha;
+
+	if (vin->state == STOPPED)
+		goto out;
+
+	switch (vin->format.pixelformat) {
+	case V4L2_PIX_FMT_ARGB555:
+		dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_ABIT;
+		if (vin->alpha)
+			dmr |= VNDMR_ABIT;
+		break;
+	case V4L2_PIX_FMT_ABGR32:
+		dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_A8BIT_MASK;
+		dmr |= VNDMR_A8BIT(vin->alpha);
+		break;
+	default:
+		goto out;
+	}
+
+	rvin_write(vin, dmr,  VNDMR_REG);
+out:
+	spin_unlock_irqrestore(&vin->qlock, flags);
+}
diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 0936bcd..cbc1c07 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -54,12 +54,24 @@
 		.fourcc			= V4L2_PIX_FMT_XBGR32,
 		.bpp			= 4,
 	},
+	{
+		.fourcc			= V4L2_PIX_FMT_ARGB555,
+		.bpp			= 2,
+	},
+	{
+		.fourcc			= V4L2_PIX_FMT_ABGR32,
+		.bpp			= 4,
+	},
 };
 
-const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat)
+const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,
+						       u32 pixelformat)
 {
 	int i;
 
+	if (vin->info->model == RCAR_M1 && pixelformat == V4L2_PIX_FMT_XBGR32)
+		return NULL;
+
 	for (i = 0; i < ARRAY_SIZE(rvin_formats); i++)
 		if (rvin_formats[i].fourcc == pixelformat)
 			return rvin_formats + i;
@@ -67,16 +79,20 @@
 	return NULL;
 }
 
-static u32 rvin_format_bytesperline(struct v4l2_pix_format *pix)
+static u32 rvin_format_bytesperline(struct rvin_dev *vin,
+				    struct v4l2_pix_format *pix)
 {
 	const struct rvin_video_format *fmt;
+	u32 align;
 
-	fmt = rvin_format_from_pixel(pix->pixelformat);
+	fmt = rvin_format_from_pixel(vin, pix->pixelformat);
 
 	if (WARN_ON(!fmt))
 		return -EINVAL;
 
-	return pix->width * fmt->bpp;
+	align = pix->pixelformat == V4L2_PIX_FMT_NV16 ? 0x20 : 0x10;
+
+	return ALIGN(pix->width, align) * fmt->bpp;
 }
 
 static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix)
@@ -91,9 +107,7 @@
 {
 	u32 walign;
 
-	if (!rvin_format_from_pixel(pix->pixelformat) ||
-	    (vin->info->model == RCAR_M1 &&
-	     pix->pixelformat == V4L2_PIX_FMT_XBGR32))
+	if (!rvin_format_from_pixel(vin, pix->pixelformat))
 		pix->pixelformat = RVIN_DEFAULT_FORMAT;
 
 	switch (pix->field) {
@@ -125,7 +139,7 @@
 	v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign,
 			      &pix->height, 4, vin->info->max_height, 2, 0);
 
-	pix->bytesperline = rvin_format_bytesperline(pix);
+	pix->bytesperline = rvin_format_bytesperline(vin, pix);
 	pix->sizeimage = rvin_format_sizeimage(pix);
 
 	vin_dbg(vin, "Format %ux%u bpl: %u size: %u\n",
@@ -181,9 +195,7 @@
 	if (pad_cfg == NULL)
 		return -ENOMEM;
 
-	if (!rvin_format_from_pixel(pix->pixelformat) ||
-	    (vin->info->model == RCAR_M1 &&
-	     pix->pixelformat == V4L2_PIX_FMT_XBGR32))
+	if (!rvin_format_from_pixel(vin, pix->pixelformat))
 		pix->pixelformat = RVIN_DEFAULT_FORMAT;
 
 	v4l2_fill_mbus_format(&format.format, pix, vin->mbus_code);
@@ -384,7 +396,7 @@
 		while ((r.top * vin->format.bytesperline) & HW_BUFFER_MASK)
 			r.top--;
 
-		fmt = rvin_format_from_pixel(vin->format.pixelformat);
+		fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
 		while ((r.left * fmt->bpp) & HW_BUFFER_MASK)
 			r.left--;
 
@@ -781,26 +793,26 @@
 	if (ret)
 		goto err_unlock;
 
-	if (vin->info->use_mc) {
+	if (vin->info->use_mc)
 		ret = v4l2_pipeline_pm_use(&vin->vdev.entity, 1);
-		if (ret < 0)
-			goto err_open;
-	} else {
-		if (v4l2_fh_is_singular_file(file)) {
-			ret = rvin_power_parallel(vin, true);
-			if (ret < 0)
-				goto err_open;
+	else if (v4l2_fh_is_singular_file(file))
+		ret = rvin_power_parallel(vin, true);
 
-			ret = v4l2_ctrl_handler_setup(&vin->ctrl_handler);
-			if (ret)
-				goto err_parallel;
-		}
-	}
+	if (ret < 0)
+		goto err_open;
+
+	ret = v4l2_ctrl_handler_setup(&vin->ctrl_handler);
+	if (ret)
+		goto err_power;
+
 	mutex_unlock(&vin->lock);
 
 	return 0;
-err_parallel:
-	rvin_power_parallel(vin, false);
+err_power:
+	if (vin->info->use_mc)
+		v4l2_pipeline_pm_use(&vin->vdev.entity, 0);
+	else if (v4l2_fh_is_singular_file(file))
+		rvin_power_parallel(vin, false);
 err_open:
 	v4l2_fh_release(file);
 err_unlock:
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 0b13b34..e562c2f 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -178,6 +178,8 @@
  * @compose:		active composing
  * @source:		active size of the video source
  * @std:		active video standard of the video source
+ *
+ * @alpha:		Alpha component to fill in for supported pixel formats
  */
 struct rvin_dev {
 	struct device *dev;
@@ -215,6 +217,8 @@
 	struct v4l2_rect compose;
 	struct v4l2_rect source;
 	v4l2_std_id std;
+
+	unsigned int alpha;
 };
 
 #define vin_to_source(vin)		((vin)->parallel->subdev)
@@ -260,11 +264,14 @@
 int rvin_v4l2_register(struct rvin_dev *vin);
 void rvin_v4l2_unregister(struct rvin_dev *vin);
 
-const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
+const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,
+						       u32 pixelformat);
+
 
 /* Cropping, composing and scaling */
 void rvin_crop_scale_comp(struct rvin_dev *vin);
 
 int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel);
+void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha);
 
 #endif
diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c
index 43aae9b..cb93a13 100644
--- a/drivers/media/platform/rcar_fdp1.c
+++ b/drivers/media/platform/rcar_fdp1.c
@@ -2122,6 +2122,7 @@
 	if (ctx->hdl.error) {
 		ret = ctx->hdl.error;
 		v4l2_ctrl_handler_free(&ctx->hdl);
+		kfree(ctx);
 		goto done;
 	}
 
@@ -2306,7 +2307,7 @@
 		fdp1->fcp = rcar_fcp_get(fcp_node);
 		of_node_put(fcp_node);
 		if (IS_ERR(fdp1->fcp)) {
-			dev_err(&pdev->dev, "FCP not found (%ld)\n",
+			dev_dbg(&pdev->dev, "FCP not found (%ld)\n",
 				PTR_ERR(fdp1->fcp));
 			return PTR_ERR(fdp1->fcp);
 		}
diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c
index 57d0c0f..197b399 100644
--- a/drivers/media/platform/renesas-ceu.c
+++ b/drivers/media/platform/renesas-ceu.c
@@ -1659,10 +1659,8 @@
 	}
 
 	ret = platform_get_irq(pdev, 0);
-	if (ret < 0) {
-		dev_err(dev, "Failed to get irq: %d\n", ret);
+	if (ret < 0)
 		goto error_free_ceudev;
-	}
 	irq = ret;
 
 	ret = devm_request_irq(dev, irq, ceu_irq,
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
index 5283d45..e9ff12b 100644
--- a/drivers/media/platform/rockchip/rga/rga.c
+++ b/drivers/media/platform/rockchip/rga/rga.c
@@ -831,7 +831,6 @@
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
-		dev_err(rga->dev, "failed to get irq\n");
 		ret = irq;
 		goto err_put_clk;
 	}
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index a876d08..2fb45db 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -641,10 +641,6 @@
 	strscpy(cap->card, S3C_CAMIF_DRIVER_NAME, sizeof(cap->card));
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s.%d",
 		 dev_name(vp->camif->dev), vp->id);
-
-	cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-
 	return 0;
 }
 
@@ -685,10 +681,7 @@
 	if (!fmt)
 		return -EINVAL;
 
-	strscpy(f->description, fmt->name, sizeof(f->description));
 	f->pixelformat = fmt->fourcc;
-
-	pr_debug("fmt(%d): %s\n", f->index, f->description);
 	return 0;
 }
 
@@ -802,10 +795,10 @@
 	if (vp->owner == NULL)
 		vp->owner = priv;
 
-	pr_debug("%ux%u. payload: %u. fmt: %s. %d %d. sizeimage: %d. bpl: %d\n",
-		out_frame->f_width, out_frame->f_height, vp->payload, fmt->name,
-		pix->width * pix->height * fmt->depth, fmt->depth,
-		pix->sizeimage, pix->bytesperline);
+	pr_debug("%ux%u. payload: %u. fmt: 0x%08x. %d %d. sizeimage: %d. bpl: %d\n",
+		 out_frame->f_width, out_frame->f_height, vp->payload,
+		 fmt->fourcc, pix->width * pix->height * fmt->depth,
+		 fmt->depth, pix->sizeimage, pix->bytesperline);
 
 	return 0;
 }
@@ -1163,6 +1156,7 @@
 		goto err_me_cleanup;
 
 	vfd->ctrl_handler = &vp->ctrl_handler;
+	vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
 
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
 	if (ret)
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index b05ce01..c6fbcd7 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -42,7 +42,6 @@
 
 static const struct camif_fmt camif_formats[] = {
 	{
-		.name		= "YUV 4:2:2 planar, Y/Cb/Cr",
 		.fourcc		= V4L2_PIX_FMT_YUV422P,
 		.depth		= 16,
 		.ybpp		= 1,
@@ -51,7 +50,6 @@
 		.flags		= FMT_FL_S3C24XX_CODEC |
 				  FMT_FL_S3C64XX,
 	}, {
-		.name		= "YUV 4:2:0 planar, Y/Cb/Cr",
 		.fourcc		= V4L2_PIX_FMT_YUV420,
 		.depth		= 12,
 		.ybpp		= 1,
@@ -60,7 +58,6 @@
 		.flags		= FMT_FL_S3C24XX_CODEC |
 				  FMT_FL_S3C64XX,
 	}, {
-		.name		= "YVU 4:2:0 planar, Y/Cr/Cb",
 		.fourcc		= V4L2_PIX_FMT_YVU420,
 		.depth		= 12,
 		.ybpp		= 1,
@@ -69,7 +66,6 @@
 		.flags		= FMT_FL_S3C24XX_CODEC |
 				  FMT_FL_S3C64XX,
 	}, {
-		.name		= "RGB565, 16 bpp",
 		.fourcc		= V4L2_PIX_FMT_RGB565X,
 		.depth		= 16,
 		.ybpp		= 2,
@@ -78,7 +74,6 @@
 		.flags		= FMT_FL_S3C24XX_PREVIEW |
 				  FMT_FL_S3C64XX,
 	}, {
-		.name		= "XRGB8888, 32 bpp",
 		.fourcc		= V4L2_PIX_FMT_RGB32,
 		.depth		= 32,
 		.ybpp		= 4,
@@ -87,7 +82,6 @@
 		.flags		= FMT_FL_S3C24XX_PREVIEW |
 				  FMT_FL_S3C64XX,
 	}, {
-		.name		= "BGR666",
 		.fourcc		= V4L2_PIX_FMT_BGR666,
 		.depth		= 32,
 		.ybpp		= 4,
@@ -386,10 +380,8 @@
 		init_waitqueue_head(&vp->irq_queue);
 
 		irq = platform_get_irq(pdev, i);
-		if (irq <= 0) {
-			dev_err(&pdev->dev, "failed to get IRQ %d\n", i);
+		if (irq <= 0)
 			return -ENXIO;
-		}
 
 		ret = devm_request_irq(&pdev->dev, irq, s3c_camif_irq_handler,
 				       0, dev_name(&pdev->dev), vp);
diff --git a/drivers/media/platform/s3c-camif/camif-core.h b/drivers/media/platform/s3c-camif/camif-core.h
index efdc00b..f937e63 100644
--- a/drivers/media/platform/s3c-camif/camif-core.h
+++ b/drivers/media/platform/s3c-camif/camif-core.h
@@ -89,7 +89,6 @@
  * @ybpp:      number of luminance bytes per pixel
  */
 struct camif_fmt {
-	char *name;
 	u32 fourcc;
 	u32 color;
 	u16 colplanes;
diff --git a/drivers/media/platform/s3c-camif/camif-regs.h b/drivers/media/platform/s3c-camif/camif-regs.h
index 29f839c..052948a 100644
--- a/drivers/media/platform/s3c-camif/camif-regs.h
+++ b/drivers/media/platform/s3c-camif/camif-regs.h
@@ -9,6 +9,8 @@
 #ifndef CAMIF_REGS_H_
 #define CAMIF_REGS_H_
 
+#include <linux/bitops.h>
+
 #include "camif-core.h"
 #include <media/drv-intf/s3c_camif.h>
 
@@ -19,7 +21,7 @@
 
 /* Camera input format */
 #define S3C_CAMIF_REG_CISRCFMT			0x00
-#define  CISRCFMT_ITU601_8BIT			(1 << 31)
+#define  CISRCFMT_ITU601_8BIT			BIT(31)
 #define  CISRCFMT_ITU656_8BIT			(0 << 31)
 #define  CISRCFMT_ORDER422_YCBYCR		(0 << 14)
 #define  CISRCFMT_ORDER422_YCRYCB		(1 << 14)
@@ -30,14 +32,14 @@
 
 /* Window offset */
 #define S3C_CAMIF_REG_CIWDOFST			0x04
-#define  CIWDOFST_WINOFSEN			(1 << 31)
-#define  CIWDOFST_CLROVCOFIY			(1 << 30)
-#define  CIWDOFST_CLROVRLB_PR			(1 << 28)
-/* #define  CIWDOFST_CLROVPRFIY			(1 << 27) */
-#define  CIWDOFST_CLROVCOFICB			(1 << 15)
-#define  CIWDOFST_CLROVCOFICR			(1 << 14)
-#define  CIWDOFST_CLROVPRFICB			(1 << 13)
-#define  CIWDOFST_CLROVPRFICR			(1 << 12)
+#define  CIWDOFST_WINOFSEN			BIT(31)
+#define  CIWDOFST_CLROVCOFIY			BIT(30)
+#define  CIWDOFST_CLROVRLB_PR			BIT(28)
+/* #define  CIWDOFST_CLROVPRFIY			BIT(27) */
+#define  CIWDOFST_CLROVCOFICB			BIT(15)
+#define  CIWDOFST_CLROVCOFICR			BIT(14)
+#define  CIWDOFST_CLROVPRFICB			BIT(13)
+#define  CIWDOFST_CLROVPRFICR			BIT(12)
 #define  CIWDOFST_OFST_MASK			(0x7ff << 16 | 0x7ff)
 
 /* Window offset 2 */
@@ -46,24 +48,24 @@
 
 /* Global control */
 #define S3C_CAMIF_REG_CIGCTRL			0x08
-#define  CIGCTRL_SWRST				(1 << 31)
-#define  CIGCTRL_CAMRST				(1 << 30)
+#define  CIGCTRL_SWRST				BIT(31)
+#define  CIGCTRL_CAMRST				BIT(30)
 #define  CIGCTRL_TESTPATTERN_NORMAL		(0 << 27)
 #define  CIGCTRL_TESTPATTERN_COLOR_BAR		(1 << 27)
 #define  CIGCTRL_TESTPATTERN_HOR_INC		(2 << 27)
 #define  CIGCTRL_TESTPATTERN_VER_INC		(3 << 27)
 #define  CIGCTRL_TESTPATTERN_MASK		(3 << 27)
-#define  CIGCTRL_INVPOLPCLK			(1 << 26)
-#define  CIGCTRL_INVPOLVSYNC			(1 << 25)
-#define  CIGCTRL_INVPOLHREF			(1 << 24)
-#define  CIGCTRL_IRQ_OVFEN			(1 << 22)
-#define  CIGCTRL_HREF_MASK			(1 << 21)
-#define  CIGCTRL_IRQ_LEVEL			(1 << 20)
+#define  CIGCTRL_INVPOLPCLK			BIT(26)
+#define  CIGCTRL_INVPOLVSYNC			BIT(25)
+#define  CIGCTRL_INVPOLHREF			BIT(24)
+#define  CIGCTRL_IRQ_OVFEN			BIT(22)
+#define  CIGCTRL_HREF_MASK			BIT(21)
+#define  CIGCTRL_IRQ_LEVEL			BIT(20)
 /* IRQ_CLR_C, IRQ_CLR_P */
-#define  CIGCTRL_IRQ_CLR(id)			(1 << (19 - (id)))
-#define  CIGCTRL_FIELDMODE			(1 << 2)
-#define  CIGCTRL_INVPOLFIELD			(1 << 1)
-#define  CIGCTRL_CAM_INTERLACE			(1 << 0)
+#define  CIGCTRL_IRQ_CLR(id)			BIT(19 - (id))
+#define  CIGCTRL_FIELDMODE			BIT(2)
+#define  CIGCTRL_INVPOLFIELD			BIT(1)
+#define  CIGCTRL_CAM_INTERLACE			BIT(0)
 
 /* Y DMA output frame start address. n = 0..3. */
 #define S3C_CAMIF_REG_CIYSA(id, n)		(0x18 + (id) * 0x54 + (n) * 4)
@@ -74,8 +76,8 @@
 
 /* CICOTRGFMT, CIPRTRGFMT - Target format */
 #define S3C_CAMIF_REG_CITRGFMT(id, _offs)	(0x48 + (id) * (0x34 + (_offs)))
-#define  CITRGFMT_IN422				(1 << 31) /* only for s3c24xx */
-#define  CITRGFMT_OUT422			(1 << 30) /* only for s3c24xx */
+#define  CITRGFMT_IN422				BIT(31) /* only for s3c24xx */
+#define  CITRGFMT_OUT422			BIT(30) /* only for s3c24xx */
 #define  CITRGFMT_OUTFORMAT_YCBCR420		(0 << 29) /* only for s3c6410 */
 #define  CITRGFMT_OUTFORMAT_YCBCR422		(1 << 29) /* only for s3c6410 */
 #define  CITRGFMT_OUTFORMAT_YCBCR422I		(2 << 29) /* only for s3c6410 */
@@ -88,7 +90,7 @@
 #define  CITRGFMT_FLIP_180			(3 << 14)
 #define  CITRGFMT_FLIP_MASK			(3 << 14)
 /* Preview path only */
-#define  CITRGFMT_ROT90_PR			(1 << 13)
+#define  CITRGFMT_ROT90_PR			BIT(13)
 #define  CITRGFMT_TARGETVSIZE(x)		((x) << 0)
 #define  CITRGFMT_TARGETSIZE_MASK		((0x1fff << 16) | 0x1fff)
 
@@ -102,7 +104,7 @@
 #define  CICTRL_RGBBURST2(x)			((x) << 14)
 #define  CICTRL_CBURST1(x)			((x) << 9)
 #define  CICTRL_CBURST2(x)			((x) << 4)
-#define  CICTRL_LASTIRQ_ENABLE			(1 << 2)
+#define  CICTRL_LASTIRQ_ENABLE			BIT(2)
 #define  CICTRL_ORDER422_MASK			(3 << 0)
 
 /* CICOSCPRERATIO, CIPRSCPRERATIO. Pre-scaler control 1. */
@@ -113,22 +115,22 @@
 
 /* CICOSCCTRL, CIPRSCCTRL. Main scaler control. */
 #define S3C_CAMIF_REG_CISCCTRL(id, _offs)	(0x58 + (id) * (0x34 + (_offs)))
-#define  CISCCTRL_SCALERBYPASS			(1 << 31)
+#define  CISCCTRL_SCALERBYPASS			BIT(31)
 /* s3c244x preview path only, s3c64xx both */
-#define  CIPRSCCTRL_SAMPLE			(1 << 31)
+#define  CIPRSCCTRL_SAMPLE			BIT(31)
 /* 0 - 16-bit RGB, 1 - 24-bit RGB */
-#define  CIPRSCCTRL_RGB_FORMAT_24BIT		(1 << 30) /* only for s3c244x */
-#define  CIPRSCCTRL_SCALEUP_H			(1 << 29) /* only for s3c244x */
-#define  CIPRSCCTRL_SCALEUP_V			(1 << 28) /* only for s3c244x */
+#define  CIPRSCCTRL_RGB_FORMAT_24BIT		BIT(30) /* only for s3c244x */
+#define  CIPRSCCTRL_SCALEUP_H			BIT(29) /* only for s3c244x */
+#define  CIPRSCCTRL_SCALEUP_V			BIT(28) /* only for s3c244x */
 /* s3c64xx */
-#define  CISCCTRL_SCALEUP_H			(1 << 30)
-#define  CISCCTRL_SCALEUP_V			(1 << 29)
+#define  CISCCTRL_SCALEUP_H			BIT(30)
+#define  CISCCTRL_SCALEUP_V			BIT(29)
 #define  CISCCTRL_SCALEUP_MASK			(0x3 << 29)
-#define  CISCCTRL_CSCR2Y_WIDE			(1 << 28)
-#define  CISCCTRL_CSCY2R_WIDE			(1 << 27)
-#define  CISCCTRL_LCDPATHEN_FIFO		(1 << 26)
-#define  CISCCTRL_INTERLACE			(1 << 25)
-#define  CISCCTRL_SCALERSTART			(1 << 15)
+#define  CISCCTRL_CSCR2Y_WIDE			BIT(28)
+#define  CISCCTRL_CSCY2R_WIDE			BIT(27)
+#define  CISCCTRL_LCDPATHEN_FIFO		BIT(26)
+#define  CISCCTRL_INTERLACE			BIT(25)
+#define  CISCCTRL_SCALERSTART			BIT(15)
 #define  CISCCTRL_INRGB_FMT_RGB565		(0 << 13)
 #define  CISCCTRL_INRGB_FMT_RGB666		(1 << 13)
 #define  CISCCTRL_INRGB_FMT_RGB888		(2 << 13)
@@ -137,8 +139,8 @@
 #define  CISCCTRL_OUTRGB_FMT_RGB666		(1 << 11)
 #define  CISCCTRL_OUTRGB_FMT_RGB888		(2 << 11)
 #define  CISCCTRL_OUTRGB_FMT_MASK		(3 << 11)
-#define  CISCCTRL_EXTRGB_EXTENSION		(1 << 10)
-#define  CISCCTRL_ONE2ONE			(1 << 9)
+#define  CISCCTRL_EXTRGB_EXTENSION		BIT(10)
+#define  CISCCTRL_ONE2ONE			BIT(9)
 #define  CISCCTRL_MAIN_RATIO_MASK		(0x1ff << 16 | 0x1ff)
 
 /* CICOTAREA, CIPRTAREA. Target area for DMA (Hsize x Vsize). */
@@ -147,38 +149,38 @@
 
 /* Codec (id = 0) or preview (id = 1) path status. */
 #define S3C_CAMIF_REG_CISTATUS(id, _offs)	(0x64 + (id) * (0x34 + (_offs)))
-#define  CISTATUS_OVFIY_STATUS			(1 << 31)
-#define  CISTATUS_OVFICB_STATUS			(1 << 30)
-#define  CISTATUS_OVFICR_STATUS			(1 << 29)
+#define  CISTATUS_OVFIY_STATUS			BIT(31)
+#define  CISTATUS_OVFICB_STATUS			BIT(30)
+#define  CISTATUS_OVFICR_STATUS			BIT(29)
 #define  CISTATUS_OVF_MASK			(0x7 << 29)
 #define  CIPRSTATUS_OVF_MASK			(0x3 << 30)
-#define  CISTATUS_VSYNC_STATUS			(1 << 28)
+#define  CISTATUS_VSYNC_STATUS			BIT(28)
 #define  CISTATUS_FRAMECNT_MASK			(3 << 26)
 #define  CISTATUS_FRAMECNT(__reg)		(((__reg) >> 26) & 0x3)
-#define  CISTATUS_WINOFSTEN_STATUS		(1 << 25)
-#define  CISTATUS_IMGCPTEN_STATUS		(1 << 22)
-#define  CISTATUS_IMGCPTENSC_STATUS		(1 << 21)
-#define  CISTATUS_VSYNC_A_STATUS		(1 << 20)
-#define  CISTATUS_FRAMEEND_STATUS		(1 << 19) /* 17 on s3c64xx */
+#define  CISTATUS_WINOFSTEN_STATUS		BIT(25)
+#define  CISTATUS_IMGCPTEN_STATUS		BIT(22)
+#define  CISTATUS_IMGCPTENSC_STATUS		BIT(21)
+#define  CISTATUS_VSYNC_A_STATUS		BIT(20)
+#define  CISTATUS_FRAMEEND_STATUS		BIT(19) /* 17 on s3c64xx */
 
 /* Image capture enable */
 #define S3C_CAMIF_REG_CIIMGCPT(_offs)		(0xa0 + (_offs))
-#define  CIIMGCPT_IMGCPTEN			(1 << 31)
-#define  CIIMGCPT_IMGCPTEN_SC(id)		(1 << (30 - (id)))
+#define  CIIMGCPT_IMGCPTEN			BIT(31)
+#define  CIIMGCPT_IMGCPTEN_SC(id)		BIT(30 - (id))
 /* Frame control: 1 - one-shot, 0 - free run */
-#define  CIIMGCPT_CPT_FREN_ENABLE(id)		(1 << (25 - (id)))
+#define  CIIMGCPT_CPT_FREN_ENABLE(id)		BIT(25 - (id))
 #define  CIIMGCPT_CPT_FRMOD_ENABLE		(0 << 18)
-#define  CIIMGCPT_CPT_FRMOD_CNT			(1 << 18)
+#define  CIIMGCPT_CPT_FRMOD_CNT			BIT(18)
 
 /* Capture sequence */
 #define S3C_CAMIF_REG_CICPTSEQ			0xc4
 
 /* Image effects */
 #define S3C_CAMIF_REG_CIIMGEFF(_offs)		(0xb0 + (_offs))
-#define  CIIMGEFF_IE_ENABLE(id)			(1 << (30 + (id)))
+#define  CIIMGEFF_IE_ENABLE(id)			BIT(30 + (id))
 #define  CIIMGEFF_IE_ENABLE_MASK		(3 << 30)
 /* Image effect: 1 - after scaler, 0 - before scaler */
-#define  CIIMGEFF_IE_AFTER_SC			(1 << 29)
+#define  CIIMGEFF_IE_AFTER_SC			BIT(29)
 #define  CIIMGEFF_FIN_MASK			(7 << 26)
 #define  CIIMGEFF_FIN_BYPASS			(0 << 26)
 #define  CIIMGEFF_FIN_ARBITRARY			(1 << 26)
@@ -207,8 +209,8 @@
 
 /* Real input DMA data size. n = 0 - codec, 1 - preview. */
 #define S3C_CAMIF_REG_MSWIDTH(id)		(0xf8 + (id) * 0x2c)
-#define  AUTOLOAD_ENABLE			(1 << 31)
-#define  ADDR_CH_DIS				(1 << 30)
+#define  AUTOLOAD_ENABLE			BIT(31)
+#define  ADDR_CH_DIS				BIT(30)
 #define  MSHEIGHT(x)				(((x) & 0x3ff) << 16)
 #define  MSWIDTH(x)				((x) & 0x3ff)
 
@@ -219,12 +221,12 @@
 #define  MSCTRL_ORDER422_M_CBYCRY		(2 << 4)
 #define  MSCTRL_ORDER422_M_CRYCBY		(3 << 4)
 /* 0 - camera, 1 - DMA */
-#define  MSCTRL_SEL_DMA_CAM			(1 << 3)
+#define  MSCTRL_SEL_DMA_CAM			BIT(3)
 #define  MSCTRL_INFORMAT_M_YCBCR420		(0 << 1)
 #define  MSCTRL_INFORMAT_M_YCBCR422		(1 << 1)
 #define  MSCTRL_INFORMAT_M_YCBCR422I		(2 << 1)
 #define  MSCTRL_INFORMAT_M_RGB			(3 << 1)
-#define  MSCTRL_ENVID_M				(1 << 0)
+#define  MSCTRL_ENVID_M				BIT(0)
 
 /* CICOSCOSY, CIPRSCOSY. Scan line Y/Cb/Cr offset. */
 #define S3C_CAMIF_REG_CISSY(id)			(0x12c + (id) * 0x0c)
diff --git a/drivers/media/platform/s5p-cec/s5p_cec.c b/drivers/media/platform/s5p-cec/s5p_cec.c
index ea6231b..6ddcc35 100644
--- a/drivers/media/platform/s5p-cec/s5p_cec.c
+++ b/drivers/media/platform/s5p-cec/s5p_cec.c
@@ -214,21 +214,23 @@
 	if (IS_ERR(cec->reg))
 		return PTR_ERR(cec->reg);
 
-	cec->notifier = cec_notifier_get(hdmi_dev);
-	if (cec->notifier == NULL)
-		return -ENOMEM;
-
 	cec->adap = cec_allocate_adapter(&s5p_cec_adap_ops, cec, CEC_NAME,
-		CEC_CAP_DEFAULTS | (needs_hpd ? CEC_CAP_NEEDS_HPD : 0), 1);
+		CEC_CAP_DEFAULTS | (needs_hpd ? CEC_CAP_NEEDS_HPD : 0) |
+		CEC_CAP_CONNECTOR_INFO, 1);
 	ret = PTR_ERR_OR_ZERO(cec->adap);
 	if (ret)
 		return ret;
 
+	cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+						       cec->adap);
+	if (!cec->notifier) {
+		ret = -ENOMEM;
+		goto err_delete_adapter;
+	}
+
 	ret = cec_register_adapter(cec->adap, &pdev->dev);
 	if (ret)
-		goto err_delete_adapter;
-
-	cec_register_cec_notifier(cec->adap, cec->notifier);
+		goto err_notifier;
 
 	platform_set_drvdata(pdev, cec);
 	pm_runtime_enable(dev);
@@ -236,6 +238,9 @@
 	dev_dbg(dev, "successfully probed\n");
 	return 0;
 
+err_notifier:
+	cec_notifier_cec_adap_unregister(cec->notifier);
+
 err_delete_adapter:
 	cec_delete_adapter(cec->adap);
 	return ret;
@@ -245,8 +250,8 @@
 {
 	struct s5p_cec_dev *cec = platform_get_drvdata(pdev);
 
+	cec_notifier_cec_adap_unregister(cec->notifier);
 	cec_unregister_adapter(cec->adap);
-	cec_notifier_put(cec->notifier);
 	pm_runtime_disable(&pdev->dev);
 	return 0;
 }
diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index 152d192..f5f05ea 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -29,31 +29,26 @@
 
 static struct g2d_fmt formats[] = {
 	{
-		.name	= "XRGB_8888",
 		.fourcc	= V4L2_PIX_FMT_RGB32,
 		.depth	= 32,
 		.hw	= COLOR_MODE(ORDER_XRGB, MODE_XRGB_8888),
 	},
 	{
-		.name	= "RGB_565",
 		.fourcc	= V4L2_PIX_FMT_RGB565X,
 		.depth	= 16,
 		.hw	= COLOR_MODE(ORDER_XRGB, MODE_RGB_565),
 	},
 	{
-		.name	= "XRGB_1555",
 		.fourcc	= V4L2_PIX_FMT_RGB555X,
 		.depth	= 16,
 		.hw	= COLOR_MODE(ORDER_XRGB, MODE_XRGB_1555),
 	},
 	{
-		.name	= "XRGB_4444",
 		.fourcc	= V4L2_PIX_FMT_RGB444,
 		.depth	= 16,
 		.hw	= COLOR_MODE(ORDER_XRGB, MODE_XRGB_4444),
 	},
 	{
-		.name	= "PACKED_RGB_888",
 		.fourcc	= V4L2_PIX_FMT_RGB24,
 		.depth	= 24,
 		.hw	= COLOR_MODE(ORDER_XRGB, MODE_PACKED_RGB_888),
@@ -296,19 +291,14 @@
 	strscpy(cap->driver, G2D_NAME, sizeof(cap->driver));
 	strscpy(cap->card, G2D_NAME, sizeof(cap->card));
 	cap->bus_info[0] = 0;
-	cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
 static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
 {
-	struct g2d_fmt *fmt;
 	if (f->index >= NUM_FORMATS)
 		return -EINVAL;
-	fmt = &formats[f->index];
-	f->pixelformat = fmt->fourcc;
-	strscpy(f->description, fmt->name, sizeof(f->description));
+	f->pixelformat = formats[f->index].fourcc;
 	return 0;
 }
 
@@ -704,6 +694,7 @@
 	set_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags);
 	vfd->lock = &dev->mutex;
 	vfd->v4l2_dev = &dev->v4l2_dev;
+	vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
 	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
 	if (ret) {
 		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
diff --git a/drivers/media/platform/s5p-g2d/g2d.h b/drivers/media/platform/s5p-g2d/g2d.h
index def0ec0..c2309c1 100644
--- a/drivers/media/platform/s5p-g2d/g2d.h
+++ b/drivers/media/platform/s5p-g2d/g2d.h
@@ -61,7 +61,6 @@
 };
 
 struct g2d_fmt {
-	char	*name;
 	u32	fourcc;
 	int	depth;
 	u32	hw;
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index a3bc884..8dbbd5f 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -35,7 +35,6 @@
 
 static struct s5p_jpeg_fmt sjpeg_formats[] = {
 	{
-		.name		= "JPEG JFIF",
 		.fourcc		= V4L2_PIX_FMT_JPEG,
 		.flags		= SJPEG_FMT_FLAG_ENC_CAPTURE |
 				  SJPEG_FMT_FLAG_DEC_OUTPUT |
@@ -44,7 +43,6 @@
 				  SJPEG_FMT_FLAG_EXYNOS4,
 	},
 	{
-		.name		= "YUV 4:2:2 packed, YCbYCr",
 		.fourcc		= V4L2_PIX_FMT_YUYV,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -57,7 +55,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 	},
 	{
-		.name		= "YUV 4:2:2 packed, YCbYCr",
 		.fourcc		= V4L2_PIX_FMT_YUYV,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -70,7 +67,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 	},
 	{
-		.name		= "YUV 4:2:2 packed, YCbYCr",
 		.fourcc		= V4L2_PIX_FMT_YUYV,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -83,7 +79,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 	},
 	{
-		.name		= "YUV 4:2:2 packed, YCrYCb",
 		.fourcc		= V4L2_PIX_FMT_YVYU,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -96,7 +91,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 	},
 	{
-		.name		= "YUV 4:2:2 packed, YCrYCb",
 		.fourcc		= V4L2_PIX_FMT_YVYU,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -109,7 +103,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 	},
 	{
-		.name		= "YUV 4:2:2 packed, YCrYCb",
 		.fourcc		= V4L2_PIX_FMT_UYVY,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -122,7 +115,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 	},
 	{
-		.name		= "YUV 4:2:2 packed, YCrYCb",
 		.fourcc		= V4L2_PIX_FMT_VYUY,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -135,7 +127,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 	},
 	{
-		.name		= "RGB565",
 		.fourcc		= V4L2_PIX_FMT_RGB565,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -148,7 +139,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 	},
 	{
-		.name		= "RGB565",
 		.fourcc		= V4L2_PIX_FMT_RGB565,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -161,7 +151,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 	},
 	{
-		.name		= "RGB565X",
 		.fourcc		= V4L2_PIX_FMT_RGB565X,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -174,7 +163,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 	},
 	{
-		.name		= "RGB565",
 		.fourcc		= V4L2_PIX_FMT_RGB565,
 		.depth		= 16,
 		.colplanes	= 1,
@@ -186,7 +174,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 	},
 	{
-		.name		= "ARGB8888, 32 bpp",
 		.fourcc		= V4L2_PIX_FMT_RGB32,
 		.depth		= 32,
 		.colplanes	= 1,
@@ -199,7 +186,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 	},
 	{
-		.name		= "ARGB8888, 32 bpp",
 		.fourcc		= V4L2_PIX_FMT_RGB32,
 		.depth		= 32,
 		.colplanes	= 1,
@@ -212,7 +198,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 	},
 	{
-		.name		= "YUV 4:4:4 planar, Y/CbCr",
 		.fourcc		= V4L2_PIX_FMT_NV24,
 		.depth		= 24,
 		.colplanes	= 2,
@@ -225,7 +210,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 	},
 	{
-		.name		= "YUV 4:4:4 planar, Y/CrCb",
 		.fourcc		= V4L2_PIX_FMT_NV42,
 		.depth		= 24,
 		.colplanes	= 2,
@@ -238,7 +222,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
 	},
 	{
-		.name		= "YUV 4:2:2 planar, Y/CrCb",
 		.fourcc		= V4L2_PIX_FMT_NV61,
 		.depth		= 16,
 		.colplanes	= 2,
@@ -251,7 +234,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 	},
 	{
-		.name		= "YUV 4:2:2 planar, Y/CbCr",
 		.fourcc		= V4L2_PIX_FMT_NV16,
 		.depth		= 16,
 		.colplanes	= 2,
@@ -264,7 +246,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
 	},
 	{
-		.name		= "YUV 4:2:0 planar, Y/CbCr",
 		.fourcc		= V4L2_PIX_FMT_NV12,
 		.depth		= 12,
 		.colplanes	= 2,
@@ -277,7 +258,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 	},
 	{
-		.name		= "YUV 4:2:0 planar, Y/CbCr",
 		.fourcc		= V4L2_PIX_FMT_NV12,
 		.depth		= 12,
 		.colplanes	= 2,
@@ -290,7 +270,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 	},
 	{
-		.name		= "YUV 4:2:0 planar, Y/CbCr",
 		.fourcc		= V4L2_PIX_FMT_NV12,
 		.depth		= 12,
 		.colplanes	= 2,
@@ -303,7 +282,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 	},
 	{
-		.name		= "YUV 4:2:0 planar, Y/CrCb",
 		.fourcc		= V4L2_PIX_FMT_NV21,
 		.depth		= 12,
 		.colplanes	= 2,
@@ -316,7 +294,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 	},
 	{
-		.name		= "YUV 4:2:0 planar, Y/CrCb",
 		.fourcc		= V4L2_PIX_FMT_NV21,
 		.depth		= 12,
 		.colplanes	= 2,
@@ -330,7 +307,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 	},
 	{
-		.name		= "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
 		.fourcc		= V4L2_PIX_FMT_YUV420,
 		.depth		= 12,
 		.colplanes	= 3,
@@ -343,7 +319,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 	},
 	{
-		.name		= "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
 		.fourcc		= V4L2_PIX_FMT_YUV420,
 		.depth		= 12,
 		.colplanes	= 3,
@@ -356,7 +331,6 @@
 		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
 	},
 	{
-		.name		= "Gray",
 		.fourcc		= V4L2_PIX_FMT_GREY,
 		.depth		= 8,
 		.colplanes	= 1,
@@ -1285,8 +1259,6 @@
 	}
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
 		 dev_name(ctx->jpeg->dev));
-	cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -1314,7 +1286,6 @@
 	if (i >= n)
 		return -EINVAL;
 
-	strscpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
 	f->pixelformat = sjpeg_formats[i].fourcc;
 
 	return 0;
@@ -2974,6 +2945,7 @@
 	jpeg->vfd_encoder->lock		= &jpeg->lock;
 	jpeg->vfd_encoder->v4l2_dev	= &jpeg->v4l2_dev;
 	jpeg->vfd_encoder->vfl_dir	= VFL_DIR_M2M;
+	jpeg->vfd_encoder->device_caps	= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
 
 	ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
 	if (ret) {
@@ -3003,6 +2975,7 @@
 	jpeg->vfd_decoder->lock		= &jpeg->lock;
 	jpeg->vfd_decoder->v4l2_dev	= &jpeg->v4l2_dev;
 	jpeg->vfd_decoder->vfl_dir	= VFL_DIR_M2M;
+	jpeg->vfd_decoder->device_caps	= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
 
 	ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
 	if (ret) {
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h
index 34f87f6..3bc52f8 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h
@@ -150,7 +150,6 @@
 
 /**
  * struct jpeg_fmt - driver's internal color format data
- * @name:	format description
  * @fourcc:	the fourcc code, 0 if not applicable
  * @depth:	number of bits per pixel
  * @colplanes:	number of color planes (1 for packed formats)
@@ -159,7 +158,6 @@
  * @flags:	flags describing format applicability
  */
 struct s5p_jpeg_fmt {
-	char	*name;
 	u32	fourcc;
 	int	depth;
 	int	colplanes;
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-regs.h b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
index bab7fa4..86f376b 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-regs.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-regs.h
@@ -121,14 +121,14 @@
 
 /* JPEG timer setting register */
 #define S5P_JPG_TIMER_SE		0x7c
-#define S5P_TIMER_INT_EN_MASK		(0x1 << 31)
-#define S5P_TIMER_INT_EN		(0x1 << 31)
+#define S5P_TIMER_INT_EN_MASK		(0x1UL << 31)
+#define S5P_TIMER_INT_EN		(0x1UL << 31)
 #define S5P_TIMER_INIT_MASK		0x7fffffff
 
 /* JPEG timer status register */
 #define S5P_JPG_TIMER_ST		0x80
 #define S5P_TIMER_INT_STAT_SHIFT	31
-#define S5P_TIMER_INT_STAT_MASK		(0x1 << S5P_TIMER_INT_STAT_SHIFT)
+#define S5P_TIMER_INT_STAT_MASK		(0x1UL << S5P_TIMER_INT_STAT_SHIFT)
 #define S5P_TIMER_CNT_SHIFT		0
 #define S5P_TIMER_CNT_MASK		0x7fffffff
 
@@ -562,13 +562,13 @@
 /* JPEG timer setting register */
 #define EXYNOS3250_TIMER_SE			0x148
 #define EXYNOS3250_TIMER_INT_EN_SHIFT		31
-#define EXYNOS3250_TIMER_INT_EN			(1 << EXYNOS3250_TIMER_INT_EN_SHIFT)
+#define EXYNOS3250_TIMER_INT_EN			(1UL << EXYNOS3250_TIMER_INT_EN_SHIFT)
 #define EXYNOS3250_TIMER_INIT_MASK		0x7fffffff
 
 /* JPEG timer status register */
 #define EXYNOS3250_TIMER_ST			0x14c
 #define EXYNOS3250_TIMER_INT_STAT_SHIFT		31
-#define EXYNOS3250_TIMER_INT_STAT		(1 << EXYNOS3250_TIMER_INT_STAT_SHIFT)
+#define EXYNOS3250_TIMER_INT_STAT		(1UL << EXYNOS3250_TIMER_INT_STAT_SHIFT)
 #define EXYNOS3250_TIMER_CNT_SHIFT		0
 #define EXYNOS3250_TIMER_CNT_MASK		0x7fffffff
 
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index 5dc0865..96d1ecd 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -718,7 +718,6 @@
  *			used by the MFC
  */
 struct s5p_mfc_fmt {
-	char *name;
 	u32 fourcc;
 	u32 codec_mode;
 	enum s5p_mfc_fmt_type type;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
index 4017c8b..61e144a 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c
@@ -29,7 +29,6 @@
 
 static struct s5p_mfc_fmt formats[] = {
 	{
-		.name		= "4:2:0 2 Planes 16x16 Tiles",
 		.fourcc		= V4L2_PIX_FMT_NV12MT_16X16,
 		.codec_mode	= S5P_MFC_CODEC_NONE,
 		.type		= MFC_FMT_RAW,
@@ -37,7 +36,6 @@
 		.versions	= MFC_V6_BIT | MFC_V7_BIT,
 	},
 	{
-		.name		= "4:2:0 2 Planes 64x32 Tiles",
 		.fourcc		= V4L2_PIX_FMT_NV12MT,
 		.codec_mode	= S5P_MFC_CODEC_NONE,
 		.type		= MFC_FMT_RAW,
@@ -45,7 +43,6 @@
 		.versions	= MFC_V5_BIT,
 	},
 	{
-		.name		= "4:2:0 2 Planes Y/CbCr",
 		.fourcc		= V4L2_PIX_FMT_NV12M,
 		.codec_mode	= S5P_MFC_CODEC_NONE,
 		.type		= MFC_FMT_RAW,
@@ -53,7 +50,6 @@
 		.versions	= MFC_V6PLUS_BITS,
 	},
 	{
-		.name		= "4:2:0 2 Planes Y/CrCb",
 		.fourcc		= V4L2_PIX_FMT_NV21M,
 		.codec_mode	= S5P_MFC_CODEC_NONE,
 		.type		= MFC_FMT_RAW,
@@ -61,7 +57,6 @@
 		.versions	= MFC_V6PLUS_BITS,
 	},
 	{
-		.name		= "H264 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_H264,
 		.codec_mode	= S5P_MFC_CODEC_H264_DEC,
 		.type		= MFC_FMT_DEC,
@@ -69,7 +64,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "H264/MVC Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_H264_MVC,
 		.codec_mode	= S5P_MFC_CODEC_H264_MVC_DEC,
 		.type		= MFC_FMT_DEC,
@@ -77,7 +71,6 @@
 		.versions	= MFC_V6PLUS_BITS,
 	},
 	{
-		.name		= "H263 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_H263,
 		.codec_mode	= S5P_MFC_CODEC_H263_DEC,
 		.type		= MFC_FMT_DEC,
@@ -85,7 +78,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "MPEG1 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_MPEG1,
 		.codec_mode	= S5P_MFC_CODEC_MPEG2_DEC,
 		.type		= MFC_FMT_DEC,
@@ -93,7 +85,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "MPEG2 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_MPEG2,
 		.codec_mode	= S5P_MFC_CODEC_MPEG2_DEC,
 		.type		= MFC_FMT_DEC,
@@ -101,7 +92,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "MPEG4 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_MPEG4,
 		.codec_mode	= S5P_MFC_CODEC_MPEG4_DEC,
 		.type		= MFC_FMT_DEC,
@@ -109,7 +99,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "XviD Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_XVID,
 		.codec_mode	= S5P_MFC_CODEC_MPEG4_DEC,
 		.type		= MFC_FMT_DEC,
@@ -117,7 +106,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "VC1 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_VC1_ANNEX_G,
 		.codec_mode	= S5P_MFC_CODEC_VC1_DEC,
 		.type		= MFC_FMT_DEC,
@@ -125,7 +113,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "VC1 RCV Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_VC1_ANNEX_L,
 		.codec_mode	= S5P_MFC_CODEC_VC1RCV_DEC,
 		.type		= MFC_FMT_DEC,
@@ -133,7 +120,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "VP8 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_VP8,
 		.codec_mode	= S5P_MFC_CODEC_VP8_DEC,
 		.type		= MFC_FMT_DEC,
@@ -279,7 +265,6 @@
 							bool out)
 {
 	struct s5p_mfc_dev *dev = video_drvdata(file);
-	struct s5p_mfc_fmt *fmt;
 	int i, j = 0;
 
 	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
@@ -296,9 +281,7 @@
 	}
 	if (i == ARRAY_SIZE(formats))
 		return -EINVAL;
-	fmt = &formats[i];
-	strscpy(f->description, fmt->name, sizeof(f->description));
-	f->pixelformat = fmt->fourcc;
+	f->pixelformat = formats[i].fourcc;
 	return 0;
 }
 
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index 97e7648..912fe0c 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -32,7 +32,6 @@
 
 static struct s5p_mfc_fmt formats[] = {
 	{
-		.name		= "4:2:0 2 Planes 16x16 Tiles",
 		.fourcc		= V4L2_PIX_FMT_NV12MT_16X16,
 		.codec_mode	= S5P_MFC_CODEC_NONE,
 		.type		= MFC_FMT_RAW,
@@ -40,7 +39,6 @@
 		.versions	= MFC_V6_BIT | MFC_V7_BIT,
 	},
 	{
-		.name		= "4:2:0 2 Planes 64x32 Tiles",
 		.fourcc		= V4L2_PIX_FMT_NV12MT,
 		.codec_mode	= S5P_MFC_CODEC_NONE,
 		.type		= MFC_FMT_RAW,
@@ -48,7 +46,6 @@
 		.versions	= MFC_V5_BIT,
 	},
 	{
-		.name		= "4:2:0 2 Planes Y/CbCr",
 		.fourcc		= V4L2_PIX_FMT_NV12M,
 		.codec_mode	= S5P_MFC_CODEC_NONE,
 		.type		= MFC_FMT_RAW,
@@ -56,7 +53,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "4:2:0 2 Planes Y/CrCb",
 		.fourcc		= V4L2_PIX_FMT_NV21M,
 		.codec_mode	= S5P_MFC_CODEC_NONE,
 		.type		= MFC_FMT_RAW,
@@ -64,7 +60,6 @@
 		.versions	= MFC_V6PLUS_BITS,
 	},
 	{
-		.name		= "H264 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_H264,
 		.codec_mode	= S5P_MFC_CODEC_H264_ENC,
 		.type		= MFC_FMT_ENC,
@@ -72,7 +67,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "MPEG4 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_MPEG4,
 		.codec_mode	= S5P_MFC_CODEC_MPEG4_ENC,
 		.type		= MFC_FMT_ENC,
@@ -80,7 +74,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "H263 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_H263,
 		.codec_mode	= S5P_MFC_CODEC_H263_ENC,
 		.type		= MFC_FMT_ENC,
@@ -88,7 +81,6 @@
 		.versions	= MFC_V5PLUS_BITS,
 	},
 	{
-		.name		= "VP8 Encoded Stream",
 		.fourcc		= V4L2_PIX_FMT_VP8,
 		.codec_mode	= S5P_MFC_CODEC_VP8_ENC,
 		.type		= MFC_FMT_ENC,
@@ -1320,7 +1312,6 @@
 							bool out)
 {
 	struct s5p_mfc_dev *dev = video_drvdata(file);
-	struct s5p_mfc_fmt *fmt;
 	int i, j = 0;
 
 	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
@@ -1332,10 +1323,7 @@
 			continue;
 
 		if (j == f->index) {
-			fmt = &formats[i];
-			strscpy(f->description, fmt->name,
-				sizeof(f->description));
-			f->pixelformat = fmt->fourcc;
+			f->pixelformat = formats[i].fourcc;
 			return 0;
 		}
 		++j;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
index f76a074..49503c2 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c
@@ -711,7 +711,7 @@
 	reg = mfc_read(dev, S5P_FIMV_ENC_PADDING_CTRL);
 	if (p->pad) {
 		/** enable */
-		reg |= (1 << 31);
+		reg |= (1UL << 31);
 		/** cr value */
 		reg &= ~(0xFF << 16);
 		reg |= (p->pad_cr << 16);
@@ -955,7 +955,7 @@
 				S5P_FIMV_ENC_RC_FRAME_RATE);
 			shm = s5p_mfc_read_info_v5(ctx, RC_VOP_TIMING);
 			shm &= ~(0xFFFFFFFF);
-			shm |= (1 << 31);
+			shm |= (1UL << 31);
 			shm |= ((p->rc_framerate_num & 0x7FFF) << 16);
 			shm |= (p->rc_framerate_denom & 0xFFFF);
 			s5p_mfc_write_info_v5(ctx, shm, RC_VOP_TIMING);
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
index f7621a9..a145305 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -840,7 +840,7 @@
 	if (p->pad) {
 		reg = 0;
 		/** enable */
-		reg |= (1 << 31);
+		reg |= (1UL << 31);
 		/** cr value */
 		reg |= ((p->pad_cr & 0xFF) << 16);
 		/** cb value */
diff --git a/drivers/media/platform/seco-cec/seco-cec.c b/drivers/media/platform/seco-cec/seco-cec.c
index 1d0133f..9cd60fe 100644
--- a/drivers/media/platform/seco-cec/seco-cec.c
+++ b/drivers/media/platform/seco-cec/seco-cec.c
@@ -507,10 +507,10 @@
 }
 
 struct cec_dmi_match {
-	char *sys_vendor;
-	char *product_name;
-	char *devname;
-	char *conn;
+	const char *sys_vendor;
+	const char *product_name;
+	const char *devname;
+	const char *conn;
 };
 
 static const struct cec_dmi_match secocec_dmi_match_table[] = {
@@ -518,7 +518,8 @@
 	{ "SECO", "UDOO x86", "0000:00:02.0", "Port B" },
 };
 
-static int secocec_cec_get_notifier(struct cec_notifier **notify)
+static struct device *secocec_cec_find_hdmi_dev(struct device *dev,
+						const char **conn)
 {
 	int i;
 
@@ -533,16 +534,15 @@
 			d = bus_find_device_by_name(&pci_bus_type, NULL,
 						    m->devname);
 			if (!d)
-				return -EPROBE_DEFER;
+				return ERR_PTR(-EPROBE_DEFER);
 
-			*notify = cec_notifier_get_conn(d, m->conn);
 			put_device(d);
-
-			return 0;
+			*conn = m->conn;
+			return d;
 		}
 	}
 
-	return -EINVAL;
+	return ERR_PTR(-EINVAL);
 }
 
 static int secocec_acpi_probe(struct secocec_data *sdev)
@@ -573,9 +573,15 @@
 {
 	struct secocec_data *secocec;
 	struct device *dev = &pdev->dev;
+	struct device *hdmi_dev;
+	const char *conn = NULL;
 	int ret;
 	u16 val;
 
+	hdmi_dev = secocec_cec_find_hdmi_dev(&pdev->dev, &conn);
+	if (IS_ERR(hdmi_dev))
+		return PTR_ERR(hdmi_dev);
+
 	secocec = devm_kzalloc(dev, sizeof(*secocec), GFP_KERNEL);
 	if (!secocec)
 		return -ENOMEM;
@@ -617,12 +623,6 @@
 		goto err;
 	}
 
-	ret = secocec_cec_get_notifier(&secocec->notifier);
-	if (ret) {
-		dev_err(dev, "no CEC notifier available\n");
-		goto err;
-	}
-
 	ret = devm_request_threaded_irq(dev,
 					secocec->irq,
 					NULL,
@@ -640,7 +640,8 @@
 	secocec->cec_adap = cec_allocate_adapter(&secocec_cec_adap_ops,
 						 secocec,
 						 dev_name(dev),
-						 CEC_CAP_DEFAULTS,
+						 CEC_CAP_DEFAULTS |
+						 CEC_CAP_CONNECTOR_INFO,
 						 SECOCEC_MAX_ADDRS);
 
 	if (IS_ERR(secocec->cec_adap)) {
@@ -648,16 +649,20 @@
 		goto err;
 	}
 
+	secocec->notifier = cec_notifier_cec_adap_register(hdmi_dev, conn,
+							   secocec->cec_adap);
+	if (!secocec->notifier) {
+		ret = -ENOMEM;
+		goto err_delete_adapter;
+	}
+
 	ret = cec_register_adapter(secocec->cec_adap, dev);
 	if (ret)
-		goto err_delete_adapter;
-
-	if (secocec->notifier)
-		cec_register_cec_notifier(secocec->cec_adap, secocec->notifier);
+		goto err_notifier;
 
 	ret = secocec_ir_probe(secocec);
 	if (ret)
-		goto err_delete_adapter;
+		goto err_notifier;
 
 	platform_set_drvdata(pdev, secocec);
 
@@ -665,6 +670,8 @@
 
 	return ret;
 
+err_notifier:
+	cec_notifier_cec_adap_unregister(secocec->notifier);
 err_delete_adapter:
 	cec_delete_adapter(secocec->cec_adap);
 err:
@@ -685,11 +692,9 @@
 
 		dev_dbg(&pdev->dev, "IR disabled");
 	}
+	cec_notifier_cec_adap_unregister(secocec->notifier);
 	cec_unregister_adapter(secocec->cec_adap);
 
-	if (secocec->notifier)
-		cec_notifier_put(secocec->notifier);
-
 	release_region(BRA_SMB_BASE_ADDR, 7);
 
 	dev_dbg(&pdev->dev, "CEC device removed");
diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c
index 5a9ba05..2b4c0d9 100644
--- a/drivers/media/platform/sh_veu.c
+++ b/drivers/media/platform/sh_veu.c
@@ -81,12 +81,12 @@
 struct sh_veu_dev;
 
 struct sh_veu_file {
+	struct v4l2_fh fh;
 	struct sh_veu_dev *veu_dev;
 	bool cfg_needed;
 };
 
 struct sh_veu_format {
-	char *name;
 	u32 fourcc;
 	unsigned int depth;
 	unsigned int ydepth;
@@ -144,14 +144,14 @@
  * aligned for NV24.
  */
 static const struct sh_veu_format sh_veu_fmt[] = {
-	[SH_VEU_FMT_NV12]   = { .ydepth = 8, .depth = 12, .name = "NV12", .fourcc = V4L2_PIX_FMT_NV12 },
-	[SH_VEU_FMT_NV16]   = { .ydepth = 8, .depth = 16, .name = "NV16", .fourcc = V4L2_PIX_FMT_NV16 },
-	[SH_VEU_FMT_NV24]   = { .ydepth = 8, .depth = 24, .name = "NV24", .fourcc = V4L2_PIX_FMT_NV24 },
-	[SH_VEU_FMT_RGB332] = { .ydepth = 8, .depth = 8, .name = "RGB332", .fourcc = V4L2_PIX_FMT_RGB332 },
-	[SH_VEU_FMT_RGB444] = { .ydepth = 16, .depth = 16, .name = "RGB444", .fourcc = V4L2_PIX_FMT_RGB444 },
-	[SH_VEU_FMT_RGB565] = { .ydepth = 16, .depth = 16, .name = "RGB565", .fourcc = V4L2_PIX_FMT_RGB565 },
-	[SH_VEU_FMT_RGB666] = { .ydepth = 32, .depth = 32, .name = "BGR666", .fourcc = V4L2_PIX_FMT_BGR666 },
-	[SH_VEU_FMT_RGB24]  = { .ydepth = 24, .depth = 24, .name = "RGB24", .fourcc = V4L2_PIX_FMT_RGB24 },
+	[SH_VEU_FMT_NV12]   = { .ydepth = 8, .depth = 12, .fourcc = V4L2_PIX_FMT_NV12 },
+	[SH_VEU_FMT_NV16]   = { .ydepth = 8, .depth = 16, .fourcc = V4L2_PIX_FMT_NV16 },
+	[SH_VEU_FMT_NV24]   = { .ydepth = 8, .depth = 24, .fourcc = V4L2_PIX_FMT_NV24 },
+	[SH_VEU_FMT_RGB332] = { .ydepth = 8, .depth = 8, .fourcc = V4L2_PIX_FMT_RGB332 },
+	[SH_VEU_FMT_RGB444] = { .ydepth = 16, .depth = 16, .fourcc = V4L2_PIX_FMT_RGB444 },
+	[SH_VEU_FMT_RGB565] = { .ydepth = 16, .depth = 16, .fourcc = V4L2_PIX_FMT_RGB565 },
+	[SH_VEU_FMT_RGB666] = { .ydepth = 32, .depth = 32, .fourcc = V4L2_PIX_FMT_BGR666 },
+	[SH_VEU_FMT_RGB24]  = { .ydepth = 24, .depth = 24, .fourcc = V4L2_PIX_FMT_RGB24 },
 };
 
 #define DEFAULT_IN_VFMT (struct sh_veu_vfmt){						\
@@ -348,9 +348,6 @@
 	strscpy(cap->driver, "sh-veu", sizeof(cap->driver));
 	strscpy(cap->card, "sh-mobile VEU", sizeof(cap->card));
 	strscpy(cap->bus_info, "platform:sh-veu", sizeof(cap->bus_info));
-	cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-
 	return 0;
 }
 
@@ -359,8 +356,6 @@
 	if (f->index >= fmt_num)
 		return -EINVAL;
 
-	strscpy(f->description, sh_veu_fmt[fmt[f->index]].name,
-		sizeof(f->description));
 	f->pixelformat = sh_veu_fmt[fmt[f->index]].fourcc;
 	return 0;
 }
@@ -967,12 +962,14 @@
 	if (!veu_file)
 		return -ENOMEM;
 
+	v4l2_fh_init(&veu_file->fh, video_devdata(file));
 	veu_file->veu_dev = veu;
 	veu_file->cfg_needed = true;
 
 	file->private_data = veu_file;
 
 	pm_runtime_get_sync(veu->dev);
+	v4l2_fh_add(&veu_file->fh);
 
 	dev_dbg(veu->dev, "Created instance %p\n", veu_file);
 
@@ -1002,6 +999,8 @@
 	}
 
 	pm_runtime_put(veu->dev);
+	v4l2_fh_del(&veu_file->fh);
+	v4l2_fh_exit(&veu_file->fh);
 
 	kfree(veu_file);
 
@@ -1039,6 +1038,7 @@
 	.minor		= -1,
 	.release	= video_device_release_empty,
 	.vfl_dir	= VFL_DIR_M2M,
+	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
 };
 
 static const struct v4l2_m2m_ops sh_veu_m2m_ops = {
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 5799aa4..2236702c 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -138,7 +138,6 @@
 
 struct sh_vou_fmt {
 	u32		pfmt;
-	char		*desc;
 	unsigned char	bpp;
 	unsigned char	bpl;
 	unsigned char	rgb;
@@ -152,7 +151,6 @@
 		.pfmt	= V4L2_PIX_FMT_NV12,
 		.bpp	= 12,
 		.bpl	= 1,
-		.desc	= "YVU420 planar",
 		.yf	= 0,
 		.rgb	= 0,
 	},
@@ -160,7 +158,6 @@
 		.pfmt	= V4L2_PIX_FMT_NV16,
 		.bpp	= 16,
 		.bpl	= 1,
-		.desc	= "YVYU planar",
 		.yf	= 1,
 		.rgb	= 0,
 	},
@@ -168,7 +165,6 @@
 		.pfmt	= V4L2_PIX_FMT_RGB24,
 		.bpp	= 24,
 		.bpl	= 3,
-		.desc	= "RGB24",
 		.pkf	= 2,
 		.rgb	= 1,
 	},
@@ -176,7 +172,6 @@
 		.pfmt	= V4L2_PIX_FMT_RGB565,
 		.bpp	= 16,
 		.bpl	= 2,
-		.desc	= "RGB565",
 		.pkf	= 3,
 		.rgb	= 1,
 	},
@@ -184,7 +179,6 @@
 		.pfmt	= V4L2_PIX_FMT_RGB565X,
 		.bpp	= 16,
 		.bpl	= 2,
-		.desc	= "RGB565 byteswapped",
 		.pkf	= 3,
 		.rgb	= 1,
 	},
@@ -381,9 +375,6 @@
 	strscpy(cap->card, "SuperH VOU", sizeof(cap->card));
 	strscpy(cap->driver, "sh-vou", sizeof(cap->driver));
 	strscpy(cap->bus_info, "platform:sh-vou", sizeof(cap->bus_info));
-	cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE |
-			   V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -398,9 +389,6 @@
 
 	dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
 
-	fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	strscpy(fmt->description, vou_fmt[fmt->index].desc,
-		sizeof(fmt->description));
 	fmt->pixelformat = vou_fmt[fmt->index].pfmt;
 
 	return 0;
@@ -494,7 +482,8 @@
 	if (h_idx)
 		vouvcr |= (1 << 14) | vou_scale_v_fld[h_idx - 1];
 
-	dev_dbg(vou_dev->v4l2_dev.dev, "%s: scaling 0x%x\n", fmt->desc, vouvcr);
+	dev_dbg(vou_dev->v4l2_dev.dev, "0x%08x: scaling 0x%x\n",
+		fmt->pfmt, vouvcr);
 
 	/* To produce a colour bar for testing set bit 23 of VOUVCR */
 	sh_vou_reg_ab_write(vou_dev, VOUVCR, vouvcr);
@@ -1218,6 +1207,8 @@
 	.ioctl_ops	= &sh_vou_ioctl_ops,
 	.tvnorms	= V4L2_STD_525_60, /* PAL only supported in 8-bit non-bt656 mode */
 	.vfl_dir	= VFL_DIR_TX,
+	.device_caps	= V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE |
+			  V4L2_CAP_STREAMING,
 };
 
 static int sh_vou_probe(struct platform_device *pdev)
diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
index 79f7db1..e90f1ba 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
@@ -692,11 +692,6 @@
 	strscpy(cap->card, bdisp->pdev->name, sizeof(cap->card));
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d",
 		 BDISP_NAME, bdisp->id);
-
-	cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
-
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
-
 	return 0;
 }
 
@@ -1059,6 +1054,7 @@
 	bdisp->vdev.lock        = &bdisp->lock;
 	bdisp->vdev.vfl_dir     = VFL_DIR_M2M;
 	bdisp->vdev.v4l2_dev    = &bdisp->v4l2_dev;
+	bdisp->vdev.device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
 	snprintf(bdisp->vdev.name, sizeof(bdisp->vdev.name), "%s.%d",
 		 BDISP_NAME, bdisp->id);
 
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index 3c05b3d..5baada4 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -693,16 +693,12 @@
 	fei->sram_size = resource_size(res);
 
 	fei->idle_irq = platform_get_irq_byname(pdev, "c8sectpfe-idle-irq");
-	if (fei->idle_irq < 0) {
-		dev_err(dev, "Can't get c8sectpfe-idle-irq\n");
+	if (fei->idle_irq < 0)
 		return fei->idle_irq;
-	}
 
 	fei->error_irq = platform_get_irq_byname(pdev, "c8sectpfe-error-irq");
-	if (fei->error_irq < 0) {
-		dev_err(dev, "Can't get c8sectpfe-error-irq\n");
+	if (fei->error_irq < 0)
 		return fei->error_irq;
-	}
 
 	platform_set_drvdata(pdev, fei);
 
diff --git a/drivers/media/platform/sti/cec/stih-cec.c b/drivers/media/platform/sti/cec/stih-cec.c
index fc37efe..8118c73 100644
--- a/drivers/media/platform/sti/cec/stih-cec.c
+++ b/drivers/media/platform/sti/cec/stih-cec.c
@@ -313,10 +313,6 @@
 	if (!cec)
 		return -ENOMEM;
 
-	cec->notifier = cec_notifier_get(hdmi_dev);
-	if (!cec->notifier)
-		return -ENOMEM;
-
 	cec->dev = dev;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -340,30 +336,42 @@
 		return PTR_ERR(cec->clk);
 	}
 
-	cec->adap = cec_allocate_adapter(&sti_cec_adap_ops, cec,
-			CEC_NAME, CEC_CAP_DEFAULTS, CEC_MAX_LOG_ADDRS);
+	cec->adap = cec_allocate_adapter(&sti_cec_adap_ops, cec, CEC_NAME,
+					 CEC_CAP_DEFAULTS |
+					 CEC_CAP_CONNECTOR_INFO,
+					 CEC_MAX_LOG_ADDRS);
 	ret = PTR_ERR_OR_ZERO(cec->adap);
 	if (ret)
 		return ret;
 
-	ret = cec_register_adapter(cec->adap, &pdev->dev);
-	if (ret) {
-		cec_delete_adapter(cec->adap);
-		return ret;
+	cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+						       cec->adap);
+	if (!cec->notifier) {
+		ret = -ENOMEM;
+		goto err_delete_adapter;
 	}
 
-	cec_register_cec_notifier(cec->adap, cec->notifier);
+	ret = cec_register_adapter(cec->adap, &pdev->dev);
+	if (ret)
+		goto err_notifier;
 
 	platform_set_drvdata(pdev, cec);
 	return 0;
+
+err_notifier:
+	cec_notifier_cec_adap_unregister(cec->notifier);
+
+err_delete_adapter:
+	cec_delete_adapter(cec->adap);
+	return ret;
 }
 
 static int stih_cec_remove(struct platform_device *pdev)
 {
 	struct stih_cec *cec = platform_get_drvdata(pdev);
 
+	cec_notifier_cec_adap_unregister(cec->notifier);
 	cec_unregister_adapter(cec->adap);
-	cec_notifier_put(cec->notifier);
 
 	return 0;
 }
diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c
index 7917fd2..401aaaf 100644
--- a/drivers/media/platform/sti/hva/hva-hw.c
+++ b/drivers/media/platform/sti/hva/hva-hw.c
@@ -341,10 +341,8 @@
 
 	/* get status interruption resource */
 	ret  = platform_get_irq(pdev, 0);
-	if (ret < 0) {
-		dev_err(dev, "%s     failed to get status IRQ\n", HVA_PREFIX);
+	if (ret < 0)
 		goto err_clk;
-	}
 	hva->irq_its = ret;
 
 	ret = devm_request_threaded_irq(dev, hva->irq_its, hva_hw_its_interrupt,
@@ -360,10 +358,8 @@
 
 	/* get error interruption resource */
 	ret = platform_get_irq(pdev, 1);
-	if (ret < 0) {
-		dev_err(dev, "%s     failed to get error IRQ\n", HVA_PREFIX);
+	if (ret < 0)
 		goto err_clk;
-	}
 	hva->irq_err = ret;
 
 	ret = devm_request_threaded_irq(dev, hva->irq_err, hva_hw_err_interrupt,
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
index d855e9c..9392e34 100644
--- a/drivers/media/platform/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/stm32/stm32-dcmi.c
@@ -100,10 +100,10 @@
 #define OVERRUN_ERROR_THRESHOLD	3
 
 struct dcmi_graph_entity {
-	struct device_node *node;
-
 	struct v4l2_async_subdev asd;
-	struct v4l2_subdev *subdev;
+
+	struct device_node *remote_node;
+	struct v4l2_subdev *source;
 };
 
 struct dcmi_format {
@@ -169,6 +169,10 @@
 
 	/* Ensure DMA operations atomicity */
 	struct mutex			dma_lock;
+
+	struct media_device		mdev;
+	struct media_pad		vid_cap_pad;
+	struct media_pipeline		pipeline;
 };
 
 static inline struct stm32_dcmi *notifier_to_dcmi(struct v4l2_async_notifier *n)
@@ -580,6 +584,144 @@
 	spin_unlock_irq(&dcmi->irqlock);
 }
 
+static struct media_entity *dcmi_find_source(struct stm32_dcmi *dcmi)
+{
+	struct media_entity *entity = &dcmi->vdev->entity;
+	struct media_pad *pad;
+
+	/* Walk searching for entity having no sink */
+	while (1) {
+		pad = &entity->pads[0];
+		if (!(pad->flags & MEDIA_PAD_FL_SINK))
+			break;
+
+		pad = media_entity_remote_pad(pad);
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
+			break;
+
+		entity = pad->entity;
+	}
+
+	return entity;
+}
+
+static int dcmi_pipeline_s_fmt(struct stm32_dcmi *dcmi,
+			       struct v4l2_subdev_pad_config *pad_cfg,
+			       struct v4l2_subdev_format *format)
+{
+	struct media_entity *entity = &dcmi->entity.source->entity;
+	struct v4l2_subdev *subdev;
+	struct media_pad *sink_pad = NULL;
+	struct media_pad *src_pad = NULL;
+	struct media_pad *pad = NULL;
+	struct v4l2_subdev_format fmt = *format;
+	bool found = false;
+	int ret;
+
+	/*
+	 * Starting from sensor subdevice, walk within
+	 * pipeline and set format on each subdevice
+	 */
+	while (1) {
+		unsigned int i;
+
+		/* Search if current entity has a source pad */
+		for (i = 0; i < entity->num_pads; i++) {
+			pad = &entity->pads[i];
+			if (pad->flags & MEDIA_PAD_FL_SOURCE) {
+				src_pad = pad;
+				found = true;
+				break;
+			}
+		}
+		if (!found)
+			break;
+
+		subdev = media_entity_to_v4l2_subdev(entity);
+
+		/* Propagate format on sink pad if any, otherwise source pad */
+		if (sink_pad)
+			pad = sink_pad;
+
+		dev_dbg(dcmi->dev, "\"%s\":%d pad format set to 0x%x %ux%u\n",
+			subdev->name, pad->index, format->format.code,
+			format->format.width, format->format.height);
+
+		fmt.pad = pad->index;
+		ret = v4l2_subdev_call(subdev, pad, set_fmt, pad_cfg, &fmt);
+		if (ret < 0) {
+			dev_err(dcmi->dev, "%s: Failed to set format 0x%x %ux%u on \"%s\":%d pad (%d)\n",
+				__func__, format->format.code,
+				format->format.width, format->format.height,
+				subdev->name, pad->index, ret);
+			return ret;
+		}
+
+		if (fmt.format.code != format->format.code ||
+		    fmt.format.width != format->format.width ||
+		    fmt.format.height != format->format.height) {
+			dev_dbg(dcmi->dev, "\"%s\":%d pad format has been changed to 0x%x %ux%u\n",
+				subdev->name, pad->index, fmt.format.code,
+				fmt.format.width, fmt.format.height);
+		}
+
+		/* Walk to next entity */
+		sink_pad = media_entity_remote_pad(src_pad);
+		if (!sink_pad || !is_media_entity_v4l2_subdev(sink_pad->entity))
+			break;
+
+		entity = sink_pad->entity;
+	}
+	*format = fmt;
+
+	return 0;
+}
+
+static int dcmi_pipeline_s_stream(struct stm32_dcmi *dcmi, int state)
+{
+	struct media_entity *entity = &dcmi->vdev->entity;
+	struct v4l2_subdev *subdev;
+	struct media_pad *pad;
+	int ret;
+
+	/* Start/stop all entities within pipeline */
+	while (1) {
+		pad = &entity->pads[0];
+		if (!(pad->flags & MEDIA_PAD_FL_SINK))
+			break;
+
+		pad = media_entity_remote_pad(pad);
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
+			break;
+
+		entity = pad->entity;
+		subdev = media_entity_to_v4l2_subdev(entity);
+
+		ret = v4l2_subdev_call(subdev, video, s_stream, state);
+		if (ret < 0 && ret != -ENOIOCTLCMD) {
+			dev_err(dcmi->dev, "%s: \"%s\" failed to %s streaming (%d)\n",
+				__func__, subdev->name,
+				state ? "start" : "stop", ret);
+			return ret;
+		}
+
+		dev_dbg(dcmi->dev, "\"%s\" is %s\n",
+			subdev->name, state ? "started" : "stopped");
+	}
+
+	return 0;
+}
+
+static int dcmi_pipeline_start(struct stm32_dcmi *dcmi)
+{
+	return dcmi_pipeline_s_stream(dcmi, 1);
+}
+
+static void dcmi_pipeline_stop(struct stm32_dcmi *dcmi)
+{
+	dcmi_pipeline_s_stream(dcmi, 0);
+}
+
 static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
 	struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq);
@@ -594,14 +736,17 @@
 		goto err_release_buffers;
 	}
 
-	/* Enable stream on the sub device */
-	ret = v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 1);
-	if (ret && ret != -ENOIOCTLCMD) {
-		dev_err(dcmi->dev, "%s: Failed to start streaming, subdev streamon error",
-			__func__);
+	ret = media_pipeline_start(&dcmi->vdev->entity, &dcmi->pipeline);
+	if (ret < 0) {
+		dev_err(dcmi->dev, "%s: Failed to start streaming, media pipeline start error (%d)\n",
+			__func__, ret);
 		goto err_pm_put;
 	}
 
+	ret = dcmi_pipeline_start(dcmi);
+	if (ret)
+		goto err_media_pipeline_stop;
+
 	spin_lock_irq(&dcmi->irqlock);
 
 	/* Set bus width */
@@ -673,7 +818,7 @@
 	if (ret) {
 		dev_err(dcmi->dev, "%s: Start streaming failed, cannot start capture\n",
 			__func__);
-		goto err_subdev_streamoff;
+		goto err_pipeline_stop;
 	}
 
 	/* Enable interruptions */
@@ -684,8 +829,11 @@
 
 	return 0;
 
-err_subdev_streamoff:
-	v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 0);
+err_pipeline_stop:
+	dcmi_pipeline_stop(dcmi);
+
+err_media_pipeline_stop:
+	media_pipeline_stop(&dcmi->vdev->entity);
 
 err_pm_put:
 	pm_runtime_put(dcmi->dev);
@@ -710,13 +858,10 @@
 {
 	struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq);
 	struct dcmi_buf *buf, *node;
-	int ret;
 
-	/* Disable stream on the sub device */
-	ret = v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 0);
-	if (ret && ret != -ENOIOCTLCMD)
-		dev_err(dcmi->dev, "%s: Failed to stop streaming, subdev streamoff error (%d)\n",
-			__func__, ret);
+	dcmi_pipeline_stop(dcmi);
+
+	media_pipeline_stop(&dcmi->vdev->entity);
 
 	spin_lock_irq(&dcmi->irqlock);
 
@@ -857,7 +1002,7 @@
 	}
 
 	v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code);
-	ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt,
+	ret = v4l2_subdev_call(dcmi->entity.source, pad, set_fmt,
 			       &pad_cfg, &format);
 	if (ret < 0)
 		return ret;
@@ -934,8 +1079,7 @@
 	mf->width = sd_framesize.width;
 	mf->height = sd_framesize.height;
 
-	ret = v4l2_subdev_call(dcmi->entity.subdev, pad,
-			       set_fmt, NULL, &format);
+	ret = dcmi_pipeline_s_fmt(dcmi, NULL, &format);
 	if (ret < 0)
 		return ret;
 
@@ -991,7 +1135,7 @@
 	};
 	int ret;
 
-	ret = v4l2_subdev_call(dcmi->entity.subdev, pad, get_fmt, NULL, &fmt);
+	ret = v4l2_subdev_call(dcmi->entity.source, pad, get_fmt, NULL, &fmt);
 	if (ret)
 		return ret;
 
@@ -1020,7 +1164,7 @@
 	}
 
 	v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code);
-	ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt,
+	ret = v4l2_subdev_call(dcmi->entity.source, pad, set_fmt,
 			       &pad_cfg, &format);
 	if (ret < 0)
 		return ret;
@@ -1043,7 +1187,7 @@
 	/*
 	 * Get sensor bounds first
 	 */
-	ret = v4l2_subdev_call(dcmi->entity.subdev, pad, get_selection,
+	ret = v4l2_subdev_call(dcmi->entity.source, pad, get_selection,
 			       NULL, &bounds);
 	if (!ret)
 		*r = bounds.r;
@@ -1224,7 +1368,7 @@
 
 	fse.code = sd_fmt->mbus_code;
 
-	ret = v4l2_subdev_call(dcmi->entity.subdev, pad, enum_frame_size,
+	ret = v4l2_subdev_call(dcmi->entity.source, pad, enum_frame_size,
 			       NULL, &fse);
 	if (ret)
 		return ret;
@@ -1241,7 +1385,7 @@
 {
 	struct stm32_dcmi *dcmi = video_drvdata(file);
 
-	return v4l2_g_parm_cap(video_devdata(file), dcmi->entity.subdev, p);
+	return v4l2_g_parm_cap(video_devdata(file), dcmi->entity.source, p);
 }
 
 static int dcmi_s_parm(struct file *file, void *priv,
@@ -1249,7 +1393,7 @@
 {
 	struct stm32_dcmi *dcmi = video_drvdata(file);
 
-	return v4l2_s_parm_cap(video_devdata(file), dcmi->entity.subdev, p);
+	return v4l2_s_parm_cap(video_devdata(file), dcmi->entity.source, p);
 }
 
 static int dcmi_enum_frameintervals(struct file *file, void *fh,
@@ -1271,7 +1415,7 @@
 
 	fie.code = sd_fmt->mbus_code;
 
-	ret = v4l2_subdev_call(dcmi->entity.subdev, pad,
+	ret = v4l2_subdev_call(dcmi->entity.source, pad,
 			       enum_frame_interval, NULL, &fie);
 	if (ret)
 		return ret;
@@ -1291,7 +1435,7 @@
 static int dcmi_open(struct file *file)
 {
 	struct stm32_dcmi *dcmi = video_drvdata(file);
-	struct v4l2_subdev *sd = dcmi->entity.subdev;
+	struct v4l2_subdev *sd = dcmi->entity.source;
 	int ret;
 
 	if (mutex_lock_interruptible(&dcmi->lock))
@@ -1322,7 +1466,7 @@
 static int dcmi_release(struct file *file)
 {
 	struct stm32_dcmi *dcmi = video_drvdata(file);
-	struct v4l2_subdev *sd = dcmi->entity.subdev;
+	struct v4l2_subdev *sd = dcmi->entity.source;
 	bool fh_singular;
 	int ret;
 
@@ -1409,6 +1553,12 @@
 	return 0;
 }
 
+/*
+ * FIXME: For the time being we only support subdevices
+ * which expose RGB & YUV "parallel form" mbus code (_2X8).
+ * Nevertheless, this allows to support serial source subdevices
+ * and serial to parallel bridges which conform to this.
+ */
 static const struct dcmi_format dcmi_formats[] = {
 	{
 		.fourcc = V4L2_PIX_FMT_RGB565,
@@ -1433,7 +1583,7 @@
 {
 	const struct dcmi_format *sd_fmts[ARRAY_SIZE(dcmi_formats)];
 	unsigned int num_fmts = 0, i, j;
-	struct v4l2_subdev *subdev = dcmi->entity.subdev;
+	struct v4l2_subdev *subdev = dcmi->entity.source;
 	struct v4l2_subdev_mbus_code_enum mbus_code = {
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 	};
@@ -1447,12 +1597,20 @@
 			/* Code supported, have we got this fourcc yet? */
 			for (j = 0; j < num_fmts; j++)
 				if (sd_fmts[j]->fourcc ==
-						dcmi_formats[i].fourcc)
+						dcmi_formats[i].fourcc) {
 					/* Already available */
+					dev_dbg(dcmi->dev, "Skipping fourcc/code: %4.4s/0x%x\n",
+						(char *)&sd_fmts[j]->fourcc,
+						mbus_code.code);
 					break;
-			if (j == num_fmts)
+				}
+			if (j == num_fmts) {
 				/* New */
 				sd_fmts[num_fmts++] = dcmi_formats + i;
+				dev_dbg(dcmi->dev, "Supported fourcc/code: %4.4s/0x%x\n",
+					(char *)&sd_fmts[num_fmts - 1]->fourcc,
+					sd_fmts[num_fmts - 1]->mbus_code);
+			}
 		}
 		mbus_code.index++;
 	}
@@ -1479,7 +1637,7 @@
 static int dcmi_framesizes_init(struct stm32_dcmi *dcmi)
 {
 	unsigned int num_fsize = 0;
-	struct v4l2_subdev *subdev = dcmi->entity.subdev;
+	struct v4l2_subdev *subdev = dcmi->entity.source;
 	struct v4l2_subdev_frame_size_enum fse = {
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 		.code = dcmi->sd_format->mbus_code,
@@ -1526,7 +1684,20 @@
 	struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier);
 	int ret;
 
-	dcmi->vdev->ctrl_handler = dcmi->entity.subdev->ctrl_handler;
+	/*
+	 * Now that the graph is complete,
+	 * we search for the source subdevice
+	 * in order to expose it through V4L2 interface
+	 */
+	dcmi->entity.source =
+		media_entity_to_v4l2_subdev(dcmi_find_source(dcmi));
+	if (!dcmi->entity.source) {
+		dev_err(dcmi->dev, "Source subdevice not found\n");
+		return -ENODEV;
+	}
+
+	dcmi->vdev->ctrl_handler = dcmi->entity.source->ctrl_handler;
+
 	ret = dcmi_formats_init(dcmi);
 	if (ret) {
 		dev_err(dcmi->dev, "No supported mediabus format found\n");
@@ -1551,14 +1722,6 @@
 		return ret;
 	}
 
-	ret = video_register_device(dcmi->vdev, VFL_TYPE_GRABBER, -1);
-	if (ret) {
-		dev_err(dcmi->dev, "Failed to register video device\n");
-		return ret;
-	}
-
-	dev_dbg(dcmi->dev, "Device registered as %s\n",
-		video_device_node_name(dcmi->vdev));
 	return 0;
 }
 
@@ -1579,12 +1742,31 @@
 				   struct v4l2_async_subdev *asd)
 {
 	struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier);
+	unsigned int ret;
+	int src_pad;
 
-	dev_dbg(dcmi->dev, "Subdev %s bound\n", subdev->name);
+	dev_dbg(dcmi->dev, "Subdev \"%s\" bound\n", subdev->name);
 
-	dcmi->entity.subdev = subdev;
+	/*
+	 * Link this sub-device to DCMI, it could be
+	 * a parallel camera sensor or a bridge
+	 */
+	src_pad = media_entity_get_fwnode_pad(&subdev->entity,
+					      subdev->fwnode,
+					      MEDIA_PAD_FL_SOURCE);
 
-	return 0;
+	ret = media_create_pad_link(&subdev->entity, src_pad,
+				    &dcmi->vdev->entity, 0,
+				    MEDIA_LNK_FL_IMMUTABLE |
+				    MEDIA_LNK_FL_ENABLED);
+	if (ret)
+		dev_err(dcmi->dev, "Failed to create media pad link with subdev \"%s\"\n",
+			subdev->name);
+	else
+		dev_dbg(dcmi->dev, "DCMI is now linked to \"%s\"\n",
+			subdev->name);
+
+	return ret;
 }
 
 static const struct v4l2_async_notifier_operations dcmi_graph_notify_ops = {
@@ -1608,7 +1790,7 @@
 		return -EINVAL;
 
 	/* Remote node to connect */
-	dcmi->entity.node = remote;
+	dcmi->entity.remote_node = remote;
 	dcmi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 	dcmi->entity.asd.match.fwnode = of_fwnode_handle(remote);
 	return 0;
@@ -1631,7 +1813,7 @@
 					     &dcmi->entity.asd);
 	if (ret) {
 		dev_err(dcmi->dev, "Failed to add subdev notifier\n");
-		of_node_put(dcmi->entity.node);
+		of_node_put(dcmi->entity.remote_node);
 		return ret;
 	}
 
@@ -1679,7 +1861,6 @@
 	np = of_graph_get_next_endpoint(np, NULL);
 	if (!np) {
 		dev_err(&pdev->dev, "Could not find the endpoint\n");
-		of_node_put(np);
 		return -ENODEV;
 	}
 
@@ -1699,11 +1880,8 @@
 	dcmi->bus.data_shift = ep.bus.parallel.data_shift;
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq <= 0) {
-		if (irq != -EPROBE_DEFER)
-			dev_err(&pdev->dev, "Could not get irq\n");
+	if (irq <= 0)
 		return irq ? irq : -ENXIO;
-	}
 
 	dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!dcmi->res) {
@@ -1751,10 +1929,19 @@
 
 	q = &dcmi->queue;
 
+	dcmi->v4l2_dev.mdev = &dcmi->mdev;
+
+	/* Initialize media device */
+	strscpy(dcmi->mdev.model, DRV_NAME, sizeof(dcmi->mdev.model));
+	snprintf(dcmi->mdev.bus_info, sizeof(dcmi->mdev.bus_info),
+		 "platform:%s", DRV_NAME);
+	dcmi->mdev.dev = &pdev->dev;
+	media_device_init(&dcmi->mdev);
+
 	/* Initialize the top-level structure */
 	ret = v4l2_device_register(&pdev->dev, &dcmi->v4l2_dev);
 	if (ret)
-		goto err_dma_release;
+		goto err_media_device_cleanup;
 
 	dcmi->vdev = video_device_alloc();
 	if (!dcmi->vdev) {
@@ -1774,6 +1961,25 @@
 				  V4L2_CAP_READWRITE;
 	video_set_drvdata(dcmi->vdev, dcmi);
 
+	/* Media entity pads */
+	dcmi->vid_cap_pad.flags = MEDIA_PAD_FL_SINK;
+	ret = media_entity_pads_init(&dcmi->vdev->entity,
+				     1, &dcmi->vid_cap_pad);
+	if (ret) {
+		dev_err(dcmi->dev, "Failed to init media entity pad\n");
+		goto err_device_release;
+	}
+	dcmi->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
+
+	ret = video_register_device(dcmi->vdev, VFL_TYPE_GRABBER, -1);
+	if (ret) {
+		dev_err(dcmi->dev, "Failed to register video device\n");
+		goto err_media_entity_cleanup;
+	}
+
+	dev_dbg(dcmi->dev, "Device registered as %s\n",
+		video_device_node_name(dcmi->vdev));
+
 	/* Buffer queue */
 	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
@@ -1789,12 +1995,12 @@
 	ret = vb2_queue_init(q);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to initialize vb2 queue\n");
-		goto err_device_release;
+		goto err_media_entity_cleanup;
 	}
 
 	ret = dcmi_graph_init(dcmi);
 	if (ret < 0)
-		goto err_device_release;
+		goto err_media_entity_cleanup;
 
 	/* Reset device */
 	ret = reset_control_assert(dcmi->rstc);
@@ -1821,11 +2027,14 @@
 
 err_cleanup:
 	v4l2_async_notifier_cleanup(&dcmi->notifier);
+err_media_entity_cleanup:
+	media_entity_cleanup(&dcmi->vdev->entity);
 err_device_release:
 	video_device_release(dcmi->vdev);
 err_device_unregister:
 	v4l2_device_unregister(&dcmi->v4l2_dev);
-err_dma_release:
+err_media_device_cleanup:
+	media_device_cleanup(&dcmi->mdev);
 	dma_release_channel(dcmi->dma_chan);
 
 	return ret;
@@ -1839,7 +2048,9 @@
 
 	v4l2_async_notifier_unregister(&dcmi->notifier);
 	v4l2_async_notifier_cleanup(&dcmi->notifier);
+	media_entity_cleanup(&dcmi->vdev->entity);
 	v4l2_device_unregister(&dcmi->v4l2_dev);
+	media_device_cleanup(&dcmi->mdev);
 
 	dma_release_channel(dcmi->dma_chan);
 
diff --git a/drivers/media/platform/sunxi/Kconfig b/drivers/media/platform/sunxi/Kconfig
new file mode 100644
index 0000000..71808e9
--- /dev/null
+++ b/drivers/media/platform/sunxi/Kconfig
@@ -0,0 +1,2 @@
+source "drivers/media/platform/sunxi/sun4i-csi/Kconfig"
+source "drivers/media/platform/sunxi/sun6i-csi/Kconfig"
diff --git a/drivers/media/platform/sunxi/Makefile b/drivers/media/platform/sunxi/Makefile
new file mode 100644
index 0000000..a051275
--- /dev/null
+++ b/drivers/media/platform/sunxi/Makefile
@@ -0,0 +1,2 @@
+obj-y		+= sun4i-csi/
+obj-y		+= sun6i-csi/
diff --git a/drivers/media/platform/sunxi/sun4i-csi/Kconfig b/drivers/media/platform/sunxi/sun4i-csi/Kconfig
new file mode 100644
index 0000000..e86e29b
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/Kconfig
@@ -0,0 +1,11 @@
+config VIDEO_SUN4I_CSI
+	tristate "Allwinner A10 CMOS Sensor Interface Support"
+	depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API && HAS_DMA
+	depends on ARCH_SUNXI || COMPILE_TEST
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_FWNODE
+	help
+	  This is a V4L2 driver for the Allwinner A10 CSI
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called sun4i_csi.
diff --git a/drivers/media/platform/sunxi/sun4i-csi/Makefile b/drivers/media/platform/sunxi/sun4i-csi/Makefile
new file mode 100644
index 0000000..7c790a5
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/Makefile
@@ -0,0 +1,5 @@
+sun4i-csi-y += sun4i_csi.o
+sun4i-csi-y += sun4i_dma.o
+sun4i-csi-y += sun4i_v4l2.o
+
+obj-$(CONFIG_VIDEO_SUN4I_CSI)	+= sun4i-csi.o
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
new file mode 100644
index 0000000..f36dc62
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
@@ -0,0 +1,314 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 NextThing Co
+ * Copyright (C) 2016-2019 Bootlin
+ *
+ * Author: Maxime Ripard <maxime.ripard@bootlin.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mediabus.h>
+
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "sun4i_csi.h"
+
+static const struct media_entity_operations sun4i_csi_video_entity_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+static int sun4i_csi_notify_bound(struct v4l2_async_notifier *notifier,
+				  struct v4l2_subdev *subdev,
+				  struct v4l2_async_subdev *asd)
+{
+	struct sun4i_csi *csi = container_of(notifier, struct sun4i_csi,
+					     notifier);
+
+	csi->src_subdev = subdev;
+	csi->src_pad = media_entity_get_fwnode_pad(&subdev->entity,
+						   subdev->fwnode,
+						   MEDIA_PAD_FL_SOURCE);
+	if (csi->src_pad < 0) {
+		dev_err(csi->dev, "Couldn't find output pad for subdev %s\n",
+			subdev->name);
+		return csi->src_pad;
+	}
+
+	dev_dbg(csi->dev, "Bound %s pad: %d\n", subdev->name, csi->src_pad);
+	return 0;
+}
+
+static int sun4i_csi_notify_complete(struct v4l2_async_notifier *notifier)
+{
+	struct sun4i_csi *csi = container_of(notifier, struct sun4i_csi,
+					     notifier);
+	struct v4l2_subdev *subdev = &csi->subdev;
+	struct video_device *vdev = &csi->vdev;
+	int ret;
+
+	ret = v4l2_device_register_subdev(&csi->v4l, subdev);
+	if (ret < 0)
+		return ret;
+
+	ret = sun4i_csi_v4l2_register(csi);
+	if (ret < 0)
+		return ret;
+
+	ret = media_device_register(&csi->mdev);
+	if (ret)
+		return ret;
+
+	/* Create link from subdev to main device */
+	ret = media_create_pad_link(&subdev->entity, CSI_SUBDEV_SOURCE,
+				    &vdev->entity, 0,
+				    MEDIA_LNK_FL_ENABLED |
+				    MEDIA_LNK_FL_IMMUTABLE);
+	if (ret)
+		goto err_clean_media;
+
+	ret = media_create_pad_link(&csi->src_subdev->entity, csi->src_pad,
+				    &subdev->entity, CSI_SUBDEV_SINK,
+				    MEDIA_LNK_FL_ENABLED |
+				    MEDIA_LNK_FL_IMMUTABLE);
+	if (ret)
+		goto err_clean_media;
+
+	ret = v4l2_device_register_subdev_nodes(&csi->v4l);
+	if (ret < 0)
+		goto err_clean_media;
+
+	return 0;
+
+err_clean_media:
+	media_device_unregister(&csi->mdev);
+
+	return ret;
+}
+
+static const struct v4l2_async_notifier_operations sun4i_csi_notify_ops = {
+	.bound		= sun4i_csi_notify_bound,
+	.complete	= sun4i_csi_notify_complete,
+};
+
+static int sun4i_csi_notifier_init(struct sun4i_csi *csi)
+{
+	struct v4l2_fwnode_endpoint vep = {
+		.bus_type = V4L2_MBUS_PARALLEL,
+	};
+	struct fwnode_handle *ep;
+	int ret;
+
+	v4l2_async_notifier_init(&csi->notifier);
+
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
+					     FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (!ep)
+		return -EINVAL;
+
+	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+	if (ret)
+		goto out;
+
+	csi->bus = vep.bus.parallel;
+
+	ret = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier,
+							   ep, &csi->asd);
+	if (ret)
+		goto out;
+
+	csi->notifier.ops = &sun4i_csi_notify_ops;
+
+out:
+	fwnode_handle_put(ep);
+	return ret;
+}
+
+static int sun4i_csi_probe(struct platform_device *pdev)
+{
+	struct v4l2_subdev *subdev;
+	struct video_device *vdev;
+	struct sun4i_csi *csi;
+	struct resource *res;
+	int ret;
+	int irq;
+
+	csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
+	if (!csi)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, csi);
+	csi->dev = &pdev->dev;
+	subdev = &csi->subdev;
+	vdev = &csi->vdev;
+
+	csi->mdev.dev = csi->dev;
+	strscpy(csi->mdev.model, "Allwinner Video Capture Device",
+		sizeof(csi->mdev.model));
+	csi->mdev.hw_revision = 0;
+	media_device_init(&csi->mdev);
+	csi->v4l.mdev = &csi->mdev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	csi->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(csi->regs))
+		return PTR_ERR(csi->regs);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	csi->bus_clk = devm_clk_get(&pdev->dev, "bus");
+	if (IS_ERR(csi->bus_clk)) {
+		dev_err(&pdev->dev, "Couldn't get our bus clock\n");
+		return PTR_ERR(csi->bus_clk);
+	}
+
+	csi->isp_clk = devm_clk_get(&pdev->dev, "isp");
+	if (IS_ERR(csi->isp_clk)) {
+		dev_err(&pdev->dev, "Couldn't get our ISP clock\n");
+		return PTR_ERR(csi->isp_clk);
+	}
+
+	csi->ram_clk = devm_clk_get(&pdev->dev, "ram");
+	if (IS_ERR(csi->ram_clk)) {
+		dev_err(&pdev->dev, "Couldn't get our ram clock\n");
+		return PTR_ERR(csi->ram_clk);
+	}
+
+	csi->rst = devm_reset_control_get(&pdev->dev, NULL);
+	if (IS_ERR(csi->rst)) {
+		dev_err(&pdev->dev, "Couldn't get our reset line\n");
+		return PTR_ERR(csi->rst);
+	}
+
+	/* Initialize subdev */
+	v4l2_subdev_init(subdev, &sun4i_csi_subdev_ops);
+	subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+	subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+	subdev->owner = THIS_MODULE;
+	snprintf(subdev->name, sizeof(subdev->name), "sun4i-csi-0");
+	v4l2_set_subdevdata(subdev, csi);
+
+	csi->subdev_pads[CSI_SUBDEV_SINK].flags =
+		MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
+	csi->subdev_pads[CSI_SUBDEV_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_pads_init(&subdev->entity, CSI_SUBDEV_PADS,
+				     csi->subdev_pads);
+	if (ret < 0)
+		return ret;
+
+	csi->vdev_pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
+	vdev->entity.ops = &sun4i_csi_video_entity_ops;
+	ret = media_entity_pads_init(&vdev->entity, 1, &csi->vdev_pad);
+	if (ret < 0)
+		return ret;
+
+	ret = sun4i_csi_dma_register(csi, irq);
+	if (ret)
+		goto err_clean_pad;
+
+	ret = sun4i_csi_notifier_init(csi);
+	if (ret)
+		goto err_unregister_media;
+
+	ret = v4l2_async_notifier_register(&csi->v4l, &csi->notifier);
+	if (ret) {
+		dev_err(csi->dev, "Couldn't register our notifier.\n");
+		goto err_unregister_media;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+
+err_unregister_media:
+	media_device_unregister(&csi->mdev);
+	sun4i_csi_dma_unregister(csi);
+
+err_clean_pad:
+	media_device_cleanup(&csi->mdev);
+
+	return ret;
+}
+
+static int sun4i_csi_remove(struct platform_device *pdev)
+{
+	struct sun4i_csi *csi = platform_get_drvdata(pdev);
+
+	v4l2_async_notifier_unregister(&csi->notifier);
+	v4l2_async_notifier_cleanup(&csi->notifier);
+	media_device_unregister(&csi->mdev);
+	sun4i_csi_dma_unregister(csi);
+	media_device_cleanup(&csi->mdev);
+
+	return 0;
+}
+
+static const struct of_device_id sun4i_csi_of_match[] = {
+	{ .compatible = "allwinner,sun7i-a20-csi0" },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sun4i_csi_of_match);
+
+static int __maybe_unused sun4i_csi_runtime_resume(struct device *dev)
+{
+	struct sun4i_csi *csi = dev_get_drvdata(dev);
+
+	reset_control_deassert(csi->rst);
+	clk_prepare_enable(csi->bus_clk);
+	clk_prepare_enable(csi->ram_clk);
+	clk_set_rate(csi->isp_clk, 80000000);
+	clk_prepare_enable(csi->isp_clk);
+
+	writel(1, csi->regs + CSI_EN_REG);
+
+	return 0;
+}
+
+static int __maybe_unused sun4i_csi_runtime_suspend(struct device *dev)
+{
+	struct sun4i_csi *csi = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(csi->isp_clk);
+	clk_disable_unprepare(csi->ram_clk);
+	clk_disable_unprepare(csi->bus_clk);
+
+	reset_control_assert(csi->rst);
+
+	return 0;
+}
+
+static const struct dev_pm_ops sun4i_csi_pm_ops = {
+	SET_RUNTIME_PM_OPS(sun4i_csi_runtime_suspend,
+			   sun4i_csi_runtime_resume,
+			   NULL)
+};
+
+static struct platform_driver sun4i_csi_driver = {
+	.probe	= sun4i_csi_probe,
+	.remove	= sun4i_csi_remove,
+	.driver	= {
+		.name		= "sun4i-csi",
+		.of_match_table	= sun4i_csi_of_match,
+		.pm		= &sun4i_csi_pm_ops,
+	},
+};
+module_platform_driver(sun4i_csi_driver);
+
+MODULE_DESCRIPTION("Allwinner A10 Camera Sensor Interface driver");
+MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h
new file mode 100644
index 0000000..001c8bd
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 NextThing Co
+ * Copyright (C) 2016-2019 Bootlin
+ *
+ * Author: Maxime Ripard <maxime.ripard@bootlin.com>
+ */
+
+#ifndef _SUN4I_CSI_H_
+#define _SUN4I_CSI_H_
+
+#include <media/media-device.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/videobuf2-core.h>
+
+#define CSI_EN_REG			0x00
+
+#define CSI_CFG_REG			0x04
+#define CSI_CFG_INPUT_FMT(fmt)			((fmt) << 20)
+#define CSI_CFG_OUTPUT_FMT(fmt)			((fmt) << 16)
+#define CSI_CFG_YUV_DATA_SEQ(seq)		((seq) << 8)
+#define CSI_CFG_VSYNC_POL(pol)			((pol) << 2)
+#define CSI_CFG_HSYNC_POL(pol)			((pol) << 1)
+#define CSI_CFG_PCLK_POL(pol)			((pol) << 0)
+
+#define CSI_CPT_CTRL_REG		0x08
+#define CSI_CPT_CTRL_VIDEO_START		BIT(1)
+#define CSI_CPT_CTRL_IMAGE_START		BIT(0)
+
+#define CSI_BUF_ADDR_REG(fifo, buf)	(0x10 + (0x8 * (fifo)) + (0x4 * (buf)))
+
+#define CSI_BUF_CTRL_REG		0x28
+#define CSI_BUF_CTRL_DBN			BIT(2)
+#define CSI_BUF_CTRL_DBS			BIT(1)
+#define CSI_BUF_CTRL_DBE			BIT(0)
+
+#define CSI_INT_EN_REG			0x30
+#define CSI_INT_FRM_DONE			BIT(1)
+#define CSI_INT_CPT_DONE			BIT(0)
+
+#define CSI_INT_STA_REG			0x34
+
+#define CSI_WIN_CTRL_W_REG		0x40
+#define CSI_WIN_CTRL_W_ACTIVE(w)		((w) << 16)
+
+#define CSI_WIN_CTRL_H_REG		0x44
+#define CSI_WIN_CTRL_H_ACTIVE(h)		((h) << 16)
+
+#define CSI_BUF_LEN_REG			0x48
+
+#define CSI_MAX_BUFFER		2
+#define CSI_MAX_HEIGHT		8192U
+#define CSI_MAX_WIDTH		8192U
+
+enum csi_input {
+	CSI_INPUT_RAW	= 0,
+	CSI_INPUT_BT656	= 2,
+	CSI_INPUT_YUV	= 3,
+};
+
+enum csi_output_raw {
+	CSI_OUTPUT_RAW_PASSTHROUGH = 0,
+};
+
+enum csi_output_yuv {
+	CSI_OUTPUT_YUV_422_PLANAR	= 0,
+	CSI_OUTPUT_YUV_420_PLANAR	= 1,
+	CSI_OUTPUT_YUV_422_UV		= 4,
+	CSI_OUTPUT_YUV_420_UV		= 5,
+	CSI_OUTPUT_YUV_422_MACRO	= 8,
+	CSI_OUTPUT_YUV_420_MACRO	= 9,
+};
+
+enum csi_yuv_data_seq {
+	CSI_YUV_DATA_SEQ_YUYV	= 0,
+	CSI_YUV_DATA_SEQ_YVYU	= 1,
+	CSI_YUV_DATA_SEQ_UYVY	= 2,
+	CSI_YUV_DATA_SEQ_VYUY	= 3,
+};
+
+enum csi_subdev_pads {
+	CSI_SUBDEV_SINK,
+	CSI_SUBDEV_SOURCE,
+
+	CSI_SUBDEV_PADS,
+};
+
+extern const struct v4l2_subdev_ops sun4i_csi_subdev_ops;
+
+struct sun4i_csi_format {
+	u32			mbus;
+	u32			fourcc;
+	enum csi_input		input;
+	u32			output;
+	unsigned int		num_planes;
+	u8			bpp[3];
+	unsigned int		hsub;
+	unsigned int		vsub;
+};
+
+const struct sun4i_csi_format *sun4i_csi_find_format(const u32 *fourcc,
+						     const u32 *mbus);
+
+struct sun4i_csi {
+	/* Device resources */
+	struct device			*dev;
+
+	void __iomem			*regs;
+	struct clk			*bus_clk;
+	struct clk			*isp_clk;
+	struct clk			*ram_clk;
+	struct reset_control		*rst;
+
+	struct vb2_v4l2_buffer		*current_buf[CSI_MAX_BUFFER];
+
+	struct {
+		size_t			size;
+		void			*vaddr;
+		dma_addr_t		paddr;
+	} scratch;
+
+	struct v4l2_fwnode_bus_parallel	bus;
+
+	/* Main Device */
+	struct v4l2_device		v4l;
+	struct media_device		mdev;
+	struct video_device		vdev;
+	struct media_pad		vdev_pad;
+	struct v4l2_pix_format_mplane	fmt;
+
+	/* Local subdev */
+	struct v4l2_subdev		subdev;
+	struct media_pad		subdev_pads[CSI_SUBDEV_PADS];
+	struct v4l2_mbus_framefmt	subdev_fmt;
+
+	/* V4L2 Async variables */
+	struct v4l2_async_subdev	asd;
+	struct v4l2_async_notifier	notifier;
+	struct v4l2_subdev		*src_subdev;
+	int				src_pad;
+
+	/* V4L2 variables */
+	struct mutex			lock;
+
+	/* Videobuf2 */
+	struct vb2_queue		queue;
+	struct list_head		buf_list;
+	spinlock_t			qlock;
+	unsigned int			sequence;
+};
+
+int sun4i_csi_dma_register(struct sun4i_csi *csi, int irq);
+void sun4i_csi_dma_unregister(struct sun4i_csi *csi);
+
+int sun4i_csi_v4l2_register(struct sun4i_csi *csi);
+
+#endif /* _SUN4I_CSI_H_ */
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c
new file mode 100644
index 0000000..d6979e1
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c
@@ -0,0 +1,454 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 NextThing Co
+ * Copyright (C) 2016-2019 Bootlin
+ *
+ * Author: Maxime Ripard <maxime.ripard@bootlin.com>
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "sun4i_csi.h"
+
+struct sun4i_csi_buffer {
+	struct vb2_v4l2_buffer	vb;
+	struct list_head	list;
+};
+
+static inline struct sun4i_csi_buffer *
+vb2_v4l2_to_csi_buffer(const struct vb2_v4l2_buffer *p)
+{
+	return container_of(p, struct sun4i_csi_buffer, vb);
+}
+
+static inline struct sun4i_csi_buffer *
+vb2_to_csi_buffer(const struct vb2_buffer *p)
+{
+	return vb2_v4l2_to_csi_buffer(to_vb2_v4l2_buffer(p));
+}
+
+static void sun4i_csi_capture_start(struct sun4i_csi *csi)
+{
+	writel(CSI_CPT_CTRL_VIDEO_START, csi->regs + CSI_CPT_CTRL_REG);
+}
+
+static void sun4i_csi_capture_stop(struct sun4i_csi *csi)
+{
+	writel(0, csi->regs + CSI_CPT_CTRL_REG);
+}
+
+static int sun4i_csi_queue_setup(struct vb2_queue *vq,
+				 unsigned int *nbuffers,
+				 unsigned int *nplanes,
+				 unsigned int sizes[],
+				 struct device *alloc_devs[])
+{
+	struct sun4i_csi *csi = vb2_get_drv_priv(vq);
+	unsigned int num_planes = csi->fmt.num_planes;
+	unsigned int i;
+
+	if (*nplanes) {
+		if (*nplanes != num_planes)
+			return -EINVAL;
+
+		for (i = 0; i < num_planes; i++)
+			if (sizes[i] < csi->fmt.plane_fmt[i].sizeimage)
+				return -EINVAL;
+		return 0;
+	}
+
+	*nplanes = num_planes;
+	for (i = 0; i < num_planes; i++)
+		sizes[i] = csi->fmt.plane_fmt[i].sizeimage;
+
+	return 0;
+};
+
+static int sun4i_csi_buffer_prepare(struct vb2_buffer *vb)
+{
+	struct sun4i_csi *csi = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned int i;
+
+	for (i = 0; i < csi->fmt.num_planes; i++) {
+		unsigned long size = csi->fmt.plane_fmt[i].sizeimage;
+
+		if (vb2_plane_size(vb, i) < size) {
+			dev_err(csi->dev, "buffer too small (%lu < %lu)\n",
+				vb2_plane_size(vb, i), size);
+			return -EINVAL;
+		}
+
+		vb2_set_plane_payload(vb, i, size);
+	}
+
+	return 0;
+}
+
+static int sun4i_csi_setup_scratch_buffer(struct sun4i_csi *csi,
+					  unsigned int slot)
+{
+	dma_addr_t addr = csi->scratch.paddr;
+	unsigned int plane;
+
+	dev_dbg(csi->dev,
+		"No more available buffer, using the scratch buffer\n");
+
+	for (plane = 0; plane < csi->fmt.num_planes; plane++) {
+		writel(addr, csi->regs + CSI_BUF_ADDR_REG(plane, slot));
+		addr += csi->fmt.plane_fmt[plane].sizeimage;
+	}
+
+	csi->current_buf[slot] = NULL;
+	return 0;
+}
+
+static int sun4i_csi_buffer_fill_slot(struct sun4i_csi *csi, unsigned int slot)
+{
+	struct sun4i_csi_buffer *c_buf;
+	struct vb2_v4l2_buffer *v_buf;
+	unsigned int plane;
+
+	/*
+	 * We should never end up in a situation where we overwrite an
+	 * already filled slot.
+	 */
+	if (WARN_ON(csi->current_buf[slot]))
+		return -EINVAL;
+
+	if (list_empty(&csi->buf_list))
+		return sun4i_csi_setup_scratch_buffer(csi, slot);
+
+	c_buf = list_first_entry(&csi->buf_list, struct sun4i_csi_buffer, list);
+	list_del_init(&c_buf->list);
+
+	v_buf = &c_buf->vb;
+	csi->current_buf[slot] = v_buf;
+
+	for (plane = 0; plane < csi->fmt.num_planes; plane++) {
+		dma_addr_t buf_addr;
+
+		buf_addr = vb2_dma_contig_plane_dma_addr(&v_buf->vb2_buf,
+							 plane);
+		writel(buf_addr, csi->regs + CSI_BUF_ADDR_REG(plane, slot));
+	}
+
+	return 0;
+}
+
+static int sun4i_csi_buffer_fill_all(struct sun4i_csi *csi)
+{
+	unsigned int slot;
+	int ret;
+
+	for (slot = 0; slot < CSI_MAX_BUFFER; slot++) {
+		ret = sun4i_csi_buffer_fill_slot(csi, slot);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void sun4i_csi_buffer_mark_done(struct sun4i_csi *csi,
+				       unsigned int slot,
+				       unsigned int sequence)
+{
+	struct vb2_v4l2_buffer *v_buf;
+
+	if (!csi->current_buf[slot]) {
+		dev_dbg(csi->dev, "Scratch buffer was used, ignoring..\n");
+		return;
+	}
+
+	v_buf = csi->current_buf[slot];
+	v_buf->field = csi->fmt.field;
+	v_buf->sequence = sequence;
+	v_buf->vb2_buf.timestamp = ktime_get_ns();
+	vb2_buffer_done(&v_buf->vb2_buf, VB2_BUF_STATE_DONE);
+
+	csi->current_buf[slot] = NULL;
+}
+
+static int sun4i_csi_buffer_flip(struct sun4i_csi *csi, unsigned int sequence)
+{
+	u32 reg = readl(csi->regs + CSI_BUF_CTRL_REG);
+	unsigned int next;
+
+	/* Our next buffer is not the current buffer */
+	next = !(reg & CSI_BUF_CTRL_DBS);
+
+	/* Report the previous buffer as done */
+	sun4i_csi_buffer_mark_done(csi, next, sequence);
+
+	/* Put a new buffer in there */
+	return sun4i_csi_buffer_fill_slot(csi, next);
+}
+
+static void sun4i_csi_buffer_queue(struct vb2_buffer *vb)
+{
+	struct sun4i_csi *csi = vb2_get_drv_priv(vb->vb2_queue);
+	struct sun4i_csi_buffer *buf = vb2_to_csi_buffer(vb);
+	unsigned long flags;
+
+	spin_lock_irqsave(&csi->qlock, flags);
+	list_add_tail(&buf->list, &csi->buf_list);
+	spin_unlock_irqrestore(&csi->qlock, flags);
+}
+
+static void return_all_buffers(struct sun4i_csi *csi,
+			       enum vb2_buffer_state state)
+{
+	struct sun4i_csi_buffer *buf, *node;
+	unsigned int slot;
+
+	list_for_each_entry_safe(buf, node, &csi->buf_list, list) {
+		vb2_buffer_done(&buf->vb.vb2_buf, state);
+		list_del(&buf->list);
+	}
+
+	for (slot = 0; slot < CSI_MAX_BUFFER; slot++) {
+		struct vb2_v4l2_buffer *v_buf = csi->current_buf[slot];
+
+		if (!v_buf)
+			continue;
+
+		vb2_buffer_done(&v_buf->vb2_buf, state);
+		csi->current_buf[slot] = NULL;
+	}
+}
+
+static int sun4i_csi_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct sun4i_csi *csi = vb2_get_drv_priv(vq);
+	struct v4l2_fwnode_bus_parallel *bus = &csi->bus;
+	const struct sun4i_csi_format *csi_fmt;
+	unsigned long hsync_pol, pclk_pol, vsync_pol;
+	unsigned long flags;
+	unsigned int i;
+	int ret;
+
+	csi_fmt = sun4i_csi_find_format(&csi->fmt.pixelformat, NULL);
+	if (!csi_fmt)
+		return -EINVAL;
+
+	dev_dbg(csi->dev, "Starting capture\n");
+
+	csi->sequence = 0;
+
+	/*
+	 * We need a scratch buffer in case where we'll not have any
+	 * more buffer queued so that we don't error out. One of those
+	 * cases is when you end up at the last frame to capture, you
+	 * don't havea any buffer queued any more, and yet it doesn't
+	 * really matter since you'll never reach the next buffer.
+	 *
+	 * Since we support the multi-planar API, we need to have a
+	 * buffer for each plane. Allocating a single one large enough
+	 * to hold all the buffers is simpler, so let's go for that.
+	 */
+	csi->scratch.size = 0;
+	for (i = 0; i < csi->fmt.num_planes; i++)
+		csi->scratch.size += csi->fmt.plane_fmt[i].sizeimage;
+
+	csi->scratch.vaddr = dma_alloc_coherent(csi->dev,
+						csi->scratch.size,
+						&csi->scratch.paddr,
+						GFP_KERNEL);
+	if (!csi->scratch.vaddr) {
+		dev_err(csi->dev, "Failed to allocate scratch buffer\n");
+		ret = -ENOMEM;
+		goto err_clear_dma_queue;
+	}
+
+	ret = media_pipeline_start(&csi->vdev.entity, &csi->vdev.pipe);
+	if (ret < 0)
+		goto err_free_scratch_buffer;
+
+	spin_lock_irqsave(&csi->qlock, flags);
+
+	/* Setup timings */
+	writel(CSI_WIN_CTRL_W_ACTIVE(csi->fmt.width * 2),
+	       csi->regs + CSI_WIN_CTRL_W_REG);
+	writel(CSI_WIN_CTRL_H_ACTIVE(csi->fmt.height),
+	       csi->regs + CSI_WIN_CTRL_H_REG);
+
+	hsync_pol = !!(bus->flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH);
+	pclk_pol = !!(bus->flags & V4L2_MBUS_DATA_ACTIVE_HIGH);
+	vsync_pol = !!(bus->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH);
+	writel(CSI_CFG_INPUT_FMT(csi_fmt->input) |
+	       CSI_CFG_OUTPUT_FMT(csi_fmt->output) |
+	       CSI_CFG_VSYNC_POL(vsync_pol) |
+	       CSI_CFG_HSYNC_POL(hsync_pol) |
+	       CSI_CFG_PCLK_POL(pclk_pol),
+	       csi->regs + CSI_CFG_REG);
+
+	/* Setup buffer length */
+	writel(csi->fmt.plane_fmt[0].bytesperline,
+	       csi->regs + CSI_BUF_LEN_REG);
+
+	/* Prepare our buffers in hardware */
+	ret = sun4i_csi_buffer_fill_all(csi);
+	if (ret) {
+		spin_unlock_irqrestore(&csi->qlock, flags);
+		goto err_disable_pipeline;
+	}
+
+	/* Enable double buffering */
+	writel(CSI_BUF_CTRL_DBE, csi->regs + CSI_BUF_CTRL_REG);
+
+	/* Clear the pending interrupts */
+	writel(CSI_INT_FRM_DONE, csi->regs + 0x34);
+
+	/* Enable frame done interrupt */
+	writel(CSI_INT_FRM_DONE, csi->regs + CSI_INT_EN_REG);
+
+	sun4i_csi_capture_start(csi);
+
+	spin_unlock_irqrestore(&csi->qlock, flags);
+
+	ret = v4l2_subdev_call(csi->src_subdev, video, s_stream, 1);
+	if (ret < 0 && ret != -ENOIOCTLCMD)
+		goto err_disable_device;
+
+	return 0;
+
+err_disable_device:
+	sun4i_csi_capture_stop(csi);
+
+err_disable_pipeline:
+	media_pipeline_stop(&csi->vdev.entity);
+
+err_free_scratch_buffer:
+	dma_free_coherent(csi->dev, csi->scratch.size, csi->scratch.vaddr,
+			  csi->scratch.paddr);
+
+err_clear_dma_queue:
+	spin_lock_irqsave(&csi->qlock, flags);
+	return_all_buffers(csi, VB2_BUF_STATE_QUEUED);
+	spin_unlock_irqrestore(&csi->qlock, flags);
+
+	return ret;
+}
+
+static void sun4i_csi_stop_streaming(struct vb2_queue *vq)
+{
+	struct sun4i_csi *csi = vb2_get_drv_priv(vq);
+	unsigned long flags;
+
+	dev_dbg(csi->dev, "Stopping capture\n");
+
+	v4l2_subdev_call(csi->src_subdev, video, s_stream, 0);
+	sun4i_csi_capture_stop(csi);
+
+	/* Release all active buffers */
+	spin_lock_irqsave(&csi->qlock, flags);
+	return_all_buffers(csi, VB2_BUF_STATE_ERROR);
+	spin_unlock_irqrestore(&csi->qlock, flags);
+
+	media_pipeline_stop(&csi->vdev.entity);
+
+	dma_free_coherent(csi->dev, csi->scratch.size, csi->scratch.vaddr,
+			  csi->scratch.paddr);
+}
+
+static const struct vb2_ops sun4i_csi_qops = {
+	.queue_setup		= sun4i_csi_queue_setup,
+	.buf_prepare		= sun4i_csi_buffer_prepare,
+	.buf_queue		= sun4i_csi_buffer_queue,
+	.start_streaming	= sun4i_csi_start_streaming,
+	.stop_streaming		= sun4i_csi_stop_streaming,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+static irqreturn_t sun4i_csi_irq(int irq, void *data)
+{
+	struct sun4i_csi *csi = data;
+	u32 reg;
+
+	reg = readl(csi->regs + CSI_INT_STA_REG);
+
+	/* Acknowledge the interrupts */
+	writel(reg, csi->regs + CSI_INT_STA_REG);
+
+	if (!(reg & CSI_INT_FRM_DONE))
+		return IRQ_HANDLED;
+
+	spin_lock(&csi->qlock);
+	if (sun4i_csi_buffer_flip(csi, csi->sequence++)) {
+		dev_warn(csi->dev, "%s: Flip failed\n", __func__);
+		sun4i_csi_capture_stop(csi);
+	}
+	spin_unlock(&csi->qlock);
+
+	return IRQ_HANDLED;
+}
+
+int sun4i_csi_dma_register(struct sun4i_csi *csi, int irq)
+{
+	struct vb2_queue *q = &csi->queue;
+	int ret;
+	int i;
+
+	spin_lock_init(&csi->qlock);
+	mutex_init(&csi->lock);
+
+	INIT_LIST_HEAD(&csi->buf_list);
+	for (i = 0; i < CSI_MAX_BUFFER; i++)
+		csi->current_buf[i] = NULL;
+
+	q->min_buffers_needed = 3;
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	q->io_modes = VB2_MMAP;
+	q->lock = &csi->lock;
+	q->drv_priv = csi;
+	q->buf_struct_size = sizeof(struct sun4i_csi_buffer);
+	q->ops = &sun4i_csi_qops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->dev = csi->dev;
+
+	ret = vb2_queue_init(q);
+	if (ret < 0) {
+		dev_err(csi->dev, "failed to initialize VB2 queue\n");
+		goto err_free_mutex;
+	}
+
+	ret = v4l2_device_register(csi->dev, &csi->v4l);
+	if (ret) {
+		dev_err(csi->dev, "Couldn't register the v4l2 device\n");
+		goto err_free_queue;
+	}
+
+	ret = devm_request_irq(csi->dev, irq, sun4i_csi_irq, 0,
+			       dev_name(csi->dev), csi);
+	if (ret) {
+		dev_err(csi->dev, "Couldn't register our interrupt\n");
+		goto err_unregister_device;
+	}
+
+	return 0;
+
+err_unregister_device:
+	v4l2_device_unregister(&csi->v4l);
+
+err_free_queue:
+	vb2_queue_release(q);
+
+err_free_mutex:
+	mutex_destroy(&csi->lock);
+	return ret;
+}
+
+void sun4i_csi_dma_unregister(struct sun4i_csi *csi)
+{
+	v4l2_device_unregister(&csi->v4l);
+	vb2_queue_release(&csi->queue);
+	mutex_destroy(&csi->lock);
+}
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c
new file mode 100644
index 0000000..83a3a02
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 NextThing Co
+ * Copyright (C) 2016-2019 Bootlin
+ *
+ * Author: Maxime Ripard <maxime.ripard@bootlin.com>
+ */
+
+#include <linux/device.h>
+#include <linux/pm_runtime.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mc.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "sun4i_csi.h"
+
+#define CSI_DEFAULT_WIDTH	640
+#define CSI_DEFAULT_HEIGHT	480
+
+static const struct sun4i_csi_format sun4i_csi_formats[] = {
+	/* YUV422 inputs */
+	{
+		.mbus		= MEDIA_BUS_FMT_YUYV8_2X8,
+		.fourcc		= V4L2_PIX_FMT_YUV420M,
+		.input		= CSI_INPUT_YUV,
+		.output		= CSI_OUTPUT_YUV_420_PLANAR,
+		.num_planes	= 3,
+		.bpp		= { 8, 8, 8 },
+		.hsub		= 2,
+		.vsub		= 2,
+	},
+};
+
+const struct sun4i_csi_format *sun4i_csi_find_format(const u32 *fourcc,
+						     const u32 *mbus)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(sun4i_csi_formats); i++) {
+		if (fourcc && *fourcc != sun4i_csi_formats[i].fourcc)
+			continue;
+
+		if (mbus && *mbus != sun4i_csi_formats[i].mbus)
+			continue;
+
+		return &sun4i_csi_formats[i];
+	}
+
+	return NULL;
+}
+
+static int sun4i_csi_querycap(struct file *file, void *priv,
+			      struct v4l2_capability *cap)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+
+	strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+	strscpy(cap->card, "sun4i-csi", sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+		 dev_name(csi->dev));
+
+	return 0;
+}
+
+static int sun4i_csi_enum_input(struct file *file, void *priv,
+				struct v4l2_input *inp)
+{
+	if (inp->index != 0)
+		return -EINVAL;
+
+	inp->type = V4L2_INPUT_TYPE_CAMERA;
+	strscpy(inp->name, "Camera", sizeof(inp->name));
+
+	return 0;
+}
+
+static int sun4i_csi_g_input(struct file *file, void *fh,
+			     unsigned int *i)
+{
+	*i = 0;
+
+	return 0;
+}
+
+static int sun4i_csi_s_input(struct file *file, void *fh,
+			     unsigned int i)
+{
+	if (i != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void _sun4i_csi_try_fmt(struct sun4i_csi *csi,
+			       struct v4l2_pix_format_mplane *pix)
+{
+	const struct sun4i_csi_format *_fmt;
+	unsigned int height, width;
+	unsigned int i;
+
+	_fmt = sun4i_csi_find_format(&pix->pixelformat, NULL);
+	if (!_fmt)
+		_fmt = &sun4i_csi_formats[0];
+
+	pix->field = V4L2_FIELD_NONE;
+	pix->colorspace = V4L2_COLORSPACE_SRGB;
+	pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
+	pix->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
+	pix->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, pix->colorspace,
+							  pix->ycbcr_enc);
+
+	pix->num_planes = _fmt->num_planes;
+	pix->pixelformat = _fmt->fourcc;
+
+	memset(pix->reserved, 0, sizeof(pix->reserved));
+
+	/* Align the width and height on the subsampling */
+	width = ALIGN(pix->width, _fmt->hsub);
+	height = ALIGN(pix->height, _fmt->vsub);
+
+	/* Clamp the width and height to our capabilities */
+	pix->width = clamp(width, _fmt->hsub, CSI_MAX_WIDTH);
+	pix->height = clamp(height, _fmt->vsub, CSI_MAX_HEIGHT);
+
+	for (i = 0; i < _fmt->num_planes; i++) {
+		unsigned int hsub = i > 0 ? _fmt->hsub : 1;
+		unsigned int vsub = i > 0 ? _fmt->vsub : 1;
+		unsigned int bpl;
+
+		bpl = pix->width / hsub * _fmt->bpp[i] / 8;
+		pix->plane_fmt[i].bytesperline = bpl;
+		pix->plane_fmt[i].sizeimage = bpl * pix->height / vsub;
+		memset(pix->plane_fmt[i].reserved, 0,
+		       sizeof(pix->plane_fmt[i].reserved));
+	}
+}
+
+static int sun4i_csi_try_fmt_vid_cap(struct file *file, void *priv,
+				     struct v4l2_format *f)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+
+	_sun4i_csi_try_fmt(csi, &f->fmt.pix_mp);
+
+	return 0;
+}
+
+static int sun4i_csi_s_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+
+	_sun4i_csi_try_fmt(csi, &f->fmt.pix_mp);
+	csi->fmt = f->fmt.pix_mp;
+
+	return 0;
+}
+
+static int sun4i_csi_g_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+
+	f->fmt.pix_mp = csi->fmt;
+
+	return 0;
+}
+
+static int sun4i_csi_enum_fmt_vid_cap(struct file *file, void *priv,
+				      struct v4l2_fmtdesc *f)
+{
+	if (f->index >= ARRAY_SIZE(sun4i_csi_formats))
+		return -EINVAL;
+
+	f->pixelformat = sun4i_csi_formats[f->index].fourcc;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops sun4i_csi_ioctl_ops = {
+	.vidioc_querycap		= sun4i_csi_querycap,
+
+	.vidioc_enum_fmt_vid_cap	= sun4i_csi_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap_mplane	= sun4i_csi_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap_mplane	= sun4i_csi_s_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap_mplane	= sun4i_csi_try_fmt_vid_cap,
+
+	.vidioc_enum_input		= sun4i_csi_enum_input,
+	.vidioc_g_input			= sun4i_csi_g_input,
+	.vidioc_s_input			= sun4i_csi_s_input,
+
+	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
+	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
+	.vidioc_querybuf		= vb2_ioctl_querybuf,
+	.vidioc_qbuf			= vb2_ioctl_qbuf,
+	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
+	.vidioc_expbuf			= vb2_ioctl_expbuf,
+	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
+	.vidioc_streamon		= vb2_ioctl_streamon,
+	.vidioc_streamoff		= vb2_ioctl_streamoff,
+};
+
+static int sun4i_csi_open(struct file *file)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+	int ret;
+
+	ret = mutex_lock_interruptible(&csi->lock);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_get_sync(csi->dev);
+	if (ret < 0)
+		goto err_pm_put;
+
+	ret = v4l2_pipeline_pm_use(&csi->vdev.entity, 1);
+	if (ret)
+		goto err_pm_put;
+
+	ret = v4l2_fh_open(file);
+	if (ret)
+		goto err_pipeline_pm_put;
+
+	mutex_unlock(&csi->lock);
+
+	return 0;
+
+err_pipeline_pm_put:
+	v4l2_pipeline_pm_use(&csi->vdev.entity, 0);
+
+err_pm_put:
+	pm_runtime_put(csi->dev);
+	mutex_unlock(&csi->lock);
+
+	return ret;
+}
+
+static int sun4i_csi_release(struct file *file)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+
+	mutex_lock(&csi->lock);
+
+	v4l2_fh_release(file);
+	v4l2_pipeline_pm_use(&csi->vdev.entity, 0);
+	pm_runtime_put(csi->dev);
+
+	mutex_unlock(&csi->lock);
+
+	return 0;
+}
+
+static const struct v4l2_file_operations sun4i_csi_fops = {
+	.owner		= THIS_MODULE,
+	.open		= sun4i_csi_open,
+	.release	= sun4i_csi_release,
+	.unlocked_ioctl	= video_ioctl2,
+	.read		= vb2_fop_read,
+	.write		= vb2_fop_write,
+	.poll		= vb2_fop_poll,
+	.mmap		= vb2_fop_mmap,
+};
+
+static const struct v4l2_mbus_framefmt sun4i_csi_pad_fmt_default = {
+	.width = CSI_DEFAULT_WIDTH,
+	.height = CSI_DEFAULT_HEIGHT,
+	.code = MEDIA_BUS_FMT_YUYV8_2X8,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_RAW,
+	.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
+	.quantization = V4L2_QUANTIZATION_DEFAULT,
+	.xfer_func = V4L2_XFER_FUNC_DEFAULT,
+};
+
+static int sun4i_csi_subdev_init_cfg(struct v4l2_subdev *subdev,
+				     struct v4l2_subdev_pad_config *cfg)
+{
+	struct v4l2_mbus_framefmt *fmt;
+
+	fmt = v4l2_subdev_get_try_format(subdev, cfg, CSI_SUBDEV_SINK);
+	*fmt = sun4i_csi_pad_fmt_default;
+
+	return 0;
+}
+
+static int sun4i_csi_subdev_get_fmt(struct v4l2_subdev *subdev,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_format *fmt)
+{
+	struct sun4i_csi *csi = container_of(subdev, struct sun4i_csi, subdev);
+	struct v4l2_mbus_framefmt *subdev_fmt;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+		subdev_fmt = v4l2_subdev_get_try_format(subdev, cfg, fmt->pad);
+	else
+		subdev_fmt = &csi->subdev_fmt;
+
+	fmt->format = *subdev_fmt;
+
+	return 0;
+}
+
+static int sun4i_csi_subdev_set_fmt(struct v4l2_subdev *subdev,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_format *fmt)
+{
+	struct sun4i_csi *csi = container_of(subdev, struct sun4i_csi, subdev);
+	struct v4l2_mbus_framefmt *subdev_fmt;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+		subdev_fmt = v4l2_subdev_get_try_format(subdev, cfg, fmt->pad);
+	else
+		subdev_fmt = &csi->subdev_fmt;
+
+	/* We can only set the format on the sink pad */
+	if (fmt->pad == CSI_SUBDEV_SINK) {
+		/* It's the sink, only allow changing the frame size */
+		subdev_fmt->width = fmt->format.width;
+		subdev_fmt->height = fmt->format.height;
+		subdev_fmt->code = fmt->format.code;
+	}
+
+	fmt->format = *subdev_fmt;
+
+	return 0;
+}
+
+static int
+sun4i_csi_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_mbus_code_enum *mbus)
+{
+	if (mbus->index >= ARRAY_SIZE(sun4i_csi_formats))
+		return -EINVAL;
+
+	mbus->code = sun4i_csi_formats[mbus->index].mbus;
+
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops sun4i_csi_subdev_pad_ops = {
+	.link_validate	= v4l2_subdev_link_validate_default,
+	.init_cfg	= sun4i_csi_subdev_init_cfg,
+	.get_fmt	= sun4i_csi_subdev_get_fmt,
+	.set_fmt	= sun4i_csi_subdev_set_fmt,
+	.enum_mbus_code	= sun4i_csi_subdev_enum_mbus_code,
+};
+
+const struct v4l2_subdev_ops sun4i_csi_subdev_ops = {
+	.pad = &sun4i_csi_subdev_pad_ops,
+};
+
+int sun4i_csi_v4l2_register(struct sun4i_csi *csi)
+{
+	struct video_device *vdev = &csi->vdev;
+	int ret;
+
+	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING;
+	vdev->v4l2_dev = &csi->v4l;
+	vdev->queue = &csi->queue;
+	strscpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
+	vdev->release = video_device_release_empty;
+	vdev->lock = &csi->lock;
+
+	/* Set a default format */
+	csi->fmt.pixelformat = sun4i_csi_formats[0].fourcc,
+	csi->fmt.width = CSI_DEFAULT_WIDTH;
+	csi->fmt.height = CSI_DEFAULT_HEIGHT;
+	_sun4i_csi_try_fmt(csi, &csi->fmt);
+	csi->subdev_fmt = sun4i_csi_pad_fmt_default;
+
+	vdev->fops = &sun4i_csi_fops;
+	vdev->ioctl_ops = &sun4i_csi_ioctl_ops;
+	video_set_drvdata(vdev, csi);
+
+	ret = video_register_device(&csi->vdev, VFL_TYPE_GRABBER, -1);
+	if (ret)
+		return ret;
+
+	dev_info(csi->dev, "Device registered as %s\n",
+		 video_device_node_name(vdev));
+
+	return 0;
+}
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
index 6e0e894..055eb0b 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
@@ -866,11 +866,8 @@
 	}
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "No csi IRQ specified\n");
-		ret = -ENXIO;
-		return ret;
-	}
+	if (irq < 0)
+		return -ENXIO;
 
 	ret = devm_request_irq(&pdev->dev, irq, sun6i_csi_isr, 0, MODULE_NAME,
 			       sdev);
diff --git a/drivers/media/platform/tegra-cec/tegra_cec.c b/drivers/media/platform/tegra-cec/tegra_cec.c
index 6498b2d..a632602 100644
--- a/drivers/media/platform/tegra-cec/tegra_cec.c
+++ b/drivers/media/platform/tegra-cec/tegra_cec.c
@@ -380,38 +380,39 @@
 	if (ret) {
 		dev_err(&pdev->dev,
 			"Unable to request interrupt for device\n");
-		goto clk_error;
-	}
-
-	cec->notifier = cec_notifier_get(hdmi_dev);
-	if (!cec->notifier) {
-		ret = -ENOMEM;
-		goto clk_error;
+		goto err_clk;
 	}
 
 	cec->adap = cec_allocate_adapter(&tegra_cec_ops, cec, TEGRA_CEC_NAME,
-			CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL,
+			CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL |
+			CEC_CAP_CONNECTOR_INFO,
 			CEC_MAX_LOG_ADDRS);
 	if (IS_ERR(cec->adap)) {
 		ret = -ENOMEM;
 		dev_err(&pdev->dev, "Couldn't create cec adapter\n");
-		goto cec_error;
+		goto err_clk;
 	}
+
+	cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
+						       cec->adap);
+	if (!cec->notifier) {
+		ret = -ENOMEM;
+		goto err_adapter;
+	}
+
 	ret = cec_register_adapter(cec->adap, &pdev->dev);
 	if (ret) {
 		dev_err(&pdev->dev, "Couldn't register device\n");
-		goto cec_error;
+		goto err_notifier;
 	}
 
-	cec_register_cec_notifier(cec->adap, cec->notifier);
-
 	return 0;
 
-cec_error:
-	if (cec->notifier)
-		cec_notifier_put(cec->notifier);
+err_notifier:
+	cec_notifier_cec_adap_unregister(cec->notifier);
+err_adapter:
 	cec_delete_adapter(cec->adap);
-clk_error:
+err_clk:
 	clk_disable_unprepare(cec->clk);
 	return ret;
 }
@@ -422,8 +423,8 @@
 
 	clk_disable_unprepare(cec->clk);
 
+	cec_notifier_cec_adap_unregister(cec->notifier);
 	cec_unregister_adapter(cec->adap);
-	cec_notifier_put(cec->notifier);
 
 	return 0;
 }
diff --git a/drivers/media/platform/tegra-cec/tegra_cec.h b/drivers/media/platform/tegra-cec/tegra_cec.h
index 32d7d69..8c370be 100644
--- a/drivers/media/platform/tegra-cec/tegra_cec.h
+++ b/drivers/media/platform/tegra-cec/tegra_cec.h
@@ -34,24 +34,24 @@
 #define TEGRA_CEC_HWCTRL_RX_LADDR_MASK				0x7fff
 #define TEGRA_CEC_HWCTRL_RX_LADDR(x)	\
 	((x) & TEGRA_CEC_HWCTRL_RX_LADDR_MASK)
-#define TEGRA_CEC_HWCTRL_RX_SNOOP				(1 << 15)
-#define TEGRA_CEC_HWCTRL_RX_NAK_MODE				(1 << 16)
-#define TEGRA_CEC_HWCTRL_TX_NAK_MODE				(1 << 24)
-#define TEGRA_CEC_HWCTRL_FAST_SIM_MODE				(1 << 30)
-#define TEGRA_CEC_HWCTRL_TX_RX_MODE				(1 << 31)
+#define TEGRA_CEC_HWCTRL_RX_SNOOP				BIT(15)
+#define TEGRA_CEC_HWCTRL_RX_NAK_MODE				BIT(16)
+#define TEGRA_CEC_HWCTRL_TX_NAK_MODE				BIT(24)
+#define TEGRA_CEC_HWCTRL_FAST_SIM_MODE				BIT(30)
+#define TEGRA_CEC_HWCTRL_TX_RX_MODE				BIT(31)
 
-#define TEGRA_CEC_INPUT_FILTER_MODE				(1 << 31)
+#define TEGRA_CEC_INPUT_FILTER_MODE				BIT(31)
 #define TEGRA_CEC_INPUT_FILTER_FIFO_LENGTH_SHIFT		0
 
 #define TEGRA_CEC_TX_REG_DATA_SHIFT				0
-#define TEGRA_CEC_TX_REG_EOM					(1 << 8)
-#define TEGRA_CEC_TX_REG_BCAST					(1 << 12)
-#define TEGRA_CEC_TX_REG_START_BIT				(1 << 16)
-#define TEGRA_CEC_TX_REG_RETRY					(1 << 17)
+#define TEGRA_CEC_TX_REG_EOM					BIT(8)
+#define TEGRA_CEC_TX_REG_BCAST					BIT(12)
+#define TEGRA_CEC_TX_REG_START_BIT				BIT(16)
+#define TEGRA_CEC_TX_REG_RETRY					BIT(17)
 
 #define TEGRA_CEC_RX_REGISTER_SHIFT				0
-#define TEGRA_CEC_RX_REGISTER_EOM				(1 << 8)
-#define TEGRA_CEC_RX_REGISTER_ACK				(1 << 9)
+#define TEGRA_CEC_RX_REGISTER_EOM				BIT(8)
+#define TEGRA_CEC_RX_REGISTER_ACK				BIT(9)
 
 #define TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT		0
 #define TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT		8
@@ -79,38 +79,38 @@
 #define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT		4
 #define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT	8
 
-#define TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY			(1 << 0)
-#define TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN			(1 << 1)
-#define TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD		(1 << 2)
-#define TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED		(1 << 3)
-#define TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED		(1 << 4)
-#define TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED			(1 << 5)
-#define TEGRA_CEC_INT_STAT_RX_REGISTER_FULL			(1 << 8)
-#define TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN			(1 << 9)
-#define TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED		(1 << 10)
-#define TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED		(1 << 11)
-#define TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED		(1 << 12)
-#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_H2L	(1 << 13)
-#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_L2H	(1 << 14)
+#define TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY			BIT(0)
+#define TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN			BIT(1)
+#define TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD		BIT(2)
+#define TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED		BIT(3)
+#define TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED		BIT(4)
+#define TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED			BIT(5)
+#define TEGRA_CEC_INT_STAT_RX_REGISTER_FULL			BIT(8)
+#define TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN			BIT(9)
+#define TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED		BIT(10)
+#define TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED		BIT(11)
+#define TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED		BIT(12)
+#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_H2L	BIT(13)
+#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_L2H	BIT(14)
 
-#define TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY			(1 << 0)
-#define TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN			(1 << 1)
-#define TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD		(1 << 2)
-#define TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED		(1 << 3)
-#define TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED		(1 << 4)
-#define TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED			(1 << 5)
-#define TEGRA_CEC_INT_MASK_RX_REGISTER_FULL			(1 << 8)
-#define TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN			(1 << 9)
-#define TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED		(1 << 10)
-#define TEGRA_CEC_INT_MASK_RX_BUS_ANOMALY_DETECTED		(1 << 11)
-#define TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED		(1 << 12)
-#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_H2L	(1 << 13)
-#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_L2H	(1 << 14)
+#define TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY			BIT(0)
+#define TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN			BIT(1)
+#define TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD		BIT(2)
+#define TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED		BIT(3)
+#define TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED		BIT(4)
+#define TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED			BIT(5)
+#define TEGRA_CEC_INT_MASK_RX_REGISTER_FULL			BIT(8)
+#define TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN			BIT(9)
+#define TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED		BIT(10)
+#define TEGRA_CEC_INT_MASK_RX_BUS_ANOMALY_DETECTED		BIT(11)
+#define TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED		BIT(12)
+#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_H2L	BIT(13)
+#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_L2H	BIT(14)
 
 #define TEGRA_CEC_HW_DEBUG_TX_DURATION_COUNT_SHIFT		0
 #define TEGRA_CEC_HW_DEBUG_TX_TXBIT_COUNT_SHIFT			17
 #define TEGRA_CEC_HW_DEBUG_TX_STATE_SHIFT			21
-#define TEGRA_CEC_HW_DEBUG_TX_FORCELOOUT			(1 << 25)
-#define TEGRA_CEC_HW_DEBUG_TX_TXDATABIT_SAMPLE_TIMER		(1 << 26)
+#define TEGRA_CEC_HW_DEBUG_TX_FORCELOOUT			BIT(25)
+#define TEGRA_CEC_HW_DEBUG_TX_TXDATABIT_SAMPLE_TIMER		BIT(26)
 
 #endif /* TEGRA_CEC_H */
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
index 9e86d761..223161f 100644
--- a/drivers/media/platform/ti-vpe/cal.c
+++ b/drivers/media/platform/ti-vpe/cal.c
@@ -913,9 +913,6 @@
 
 	snprintf(cap->bus_info, sizeof(cap->bus_info),
 		 "platform:%s", ctx->v4l2_dev.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;
 }
 
@@ -1419,6 +1416,8 @@
 	.ioctl_ops	= &cal_ioctl_ops,
 	.minor		= -1,
 	.release	= video_device_release_empty,
+	.device_caps	= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+			  V4L2_CAP_READWRITE,
 };
 
 /* -----------------------------------------------------------------
@@ -1613,6 +1612,7 @@
 			}
 			prev = port;
 		} while (!of_node_name_eq(port, "port"));
+		of_node_put(ports);
 	}
 
 	return port;
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c
index fd37d79..53d27cd 100644
--- a/drivers/media/platform/ti-vpe/vpdma.c
+++ b/drivers/media/platform/ti-vpe/vpdma.c
@@ -445,23 +445,25 @@
 
 	ret = vpdma_map_desc_buf(vpdma, &abort_list.buf);
 	if (ret)
-		return ret;
+		goto free_desc;
 	ret = vpdma_submit_descs(vpdma, &abort_list, list_num);
 	if (ret)
-		return ret;
+		goto unmap_desc;
 
 	while (vpdma_list_busy(vpdma, list_num) && --timeout)
 		;
 
 	if (timeout == 0) {
 		dev_err(&vpdma->pdev->dev, "Timed out cleaning up VPDMA list\n");
-		return -EBUSY;
+		ret = -EBUSY;
 	}
 
+unmap_desc:
 	vpdma_unmap_desc_buf(vpdma, &abort_list.buf);
+free_desc:
 	vpdma_free_desc_buf(&abort_list.buf);
 
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL(vpdma_list_cleanup);
 
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index dda0449..60b575b 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -224,7 +224,6 @@
 
 /* driver info for each of the supported video formats */
 struct vpe_fmt {
-	char	*name;			/* human-readable name */
 	u32	fourcc;			/* standard format identifier */
 	u8	types;			/* CAPTURE and/or OUTPUT */
 	u8	coplanar;		/* set for unpacked Luma and Chroma */
@@ -234,7 +233,6 @@
 
 static struct vpe_fmt vpe_formats[] = {
 	{
-		.name		= "NV16 YUV 422 co-planar",
 		.fourcc		= V4L2_PIX_FMT_NV16,
 		.types		= VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 		.coplanar	= 1,
@@ -243,7 +241,6 @@
 				  },
 	},
 	{
-		.name		= "NV12 YUV 420 co-planar",
 		.fourcc		= V4L2_PIX_FMT_NV12,
 		.types		= VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 		.coplanar	= 1,
@@ -252,7 +249,6 @@
 				  },
 	},
 	{
-		.name		= "YUYV 422 packed",
 		.fourcc		= V4L2_PIX_FMT_YUYV,
 		.types		= VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 		.coplanar	= 0,
@@ -260,7 +256,6 @@
 				  },
 	},
 	{
-		.name		= "UYVY 422 packed",
 		.fourcc		= V4L2_PIX_FMT_UYVY,
 		.types		= VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT,
 		.coplanar	= 0,
@@ -268,7 +263,6 @@
 				  },
 	},
 	{
-		.name		= "RGB888 packed",
 		.fourcc		= V4L2_PIX_FMT_RGB24,
 		.types		= VPE_FMT_TYPE_CAPTURE,
 		.coplanar	= 0,
@@ -276,7 +270,6 @@
 				  },
 	},
 	{
-		.name		= "ARGB32",
 		.fourcc		= V4L2_PIX_FMT_RGB32,
 		.types		= VPE_FMT_TYPE_CAPTURE,
 		.coplanar	= 0,
@@ -284,7 +277,6 @@
 				  },
 	},
 	{
-		.name		= "BGR888 packed",
 		.fourcc		= V4L2_PIX_FMT_BGR24,
 		.types		= VPE_FMT_TYPE_CAPTURE,
 		.coplanar	= 0,
@@ -292,7 +284,6 @@
 				  },
 	},
 	{
-		.name		= "ABGR32",
 		.fourcc		= V4L2_PIX_FMT_BGR32,
 		.types		= VPE_FMT_TYPE_CAPTURE,
 		.coplanar	= 0,
@@ -300,7 +291,6 @@
 				  },
 	},
 	{
-		.name		= "RGB565",
 		.fourcc		= V4L2_PIX_FMT_RGB565,
 		.types		= VPE_FMT_TYPE_CAPTURE,
 		.coplanar	= 0,
@@ -308,7 +298,6 @@
 				  },
 	},
 	{
-		.name		= "RGB5551",
 		.fourcc		= V4L2_PIX_FMT_RGB555,
 		.types		= VPE_FMT_TYPE_CAPTURE,
 		.coplanar	= 0,
@@ -1514,7 +1503,6 @@
 	if (!fmt)
 		return -EINVAL;
 
-	strscpy(f->description, fmt->name, sizeof(f->description));
 	f->pixelformat = fmt->fourcc;
 	return 0;
 }
diff --git a/drivers/media/platform/ti-vpe/vpe_regs.h b/drivers/media/platform/ti-vpe/vpe_regs.h
index 9969bea..1a1ad5a 100644
--- a/drivers/media/platform/ti-vpe/vpe_regs.h
+++ b/drivers/media/platform/ti-vpe/vpe_regs.h
@@ -48,24 +48,24 @@
 #define VPE_INT0_ENABLE0_SET		0x0030
 #define VPE_INT0_ENABLE0		VPE_INT0_ENABLE0_SET
 #define VPE_INT0_ENABLE0_CLR		0x0038
-#define VPE_INT0_LIST0_COMPLETE		(1 << 0)
-#define VPE_INT0_LIST0_NOTIFY		(1 << 1)
-#define VPE_INT0_LIST1_COMPLETE		(1 << 2)
-#define VPE_INT0_LIST1_NOTIFY		(1 << 3)
-#define VPE_INT0_LIST2_COMPLETE		(1 << 4)
-#define VPE_INT0_LIST2_NOTIFY		(1 << 5)
-#define VPE_INT0_LIST3_COMPLETE		(1 << 6)
-#define VPE_INT0_LIST3_NOTIFY		(1 << 7)
-#define VPE_INT0_LIST4_COMPLETE		(1 << 8)
-#define VPE_INT0_LIST4_NOTIFY		(1 << 9)
-#define VPE_INT0_LIST5_COMPLETE		(1 << 10)
-#define VPE_INT0_LIST5_NOTIFY		(1 << 11)
-#define VPE_INT0_LIST6_COMPLETE		(1 << 12)
-#define VPE_INT0_LIST6_NOTIFY		(1 << 13)
-#define VPE_INT0_LIST7_COMPLETE		(1 << 14)
-#define VPE_INT0_LIST7_NOTIFY		(1 << 15)
-#define VPE_INT0_DESCRIPTOR		(1 << 16)
-#define VPE_DEI_FMD_INT			(1 << 18)
+#define VPE_INT0_LIST0_COMPLETE		BIT(0)
+#define VPE_INT0_LIST0_NOTIFY		BIT(1)
+#define VPE_INT0_LIST1_COMPLETE		BIT(2)
+#define VPE_INT0_LIST1_NOTIFY		BIT(3)
+#define VPE_INT0_LIST2_COMPLETE		BIT(4)
+#define VPE_INT0_LIST2_NOTIFY		BIT(5)
+#define VPE_INT0_LIST3_COMPLETE		BIT(6)
+#define VPE_INT0_LIST3_NOTIFY		BIT(7)
+#define VPE_INT0_LIST4_COMPLETE		BIT(8)
+#define VPE_INT0_LIST4_NOTIFY		BIT(9)
+#define VPE_INT0_LIST5_COMPLETE		BIT(10)
+#define VPE_INT0_LIST5_NOTIFY		BIT(11)
+#define VPE_INT0_LIST6_COMPLETE		BIT(12)
+#define VPE_INT0_LIST6_NOTIFY		BIT(13)
+#define VPE_INT0_LIST7_COMPLETE		BIT(14)
+#define VPE_INT0_LIST7_NOTIFY		BIT(15)
+#define VPE_INT0_DESCRIPTOR		BIT(16)
+#define VPE_DEI_FMD_INT			BIT(18)
 
 #define VPE_INT0_STATUS1_RAW_SET	0x0024
 #define VPE_INT0_STATUS1_RAW		VPE_INT0_STATUS1_RAW_SET
@@ -74,21 +74,21 @@
 #define VPE_INT0_ENABLE1_SET		0x0034
 #define VPE_INT0_ENABLE1		VPE_INT0_ENABLE1_SET
 #define VPE_INT0_ENABLE1_CLR		0x003c
-#define VPE_INT0_CHANNEL_GROUP0		(1 << 0)
-#define VPE_INT0_CHANNEL_GROUP1		(1 << 1)
-#define VPE_INT0_CHANNEL_GROUP2		(1 << 2)
-#define VPE_INT0_CHANNEL_GROUP3		(1 << 3)
-#define VPE_INT0_CHANNEL_GROUP4		(1 << 4)
-#define VPE_INT0_CHANNEL_GROUP5		(1 << 5)
-#define VPE_INT0_CLIENT			(1 << 7)
-#define VPE_DEI_ERROR_INT		(1 << 16)
-#define VPE_DS1_UV_ERROR_INT		(1 << 22)
+#define VPE_INT0_CHANNEL_GROUP0		BIT(0)
+#define VPE_INT0_CHANNEL_GROUP1		BIT(1)
+#define VPE_INT0_CHANNEL_GROUP2		BIT(2)
+#define VPE_INT0_CHANNEL_GROUP3		BIT(3)
+#define VPE_INT0_CHANNEL_GROUP4		BIT(4)
+#define VPE_INT0_CHANNEL_GROUP5		BIT(5)
+#define VPE_INT0_CLIENT			BIT(7)
+#define VPE_DEI_ERROR_INT		BIT(16)
+#define VPE_DS1_UV_ERROR_INT		BIT(22)
 
 #define VPE_INTC_EOI			0x00a0
 
 #define VPE_CLK_ENABLE			0x0100
-#define VPE_VPEDMA_CLK_ENABLE		(1 << 0)
-#define VPE_DATA_PATH_CLK_ENABLE	(1 << 1)
+#define VPE_VPEDMA_CLK_ENABLE		BIT(0)
+#define VPE_DATA_PATH_CLK_ENABLE	BIT(1)
 
 #define VPE_CLK_RESET			0x0104
 #define VPE_VPDMA_CLK_RESET_MASK	0x1
@@ -101,11 +101,11 @@
 #define VPE_CLK_FORMAT_SELECT		0x010c
 #define VPE_CSC_SRC_SELECT_MASK		0x03
 #define VPE_CSC_SRC_SELECT_SHIFT	0
-#define VPE_RGB_OUT_SELECT		(1 << 8)
+#define VPE_RGB_OUT_SELECT		BIT(8)
 #define VPE_DS_SRC_SELECT_MASK		0x07
 #define VPE_DS_SRC_SELECT_SHIFT		9
-#define VPE_DS_BYPASS			(1 << 16)
-#define VPE_COLOR_SEPARATE_422		(1 << 18)
+#define VPE_DS_BYPASS			BIT(16)
+#define VPE_COLOR_SEPARATE_422		BIT(18)
 
 #define VPE_DS_SRC_DEI_SCALER		(5 << VPE_DS_SRC_SELECT_SHIFT)
 #define VPE_CSC_SRC_DEI_SCALER		(3 << VPE_CSC_SRC_SELECT_SHIFT)
@@ -115,8 +115,8 @@
 #define VPE_RANGE_RANGE_MAP_Y_SHIFT	0
 #define VPE_RANGE_RANGE_MAP_UV_MASK	0x07
 #define VPE_RANGE_RANGE_MAP_UV_SHIFT	3
-#define VPE_RANGE_MAP_ON		(1 << 6)
-#define VPE_RANGE_REDUCTION_ON		(1 << 28)
+#define VPE_RANGE_MAP_ON		BIT(6)
+#define VPE_RANGE_REDUCTION_ON		BIT(28)
 
 /* VPE chrominance upsampler regs */
 #define VPE_US1_R0			0x0304
@@ -195,13 +195,13 @@
 #define VPE_DEI_WIDTH_SHIFT		0
 #define VPE_DEI_HEIGHT_MASK		0x07ff
 #define VPE_DEI_HEIGHT_SHIFT		16
-#define VPE_DEI_INTERLACE_BYPASS	(1 << 29)
-#define VPE_DEI_FIELD_FLUSH		(1 << 30)
-#define VPE_DEI_PROGRESSIVE		(1 << 31)
+#define VPE_DEI_INTERLACE_BYPASS	BIT(29)
+#define VPE_DEI_FIELD_FLUSH		BIT(30)
+#define VPE_DEI_PROGRESSIVE		BIT(31)
 
 #define VPE_MDT_BYPASS			0x0604
-#define VPE_MDT_TEMPMAX_BYPASS		(1 << 0)
-#define VPE_MDT_SPATMAX_BYPASS		(1 << 1)
+#define VPE_MDT_TEMPMAX_BYPASS		BIT(0)
+#define VPE_MDT_SPATMAX_BYPASS		BIT(1)
 
 #define VPE_MDT_SF_THRESHOLD		0x0608
 #define VPE_MDT_SF_SC_THR1_MASK		0xff
@@ -214,8 +214,8 @@
 #define VPE_EDI_CONFIG			0x060c
 #define VPE_EDI_INP_MODE_MASK		0x03
 #define VPE_EDI_INP_MODE_SHIFT		0
-#define VPE_EDI_ENABLE_3D		(1 << 2)
-#define VPE_EDI_ENABLE_CHROMA_3D	(1 << 3)
+#define VPE_EDI_ENABLE_3D		BIT(2)
+#define VPE_EDI_ENABLE_CHROMA_3D	BIT(3)
 #define VPE_EDI_CHROMA3D_COR_THR_MASK	0xff
 #define VPE_EDI_CHROMA3D_COR_THR_SHIFT	8
 #define VPE_EDI_DIR_COR_LOWER_THR_MASK	0xff
@@ -268,7 +268,7 @@
 #define VPE_FMD_WINDOW_MINX_SHIFT	0
 #define VPE_FMD_WINDOW_MAXX_MASK	0x07ff
 #define VPE_FMD_WINDOW_MAXX_SHIFT	16
-#define VPE_FMD_WINDOW_ENABLE		(1 << 31)
+#define VPE_FMD_WINDOW_ENABLE		BIT(31)
 
 #define VPE_DEI_FMD_WINDOW_R1		0x0624
 #define VPE_FMD_WINDOW_MINY_MASK	0x07ff
@@ -277,10 +277,10 @@
 #define VPE_FMD_WINDOW_MAXY_SHIFT	16
 
 #define VPE_DEI_FMD_CONTROL_R0		0x0628
-#define VPE_FMD_ENABLE			(1 << 0)
-#define VPE_FMD_LOCK			(1 << 1)
-#define VPE_FMD_JAM_DIR			(1 << 2)
-#define VPE_FMD_BED_ENABLE		(1 << 3)
+#define VPE_FMD_ENABLE			BIT(0)
+#define VPE_FMD_LOCK			BIT(1)
+#define VPE_FMD_JAM_DIR			BIT(2)
+#define VPE_FMD_BED_ENABLE		BIT(3)
 #define VPE_FMD_CAF_FIELD_THR_MASK	0xff
 #define VPE_FMD_CAF_FIELD_THR_SHIFT	16
 #define VPE_FMD_CAF_LINE_THR_MASK	0xff
@@ -293,7 +293,7 @@
 #define VPE_DEI_FMD_STATUS_R0		0x0630
 #define VPE_FMD_CAF_MASK		0x000fffff
 #define VPE_FMD_CAF_SHIFT		0
-#define VPE_FMD_RESET			(1 << 24)
+#define VPE_FMD_RESET			BIT(24)
 
 #define VPE_DEI_FMD_STATUS_R1		0x0634
 #define VPE_FMD_FIELD_DIFF_MASK		0x0fffffff
diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c
index 038de7a..78841b9 100644
--- a/drivers/media/platform/via-camera.c
+++ b/drivers/media/platform/via-camera.c
@@ -18,9 +18,10 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
 #include <media/v4l2-image-sizes.h>
 #include <media/i2c/ov7670.h>
-#include <media/videobuf-dma-sg.h>
+#include <media/videobuf2-dma-sg.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/pm_qos.h>
@@ -84,16 +85,11 @@
 	 * live in frame buffer memory, so we don't call them "DMA".
 	 */
 	unsigned int cb_offsets[3];	/* offsets into fb mem */
-	u8 __iomem *cb_addrs[3];		/* Kernel-space addresses */
+	u8 __iomem *cb_addrs[3];	/* Kernel-space addresses */
 	int n_cap_bufs;			/* How many are we using? */
-	int next_buf;
-	struct videobuf_queue vb_queue;
-	struct list_head buffer_queue;	/* prot. by reg_lock */
-	/*
-	 * User tracking.
-	 */
-	int users;
-	struct file *owner;
+	struct vb2_queue vq;
+	struct list_head buffer_queue;
+	u32 sequence;
 	/*
 	 * Video format information.  sensor_format is kept in a form
 	 * that we can use to pass to the sensor.  We always run the
@@ -106,6 +102,13 @@
 	u32 mbus_code;
 };
 
+/* buffer for one video frame */
+struct via_buffer {
+	/* common v4l buffer stuff -- must be first */
+	struct vb2_v4l2_buffer		vbuf;
+	struct list_head		queue;
+};
+
 /*
  * Yes, this is a hack, but there's only going to be one of these
  * on any system we know of.
@@ -142,13 +145,11 @@
  * now this information must be managed at this level too.
  */
 static struct via_format {
-	__u8 *desc;
 	__u32 pixelformat;
 	int bpp;   /* Bytes per pixel */
 	u32 mbus_code;
 } via_formats[] = {
 	{
-		.desc		= "YUYV 4:2:2",
 		.pixelformat	= V4L2_PIX_FMT_YUYV,
 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
 		.bpp		= 2,
@@ -324,28 +325,15 @@
 }
 
 /*
- * Find the next videobuf buffer which has somebody waiting on it.
+ * Find the next buffer which has somebody waiting on it.
  */
-static struct videobuf_buffer *viacam_next_buffer(struct via_camera *cam)
+static struct via_buffer *viacam_next_buffer(struct via_camera *cam)
 {
-	unsigned long flags;
-	struct videobuf_buffer *buf = NULL;
-
-	spin_lock_irqsave(&cam->viadev->reg_lock, flags);
 	if (cam->opstate != S_RUNNING)
-		goto out;
+		return NULL;
 	if (list_empty(&cam->buffer_queue))
-		goto out;
-	buf = list_entry(cam->buffer_queue.next, struct videobuf_buffer, queue);
-	if (!waitqueue_active(&buf->done)) {/* Nobody waiting */
-		buf = NULL;
-		goto out;
-	}
-	list_del(&buf->queue);
-	buf->state = VIDEOBUF_ACTIVE;
-out:
-	spin_unlock_irqrestore(&cam->viadev->reg_lock, flags);
-	return buf;
+		return NULL;
+	return list_entry(cam->buffer_queue.next, struct via_buffer, queue);
 }
 
 /*
@@ -353,11 +341,12 @@
  */
 static irqreturn_t viacam_irq(int irq, void *data)
 {
-	int bufn;
-	struct videobuf_buffer *vb;
 	struct via_camera *cam = data;
-	struct videobuf_dmabuf *vdma;
+	struct via_buffer *vb;
+	int bufn;
+	struct sg_table *sgt;
 
+	mutex_lock(&cam->lock);
 	/*
 	 * If there is no place to put the data frame, don't bother
 	 * with anything else.
@@ -375,12 +364,15 @@
 	/*
 	 * Copy over the data and let any waiters know.
 	 */
-	vdma = videobuf_to_dma(vb);
-	viafb_dma_copy_out_sg(cam->cb_offsets[bufn], vdma->sglist, vdma->sglen);
-	vb->state = VIDEOBUF_DONE;
-	vb->size = cam->user_format.sizeimage;
-	wake_up(&vb->done);
+	sgt = vb2_dma_sg_plane_desc(&vb->vbuf.vb2_buf, 0);
+	vb->vbuf.vb2_buf.timestamp = ktime_get_ns();
+	viafb_dma_copy_out_sg(cam->cb_offsets[bufn], sgt->sgl, sgt->nents);
+	vb->vbuf.sequence = cam->sequence++;
+	vb->vbuf.field = V4L2_FIELD_NONE;
+	list_del(&vb->queue);
+	vb2_buffer_done(&vb->vbuf.vb2_buf, VB2_BUF_STATE_DONE);
 done:
+	mutex_unlock(&cam->lock);
 	return IRQ_HANDLED;
 }
 
@@ -556,7 +548,6 @@
 static void viacam_start_engine(struct via_camera *cam)
 {
 	spin_lock_irq(&cam->viadev->reg_lock);
-	cam->next_buf = 0;
 	viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_ENABLE, VCR_CI_ENABLE);
 	viacam_int_enable(cam);
 	(void) viacam_read_reg(cam, VCR_CAPINTC); /* Force post */
@@ -577,81 +568,117 @@
 
 
 /* --------------------------------------------------------------------------*/
-/* Videobuf callback ops */
+/* vb2 callback ops */
 
-/*
- * buffer_setup.  The purpose of this one would appear to be to tell
- * videobuf how big a single image is.	It's also evidently up to us
- * to put some sort of limit on the maximum number of buffers allowed.
- */
-static int viacam_vb_buf_setup(struct videobuf_queue *q,
-		unsigned int *count, unsigned int *size)
+static struct via_buffer *vb2_to_via_buffer(struct vb2_buffer *vb)
 {
-	struct via_camera *cam = q->priv_data;
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 
-	*size = cam->user_format.sizeimage;
-	if (*count == 0 || *count > 6)	/* Arbitrary number */
-		*count = 6;
-	return 0;
+	return container_of(vbuf, struct via_buffer, vbuf);
 }
 
-/*
- * Prepare a buffer.
- */
-static int viacam_vb_buf_prepare(struct videobuf_queue *q,
-		struct videobuf_buffer *vb, enum v4l2_field field)
+static void viacam_vb2_queue(struct vb2_buffer *vb)
 {
-	struct via_camera *cam = q->priv_data;
+	struct via_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
+	struct via_buffer *via = vb2_to_via_buffer(vb);
 
-	vb->size = cam->user_format.sizeimage;
-	vb->width = cam->user_format.width; /* bytesperline???? */
-	vb->height = cam->user_format.height;
-	vb->field = field;
-	if (vb->state == VIDEOBUF_NEEDS_INIT) {
-		int ret = videobuf_iolock(q, vb, NULL);
-		if (ret)
-			return ret;
+	list_add_tail(&via->queue, &cam->buffer_queue);
+}
+
+static int viacam_vb2_prepare(struct vb2_buffer *vb)
+{
+	struct via_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
+
+	if (vb2_plane_size(vb, 0) < cam->user_format.sizeimage) {
+		cam_dbg(cam,
+			"Plane size too small (%lu < %u)\n",
+			vb2_plane_size(vb, 0),
+			cam->user_format.sizeimage);
+		return -EINVAL;
 	}
-	vb->state = VIDEOBUF_PREPARED;
+
+	vb2_set_plane_payload(vb, 0, cam->user_format.sizeimage);
+
 	return 0;
 }
 
-/*
- * We've got a buffer to put data into.
- *
- * FIXME: check for a running engine and valid buffers?
- */
-static void viacam_vb_buf_queue(struct videobuf_queue *q,
-		struct videobuf_buffer *vb)
+static int viacam_vb2_queue_setup(struct vb2_queue *vq,
+				  unsigned int *nbufs,
+				  unsigned int *num_planes, unsigned int sizes[],
+				  struct device *alloc_devs[])
 {
-	struct via_camera *cam = q->priv_data;
+	struct via_camera *cam = vb2_get_drv_priv(vq);
+	int size = cam->user_format.sizeimage;
 
+	if (*num_planes)
+		return sizes[0] < size ? -EINVAL : 0;
+
+	*num_planes = 1;
+	sizes[0] = size;
+	return 0;
+}
+
+static int viacam_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct via_camera *cam = vb2_get_drv_priv(vq);
+	struct via_buffer *buf, *tmp;
+	int ret = 0;
+
+	if (cam->opstate != S_IDLE) {
+		ret = -EBUSY;
+		goto out;
+	}
 	/*
-	 * Note that videobuf holds the lock when it calls
-	 * us, so we need not (indeed, cannot) take it here.
+	 * Configure things if need be.
 	 */
-	vb->state = VIDEOBUF_QUEUED;
-	list_add_tail(&vb->queue, &cam->buffer_queue);
+	if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) {
+		ret = viacam_configure_sensor(cam);
+		if (ret)
+			goto out;
+		ret = viacam_config_controller(cam);
+		if (ret)
+			goto out;
+	}
+	cam->sequence = 0;
+	/*
+	 * If the CPU goes into C3, the DMA transfer gets corrupted and
+	 * users start filing unsightly bug reports.  Put in a "latency"
+	 * requirement which will keep the CPU out of the deeper sleep
+	 * states.
+	 */
+	pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50);
+	viacam_start_engine(cam);
+	return 0;
+out:
+	list_for_each_entry_safe(buf, tmp, &cam->buffer_queue, queue) {
+		list_del(&buf->queue);
+		vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED);
+	}
+	return ret;
 }
 
-/*
- * Free a buffer.
- */
-static void viacam_vb_buf_release(struct videobuf_queue *q,
-		struct videobuf_buffer *vb)
+static void viacam_vb2_stop_streaming(struct vb2_queue *vq)
 {
-	struct via_camera *cam = q->priv_data;
+	struct via_camera *cam = vb2_get_drv_priv(vq);
+	struct via_buffer *buf, *tmp;
 
-	videobuf_dma_unmap(&cam->platdev->dev, videobuf_to_dma(vb));
-	videobuf_dma_free(videobuf_to_dma(vb));
-	vb->state = VIDEOBUF_NEEDS_INIT;
+	pm_qos_remove_request(&cam->qos_request);
+	viacam_stop_engine(cam);
+
+	list_for_each_entry_safe(buf, tmp, &cam->buffer_queue, queue) {
+		list_del(&buf->queue);
+		vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR);
+	}
 }
 
-static const struct videobuf_queue_ops viacam_vb_ops = {
-	.buf_setup	= viacam_vb_buf_setup,
-	.buf_prepare	= viacam_vb_buf_prepare,
-	.buf_queue	= viacam_vb_buf_queue,
-	.buf_release	= viacam_vb_buf_release,
+static const struct vb2_ops viacam_vb2_ops = {
+	.queue_setup		= viacam_vb2_queue_setup,
+	.buf_queue		= viacam_vb2_queue,
+	.buf_prepare		= viacam_vb2_prepare,
+	.start_streaming	= viacam_vb2_start_streaming,
+	.stop_streaming		= viacam_vb2_stop_streaming,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
 };
 
 /* --------------------------------------------------------------------------*/
@@ -660,62 +687,43 @@
 static int viacam_open(struct file *filp)
 {
 	struct via_camera *cam = video_drvdata(filp);
+	int ret;
 
-	filp->private_data = cam;
 	/*
 	 * Note the new user.  If this is the first one, we'll also
 	 * need to power up the sensor.
 	 */
 	mutex_lock(&cam->lock);
-	if (cam->users == 0) {
-		int ret = viafb_request_dma();
+	ret = v4l2_fh_open(filp);
+	if (ret)
+		goto out;
+	if (v4l2_fh_is_singular_file(filp)) {
+		ret = viafb_request_dma();
 
 		if (ret) {
-			mutex_unlock(&cam->lock);
-			return ret;
+			v4l2_fh_release(filp);
+			goto out;
 		}
 		via_sensor_power_up(cam);
 		set_bit(CF_CONFIG_NEEDED, &cam->flags);
-		/*
-		 * Hook into videobuf.	Evidently this cannot fail.
-		 */
-		videobuf_queue_sg_init(&cam->vb_queue, &viacam_vb_ops,
-				&cam->platdev->dev, &cam->viadev->reg_lock,
-				V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
-				sizeof(struct videobuf_buffer), cam, NULL);
 	}
-	(cam->users)++;
+out:
 	mutex_unlock(&cam->lock);
-	return 0;
+	return ret;
 }
 
 static int viacam_release(struct file *filp)
 {
 	struct via_camera *cam = video_drvdata(filp);
+	bool last_open;
 
 	mutex_lock(&cam->lock);
-	(cam->users)--;
-	/*
-	 * If the "owner" is closing, shut down any ongoing
-	 * operations.
-	 */
-	if (filp == cam->owner) {
-		videobuf_stop(&cam->vb_queue);
-		/*
-		 * We don't hold the spinlock here, but, if release()
-		 * is being called by the owner, nobody else will
-		 * be changing the state.  And an extra stop would
-		 * not hurt anyway.
-		 */
-		if (cam->opstate != S_IDLE)
-			viacam_stop_engine(cam);
-		cam->owner = NULL;
-	}
+	last_open = v4l2_fh_is_singular_file(filp);
+	_vb2_fop_release(filp, NULL);
 	/*
 	 * Last one out needs to turn out the lights.
 	 */
-	if (cam->users == 0) {
-		videobuf_mmap_free(&cam->vb_queue);
+	if (last_open) {
 		via_sensor_power_down(cam);
 		viafb_release_dma();
 	}
@@ -723,77 +731,14 @@
 	return 0;
 }
 
-/*
- * Read a frame from the device.
- */
-static ssize_t viacam_read(struct file *filp, char __user *buffer,
-		size_t len, loff_t *pos)
-{
-	struct via_camera *cam = video_drvdata(filp);
-	int ret;
-
-	mutex_lock(&cam->lock);
-	/*
-	 * Enforce the V4l2 "only one owner gets to read data" rule.
-	 */
-	if (cam->owner && cam->owner != filp) {
-		ret = -EBUSY;
-		goto out_unlock;
-	}
-	cam->owner = filp;
-	/*
-	 * Do we need to configure the hardware?
-	 */
-	if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) {
-		ret = viacam_configure_sensor(cam);
-		if (!ret)
-			ret = viacam_config_controller(cam);
-		if (ret)
-			goto out_unlock;
-	}
-	/*
-	 * Fire up the capture engine, then have videobuf do
-	 * the heavy lifting.  Someday it would be good to avoid
-	 * stopping and restarting the engine each time.
-	 */
-	INIT_LIST_HEAD(&cam->buffer_queue);
-	viacam_start_engine(cam);
-	ret = videobuf_read_stream(&cam->vb_queue, buffer, len, pos, 0,
-			filp->f_flags & O_NONBLOCK);
-	viacam_stop_engine(cam);
-	/* videobuf_stop() ?? */
-
-out_unlock:
-	mutex_unlock(&cam->lock);
-	return ret;
-}
-
-
-static __poll_t viacam_poll(struct file *filp, struct poll_table_struct *pt)
-{
-	struct via_camera *cam = video_drvdata(filp);
-
-	return videobuf_poll_stream(filp, &cam->vb_queue, pt);
-}
-
-
-static int viacam_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	struct via_camera *cam = video_drvdata(filp);
-
-	return videobuf_mmap_mapper(&cam->vb_queue, vma);
-}
-
-
-
 static const struct v4l2_file_operations viacam_fops = {
 	.owner		= THIS_MODULE,
 	.open		= viacam_open,
 	.release	= viacam_release,
-	.read		= viacam_read,
-	.poll		= viacam_poll,
-	.mmap		= viacam_mmap,
-	.unlocked_ioctl	= video_ioctl2,
+	.read		= vb2_fop_read,
+	.poll		= vb2_fop_poll,
+	.mmap		= vb2_fop_mmap,
+	.unlocked_ioctl = video_ioctl2,
 };
 
 /*----------------------------------------------------------------------------*/
@@ -811,7 +756,6 @@
 		return -EINVAL;
 
 	input->type = V4L2_INPUT_TYPE_CAMERA;
-	input->std = V4L2_STD_ALL; /* Not sure what should go here */
 	strscpy(input->name, "Camera", sizeof(input->name));
 	return 0;
 }
@@ -829,17 +773,6 @@
 	return 0;
 }
 
-static int viacam_s_std(struct file *filp, void *priv, v4l2_std_id std)
-{
-	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.
@@ -851,6 +784,7 @@
 	.field		= V4L2_FIELD_NONE,
 	.bytesperline	= VGA_WIDTH * 2,
 	.sizeimage	= VGA_WIDTH * VGA_HEIGHT * 2,
+	.colorspace	= V4L2_COLORSPACE_SRGB,
 };
 
 static const u32 via_def_mbus_code = MEDIA_BUS_FMT_YUYV8_2X8;
@@ -860,8 +794,6 @@
 {
 	if (fmt->index >= N_VIA_FMTS)
 		return -EINVAL;
-	strscpy(fmt->description, via_formats[fmt->index].desc,
-		sizeof(fmt->description));
 	fmt->pixelformat = via_formats[fmt->index].pixelformat;
 	return 0;
 }
@@ -897,6 +829,10 @@
 	userfmt->field = sensorfmt->field;
 	userfmt->bytesperline = 2 * userfmt->width;
 	userfmt->sizeimage = userfmt->bytesperline * userfmt->height;
+	userfmt->colorspace = sensorfmt->colorspace;
+	userfmt->ycbcr_enc = sensorfmt->ycbcr_enc;
+	userfmt->quantization = sensorfmt->quantization;
+	userfmt->xfer_func = sensorfmt->xfer_func;
 }
 
 
@@ -927,32 +863,26 @@
 static int viacam_try_fmt_vid_cap(struct file *filp, void *priv,
 		struct v4l2_format *fmt)
 {
-	struct via_camera *cam = priv;
+	struct via_camera *cam = video_drvdata(filp);
 	struct v4l2_format sfmt;
-	int ret;
 
-	mutex_lock(&cam->lock);
-	ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix);
-	mutex_unlock(&cam->lock);
-	return ret;
+	return viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix);
 }
 
 
 static int viacam_g_fmt_vid_cap(struct file *filp, void *priv,
 		struct v4l2_format *fmt)
 {
-	struct via_camera *cam = priv;
+	struct via_camera *cam = video_drvdata(filp);
 
-	mutex_lock(&cam->lock);
 	fmt->fmt.pix = cam->user_format;
-	mutex_unlock(&cam->lock);
 	return 0;
 }
 
 static int viacam_s_fmt_vid_cap(struct file *filp, void *priv,
 		struct v4l2_format *fmt)
 {
-	struct via_camera *cam = priv;
+	struct via_camera *cam = video_drvdata(filp);
 	int ret;
 	struct v4l2_format sfmt;
 	struct via_format *f = via_find_format(fmt->fmt.pix.pixelformat);
@@ -961,18 +891,15 @@
 	 * Camera must be idle or we can't mess with the
 	 * video setup.
 	 */
-	mutex_lock(&cam->lock);
-	if (cam->opstate != S_IDLE) {
-		ret = -EBUSY;
-		goto out;
-	}
+	if (cam->opstate != S_IDLE)
+		return -EBUSY;
 	/*
 	 * Let the sensor code look over and tweak the
 	 * requested formatting.
 	 */
 	ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix);
 	if (ret)
-		goto out;
+		return ret;
 	/*
 	 * OK, let's commit to the new format.
 	 */
@@ -982,8 +909,6 @@
 	ret = viacam_configure_sensor(cam);
 	if (!ret)
 		ret = viacam_config_controller(cam);
-out:
-	mutex_unlock(&cam->lock);
 	return ret;
 }
 
@@ -992,155 +917,40 @@
 {
 	strscpy(cap->driver, "via-camera", sizeof(cap->driver));
 	strscpy(cap->card, "via-camera", sizeof(cap->card));
-	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
-		V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
+	strscpy(cap->bus_info, "platform:via-camera", sizeof(cap->bus_info));
 	return 0;
 }
 
-/*
- * Streaming operations - pure videobuf stuff.
- */
-static int viacam_reqbufs(struct file *filp, void *priv,
-		struct v4l2_requestbuffers *rb)
-{
-	struct via_camera *cam = priv;
-
-	return videobuf_reqbufs(&cam->vb_queue, rb);
-}
-
-static int viacam_querybuf(struct file *filp, void *priv,
-		struct v4l2_buffer *buf)
-{
-	struct via_camera *cam = priv;
-
-	return videobuf_querybuf(&cam->vb_queue, buf);
-}
-
-static int viacam_qbuf(struct file *filp, void *priv, struct v4l2_buffer *buf)
-{
-	struct via_camera *cam = priv;
-
-	return videobuf_qbuf(&cam->vb_queue, buf);
-}
-
-static int viacam_dqbuf(struct file *filp, void *priv, struct v4l2_buffer *buf)
-{
-	struct via_camera *cam = priv;
-
-	return videobuf_dqbuf(&cam->vb_queue, buf, filp->f_flags & O_NONBLOCK);
-}
-
-static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t)
-{
-	struct via_camera *cam = priv;
-	int ret = 0;
-
-	if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-
-	mutex_lock(&cam->lock);
-	if (cam->opstate != S_IDLE) {
-		ret = -EBUSY;
-		goto out;
-	}
-	/*
-	 * Enforce the V4l2 "only one owner gets to read data" rule.
-	 */
-	if (cam->owner && cam->owner != filp) {
-		ret = -EBUSY;
-		goto out;
-	}
-	cam->owner = filp;
-	/*
-	 * Configure things if need be.
-	 */
-	if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) {
-		ret = viacam_configure_sensor(cam);
-		if (ret)
-			goto out;
-		ret = viacam_config_controller(cam);
-		if (ret)
-			goto out;
-	}
-	/*
-	 * If the CPU goes into C3, the DMA transfer gets corrupted and
-	 * users start filing unsightly bug reports.  Put in a "latency"
-	 * requirement which will keep the CPU out of the deeper sleep
-	 * states.
-	 */
-	pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50);
-	/*
-	 * Fire things up.
-	 */
-	INIT_LIST_HEAD(&cam->buffer_queue);
-	ret = videobuf_streamon(&cam->vb_queue);
-	if (!ret)
-		viacam_start_engine(cam);
-out:
-	mutex_unlock(&cam->lock);
-	return ret;
-}
-
-static int viacam_streamoff(struct file *filp, void *priv, enum v4l2_buf_type t)
-{
-	struct via_camera *cam = priv;
-	int ret;
-
-	if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;
-	mutex_lock(&cam->lock);
-	if (cam->opstate != S_RUNNING) {
-		ret = -EINVAL;
-		goto out;
-	}
-	pm_qos_remove_request(&cam->qos_request);
-	viacam_stop_engine(cam);
-	/*
-	 * Videobuf will recycle all of the outstanding buffers, but
-	 * we should be sure we don't retain any references to
-	 * any of them.
-	 */
-	ret = videobuf_streamoff(&cam->vb_queue);
-	INIT_LIST_HEAD(&cam->buffer_queue);
-out:
-	mutex_unlock(&cam->lock);
-	return ret;
-}
-
 /* G/S_PARM */
 
 static int viacam_g_parm(struct file *filp, void *priv,
 		struct v4l2_streamparm *parm)
 {
-	struct via_camera *cam = priv;
-	int ret;
+	struct via_camera *cam = video_drvdata(filp);
 
-	mutex_lock(&cam->lock);
-	ret = v4l2_g_parm_cap(video_devdata(filp), cam->sensor, parm);
-	mutex_unlock(&cam->lock);
-	parm->parm.capture.readbuffers = cam->n_cap_bufs;
-	return ret;
+	return v4l2_g_parm_cap(video_devdata(filp), cam->sensor, parm);
 }
 
 static int viacam_s_parm(struct file *filp, void *priv,
 		struct v4l2_streamparm *parm)
 {
-	struct via_camera *cam = priv;
-	int ret;
+	struct via_camera *cam = video_drvdata(filp);
 
-	mutex_lock(&cam->lock);
-	ret = v4l2_s_parm_cap(video_devdata(filp), cam->sensor, parm);
-	mutex_unlock(&cam->lock);
-	parm->parm.capture.readbuffers = cam->n_cap_bufs;
-	return ret;
+	return v4l2_s_parm_cap(video_devdata(filp), cam->sensor, parm);
 }
 
 static int viacam_enum_framesizes(struct file *filp, void *priv,
 		struct v4l2_frmsizeenum *sizes)
 {
+	unsigned int i;
+
 	if (sizes->index != 0)
 		return -EINVAL;
+	for (i = 0; i < N_VIA_FMTS; i++)
+		if (sizes->pixel_format == via_formats[i].pixelformat)
+			break;
+	if (i >= N_VIA_FMTS)
+		return -EINVAL;
 	sizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
 	sizes->stepwise.min_width = QCIF_WIDTH;
 	sizes->stepwise.min_height = QCIF_HEIGHT;
@@ -1153,7 +963,7 @@
 static int viacam_enum_frameintervals(struct file *filp, void *priv,
 		struct v4l2_frmivalenum *interval)
 {
-	struct via_camera *cam = priv;
+	struct via_camera *cam = video_drvdata(filp);
 	struct v4l2_subdev_frame_interval_enum fie = {
 		.index = interval->index,
 		.code = cam->mbus_code,
@@ -1161,11 +971,18 @@
 		.height = cam->sensor_format.height,
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 	};
+	unsigned int i;
 	int ret;
 
-	mutex_lock(&cam->lock);
+	for (i = 0; i < N_VIA_FMTS; i++)
+		if (interval->pixel_format == via_formats[i].pixelformat)
+			break;
+	if (i >= N_VIA_FMTS)
+		return -EINVAL;
+	if (interval->width < QCIF_WIDTH || interval->width > VGA_WIDTH ||
+	    interval->height < QCIF_HEIGHT || interval->height > VGA_HEIGHT)
+		return -EINVAL;
 	ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie);
-	mutex_unlock(&cam->lock);
 	if (ret)
 		return ret;
 	interval->type = V4L2_FRMIVAL_TYPE_DISCRETE;
@@ -1173,29 +990,30 @@
 	return 0;
 }
 
-
-
 static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
 	.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,
 	.vidioc_s_fmt_vid_cap	= viacam_s_fmt_vid_cap,
 	.vidioc_querycap	= viacam_querycap,
-	.vidioc_reqbufs		= viacam_reqbufs,
-	.vidioc_querybuf	= viacam_querybuf,
-	.vidioc_qbuf		= viacam_qbuf,
-	.vidioc_dqbuf		= viacam_dqbuf,
-	.vidioc_streamon	= viacam_streamon,
-	.vidioc_streamoff	= viacam_streamoff,
+	.vidioc_reqbufs		= vb2_ioctl_reqbufs,
+	.vidioc_create_bufs	= vb2_ioctl_create_bufs,
+	.vidioc_querybuf	= vb2_ioctl_querybuf,
+	.vidioc_prepare_buf	= vb2_ioctl_prepare_buf,
+	.vidioc_qbuf		= vb2_ioctl_qbuf,
+	.vidioc_dqbuf		= vb2_ioctl_dqbuf,
+	.vidioc_expbuf		= vb2_ioctl_expbuf,
+	.vidioc_streamon	= vb2_ioctl_streamon,
+	.vidioc_streamoff	= vb2_ioctl_streamoff,
 	.vidioc_g_parm		= viacam_g_parm,
 	.vidioc_s_parm		= viacam_s_parm,
 	.vidioc_enum_framesizes = viacam_enum_framesizes,
 	.vidioc_enum_frameintervals = viacam_enum_frameintervals,
+	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
 };
 
 /*----------------------------------------------------------------------------*/
@@ -1233,7 +1051,7 @@
 	/*
 	 * Make sure the sensor's power state is correct
 	 */
-	if (cam->users > 0)
+	if (!list_empty(&cam->vdev.fh_list))
 		via_sensor_power_up(cam);
 	else
 		via_sensor_power_down(cam);
@@ -1267,10 +1085,11 @@
 static const struct video_device viacam_v4l_template = {
 	.name		= "via-camera",
 	.minor		= -1,
-	.tvnorms	= V4L2_STD_NTSC_M,
 	.fops		= &viacam_fops,
 	.ioctl_ops	= &viacam_ioctl_ops,
 	.release	= video_device_release_empty, /* Check this */
+	.device_caps	= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
+			  V4L2_CAP_STREAMING,
 };
 
 /*
@@ -1317,6 +1136,7 @@
 	int ret;
 	struct i2c_adapter *sensor_adapter;
 	struct viafb_dev *viadev = pdev->dev.platform_data;
+	struct vb2_queue *vq;
 	struct i2c_board_info ov7670_info = {
 		.type = "ov7670",
 		.addr = 0x42 >> 1,
@@ -1360,8 +1180,6 @@
 	via_cam_info = cam;
 	cam->platdev = pdev;
 	cam->viadev = viadev;
-	cam->users = 0;
-	cam->owner = NULL;
 	cam->opstate = S_IDLE;
 	cam->user_format = cam->sensor_format = viacam_def_pix_format;
 	mutex_init(&cam->lock);
@@ -1422,15 +1240,31 @@
 			viacam_irq, IRQF_SHARED, "via-camera", cam);
 	if (ret)
 		goto out_power_down;
+
+	vq = &cam->vq;
+	vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+	vq->drv_priv = cam;
+	vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	vq->buf_struct_size = sizeof(struct via_buffer);
+	vq->dev = cam->v4l2_dev.dev;
+
+	vq->ops = &viacam_vb2_ops;
+	vq->mem_ops = &vb2_dma_sg_memops;
+	vq->lock = &cam->lock;
+
+	ret = vb2_queue_init(vq);
 	/*
 	 * Tell V4l2 that we exist.
 	 */
 	cam->vdev = viacam_v4l_template;
 	cam->vdev.v4l2_dev = &cam->v4l2_dev;
+	cam->vdev.lock = &cam->lock;
+	cam->vdev.queue = vq;
+	video_set_drvdata(&cam->vdev, cam);
 	ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
 	if (ret)
 		goto out_irq;
-	video_set_drvdata(&cam->vdev, cam);
 
 #ifdef CONFIG_PM
 	/*
@@ -1464,6 +1298,9 @@
 
 	video_unregister_device(&cam->vdev);
 	v4l2_device_unregister(&cam->v4l2_dev);
+#ifdef CONFIG_PM
+	viafb_pm_unregister(&viacam_pm_hooks);
+#endif
 	free_irq(viadev->pdev->irq, cam);
 	via_sensor_power_release(cam);
 	v4l2_ctrl_handler_free(&cam->ctrl_handler);
diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.c b/drivers/media/platform/vicodec/codec-v4l2-fwht.c
index 01e7f09..3c93d92 100644
--- a/drivers/media/platform/vicodec/codec-v4l2-fwht.c
+++ b/drivers/media/platform/vicodec/codec-v4l2-fwht.c
@@ -29,11 +29,15 @@
 	{ V4L2_PIX_FMT_HSV24,   3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV},
 	{ V4L2_PIX_FMT_BGR32,   4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB},
 	{ V4L2_PIX_FMT_XBGR32,  4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_ABGR32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
 	{ V4L2_PIX_FMT_RGB32,   4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB},
 	{ V4L2_PIX_FMT_XRGB32,  4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_HSV32,   4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV},
 	{ V4L2_PIX_FMT_ARGB32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
-	{ V4L2_PIX_FMT_ABGR32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_BGRX32,  4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_BGRA32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_RGBX32,  4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_RGBA32,  4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB},
+	{ V4L2_PIX_FMT_HSV32,   4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV},
 	{ V4L2_PIX_FMT_GREY,    1, 1, 1, 1, 0, 1, 1, 1, 1, FWHT_FL_PIXENC_RGB},
 };
 
@@ -193,6 +197,28 @@
 		rf->luma++;
 		rf->alpha = rf->cr + 1;
 		break;
+	case V4L2_PIX_FMT_BGRX32:
+		rf->cb = rf->luma + 1;
+		rf->cr = rf->cb + 2;
+		rf->luma += 2;
+		break;
+	case V4L2_PIX_FMT_BGRA32:
+		rf->alpha = rf->luma;
+		rf->cb = rf->luma + 1;
+		rf->cr = rf->cb + 2;
+		rf->luma += 2;
+		break;
+	case V4L2_PIX_FMT_RGBX32:
+		rf->cr = rf->luma;
+		rf->cb = rf->cr + 2;
+		rf->luma++;
+		break;
+	case V4L2_PIX_FMT_RGBA32:
+		rf->alpha = rf->luma + 3;
+		rf->cr = rf->luma;
+		rf->cb = rf->cr + 2;
+		rf->luma++;
+		break;
 	default:
 		return -EINVAL;
 	}
diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c
index 7e7c1e8..0ee143a 100644
--- a/drivers/media/platform/vicodec/vicodec-core.c
+++ b/drivers/media/platform/vicodec/vicodec-core.c
@@ -742,6 +742,9 @@
 			return -EINVAL;
 		f->pixelformat = ctx->is_stateless ?
 			V4L2_PIX_FMT_FWHT_STATELESS : V4L2_PIX_FMT_FWHT;
+		if (!ctx->is_enc && !ctx->is_stateless)
+			f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION |
+				   V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM;
 	}
 	return 0;
 }
@@ -1661,19 +1664,22 @@
 	kvfree(state->compressed_frame);
 	state->compressed_frame = new_comp_frame;
 
-	if (info->components_num >= 3) {
-		state->ref_frame.cb = state->ref_frame.luma + size;
-		state->ref_frame.cr = state->ref_frame.cb + size / chroma_div;
-	} else {
+	if (info->components_num < 3) {
 		state->ref_frame.cb = NULL;
 		state->ref_frame.cr = NULL;
+		state->ref_frame.alpha = NULL;
+		return 0;
 	}
 
+	state->ref_frame.cb = state->ref_frame.luma + size;
+	state->ref_frame.cr = state->ref_frame.cb + size / chroma_div;
+
 	if (info->components_num == 4)
 		state->ref_frame.alpha =
 			state->ref_frame.cr + size / chroma_div;
 	else
 		state->ref_frame.alpha = NULL;
+
 	return 0;
 }
 
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
index 6648557..1d56b91 100644
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ b/drivers/media/platform/vimc/vimc-capture.c
@@ -18,32 +18,6 @@
 
 #define VIMC_CAP_DRV_NAME "vimc-capture"
 
-static const u32 vimc_cap_supported_pixfmt[] = {
-	V4L2_PIX_FMT_BGR24,
-	V4L2_PIX_FMT_RGB24,
-	V4L2_PIX_FMT_ARGB32,
-	V4L2_PIX_FMT_SBGGR8,
-	V4L2_PIX_FMT_SGBRG8,
-	V4L2_PIX_FMT_SGRBG8,
-	V4L2_PIX_FMT_SRGGB8,
-	V4L2_PIX_FMT_SBGGR10,
-	V4L2_PIX_FMT_SGBRG10,
-	V4L2_PIX_FMT_SGRBG10,
-	V4L2_PIX_FMT_SRGGB10,
-	V4L2_PIX_FMT_SBGGR10ALAW8,
-	V4L2_PIX_FMT_SGBRG10ALAW8,
-	V4L2_PIX_FMT_SGRBG10ALAW8,
-	V4L2_PIX_FMT_SRGGB10ALAW8,
-	V4L2_PIX_FMT_SBGGR10DPCM8,
-	V4L2_PIX_FMT_SGBRG10DPCM8,
-	V4L2_PIX_FMT_SGRBG10DPCM8,
-	V4L2_PIX_FMT_SRGGB10DPCM8,
-	V4L2_PIX_FMT_SBGGR12,
-	V4L2_PIX_FMT_SGBRG12,
-	V4L2_PIX_FMT_SGRBG12,
-	V4L2_PIX_FMT_SRGGB12,
-};
-
 struct vimc_cap_device {
 	struct vimc_ent_device ved;
 	struct video_device vdev;
@@ -117,25 +91,29 @@
 				    struct v4l2_format *f)
 {
 	struct v4l2_pix_format *format = &f->fmt.pix;
+	const struct vimc_pix_map *vpix;
 
 	format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH,
 				VIMC_FRAME_MAX_WIDTH) & ~1;
 	format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT,
 				 VIMC_FRAME_MAX_HEIGHT) & ~1;
 
-	vimc_colorimetry_clamp(format);
+	/* Don't accept a pixelformat that is not on the table */
+	vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
+	if (!vpix) {
+		format->pixelformat = fmt_default.pixelformat;
+		vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
+	}
+	/* TODO: Add support for custom bytesperline values */
+	format->bytesperline = format->width * vpix->bpp;
+	format->sizeimage = format->bytesperline * format->height;
 
 	if (format->field == V4L2_FIELD_ANY)
 		format->field = fmt_default.field;
 
-	/* TODO: Add support for custom bytesperline values */
+	vimc_colorimetry_clamp(format);
 
-	/* Don't accept a pixelformat that is not on the table */
-	if (!v4l2_format_info(format->pixelformat))
-		format->pixelformat = fmt_default.pixelformat;
-
-	return v4l2_fill_pixfmt(format, format->pixelformat,
-				format->width, format->height);
+	return 0;
 }
 
 static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
@@ -174,31 +152,27 @@
 static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
 				     struct v4l2_fmtdesc *f)
 {
-	if (f->index >= ARRAY_SIZE(vimc_cap_supported_pixfmt))
+	const struct vimc_pix_map *vpix = vimc_pix_map_by_index(f->index);
+
+	if (!vpix)
 		return -EINVAL;
 
-	f->pixelformat = vimc_cap_supported_pixfmt[f->index];
+	f->pixelformat = vpix->pixelformat;
 
 	return 0;
 }
 
-static bool vimc_cap_is_pixfmt_supported(u32 pixelformat)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(vimc_cap_supported_pixfmt); i++)
-		if (vimc_cap_supported_pixfmt[i] == pixelformat)
-			return true;
-	return false;
-}
-
 static int vimc_cap_enum_framesizes(struct file *file, void *fh,
 				    struct v4l2_frmsizeenum *fsize)
 {
+	const struct vimc_pix_map *vpix;
+
 	if (fsize->index)
 		return -EINVAL;
 
-	if (!vimc_cap_is_pixfmt_supported(fsize->pixel_format))
+	/* Only accept code in the pix map table */
+	vpix = vimc_pix_map_by_code(fsize->pixel_format);
+	if (!vpix)
 		return -EINVAL;
 
 	fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
@@ -272,7 +246,6 @@
 		return ret;
 	}
 
-	vcap->stream.producer_pixfmt = vcap->format.pixelformat;
 	ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1);
 	if (ret) {
 		media_pipeline_stop(entity);
@@ -423,6 +396,7 @@
 {
 	struct v4l2_device *v4l2_dev = master_data;
 	struct vimc_platform_data *pdata = comp->platform_data;
+	const struct vimc_pix_map *vpix;
 	struct vimc_cap_device *vcap;
 	struct video_device *vdev;
 	struct vb2_queue *q;
@@ -477,8 +451,10 @@
 
 	/* Set default frame format */
 	vcap->format = fmt_default;
-	v4l2_fill_pixfmt(&vcap->format, vcap->format.pixelformat,
-			 vcap->format.width, vcap->format.height);
+	vpix = vimc_pix_map_by_pixelformat(vcap->format.pixelformat);
+	vcap->format.bytesperline = vcap->format.width * vpix->bpp;
+	vcap->format.sizeimage = vcap->format.bytesperline *
+				 vcap->format.height;
 
 	/* Fill the vimc_ent_device struct */
 	vcap->ved.ent = &vcap->vdev.entity;
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
index 03016f2..7e1ae0b 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -10,139 +10,192 @@
 
 #include "vimc-common.h"
 
-static const __u32 vimc_mbus_list[] = {
-	MEDIA_BUS_FMT_FIXED,
-	MEDIA_BUS_FMT_RGB444_1X12,
-	MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE,
-	MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE,
-	MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
-	MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
-	MEDIA_BUS_FMT_RGB565_1X16,
-	MEDIA_BUS_FMT_BGR565_2X8_BE,
-	MEDIA_BUS_FMT_BGR565_2X8_LE,
-	MEDIA_BUS_FMT_RGB565_2X8_BE,
-	MEDIA_BUS_FMT_RGB565_2X8_LE,
-	MEDIA_BUS_FMT_RGB666_1X18,
-	MEDIA_BUS_FMT_RBG888_1X24,
-	MEDIA_BUS_FMT_RGB666_1X24_CPADHI,
-	MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
-	MEDIA_BUS_FMT_BGR888_1X24,
-	MEDIA_BUS_FMT_GBR888_1X24,
-	MEDIA_BUS_FMT_RGB888_1X24,
-	MEDIA_BUS_FMT_RGB888_2X12_BE,
-	MEDIA_BUS_FMT_RGB888_2X12_LE,
-	MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
-	MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
-	MEDIA_BUS_FMT_ARGB8888_1X32,
-	MEDIA_BUS_FMT_RGB888_1X32_PADHI,
-	MEDIA_BUS_FMT_RGB101010_1X30,
-	MEDIA_BUS_FMT_RGB121212_1X36,
-	MEDIA_BUS_FMT_RGB161616_1X48,
-	MEDIA_BUS_FMT_Y8_1X8,
-	MEDIA_BUS_FMT_UV8_1X8,
-	MEDIA_BUS_FMT_UYVY8_1_5X8,
-	MEDIA_BUS_FMT_VYUY8_1_5X8,
-	MEDIA_BUS_FMT_YUYV8_1_5X8,
-	MEDIA_BUS_FMT_YVYU8_1_5X8,
-	MEDIA_BUS_FMT_UYVY8_2X8,
-	MEDIA_BUS_FMT_VYUY8_2X8,
-	MEDIA_BUS_FMT_YUYV8_2X8,
-	MEDIA_BUS_FMT_YVYU8_2X8,
-	MEDIA_BUS_FMT_Y10_1X10,
-	MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
-	MEDIA_BUS_FMT_UYVY10_2X10,
-	MEDIA_BUS_FMT_VYUY10_2X10,
-	MEDIA_BUS_FMT_YUYV10_2X10,
-	MEDIA_BUS_FMT_YVYU10_2X10,
-	MEDIA_BUS_FMT_Y12_1X12,
-	MEDIA_BUS_FMT_UYVY12_2X12,
-	MEDIA_BUS_FMT_VYUY12_2X12,
-	MEDIA_BUS_FMT_YUYV12_2X12,
-	MEDIA_BUS_FMT_YVYU12_2X12,
-	MEDIA_BUS_FMT_UYVY8_1X16,
-	MEDIA_BUS_FMT_VYUY8_1X16,
-	MEDIA_BUS_FMT_YUYV8_1X16,
-	MEDIA_BUS_FMT_YVYU8_1X16,
-	MEDIA_BUS_FMT_YDYUYDYV8_1X16,
-	MEDIA_BUS_FMT_UYVY10_1X20,
-	MEDIA_BUS_FMT_VYUY10_1X20,
-	MEDIA_BUS_FMT_YUYV10_1X20,
-	MEDIA_BUS_FMT_YVYU10_1X20,
-	MEDIA_BUS_FMT_VUY8_1X24,
-	MEDIA_BUS_FMT_YUV8_1X24,
-	MEDIA_BUS_FMT_UYYVYY8_0_5X24,
-	MEDIA_BUS_FMT_UYVY12_1X24,
-	MEDIA_BUS_FMT_VYUY12_1X24,
-	MEDIA_BUS_FMT_YUYV12_1X24,
-	MEDIA_BUS_FMT_YVYU12_1X24,
-	MEDIA_BUS_FMT_YUV10_1X30,
-	MEDIA_BUS_FMT_UYYVYY10_0_5X30,
-	MEDIA_BUS_FMT_AYUV8_1X32,
-	MEDIA_BUS_FMT_UYYVYY12_0_5X36,
-	MEDIA_BUS_FMT_YUV12_1X36,
-	MEDIA_BUS_FMT_YUV16_1X48,
-	MEDIA_BUS_FMT_UYYVYY16_0_5X48,
-	MEDIA_BUS_FMT_SBGGR8_1X8,
-	MEDIA_BUS_FMT_SGBRG8_1X8,
-	MEDIA_BUS_FMT_SGRBG8_1X8,
-	MEDIA_BUS_FMT_SRGGB8_1X8,
-	MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
-	MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
-	MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
-	MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8,
-	MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
-	MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
-	MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
-	MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
-	MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE,
-	MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
-	MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE,
-	MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE,
-	MEDIA_BUS_FMT_SBGGR10_1X10,
-	MEDIA_BUS_FMT_SGBRG10_1X10,
-	MEDIA_BUS_FMT_SGRBG10_1X10,
-	MEDIA_BUS_FMT_SRGGB10_1X10,
-	MEDIA_BUS_FMT_SBGGR12_1X12,
-	MEDIA_BUS_FMT_SGBRG12_1X12,
-	MEDIA_BUS_FMT_SGRBG12_1X12,
-	MEDIA_BUS_FMT_SRGGB12_1X12,
-	MEDIA_BUS_FMT_SBGGR14_1X14,
-	MEDIA_BUS_FMT_SGBRG14_1X14,
-	MEDIA_BUS_FMT_SGRBG14_1X14,
-	MEDIA_BUS_FMT_SRGGB14_1X14,
-	MEDIA_BUS_FMT_SBGGR16_1X16,
-	MEDIA_BUS_FMT_SGBRG16_1X16,
-	MEDIA_BUS_FMT_SGRBG16_1X16,
-	MEDIA_BUS_FMT_SRGGB16_1X16,
-	MEDIA_BUS_FMT_JPEG_1X8,
-	MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8,
-	MEDIA_BUS_FMT_AHSV8888_1X32,
+/*
+ * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code
+ * in the scaler)
+ */
+static const struct vimc_pix_map vimc_pix_map_list[] = {
+	/* TODO: add all missing formats */
+
+	/* RGB formats */
+	{
+		.code = MEDIA_BUS_FMT_BGR888_1X24,
+		.pixelformat = V4L2_PIX_FMT_BGR24,
+		.bpp = 3,
+		.bayer = false,
+	},
+	{
+		.code = MEDIA_BUS_FMT_RGB888_1X24,
+		.pixelformat = V4L2_PIX_FMT_RGB24,
+		.bpp = 3,
+		.bayer = false,
+	},
+	{
+		.code = MEDIA_BUS_FMT_ARGB8888_1X32,
+		.pixelformat = V4L2_PIX_FMT_ARGB32,
+		.bpp = 4,
+		.bayer = false,
+	},
+
+	/* Bayer formats */
+	{
+		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SBGGR8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGBRG8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGRBG8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SRGGB8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.pixelformat = V4L2_PIX_FMT_SBGGR10,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
+		.pixelformat = V4L2_PIX_FMT_SGBRG10,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.pixelformat = V4L2_PIX_FMT_SGRBG10,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.pixelformat = V4L2_PIX_FMT_SRGGB10,
+		.bpp = 2,
+		.bayer = true,
+	},
+
+	/* 10bit raw bayer a-law compressed to 8 bits */
+	{
+		.code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8,
+		.bpp = 1,
+		.bayer = true,
+	},
+
+	/* 10bit raw bayer DPCM compressed to 8 bits */
+	{
+		.code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8,
+		.pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8,
+		.bpp = 1,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SBGGR12,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SGBRG12,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SGRBG12,
+		.bpp = 2,
+		.bayer = true,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.pixelformat = V4L2_PIX_FMT_SRGGB12,
+		.bpp = 2,
+		.bayer = true,
+	},
 };
 
-/* Helper function to check mbus codes */
-bool vimc_mbus_code_supported(__u32 code)
+const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i)
+{
+	if (i >= ARRAY_SIZE(vimc_pix_map_list))
+		return NULL;
+
+	return &vimc_pix_map_list[i];
+}
+EXPORT_SYMBOL_GPL(vimc_pix_map_by_index);
+
+const struct vimc_pix_map *vimc_pix_map_by_code(u32 code)
 {
 	unsigned int i;
 
-	for (i = 0; i < ARRAY_SIZE(vimc_mbus_list); i++)
-		if (code == vimc_mbus_list[i])
-			return true;
-	return false;
+	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
+		if (vimc_pix_map_list[i].code == code)
+			return &vimc_pix_map_list[i];
+	}
+	return NULL;
 }
-EXPORT_SYMBOL_GPL(vimc_mbus_code_supported);
+EXPORT_SYMBOL_GPL(vimc_pix_map_by_code);
 
-/* Helper function to enumerate mbus codes */
-int vimc_enum_mbus_code(struct v4l2_subdev *sd,
-			struct v4l2_subdev_pad_config *cfg,
-			struct v4l2_subdev_mbus_code_enum *code)
+const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
 {
-	if (code->index >= ARRAY_SIZE(vimc_mbus_list))
-		return -EINVAL;
+	unsigned int i;
 
-	code->code = vimc_mbus_list[code->index];
-	return 0;
+	for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) {
+		if (vimc_pix_map_list[i].pixelformat == pixelformat)
+			return &vimc_pix_map_list[i];
+	}
+	return NULL;
 }
-EXPORT_SYMBOL_GPL(vimc_enum_mbus_code);
+EXPORT_SYMBOL_GPL(vimc_pix_map_by_pixelformat);
 
 /* Helper function to allocate and initialize pads */
 struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
@@ -214,13 +267,15 @@
 							 struct video_device,
 							 entity);
 		struct vimc_ent_device *ved = video_get_drvdata(vdev);
+		const struct vimc_pix_map *vpix;
 		struct v4l2_pix_format vdev_fmt;
 
 		if (!ved->vdev_get_format)
 			return -ENOIOCTLCMD;
 
 		ved->vdev_get_format(ved, &vdev_fmt);
-		v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, 0);
+		vpix = vimc_pix_map_by_pixelformat(vdev_fmt.pixelformat);
+		v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, vpix->code);
 	} else {
 		return -EINVAL;
 	}
@@ -260,12 +315,8 @@
 	/* The width, height and code must match. */
 	if (source_fmt.format.width != sink_fmt.format.width
 	    || source_fmt.format.height != sink_fmt.format.height
-	    || (source_fmt.format.code && sink_fmt.format.code &&
-		source_fmt.format.code != sink_fmt.format.code)) {
-		pr_err("vimc: format doesn't match in link %s->%s\n",
-			link->source->entity->name, link->sink->entity->name);
+	    || source_fmt.format.code != sink_fmt.format.code)
 		return -EPIPE;
-	}
 
 	/*
 	 * The field order must match, or the sink field order must be NONE
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
index 7b4d988..9c2e0e2 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -12,8 +12,6 @@
 #include <media/media-device.h>
 #include <media/v4l2-device.h>
 
-#include "vimc-streamer.h"
-
 #define VIMC_PDEV_NAME "vimc"
 
 /* VIMC-specific controls */
@@ -70,6 +68,23 @@
 };
 
 /**
+ * struct vimc_pix_map - maps media bus code with v4l2 pixel format
+ *
+ * @code:		media bus format code defined by MEDIA_BUS_FMT_* macros
+ * @bbp:		number of bytes each pixel occupies
+ * @pixelformat:	pixel format devined by V4L2_PIX_FMT_* macros
+ *
+ * Struct which matches the MEDIA_BUS_FMT_* codes with the corresponding
+ * V4L2_PIX_FMT_* fourcc pixelformat and its bytes per pixel (bpp)
+ */
+struct vimc_pix_map {
+	unsigned int code;
+	unsigned int bpp;
+	u32 pixelformat;
+	bool bayer;
+};
+
+/**
  * struct vimc_ent_device - core struct that represents a node in the topology
  *
  * @ent:		the pointer to struct media_entity for the node
@@ -90,7 +105,6 @@
 struct vimc_ent_device {
 	struct media_entity *ent;
 	struct media_pad *pads;
-	struct vimc_stream *stream;
 	void * (*process_frame)(struct vimc_ent_device *ved,
 				const void *frame);
 	void (*vdev_get_format)(struct vimc_ent_device *ved,
@@ -98,23 +112,6 @@
 };
 
 /**
- * vimc_mbus_code_supported - helper to check supported mbus codes
- *
- * Helper function to check if mbus code is enumerated by vimc_enum_mbus_code()
- */
-bool vimc_mbus_code_supported(__u32 code);
-
-/**
- * vimc_enum_mbus_code - enumerate mbus codes
- *
- * Helper function to be pluged in .enum_mbus_code from
- * struct v4l2_subdev_pad_ops.
- */
-int vimc_enum_mbus_code(struct v4l2_subdev *sd,
-			struct v4l2_subdev_pad_config *cfg,
-			struct v4l2_subdev_mbus_code_enum *code);
-
-/**
  * vimc_pads_init - initialize pads
  *
  * @num_pads:	number of pads to initialize
@@ -149,6 +146,27 @@
 int vimc_pipeline_s_stream(struct media_entity *ent, int enable);
 
 /**
+ * vimc_pix_map_by_index - get vimc_pix_map struct by its index
+ *
+ * @i:			index of the vimc_pix_map struct in vimc_pix_map_list
+ */
+const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i);
+
+/**
+ * vimc_pix_map_by_code - get vimc_pix_map struct by media bus code
+ *
+ * @code:		media bus format code defined by MEDIA_BUS_FMT_* macros
+ */
+const struct vimc_pix_map *vimc_pix_map_by_code(u32 code);
+
+/**
+ * vimc_pix_map_by_pixelformat - get vimc_pix_map struct by v4l2 pixel format
+ *
+ * @pixelformat:	pixel format devined by V4L2_PIX_FMT_* macros
+ */
+const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat);
+
+/**
  * vimc_ent_sd_register - initialize and register a subdev node
  *
  * @ved:	the vimc_ent_device struct to be initialize
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
index 00598fb..b72b838 100644
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -16,11 +16,6 @@
 #include "vimc-common.h"
 
 #define VIMC_DEB_DRV_NAME "vimc-debayer"
-/* This module only supports transforming a bayer format
- * to V4L2_PIX_FMT_RGB24
- */
-#define VIMC_DEB_SRC_PIXFMT V4L2_PIX_FMT_RGB24
-#define VIMC_DEB_SRC_MBUS_FMT_DEFAULT MEDIA_BUS_FMT_RGB888_1X24
 
 static unsigned int deb_mean_win_size = 3;
 module_param(deb_mean_win_size, uint, 0000);
@@ -39,7 +34,6 @@
 };
 
 struct vimc_deb_pix_map {
-	u32 pixelformat;
 	u32 code;
 	enum vimc_deb_rgb_colors order[2][2];
 };
@@ -69,73 +63,61 @@
 
 static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = {
 	{
-		.pixelformat = V4L2_PIX_FMT_SBGGR8,
 		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
 		.order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
 			   { VIMC_DEB_GREEN, VIMC_DEB_RED } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SGBRG8,
 		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
 		.order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
 			   { VIMC_DEB_RED, VIMC_DEB_GREEN } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SGRBG8,
 		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
 		.order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
 			   { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SRGGB8,
 		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
 		.order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
 			   { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SBGGR10,
 		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
 		.order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
 			   { VIMC_DEB_GREEN, VIMC_DEB_RED } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SGBRG10,
 		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
 		.order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
 			   { VIMC_DEB_RED, VIMC_DEB_GREEN } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SGRBG10,
 		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
 		.order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
 			   { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SRGGB10,
 		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
 		.order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
 			   { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SBGGR12,
 		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
 		.order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
 			   { VIMC_DEB_GREEN, VIMC_DEB_RED } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SGBRG12,
 		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
 		.order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
 			   { VIMC_DEB_RED, VIMC_DEB_GREEN } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SGRBG12,
 		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
 		.order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
 			   { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
 	},
 	{
-		.pixelformat = V4L2_PIX_FMT_SRGGB12,
 		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
 		.order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
 			   { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
@@ -176,32 +158,41 @@
 				   struct v4l2_subdev_pad_config *cfg,
 				   struct v4l2_subdev_mbus_code_enum *code)
 {
-	/* For the sink pad we only support codes in the map_list */
-	if (IS_SINK(code->pad)) {
+	/* We only support one format for source pads */
+	if (IS_SRC(code->pad)) {
+		struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
+
+		if (code->index)
+			return -EINVAL;
+
+		code->code = vdeb->src_code;
+	} else {
 		if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list))
 			return -EINVAL;
 
 		code->code = vimc_deb_pix_map_list[code->index].code;
-		return 0;
 	}
 
-	return vimc_enum_mbus_code(sd, cfg, code);
+	return 0;
 }
 
 static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd,
 				    struct v4l2_subdev_pad_config *cfg,
 				    struct v4l2_subdev_frame_size_enum *fse)
 {
+	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
+
 	if (fse->index)
 		return -EINVAL;
 
-	/* For the sink pad we only support codes in the map_list */
 	if (IS_SINK(fse->pad)) {
 		const struct vimc_deb_pix_map *vpix =
 			vimc_deb_pix_map_by_code(fse->code);
 
 		if (!vpix)
 			return -EINVAL;
+	} else if (fse->code != vdeb->src_code) {
+		return -EINVAL;
 	}
 
 	fse->min_width = VIMC_FRAME_MIN_WIDTH;
@@ -257,12 +248,9 @@
 	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *sink_fmt;
 
-	if (!vimc_mbus_code_supported(fmt->format.code))
-		fmt->format.code = sink_fmt_default.code;
-
 	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
 		/* Do not change the format while stream is on */
-		if (vdeb->ved.stream)
+		if (vdeb->src_frame)
 			return -EBUSY;
 
 		sink_fmt = &vdeb->sink_fmt;
@@ -272,11 +260,11 @@
 
 	/*
 	 * Do not change the format of the source pad,
-	 * it is propagated from the sink (except for the code)
+	 * it is propagated from the sink
 	 */
 	if (IS_SRC(fmt->pad)) {
-		vdeb->src_code = fmt->format.code;
 		fmt->format = *sink_fmt;
+		/* TODO: Add support for other formats */
 		fmt->format.code = vdeb->src_code;
 	} else {
 		/* Set the new format in the sink pad */
@@ -308,7 +296,7 @@
 	.set_fmt		= vimc_deb_set_fmt,
 };
 
-static void vimc_deb_set_rgb_pix_rgb24(struct vimc_deb_device *vdeb,
+static void vimc_deb_set_rgb_mbus_fmt_rgb888_1x24(struct vimc_deb_device *vdeb,
 						  unsigned int lin,
 						  unsigned int col,
 						  unsigned int rgb[3])
@@ -325,35 +313,25 @@
 	struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
 
 	if (enable) {
-		u32 src_pixelformat = vdeb->ved.stream->producer_pixfmt;
-		const struct v4l2_format_info *pix_info;
+		const struct vimc_pix_map *vpix;
 		unsigned int frame_size;
 
-		/* We only support translating bayer to RGB24 */
-		if (src_pixelformat != V4L2_PIX_FMT_RGB24) {
-			dev_err(vdeb->dev,
-				"translating to pixfmt (0x%08x) is not supported\n",
-				src_pixelformat);
-			return -EINVAL;
-		}
+		if (vdeb->src_frame)
+			return 0;
+
+		/* Calculate the frame size of the source pad */
+		vpix = vimc_pix_map_by_code(vdeb->src_code);
+		frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height *
+				vpix->bpp;
+
+		/* Save the bytes per pixel of the sink */
+		vpix = vimc_pix_map_by_code(vdeb->sink_fmt.code);
+		vdeb->sink_bpp = vpix->bpp;
 
 		/* Get the corresponding pixel map from the table */
 		vdeb->sink_pix_map =
 			vimc_deb_pix_map_by_code(vdeb->sink_fmt.code);
 
-		/* Request bayer format from the pipeline for the sink pad */
-		vdeb->ved.stream->producer_pixfmt =
-			vdeb->sink_pix_map->pixelformat;
-
-		/* Calculate frame_size of the source */
-		pix_info = v4l2_format_info(src_pixelformat);
-		frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height *
-			     pix_info->bpp[0];
-
-		/* Get bpp from the sink */
-		pix_info = v4l2_format_info(vdeb->sink_pix_map->pixelformat);
-		vdeb->sink_bpp = pix_info->bpp[0];
-
 		/*
 		 * Allocate the frame buffer. Use vmalloc to be able to
 		 * allocate a large amount of memory
@@ -554,14 +532,14 @@
 
 	/* Initialize the frame format */
 	vdeb->sink_fmt = sink_fmt_default;
-	vdeb->src_code = VIMC_DEB_SRC_MBUS_FMT_DEFAULT;
 	/*
 	 * TODO: Add support for more output formats, we only support
-	 * RGB24 for now.
+	 * RGB888 for now
 	 * NOTE: the src format is always the same as the sink, except
 	 * for the code
 	 */
-	vdeb->set_rgb_src = vimc_deb_set_rgb_pix_rgb24;
+	vdeb->src_code = MEDIA_BUS_FMT_RGB888_1X24;
+	vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24;
 
 	return 0;
 }
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
index c7123a4..49ab8d9 100644
--- a/drivers/media/platform/vimc/vimc-scaler.c
+++ b/drivers/media/platform/vimc/vimc-scaler.c
@@ -25,12 +25,6 @@
 #define IS_SRC(pad)	(pad)
 #define MAX_ZOOM	8
 
-static const u32 vimc_sca_supported_pixfmt[] = {
-	V4L2_PIX_FMT_BGR24,
-	V4L2_PIX_FMT_RGB24,
-	V4L2_PIX_FMT_ARGB32,
-};
-
 struct vimc_sca_device {
 	struct vimc_ent_device ved;
 	struct v4l2_subdev sd;
@@ -53,16 +47,6 @@
 	.colorspace = V4L2_COLORSPACE_DEFAULT,
 };
 
-static bool vimc_sca_is_pixfmt_supported(u32 pixelformat)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(vimc_sca_supported_pixfmt); i++)
-		if (vimc_sca_supported_pixfmt[i] == pixelformat)
-			return true;
-	return false;
-}
-
 static int vimc_sca_init_cfg(struct v4l2_subdev *sd,
 			     struct v4l2_subdev_pad_config *cfg)
 {
@@ -82,13 +66,35 @@
 	return 0;
 }
 
+static int vimc_sca_enum_mbus_code(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_mbus_code_enum *code)
+{
+	const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
+
+	/* We don't support bayer format */
+	if (!vpix || vpix->bayer)
+		return -EINVAL;
+
+	code->code = vpix->code;
+
+	return 0;
+}
+
 static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd,
 				    struct v4l2_subdev_pad_config *cfg,
 				    struct v4l2_subdev_frame_size_enum *fse)
 {
+	const struct vimc_pix_map *vpix;
+
 	if (fse->index)
 		return -EINVAL;
 
+	/* Only accept code in the pix map table in non bayer format */
+	vpix = vimc_pix_map_by_code(fse->code);
+	if (!vpix || vpix->bayer)
+		return -EINVAL;
+
 	fse->min_width = VIMC_FRAME_MIN_WIDTH;
 	fse->min_height = VIMC_FRAME_MIN_HEIGHT;
 
@@ -125,6 +131,13 @@
 
 static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt)
 {
+	const struct vimc_pix_map *vpix;
+
+	/* Only accept code in the pix map table in non bayer format */
+	vpix = vimc_pix_map_by_code(fmt->code);
+	if (!vpix || vpix->bayer)
+		fmt->code = sink_fmt_default.code;
+
 	fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
 			     VIMC_FRAME_MAX_WIDTH) & ~1;
 	fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
@@ -143,12 +156,9 @@
 	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *sink_fmt;
 
-	if (!vimc_mbus_code_supported(fmt->format.code))
-		fmt->format.code = sink_fmt_default.code;
-
 	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
 		/* Do not change the format while stream is on */
-		if (vsca->ved.stream)
+		if (vsca->src_frame)
 			return -EBUSY;
 
 		sink_fmt = &vsca->sink_fmt;
@@ -188,7 +198,7 @@
 
 static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = {
 	.init_cfg		= vimc_sca_init_cfg,
-	.enum_mbus_code		= vimc_enum_mbus_code,
+	.enum_mbus_code		= vimc_sca_enum_mbus_code,
 	.enum_frame_size	= vimc_sca_enum_frame_size,
 	.get_fmt		= vimc_sca_get_fmt,
 	.set_fmt		= vimc_sca_set_fmt,
@@ -199,19 +209,15 @@
 	struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
 
 	if (enable) {
-		u32 pixelformat = vsca->ved.stream->producer_pixfmt;
-		const struct v4l2_format_info *pix_info;
+		const struct vimc_pix_map *vpix;
 		unsigned int frame_size;
 
-		if (!vimc_sca_is_pixfmt_supported(pixelformat)) {
-			dev_err(vsca->dev, "pixfmt (0x%08x) is not supported\n",
-				pixelformat);
-			return -EINVAL;
-		}
+		if (vsca->src_frame)
+			return 0;
 
 		/* Save the bytes per pixel of the sink */
-		pix_info = v4l2_format_info(pixelformat);
-		vsca->bpp = pix_info->bpp[0];
+		vpix = vimc_pix_map_by_code(vsca->sink_fmt.code);
+		vsca->bpp = vpix->bpp;
 
 		/* Calculate the width in bytes of the src frame */
 		vsca->src_line_size = vsca->sink_fmt.width *
@@ -324,7 +330,7 @@
 						    ved);
 
 	/* If the stream in this node is not active, just return */
-	if (!ved->stream)
+	if (!vsca->src_frame)
 		return ERR_PTR(-EINVAL);
 
 	vimc_sca_fill_src_frame(vsca, sink_frame);
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index 5135947..6c53b9f 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -55,13 +55,34 @@
 	return 0;
 }
 
+static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_pad_config *cfg,
+				   struct v4l2_subdev_mbus_code_enum *code)
+{
+	const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index);
+
+	if (!vpix)
+		return -EINVAL;
+
+	code->code = vpix->code;
+
+	return 0;
+}
+
 static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd,
 				    struct v4l2_subdev_pad_config *cfg,
 				    struct v4l2_subdev_frame_size_enum *fse)
 {
+	const struct vimc_pix_map *vpix;
+
 	if (fse->index)
 		return -EINVAL;
 
+	/* Only accept code in the pix map table */
+	vpix = vimc_pix_map_by_code(fse->code);
+	if (!vpix)
+		return -EINVAL;
+
 	fse->min_width = VIMC_FRAME_MIN_WIDTH;
 	fse->max_width = VIMC_FRAME_MAX_WIDTH;
 	fse->min_height = VIMC_FRAME_MIN_HEIGHT;
@@ -86,17 +107,14 @@
 
 static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
 {
-	u32 pixelformat = vsen->ved.stream->producer_pixfmt;
-	const struct v4l2_format_info *pix_info;
-
-	pix_info = v4l2_format_info(pixelformat);
+	const struct vimc_pix_map *vpix =
+				vimc_pix_map_by_code(vsen->mbus_format.code);
 
 	tpg_reset_source(&vsen->tpg, vsen->mbus_format.width,
 			 vsen->mbus_format.height, vsen->mbus_format.field);
-	tpg_s_bytesperline(&vsen->tpg, 0,
-			   vsen->mbus_format.width * pix_info->bpp[0]);
+	tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp);
 	tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
-	tpg_s_fourcc(&vsen->tpg, pixelformat);
+	tpg_s_fourcc(&vsen->tpg, vpix->pixelformat);
 	/* TODO: add support for V4L2_FIELD_ALTERNATE */
 	tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false);
 	tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace);
@@ -107,6 +125,13 @@
 
 static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt)
 {
+	const struct vimc_pix_map *vpix;
+
+	/* Only accept code in the pix map table */
+	vpix = vimc_pix_map_by_code(fmt->code);
+	if (!vpix)
+		fmt->code = fmt_default.code;
+
 	fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH,
 			     VIMC_FRAME_MAX_WIDTH) & ~1;
 	fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT,
@@ -126,12 +151,9 @@
 	struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
 	struct v4l2_mbus_framefmt *mf;
 
-	if (!vimc_mbus_code_supported(fmt->format.code))
-		fmt->format.code = fmt_default.code;
-
 	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
 		/* Do not change the format while stream is on */
-		if (vsen->ved.stream)
+		if (vsen->frame)
 			return -EBUSY;
 
 		mf = &vsen->mbus_format;
@@ -161,7 +183,7 @@
 
 static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
 	.init_cfg		= vimc_sen_init_cfg,
-	.enum_mbus_code		= vimc_enum_mbus_code,
+	.enum_mbus_code		= vimc_sen_enum_mbus_code,
 	.enum_frame_size	= vimc_sen_enum_frame_size,
 	.get_fmt		= vimc_sen_get_fmt,
 	.set_fmt		= vimc_sen_set_fmt,
@@ -183,13 +205,16 @@
 				container_of(sd, struct vimc_sen_device, sd);
 
 	if (enable) {
-		u32 pixelformat = vsen->ved.stream->producer_pixfmt;
-		const struct v4l2_format_info *pix_info;
+		const struct vimc_pix_map *vpix;
 		unsigned int frame_size;
 
+		if (vsen->kthread_sen)
+			/* tpg is already executing */
+			return 0;
+
 		/* Calculate the frame size */
-		pix_info = v4l2_format_info(pixelformat);
-		frame_size = vsen->mbus_format.width * pix_info->bpp[0] *
+		vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
+		frame_size = vsen->mbus_format.width * vpix->bpp *
 			     vsen->mbus_format.height;
 
 		/*
diff --git a/drivers/media/platform/vimc/vimc-streamer.c b/drivers/media/platform/vimc/vimc-streamer.c
index 3b3f363..048d770 100644
--- a/drivers/media/platform/vimc/vimc-streamer.c
+++ b/drivers/media/platform/vimc/vimc-streamer.c
@@ -20,6 +20,8 @@
  *
  * Helper function that returns the media entity containing the source pad
  * linked with the first sink pad from the given media entity pad list.
+ *
+ * Return: The source pad or NULL, if it wasn't found.
  */
 static struct media_entity *vimc_get_source_entity(struct media_entity *ent)
 {
@@ -35,7 +37,7 @@
 	return NULL;
 }
 
-/*
+/**
  * vimc_streamer_pipeline_terminate - Disable stream in all ved in stream
  *
  * @stream: the pointer to the stream structure with the pipeline to be
@@ -52,7 +54,6 @@
 	while (stream->pipe_size) {
 		stream->pipe_size--;
 		ved = stream->ved_pipeline[stream->pipe_size];
-		ved->stream = NULL;
 		stream->ved_pipeline[stream->pipe_size] = NULL;
 
 		if (!is_media_entity_v4l2_subdev(ved->ent))
@@ -63,15 +64,18 @@
 	}
 }
 
-/*
- * vimc_streamer_pipeline_init - initializes the stream structure
+/**
+ * vimc_streamer_pipeline_init - Initializes the stream structure
  *
  * @stream: the pointer to the stream structure to be initialized
  * @ved:    the pointer to the vimc entity initializing the stream
  *
  * Initializes the stream structure. Walks through the entity graph to
  * construct the pipeline used later on the streamer thread.
- * Calls s_stream to enable stream in all entities of the pipeline.
+ * Calls vimc_streamer_s_stream() to enable stream in all entities of
+ * the pipeline.
+ *
+ * Return: 0 if success, error code otherwise.
  */
 static int vimc_streamer_pipeline_init(struct vimc_stream *stream,
 				       struct vimc_ent_device *ved)
@@ -88,7 +92,6 @@
 			return -EINVAL;
 		}
 		stream->ved_pipeline[stream->pipe_size++] = ved;
-		ved->stream = stream;
 
 		if (is_media_entity_v4l2_subdev(ved->ent)) {
 			sd = media_entity_to_v4l2_subdev(ved->ent);
@@ -122,13 +125,17 @@
 	return -EINVAL;
 }
 
-/*
- * vimc_streamer_thread - process frames through the pipeline
+/**
+ * vimc_streamer_thread - Process frames through the pipeline
  *
  * @data:	vimc_stream struct of the current stream
  *
  * From the source to the sink, gets a frame from each subdevice and send to
  * the next one of the pipeline at a fixed framerate.
+ *
+ * Return:
+ * Always zero (created as ``int`` instead of ``void`` to comply with
+ * kthread API).
  */
 static int vimc_streamer_thread(void *data)
 {
@@ -157,19 +164,20 @@
 	return 0;
 }
 
-/*
- * vimc_streamer_s_stream - start/stop the streaming on the media pipeline
+/**
+ * vimc_streamer_s_stream - Start/stop the streaming on the media pipeline
  *
  * @stream:	the pointer to the stream structure of the current stream
  * @ved:	pointer to the vimc entity of the entity of the stream
  * @enable:	flag to determine if stream should start/stop
  *
- * When starting, check if there is no stream->kthread allocated. This should
- * indicate that a stream is already running. Then, it initializes
- * the pipeline, creates and runs a kthread to consume buffers through the
- * pipeline.
- * When stopping, analogously check if there is a stream running, stop
- * the thread and terminates the pipeline.
+ * When starting, check if there is no ``stream->kthread`` allocated. This
+ * should indicate that a stream is already running. Then, it initializes the
+ * pipeline, creates and runs a kthread to consume buffers through the pipeline.
+ * When stopping, analogously check if there is a stream running, stop the
+ * thread and terminates the pipeline.
+ *
+ * Return: 0 if success, error code otherwise.
  */
 int vimc_streamer_s_stream(struct vimc_stream *stream,
 			   struct vimc_ent_device *ved,
diff --git a/drivers/media/platform/vimc/vimc-streamer.h b/drivers/media/platform/vimc/vimc-streamer.h
index 2b36674..fe3c51f 100644
--- a/drivers/media/platform/vimc/vimc-streamer.h
+++ b/drivers/media/platform/vimc/vimc-streamer.h
@@ -25,11 +25,6 @@
  * processed in the pipeline.
  * @pipe_size:		size of @ved_pipeline
  * @kthread:		thread that generates the frames of the stream.
- * @producer_pixfmt:	the pixel format requested from the pipeline. This must
- * be set just before calling vimc_streamer_s_stream(ent, 1). This value is
- * propagated up to the source of the base image (usually a sensor node) and
- * can be modified by entities during s_stream callback to request a different
- * format from rest of the pipeline.
  *
  * When the user call stream_on in a video device, struct vimc_stream is
  * used to keep track of all entities and subdevices that generates and
@@ -40,17 +35,8 @@
 	struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE];
 	unsigned int pipe_size;
 	struct task_struct *kthread;
-	u32 producer_pixfmt;
 };
 
-/**
- * vimc_streamer_s_streamer - start/stop the stream
- *
- * @stream:	the pointer to the stream to start or stop
- * @ved:	The last entity of the streamer pipeline
- * @enable:	any non-zero number start the stream, zero stop
- *
- */
 int vimc_streamer_s_stream(struct vimc_stream *stream,
 			   struct vimc_ent_device *ved,
 			   int enable);
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index d535aac..53315c8 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -792,7 +792,7 @@
 	if (no_error_inj && ccs_cap == -1)
 		ccs_cap = 7;
 
-	/* if ccs_cap == -1, then the use can select it using controls */
+	/* if ccs_cap == -1, then the user can select it using controls */
 	if (ccs_cap != -1) {
 		dev->has_crop_cap = ccs_cap & 1;
 		dev->has_compose_cap = ccs_cap & 2;
@@ -807,7 +807,7 @@
 	if (no_error_inj && ccs_out == -1)
 		ccs_out = 7;
 
-	/* if ccs_out == -1, then the use can select it using controls */
+	/* if ccs_out == -1, then the user can select it using controls */
 	if (ccs_out != -1) {
 		dev->has_crop_out = ccs_out & 1;
 		dev->has_compose_out = ccs_out & 2;
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
index 3e916c8..cb19a9a 100644
--- a/drivers/media/platform/vivid/vivid-ctrls.c
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
@@ -1473,7 +1473,7 @@
 	v4l2_ctrl_handler_init(hdl_vid_cap, 55);
 	v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL);
 	v4l2_ctrl_handler_init(hdl_vid_out, 26);
-	if (!no_error_inj || dev->has_fb)
+	if (!no_error_inj || dev->has_fb || dev->num_hdmi_outputs)
 		v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL);
 	v4l2_ctrl_handler_init(hdl_vbi_cap, 21);
 	v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL);
@@ -1613,6 +1613,8 @@
 	}
 
 	if (dev->num_hdmi_inputs) {
+		s64 hdmi_input_mask = GENMASK(dev->num_hdmi_inputs - 1, 0);
+
 		dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap,
 					&vivid_ctrl_dv_timings_signal_mode, NULL);
 
@@ -1633,12 +1635,13 @@
 			V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
 			0, V4L2_DV_RGB_RANGE_AUTO);
 		dev->ctrl_rx_power_present = v4l2_ctrl_new_std(hdl_vid_cap,
-			NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0,
-			(2 << (dev->num_hdmi_inputs - 1)) - 1, 0,
-			(2 << (dev->num_hdmi_inputs - 1)) - 1);
+			NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, hdmi_input_mask,
+			0, hdmi_input_mask);
 
 	}
 	if (dev->num_hdmi_outputs) {
+		s64 hdmi_output_mask = GENMASK(dev->num_hdmi_outputs - 1, 0);
+
 		/*
 		 * We aren't doing anything with this at the moment, but
 		 * HDMI outputs typically have this controls.
@@ -1652,17 +1655,14 @@
 		dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out,
 			&vivid_ctrl_display_present, NULL);
 		dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out,
-			NULL, V4L2_CID_DV_TX_HOTPLUG, 0,
-			(2 << (dev->num_hdmi_outputs - 1)) - 1, 0,
-			(2 << (dev->num_hdmi_outputs - 1)) - 1);
+			NULL, V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask,
+			0, hdmi_output_mask);
 		dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out,
-			NULL, V4L2_CID_DV_TX_RXSENSE, 0,
-			(2 << (dev->num_hdmi_outputs - 1)) - 1, 0,
-			(2 << (dev->num_hdmi_outputs - 1)) - 1);
+			NULL, V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask,
+			0, hdmi_output_mask);
 		dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out,
-			NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0,
-			(2 << (dev->num_hdmi_outputs - 1)) - 1, 0,
-			(2 << (dev->num_hdmi_outputs - 1)) - 1);
+			NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask,
+			0, hdmi_output_mask);
 	}
 	if ((dev->has_vid_cap && dev->has_vid_out) ||
 	    (dev->has_vbi_cap && dev->has_vbi_out))
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
index 6cf495a..003319d 100644
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
@@ -232,8 +232,8 @@
 	return vbuf;
 }
 
-static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
-		struct vivid_buffer *vid_cap_buf)
+static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, unsigned p,
+		u8 *vcapbuf, struct vivid_buffer *vid_cap_buf)
 {
 	bool blank = dev->must_blank[vid_cap_buf->vb.vb2_buf.index];
 	struct tpg_data *tpg = &dev->tpg;
@@ -658,6 +658,8 @@
 	u64 f_period;
 
 	f_period = (u64)dev->timeperframe_vid_cap.numerator * 1000000000;
+	if (WARN_ON(dev->timeperframe_vid_cap.denominator == 0))
+		dev->timeperframe_vid_cap.denominator = 1;
 	do_div(f_period, dev->timeperframe_vid_cap.denominator);
 	if (dev->field_cap == V4L2_FIELD_ALTERNATE)
 		f_period >>= 1;
@@ -670,7 +672,8 @@
 	dev->cap_frame_period = f_period;
 }
 
-static void vivid_thread_vid_cap_tick(struct vivid_dev *dev, int dropped_bufs)
+static noinline_for_stack void vivid_thread_vid_cap_tick(struct vivid_dev *dev,
+							 int dropped_bufs)
 {
 	struct vivid_buffer *vid_cap_buf = NULL;
 	struct vivid_buffer *vbi_cap_buf = NULL;
diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c
index 1f33eb1..8665dfd 100644
--- a/drivers/media/platform/vivid/vivid-vid-common.c
+++ b/drivers/media/platform/vivid/vivid-vid-common.c
@@ -262,21 +262,66 @@
 		.can_do_overlay = true,
 	},
 	{
-		.fourcc   = V4L2_PIX_FMT_RGB444, /* xxxxrrrr ggggbbbb */
+		.fourcc   = V4L2_PIX_FMT_RGB444, /* ggggbbbb xxxxrrrr */
 		.vdownsampling = { 1 },
 		.bit_depth = { 16 },
 		.planes   = 1,
 		.buffers = 1,
 	},
 	{
-		.fourcc   = V4L2_PIX_FMT_XRGB444, /* xxxxrrrr ggggbbbb */
+		.fourcc   = V4L2_PIX_FMT_XRGB444, /* ggggbbbb xxxxrrrr */
 		.vdownsampling = { 1 },
 		.bit_depth = { 16 },
 		.planes   = 1,
 		.buffers = 1,
 	},
 	{
-		.fourcc   = V4L2_PIX_FMT_ARGB444, /* aaaarrrr ggggbbbb */
+		.fourcc   = V4L2_PIX_FMT_ARGB444, /* ggggbbbb aaaarrrr */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x00f0,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGBX444, /* bbbbxxxx rrrrgggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGBA444, /* bbbbaaaa rrrrgggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x00f0,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XBGR444, /* ggggrrrr xxxxbbbb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_ABGR444, /* ggggrrrr aaaabbbb */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x00f0,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRX444, /* rrrrxxxx bbbbgggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRA444, /* rrrraaaa bbbbgggg  */
 		.vdownsampling = { 1 },
 		.bit_depth = { 16 },
 		.planes   = 1,
@@ -309,6 +354,57 @@
 		.alpha_mask = 0x8000,
 	},
 	{
+		.fourcc   = V4L2_PIX_FMT_RGBX555, /* ggbbbbbx rrrrrggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGBA555, /* ggbbbbba rrrrrggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+		.alpha_mask = 0x8000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_XBGR555, /* gggrrrrr xbbbbbgg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_ABGR555, /* gggrrrrr abbbbbgg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+		.alpha_mask = 0x8000,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRX555, /* ggrrrrrx bbbbbggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRA555, /* ggrrrrra bbbbbggg */
+		.vdownsampling = { 1 },
+		.bit_depth = { 16 },
+		.planes   = 1,
+		.buffers = 1,
+		.can_do_overlay = true,
+		.alpha_mask = 0x8000,
+	},
+	{
 		.fourcc   = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */
 		.vdownsampling = { 1 },
 		.bit_depth = { 16 },
@@ -396,6 +492,36 @@
 		.alpha_mask = 0xff000000,
 	},
 	{
+		.fourcc   = V4L2_PIX_FMT_RGBX32, /* rgbx */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRX32, /* xbgr */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_RGBA32, /* rgba */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0x000000ff,
+	},
+	{
+		.fourcc   = V4L2_PIX_FMT_BGRA32, /* abgr */
+		.vdownsampling = { 1 },
+		.bit_depth = { 32 },
+		.planes   = 1,
+		.buffers = 1,
+		.alpha_mask = 0xff000000,
+	},
+	{
 		.fourcc   = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */
 		.vdownsampling = { 1 },
 		.bit_depth = { 8 },
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 104b6f5..d7b43037 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -557,8 +557,10 @@
 
 	/* Get a default body for our list. */
 	dl->body0 = vsp1_dl_body_get(dlm->pool);
-	if (!dl->body0)
+	if (!dl->body0) {
+		kfree(dl);
 		return NULL;
+	}
 
 	header_offset = dl->body0->max_entries * sizeof(*dl->body0->entries);
 
diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c
index 8b01e99..30d751f 100644
--- a/drivers/media/platform/vsp1/vsp1_histo.c
+++ b/drivers/media/platform/vsp1/vsp1_histo.c
@@ -426,8 +426,6 @@
 			  | V4L2_CAP_VIDEO_CAPTURE_MPLANE
 			  | V4L2_CAP_VIDEO_OUTPUT_MPLANE
 			  | V4L2_CAP_META_CAPTURE;
-	cap->device_caps = V4L2_CAP_META_CAPTURE
-			 | V4L2_CAP_STREAMING;
 
 	strscpy(cap->driver, "vsp1", sizeof(cap->driver));
 	strscpy(cap->card, histo->video.name, sizeof(cap->card));
@@ -556,6 +554,7 @@
 	histo->video.vfl_type = VFL_TYPE_GRABBER;
 	histo->video.release = video_device_release_empty;
 	histo->video.ioctl_ops = &histo_v4l2_ioctl_ops;
+	histo->video.device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
 
 	video_set_drvdata(&histo->video, histo);
 
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 1bb1d39..5c67ff9 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -15,8 +15,8 @@
  */
 
 #define VI6_CMD(n)			(0x0000 + (n) * 4)
-#define VI6_CMD_UPDHDR			(1 << 4)
-#define VI6_CMD_STRCMD			(1 << 0)
+#define VI6_CMD_UPDHDR			BIT(4)
+#define VI6_CMD_STRCMD			BIT(0)
 
 #define VI6_CLK_DCSWT			0x0018
 #define VI6_CLK_DCSWT_CSTPW_MASK	(0xff << 8)
@@ -25,29 +25,29 @@
 #define VI6_CLK_DCSWT_CSTRW_SHIFT	0
 
 #define VI6_SRESET			0x0028
-#define VI6_SRESET_SRTS(n)		(1 << (n))
+#define VI6_SRESET_SRTS(n)		BIT(n)
 
 #define VI6_STATUS			0x0038
-#define VI6_STATUS_FLD_STD(n)		(1 << ((n) + 28))
-#define VI6_STATUS_SYS_ACT(n)		(1 << ((n) + 8))
+#define VI6_STATUS_FLD_STD(n)		BIT((n) + 28)
+#define VI6_STATUS_SYS_ACT(n)		BIT((n) + 8)
 
 #define VI6_WPF_IRQ_ENB(n)		(0x0048 + (n) * 12)
-#define VI6_WFP_IRQ_ENB_DFEE		(1 << 1)
-#define VI6_WFP_IRQ_ENB_FREE		(1 << 0)
+#define VI6_WFP_IRQ_ENB_DFEE		BIT(1)
+#define VI6_WFP_IRQ_ENB_FREE		BIT(0)
 
 #define VI6_WPF_IRQ_STA(n)		(0x004c + (n) * 12)
-#define VI6_WFP_IRQ_STA_DFE		(1 << 1)
-#define VI6_WFP_IRQ_STA_FRE		(1 << 0)
+#define VI6_WFP_IRQ_STA_DFE		BIT(1)
+#define VI6_WFP_IRQ_STA_FRE		BIT(0)
 
 #define VI6_DISP_IRQ_ENB(n)		(0x0078 + (n) * 60)
-#define VI6_DISP_IRQ_ENB_DSTE		(1 << 8)
-#define VI6_DISP_IRQ_ENB_MAEE		(1 << 5)
-#define VI6_DISP_IRQ_ENB_LNEE(n)	(1 << (n))
+#define VI6_DISP_IRQ_ENB_DSTE		BIT(8)
+#define VI6_DISP_IRQ_ENB_MAEE		BIT(5)
+#define VI6_DISP_IRQ_ENB_LNEE(n)	BIT(n)
 
 #define VI6_DISP_IRQ_STA(n)		(0x007c + (n) * 60)
-#define VI6_DISP_IRQ_STA_DST		(1 << 8)
-#define VI6_DISP_IRQ_STA_MAE		(1 << 5)
-#define VI6_DISP_IRQ_STA_LNE(n)		(1 << (n))
+#define VI6_DISP_IRQ_STA_DST		BIT(8)
+#define VI6_DISP_IRQ_STA_MAE		BIT(5)
+#define VI6_DISP_IRQ_STA_LNE(n)		BIT(n)
 
 #define VI6_WPF_LINE_COUNT(n)		(0x0084 + (n) * 4)
 #define VI6_WPF_LINE_COUNT_MASK		(0x1fffff << 0)
@@ -59,32 +59,32 @@
 #define VI6_DL_CTRL			0x0100
 #define VI6_DL_CTRL_AR_WAIT_MASK	(0xffff << 16)
 #define VI6_DL_CTRL_AR_WAIT_SHIFT	16
-#define VI6_DL_CTRL_DC2			(1 << 12)
-#define VI6_DL_CTRL_DC1			(1 << 8)
-#define VI6_DL_CTRL_DC0			(1 << 4)
-#define VI6_DL_CTRL_CFM0		(1 << 2)
-#define VI6_DL_CTRL_NH0			(1 << 1)
-#define VI6_DL_CTRL_DLE			(1 << 0)
+#define VI6_DL_CTRL_DC2			BIT(12)
+#define VI6_DL_CTRL_DC1			BIT(8)
+#define VI6_DL_CTRL_DC0			BIT(4)
+#define VI6_DL_CTRL_CFM0		BIT(2)
+#define VI6_DL_CTRL_NH0			BIT(1)
+#define VI6_DL_CTRL_DLE			BIT(0)
 
 #define VI6_DL_HDR_ADDR(n)		(0x0104 + (n) * 4)
 
 #define VI6_DL_SWAP			0x0114
-#define VI6_DL_SWAP_LWS			(1 << 2)
-#define VI6_DL_SWAP_WDS			(1 << 1)
-#define VI6_DL_SWAP_BTS			(1 << 0)
+#define VI6_DL_SWAP_LWS			BIT(2)
+#define VI6_DL_SWAP_WDS			BIT(1)
+#define VI6_DL_SWAP_BTS			BIT(0)
 
 #define VI6_DL_EXT_CTRL(n)		(0x011c + (n) * 36)
-#define VI6_DL_EXT_CTRL_NWE		(1 << 16)
+#define VI6_DL_EXT_CTRL_NWE		BIT(16)
 #define VI6_DL_EXT_CTRL_POLINT_MASK	(0x3f << 8)
 #define VI6_DL_EXT_CTRL_POLINT_SHIFT	8
-#define VI6_DL_EXT_CTRL_DLPRI		(1 << 5)
-#define VI6_DL_EXT_CTRL_EXPRI		(1 << 4)
-#define VI6_DL_EXT_CTRL_EXT		(1 << 0)
+#define VI6_DL_EXT_CTRL_DLPRI		BIT(5)
+#define VI6_DL_EXT_CTRL_EXPRI		BIT(4)
+#define VI6_DL_EXT_CTRL_EXT		BIT(0)
 
 #define VI6_DL_EXT_AUTOFLD_INT		BIT(0)
 
 #define VI6_DL_BODY_SIZE		0x0120
-#define VI6_DL_BODY_SIZE_UPD		(1 << 24)
+#define VI6_DL_BODY_SIZE_UPD		BIT(24)
 #define VI6_DL_BODY_SIZE_BS_MASK	(0x1ffff << 0)
 #define VI6_DL_BODY_SIZE_BS_SHIFT	0
 
@@ -107,10 +107,10 @@
 #define VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT	0
 
 #define VI6_RPF_INFMT			0x0308
-#define VI6_RPF_INFMT_VIR		(1 << 28)
-#define VI6_RPF_INFMT_CIPM		(1 << 16)
-#define VI6_RPF_INFMT_SPYCS		(1 << 15)
-#define VI6_RPF_INFMT_SPUVS		(1 << 14)
+#define VI6_RPF_INFMT_VIR		BIT(28)
+#define VI6_RPF_INFMT_CIPM		BIT(16)
+#define VI6_RPF_INFMT_SPYCS		BIT(15)
+#define VI6_RPF_INFMT_SPUVS		BIT(14)
 #define VI6_RPF_INFMT_CEXT_ZERO		(0 << 12)
 #define VI6_RPF_INFMT_CEXT_EXT		(1 << 12)
 #define VI6_RPF_INFMT_CEXT_ONE		(2 << 12)
@@ -120,19 +120,19 @@
 #define VI6_RPF_INFMT_RDTM_BT709	(2 << 9)
 #define VI6_RPF_INFMT_RDTM_BT709_EXT	(3 << 9)
 #define VI6_RPF_INFMT_RDTM_MASK		(7 << 9)
-#define VI6_RPF_INFMT_CSC		(1 << 8)
+#define VI6_RPF_INFMT_CSC		BIT(8)
 #define VI6_RPF_INFMT_RDFMT_MASK	(0x7f << 0)
 #define VI6_RPF_INFMT_RDFMT_SHIFT	0
 
 #define VI6_RPF_DSWAP			0x030c
-#define VI6_RPF_DSWAP_A_LLS		(1 << 11)
-#define VI6_RPF_DSWAP_A_LWS		(1 << 10)
-#define VI6_RPF_DSWAP_A_WDS		(1 << 9)
-#define VI6_RPF_DSWAP_A_BTS		(1 << 8)
-#define VI6_RPF_DSWAP_P_LLS		(1 << 3)
-#define VI6_RPF_DSWAP_P_LWS		(1 << 2)
-#define VI6_RPF_DSWAP_P_WDS		(1 << 1)
-#define VI6_RPF_DSWAP_P_BTS		(1 << 0)
+#define VI6_RPF_DSWAP_A_LLS		BIT(11)
+#define VI6_RPF_DSWAP_A_LWS		BIT(10)
+#define VI6_RPF_DSWAP_A_WDS		BIT(9)
+#define VI6_RPF_DSWAP_A_BTS		BIT(8)
+#define VI6_RPF_DSWAP_P_LLS		BIT(3)
+#define VI6_RPF_DSWAP_P_LWS		BIT(2)
+#define VI6_RPF_DSWAP_P_WDS		BIT(1)
+#define VI6_RPF_DSWAP_P_BTS		BIT(0)
 
 #define VI6_RPF_LOC			0x0310
 #define VI6_RPF_LOC_HCOORD_MASK		(0x1fff << 16)
@@ -150,7 +150,7 @@
 #define VI6_RPF_ALPH_SEL_ASEL_SHIFT	28
 #define VI6_RPF_ALPH_SEL_IROP_MASK	(0xf << 24)
 #define VI6_RPF_ALPH_SEL_IROP_SHIFT	24
-#define VI6_RPF_ALPH_SEL_BSEL		(1 << 23)
+#define VI6_RPF_ALPH_SEL_BSEL		BIT(23)
 #define VI6_RPF_ALPH_SEL_AEXT_ZERO	(0 << 18)
 #define VI6_RPF_ALPH_SEL_AEXT_EXT	(1 << 18)
 #define VI6_RPF_ALPH_SEL_AEXT_ONE	(2 << 18)
@@ -171,7 +171,7 @@
 #define VI6_RPF_VRTCOL_SET_LAYB_SHIFT	0
 
 #define VI6_RPF_MSK_CTRL		0x031c
-#define VI6_RPF_MSK_CTRL_MSK_EN		(1 << 24)
+#define VI6_RPF_MSK_CTRL_MSK_EN		BIT(24)
 #define VI6_RPF_MSK_CTRL_MGR_MASK	(0xff << 16)
 #define VI6_RPF_MSK_CTRL_MGR_SHIFT	16
 #define VI6_RPF_MSK_CTRL_MGG_MASK	(0xff << 8)
@@ -191,9 +191,9 @@
 #define VI6_RPF_MSK_SET_MSB_SHIFT	0
 
 #define VI6_RPF_CKEY_CTRL		0x0328
-#define VI6_RPF_CKEY_CTRL_CV		(1 << 4)
-#define VI6_RPF_CKEY_CTRL_SAPE1		(1 << 1)
-#define VI6_RPF_CKEY_CTRL_SAPE0		(1 << 0)
+#define VI6_RPF_CKEY_CTRL_CV		BIT(4)
+#define VI6_RPF_CKEY_CTRL_SAPE1		BIT(1)
+#define VI6_RPF_CKEY_CTRL_SAPE0		BIT(0)
 
 #define VI6_RPF_CKEY_SET0		0x032c
 #define VI6_RPF_CKEY_SET1		0x0330
@@ -250,7 +250,7 @@
 
 #define VI6_WPF_HSZCLIP			0x1004
 #define VI6_WPF_VSZCLIP			0x1008
-#define VI6_WPF_SZCLIP_EN		(1 << 28)
+#define VI6_WPF_SZCLIP_EN		BIT(28)
 #define VI6_WPF_SZCLIP_OFST_MASK	(0xff << 16)
 #define VI6_WPF_SZCLIP_OFST_SHIFT	16
 #define VI6_WPF_SZCLIP_SIZE_MASK	(0xfff << 0)
@@ -259,12 +259,12 @@
 #define VI6_WPF_OUTFMT			0x100c
 #define VI6_WPF_OUTFMT_PDV_MASK		(0xff << 24)
 #define VI6_WPF_OUTFMT_PDV_SHIFT	24
-#define VI6_WPF_OUTFMT_PXA		(1 << 23)
-#define VI6_WPF_OUTFMT_ROT		(1 << 18)
-#define VI6_WPF_OUTFMT_HFLP		(1 << 17)
-#define VI6_WPF_OUTFMT_FLP		(1 << 16)
-#define VI6_WPF_OUTFMT_SPYCS		(1 << 15)
-#define VI6_WPF_OUTFMT_SPUVS		(1 << 14)
+#define VI6_WPF_OUTFMT_PXA		BIT(23)
+#define VI6_WPF_OUTFMT_ROT		BIT(18)
+#define VI6_WPF_OUTFMT_HFLP		BIT(17)
+#define VI6_WPF_OUTFMT_FLP		BIT(16)
+#define VI6_WPF_OUTFMT_SPYCS		BIT(15)
+#define VI6_WPF_OUTFMT_SPUVS		BIT(14)
 #define VI6_WPF_OUTFMT_DITH_DIS		(0 << 12)
 #define VI6_WPF_OUTFMT_DITH_EN		(3 << 12)
 #define VI6_WPF_OUTFMT_DITH_MASK	(3 << 12)
@@ -273,18 +273,18 @@
 #define VI6_WPF_OUTFMT_WRTM_BT709	(2 << 9)
 #define VI6_WPF_OUTFMT_WRTM_BT709_EXT	(3 << 9)
 #define VI6_WPF_OUTFMT_WRTM_MASK	(7 << 9)
-#define VI6_WPF_OUTFMT_CSC		(1 << 8)
+#define VI6_WPF_OUTFMT_CSC		BIT(8)
 #define VI6_WPF_OUTFMT_WRFMT_MASK	(0x7f << 0)
 #define VI6_WPF_OUTFMT_WRFMT_SHIFT	0
 
 #define VI6_WPF_DSWAP			0x1010
-#define VI6_WPF_DSWAP_P_LLS		(1 << 3)
-#define VI6_WPF_DSWAP_P_LWS		(1 << 2)
-#define VI6_WPF_DSWAP_P_WDS		(1 << 1)
-#define VI6_WPF_DSWAP_P_BTS		(1 << 0)
+#define VI6_WPF_DSWAP_P_LLS		BIT(3)
+#define VI6_WPF_DSWAP_P_LWS		BIT(2)
+#define VI6_WPF_DSWAP_P_WDS		BIT(1)
+#define VI6_WPF_DSWAP_P_BTS		BIT(0)
 
 #define VI6_WPF_RNDCTRL			0x1014
-#define VI6_WPF_RNDCTRL_CBRM		(1 << 28)
+#define VI6_WPF_RNDCTRL_CBRM		BIT(28)
 #define VI6_WPF_RNDCTRL_ABRM_TRUNC	(0 << 24)
 #define VI6_WPF_RNDCTRL_ABRM_ROUND	(1 << 24)
 #define VI6_WPF_RNDCTRL_ABRM_THRESH	(2 << 24)
@@ -297,7 +297,7 @@
 #define VI6_WPF_RNDCTRL_CLMD_MASK	(3 << 12)
 
 #define VI6_WPF_ROT_CTRL		0x1018
-#define VI6_WPF_ROT_CTRL_LN16		(1 << 17)
+#define VI6_WPF_ROT_CTRL_LN16		BIT(17)
 #define VI6_WPF_ROT_CTRL_LMEM_WD_MASK	(0x1fff << 0)
 #define VI6_WPF_ROT_CTRL_LMEM_WD_SHIFT	0
 
@@ -308,7 +308,7 @@
 #define VI6_WPF_DSTM_ADDR_C1		0x102c
 
 #define VI6_WPF_WRBCK_CTRL(n)		(0x1034 + (n) * 0x100)
-#define VI6_WPF_WRBCK_CTRL_WBMD		(1 << 0)
+#define VI6_WPF_WRBCK_CTRL_WBMD		BIT(0)
 
 /* -----------------------------------------------------------------------------
  * UIF Control Registers
@@ -317,20 +317,20 @@
 #define VI6_UIF_OFFSET			0x100
 
 #define VI6_UIF_DISCOM_DOCMCR		0x1c00
-#define VI6_UIF_DISCOM_DOCMCR_CMPRU	(1 << 16)
-#define VI6_UIF_DISCOM_DOCMCR_CMPR	(1 << 0)
+#define VI6_UIF_DISCOM_DOCMCR_CMPRU	BIT(16)
+#define VI6_UIF_DISCOM_DOCMCR_CMPR	BIT(0)
 
 #define VI6_UIF_DISCOM_DOCMSTR		0x1c04
-#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE	(1 << 1)
-#define VI6_UIF_DISCOM_DOCMSTR_CMPST	(1 << 0)
+#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE	BIT(1)
+#define VI6_UIF_DISCOM_DOCMSTR_CMPST	BIT(0)
 
 #define VI6_UIF_DISCOM_DOCMCLSTR	0x1c08
-#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE	(1 << 1)
-#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST	(1 << 0)
+#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE	BIT(1)
+#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST	BIT(0)
 
 #define VI6_UIF_DISCOM_DOCMIENR		0x1c0c
-#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN	(1 << 1)
-#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN		(1 << 0)
+#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN	BIT(1)
+#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN		BIT(0)
 
 #define VI6_UIF_DISCOM_DOCMMDR		0x1c10
 #define VI6_UIF_DISCOM_DOCMMDR_INTHRH(n)	((n) << 16)
@@ -338,7 +338,7 @@
 #define VI6_UIF_DISCOM_DOCMPMR		0x1c14
 #define VI6_UIF_DISCOM_DOCMPMR_CMPDFF(n)	((n) << 17)
 #define VI6_UIF_DISCOM_DOCMPMR_CMPDFA(n)	((n) << 8)
-#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF		(1 << 7)
+#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF		BIT(7)
 #define VI6_UIF_DISCOM_DOCMPMR_SEL(n)		((n) << 0)
 
 #define VI6_UIF_DISCOM_DOCMECRCR	0x1c18
@@ -365,7 +365,7 @@
 #define VI6_DPR_HSI_ROUTE		0x2048
 #define VI6_DPR_BRU_ROUTE		0x204c
 #define VI6_DPR_ILV_BRS_ROUTE		0x2050
-#define VI6_DPR_ROUTE_BRSSEL		(1 << 28)
+#define VI6_DPR_ROUTE_BRSSEL		BIT(28)
 #define VI6_DPR_ROUTE_FXA_MASK		(0xff << 16)
 #define VI6_DPR_ROUTE_FXA_SHIFT		16
 #define VI6_DPR_ROUTE_FP_MASK		(0x3f << 8)
@@ -407,10 +407,10 @@
 #define VI6_SRU_CTRL0_PARAM1_MASK	(0x1f << 8)
 #define VI6_SRU_CTRL0_PARAM1_SHIFT	8
 #define VI6_SRU_CTRL0_MODE_UPSCALE	(4 << 4)
-#define VI6_SRU_CTRL0_PARAM2		(1 << 3)
-#define VI6_SRU_CTRL0_PARAM3		(1 << 2)
-#define VI6_SRU_CTRL0_PARAM4		(1 << 1)
-#define VI6_SRU_CTRL0_EN		(1 << 0)
+#define VI6_SRU_CTRL0_PARAM2		BIT(3)
+#define VI6_SRU_CTRL0_PARAM3		BIT(2)
+#define VI6_SRU_CTRL0_PARAM4		BIT(1)
+#define VI6_SRU_CTRL0_EN		BIT(0)
 
 #define VI6_SRU_CTRL1			0x2204
 #define VI6_SRU_CTRL1_PARAM5		0x7ff
@@ -427,18 +427,18 @@
 #define VI6_UDS_OFFSET			0x100
 
 #define VI6_UDS_CTRL			0x2300
-#define VI6_UDS_CTRL_AMD		(1 << 30)
-#define VI6_UDS_CTRL_FMD		(1 << 29)
-#define VI6_UDS_CTRL_BLADV		(1 << 28)
-#define VI6_UDS_CTRL_AON		(1 << 25)
-#define VI6_UDS_CTRL_ATHON		(1 << 24)
-#define VI6_UDS_CTRL_BC			(1 << 20)
-#define VI6_UDS_CTRL_NE_A		(1 << 19)
-#define VI6_UDS_CTRL_NE_RCR		(1 << 18)
-#define VI6_UDS_CTRL_NE_GY		(1 << 17)
-#define VI6_UDS_CTRL_NE_BCB		(1 << 16)
-#define VI6_UDS_CTRL_AMDSLH		(1 << 2)
-#define VI6_UDS_CTRL_TDIPC		(1 << 1)
+#define VI6_UDS_CTRL_AMD		BIT(30)
+#define VI6_UDS_CTRL_FMD		BIT(29)
+#define VI6_UDS_CTRL_BLADV		BIT(28)
+#define VI6_UDS_CTRL_AON		BIT(25)
+#define VI6_UDS_CTRL_ATHON		BIT(24)
+#define VI6_UDS_CTRL_BC			BIT(20)
+#define VI6_UDS_CTRL_NE_A		BIT(19)
+#define VI6_UDS_CTRL_NE_RCR		BIT(18)
+#define VI6_UDS_CTRL_NE_GY		BIT(17)
+#define VI6_UDS_CTRL_NE_BCB		BIT(16)
+#define VI6_UDS_CTRL_AMDSLH		BIT(2)
+#define VI6_UDS_CTRL_TDIPC		BIT(1)
 
 #define VI6_UDS_SCALE			0x2304
 #define VI6_UDS_SCALE_HMANT_MASK	(0xf << 28)
@@ -477,12 +477,12 @@
 #define VI6_UDS_HPHASE_HEDP_SHIFT	0
 
 #define VI6_UDS_IPC			0x2318
-#define VI6_UDS_IPC_FIELD		(1 << 27)
+#define VI6_UDS_IPC_FIELD		BIT(27)
 #define VI6_UDS_IPC_VEDP_MASK		(0xfff << 0)
 #define VI6_UDS_IPC_VEDP_SHIFT		0
 
 #define VI6_UDS_HSZCLIP			0x231c
-#define VI6_UDS_HSZCLIP_HCEN		(1 << 28)
+#define VI6_UDS_HSZCLIP_HCEN		BIT(28)
 #define VI6_UDS_HSZCLIP_HCL_OFST_MASK	(0xff << 16)
 #define VI6_UDS_HSZCLIP_HCL_OFST_SHIFT	16
 #define VI6_UDS_HSZCLIP_HCL_SIZE_MASK	(0x1fff << 0)
@@ -507,36 +507,36 @@
  */
 
 #define VI6_LUT_CTRL			0x2800
-#define VI6_LUT_CTRL_EN			(1 << 0)
+#define VI6_LUT_CTRL_EN			BIT(0)
 
 /* -----------------------------------------------------------------------------
  * CLU Control Registers
  */
 
 #define VI6_CLU_CTRL			0x2900
-#define VI6_CLU_CTRL_AAI		(1 << 28)
-#define VI6_CLU_CTRL_MVS		(1 << 24)
+#define VI6_CLU_CTRL_AAI		BIT(28)
+#define VI6_CLU_CTRL_MVS		BIT(24)
 #define VI6_CLU_CTRL_AX1I_2D		(3 << 14)
 #define VI6_CLU_CTRL_AX2I_2D		(1 << 12)
 #define VI6_CLU_CTRL_OS0_2D		(3 << 8)
 #define VI6_CLU_CTRL_OS1_2D		(1 << 6)
 #define VI6_CLU_CTRL_OS2_2D		(3 << 4)
-#define VI6_CLU_CTRL_M2D		(1 << 1)
-#define VI6_CLU_CTRL_EN			(1 << 0)
+#define VI6_CLU_CTRL_M2D		BIT(1)
+#define VI6_CLU_CTRL_EN			BIT(0)
 
 /* -----------------------------------------------------------------------------
  * HST Control Registers
  */
 
 #define VI6_HST_CTRL			0x2a00
-#define VI6_HST_CTRL_EN			(1 << 0)
+#define VI6_HST_CTRL_EN			BIT(0)
 
 /* -----------------------------------------------------------------------------
  * HSI Control Registers
  */
 
 #define VI6_HSI_CTRL			0x2b00
-#define VI6_HSI_CTRL_EN			(1 << 0)
+#define VI6_HSI_CTRL_EN			BIT(0)
 
 /* -----------------------------------------------------------------------------
  * BRS and BRU Control Registers
@@ -563,7 +563,7 @@
 #define VI6_BRS_BASE			0x3900
 
 #define VI6_BRU_INCTRL			0x0000
-#define VI6_BRU_INCTRL_NRM		(1 << 28)
+#define VI6_BRU_INCTRL_NRM		BIT(28)
 #define VI6_BRU_INCTRL_DnON		(1 << (16 + (n)))
 #define VI6_BRU_INCTRL_DITHn_OFF	(0 << ((n) * 4))
 #define VI6_BRU_INCTRL_DITHn_18BPP	(1 << ((n) * 4))
@@ -597,7 +597,7 @@
 #define VI6_BRU_VIRRPF_COL_BCB_SHIFT	0
 
 #define VI6_BRU_CTRL(n)			(0x0010 + (n) * 8 + ((n) <= 3 ? 0 : 4))
-#define VI6_BRU_CTRL_RBC		(1 << 31)
+#define VI6_BRU_CTRL_RBC		BIT(31)
 #define VI6_BRU_CTRL_DSTSEL_BRUIN(n)	(((n) <= 3 ? (n) : (n)+1) << 20)
 #define VI6_BRU_CTRL_DSTSEL_VRPF	(4 << 20)
 #define VI6_BRU_CTRL_DSTSEL_MASK	(7 << 20)
@@ -610,7 +610,7 @@
 #define VI6_BRU_CTRL_AROP_MASK		(0xf << 0)
 
 #define VI6_BRU_BLD(n)			(0x0014 + (n) * 8 + ((n) <= 3 ? 0 : 4))
-#define VI6_BRU_BLD_CBES		(1 << 31)
+#define VI6_BRU_BLD_CBES		BIT(31)
 #define VI6_BRU_BLD_CCMDX_DST_A		(0 << 28)
 #define VI6_BRU_BLD_CCMDX_255_DST_A	(1 << 28)
 #define VI6_BRU_BLD_CCMDX_SRC_A		(2 << 28)
@@ -624,7 +624,7 @@
 #define VI6_BRU_BLD_CCMDY_COEFY		(4 << 24)
 #define VI6_BRU_BLD_CCMDY_MASK		(7 << 24)
 #define VI6_BRU_BLD_CCMDY_SHIFT		24
-#define VI6_BRU_BLD_ABES		(1 << 23)
+#define VI6_BRU_BLD_ABES		BIT(23)
 #define VI6_BRU_BLD_ACMDX_DST_A		(0 << 20)
 #define VI6_BRU_BLD_ACMDX_255_DST_A	(1 << 20)
 #define VI6_BRU_BLD_ACMDX_SRC_A		(2 << 20)
@@ -662,11 +662,11 @@
 #define VI6_HGO_SIZE_HSIZE_SHIFT	16
 #define VI6_HGO_SIZE_VSIZE_SHIFT	0
 #define VI6_HGO_MODE			0x3008
-#define VI6_HGO_MODE_STEP		(1 << 10)
-#define VI6_HGO_MODE_MAXRGB		(1 << 7)
-#define VI6_HGO_MODE_OFSB_R		(1 << 6)
-#define VI6_HGO_MODE_OFSB_G		(1 << 5)
-#define VI6_HGO_MODE_OFSB_B		(1 << 4)
+#define VI6_HGO_MODE_STEP		BIT(10)
+#define VI6_HGO_MODE_MAXRGB		BIT(7)
+#define VI6_HGO_MODE_OFSB_R		BIT(6)
+#define VI6_HGO_MODE_OFSB_G		BIT(5)
+#define VI6_HGO_MODE_OFSB_B		BIT(4)
 #define VI6_HGO_MODE_HRATIO_SHIFT	2
 #define VI6_HGO_MODE_VRATIO_SHIFT	0
 #define VI6_HGO_LB_TH			0x300c
@@ -687,7 +687,7 @@
 #define VI6_HGO_EXT_HIST_ADDR		0x335c
 #define VI6_HGO_EXT_HIST_DATA		0x3360
 #define VI6_HGO_REGRST			0x33fc
-#define VI6_HGO_REGRST_RCLEA		(1 << 0)
+#define VI6_HGO_REGRST_RCLEA		BIT(0)
 
 /* -----------------------------------------------------------------------------
  * HGT Control Registers
@@ -713,7 +713,7 @@
 #define VI6_HGT_SUM			0x3754
 #define VI6_HGT_LB_DET			0x3758
 #define VI6_HGT_REGRST			0x37fc
-#define VI6_HGT_REGRST_RCLEA		(1 << 0)
+#define VI6_HGT_REGRST_RCLEA		BIT(0)
 
 /* -----------------------------------------------------------------------------
  * LIF Control Registers
@@ -724,9 +724,9 @@
 #define VI6_LIF_CTRL			0x3b00
 #define VI6_LIF_CTRL_OBTH_MASK		(0x7ff << 16)
 #define VI6_LIF_CTRL_OBTH_SHIFT		16
-#define VI6_LIF_CTRL_CFMT		(1 << 4)
-#define VI6_LIF_CTRL_REQSEL		(1 << 1)
-#define VI6_LIF_CTRL_LIF_EN		(1 << 0)
+#define VI6_LIF_CTRL_CFMT		BIT(4)
+#define VI6_LIF_CTRL_REQSEL		BIT(1)
+#define VI6_LIF_CTRL_LIF_EN		BIT(0)
 
 #define VI6_LIF_CSBTH			0x3b04
 #define VI6_LIF_CSBTH_HBTH_MASK		(0x7ff << 16)
@@ -735,7 +735,7 @@
 #define VI6_LIF_CSBTH_LBTH_SHIFT	0
 
 #define VI6_LIF_LBA			0x3b0c
-#define VI6_LIF_LBA_LBA0		(1 << 31)
+#define VI6_LIF_LBA_LBA0		BIT(31)
 #define VI6_LIF_LBA_LBA1_MASK		(0xfff << 16)
 #define VI6_LIF_LBA_LBA1_SHIFT		16
 
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index fd98e48..5e59ed2 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -956,12 +956,6 @@
 			  | V4L2_CAP_VIDEO_CAPTURE_MPLANE
 			  | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
 
-	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-		cap->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE
-				 | V4L2_CAP_STREAMING;
-	else
-		cap->device_caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE
-				 | V4L2_CAP_STREAMING;
 
 	strscpy(cap->driver, "vsp1", sizeof(cap->driver));
 	strscpy(cap->card, video->video.name, sizeof(cap->card));
@@ -1268,11 +1262,15 @@
 		video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
 		video->pad.flags = MEDIA_PAD_FL_SOURCE;
 		video->video.vfl_dir = VFL_DIR_TX;
+		video->video.device_caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+					   V4L2_CAP_STREAMING;
 	} else {
 		direction = "output";
 		video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
 		video->pad.flags = MEDIA_PAD_FL_SINK;
 		video->video.vfl_dir = VFL_DIR_RX;
+		video->video.device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
+					   V4L2_CAP_STREAMING;
 	}
 
 	mutex_init(&video->lock);
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index c9d5fdb..b211380 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -491,15 +491,8 @@
 	struct v4l2_fh *vfh = file->private_data;
 	struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
 
-	cap->device_caps = V4L2_CAP_STREAMING;
-
-	if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
-	else
-		cap->device_caps |= V4L2_CAP_VIDEO_OUTPUT;
-
-	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS
-			  | dma->xdev->v4l2_caps;
+	cap->capabilities = dma->xdev->v4l2_caps | V4L2_CAP_STREAMING |
+			    V4L2_CAP_DEVICE_CAPS;
 
 	strscpy(cap->driver, "xilinx-vipp", sizeof(cap->driver));
 	strscpy(cap->card, dma->video.name, sizeof(cap->card));
@@ -524,8 +517,6 @@
 		return -EINVAL;
 
 	f->pixelformat = dma->format.pixelformat;
-	strscpy(f->description, dma->fmtinfo->description,
-		sizeof(f->description));
 
 	return 0;
 }
@@ -700,6 +691,11 @@
 	dma->video.release = video_device_release_empty;
 	dma->video.ioctl_ops = &xvip_dma_ioctl_ops;
 	dma->video.lock = &dma->lock;
+	dma->video.device_caps = V4L2_CAP_STREAMING;
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		dma->video.device_caps |= V4L2_CAP_VIDEO_CAPTURE;
+	else
+		dma->video.device_caps |= V4L2_CAP_VIDEO_OUTPUT;
 
 	video_set_drvdata(&dma->video, dma);
 
diff --git a/drivers/media/platform/xilinx/xilinx-vip.c b/drivers/media/platform/xilinx/xilinx-vip.c
index 08a825c..6ad61b0 100644
--- a/drivers/media/platform/xilinx/xilinx-vip.c
+++ b/drivers/media/platform/xilinx/xilinx-vip.c
@@ -25,21 +25,21 @@
 
 static const struct xvip_video_format xvip_video_formats[] = {
 	{ XVIP_VF_YUV_422, 8, NULL, MEDIA_BUS_FMT_UYVY8_1X16,
-	  2, V4L2_PIX_FMT_YUYV, "4:2:2, packed, YUYV" },
+	  2, V4L2_PIX_FMT_YUYV },
 	{ XVIP_VF_YUV_444, 8, NULL, MEDIA_BUS_FMT_VUY8_1X24,
-	  3, V4L2_PIX_FMT_YUV444, "4:4:4, packed, YUYV" },
+	  3, V4L2_PIX_FMT_YUV444 },
 	{ XVIP_VF_RBG, 8, NULL, MEDIA_BUS_FMT_RBG888_1X24,
-	  3, 0, NULL },
+	  3, 0 },
 	{ XVIP_VF_MONO_SENSOR, 8, "mono", MEDIA_BUS_FMT_Y8_1X8,
-	  1, V4L2_PIX_FMT_GREY, "Greyscale 8-bit" },
+	  1, V4L2_PIX_FMT_GREY },
 	{ XVIP_VF_MONO_SENSOR, 8, "rggb", MEDIA_BUS_FMT_SRGGB8_1X8,
-	  1, V4L2_PIX_FMT_SRGGB8, "Bayer 8-bit RGGB" },
+	  1, V4L2_PIX_FMT_SRGGB8 },
 	{ XVIP_VF_MONO_SENSOR, 8, "grbg", MEDIA_BUS_FMT_SGRBG8_1X8,
-	  1, V4L2_PIX_FMT_SGRBG8, "Bayer 8-bit GRBG" },
+	  1, V4L2_PIX_FMT_SGRBG8 },
 	{ XVIP_VF_MONO_SENSOR, 8, "gbrg", MEDIA_BUS_FMT_SGBRG8_1X8,
-	  1, V4L2_PIX_FMT_SGBRG8, "Bayer 8-bit GBRG" },
+	  1, V4L2_PIX_FMT_SGBRG8 },
 	{ XVIP_VF_MONO_SENSOR, 8, "bggr", MEDIA_BUS_FMT_SBGGR8_1X8,
-	  1, V4L2_PIX_FMT_SBGGR8, "Bayer 8-bit BGGR" },
+	  1, V4L2_PIX_FMT_SBGGR8 },
 };
 
 /**
diff --git a/drivers/media/platform/xilinx/xilinx-vip.h b/drivers/media/platform/xilinx/xilinx-vip.h
index ba939dd..f71e2b6 100644
--- a/drivers/media/platform/xilinx/xilinx-vip.h
+++ b/drivers/media/platform/xilinx/xilinx-vip.h
@@ -12,6 +12,7 @@
 #ifndef __XILINX_VIP_H__
 #define __XILINX_VIP_H__
 
+#include <linux/bitops.h>
 #include <linux/io.h>
 #include <media/v4l2-subdev.h>
 
@@ -35,23 +36,23 @@
 
 /* Xilinx Video IP Control Registers */
 #define XVIP_CTRL_CONTROL			0x0000
-#define XVIP_CTRL_CONTROL_SW_ENABLE		(1 << 0)
-#define XVIP_CTRL_CONTROL_REG_UPDATE		(1 << 1)
-#define XVIP_CTRL_CONTROL_BYPASS		(1 << 4)
-#define XVIP_CTRL_CONTROL_TEST_PATTERN		(1 << 5)
-#define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET	(1 << 30)
-#define XVIP_CTRL_CONTROL_SW_RESET		(1 << 31)
+#define XVIP_CTRL_CONTROL_SW_ENABLE		BIT(0)
+#define XVIP_CTRL_CONTROL_REG_UPDATE		BIT(1)
+#define XVIP_CTRL_CONTROL_BYPASS		BIT(4)
+#define XVIP_CTRL_CONTROL_TEST_PATTERN		BIT(5)
+#define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET	BIT(30)
+#define XVIP_CTRL_CONTROL_SW_RESET		BIT(31)
 #define XVIP_CTRL_STATUS			0x0004
-#define XVIP_CTRL_STATUS_PROC_STARTED		(1 << 0)
-#define XVIP_CTRL_STATUS_EOF			(1 << 1)
+#define XVIP_CTRL_STATUS_PROC_STARTED		BIT(0)
+#define XVIP_CTRL_STATUS_EOF			BIT(1)
 #define XVIP_CTRL_ERROR				0x0008
-#define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY		(1 << 0)
-#define XVIP_CTRL_ERROR_SLAVE_EOL_LATE		(1 << 1)
-#define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY		(1 << 2)
-#define XVIP_CTRL_ERROR_SLAVE_SOF_LATE		(1 << 3)
+#define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY		BIT(0)
+#define XVIP_CTRL_ERROR_SLAVE_EOL_LATE		BIT(1)
+#define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY		BIT(2)
+#define XVIP_CTRL_ERROR_SLAVE_SOF_LATE		BIT(3)
 #define XVIP_CTRL_IRQ_ENABLE			0x000c
-#define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED	(1 << 0)
-#define XVIP_CTRL_IRQ_EOF			(1 << 1)
+#define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED	BIT(0)
+#define XVIP_CTRL_IRQ_EOF			BIT(1)
 #define XVIP_CTRL_VERSION			0x0010
 #define XVIP_CTRL_VERSION_MAJOR_MASK		(0xff << 24)
 #define XVIP_CTRL_VERSION_MAJOR_SHIFT		24
@@ -108,7 +109,6 @@
  * @code: media bus format code
  * @bpp: bytes per pixel (when stored in memory)
  * @fourcc: V4L2 pixel format FCC identifier
- * @description: format description, suitable for userspace
  */
 struct xvip_video_format {
 	unsigned int vf_code;
@@ -117,7 +117,6 @@
 	unsigned int code;
 	unsigned int bpp;
 	u32 fourcc;
-	const char *description;
 };
 
 const struct xvip_video_format *xvip_get_format_by_code(unsigned int code);
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index edce040..cc2856e 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -385,9 +385,9 @@
 		asd = v4l2_async_notifier_add_fwnode_subdev(
 			&xdev->notifier, remote,
 			sizeof(struct xvip_graph_entity));
+		fwnode_handle_put(remote);
 		if (IS_ERR(asd)) {
 			ret = PTR_ERR(asd);
-			fwnode_handle_put(remote);
 			goto err_notifier_cleanup;
 		}
 	}
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 0640011..a532f63 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -125,7 +125,7 @@
 #define BU2614_FMUN_SHIFT	(BU2614_VOID2_BITS + BU2614_VOID2_SHIFT)
 #define BU2614_TEST_SHIFT	(BU2614_FMUN_BITS + BU2614_FMUN_SHIFT)
 
-#define MKMASK(field)	(((1<<BU2614_##field##_BITS) - 1) << \
+#define MKMASK(field)	(((1UL<<BU2614_##field##_BITS) - 1) << \
 			BU2614_##field##_SHIFT)
 #define BU2614_PORT_MASK	MKMASK(PORT)
 #define BU2614_FREQ_MASK	MKMASK(FREQ)
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index 2fc0095..dfb8b62 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -16,7 +16,6 @@
  * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org>
  */
 
-#include <stdarg.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index 7d53422..7541698 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -330,8 +330,7 @@
 /*
  * si470x_i2c_probe - probe for the device
  */
-static int si470x_i2c_probe(struct i2c_client *client,
-			    const struct i2c_device_id *id)
+static int si470x_i2c_probe(struct i2c_client *client)
 {
 	struct si470x_device *radio;
 	int retval = 0;
@@ -544,7 +543,7 @@
 		.pm		= &si470x_i2c_pm,
 #endif
 	},
-	.probe			= si470x_i2c_probe,
+	.probe_new		= si470x_i2c_probe,
 	.remove			= si470x_i2c_remove,
 	.id_table		= si470x_i2c_id,
 };
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
index 4907374..fedff68 100644
--- a/drivers/media/radio/si470x/radio-si470x-usb.c
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -734,7 +734,7 @@
 	/* start radio */
 	retval = si470x_start_usb(radio);
 	if (retval < 0)
-		goto err_all;
+		goto err_buf;
 
 	/* set initial frequency */
 	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
@@ -749,6 +749,8 @@
 
 	return 0;
 err_all:
+	usb_kill_urb(radio->int_in_urb);
+err_buf:
 	kfree(radio->buffer);
 err_ctrl:
 	v4l2_ctrl_handler_free(&radio->hdl);
@@ -822,6 +824,7 @@
 	mutex_lock(&radio->lock);
 	v4l2_device_disconnect(&radio->v4l2_dev);
 	video_unregister_device(&radio->videodev);
+	usb_kill_urb(radio->int_in_urb);
 	usb_set_intfdata(intf, NULL);
 	mutex_unlock(&radio->lock);
 	v4l2_device_put(&radio->v4l2_dev);
diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c
index 7d97de2..7f3aee4 100644
--- a/drivers/media/radio/si4713/si4713.c
+++ b/drivers/media/radio/si4713/si4713.c
@@ -1427,8 +1427,7 @@
  * I2C driver interface
  */
 /* si4713_probe - probe for the device */
-static int si4713_probe(struct i2c_client *client,
-					const struct i2c_device_id *id)
+static int si4713_probe(struct i2c_client *client)
 {
 	struct si4713_device *sdev;
 	struct v4l2_ctrl_handler *hdl;
@@ -1660,7 +1659,7 @@
 		.name	= "si4713",
 		.of_match_table = of_match_ptr(si4713_of_match),
 	},
-	.probe		= si4713_probe,
+	.probe_new	= si4713_probe,
 	.remove         = si4713_remove,
 	.id_table       = si4713_id,
 };
diff --git a/drivers/media/radio/wl128x/fmdrv_common.h b/drivers/media/radio/wl128x/fmdrv_common.h
index 7d7a2b1..6a287ea 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.h
+++ b/drivers/media/radio/wl128x/fmdrv_common.h
@@ -159,18 +159,18 @@
 #define FM_DISABLE  0
 
 /* FLAG_GET register bits */
-#define FM_FR_EVENT		(1 << 0)
-#define FM_BL_EVENT		(1 << 1)
-#define FM_RDS_EVENT		(1 << 2)
-#define FM_BBLK_EVENT		(1 << 3)
-#define FM_LSYNC_EVENT		(1 << 4)
-#define FM_LEV_EVENT		(1 << 5)
-#define FM_IFFR_EVENT		(1 << 6)
-#define FM_PI_EVENT		(1 << 7)
-#define FM_PD_EVENT		(1 << 8)
-#define FM_STIC_EVENT		(1 << 9)
-#define FM_MAL_EVENT		(1 << 10)
-#define FM_POW_ENB_EVENT	(1 << 11)
+#define FM_FR_EVENT		BIT(0)
+#define FM_BL_EVENT		BIT(1)
+#define FM_RDS_EVENT		BIT(2)
+#define FM_BBLK_EVENT		BIT(3)
+#define FM_LSYNC_EVENT		BIT(4)
+#define FM_LEV_EVENT		BIT(5)
+#define FM_IFFR_EVENT		BIT(6)
+#define FM_PI_EVENT		BIT(7)
+#define FM_PD_EVENT		BIT(8)
+#define FM_STIC_EVENT		BIT(9)
+#define FM_MAL_EVENT		BIT(10)
+#define FM_POW_ENB_EVENT	BIT(11)
 
 /*
  * Firmware files of FM. ASIC ID and ASIC version will be appened to this,
@@ -268,38 +268,38 @@
  * Represents an RDS group type & version.
  * There are 15 groups, each group has 2 versions: A and B.
  */
-#define FM_RDS_GROUP_TYPE_MASK_0A	    ((unsigned long)1<<0)
-#define FM_RDS_GROUP_TYPE_MASK_0B	    ((unsigned long)1<<1)
-#define FM_RDS_GROUP_TYPE_MASK_1A	    ((unsigned long)1<<2)
-#define FM_RDS_GROUP_TYPE_MASK_1B	    ((unsigned long)1<<3)
-#define FM_RDS_GROUP_TYPE_MASK_2A	    ((unsigned long)1<<4)
-#define FM_RDS_GROUP_TYPE_MASK_2B	    ((unsigned long)1<<5)
-#define FM_RDS_GROUP_TYPE_MASK_3A	    ((unsigned long)1<<6)
-#define FM_RDS_GROUP_TYPE_MASK_3B           ((unsigned long)1<<7)
-#define FM_RDS_GROUP_TYPE_MASK_4A	    ((unsigned long)1<<8)
-#define FM_RDS_GROUP_TYPE_MASK_4B	    ((unsigned long)1<<9)
-#define FM_RDS_GROUP_TYPE_MASK_5A	    ((unsigned long)1<<10)
-#define FM_RDS_GROUP_TYPE_MASK_5B	    ((unsigned long)1<<11)
-#define FM_RDS_GROUP_TYPE_MASK_6A	    ((unsigned long)1<<12)
-#define FM_RDS_GROUP_TYPE_MASK_6B	    ((unsigned long)1<<13)
-#define FM_RDS_GROUP_TYPE_MASK_7A	    ((unsigned long)1<<14)
-#define FM_RDS_GROUP_TYPE_MASK_7B	    ((unsigned long)1<<15)
-#define FM_RDS_GROUP_TYPE_MASK_8A           ((unsigned long)1<<16)
-#define FM_RDS_GROUP_TYPE_MASK_8B	    ((unsigned long)1<<17)
-#define FM_RDS_GROUP_TYPE_MASK_9A	    ((unsigned long)1<<18)
-#define FM_RDS_GROUP_TYPE_MASK_9B	    ((unsigned long)1<<19)
-#define FM_RDS_GROUP_TYPE_MASK_10A	    ((unsigned long)1<<20)
-#define FM_RDS_GROUP_TYPE_MASK_10B	    ((unsigned long)1<<21)
-#define FM_RDS_GROUP_TYPE_MASK_11A	    ((unsigned long)1<<22)
-#define FM_RDS_GROUP_TYPE_MASK_11B	    ((unsigned long)1<<23)
-#define FM_RDS_GROUP_TYPE_MASK_12A	    ((unsigned long)1<<24)
-#define FM_RDS_GROUP_TYPE_MASK_12B	    ((unsigned long)1<<25)
-#define FM_RDS_GROUP_TYPE_MASK_13A	    ((unsigned long)1<<26)
-#define FM_RDS_GROUP_TYPE_MASK_13B	    ((unsigned long)1<<27)
-#define FM_RDS_GROUP_TYPE_MASK_14A	    ((unsigned long)1<<28)
-#define FM_RDS_GROUP_TYPE_MASK_14B	    ((unsigned long)1<<29)
-#define FM_RDS_GROUP_TYPE_MASK_15A	    ((unsigned long)1<<30)
-#define FM_RDS_GROUP_TYPE_MASK_15B	    ((unsigned long)1<<31)
+#define FM_RDS_GROUP_TYPE_MASK_0A	    BIT(0)
+#define FM_RDS_GROUP_TYPE_MASK_0B	    BIT(1)
+#define FM_RDS_GROUP_TYPE_MASK_1A	    BIT(2)
+#define FM_RDS_GROUP_TYPE_MASK_1B	    BIT(3)
+#define FM_RDS_GROUP_TYPE_MASK_2A	    BIT(4)
+#define FM_RDS_GROUP_TYPE_MASK_2B	    BIT(5)
+#define FM_RDS_GROUP_TYPE_MASK_3A	    BIT(6)
+#define FM_RDS_GROUP_TYPE_MASK_3B	    BIT(7)
+#define FM_RDS_GROUP_TYPE_MASK_4A	    BIT(8)
+#define FM_RDS_GROUP_TYPE_MASK_4B	    BIT(9)
+#define FM_RDS_GROUP_TYPE_MASK_5A	    BIT(10)
+#define FM_RDS_GROUP_TYPE_MASK_5B	    BIT(11)
+#define FM_RDS_GROUP_TYPE_MASK_6A	    BIT(12)
+#define FM_RDS_GROUP_TYPE_MASK_6B	    BIT(13)
+#define FM_RDS_GROUP_TYPE_MASK_7A	    BIT(14)
+#define FM_RDS_GROUP_TYPE_MASK_7B	    BIT(15)
+#define FM_RDS_GROUP_TYPE_MASK_8A	    BIT(16)
+#define FM_RDS_GROUP_TYPE_MASK_8B	    BIT(17)
+#define FM_RDS_GROUP_TYPE_MASK_9A	    BIT(18)
+#define FM_RDS_GROUP_TYPE_MASK_9B	    BIT(19)
+#define FM_RDS_GROUP_TYPE_MASK_10A	    BIT(20)
+#define FM_RDS_GROUP_TYPE_MASK_10B	    BIT(21)
+#define FM_RDS_GROUP_TYPE_MASK_11A	    BIT(22)
+#define FM_RDS_GROUP_TYPE_MASK_11B	    BIT(23)
+#define FM_RDS_GROUP_TYPE_MASK_12A	    BIT(24)
+#define FM_RDS_GROUP_TYPE_MASK_12B	    BIT(25)
+#define FM_RDS_GROUP_TYPE_MASK_13A	    BIT(26)
+#define FM_RDS_GROUP_TYPE_MASK_13B	    BIT(27)
+#define FM_RDS_GROUP_TYPE_MASK_14A	    BIT(28)
+#define FM_RDS_GROUP_TYPE_MASK_14B	    BIT(29)
+#define FM_RDS_GROUP_TYPE_MASK_15A	    BIT(30)
+#define FM_RDS_GROUP_TYPE_MASK_15B	    BIT(31)
 
 /* RX Alternate Frequency info */
 #define FM_RDS_MIN_AF			  1
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index ea05e12..872d644 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -413,6 +413,10 @@
 	int ret, pipein, pipeout;
 	struct usb_host_interface *idesc;
 
+	idesc = intf->altsetting;
+	if (idesc->desc.bNumEndpoints < 2)
+		return -ENODEV;
+
 	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
 	rc = rc_allocate_device(RC_DRIVER_IR_RAW);
 	if (!ir || !rc) {
@@ -427,18 +431,13 @@
 	ir->urb_in = usb_alloc_urb(0, GFP_KERNEL);
 	ir->urb_out = usb_alloc_urb(0, GFP_KERNEL);
 
-	if (!ir->buf_in || !ir->packet || !ir->urb_in || !ir->urb_out) {
+	if (!ir->buf_in || !ir->packet || !ir->urb_in || !ir->urb_out ||
+	    !usb_endpoint_is_int_in(&idesc->endpoint[0].desc) ||
+	    !usb_endpoint_is_int_out(&idesc->endpoint[1].desc)) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
-	idesc = intf->altsetting;
-
-	if (idesc->desc.bNumEndpoints < 2) {
-		ret = -ENODEV;
-		goto out;
-	}
-
 	ir->rc = rc;
 	ir->dev = &intf->dev;
 	ir->udev = udev;
diff --git a/drivers/media/rc/img-ir/img-ir-core.c b/drivers/media/rc/img-ir/img-ir-core.c
index 7e457f2..094aa6a 100644
--- a/drivers/media/rc/img-ir/img-ir-core.c
+++ b/drivers/media/rc/img-ir/img-ir-core.c
@@ -81,10 +81,8 @@
 
 	/* Get resources from platform device */
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(&pdev->dev, "cannot find IRQ resource\n");
+	if (irq < 0)
 		return irq;
-	}
 
 	/* Private driver data */
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 7bee721..37a8504 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -1826,12 +1826,17 @@
 		break;
 	/* iMON VFD, MCE IR */
 	case 0x46:
-	case 0x7e:
 	case 0x9e:
 		dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR");
 		detected_display_type = IMON_DISPLAY_TYPE_VFD;
 		allowed_protos = RC_PROTO_BIT_RC6_MCE;
 		break;
+	/* iMON VFD, iMON or MCE IR */
+	case 0x7e:
+		dev_info(ictx->dev, "0xffdc iMON VFD, iMON or MCE IR");
+		detected_display_type = IMON_DISPLAY_TYPE_VFD;
+		allowed_protos |= RC_PROTO_BIT_RC6_MCE;
+		break;
 	/* iMON LCD, MCE IR */
 	case 0x9f:
 		dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
diff --git a/drivers/media/rc/imon_raw.c b/drivers/media/rc/imon_raw.c
index 25e56c5..d4aedcf 100644
--- a/drivers/media/rc/imon_raw.c
+++ b/drivers/media/rc/imon_raw.c
@@ -14,7 +14,7 @@
 	struct device *dev;
 	struct urb *ir_urb;
 	struct rc_dev *rcdev;
-	u8 ir_buf[8] __aligned(__alignof__(u64));
+	__be64 ir_buf;
 	char phys[64];
 };
 
@@ -29,14 +29,35 @@
 static void imon_ir_data(struct imon *imon)
 {
 	struct ir_raw_event rawir = {};
-	u64 d = be64_to_cpup((__be64 *)imon->ir_buf) >> 24;
+	u64 data = be64_to_cpu(imon->ir_buf);
+	u8 packet_no = data & 0xff;
 	int offset = 40;
 	int bit;
 
-	dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf);
+	if (packet_no == 0xff)
+		return;
+
+	dev_dbg(imon->dev, "data: %*ph", 8, &imon->ir_buf);
+
+	/*
+	 * Only the first 5 bytes contain IR data. Right shift so we move
+	 * the IR bits to the lower 40 bits.
+	 */
+	data >>= 24;
 
 	do {
-		bit = fls64(d & (BIT_ULL(offset) - 1));
+		/*
+		 * Find highest set bit which is less or equal to offset
+		 *
+		 * offset is the bit above (base 0) where we start looking.
+		 *
+		 * data & (BIT_ULL(offset) - 1) masks off any unwanted bits,
+		 * so we have just bits less than offset.
+		 *
+		 * fls will tell us the highest bit set plus 1 (or 0 if no
+		 * bits are set).
+		 */
+		bit = fls64(data & (BIT_ULL(offset) - 1));
 		if (bit < offset) {
 			dev_dbg(imon->dev, "pulse: %d bits", offset - bit);
 			rawir.pulse = true;
@@ -49,7 +70,12 @@
 			offset = bit;
 		}
 
-		bit = fls64(~d & (BIT_ULL(offset) - 1));
+		/*
+		 * Find highest clear bit which is less than offset.
+		 *
+		 * Just invert the data and use same trick as above.
+		 */
+		bit = fls64(~data & (BIT_ULL(offset) - 1));
 		dev_dbg(imon->dev, "space: %d bits", offset - bit);
 
 		rawir.pulse = false;
@@ -59,7 +85,7 @@
 		offset = bit;
 	} while (offset > 0);
 
-	if (imon->ir_buf[7] == 0x0a) {
+	if (packet_no == 0x0a && !imon->rcdev->idle) {
 		ir_raw_event_set_idle(imon->rcdev, true);
 		ir_raw_event_handle(imon->rcdev);
 	}
@@ -72,8 +98,7 @@
 
 	switch (urb->status) {
 	case 0:
-		if (imon->ir_buf[7] != 0xff)
-			imon_ir_data(imon);
+		imon_ir_data(imon);
 		break;
 	case -ECONNRESET:
 	case -ENOENT:
@@ -129,7 +154,7 @@
 	imon->dev = &intf->dev;
 	usb_fill_int_urb(imon->ir_urb, udev,
 			 usb_rcvintpipe(udev, ir_ep->bEndpointAddress),
-			 imon->ir_buf, sizeof(imon->ir_buf),
+			 &imon->ir_buf, sizeof(imon->ir_buf),
 			 imon_ir_rx, imon, ir_ep->bInterval);
 
 	rcdev = devm_rc_allocate_device(&intf->dev, RC_DRIVER_IR_RAW);
diff --git a/drivers/media/rc/ir-hix5hd2.c b/drivers/media/rc/ir-hix5hd2.c
index 85561f6..32ccefe 100644
--- a/drivers/media/rc/ir-hix5hd2.c
+++ b/drivers/media/rc/ir-hix5hd2.c
@@ -232,10 +232,8 @@
 		return PTR_ERR(priv->base);
 
 	priv->irq = platform_get_irq(pdev, 0);
-	if (priv->irq < 0) {
-		dev_err(dev, "irq can not get\n");
+	if (priv->irq < 0)
 		return priv->irq;
-	}
 
 	rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
 	if (!rdev)
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 5b1399a..a56fc63 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -58,6 +58,7 @@
 			rc-it913x-v1.o \
 			rc-it913x-v2.o \
 			rc-kaiomy.o \
+			rc-khadas.o \
 			rc-kworld-315u.o \
 			rc-kworld-pc150u.o \
 			rc-kworld-plus-tv-analog.o \
@@ -75,6 +76,7 @@
 			rc-nec-terratec-cinergy-xs.o \
 			rc-norwood.o \
 			rc-npgtech.o \
+			rc-odroid.o \
 			rc-pctv-sedna.o \
 			rc-pinnacle-color.o \
 			rc-pinnacle-grey.o \
@@ -94,6 +96,8 @@
 			rc-snapstream-firefly.o \
 			rc-streamzap.o \
 			rc-tango.o \
+			rc-tanix-tx3mini.o \
+			rc-tanix-tx5max.o \
 			rc-tbs-nec.o \
 			rc-technisat-ts35.o \
 			rc-technisat-usb2.o \
@@ -113,8 +117,11 @@
 			rc-videomate-m1f.o \
 			rc-videomate-s350.o \
 			rc-videomate-tv-pvr.o \
+			rc-wetek-hub.o \
+			rc-wetek-play2.o \
 			rc-winfast.o \
 			rc-winfast-usbii-deluxe.o \
 			rc-su3000.o \
 			rc-xbox-dvd.o \
+			rc-x96max.o \
 			rc-zx-irdec.o
diff --git a/drivers/media/rc/keymaps/rc-imon-rsc.c b/drivers/media/rc/keymaps/rc-imon-rsc.c
index 6f7ee48..38787dd 100644
--- a/drivers/media/rc/keymaps/rc-imon-rsc.c
+++ b/drivers/media/rc/keymaps/rc-imon-rsc.c
@@ -7,7 +7,8 @@
 
 //
 // Note that this remote has a stick which its own IR protocol,
-// with 16 directions. This is not supported yet.
+// with 16 directions. This is supported by the imon_rsc BPF decoder
+// in v4l-utils.
 //
 static struct rc_map_table imon_rsc[] = {
 	{ 0x801010, KEY_EXIT },
@@ -25,7 +26,7 @@
 	{ 0x80105c, KEY_NUMERIC_9 },
 	{ 0x801081, KEY_SCREEN },	/* Desktop */
 	{ 0x80105d, KEY_NUMERIC_0 },
-	{ 0x801082, KEY_MAX },
+	{ 0x801082, KEY_ZOOM },		/* Maximise */
 	{ 0x801048, KEY_ESC },
 	{ 0x80104b, KEY_MEDIA },	/* Windows key */
 	{ 0x801083, KEY_MENU },
@@ -52,7 +53,7 @@
 	{ 0x80104e, KEY_STOP },
 	{ 0x801052, KEY_REWIND },
 	{ 0x801053, KEY_FASTFORWARD },
-	{ 0x801089, KEY_ZOOM }		/* full screen */
+	{ 0x801089, KEY_FULL_SCREEN }	/* full screen */
 };
 
 static struct rc_map_list imon_rsc_map = {
diff --git a/drivers/media/rc/keymaps/rc-khadas.c b/drivers/media/rc/keymaps/rc-khadas.c
new file mode 100644
index 0000000..ce49384
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-khadas.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (C) 2019 Christian Hewitt <christianshewitt@gmail.com>
+
+/*
+ * Keytable for the Khadas VIM/EDGE SBC remote control
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+static struct rc_map_table khadas[] = {
+	{ 0x14, KEY_POWER },
+
+	{ 0x03, KEY_UP },
+	{ 0x02, KEY_DOWN },
+	{ 0x0e, KEY_LEFT },
+	{ 0x1a, KEY_RIGHT },
+	{ 0x07, KEY_OK },
+
+	{ 0x01, KEY_BACK },
+	{ 0x5b, KEY_MUTE }, // mouse
+	{ 0x13, KEY_MENU },
+
+	{ 0x58, KEY_VOLUMEDOWN },
+	{ 0x0b, KEY_VOLUMEUP },
+
+	{ 0x48, KEY_HOME },
+};
+
+static struct rc_map_list khadas_map = {
+	.map = {
+		.scan     = khadas,
+		.size     = ARRAY_SIZE(khadas),
+		.rc_proto = RC_PROTO_NEC,
+		.name     = RC_MAP_KHADAS,
+	}
+};
+
+static int __init init_rc_map_khadas(void)
+{
+	return rc_map_register(&khadas_map);
+}
+
+static void __exit exit_rc_map_khadas(void)
+{
+	rc_map_unregister(&khadas_map);
+}
+
+module_init(init_rc_map_khadas)
+module_exit(exit_rc_map_khadas)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com>");
diff --git a/drivers/media/rc/keymaps/rc-odroid.c b/drivers/media/rc/keymaps/rc-odroid.c
new file mode 100644
index 0000000..c6fbb64
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-odroid.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (C) 2019 Christian Hewitt <christianshewitt@gmail.com>
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+//
+// Keytable for the HardKernel ODROID remote control
+//
+
+static struct rc_map_table odroid[] = {
+	{ 0xb2dc, KEY_POWER },
+
+	{ 0xb288, KEY_MUTE },
+	{ 0xb282, KEY_HOME },
+
+	{ 0xb2ca, KEY_UP },
+	{ 0xb299, KEY_LEFT },
+	{ 0xb2ce, KEY_OK },
+	{ 0xb2c1, KEY_RIGHT },
+	{ 0xb2d2, KEY_DOWN },
+
+	{ 0xb2c5, KEY_MENU },
+	{ 0xb29a, KEY_BACK },
+
+	{ 0xb281, KEY_VOLUMEDOWN },
+	{ 0xb280, KEY_VOLUMEUP },
+};
+
+static struct rc_map_list odroid_map = {
+	.map = {
+		.scan     = odroid,
+		.size     = ARRAY_SIZE(odroid),
+		.rc_proto = RC_PROTO_NEC,
+		.name     = RC_MAP_ODROID,
+	}
+};
+
+static int __init init_rc_map_odroid(void)
+{
+	return rc_map_register(&odroid_map);
+}
+
+static void __exit exit_rc_map_odroid(void)
+{
+	rc_map_unregister(&odroid_map);
+}
+
+module_init(init_rc_map_odroid)
+module_exit(exit_rc_map_odroid)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com");
diff --git a/drivers/media/rc/keymaps/rc-tanix-tx3mini.c b/drivers/media/rc/keymaps/rc-tanix-tx3mini.c
new file mode 100644
index 0000000..d486cd6
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-tanix-tx3mini.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2018 Christian Hewitt
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+/*
+ * Keymap for the Tanix TX3 mini STB remote control
+ */
+
+static struct rc_map_table tanix_tx3mini[] = {
+	{ 0x8051, KEY_POWER },
+	{ 0x804d, KEY_MUTE },
+
+	{ 0x8009, KEY_RED },
+	{ 0x8011, KEY_GREEN },
+	{ 0x8054, KEY_YELLOW },
+	{ 0x804f, KEY_BLUE },
+
+	{ 0x8056, KEY_VOLUMEDOWN },
+	{ 0x80bd, KEY_PREVIOUS },
+	{ 0x80bb, KEY_NEXT },
+	{ 0x804e, KEY_VOLUMEUP },
+
+	{ 0x8053, KEY_HOME },
+	{ 0x801b, KEY_BACK },
+
+	{ 0x8026, KEY_UP },
+	{ 0x8028, KEY_DOWN },
+	{ 0x8025, KEY_LEFT },
+	{ 0x8027, KEY_RIGHT },
+	{ 0x800d, KEY_OK },
+
+	{ 0x8049, KEY_MENU },
+	{ 0x8052, KEY_EPG }, // mouse
+
+	{ 0x8031, KEY_1 },
+	{ 0x8032, KEY_2 },
+	{ 0x8033, KEY_3 },
+
+	{ 0x8034, KEY_4 },
+	{ 0x8035, KEY_5 },
+	{ 0x8036, KEY_6 },
+
+	{ 0x8037, KEY_7 },
+	{ 0x8038, KEY_8 },
+	{ 0x8039, KEY_9 },
+
+	{ 0x8058, KEY_SUBTITLE }, // 1/a
+	{ 0x8030, KEY_0 },
+	{ 0x8044, KEY_DELETE },
+};
+
+static struct rc_map_list tanix_tx3mini_map = {
+	.map = {
+		.scan     = tanix_tx3mini,
+		.size     = ARRAY_SIZE(tanix_tx3mini),
+		.rc_proto = RC_PROTO_NEC,
+		.name     = RC_MAP_TANIX_TX3MINI,
+	}
+};
+
+static int __init init_rc_map_tanix_tx3mini(void)
+{
+	return rc_map_register(&tanix_tx3mini_map);
+}
+
+static void __exit exit_rc_map_tanix_tx3mini(void)
+{
+	rc_map_unregister(&tanix_tx3mini_map);
+}
+
+module_init(init_rc_map_tanix_tx3mini)
+module_exit(exit_rc_map_tanix_tx3mini)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com>");
diff --git a/drivers/media/rc/keymaps/rc-tanix-tx5max.c b/drivers/media/rc/keymaps/rc-tanix-tx5max.c
new file mode 100644
index 0000000..59aaabe
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-tanix-tx5max.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2018 Christian Hewitt
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+/*
+ * Keymap for the Tanix TX5 max STB remote control
+ */
+
+static struct rc_map_table tanix_tx5max[] = {
+	{ 0x40404d, KEY_POWER },
+	{ 0x404043, KEY_MUTE },
+
+	{ 0x404017, KEY_VOLUMEDOWN },
+	{ 0x404018, KEY_VOLUMEUP },
+
+	{ 0x40400b, KEY_UP },
+	{ 0x404010, KEY_LEFT },
+	{ 0x404011, KEY_RIGHT },
+	{ 0x40400e, KEY_DOWN },
+	{ 0x40400d, KEY_OK },
+
+	{ 0x40401a, KEY_HOME },
+	{ 0x404045, KEY_MENU },
+	{ 0x404042, KEY_BACK },
+
+	{ 0x404001, KEY_1 },
+	{ 0x404002, KEY_2 },
+	{ 0x404003, KEY_3 },
+
+	{ 0x404004, KEY_4 },
+	{ 0x404005, KEY_5 },
+	{ 0x404006, KEY_6 },
+
+	{ 0x404007, KEY_7 },
+	{ 0x404008, KEY_8 },
+	{ 0x404009, KEY_9 },
+
+	{ 0x404047, KEY_SUBTITLE }, // mouse
+	{ 0x404000, KEY_0 },
+	{ 0x40400c, KEY_DELETE },
+};
+
+static struct rc_map_list tanix_tx5max_map = {
+	.map = {
+		.scan     = tanix_tx5max,
+		.size     = ARRAY_SIZE(tanix_tx5max),
+		.rc_proto = RC_PROTO_NECX,
+		.name     = RC_MAP_TANIX_TX5MAX,
+	}
+};
+
+static int __init init_rc_map_tanix_tx5max(void)
+{
+	return rc_map_register(&tanix_tx5max_map);
+}
+
+static void __exit exit_rc_map_tanix_tx5max(void)
+{
+	rc_map_unregister(&tanix_tx5max_map);
+}
+
+module_init(init_rc_map_tanix_tx5max)
+module_exit(exit_rc_map_tanix_tx5max)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com>");
diff --git a/drivers/media/rc/keymaps/rc-wetek-hub.c b/drivers/media/rc/keymaps/rc-wetek-hub.c
new file mode 100644
index 0000000..b5a21af
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-wetek-hub.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2018 Christian Hewitt
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+/*
+ * This keymap is used with the WeTek Hub STB.
+ */
+
+static struct rc_map_table wetek_hub[] = {
+	{ 0x77f1, KEY_POWER },
+
+	{ 0x77f2, KEY_HOME },
+	{ 0x77f3, KEY_MUTE }, // mouse
+
+	{ 0x77f4, KEY_UP },
+	{ 0x77f5, KEY_DOWN },
+	{ 0x77f6, KEY_LEFT },
+	{ 0x77f7, KEY_RIGHT },
+	{ 0x77f8, KEY_OK },
+
+	{ 0x77f9, KEY_BACK },
+	{ 0x77fa, KEY_MENU },
+
+	{ 0x77fb, KEY_VOLUMEUP },
+	{ 0x77fc, KEY_VOLUMEDOWN },
+};
+
+static struct rc_map_list wetek_hub_map = {
+	.map = {
+		.scan     = wetek_hub,
+		.size     = ARRAY_SIZE(wetek_hub),
+		.rc_proto = RC_PROTO_NEC,
+		.name     = RC_MAP_WETEK_HUB,
+	}
+};
+
+static int __init init_rc_map_wetek_hub(void)
+{
+	return rc_map_register(&wetek_hub_map);
+}
+
+static void __exit exit_rc_map_wetek_hub(void)
+{
+	rc_map_unregister(&wetek_hub_map);
+}
+
+module_init(init_rc_map_wetek_hub)
+module_exit(exit_rc_map_wetek_hub)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com>");
diff --git a/drivers/media/rc/keymaps/rc-wetek-play2.c b/drivers/media/rc/keymaps/rc-wetek-play2.c
new file mode 100644
index 0000000..bbbb11f
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-wetek-play2.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (C) 2019 Christian Hewitt <christianshewitt@gmail.com>
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+//
+// Keytable for the WeTek Play 2 STB remote control
+//
+
+static struct rc_map_table wetek_play2[] = {
+	{ 0x5e5f02, KEY_POWER },
+	{ 0x5e5f46, KEY_SLEEP }, // tv
+	{ 0x5e5f10, KEY_MUTE },
+
+	{ 0x5e5f22, KEY_1 },
+	{ 0x5e5f23, KEY_2 },
+	{ 0x5e5f24, KEY_3 },
+
+	{ 0x5e5f25, KEY_4 },
+	{ 0x5e5f26, KEY_5 },
+	{ 0x5e5f27, KEY_6 },
+
+	{ 0x5e5f28, KEY_7 },
+	{ 0x5e5f29, KEY_8 },
+	{ 0x5e5f30, KEY_9 },
+
+	{ 0x5e5f71, KEY_BACK },
+	{ 0x5e5f21, KEY_0 },
+	{ 0x5e5f72, KEY_CAPSLOCK },
+
+	// outer ring clockwide from top
+	{ 0x5e5f03, KEY_HOME },
+	{ 0x5e5f61, KEY_BACK },
+	{ 0x5e5f77, KEY_CONFIG }, // mouse
+	{ 0x5e5f83, KEY_EPG },
+	{ 0x5e5f84, KEY_SCREEN }, // square
+	{ 0x5e5f48, KEY_MENU },
+
+	// inner ring
+	{ 0x5e5f50, KEY_UP },
+	{ 0x5e5f4b, KEY_DOWN },
+	{ 0x5e5f4c, KEY_LEFT },
+	{ 0x5e5f4d, KEY_RIGHT },
+	{ 0x5e5f47, KEY_OK },
+
+	{ 0x5e5f44, KEY_VOLUMEUP },
+	{ 0x5e5f43, KEY_VOLUMEDOWN },
+	{ 0x5e5f4f, KEY_FAVORITES },
+	{ 0x5e5f82, KEY_SUBTITLE }, // txt
+	{ 0x5e5f41, KEY_PAGEUP },
+	{ 0x5e5f42, KEY_PAGEDOWN },
+
+	{ 0x5e5f73, KEY_RED },
+	{ 0x5e5f74, KEY_GREEN },
+	{ 0x5e5f75, KEY_YELLOW },
+	{ 0x5e5f76, KEY_BLUE },
+
+	{ 0x5e5f67, KEY_PREVIOUSSONG },
+	{ 0x5e5f79, KEY_REWIND },
+	{ 0x5e5f80, KEY_FASTFORWARD },
+	{ 0x5e5f81, KEY_NEXTSONG },
+
+	{ 0x5e5f04, KEY_RECORD },
+	{ 0x5e5f2c, KEY_PLAYPAUSE },
+	{ 0x5e5f2b, KEY_STOP },
+};
+
+static struct rc_map_list wetek_play2_map = {
+	.map = {
+		.scan     = wetek_play2,
+		.size     = ARRAY_SIZE(wetek_play2),
+		.rc_proto = RC_PROTO_NECX,
+		.name     = RC_MAP_WETEK_PLAY2,
+	}
+};
+
+static int __init init_rc_map_wetek_play2(void)
+{
+	return rc_map_register(&wetek_play2_map);
+}
+
+static void __exit exit_rc_map_wetek_play2(void)
+{
+	rc_map_unregister(&wetek_play2_map);
+}
+
+module_init(init_rc_map_wetek_play2)
+module_exit(exit_rc_map_wetek_play2)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com");
diff --git a/drivers/media/rc/keymaps/rc-x96max.c b/drivers/media/rc/keymaps/rc-x96max.c
new file mode 100644
index 0000000..0998ec3
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-x96max.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright (C) 2019 Christian Hewitt <christianshewitt@gmail.com>
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+//
+// Keytable for the X96-max STB remote control
+//
+
+static struct rc_map_table x96max[] = {
+	{ 0x140, KEY_POWER },
+
+	// ** TV CONTROL **
+	// SET
+	// AV/TV
+	// POWER
+	// VOLUME UP
+	// VOLUME DOWN
+
+	{ 0x118, KEY_VOLUMEUP },
+	{ 0x110, KEY_VOLUMEDOWN },
+
+	{ 0x143, KEY_MUTE }, // config
+
+	{ 0x100, KEY_EPG }, // mouse
+	{ 0x119, KEY_BACK },
+
+	{ 0x116, KEY_UP },
+	{ 0x151, KEY_LEFT },
+	{ 0x150, KEY_RIGHT },
+	{ 0x11a, KEY_DOWN },
+	{ 0x113, KEY_OK },
+
+	{ 0x111, KEY_HOME },
+	{ 0x14c, KEY_CONTEXT_MENU },
+
+	{ 0x159, KEY_PREVIOUS },
+	{ 0x15a, KEY_PLAYPAUSE },
+	{ 0x158, KEY_NEXT },
+
+	{ 0x147, KEY_MENU }, // @ key
+	{ 0x101, KEY_NUMERIC_0 },
+	{ 0x142, KEY_BACKSPACE },
+
+	{ 0x14e, KEY_NUMERIC_1 },
+	{ 0x10d, KEY_NUMERIC_2 },
+	{ 0x10c, KEY_NUMERIC_3 },
+
+	{ 0x14a, KEY_NUMERIC_4 },
+	{ 0x109, KEY_NUMERIC_5 },
+	{ 0x108, KEY_NUMERIC_6 },
+
+	{ 0x146, KEY_NUMERIC_7 },
+	{ 0x105, KEY_NUMERIC_8 },
+	{ 0x104, KEY_NUMERIC_9 },
+};
+
+static struct rc_map_list x96max_map = {
+	.map = {
+		.scan     = x96max,
+		.size     = ARRAY_SIZE(x96max),
+		.rc_proto = RC_PROTO_NEC,
+		.name     = RC_MAP_X96MAX,
+	}
+};
+
+static int __init init_rc_map_x96max(void)
+{
+	return rc_map_register(&x96max_map);
+}
+
+static void __exit exit_rc_map_x96max(void)
+{
+	rc_map_unregister(&x96max_map);
+}
+
+module_init(init_rc_map_x96max)
+module_exit(exit_rc_map_x96max)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Hewitt <christianshewitt@gmail.com");
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 4d5351e..3fc9829 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -31,21 +31,22 @@
 #include <linux/pm_wakeup.h>
 #include <media/rc-core.h>
 
-#define DRIVER_VERSION	"1.94"
+#define DRIVER_VERSION	"1.95"
 #define DRIVER_AUTHOR	"Jarod Wilson <jarod@redhat.com>"
 #define DRIVER_DESC	"Windows Media Center Ed. eHome Infrared Transceiver " \
 			"device driver"
 #define DRIVER_NAME	"mceusb"
 
+#define USB_TX_TIMEOUT		1000 /* in milliseconds */
 #define USB_CTRL_MSG_SZ		2  /* Size of usb ctrl msg on gen1 hw */
 #define MCE_G1_INIT_MSGS	40 /* Init messages on gen1 hw to throw out */
 
 /* MCE constants */
-#define MCE_CMDBUF_SIZE		384  /* MCE Command buffer length */
+#define MCE_IRBUF_SIZE		128  /* TX IR buffer length */
 #define MCE_TIME_UNIT		50   /* Approx 50us resolution */
-#define MCE_CODE_LENGTH		5    /* Normal length of packet (with header) */
-#define MCE_PACKET_SIZE		4    /* Normal length of packet (without header) */
-#define MCE_IRDATA_HEADER	0x84 /* Actual header format is 0x80 + num_bytes */
+#define MCE_PACKET_SIZE		31   /* Max length of packet (with header) */
+#define MCE_IRDATA_HEADER	(0x80 + MCE_PACKET_SIZE - 1)
+				     /* Actual format is 0x80 + num_bytes */
 #define MCE_IRDATA_TRAILER	0x80 /* End of IR data */
 #define MCE_MAX_CHANNELS	2    /* Two transmitters, hardware dependent? */
 #define MCE_DEFAULT_TX_MASK	0x03 /* Vals: TX1=0x01, TX2=0x02, ALL=0x03 */
@@ -461,6 +462,7 @@
 
 	/* usb */
 	struct usb_device *usbdev;
+	struct usb_interface *usbintf;
 	struct urb *urb_in;
 	unsigned int pipe_in;
 	struct usb_endpoint_descriptor *usb_ep_out;
@@ -517,6 +519,7 @@
 	unsigned long kevent_flags;
 #		define EVENT_TX_HALT	0
 #		define EVENT_RX_HALT	1
+#		define EVENT_RST_PEND	31
 };
 
 /* MCE Device Command Strings, generally a port and command pair */
@@ -607,9 +610,9 @@
 	if (len <= skip)
 		return;
 
-	dev_dbg(dev, "%cx data: %*ph (length=%d)",
-		(out ? 't' : 'r'),
-		min(len, buf_len - offset), buf + offset, len);
+	dev_dbg(dev, "%cx data[%d]: %*ph (len=%d sz=%d)",
+		(out ? 't' : 'r'), offset,
+		min(len, buf_len - offset), buf + offset, len, buf_len);
 
 	inout = out ? "Request" : "Got";
 
@@ -731,6 +734,9 @@
 		case MCE_RSP_CMD_ILLEGAL:
 			dev_dbg(dev, "Illegal PORT_IR command");
 			break;
+		case MCE_RSP_TX_TIMEOUT:
+			dev_dbg(dev, "IR TX timeout (TX buffer underrun)");
+			break;
 		default:
 			dev_dbg(dev, "Unknown command 0x%02x 0x%02x",
 				 cmd, subcmd);
@@ -745,42 +751,107 @@
 		dev_dbg(dev, "End of raw IR data");
 	else if ((cmd != MCE_CMD_PORT_IR) &&
 		 ((cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA))
-		dev_dbg(dev, "Raw IR data, %d pulse/space samples", ir->rem);
+		dev_dbg(dev, "Raw IR data, %d pulse/space samples",
+			cmd & MCE_PACKET_LENGTH_MASK);
 #endif
 }
 
 /*
  * Schedule work that can't be done in interrupt handlers
- * (mceusb_dev_recv() and mce_async_callback()) nor tasklets.
+ * (mceusb_dev_recv() and mce_write_callback()) nor tasklets.
  * Invokes mceusb_deferred_kevent() for recovering from
  * error events specified by the kevent bit field.
  */
 static void mceusb_defer_kevent(struct mceusb_dev *ir, int kevent)
 {
 	set_bit(kevent, &ir->kevent_flags);
+
+	if (test_bit(EVENT_RST_PEND, &ir->kevent_flags)) {
+		dev_dbg(ir->dev, "kevent %d dropped pending USB Reset Device",
+			kevent);
+		return;
+	}
+
 	if (!schedule_work(&ir->kevent))
-		dev_err(ir->dev, "kevent %d may have been dropped", kevent);
+		dev_dbg(ir->dev, "kevent %d already scheduled", kevent);
 	else
 		dev_dbg(ir->dev, "kevent %d scheduled", kevent);
 }
 
-static void mce_async_callback(struct urb *urb)
+static void mce_write_callback(struct urb *urb)
 {
-	struct mceusb_dev *ir;
-	int len;
-
 	if (!urb)
 		return;
 
-	ir = urb->context;
+	complete(urb->context);
+}
+
+/*
+ * Write (TX/send) data to MCE device USB endpoint out.
+ * Used for IR blaster TX and MCE device commands.
+ *
+ * Return: The number of bytes written (> 0) or errno (< 0).
+ */
+static int mce_write(struct mceusb_dev *ir, u8 *data, int size)
+{
+	int ret;
+	struct urb *urb;
+	struct device *dev = ir->dev;
+	unsigned char *buf_out;
+	struct completion tx_done;
+	unsigned long expire;
+	unsigned long ret_wait;
+
+	mceusb_dev_printdata(ir, data, size, 0, size, true);
+
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (unlikely(!urb)) {
+		dev_err(dev, "Error: mce write couldn't allocate urb");
+		return -ENOMEM;
+	}
+
+	buf_out = kmalloc(size, GFP_KERNEL);
+	if (!buf_out) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	init_completion(&tx_done);
+
+	/* outbound data */
+	if (usb_endpoint_xfer_int(ir->usb_ep_out))
+		usb_fill_int_urb(urb, ir->usbdev, ir->pipe_out,
+				 buf_out, size, mce_write_callback, &tx_done,
+				 ir->usb_ep_out->bInterval);
+	else
+		usb_fill_bulk_urb(urb, ir->usbdev, ir->pipe_out,
+				  buf_out, size, mce_write_callback, &tx_done);
+	memcpy(buf_out, data, size);
+
+	ret = usb_submit_urb(urb, GFP_KERNEL);
+	if (ret) {
+		dev_err(dev, "Error: mce write submit urb error = %d", ret);
+		kfree(buf_out);
+		usb_free_urb(urb);
+		return ret;
+	}
+
+	expire = msecs_to_jiffies(USB_TX_TIMEOUT);
+	ret_wait = wait_for_completion_timeout(&tx_done, expire);
+	if (!ret_wait) {
+		dev_err(dev, "Error: mce write timed out (expire = %lu (%dms))",
+			expire, USB_TX_TIMEOUT);
+		usb_kill_urb(urb);
+		ret = (urb->status == -ENOENT ? -ETIMEDOUT : urb->status);
+	} else {
+		ret = urb->status;
+	}
+	if (ret >= 0)
+		ret = urb->actual_length;	/* bytes written */
 
 	switch (urb->status) {
 	/* success */
 	case 0:
-		len = urb->actual_length;
-
-		mceusb_dev_printdata(ir, urb->transfer_buffer, len,
-				     0, len, true);
 		break;
 
 	case -ECONNRESET:
@@ -790,140 +861,135 @@
 		break;
 
 	case -EPIPE:
-		dev_err(ir->dev, "Error: request urb status = %d (TX HALT)",
+		dev_err(ir->dev, "Error: mce write urb status = %d (TX HALT)",
 			urb->status);
 		mceusb_defer_kevent(ir, EVENT_TX_HALT);
 		break;
 
 	default:
-		dev_err(ir->dev, "Error: request urb status = %d", urb->status);
+		dev_err(ir->dev, "Error: mce write urb status = %d",
+			urb->status);
 		break;
 	}
 
-	/* the transfer buffer and urb were allocated in mce_request_packet */
-	kfree(urb->transfer_buffer);
+	dev_dbg(dev, "tx done status = %d (wait = %lu, expire = %lu (%dms), urb->actual_length = %d, urb->status = %d)",
+		ret, ret_wait, expire, USB_TX_TIMEOUT,
+		urb->actual_length, urb->status);
+
+	kfree(buf_out);
 	usb_free_urb(urb);
+
+	return ret;
 }
 
-/* request outgoing (send) usb packet - used to initialize remote */
-static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
-								int size)
-{
-	int res;
-	struct urb *async_urb;
-	struct device *dev = ir->dev;
-	unsigned char *async_buf;
-
-	async_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (unlikely(!async_urb)) {
-		dev_err(dev, "Error, couldn't allocate urb!");
-		return;
-	}
-
-	async_buf = kmalloc(size, GFP_KERNEL);
-	if (!async_buf) {
-		usb_free_urb(async_urb);
-		return;
-	}
-
-	/* outbound data */
-	if (usb_endpoint_xfer_int(ir->usb_ep_out))
-		usb_fill_int_urb(async_urb, ir->usbdev, ir->pipe_out,
-				 async_buf, size, mce_async_callback, ir,
-				 ir->usb_ep_out->bInterval);
-	else
-		usb_fill_bulk_urb(async_urb, ir->usbdev, ir->pipe_out,
-				  async_buf, size, mce_async_callback, ir);
-
-	memcpy(async_buf, data, size);
-
-	dev_dbg(dev, "send request called (size=%#x)", size);
-
-	res = usb_submit_urb(async_urb, GFP_ATOMIC);
-	if (res) {
-		dev_err(dev, "send request FAILED! (res=%d)", res);
-		kfree(async_buf);
-		usb_free_urb(async_urb);
-		return;
-	}
-	dev_dbg(dev, "send request complete (res=%d)", res);
-}
-
-static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
+static void mce_command_out(struct mceusb_dev *ir, u8 *data, int size)
 {
 	int rsize = sizeof(DEVICE_RESUME);
 
 	if (ir->need_reset) {
 		ir->need_reset = false;
-		mce_request_packet(ir, DEVICE_RESUME, rsize);
+		mce_write(ir, DEVICE_RESUME, rsize);
 		msleep(10);
 	}
 
-	mce_request_packet(ir, data, size);
+	mce_write(ir, data, size);
 	msleep(10);
 }
 
-/* Send data out the IR blaster port(s) */
+/*
+ * Transmit IR out the MCE device IR blaster port(s).
+ *
+ * Convert IR pulse/space sequence from LIRC to MCE format.
+ * Break up a long IR sequence into multiple parts (MCE IR data packets).
+ *
+ * u32 txbuf[] consists of IR pulse, space, ..., and pulse times in usec.
+ * Pulses and spaces are implicit by their position.
+ * The first IR sample, txbuf[0], is always a pulse.
+ *
+ * u8 irbuf[] consists of multiple IR data packets for the MCE device.
+ * A packet is 1 u8 MCE_IRDATA_HEADER and up to 30 u8 IR samples.
+ * An IR sample is 1-bit pulse/space flag with 7-bit time
+ * in MCE time units (50usec).
+ *
+ * Return: The number of IR samples sent (> 0) or errno (< 0).
+ */
 static int mceusb_tx_ir(struct rc_dev *dev, unsigned *txbuf, unsigned count)
 {
 	struct mceusb_dev *ir = dev->priv;
-	int i, length, ret = 0;
-	int cmdcount = 0;
-	unsigned char cmdbuf[MCE_CMDBUF_SIZE];
-
-	/* MCE tx init header */
-	cmdbuf[cmdcount++] = MCE_CMD_PORT_IR;
-	cmdbuf[cmdcount++] = MCE_CMD_SETIRTXPORTS;
-	cmdbuf[cmdcount++] = ir->tx_mask;
+	u8 cmdbuf[3] = { MCE_CMD_PORT_IR, MCE_CMD_SETIRTXPORTS, 0x00 };
+	u8 irbuf[MCE_IRBUF_SIZE];
+	int ircount = 0;
+	unsigned int irsample;
+	int i, length, ret;
 
 	/* Send the set TX ports command */
-	mce_async_out(ir, cmdbuf, cmdcount);
-	cmdcount = 0;
+	cmdbuf[2] = ir->tx_mask;
+	mce_command_out(ir, cmdbuf, sizeof(cmdbuf));
 
-	/* Generate mce packet data */
-	for (i = 0; (i < count) && (cmdcount < MCE_CMDBUF_SIZE); i++) {
-		txbuf[i] = txbuf[i] / MCE_TIME_UNIT;
+	/* Generate mce IR data packet */
+	for (i = 0; i < count; i++) {
+		irsample = txbuf[i] / MCE_TIME_UNIT;
 
-		do { /* loop to support long pulses/spaces > 127*50us=6.35ms */
-
-			/* Insert mce packet header every 4th entry */
-			if ((cmdcount < MCE_CMDBUF_SIZE) &&
-			    (cmdcount % MCE_CODE_LENGTH) == 0)
-				cmdbuf[cmdcount++] = MCE_IRDATA_HEADER;
-
-			/* Insert mce packet data */
-			if (cmdcount < MCE_CMDBUF_SIZE)
-				cmdbuf[cmdcount++] =
-					(txbuf[i] < MCE_PULSE_BIT ?
-					 txbuf[i] : MCE_MAX_PULSE_LENGTH) |
-					 (i & 1 ? 0x00 : MCE_PULSE_BIT);
-			else {
-				ret = -EINVAL;
-				goto out;
+		/* loop to support long pulses/spaces > 6350us (127*50us) */
+		while (irsample > 0) {
+			/* Insert IR header every 30th entry */
+			if (ircount % MCE_PACKET_SIZE == 0) {
+				/* Room for IR header and one IR sample? */
+				if (ircount >= MCE_IRBUF_SIZE - 1) {
+					/* Send near full buffer */
+					ret = mce_write(ir, irbuf, ircount);
+					if (ret < 0)
+						return ret;
+					ircount = 0;
+				}
+				irbuf[ircount++] = MCE_IRDATA_HEADER;
 			}
 
-		} while ((txbuf[i] > MCE_MAX_PULSE_LENGTH) &&
-			 (txbuf[i] -= MCE_MAX_PULSE_LENGTH));
-	}
+			/* Insert IR sample */
+			if (irsample <= MCE_MAX_PULSE_LENGTH) {
+				irbuf[ircount] = irsample;
+				irsample = 0;
+			} else {
+				irbuf[ircount] = MCE_MAX_PULSE_LENGTH;
+				irsample -= MCE_MAX_PULSE_LENGTH;
+			}
+			/*
+			 * Even i = IR pulse
+			 * Odd  i = IR space
+			 */
+			irbuf[ircount] |= (i & 1 ? 0 : MCE_PULSE_BIT);
+			ircount++;
 
-	/* Check if we have room for the empty packet at the end */
-	if (cmdcount >= MCE_CMDBUF_SIZE) {
-		ret = -EINVAL;
-		goto out;
-	}
+			/* IR buffer full? */
+			if (ircount >= MCE_IRBUF_SIZE) {
+				/* Fix packet length in last header */
+				length = ircount % MCE_PACKET_SIZE;
+				if (length > 0)
+					irbuf[ircount - length] -=
+						MCE_PACKET_SIZE - length;
+				/* Send full buffer */
+				ret = mce_write(ir, irbuf, ircount);
+				if (ret < 0)
+					return ret;
+				ircount = 0;
+			}
+		}
+	} /* after for loop, 0 <= ircount < MCE_IRBUF_SIZE */
 
 	/* Fix packet length in last header */
-	length = cmdcount % MCE_CODE_LENGTH;
-	cmdbuf[cmdcount - length] -= MCE_CODE_LENGTH - length;
+	length = ircount % MCE_PACKET_SIZE;
+	if (length > 0)
+		irbuf[ircount - length] -= MCE_PACKET_SIZE - length;
 
-	/* All mce commands end with an empty packet (0x80) */
-	cmdbuf[cmdcount++] = MCE_IRDATA_TRAILER;
+	/* Append IR trailer (0x80) to final partial (or empty) IR buffer */
+	irbuf[ircount++] = MCE_IRDATA_TRAILER;
 
-	/* Transmit the command to the mce device */
-	mce_async_out(ir, cmdbuf, cmdcount);
+	/* Send final buffer */
+	ret = mce_write(ir, irbuf, ircount);
+	if (ret < 0)
+		return ret;
 
-out:
-	return ret ? ret : count;
+	return count;
 }
 
 /* Sets active IR outputs -- mce devices typically have two */
@@ -963,7 +1029,7 @@
 			cmdbuf[2] = MCE_CMD_SIG_END;
 			cmdbuf[3] = MCE_IRDATA_TRAILER;
 			dev_dbg(ir->dev, "disabling carrier modulation");
-			mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+			mce_command_out(ir, cmdbuf, sizeof(cmdbuf));
 			return 0;
 		}
 
@@ -977,7 +1043,7 @@
 								carrier);
 
 				/* Transmit new carrier to mce device */
-				mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+				mce_command_out(ir, cmdbuf, sizeof(cmdbuf));
 				return 0;
 			}
 		}
@@ -1000,10 +1066,10 @@
 	cmdbuf[2] = units >> 8;
 	cmdbuf[3] = units;
 
-	mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+	mce_command_out(ir, cmdbuf, sizeof(cmdbuf));
 
 	/* get receiver timeout value */
-	mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
+	mce_command_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
 
 	return 0;
 }
@@ -1028,7 +1094,7 @@
 		ir->wideband_rx_enabled = false;
 		cmdbuf[2] = 1;	/* port 1 is long range receiver */
 	}
-	mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+	mce_command_out(ir, cmdbuf, sizeof(cmdbuf));
 	/* response from device sets ir->learning_active */
 
 	return 0;
@@ -1051,7 +1117,7 @@
 		ir->carrier_report_enabled = true;
 		if (!ir->learning_active) {
 			cmdbuf[2] = 2;	/* port 2 is short range receiver */
-			mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+			mce_command_out(ir, cmdbuf, sizeof(cmdbuf));
 		}
 	} else {
 		ir->carrier_report_enabled = false;
@@ -1062,7 +1128,7 @@
 		 */
 		if (ir->learning_active && !ir->wideband_rx_enabled) {
 			cmdbuf[2] = 1;	/* port 1 is long range receiver */
-			mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+			mce_command_out(ir, cmdbuf, sizeof(cmdbuf));
 		}
 	}
 
@@ -1141,6 +1207,7 @@
 		}
 		break;
 	case MCE_RSP_CMD_ILLEGAL:
+	case MCE_RSP_TX_TIMEOUT:
 		ir->need_reset = true;
 		break;
 	default:
@@ -1279,7 +1346,7 @@
 {
 	/* If we get no reply or an illegal command reply, its ver 1, says MS */
 	ir->emver = 1;
-	mce_async_out(ir, GET_EMVER, sizeof(GET_EMVER));
+	mce_command_out(ir, GET_EMVER, sizeof(GET_EMVER));
 }
 
 static void mceusb_gen1_init(struct mceusb_dev *ir)
@@ -1325,10 +1392,10 @@
 	dev_dbg(dev, "set handshake  - retC = %d", ret);
 
 	/* device resume */
-	mce_async_out(ir, DEVICE_RESUME, sizeof(DEVICE_RESUME));
+	mce_command_out(ir, DEVICE_RESUME, sizeof(DEVICE_RESUME));
 
 	/* get hw/sw revision? */
-	mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
+	mce_command_out(ir, GET_REVISION, sizeof(GET_REVISION));
 
 	kfree(data);
 }
@@ -1336,13 +1403,13 @@
 static void mceusb_gen2_init(struct mceusb_dev *ir)
 {
 	/* device resume */
-	mce_async_out(ir, DEVICE_RESUME, sizeof(DEVICE_RESUME));
+	mce_command_out(ir, DEVICE_RESUME, sizeof(DEVICE_RESUME));
 
 	/* get wake version (protocol, key, address) */
-	mce_async_out(ir, GET_WAKEVERSION, sizeof(GET_WAKEVERSION));
+	mce_command_out(ir, GET_WAKEVERSION, sizeof(GET_WAKEVERSION));
 
 	/* unknown what this one actually returns... */
-	mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2));
+	mce_command_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2));
 }
 
 static void mceusb_get_parameters(struct mceusb_dev *ir)
@@ -1356,24 +1423,24 @@
 	ir->num_rxports = 2;
 
 	/* get number of tx and rx ports */
-	mce_async_out(ir, GET_NUM_PORTS, sizeof(GET_NUM_PORTS));
+	mce_command_out(ir, GET_NUM_PORTS, sizeof(GET_NUM_PORTS));
 
 	/* get the carrier and frequency */
-	mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
+	mce_command_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
 
 	if (ir->num_txports && !ir->flags.no_tx)
 		/* get the transmitter bitmask */
-		mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
+		mce_command_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
 
 	/* get receiver timeout value */
-	mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
+	mce_command_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
 
 	/* get receiver sensor setting */
-	mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR));
+	mce_command_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR));
 
 	for (i = 0; i < ir->num_txports; i++) {
 		cmdbuf[2] = i;
-		mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+		mce_command_out(ir, cmdbuf, sizeof(cmdbuf));
 	}
 }
 
@@ -1382,7 +1449,7 @@
 	if (ir->emver < 2)
 		return;
 
-	mce_async_out(ir, FLASH_LED, sizeof(FLASH_LED));
+	mce_command_out(ir, FLASH_LED, sizeof(FLASH_LED));
 }
 
 /*
@@ -1398,28 +1465,59 @@
 		container_of(work, struct mceusb_dev, kevent);
 	int status;
 
+	dev_err(ir->dev, "kevent handler called (flags 0x%lx)",
+		ir->kevent_flags);
+
+	if (test_bit(EVENT_RST_PEND, &ir->kevent_flags)) {
+		dev_err(ir->dev, "kevent handler canceled pending USB Reset Device");
+		return;
+	}
+
 	if (test_bit(EVENT_RX_HALT, &ir->kevent_flags)) {
 		usb_unlink_urb(ir->urb_in);
 		status = usb_clear_halt(ir->usbdev, ir->pipe_in);
+		dev_err(ir->dev, "rx clear halt status = %d", status);
 		if (status < 0) {
-			dev_err(ir->dev, "rx clear halt error %d",
-				status);
+			/*
+			 * Unable to clear RX halt/stall.
+			 * Will need to call usb_reset_device().
+			 */
+			dev_err(ir->dev,
+				"stuck RX HALT state requires USB Reset Device to clear");
+			usb_queue_reset_device(ir->usbintf);
+			set_bit(EVENT_RST_PEND, &ir->kevent_flags);
+			clear_bit(EVENT_RX_HALT, &ir->kevent_flags);
+
+			/* Cancel all other error events and handlers */
+			clear_bit(EVENT_TX_HALT, &ir->kevent_flags);
+			return;
 		}
 		clear_bit(EVENT_RX_HALT, &ir->kevent_flags);
-		if (status == 0) {
-			status = usb_submit_urb(ir->urb_in, GFP_KERNEL);
-			if (status < 0) {
-				dev_err(ir->dev,
-					"rx unhalt submit urb error %d",
-					status);
-			}
+		status = usb_submit_urb(ir->urb_in, GFP_KERNEL);
+		if (status < 0) {
+			dev_err(ir->dev, "rx unhalt submit urb error = %d",
+				status);
 		}
 	}
 
 	if (test_bit(EVENT_TX_HALT, &ir->kevent_flags)) {
 		status = usb_clear_halt(ir->usbdev, ir->pipe_out);
-		if (status < 0)
-			dev_err(ir->dev, "tx clear halt error %d", status);
+		dev_err(ir->dev, "tx clear halt status = %d", status);
+		if (status < 0) {
+			/*
+			 * Unable to clear TX halt/stall.
+			 * Will need to call usb_reset_device().
+			 */
+			dev_err(ir->dev,
+				"stuck TX HALT state requires USB Reset Device to clear");
+			usb_queue_reset_device(ir->usbintf);
+			set_bit(EVENT_RST_PEND, &ir->kevent_flags);
+			clear_bit(EVENT_TX_HALT, &ir->kevent_flags);
+
+			/* Cancel all other error events and handlers */
+			clear_bit(EVENT_RX_HALT, &ir->kevent_flags);
+			return;
+		}
 		clear_bit(EVENT_TX_HALT, &ir->kevent_flags);
 	}
 }
@@ -1581,6 +1679,7 @@
 	if (!ir->urb_in)
 		goto urb_in_alloc_fail;
 
+	ir->usbintf = intf;
 	ir->usbdev = usb_get_dev(dev);
 	ir->dev = &intf->dev;
 	ir->len_in = maxp;
@@ -1688,6 +1787,8 @@
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct mceusb_dev *ir = usb_get_intfdata(intf);
 
+	dev_dbg(&intf->dev, "%s called", __func__);
+
 	usb_set_intfdata(intf, NULL);
 
 	if (!ir)
diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
index 72a7bbb..51c6dd3 100644
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -117,10 +117,8 @@
 		return PTR_ERR(ir->reg);
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		dev_err(dev, "no irq resource\n");
+	if (irq < 0)
 		return irq;
-	}
 
 	ir->rc = devm_rc_allocate_device(dev, RC_DRIVER_IR_RAW);
 	if (!ir->rc) {
diff --git a/drivers/media/rc/mtk-cir.c b/drivers/media/rc/mtk-cir.c
index 50fb0ae..a0c94ab 100644
--- a/drivers/media/rc/mtk-cir.c
+++ b/drivers/media/rc/mtk-cir.c
@@ -35,6 +35,11 @@
 /* Fields containing pulse width data */
 #define MTK_WIDTH_MASK		  (GENMASK(7, 0))
 
+/* IR threshold */
+#define MTK_IRTHD		 0x14
+#define MTK_DG_CNT_MASK		 (GENMASK(12, 8))
+#define MTK_DG_CNT(x)		 ((x) << 8)
+
 /* Bit to enable interrupt */
 #define MTK_IRINT_EN		  BIT(0)
 
@@ -340,7 +345,7 @@
 	ir->rc->map_name = map_name ?: RC_MAP_EMPTY;
 	ir->rc->dev.parent = dev;
 	ir->rc->driver_name = MTK_IR_DEV;
-	ir->rc->allowed_protocols = RC_PROTO_BIT_ALL;
+	ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
 	ir->rc->rx_resolution = MTK_IR_SAMPLE;
 	ir->rc->timeout = MTK_MAX_SAMPLES * (MTK_IR_SAMPLE + 1);
 
@@ -353,10 +358,8 @@
 	platform_set_drvdata(pdev, ir);
 
 	ir->irq = platform_get_irq(pdev, 0);
-	if (ir->irq < 0) {
-		dev_err(dev, "no irq resource\n");
+	if (ir->irq < 0)
 		return -ENODEV;
-	}
 
 	if (clk_prepare_enable(ir->clk)) {
 		dev_err(dev, "try to enable ir_clk failed\n");
@@ -398,6 +401,9 @@
 	mtk_w32_mask(ir, val, ir->data->fields[MTK_HW_PERIOD].mask,
 		     ir->data->fields[MTK_HW_PERIOD].reg);
 
+	/* Set de-glitch counter */
+	mtk_w32_mask(ir, MTK_DG_CNT(1), MTK_DG_CNT_MASK, MTK_IRTHD);
+
 	/* Enable IR and PWM */
 	val = mtk_r32(ir, MTK_CONFIG_HIGH_REG);
 	val |= MTK_OK_COUNT(ir->data->ok_count) |  MTK_PWM_EN | MTK_IR_EN;
diff --git a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c
index aa719d0..e222b4c 100644
--- a/drivers/media/rc/sunxi-cir.c
+++ b/drivers/media/rc/sunxi-cir.c
@@ -39,11 +39,11 @@
 
 /* Rx Interrupt Enable */
 #define SUNXI_IR_RXINT_REG    0x2C
-/* Rx FIFO Overflow */
+/* Rx FIFO Overflow Interrupt Enable */
 #define REG_RXINT_ROI_EN		BIT(0)
-/* Rx Packet End */
+/* Rx Packet End Interrupt Enable */
 #define REG_RXINT_RPEI_EN		BIT(1)
-/* Rx FIFO Data Available */
+/* Rx FIFO Data Available Interrupt Enable */
 #define REG_RXINT_RAI_EN		BIT(4)
 
 /* Rx FIFO available byte level */
@@ -51,6 +51,12 @@
 
 /* Rx Interrupt Status */
 #define SUNXI_IR_RXSTA_REG    0x30
+/* Rx FIFO Overflow */
+#define REG_RXSTA_ROI			REG_RXINT_ROI_EN
+/* Rx Packet End */
+#define REG_RXSTA_RPE			REG_RXINT_RPEI_EN
+/* Rx FIFO Data Available */
+#define REG_RXSTA_RA			REG_RXINT_RAI_EN
 /* RX FIFO Get Available Counter */
 #define REG_RXSTA_GET_AC(val) (((val) >> 8) & (ir->fifo_size * 2 - 1))
 /* Clear all interrupt status value */
@@ -72,6 +78,17 @@
 /* Time after which device stops sending data in ms */
 #define SUNXI_IR_TIMEOUT      120
 
+/**
+ * struct sunxi_ir_quirks - Differences between SoC variants.
+ *
+ * @has_reset: SoC needs reset deasserted.
+ * @fifo_size: size of the fifo.
+ */
+struct sunxi_ir_quirks {
+	bool		has_reset;
+	int		fifo_size;
+};
+
 struct sunxi_ir {
 	spinlock_t      ir_lock;
 	struct rc_dev   *rc;
@@ -99,7 +116,7 @@
 	/* clean all pending statuses */
 	writel(status | REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG);
 
-	if (status & (REG_RXINT_RAI_EN | REG_RXINT_RPEI_EN)) {
+	if (status & (REG_RXSTA_RA | REG_RXSTA_RPE)) {
 		/* How many messages in fifo */
 		rc  = REG_RXSTA_GET_AC(status);
 		/* Sanity check */
@@ -115,9 +132,9 @@
 		}
 	}
 
-	if (status & REG_RXINT_ROI_EN) {
+	if (status & REG_RXSTA_ROI) {
 		ir_raw_event_reset(ir->rc);
-	} else if (status & REG_RXINT_RPEI_EN) {
+	} else if (status & REG_RXSTA_RPE) {
 		ir_raw_event_set_idle(ir->rc, true);
 		ir_raw_event_handle(ir->rc);
 	}
@@ -134,6 +151,7 @@
 
 	struct device *dev = &pdev->dev;
 	struct device_node *dn = dev->of_node;
+	const struct sunxi_ir_quirks *quirks;
 	struct resource *res;
 	struct sunxi_ir *ir;
 	u32 b_clk_freq = SUNXI_IR_BASE_CLK;
@@ -142,12 +160,15 @@
 	if (!ir)
 		return -ENOMEM;
 
+	quirks = of_device_get_match_data(&pdev->dev);
+	if (!quirks) {
+		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
+		return -ENODEV;
+	}
+
 	spin_lock_init(&ir->ir_lock);
 
-	if (of_device_is_compatible(dn, "allwinner,sun5i-a13-ir"))
-		ir->fifo_size = 64;
-	else
-		ir->fifo_size = 16;
+	ir->fifo_size = quirks->fifo_size;
 
 	/* Clock */
 	ir->apb_clk = devm_clk_get(dev, "apb");
@@ -164,13 +185,15 @@
 	/* Base clock frequency (optional) */
 	of_property_read_u32(dn, "clock-frequency", &b_clk_freq);
 
-	/* Reset (optional) */
-	ir->rst = devm_reset_control_get_optional_exclusive(dev, NULL);
-	if (IS_ERR(ir->rst))
-		return PTR_ERR(ir->rst);
-	ret = reset_control_deassert(ir->rst);
-	if (ret)
-		return ret;
+	/* Reset */
+	if (quirks->has_reset) {
+		ir->rst = devm_reset_control_get_exclusive(dev, NULL);
+		if (IS_ERR(ir->rst))
+			return PTR_ERR(ir->rst);
+		ret = reset_control_deassert(ir->rst);
+		if (ret)
+			return ret;
+	}
 
 	ret = clk_set_rate(ir->clk, b_clk_freq);
 	if (ret) {
@@ -233,7 +256,6 @@
 	/* IRQ */
 	ir->irq = platform_get_irq(pdev, 0);
 	if (ir->irq < 0) {
-		dev_err(dev, "no irq resource\n");
 		ret = ir->irq;
 		goto exit_free_dev;
 	}
@@ -306,10 +328,35 @@
 	return 0;
 }
 
+static const struct sunxi_ir_quirks sun4i_a10_ir_quirks = {
+	.has_reset = false,
+	.fifo_size = 16,
+};
+
+static const struct sunxi_ir_quirks sun5i_a13_ir_quirks = {
+	.has_reset = false,
+	.fifo_size = 64,
+};
+
+static const struct sunxi_ir_quirks sun6i_a31_ir_quirks = {
+	.has_reset = true,
+	.fifo_size = 64,
+};
+
 static const struct of_device_id sunxi_ir_match[] = {
-	{ .compatible = "allwinner,sun4i-a10-ir", },
-	{ .compatible = "allwinner,sun5i-a13-ir", },
-	{},
+	{
+		.compatible = "allwinner,sun4i-a10-ir",
+		.data = &sun4i_a10_ir_quirks,
+	},
+	{
+		.compatible = "allwinner,sun5i-a13-ir",
+		.data = &sun5i_a13_ir_quirks,
+	},
+	{
+		.compatible = "allwinner,sun6i-a31-ir",
+		.data = &sun6i_a31_ir_quirks,
+	},
+	{}
 };
 MODULE_DEVICE_TABLE(of, sunxi_ir_match);
 
diff --git a/drivers/media/spi/Kconfig b/drivers/media/spi/Kconfig
index 08386ab..bcc49cb 100644
--- a/drivers/media/spi/Kconfig
+++ b/drivers/media/spi/Kconfig
@@ -1,8 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0-only
 if VIDEO_V4L2
 
+comment "SPI drivers hidden by 'Autoselect ancillary drivers'"
+	depends on MEDIA_HIDE_ANCILLARY_SUBDRV
+
 menu "SPI helper chips"
-	visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
 
 config VIDEO_GS1662
 	tristate "Gennum Serializers video"
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
index a7108e5..e104bb7 100644
--- a/drivers/media/tuners/Kconfig
+++ b/drivers/media/tuners/Kconfig
@@ -15,8 +15,12 @@
 	select MEDIA_TUNER_TDA9887 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MC44S803 if MEDIA_SUBDRV_AUTOSELECT
 
+comment "Tuner drivers hidden by 'Autoselect ancillary drivers'"
+	depends on MEDIA_HIDE_ANCILLARY_SUBDRV
+	depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT
+
 menu "Customize TV tuners"
-	visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
+	visible if !MEDIA_HIDE_ANCILLARY_SUBDRV
 	depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT
 
 config MEDIA_TUNER_SIMPLE
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
index aa6861d..574c3bb 100644
--- a/drivers/media/tuners/tuner-xc2028.c
+++ b/drivers/media/tuners/tuner-xc2028.c
@@ -381,7 +381,7 @@
 			goto corrupt;
 		}
 
-		priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
+		priv->firm[n].ptr = kmemdup(p, size, GFP_KERNEL);
 		if (priv->firm[n].ptr == NULL) {
 			tuner_err("Not enough memory to load firmware file.\n");
 			rc = -ENOMEM;
@@ -394,7 +394,6 @@
 			       type, (unsigned long long)id, size);
 		}
 
-		memcpy(priv->firm[n].ptr, p, size);
 		priv->firm[n].type = type;
 		priv->firm[n].id   = id;
 		priv->firm[n].size = size;
diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
index 43925e2..d960673 100644
--- a/drivers/media/tuners/xc4000.c
+++ b/drivers/media/tuners/xc4000.c
@@ -812,7 +812,7 @@
 			goto corrupt;
 		}
 
-		priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
+		priv->firm[n].ptr = kmemdup(p, size, GFP_KERNEL);
 		if (priv->firm[n].ptr == NULL) {
 			printk(KERN_ERR "Not enough memory to load firmware file.\n");
 			rc = -ENOMEM;
@@ -826,7 +826,6 @@
 			       type, (unsigned long long)id, size);
 		}
 
-		memcpy(priv->firm[n].ptr, p, size);
 		priv->firm[n].type = type;
 		priv->firm[n].id   = id;
 		priv->firm[n].size = size;
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
index b35231f..751703d 100644
--- a/drivers/media/usb/airspy/airspy.c
+++ b/drivers/media/usb/airspy/airspy.c
@@ -71,7 +71,6 @@
 
 /* stream formats */
 struct airspy_format {
-	char	*name;
 	u32	pixelformat;
 	u32	buffersize;
 };
@@ -79,7 +78,6 @@
 /* format descriptions for capture and preview */
 static struct airspy_format formats[] = {
 	{
-		.name		= "Real U12LE",
 		.pixelformat	= V4L2_SDR_FMT_RU12LE,
 		.buffersize	= BULK_BUFFER_SIZE,
 	},
@@ -622,7 +620,6 @@
 	if (f->index >= NUM_FORMATS)
 		return -EINVAL;
 
-	strscpy(f->description, formats[f->index].name, sizeof(f->description));
 	f->pixelformat = formats[f->index].pixelformat;
 
 	return 0;
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 5e00019..d189533 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -1153,7 +1153,6 @@
 	format->fmt.pix.sizeimage = width * height * 2;
 	format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 	format->fmt.pix.field = V4L2_FIELD_INTERLACED;
-	format->fmt.pix.priv = 0;
 
 	if (cmd == VIDIOC_TRY_FMT)
 		return 0;
@@ -1207,10 +1206,6 @@
 
 	dprintk(1, "%s called\n", __func__);
 
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	strscpy(f->description, "Packed YUV2", sizeof(f->description));
-
-	f->flags = 0;
 	f->pixelformat = V4L2_PIX_FMT_UYVY;
 
 	return 0;
@@ -1231,7 +1226,6 @@
 	f->fmt.pix.sizeimage = dev->frame_size;
 	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
 	f->fmt.pix.field = V4L2_FIELD_INTERLACED;
-	f->fmt.pix.priv = 0;
 	return 0;
 }
 
diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c
index 17468f7..3ab80a7 100644
--- a/drivers/media/usb/cpia2/cpia2_usb.c
+++ b/drivers/media/usb/cpia2/cpia2_usb.c
@@ -676,6 +676,10 @@
 		if (!urb) {
 			for (j = 0; j < i; j++)
 				usb_free_urb(cam->sbuf[j].urb);
+			for (j = 0; j < NUM_SBUF; j++) {
+				kfree(cam->sbuf[j].data);
+				cam->sbuf[j].data = NULL;
+			}
 			return -ENOMEM;
 		}
 
diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c
index 0feae82..626264a 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -292,28 +292,13 @@
 static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh,
 					    struct v4l2_fmtdesc *f)
 {
-	int index = f->index;
-
-	if (index < 0 || index > 1)
-	       return -EINVAL;
-
-	memset(f, 0, sizeof(*f));
-	f->index = index;
-	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	f->flags = V4L2_FMT_FLAG_COMPRESSED;
-	switch(index) {
-	case 0:
-		strscpy(f->description, "MJPEG", sizeof(f->description));
-		f->pixelformat = V4L2_PIX_FMT_MJPEG;
-		break;
-	case 1:
-		strscpy(f->description, "JPEG", sizeof(f->description));
-		f->pixelformat = V4L2_PIX_FMT_JPEG;
-		break;
-	default:
+	if (f->index > 1)
 		return -EINVAL;
-	}
 
+	if (f->index == 0)
+		f->pixelformat = V4L2_PIX_FMT_MJPEG;
+	else
+		f->pixelformat = V4L2_PIX_FMT_JPEG;
 	return 0;
 }
 
@@ -338,7 +323,6 @@
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage = cam->frame_size;
 	f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
-	f->fmt.pix.priv = 0;
 
 	switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) {
 	case VIDEOSIZE_VGA:
@@ -449,7 +433,6 @@
 	f->fmt.pix.bytesperline = 0;
 	f->fmt.pix.sizeimage = cam->frame_size;
 	f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
-	f->fmt.pix.priv = 0;
 
 	return 0;
 }
diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c
index 2475f69..6d218a0 100644
--- a/drivers/media/usb/cx231xx/cx231xx-417.c
+++ b/drivers/media/usb/cx231xx/cx231xx-417.c
@@ -1051,6 +1051,7 @@
 	p_current_fw = p_fw;
 	vfree(p_current_fw);
 	p_current_fw = NULL;
+	vfree(p_buffer);
 	uninitGPIO(dev);
 	release_firmware(firmware);
 	dprintk(1, "Firmware upload successful.\n");
@@ -1592,7 +1593,6 @@
 	if (f->index != 0)
 		return -EINVAL;
 
-	strscpy(f->description, "MPEG", sizeof(f->description));
 	f->pixelformat = V4L2_PIX_FMT_MPEG;
 
 	return 0;
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index e0d98ba..e123e74 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1351,7 +1351,7 @@
 /*
  * cx231xx_realease_resources()
  * unregisters the v4l2,i2c and usb devices
- * called when the device gets disconected or at module unload
+ * called when the device gets disconnected or at module unload
 */
 void cx231xx_release_resources(struct cx231xx *dev)
 {
@@ -1924,7 +1924,7 @@
 
 /*
  * cx231xx_usb_disconnect()
- * called when the device gets diconencted
+ * called when the device gets disconnected
  * video device will be unregistered on v4l2_close in case it is still open
  */
 static void cx231xx_usb_disconnect(struct usb_interface *interface)
diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c
index a749baa..982cb56e 100644
--- a/drivers/media/usb/cx231xx/cx231xx-core.c
+++ b/drivers/media/usb/cx231xx/cx231xx-core.c
@@ -53,7 +53,7 @@
 /*
  * cx231xx_realease_resources()
  * unregisters the v4l2,i2c and usb devices
- * called when the device gets disconected or at module unload
+ * called when the device gets disconnected or at module unload
 */
 void cx231xx_remove_from_devlist(struct cx231xx *dev)
 {
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index b651ac7..9b51f07 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -80,7 +80,6 @@
 /* supported video standards */
 static struct cx231xx_fmt format[] = {
 	{
-	 .name = "16bpp YUY2, 4:2:2, packed",
 	 .fourcc = V4L2_PIX_FMT_YUYV,
 	 .depth = 16,
 	 .reg = 0,
@@ -1578,7 +1577,6 @@
 	if (unlikely(f->index >= ARRAY_SIZE(format)))
 		return -EINVAL;
 
-	strscpy(f->description, format[f->index].name, sizeof(f->description));
 	f->pixelformat = format[f->index].fourcc;
 
 	return 0;
@@ -1839,7 +1837,7 @@
 /*
  * cx231xx_realease_resources()
  * unregisters the v4l2,i2c and usb devices
- * called when the device gets disconected or at module unload
+ * called when the device gets disconnected or at module unload
 */
 void cx231xx_release_analog_resources(struct cx231xx *dev)
 {
diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h
index 3efa8ff..b007611 100644
--- a/drivers/media/usb/cx231xx/cx231xx.h
+++ b/drivers/media/usb/cx231xx/cx231xx.h
@@ -121,7 +121,6 @@
 #define CX23417_RESET    9
 
 struct cx23417_fmt {
-	char  *name;
 	u32   fourcc;          /* v4l2 format id */
 	int   depth;
 	int   flags;
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
index 8610487..617a306 100644
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
@@ -540,6 +540,8 @@
 	si2168_config.i2c_adapter = &i2c_adapter;
 	si2168_config.fe = &adap->fe[0];
 	si2168_config.ts_mode = SI2168_TS_PARALLEL;
+	if (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_MYGICA_T230C2)
+		si2168_config.ts_mode |= SI2168_TS_CLK_MANUAL;
 	si2168_config.ts_clock_inv = 1;
 
 	state->i2c_client_demod = dvb_module_probe("si2168", NULL,
@@ -550,11 +552,19 @@
 
 	/* attach tuner */
 	si2157_config.fe = adap->fe[0];
-	si2157_config.if_port = 0;
-
-	state->i2c_client_tuner = dvb_module_probe("si2157", "si2141",
-						   i2c_adapter,
-						   0x60, &si2157_config);
+	if (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_MYGICA_T230) {
+		si2157_config.if_port = 1;
+		state->i2c_client_tuner = dvb_module_probe("si2157", NULL,
+							   i2c_adapter,
+							   0x60,
+							   &si2157_config);
+	} else {
+		si2157_config.if_port = 0;
+		state->i2c_client_tuner = dvb_module_probe("si2157", "si2141",
+							   i2c_adapter,
+							   0x60,
+							   &si2157_config);
+	}
 	if (!state->i2c_client_tuner) {
 		dvb_module_release(state->i2c_client_demod);
 		return -ENODEV;
@@ -776,9 +786,15 @@
 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R4,
 		&dvbsky_s960_props, "Terratec Cinergy S2 Rev.4",
 		RC_MAP_DVBSKY) },
+	{ DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230,
+		&mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230",
+		RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
 	{ DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C,
 		&mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C",
 		RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
+	{ DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C2,
+		&mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C v2",
+		RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
diff --git a/drivers/media/usb/dvb-usb-v2/ec168.c b/drivers/media/usb/dvb-usb-v2/ec168.c
index 0c1fef1..e303058 100644
--- a/drivers/media/usb/dvb-usb-v2/ec168.c
+++ b/drivers/media/usb/dvb-usb-v2/ec168.c
@@ -309,7 +309,7 @@
 /* DVB USB Driver stuff */
 /* bInterfaceNumber 0 is HID
  * bInterfaceNumber 1 is DVB-T */
-static struct dvb_usb_device_properties ec168_props = {
+static const struct dvb_usb_device_properties ec168_props = {
 	.driver_name = KBUILD_MODNAME,
 	.owner = THIS_MODULE,
 	.adapter_nr = adapter_nr,
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c
index b784d9d..c7197e5 100644
--- a/drivers/media/usb/dvb-usb-v2/gl861.c
+++ b/drivers/media/usb/dvb-usb-v2/gl861.c
@@ -353,7 +353,7 @@
 	ret += i2c_transfer(&d->i2c_adap, &msg, 1);
 
 	/* send 32bit(satur, R, G, B) data in serial */
-	mask = 1 << 31;
+	mask = 1UL << 31;
 	for (i = 0; i < 32; i++) {
 		buf[1] = power | FRIIO_CTL_STROBE;
 		if (sat_color & mask)
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index bac0778..f02fa0a 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -78,7 +78,6 @@
 	DVICO_BLUEBIRD_DUAL_4_REV_2,
 	CONEXANT_D680_DMB,
 	MYGICA_D689,
-	MYGICA_T230,
 	NR__cxusb_table_index
 };
 
@@ -456,26 +455,6 @@
 	return 0;
 }
 
-static int cxusb_read_status(struct dvb_frontend *fe,
-			     enum fe_status *status)
-{
-	struct dvb_usb_adapter *adap = (struct dvb_usb_adapter *)fe->dvb->priv;
-	struct cxusb_state *state = (struct cxusb_state *)adap->dev->priv;
-	int ret;
-
-	ret = state->fe_read_status(fe, status);
-
-	/* it need resync slave fifo when signal change from unlock to lock.*/
-	if ((*status & FE_HAS_LOCK) && (!state->last_lock)) {
-		mutex_lock(&state->stream_mutex);
-		cxusb_streaming_ctrl(adap, 1);
-		mutex_unlock(&state->stream_mutex);
-	}
-
-	state->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0;
-	return ret;
-}
-
 static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
 {
 	int       ep = d->props.generic_bulk_ctrl_endpoint;
@@ -1374,86 +1353,6 @@
 	return 0;
 }
 
-static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap)
-{
-	struct dvb_usb_device *d = adap->dev;
-	struct cxusb_state *st = d->priv;
-	struct i2c_adapter *adapter;
-	struct i2c_client *client_demod;
-	struct i2c_client *client_tuner;
-	struct i2c_board_info info;
-	struct si2168_config si2168_config;
-	struct si2157_config si2157_config;
-
-	/* Select required USB configuration */
-	if (usb_set_interface(d->udev, 0, 0) < 0)
-		err("set interface failed");
-
-	/* Unblock all USB pipes */
-	usb_clear_halt(d->udev,
-		       usb_sndbulkpipe(d->udev,
-				       d->props.generic_bulk_ctrl_endpoint));
-	usb_clear_halt(d->udev,
-		       usb_rcvbulkpipe(d->udev,
-				       d->props.generic_bulk_ctrl_endpoint));
-	usb_clear_halt(d->udev,
-		       usb_rcvbulkpipe(d->udev,
-				       d->props.adapter[0].fe[0].stream.endpoint));
-
-	/* attach frontend */
-	si2168_config.i2c_adapter = &adapter;
-	si2168_config.fe = &adap->fe_adap[0].fe;
-	si2168_config.ts_mode = SI2168_TS_PARALLEL;
-	si2168_config.ts_clock_inv = 1;
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strscpy(info.type, "si2168", I2C_NAME_SIZE);
-	info.addr = 0x64;
-	info.platform_data = &si2168_config;
-	request_module(info.type);
-	client_demod = i2c_new_device(&d->i2c_adap, &info);
-	if (!client_demod || !client_demod->dev.driver)
-		return -ENODEV;
-
-	if (!try_module_get(client_demod->dev.driver->owner)) {
-		i2c_unregister_device(client_demod);
-		return -ENODEV;
-	}
-
-	st->i2c_client_demod = client_demod;
-
-	/* attach tuner */
-	memset(&si2157_config, 0, sizeof(si2157_config));
-	si2157_config.fe = adap->fe_adap[0].fe;
-	si2157_config.if_port = 1;
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	strscpy(info.type, "si2157", I2C_NAME_SIZE);
-	info.addr = 0x60;
-	info.platform_data = &si2157_config;
-	request_module(info.type);
-	client_tuner = i2c_new_device(adapter, &info);
-	if (!client_tuner || !client_tuner->dev.driver) {
-		module_put(client_demod->dev.driver->owner);
-		i2c_unregister_device(client_demod);
-		return -ENODEV;
-	}
-	if (!try_module_get(client_tuner->dev.driver->owner)) {
-		i2c_unregister_device(client_tuner);
-		module_put(client_demod->dev.driver->owner);
-		i2c_unregister_device(client_demod);
-		return -ENODEV;
-	}
-
-	st->i2c_client_tuner = client_tuner;
-
-	/* hook fe: need to resync the slave fifo when signal locks. */
-	mutex_init(&st->stream_mutex);
-	st->last_lock = 0;
-	st->fe_read_status = adap->fe_adap[0].fe->ops.read_status;
-	adap->fe_adap[0].fe->ops.read_status = cxusb_read_status;
-
-	return 0;
-}
-
 /*
  * DViCO has shipped two devices with the same USB ID, but only one of them
  * needs a firmware download.  Check the device class details to see if they
@@ -1633,7 +1532,6 @@
 static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
 static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
 static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
-static struct dvb_usb_device_properties cxusb_mygica_t230_properties;
 
 static int cxusb_medion_priv_init(struct dvb_usb_device *dvbdev)
 {
@@ -1759,8 +1657,6 @@
 					THIS_MODULE, NULL, adapter_nr) ||
 		   !dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
 					THIS_MODULE, NULL, adapter_nr) ||
-		   !dvb_usb_device_init(intf, &cxusb_mygica_t230_properties,
-					THIS_MODULE, NULL, adapter_nr) ||
 		   0)
 		return 0;
 
@@ -1862,9 +1758,6 @@
 	[MYGICA_D689] = {
 		USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689)
 	},
-	[MYGICA_T230] = {
-		USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230)
-	},
 	{}		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, cxusb_table);
@@ -2535,60 +2428,6 @@
 	}
 };
 
-static struct dvb_usb_device_properties cxusb_mygica_t230_properties = {
-	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
-
-	.usb_ctrl         = CYPRESS_FX2,
-
-	.size_of_priv     = sizeof(struct cxusb_state),
-
-	.num_adapters = 1,
-	.adapter = {
-		{
-		.num_frontends = 1,
-		.fe = {{
-			.streaming_ctrl   = cxusb_streaming_ctrl,
-			.frontend_attach  = cxusb_mygica_t230_frontend_attach,
-
-			/* parameter for the MPEG2-data transfer */
-			.stream = {
-				.type = USB_BULK,
-				.count = 5,
-				.endpoint = 0x02,
-				.u = {
-					.bulk = {
-						.buffersize = 8192,
-					}
-				}
-			},
-		} },
-		},
-	},
-
-	.power_ctrl       = cxusb_d680_dmb_power_ctrl,
-
-	.i2c_algo         = &cxusb_i2c_algo,
-
-	.generic_bulk_ctrl_endpoint = 0x01,
-
-	.rc.core = {
-		.rc_interval	= 100,
-		.rc_codes	= RC_MAP_D680_DMB,
-		.module_name	= KBUILD_MODNAME,
-		.rc_query       = cxusb_d680_dmb_rc_query,
-		.allowed_protos = RC_PROTO_BIT_UNKNOWN,
-	},
-
-	.num_device_descs = 1,
-	.devices = {
-		{
-			"Mygica T230 DVB-T/T2/C",
-			{ NULL },
-			{ &cxusb_table[MYGICA_T230], NULL },
-		},
-	}
-};
-
 static struct usb_driver cxusb_driver = {
 	.name		= "dvb_usb_cxusb",
 	.probe		= cxusb_probe,
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
index 66d6850..ab7a100 100644
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -2439,9 +2439,13 @@
 		8, 0x0486,
 	};
 
+	if (!IS_ENABLED(CONFIG_DVB_DIB9000))
+		return -ENODEV;
 	if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &dib9090_dib0090_config) == NULL)
 		return -ENODEV;
 	i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
+	if (!i2c)
+		return -ENODEV;
 	if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
 		return -ENODEV;
 	dib0700_set_i2c_speed(adap->dev, 1500);
@@ -2517,10 +2521,14 @@
 		0, 0x00ef,
 		8, 0x0406,
 	};
+	if (!IS_ENABLED(CONFIG_DVB_DIB9000))
+		return -ENODEV;
 	i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe);
 	if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &nim9090md_dib0090_config[0]) == NULL)
 		return -ENODEV;
 	i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
+	if (!i2c)
+		return -ENODEV;
 	if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
 		return -ENODEV;
 
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index d6b36e4..441d878 100644
--- a/drivers/media/usb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -909,14 +909,6 @@
 						&a->dev->i2c_adap);
 	if (!a->fe_adap[0].fe)
 		return -ENODEV;
-
-	/*
-	 * dvb_frontend will call dvb_detach for both stb0899_detach
-	 * and stb0899_release but we only do dvb_attach(stb0899_attach).
-	 * Increment the module refcount instead.
-	 */
-	symbol_get(stb0899_attach);
-
 	if ((dvb_attach(lnbp22_attach, a->fe_adap[0].fe,
 					&a->dev->i2c_adap)) == NULL)
 		err("Cannot attach lnbp22\n");
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
index c659e18..676d233 100644
--- a/drivers/media/usb/dvb-usb/technisat-usb2.c
+++ b/drivers/media/usb/dvb-usb/technisat-usb2.c
@@ -608,10 +608,9 @@
 static int technisat_usb2_get_ir(struct dvb_usb_device *d)
 {
 	struct technisat_usb2_state *state = d->priv;
-	u8 *buf = state->buf;
-	u8 *b;
-	int ret;
 	struct ir_raw_event ev;
+	u8 *buf = state->buf;
+	int i, ret;
 
 	buf[0] = GET_IR_DATA_VENDOR_REQUEST;
 	buf[1] = 0x08;
@@ -647,26 +646,25 @@
 		return 0; /* no key pressed */
 
 	/* decoding */
-	b = buf+1;
 
 #if 0
 	deb_rc("RC: %d ", ret);
-	debug_dump(b, ret, deb_rc);
+	debug_dump(buf + 1, ret, deb_rc);
 #endif
 
 	ev.pulse = 0;
-	while (1) {
-		ev.pulse = !ev.pulse;
-		ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000;
-		ir_raw_event_store(d->rc_dev, &ev);
-
-		b++;
-		if (*b == 0xff) {
+	for (i = 1; i < ARRAY_SIZE(state->buf); i++) {
+		if (buf[i] == 0xff) {
 			ev.pulse = 0;
 			ev.duration = 888888*2;
 			ir_raw_event_store(d->rc_dev, &ev);
 			break;
 		}
+
+		ev.pulse = !ev.pulse;
+		ev.duration = (buf[i] * FIRMWARE_CLOCK_DIVISOR *
+			       FIRMWARE_CLOCK_TICK) / 1000;
+		ir_raw_event_store(d->rc_dev, &ev);
 	}
 
 	ir_raw_event_handle(d->rc_dev);
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 1283c7c..5983e72 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -3566,13 +3566,12 @@
 static int em28xx_duplicate_dev(struct em28xx *dev)
 {
 	int nr;
-	struct em28xx *sec_dev = kzalloc(sizeof(*sec_dev), GFP_KERNEL);
+	struct em28xx *sec_dev = kmemdup(dev, sizeof(*sec_dev), GFP_KERNEL);
 
 	if (!sec_dev) {
 		dev->dev_next = NULL;
 		return -ENOMEM;
 	}
-	memcpy(sec_dev, dev, sizeof(*sec_dev));
 	/* Check to see next free device and mark as used */
 	do {
 		nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS);
@@ -4020,7 +4019,6 @@
 		dev->dev_next->disconnected = 1;
 		dev_info(&dev->intf->dev, "Disconnecting %s\n",
 			 dev->dev_next->name);
-		flush_request_modules(dev->dev_next);
 	}
 
 	dev->disconnected = 1;
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
index 2b8c84a..e6088b5 100644
--- a/drivers/media/usb/em28xx/em28xx-core.c
+++ b/drivers/media/usb/em28xx/em28xx-core.c
@@ -931,7 +931,7 @@
 
 	usb_bufs->buf = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL);
 	if (!usb_bufs->buf) {
-		kfree(usb_bufs->buf);
+		kfree(usb_bufs->urb);
 		return -ENOMEM;
 	}
 
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 0512e19..b0f7390 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -102,37 +102,30 @@
 /* supported video standards */
 static struct em28xx_fmt format[] = {
 	{
-		.name     = "16 bpp YUY2, 4:2:2, packed",
 		.fourcc   = V4L2_PIX_FMT_YUYV,
 		.depth    = 16,
 		.reg	  = EM28XX_OUTFMT_YUV422_Y0UY1V,
 	}, {
-		.name     = "16 bpp RGB 565, LE",
 		.fourcc   = V4L2_PIX_FMT_RGB565,
 		.depth    = 16,
 		.reg      = EM28XX_OUTFMT_RGB_16_656,
 	}, {
-		.name     = "8 bpp Bayer RGRG..GBGB",
 		.fourcc   = V4L2_PIX_FMT_SRGGB8,
 		.depth    = 8,
 		.reg      = EM28XX_OUTFMT_RGB_8_RGRG,
 	}, {
-		.name     = "8 bpp Bayer BGBG..GRGR",
 		.fourcc   = V4L2_PIX_FMT_SBGGR8,
 		.depth    = 8,
 		.reg      = EM28XX_OUTFMT_RGB_8_BGBG,
 	}, {
-		.name     = "8 bpp Bayer GRGR..BGBG",
 		.fourcc   = V4L2_PIX_FMT_SGRBG8,
 		.depth    = 8,
 		.reg      = EM28XX_OUTFMT_RGB_8_GRGR,
 	}, {
-		.name     = "8 bpp Bayer GBGB..RGRG",
 		.fourcc   = V4L2_PIX_FMT_SGBRG8,
 		.depth    = 8,
 		.reg      = EM28XX_OUTFMT_RGB_8_GBGB,
 	}, {
-		.name     = "12 bpp YUV411",
 		.fourcc   = V4L2_PIX_FMT_YUV411P,
 		.depth    = 12,
 		.reg      = EM28XX_OUTFMT_YUV411,
@@ -1517,7 +1510,6 @@
 	else
 		f->fmt.pix.field = v4l2->interlaced_fieldmode ?
 			   V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
-	f->fmt.pix.priv = 0;
 
 	return 0;
 }
@@ -2011,7 +2003,6 @@
 	if (unlikely(f->index >= ARRAY_SIZE(format)))
 		return -EINVAL;
 
-	strscpy(f->description, format[f->index].name, sizeof(f->description));
 	f->pixelformat = format[f->index].fourcc;
 
 	return 0;
@@ -2208,7 +2199,7 @@
 /*
  * em28xx_v4l2_fini()
  * unregisters the v4l2,i2c and usb devices
- * called when the device gets disconected or at module unload
+ * called when the device gets disconnected or at module unload
  */
 static int em28xx_v4l2_fini(struct em28xx *dev)
 {
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index a551072..c8bc590 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -251,13 +251,11 @@
 /**
  * struct em28xx_fmt - Struct to enumberate video formats
  *
- * @name:	Name for the video standard
  * @fourcc:	v4l2 format id
  * @depth:	mean number of bits to represent a pixel
  * @reg:	em28xx register value to set it
  */
 struct em28xx_fmt {
-	char	*name;
 	u32	fourcc;
 	int	depth;
 	int	reg;
@@ -657,7 +655,7 @@
 	enum em28xx_chip_id chip_id;
 
 	unsigned int is_em25xx:1;	// em25xx/em276x/7x/8x family bridge
-	unsigned int disconnected:1;	// device has been diconnected
+	unsigned int disconnected:1;	// device has been disconnected
 	unsigned int has_video:1;
 	unsigned int is_audio_only:1;
 	unsigned int is_webcam:1;
diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c
index 88edfef..0b3d185f 100644
--- a/drivers/media/usb/go7007/go7007-v4l2.c
+++ b/drivers/media/usb/go7007/go7007-v4l2.c
@@ -285,33 +285,22 @@
 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 					struct v4l2_fmtdesc *fmt)
 {
-	char *desc = NULL;
-
 	switch (fmt->index) {
 	case 0:
 		fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
-		desc = "Motion JPEG";
 		break;
 	case 1:
 		fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
-		desc = "MPEG-1 ES";
 		break;
 	case 2:
 		fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
-		desc = "MPEG-2 ES";
 		break;
 	case 3:
 		fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
-		desc = "MPEG-4 ES";
 		break;
 	default:
 		return -EINVAL;
 	}
-	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
-
-	strscpy(fmt->description, desc, sizeof(fmt->description));
-
 	return 0;
 }
 
diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c
index 179d4d6..49e75a1 100644
--- a/drivers/media/usb/go7007/s2250-board.c
+++ b/drivers/media/usb/go7007/s2250-board.c
@@ -505,9 +505,9 @@
 	struct go7007 *go = i2c_get_adapdata(adapter);
 	struct go7007_usb *usb = go->hpi_context;
 
-	audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1);
-	if (audio == NULL)
-		return -ENOMEM;
+	audio = i2c_new_dummy_device(adapter, TLV320_ADDRESS >> 1);
+	if (IS_ERR(audio))
+		return PTR_ERR(audio);
 
 	state = kzalloc(sizeof(struct s2250), GFP_KERNEL);
 	if (state == NULL) {
diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c
index 4a449c6..b05fa22 100644
--- a/drivers/media/usb/go7007/snd-go7007.c
+++ b/drivers/media/usb/go7007/snd-go7007.c
@@ -253,7 +253,7 @@
 		return ret;
 	}
 	strscpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
-	strscpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
+	strscpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->shortname));
 	strscpy(gosnd->card->longname, gosnd->card->shortname,
 		sizeof(gosnd->card->longname));
 
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index be11f78..4add2b1 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -1024,27 +1024,18 @@
 		return -EINVAL;		/* no more format */
 
 	fmtdesc->pixelformat = fmt_tb[index];
-	if (gspca_dev->cam.cam_mode[i].sizeimage <
-			gspca_dev->cam.cam_mode[i].width *
-				gspca_dev->cam.cam_mode[i].height)
-		fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
-	fmtdesc->description[0] = fmtdesc->pixelformat & 0xff;
-	fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff;
-	fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff;
-	fmtdesc->description[3] = fmtdesc->pixelformat >> 24;
-	fmtdesc->description[4] = '\0';
 	return 0;
 }
 
-static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
-			    struct v4l2_format *fmt)
+static int vidioc_g_fmt_vid_cap(struct file *file, void *_priv,
+				struct v4l2_format *fmt)
 {
 	struct gspca_dev *gspca_dev = video_drvdata(file);
+	u32 priv = fmt->fmt.pix.priv;
 
 	fmt->fmt.pix = gspca_dev->pixfmt;
-	/* some drivers use priv internally, zero it before giving it back to
-	   the core */
-	fmt->fmt.pix.priv = 0;
+	/* some drivers use priv internally, so keep the original value */
+	fmt->fmt.pix.priv = priv;
 	return 0;
 }
 
@@ -1079,27 +1070,27 @@
 		fmt->fmt.pix.height = h;
 		gspca_dev->sd_desc->try_fmt(gspca_dev, fmt);
 	}
-	/* some drivers use priv internally, zero it before giving it back to
-	   the core */
-	fmt->fmt.pix.priv = 0;
 	return mode;			/* used when s_fmt */
 }
 
-static int vidioc_try_fmt_vid_cap(struct file *file,
-			      void *priv,
-			      struct v4l2_format *fmt)
+static int vidioc_try_fmt_vid_cap(struct file *file, void *_priv,
+				  struct v4l2_format *fmt)
 {
 	struct gspca_dev *gspca_dev = video_drvdata(file);
+	u32 priv = fmt->fmt.pix.priv;
 
 	if (try_fmt_vid_cap(gspca_dev, fmt) < 0)
 		return -EINVAL;
+	/* some drivers use priv internally, so keep the original value */
+	fmt->fmt.pix.priv = priv;
 	return 0;
 }
 
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
-			    struct v4l2_format *fmt)
+static int vidioc_s_fmt_vid_cap(struct file *file, void *_priv,
+				struct v4l2_format *fmt)
 {
 	struct gspca_dev *gspca_dev = video_drvdata(file);
+	u32 priv = fmt->fmt.pix.priv;
 	int mode;
 
 	if (vb2_is_busy(&gspca_dev->queue))
@@ -1115,6 +1106,8 @@
 		gspca_dev->pixfmt = fmt->fmt.pix;
 	else
 		gspca_dev->pixfmt = gspca_dev->cam.cam_mode[mode];
+	/* some drivers use priv internally, so keep the original value */
+	fmt->fmt.pix.priv = priv;
 	return 0;
 }
 
diff --git a/drivers/media/usb/gspca/konica.c b/drivers/media/usb/gspca/konica.c
index d8e4013..53db9a2 100644
--- a/drivers/media/usb/gspca/konica.c
+++ b/drivers/media/usb/gspca/konica.c
@@ -114,6 +114,11 @@
 	if (ret < 0) {
 		pr_err("reg_r err %d\n", ret);
 		gspca_dev->usb_err = ret;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(gspca_dev->usb_buf, 0, 2);
 	}
 }
 
diff --git a/drivers/media/usb/gspca/nw80x.c b/drivers/media/usb/gspca/nw80x.c
index 5964970..880f569 100644
--- a/drivers/media/usb/gspca/nw80x.c
+++ b/drivers/media/usb/gspca/nw80x.c
@@ -1572,6 +1572,11 @@
 	if (ret < 0) {
 		pr_err("reg_r err %d\n", ret);
 		gspca_dev->usb_err = ret;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
 		return;
 	}
 	if (len == 1)
diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c
index cfb1f53..f417dfc 100644
--- a/drivers/media/usb/gspca/ov519.c
+++ b/drivers/media/usb/gspca/ov519.c
@@ -2073,6 +2073,11 @@
 	} else {
 		gspca_err(gspca_dev, "reg_r %02x failed %d\n", index, ret);
 		sd->gspca_dev.usb_err = ret;
+		/*
+		 * Make sure the result is zeroed to avoid uninitialized
+		 * values.
+		 */
+		gspca_dev->usb_buf[0] = 0;
 	}
 
 	return ret;
@@ -2101,6 +2106,11 @@
 	} else {
 		gspca_err(gspca_dev, "reg_r8 %02x failed %d\n", index, ret);
 		sd->gspca_dev.usb_err = ret;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(gspca_dev->usb_buf, 0, 8);
 	}
 
 	return ret;
diff --git a/drivers/media/usb/gspca/ov534.c b/drivers/media/usb/gspca/ov534.c
index 56521c9..185c1f1 100644
--- a/drivers/media/usb/gspca/ov534.c
+++ b/drivers/media/usb/gspca/ov534.c
@@ -693,6 +693,11 @@
 	if (ret < 0) {
 		pr_err("read failed %d\n", ret);
 		gspca_dev->usb_err = ret;
+		/*
+		 * Make sure the result is zeroed to avoid uninitialized
+		 * values.
+		 */
+		gspca_dev->usb_buf[0] = 0;
 	}
 	return gspca_dev->usb_buf[0];
 }
diff --git a/drivers/media/usb/gspca/ov534_9.c b/drivers/media/usb/gspca/ov534_9.c
index 867f860..91efc65 100644
--- a/drivers/media/usb/gspca/ov534_9.c
+++ b/drivers/media/usb/gspca/ov534_9.c
@@ -1145,6 +1145,7 @@
 	if (ret < 0) {
 		pr_err("reg_r err %d\n", ret);
 		gspca_dev->usb_err = ret;
+		return 0;
 	}
 	return gspca_dev->usb_buf[0];
 }
diff --git a/drivers/media/usb/gspca/se401.c b/drivers/media/usb/gspca/se401.c
index 061deee..e087cfb 100644
--- a/drivers/media/usb/gspca/se401.c
+++ b/drivers/media/usb/gspca/se401.c
@@ -101,6 +101,11 @@
 			pr_err("read req failed req %#04x error %d\n",
 			       req, err);
 		gspca_dev->usb_err = err;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(gspca_dev->usb_buf, 0, READ_REQ_SIZE);
 	}
 }
 
diff --git a/drivers/media/usb/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c
index b43f89f..2a6d0a1 100644
--- a/drivers/media/usb/gspca/sn9c20x.c
+++ b/drivers/media/usb/gspca/sn9c20x.c
@@ -124,6 +124,13 @@
 		}
 	},
 	{
+		.ident = "MSI MS-1039",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1039"),
+		}
+	},
+	{
 		.ident = "MSI MS-1632",
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
@@ -909,6 +916,11 @@
 	if (unlikely(result < 0 || result != length)) {
 		pr_err("Read register %02x failed %d\n", reg, result);
 		gspca_dev->usb_err = result;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
 	}
 }
 
diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c
index 046fc2c..4d655e2 100644
--- a/drivers/media/usb/gspca/sonixb.c
+++ b/drivers/media/usb/gspca/sonixb.c
@@ -453,6 +453,11 @@
 		dev_err(gspca_dev->v4l2_dev.dev,
 			"Error reading register %02x: %d\n", value, res);
 		gspca_dev->usb_err = res;
+		/*
+		 * Make sure the result is zeroed to avoid uninitialized
+		 * values.
+		 */
+		gspca_dev->usb_buf[0] = 0;
 	}
 }
 
diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c
index 50a6c84..2e1bd2d 100644
--- a/drivers/media/usb/gspca/sonixj.c
+++ b/drivers/media/usb/gspca/sonixj.c
@@ -1162,6 +1162,11 @@
 	if (ret < 0) {
 		pr_err("reg_r err %d\n", ret);
 		gspca_dev->usb_err = ret;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
 	}
 }
 
diff --git a/drivers/media/usb/gspca/spca1528.c b/drivers/media/usb/gspca/spca1528.c
index 2ae03b6..ccc4779 100644
--- a/drivers/media/usb/gspca/spca1528.c
+++ b/drivers/media/usb/gspca/spca1528.c
@@ -71,6 +71,11 @@
 	if (ret < 0) {
 		pr_err("reg_r err %d\n", ret);
 		gspca_dev->usb_err = ret;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
 	}
 }
 
diff --git a/drivers/media/usb/gspca/sq930x.c b/drivers/media/usb/gspca/sq930x.c
index d1ba088..c361024 100644
--- a/drivers/media/usb/gspca/sq930x.c
+++ b/drivers/media/usb/gspca/sq930x.c
@@ -425,6 +425,11 @@
 	if (ret < 0) {
 		pr_err("reg_r %04x failed %d\n", value, ret);
 		gspca_dev->usb_err = ret;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
 	}
 }
 
diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c
index d0ddfa9..f4a4222 100644
--- a/drivers/media/usb/gspca/sunplus.c
+++ b/drivers/media/usb/gspca/sunplus.c
@@ -255,6 +255,11 @@
 	if (ret < 0) {
 		pr_err("reg_r err %d\n", ret);
 		gspca_dev->usb_err = ret;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
 	}
 }
 
diff --git a/drivers/media/usb/gspca/vc032x.c b/drivers/media/usb/gspca/vc032x.c
index 588a847..4cb7c92 100644
--- a/drivers/media/usb/gspca/vc032x.c
+++ b/drivers/media/usb/gspca/vc032x.c
@@ -2906,6 +2906,11 @@
 	if (ret < 0) {
 		pr_err("reg_r err %d\n", ret);
 		gspca_dev->usb_err = ret;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
 	}
 }
 static void reg_r(struct gspca_dev *gspca_dev,
diff --git a/drivers/media/usb/gspca/w996Xcf.c b/drivers/media/usb/gspca/w996Xcf.c
index 16b679c..a8350ee 100644
--- a/drivers/media/usb/gspca/w996Xcf.c
+++ b/drivers/media/usb/gspca/w996Xcf.c
@@ -133,6 +133,11 @@
 	} else {
 		pr_err("Read SB reg [01] failed\n");
 		sd->gspca_dev.usb_err = ret;
+		/*
+		 * Make sure the buffer is zeroed to avoid uninitialized
+		 * values.
+		 */
+		memset(sd->gspca_dev.usb_buf, 0, 2);
 	}
 
 	udelay(W9968CF_I2C_BUS_DELAY);
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c
index 9b9d894..b75c18a 100644
--- a/drivers/media/usb/hdpvr/hdpvr-core.c
+++ b/drivers/media/usb/hdpvr/hdpvr-core.c
@@ -137,6 +137,7 @@
 
 	dev->fw_ver = dev->usbc_buf[1];
 
+	dev->usbc_buf[46] = '\0';
 	v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n",
 			  dev->fw_ver, &dev->usbc_buf[2]);
 
@@ -271,6 +272,7 @@
 #endif
 	size_t buffer_size;
 	int i;
+	int dev_num;
 	int retval = -ENOMEM;
 
 	/* allocate memory for our device state and initialize it */
@@ -368,8 +370,17 @@
 	}
 #endif
 
+	dev_num = atomic_inc_return(&dev_nr);
+	if (dev_num >= HDPVR_MAX) {
+		v4l2_err(&dev->v4l2_dev,
+			 "max device number reached, device register failed\n");
+		atomic_dec(&dev_nr);
+		retval = -ENODEV;
+		goto reg_fail;
+	}
+
 	retval = hdpvr_register_videodev(dev, &interface->dev,
-				    video_nr[atomic_inc_return(&dev_nr)]);
+				    video_nr[dev_num]);
 	if (retval < 0) {
 		v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
 		goto reg_fail;
diff --git a/drivers/media/usb/hdpvr/hdpvr-i2c.c b/drivers/media/usb/hdpvr/hdpvr-i2c.c
index bc5975b..785c850 100644
--- a/drivers/media/usb/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/usb/hdpvr/hdpvr-i2c.c
@@ -193,8 +193,6 @@
 
 int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
 {
-	int retval = -ENOMEM;
-
 	hdpvr_activate_ir(dev);
 
 	dev->i2c_adapter = hdpvr_i2c_adapter_template;
@@ -202,9 +200,7 @@
 
 	i2c_set_adapdata(&dev->i2c_adapter, dev);
 
-	retval = i2c_add_adapter(&dev->i2c_adapter);
-
-	return retval;
+	return i2c_add_adapter(&dev->i2c_adapter);
 }
 
 #endif
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
index 5b3e67b..bad71d8 100644
--- a/drivers/media/usb/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -987,9 +987,6 @@
 	if (f->index != 0)
 		return -EINVAL;
 
-	f->flags = V4L2_FMT_FLAG_COMPRESSED;
-	strscpy(f->description, "MPEG2-TS with AVC/AAC streams",
-		sizeof(f->description));
 	f->pixelformat = V4L2_PIX_FMT_MPEG;
 
 	return 0;
diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c
index 4c9b2a1..65be6f1 100644
--- a/drivers/media/usb/msi2500/msi2500.c
+++ b/drivers/media/usb/msi2500/msi2500.c
@@ -66,7 +66,6 @@
 
 /* stream formats */
 struct msi2500_format {
-	char	*name;
 	u32	pixelformat;
 	u32	buffersize;
 };
@@ -74,27 +73,21 @@
 /* format descriptions for capture and preview */
 static struct msi2500_format formats[] = {
 	{
-		.name		= "Complex S8",
 		.pixelformat	= V4L2_SDR_FMT_CS8,
 		.buffersize	= 3 * 1008,
 #if 0
 	}, {
-		.name		= "10+2-bit signed",
 		.pixelformat	= MSI2500_PIX_FMT_SDR_MSI2500_384,
 	}, {
-		.name		= "12-bit signed",
 		.pixelformat	= MSI2500_PIX_FMT_SDR_S12,
 #endif
 	}, {
-		.name		= "Complex S14LE",
 		.pixelformat	= V4L2_SDR_FMT_CS14LE,
 		.buffersize	= 3 * 1008,
 	}, {
-		.name		= "Complex U8 (emulated)",
 		.pixelformat	= V4L2_SDR_FMT_CU8,
 		.buffersize	= 3 * 1008,
 	}, {
-		.name		= "Complex U16LE (emulated)",
 		.pixelformat	=  V4L2_SDR_FMT_CU16LE,
 		.buffersize	= 3 * 1008,
 	},
@@ -904,7 +897,6 @@
 	if (f->index >= dev->num_formats)
 		return -EINVAL;
 
-	strscpy(f->description, formats[f->index].name, sizeof(f->description));
 	f->pixelformat = formats[f->index].pixelformat;
 
 	return 0;
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
index 79f0e0c..8e81af5 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c
@@ -39,7 +39,7 @@
 	int ret;
 	int mode16 = 0;
 	unsigned pcnt,tcnt;
-	eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
+	eeprom = kzalloc(EEPROM_SIZE, GFP_KERNEL);
 	if (!eeprom) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 			   "Failed to allocate memory required to read eeprom");
@@ -74,7 +74,6 @@
 	   (1) we're only fetching part of the eeprom, and (2) if we were
 	   getting the whole thing our I2C driver can't grab it in one
 	   pass - which is what tveeprom is otherwise going to attempt */
-	memset(eeprom,0,EEPROM_SIZE);
 	for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
 		pcnt = 16;
 		if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index 6fe8b9a..1cfb7cf 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -660,7 +660,7 @@
 {
 	if (v < 0 || v > PVR2_CVAL_INPUT_MAX)
 		return 0;
-	return ((1 << v) & cptr->hdw->input_allowed_mask) != 0;
+	return ((1UL << v) & cptr->hdw->input_allowed_mask) != 0;
 }
 
 static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
@@ -784,7 +784,7 @@
 
 static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr)
 {
-	struct v4l2_queryctrl qctrl;
+	struct v4l2_queryctrl qctrl = {};
 	struct pvr2_ctl_info *info;
 	qctrl.id = cptr->info->v4l_id;
 	cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl);
@@ -2445,7 +2445,7 @@
 	/* Ensure that default input choice is a valid one. */
 	m = hdw->input_avail_mask;
 	if (m) for (idx = 0; idx < (sizeof(m) << 3); idx++) {
-		if (!((1 << idx) & m)) continue;
+		if (!((1UL << idx) & m)) continue;
 		hdw->input_val = idx;
 		break;
 	}
@@ -2501,11 +2501,11 @@
 	// Initialize control data regarding video standard masks
 	valid_std_mask = pvr2_std_get_usable();
 	for (idx = 0; idx < 32; idx++) {
-		if (!(valid_std_mask & (1 << idx))) continue;
+		if (!(valid_std_mask & (1UL << idx))) continue;
 		cnt1 = pvr2_std_id_to_str(
 			hdw->std_mask_names[idx],
 			sizeof(hdw->std_mask_names[idx])-1,
-			1 << idx);
+			1UL << idx);
 		hdw->std_mask_names[idx][cnt1] = 0;
 	}
 	cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL);
@@ -3329,7 +3329,7 @@
 	int ret;
 	int mode16 = 0;
 	unsigned pcnt,tcnt;
-	eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
+	eeprom = kzalloc(EEPROM_SIZE, GFP_KERNEL);
 	if (!eeprom) {
 		pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 			   "Failed to allocate memory required to read eeprom");
@@ -3364,7 +3364,6 @@
 	   (1) we're only fetching part of the eeprom, and (2) if we were
 	   getting the whole thing our I2C driver can't grab it in one
 	   pass - which is what tveeprom is otherwise going to attempt */
-	memset(eeprom,0,EEPROM_SIZE);
 	for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
 		pcnt = 16;
 		if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
@@ -4673,7 +4672,7 @@
 	unsigned int idx,ccnt;
 	unsigned int tcnt = 0;
 	for (idx = 0; idx < ARRAY_SIZE(control_values_input); idx++) {
-		if (!((1 << idx) & msk)) continue;
+		if (!((1UL << idx) & msk)) continue;
 		ccnt = scnprintf(buf+tcnt,
 				 acnt-tcnt,
 				 "%s%s",
@@ -5100,7 +5099,7 @@
 			break;
 		}
 		hdw->input_allowed_mask = nv;
-		if ((1 << hdw->input_val) & hdw->input_allowed_mask) {
+		if ((1UL << hdw->input_val) & hdw->input_allowed_mask) {
 			/* Current mode is still in the allowed mask, so
 			   we're done. */
 			break;
@@ -5113,7 +5112,7 @@
 		}
 		m = hdw->input_allowed_mask;
 		for (idx = 0; idx < (sizeof(m) << 3); idx++) {
-			if (!((1 << idx) & m)) continue;
+			if (!((1UL << idx) & m)) continue;
 			pvr2_hdw_set_input(hdw,idx);
 			break;
 		}
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
index 0aff2f3..a34717e 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -1003,7 +1003,7 @@
 	input_mask &= pvr2_hdw_get_input_available(hdw);
 	input_cnt = 0;
 	for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
-		if (input_mask & (1 << idx)) input_cnt++;
+		if (input_mask & (1UL << idx)) input_cnt++;
 	}
 	fhp->input_cnt = input_cnt;
 	fhp->input_map = kzalloc(input_cnt,GFP_KERNEL);
@@ -1018,7 +1018,7 @@
 	}
 	input_cnt = 0;
 	for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
-		if (!(input_mask & (1 << idx))) continue;
+		if (!(input_mask & (1UL << idx))) continue;
 		fhp->input_map[input_cnt++] = idx;
 	}
 
diff --git a/drivers/media/usb/pwc/pwc-v4l.c b/drivers/media/usb/pwc/pwc-v4l.c
index 76c498c..2f135d5 100644
--- a/drivers/media/usb/pwc/pwc-v4l.c
+++ b/drivers/media/usb/pwc/pwc-v4l.c
@@ -873,14 +873,9 @@
 	case 0:
 		/* RAW format */
 		f->pixelformat = pdev->type <= 646 ? V4L2_PIX_FMT_PWC1 : V4L2_PIX_FMT_PWC2;
-		f->flags = V4L2_FMT_FLAG_COMPRESSED;
-		strscpy(f->description, "Raw Philips Webcam",
-			sizeof(f->description));
 		break;
 	case 1:
 		f->pixelformat = V4L2_PIX_FMT_YUV420;
-		strscpy(f->description, "4:2:0, planar, Y-Cb-Cr",
-			sizeof(f->description));
 		break;
 	default:
 		return -EINVAL;
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index aa90558..329ec80 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -273,7 +273,6 @@
 }
 
 struct s2255_fmt {
-	char *name;
 	u32 fourcc;
 	int depth;
 };
@@ -385,29 +384,23 @@
 /* JPEG formats must be defined last to support jpeg_enable parameter */
 static const struct s2255_fmt formats[] = {
 	{
-		.name = "4:2:2, packed, YUYV",
 		.fourcc = V4L2_PIX_FMT_YUYV,
 		.depth = 16
 
 	}, {
-		.name = "4:2:2, packed, UYVY",
 		.fourcc = V4L2_PIX_FMT_UYVY,
 		.depth = 16
 	}, {
-		.name = "4:2:2, planar, YUV422P",
 		.fourcc = V4L2_PIX_FMT_YUV422P,
 		.depth = 16
 
 	}, {
-		.name = "8bpp GREY",
 		.fourcc = V4L2_PIX_FMT_GREY,
 		.depth = 8
 	}, {
-		.name = "JPG",
 		.fourcc = V4L2_PIX_FMT_JPEG,
 		.depth = 24
 	}, {
-		.name = "MJPG",
 		.fourcc = V4L2_PIX_FMT_MJPEG,
 		.depth = 24
 	}
@@ -737,7 +730,6 @@
 	if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
 			(formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
 		return -EINVAL;
-	strscpy(f->description, formats[index].name, sizeof(f->description));
 	f->pixelformat = formats[index].fourcc;
 	return 0;
 }
@@ -759,7 +751,6 @@
 	f->fmt.pix.bytesperline = f->fmt.pix.width * (vc->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;
 }
 
@@ -811,7 +802,6 @@
 	f->fmt.pix.bytesperline = (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;
 	dprintk(vc->dev, 50, "%s: set width %d height %d field %d\n", __func__,
 		f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
 	return 0;
diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c
index b71a0f4..bcd14c6 100644
--- a/drivers/media/usb/stk1160/stk1160-v4l.c
+++ b/drivers/media/usb/stk1160/stk1160-v4l.c
@@ -46,7 +46,6 @@
 /* supported video standards */
 static struct stk1160_fmt format[] = {
 	{
-		.name     = "16 bpp YUY2, 4:2:2, packed",
 		.fourcc   = V4L2_PIX_FMT_UYVY,
 		.depth    = 16,
 	}
@@ -346,7 +345,6 @@
 	if (f->index != 0)
 		return -EINVAL;
 
-	strscpy(f->description, format[f->index].name, sizeof(f->description));
 	f->pixelformat = format[f->index].fourcc;
 	return 0;
 }
diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h
index 099ce2a..a31ea1c 100644
--- a/drivers/media/usb/stk1160/stk1160.h
+++ b/drivers/media/usb/stk1160/stk1160.h
@@ -102,7 +102,6 @@
 };
 
 struct stk1160_fmt {
-	char  *name;
 	u32   fourcc;          /* v4l2 format id */
 	int   depth;
 };
diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c
index be8041e..cfca3c7 100644
--- a/drivers/media/usb/stkwebcam/stk-webcam.c
+++ b/drivers/media/usb/stkwebcam/stk-webcam.c
@@ -857,23 +857,18 @@
 	switch (fmtd->index) {
 	case 0:
 		fmtd->pixelformat = V4L2_PIX_FMT_RGB565;
-		strscpy(fmtd->description, "r5g6b5", sizeof(fmtd->description));
 		break;
 	case 1:
 		fmtd->pixelformat = V4L2_PIX_FMT_RGB565X;
-		strscpy(fmtd->description, "r5g6b5BE", sizeof(fmtd->description));
 		break;
 	case 2:
 		fmtd->pixelformat = V4L2_PIX_FMT_UYVY;
-		strscpy(fmtd->description, "yuv4:2:2", sizeof(fmtd->description));
 		break;
 	case 3:
 		fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8;
-		strscpy(fmtd->description, "Raw bayer", sizeof(fmtd->description));
 		break;
 	case 4:
 		fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
-		strscpy(fmtd->description, "yuv4:2:2", sizeof(fmtd->description));
 		break;
 	default:
 		return -EINVAL;
diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c
index 23df50a..5358cd8 100644
--- a/drivers/media/usb/tm6000/tm6000-cards.c
+++ b/drivers/media/usb/tm6000/tm6000-cards.c
@@ -1328,7 +1328,7 @@
 
 /*
  * tm6000_usb_disconnect()
- * called when the device gets diconencted
+ * called when the device gets disconnected
  * video device will be unregistered on v4l2_close in case it is still open
  */
 static void tm6000_usb_disconnect(struct usb_interface *interface)
diff --git a/drivers/media/usb/tm6000/tm6000-dvb.c b/drivers/media/usb/tm6000/tm6000-dvb.c
index e4d2dcd..19c90fa 100644
--- a/drivers/media/usb/tm6000/tm6000-dvb.c
+++ b/drivers/media/usb/tm6000/tm6000-dvb.c
@@ -97,6 +97,7 @@
 			printk(KERN_ERR "tm6000:  error %s\n", __func__);
 			kfree(urb->transfer_buffer);
 			usb_free_urb(urb);
+			dev->dvb->bulk_urb = NULL;
 		}
 	}
 }
@@ -127,6 +128,7 @@
 	dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
 	if (!dvb->bulk_urb->transfer_buffer) {
 		usb_free_urb(dvb->bulk_urb);
+		dvb->bulk_urb = NULL;
 		return -ENOMEM;
 	}
 
@@ -153,6 +155,7 @@
 
 		kfree(dvb->bulk_urb->transfer_buffer);
 		usb_free_urb(dvb->bulk_urb);
+		dvb->bulk_urb = NULL;
 		return ret;
 	}
 
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index 85fcddf..c07a81a 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -52,15 +52,12 @@
 
 static struct tm6000_fmt format[] = {
 	{
-		.name     = "4:2:2, packed, YVY2",
 		.fourcc   = V4L2_PIX_FMT_YUYV,
 		.depth    = 16,
 	}, {
-		.name     = "4:2:2, packed, UYVY",
 		.fourcc   = V4L2_PIX_FMT_UYVY,
 		.depth    = 16,
 	}, {
-		.name     = "A/V + VBI mux packet",
 		.fourcc   = V4L2_PIX_FMT_TM6000,
 		.depth    = 16,
 	}
@@ -875,7 +872,6 @@
 	if (f->index >= ARRAY_SIZE(format))
 		return -EINVAL;
 
-	strscpy(f->description, format[f->index].name, sizeof(f->description));
 	f->pixelformat = format[f->index].fourcc;
 	return 0;
 }
diff --git a/drivers/media/usb/tm6000/tm6000.h b/drivers/media/usb/tm6000/tm6000.h
index 0864ed7..bf39654 100644
--- a/drivers/media/usb/tm6000/tm6000.h
+++ b/drivers/media/usb/tm6000/tm6000.h
@@ -64,7 +64,6 @@
  */
 
 struct tm6000_fmt {
-	char  *name;
 	u32   fourcc;          /* v4l2 format id */
 	int   depth;
 };
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c
index 1d0afa3..3198f96 100644
--- a/drivers/media/usb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c
@@ -319,7 +319,7 @@
 
 	dprintk("%s\n", __func__);
 
-	b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
+	b = kzalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
 	if (!b)
 		return -ENOMEM;
 
diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c
index 51f7844..3d9284a 100644
--- a/drivers/media/usb/usbtv/usbtv-video.c
+++ b/drivers/media/usb/usbtv/usbtv-video.c
@@ -633,8 +633,6 @@
 	if (f->index > 0)
 		return -EINVAL;
 
-	strscpy(f->description, "16 bpp YUY2, 4:2:2, packed",
-		sizeof(f->description));
 	f->pixelformat = V4L2_PIX_FMT_YUYV;
 	return 0;
 }
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index 93750af..cdc66ad 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -87,14 +87,14 @@
 static int usbvision_nr;
 
 static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = {
-	{ 1, 1,  8, V4L2_PIX_FMT_GREY    , "GREY" },
-	{ 1, 2, 16, V4L2_PIX_FMT_RGB565  , "RGB565" },
-	{ 1, 3, 24, V4L2_PIX_FMT_RGB24   , "RGB24" },
-	{ 1, 4, 32, V4L2_PIX_FMT_RGB32   , "RGB32" },
-	{ 1, 2, 16, V4L2_PIX_FMT_RGB555  , "RGB555" },
-	{ 1, 2, 16, V4L2_PIX_FMT_YUYV    , "YUV422" },
-	{ 1, 2, 12, V4L2_PIX_FMT_YVU420  , "YUV420P" }, /* 1.5 ! */
-	{ 1, 2, 16, V4L2_PIX_FMT_YUV422P , "YUV422P" }
+	{ 1, 1,  8, V4L2_PIX_FMT_GREY },
+	{ 1, 2, 16, V4L2_PIX_FMT_RGB565 },
+	{ 1, 3, 24, V4L2_PIX_FMT_RGB24 },
+	{ 1, 4, 32, V4L2_PIX_FMT_RGB32 },
+	{ 1, 2, 16, V4L2_PIX_FMT_RGB555 },
+	{ 1, 2, 16, V4L2_PIX_FMT_YUYV },
+	{ 1, 2, 12, V4L2_PIX_FMT_YVU420 }, /* 1.5 ! */
+	{ 1, 2, 16, V4L2_PIX_FMT_YUV422P }
 };
 
 /* Function prototypes */
@@ -796,8 +796,6 @@
 {
 	if (vfd->index >= USBVISION_SUPPORTED_PALETTES - 1)
 		return -EINVAL;
-	strscpy(vfd->description, usbvision_v4l2_format[vfd->index].desc,
-		sizeof(vfd->description));
 	vfd->pixelformat = usbvision_v4l2_format[vfd->index].format;
 	return 0;
 }
@@ -967,7 +965,6 @@
 	       __func__,
 	       (unsigned long)count, frame->bytes_read);
 
-#if 1
 	/*
 	 * FIXME:
 	 * For now, forget the frame if it has not been read in one shot.
@@ -976,15 +973,6 @@
 
 	/* Mark it as available to be used again. */
 	frame->grabstate = frame_state_unused;
-#else
-	if (frame->bytes_read >= frame->scanlength) {
-		/* All data has been read */
-		frame->bytes_read = 0;
-
-		/* Mark it as available to be used again. */
-		frame->grabstate = frame_state_unused;
-	}
-#endif
 
 	return count;
 }
diff --git a/drivers/media/usb/usbvision/usbvision.h b/drivers/media/usb/usbvision/usbvision.h
index 4198f97..1153957 100644
--- a/drivers/media/usb/usbvision/usbvision.h
+++ b/drivers/media/usb/usbvision/usbvision.h
@@ -264,7 +264,6 @@
 	int		bytes_per_pixel;
 	int		depth;
 	int		format;
-	char		*desc;
 };
 #define USBVISION_SUPPORTED_PALETTES ARRAY_SIZE(usbvision_v4l2_format)
 
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index 203329c..0335e69 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -253,7 +253,6 @@
 	fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
 	fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
 	fmt->fmt.pix.colorspace = format->colorspace;
-	fmt->fmt.pix.priv = 0;
 
 	if (uvc_format != NULL)
 		*uvc_format = format;
@@ -290,7 +289,6 @@
 	fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
 	fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
 	fmt->fmt.pix.colorspace = format->colorspace;
-	fmt->fmt.pix.priv = 0;
 
 done:
 	mutex_unlock(&stream->mutex);
diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c
index a9bcba4..6379628 100644
--- a/drivers/media/usb/zr364xx/zr364xx.c
+++ b/drivers/media/usb/zr364xx/zr364xx.c
@@ -141,7 +141,6 @@
 };
 
 struct zr364xx_fmt {
-	char *name;
 	u32 fourcc;
 	int depth;
 };
@@ -149,7 +148,6 @@
 /* image formats.  */
 static const struct zr364xx_fmt formats[] = {
 	{
-		.name = "JPG",
 		.fourcc = V4L2_PIX_FMT_JPEG,
 		.depth = 24
 	}
@@ -199,12 +197,10 @@
 {
 	int status;
 
-	unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL);
+	unsigned char *transfer_buffer = kmemdup(cp, size, GFP_KERNEL);
 	if (!transfer_buffer)
 		return -ENOMEM;
 
-	memcpy(transfer_buffer, cp, size);
-
 	status = usb_control_msg(udev,
 				 usb_sndctrlpipe(udev, 0),
 				 request,
@@ -376,8 +372,7 @@
 						  vb);
 	int rc;
 
-	DBG("%s, field=%d, fmt name = %s\n", __func__, field,
-	    cam->fmt ? cam->fmt->name : "");
+	DBG("%s, field=%d\n", __func__, field);
 	if (!cam->fmt)
 		return -EINVAL;
 
@@ -751,8 +746,6 @@
 {
 	if (f->index > 0)
 		return -EINVAL;
-	f->flags = V4L2_FMT_FLAG_COMPRESSED;
-	strscpy(f->description, formats[0].name, sizeof(f->description));
 	f->pixelformat = formats[0].fourcc;
 	return 0;
 }
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 7c5f62f..39e3fb30 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -11,6 +11,11 @@
 	select VIDEOBUF2_V4L2 if VIDEOBUF2_CORE
 	default (I2C || I2C=n) && VIDEO_DEV
 
+config VIDEO_V4L2_I2C
+	bool
+	depends on I2C && VIDEO_V4L2
+	default y
+
 config VIDEO_ADV_DEBUG
 	bool "Enable advanced debug functionality on V4L2 drivers"
 	help
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 9ee57e1..786bd1e 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -7,18 +7,15 @@
 
 videodev-objs	:=	v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.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
-obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
-ifeq ($(CONFIG_TRACEPOINTS),y)
-  videodev-objs += v4l2-trace.o
-endif
+			v4l2-async.o v4l2-common.o
+videodev-$(CONFIG_COMPAT) += v4l2-compat-ioctl32.o
+videodev-$(CONFIG_TRACEPOINTS) += v4l2-trace.o
 videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o
+videodev-$(CONFIG_SPI) += v4l2-spi.o
+videodev-$(CONFIG_VIDEO_V4L2_I2C) += v4l2-i2c.o
 
+obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
 obj-$(CONFIG_VIDEO_V4L2) += videodev.o
-obj-$(CONFIG_VIDEO_V4L2) += v4l2-common.o
 obj-$(CONFIG_VIDEO_V4L2) += v4l2-dv-timings.o
 
 obj-$(CONFIG_VIDEO_TUNER) += tuner.o
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 8d307b5..8bde33c 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -534,7 +534,7 @@
 {
 	struct v4l2_async_subdev *asd, *tmp;
 
-	if (!notifier)
+	if (!notifier || !notifier->asd_list.next)
 		return;
 
 	list_for_each_entry_safe(asd, tmp, &notifier->asd_list, asd_list) {
@@ -593,10 +593,11 @@
 		return ERR_PTR(-ENOMEM);
 
 	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-	asd->match.fwnode = fwnode;
+	asd->match.fwnode = fwnode_handle_get(fwnode);
 
 	ret = v4l2_async_notifier_add_subdev(notifier, asd);
 	if (ret) {
+		fwnode_handle_put(fwnode);
 		kfree(asd);
 		return ERR_PTR(ret);
 	}
@@ -605,6 +606,29 @@
 }
 EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_subdev);
 
+int
+v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
+					     struct fwnode_handle *endpoint,
+					     struct v4l2_async_subdev *asd)
+{
+	struct fwnode_handle *remote;
+	int ret;
+
+	remote = fwnode_graph_get_remote_port_parent(endpoint);
+	if (!remote)
+		return -ENOTCONN;
+
+	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
+	asd->match.fwnode = remote;
+
+	ret = v4l2_async_notifier_add_subdev(notif, asd);
+	if (ret)
+		fwnode_handle_put(remote);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_remote_subdev);
+
 struct v4l2_async_subdev *
 v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
 				   int adapter_id, unsigned short address,
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index f8ad1c5..62f7aa9 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -40,10 +40,6 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/i2c.h>
-#if defined(CONFIG_SPI)
-#include <linux/spi/spi.h>
-#endif
 #include <linux/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -54,10 +50,6 @@
 
 #include <linux/videodev2.h>
 
-MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
-MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
-MODULE_LICENSE("GPL");
-
 /*
  *
  *	V 4 L 2   D R I V E R   H E L P E R   A P I
@@ -95,212 +87,6 @@
 }
 EXPORT_SYMBOL(v4l2_ctrl_query_fill);
 
-/* I2C Helper functions */
-
-#if IS_ENABLED(CONFIG_I2C)
-
-void v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd, struct i2c_client *client,
-			      const char *devname, const char *postfix)
-{
-	if (!devname)
-		devname = client->dev.driver->name;
-	if (!postfix)
-		postfix = "";
-
-	snprintf(sd->name, sizeof(sd->name), "%s%s %d-%04x", devname, postfix,
-		 i2c_adapter_id(client->adapter), client->addr);
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_set_name);
-
-void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
-		const struct v4l2_subdev_ops *ops)
-{
-	v4l2_subdev_init(sd, ops);
-	sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
-	/* the owner is the same as the i2c_client's driver owner */
-	sd->owner = client->dev.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);
-	v4l2_i2c_subdev_set_name(sd, client, NULL, NULL);
-}
-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,
-		const unsigned short *probe_addrs)
-{
-	struct v4l2_subdev *sd = NULL;
-	struct i2c_client *client;
-
-	BUG_ON(!v4l2_dev);
-
-	request_module(I2C_MODULE_PREFIX "%s", info->type);
-
-	/* Create the i2c client */
-	if (info->addr == 0 && probe_addrs)
-		client = i2c_new_probed_device(adapter, info, probe_addrs,
-					       NULL);
-	else
-		client = i2c_new_device(adapter, info);
-
-	/* Note: by loading the module first we are certain that c->driver
-	   will be set if the driver was found. If the module was not loaded
-	   first, then the i2c core tries to delay-load the module for us,
-	   and then c->driver is still NULL until the module is finally
-	   loaded. This delay-load mechanism doesn't work if other drivers
-	   want to use the i2c device, so explicitly loading the module
-	   is the best alternative. */
-	if (client == NULL || client->dev.driver == NULL)
-		goto error;
-
-	/* Lock the module so we can safely get the v4l2_subdev pointer */
-	if (!try_module_get(client->dev.driver->owner))
-		goto error;
-	sd = i2c_get_clientdata(client);
-
-	/* Register with the v4l2_device which increases the module's
-	   use count as well. */
-	if (v4l2_device_register_subdev(v4l2_dev, sd))
-		sd = NULL;
-	/* Decrease the module use count to match the first try_module_get. */
-	module_put(client->dev.driver->owner);
-
-error:
-	/* If we have a client but no subdev, then something went wrong and
-	   we must unregister the client. */
-	if (client && sd == NULL)
-		i2c_unregister_device(client);
-	return sd;
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
-
-struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
-		struct i2c_adapter *adapter, const char *client_type,
-		u8 addr, const unsigned short *probe_addrs)
-{
-	struct i2c_board_info info;
-
-	/* Setup the i2c board info with the device type and
-	   the device address. */
-	memset(&info, 0, sizeof(info));
-	strscpy(info.type, client_type, sizeof(info.type));
-	info.addr = addr;
-
-	return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
-
-/* Return i2c client address of v4l2_subdev. */
-unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	return client ? client->addr : I2C_CLIENT_END;
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
-
-/* Return a list of I2C tuner addresses to probe. Use only if the tuner
-   addresses are unknown. */
-const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
-{
-	static const unsigned short radio_addrs[] = {
-#if IS_ENABLED(CONFIG_MEDIA_TUNER_TEA5761)
-		0x10,
-#endif
-		0x60,
-		I2C_CLIENT_END
-	};
-	static const unsigned short demod_addrs[] = {
-		0x42, 0x43, 0x4a, 0x4b,
-		I2C_CLIENT_END
-	};
-	static const unsigned short tv_addrs[] = {
-		0x42, 0x43, 0x4a, 0x4b,		/* tda8290 */
-		0x60, 0x61, 0x62, 0x63, 0x64,
-		I2C_CLIENT_END
-	};
-
-	switch (type) {
-	case ADDRS_RADIO:
-		return radio_addrs;
-	case ADDRS_DEMOD:
-		return demod_addrs;
-	case ADDRS_TV:
-		return tv_addrs;
-	case ADDRS_TV_WITH_DEMOD:
-		return tv_addrs + 4;
-	}
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
-
-#endif /* defined(CONFIG_I2C) */
-
-#if defined(CONFIG_SPI)
-
-/* Load an spi sub-device. */
-
-void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
-		const struct v4l2_subdev_ops *ops)
-{
-	v4l2_subdev_init(sd, ops);
-	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);
-	/* initialize name */
-	snprintf(sd->name, sizeof(sd->name), "%s %s",
-		spi->dev.driver->name, dev_name(&spi->dev));
-}
-EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init);
-
-struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
-		struct spi_master *master, struct spi_board_info *info)
-{
-	struct v4l2_subdev *sd = NULL;
-	struct spi_device *spi = NULL;
-
-	BUG_ON(!v4l2_dev);
-
-	if (info->modalias[0])
-		request_module(info->modalias);
-
-	spi = spi_new_device(master, info);
-
-	if (spi == NULL || spi->dev.driver == NULL)
-		goto error;
-
-	if (!try_module_get(spi->dev.driver->owner))
-		goto error;
-
-	sd = spi_get_drvdata(spi);
-
-	/* Register with the v4l2_device which increases the module's
-	   use count as well. */
-	if (v4l2_device_register_subdev(v4l2_dev, sd))
-		sd = NULL;
-
-	/* Decrease the module use count to match the first try_module_get. */
-	module_put(spi->dev.driver->owner);
-
-error:
-	/* If we have a client but no subdev, then something went wrong and
-	   we must unregister the client. */
-	if (!sd)
-		spi_unregister_device(spi);
-
-	return sd;
-}
-EXPORT_SYMBOL_GPL(v4l2_spi_new_subdev);
-
-#endif /* defined(CONFIG_SPI) */
-
 /* Clamp x to be between min and max, aligned to a multiple of 2^align.  min
  * and max don't have to be aligned, but there must be at least one valid
  * value.  E.g., min=17,max=31,align=4 is not allowed as there are no multiples
@@ -455,11 +241,15 @@
 		{ .format = V4L2_PIX_FMT_HSV24,   .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_BGR32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_XBGR32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+		{ .format = V4L2_PIX_FMT_BGRX32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_RGB32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_XRGB32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+		{ .format = V4L2_PIX_FMT_RGBX32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_HSV32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_ARGB32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+		{ .format = V4L2_PIX_FMT_RGBA32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_ABGR32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
+		{ .format = V4L2_PIX_FMT_BGRA32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 		{ .format = V4L2_PIX_FMT_GREY,    .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 },
 
 		/* YUV packed formats */
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 371537d..1d8f388 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -6,6 +6,8 @@
 
  */
 
+#define pr_fmt(fmt) "v4l2-ctrls: " fmt
+
 #include <linux/ctype.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
@@ -16,6 +18,12 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-dev.h>
 
+#define dprintk(vdev, fmt, arg...) do {					\
+	if (!WARN_ON(!(vdev)) && ((vdev)->dev_debug & V4L2_DEV_DEBUG_CTRL)) \
+		printk(KERN_DEBUG pr_fmt("%s: %s: " fmt),		\
+		       __func__, video_device_node_name(vdev), ##arg);	\
+} while (0)
+
 #define has_op(master, op) \
 	(master->ops && master->ops->op)
 #define call_op(master, op) \
@@ -394,6 +402,16 @@
 		"Explicit",
 		NULL,
 	};
+	static const char * const h264_decode_mode[] = {
+		"Slice-Based",
+		"Frame-Based",
+		NULL,
+	};
+	static const char * const h264_start_code[] = {
+		"No Start Code",
+		"Annex B Start Code",
+		NULL,
+	};
 	static const char * const mpeg_mpeg2_level[] = {
 		"Low",
 		"Main",
@@ -625,6 +643,10 @@
 		return h264_fp_arrangement_type;
 	case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
 		return h264_fmo_map_type;
+	case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE:
+		return h264_decode_mode;
+	case V4L2_CID_MPEG_VIDEO_H264_START_CODE:
+		return h264_start_code;
 	case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:
 		return mpeg_mpeg2_level;
 	case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:
@@ -844,6 +866,8 @@
 	case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX:		return "H264 Scaling Matrix";
 	case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS:		return "H264 Slice Parameters";
 	case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS:		return "H264 Decode Parameters";
+	case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE:		return "H264 Decode Mode";
+	case V4L2_CID_MPEG_VIDEO_H264_START_CODE:		return "H264 Start Code";
 	case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:			return "MPEG2 Level";
 	case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:			return "MPEG2 Profile";
 	case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:		return "MPEG4 I-Frame QP Value";
@@ -885,6 +909,7 @@
 	case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP:		return "VPX P-Frame QP Value";
 	case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:			return "VP8 Profile";
 	case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:			return "VP9 Profile";
+	case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER:		return "VP8 Frame Header";
 
 	/* HEVC controls */
 	case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:		return "HEVC I-Frame QP Value";
@@ -1211,6 +1236,8 @@
 	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
 	case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE:
 	case V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE:
+	case V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE:
+	case V4L2_CID_MPEG_VIDEO_H264_START_CODE:
 	case V4L2_CID_MPEG_VIDEO_MPEG2_LEVEL:
 	case V4L2_CID_MPEG_VIDEO_MPEG2_PROFILE:
 	case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
@@ -1345,6 +1372,9 @@
 	case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS:
 		*type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS;
 		break;
+	case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER:
+		*type = V4L2_CTRL_TYPE_VP8_FRAME_HEADER;
+		break;
 	default:
 		*type = V4L2_CTRL_TYPE_INTEGER;
 		break;
@@ -1629,10 +1659,105 @@
 })
 
 /* Validate a new control */
+
+#define zero_padding(s) \
+	memset(&(s).padding, 0, sizeof((s).padding))
+
+/*
+ * Compound controls validation requires setting unused fields/flags to zero
+ * in order to properly detect unchanged controls with std_equal's memcmp.
+ */
+static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
+				 union v4l2_ctrl_ptr ptr)
+{
+	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
+	struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header;
+	void *p = ptr.p + idx * ctrl->elem_size;
+
+	switch ((u32)ctrl->type) {
+	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
+		p_mpeg2_slice_params = p;
+
+		switch (p_mpeg2_slice_params->sequence.chroma_format) {
+		case 1: /* 4:2:0 */
+		case 2: /* 4:2:2 */
+		case 3: /* 4:4:4 */
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		switch (p_mpeg2_slice_params->picture.intra_dc_precision) {
+		case 0: /* 8 bits */
+		case 1: /* 9 bits */
+		case 2: /* 10 bits */
+		case 3: /* 11 bits */
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		switch (p_mpeg2_slice_params->picture.picture_structure) {
+		case 1: /* interlaced top field */
+		case 2: /* interlaced bottom field */
+		case 3: /* progressive */
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		switch (p_mpeg2_slice_params->picture.picture_coding_type) {
+		case V4L2_MPEG2_PICTURE_CODING_TYPE_I:
+		case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
+		case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		break;
+
+	case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
+		break;
+
+	case V4L2_CTRL_TYPE_FWHT_PARAMS:
+		break;
+
+	case V4L2_CTRL_TYPE_H264_SPS:
+	case V4L2_CTRL_TYPE_H264_PPS:
+	case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
+	case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
+	case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
+		break;
+
+	case V4L2_CTRL_TYPE_VP8_FRAME_HEADER:
+		p_vp8_frame_header = p;
+
+		switch (p_vp8_frame_header->num_dct_parts) {
+		case 1:
+		case 2:
+		case 4:
+		case 8:
+			break;
+		default:
+			return -EINVAL;
+		}
+		zero_padding(p_vp8_frame_header->segment_header);
+		zero_padding(p_vp8_frame_header->lf_header);
+		zero_padding(p_vp8_frame_header->quant_header);
+		zero_padding(p_vp8_frame_header->entropy_header);
+		zero_padding(p_vp8_frame_header->coder_state);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
 			union v4l2_ctrl_ptr ptr)
 {
-	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
 	size_t len;
 	u64 offset;
 	s64 val;
@@ -1695,63 +1820,8 @@
 			return -ERANGE;
 		return 0;
 
-	case V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS:
-		p_mpeg2_slice_params = ptr.p;
-
-		switch (p_mpeg2_slice_params->sequence.chroma_format) {
-		case 1: /* 4:2:0 */
-		case 2: /* 4:2:2 */
-		case 3: /* 4:4:4 */
-			break;
-		default:
-			return -EINVAL;
-		}
-
-		switch (p_mpeg2_slice_params->picture.intra_dc_precision) {
-		case 0: /* 8 bits */
-		case 1: /* 9 bits */
-		case 2: /* 10 bits */
-		case 3: /* 11 bits */
-			break;
-		default:
-			return -EINVAL;
-		}
-
-		switch (p_mpeg2_slice_params->picture.picture_structure) {
-		case 1: /* interlaced top field */
-		case 2: /* interlaced bottom field */
-		case 3: /* progressive */
-			break;
-		default:
-			return -EINVAL;
-		}
-
-		switch (p_mpeg2_slice_params->picture.picture_coding_type) {
-		case V4L2_MPEG2_PICTURE_CODING_TYPE_I:
-		case V4L2_MPEG2_PICTURE_CODING_TYPE_P:
-		case V4L2_MPEG2_PICTURE_CODING_TYPE_B:
-			break;
-		default:
-			return -EINVAL;
-		}
-
-		return 0;
-
-	case V4L2_CTRL_TYPE_MPEG2_QUANTIZATION:
-		return 0;
-
-	case V4L2_CTRL_TYPE_FWHT_PARAMS:
-		return 0;
-
-	case V4L2_CTRL_TYPE_H264_SPS:
-	case V4L2_CTRL_TYPE_H264_PPS:
-	case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
-	case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
-	case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
-		return 0;
-
 	default:
-		return -EINVAL;
+		return std_validate_compound(ctrl, idx, ptr);
 	}
 }
 
@@ -2348,6 +2418,9 @@
 	case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
 		elem_size = sizeof(struct v4l2_ctrl_h264_decode_params);
 		break;
+	case V4L2_CTRL_TYPE_VP8_FRAME_HEADER:
+		elem_size = sizeof(struct v4l2_ctrl_vp8_frame_header);
+		break;
 	default:
 		if (type < V4L2_CTRL_COMPOUND_TYPES)
 			elem_size = sizeof(s32);
@@ -3217,6 +3290,7 @@
 static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
 			     struct v4l2_ext_controls *cs,
 			     struct v4l2_ctrl_helper *helpers,
+			     struct video_device *vdev,
 			     bool get)
 {
 	struct v4l2_ctrl_helper *h;
@@ -3234,20 +3308,31 @@
 		if (cs->which &&
 		    cs->which != V4L2_CTRL_WHICH_DEF_VAL &&
 		    cs->which != V4L2_CTRL_WHICH_REQUEST_VAL &&
-		    V4L2_CTRL_ID2WHICH(id) != cs->which)
+		    V4L2_CTRL_ID2WHICH(id) != cs->which) {
+			dprintk(vdev,
+				"invalid which 0x%x or control id 0x%x\n",
+				cs->which, id);
 			return -EINVAL;
+		}
 
 		/* Old-style private controls are not allowed for
 		   extended controls */
-		if (id >= V4L2_CID_PRIVATE_BASE)
+		if (id >= V4L2_CID_PRIVATE_BASE) {
+			dprintk(vdev,
+				"old-style private controls not allowed\n");
 			return -EINVAL;
+		}
 		ref = find_ref_lock(hdl, id);
-		if (ref == NULL)
+		if (ref == NULL) {
+			dprintk(vdev, "cannot find control id 0x%x\n", id);
 			return -EINVAL;
+		}
 		h->ref = ref;
 		ctrl = ref->ctrl;
-		if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED)
+		if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED) {
+			dprintk(vdev, "control id 0x%x is disabled\n", id);
 			return -EINVAL;
+		}
 
 		if (ctrl->cluster[0]->ncontrols > 1)
 			have_clusters = true;
@@ -3257,10 +3342,17 @@
 			unsigned tot_size = ctrl->elems * ctrl->elem_size;
 
 			if (c->size < tot_size) {
+				/*
+				 * In the get case the application first
+				 * queries to obtain the size of the control.
+				 */
 				if (get) {
 					c->size = tot_size;
 					return -ENOSPC;
 				}
+				dprintk(vdev,
+					"pointer control id 0x%x size too small, %d bytes but %d bytes needed\n",
+					id, c->size, tot_size);
 				return -EFAULT;
 			}
 			c->size = tot_size;
@@ -3321,7 +3413,8 @@
 
 /* Get extended controls. Allocates the helpers array if needed. */
 static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
-				   struct v4l2_ext_controls *cs)
+				   struct v4l2_ext_controls *cs,
+				   struct video_device *vdev)
 {
 	struct v4l2_ctrl_helper helper[4];
 	struct v4l2_ctrl_helper *helpers = helper;
@@ -3347,7 +3440,7 @@
 			return -ENOMEM;
 	}
 
-	ret = prepare_ext_ctrls(hdl, cs, helpers, true);
+	ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, true);
 	cs->error_idx = cs->count;
 
 	for (i = 0; !ret && i < cs->count; i++)
@@ -3440,8 +3533,8 @@
 	return obj;
 }
 
-int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct media_device *mdev,
-		     struct v4l2_ext_controls *cs)
+int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev,
+		     struct media_device *mdev, struct v4l2_ext_controls *cs)
 {
 	struct media_request_object *obj = NULL;
 	struct media_request *req = NULL;
@@ -3477,7 +3570,7 @@
 				   req_obj);
 	}
 
-	ret = v4l2_g_ext_ctrls_common(hdl, cs);
+	ret = v4l2_g_ext_ctrls_common(hdl, cs, vdev);
 
 	if (obj) {
 		media_request_unlock_for_access(req);
@@ -3620,7 +3713,9 @@
 
 /* Validate controls. */
 static int validate_ctrls(struct v4l2_ext_controls *cs,
-			  struct v4l2_ctrl_helper *helpers, bool set)
+			  struct v4l2_ctrl_helper *helpers,
+			  struct video_device *vdev,
+			  bool set)
 {
 	unsigned i;
 	int ret = 0;
@@ -3632,16 +3727,24 @@
 
 		cs->error_idx = i;
 
-		if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)
+		if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) {
+			dprintk(vdev,
+				"control id 0x%x is read-only\n",
+				ctrl->id);
 			return -EACCES;
+		}
 		/* This test is also done in try_set_control_cluster() which
 		   is called in atomic context, so that has the final say,
 		   but it makes sense to do an up-front check as well. Once
 		   an error occurs in try_set_control_cluster() some other
 		   controls may have been set already and we want to do a
 		   best-effort to avoid that. */
-		if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED))
+		if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) {
+			dprintk(vdev,
+				"control id 0x%x is grabbed, cannot set\n",
+				ctrl->id);
 			return -EBUSY;
+		}
 		/*
 		 * Skip validation for now if the payload needs to be copied
 		 * from userspace into kernelspace. We'll validate those later.
@@ -3676,7 +3779,8 @@
 /* Try or try-and-set controls */
 static int try_set_ext_ctrls_common(struct v4l2_fh *fh,
 				    struct v4l2_ctrl_handler *hdl,
-				    struct v4l2_ext_controls *cs, bool set)
+				    struct v4l2_ext_controls *cs,
+				    struct video_device *vdev, bool set)
 {
 	struct v4l2_ctrl_helper helper[4];
 	struct v4l2_ctrl_helper *helpers = helper;
@@ -3686,13 +3790,19 @@
 	cs->error_idx = cs->count;
 
 	/* Default value cannot be changed */
-	if (cs->which == V4L2_CTRL_WHICH_DEF_VAL)
+	if (cs->which == V4L2_CTRL_WHICH_DEF_VAL) {
+		dprintk(vdev, "%s: cannot change default value\n",
+			video_device_node_name(vdev));
 		return -EINVAL;
+	}
 
 	cs->which = V4L2_CTRL_ID2WHICH(cs->which);
 
-	if (hdl == NULL)
+	if (hdl == NULL) {
+		dprintk(vdev, "%s: invalid null control handler\n",
+			video_device_node_name(vdev));
 		return -EINVAL;
+	}
 
 	if (cs->count == 0)
 		return class_check(hdl, cs->which);
@@ -3703,9 +3813,9 @@
 		if (!helpers)
 			return -ENOMEM;
 	}
-	ret = prepare_ext_ctrls(hdl, cs, helpers, false);
+	ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, false);
 	if (!ret)
-		ret = validate_ctrls(cs, helpers, set);
+		ret = validate_ctrls(cs, helpers, vdev, set);
 	if (ret && set)
 		cs->error_idx = cs->count;
 	for (i = 0; !ret && i < cs->count; i++) {
@@ -3790,7 +3900,9 @@
 }
 
 static int try_set_ext_ctrls(struct v4l2_fh *fh,
-			     struct v4l2_ctrl_handler *hdl, struct media_device *mdev,
+			     struct v4l2_ctrl_handler *hdl,
+			     struct video_device *vdev,
+			     struct media_device *mdev,
 			     struct v4l2_ext_controls *cs, bool set)
 {
 	struct media_request_object *obj = NULL;
@@ -3798,21 +3910,39 @@
 	int ret;
 
 	if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) {
-		if (!mdev || cs->request_fd < 0)
+		if (!mdev) {
+			dprintk(vdev, "%s: missing media device\n",
+				video_device_node_name(vdev));
 			return -EINVAL;
+		}
+
+		if (cs->request_fd < 0) {
+			dprintk(vdev, "%s: invalid request fd %d\n",
+				video_device_node_name(vdev), cs->request_fd);
+			return -EINVAL;
+		}
 
 		req = media_request_get_by_fd(mdev, cs->request_fd);
-		if (IS_ERR(req))
+		if (IS_ERR(req)) {
+			dprintk(vdev, "%s: cannot find request fd %d\n",
+				video_device_node_name(vdev), cs->request_fd);
 			return PTR_ERR(req);
+		}
 
 		ret = media_request_lock_for_update(req);
 		if (ret) {
+			dprintk(vdev, "%s: cannot lock request fd %d\n",
+				video_device_node_name(vdev), cs->request_fd);
 			media_request_put(req);
 			return ret;
 		}
 
 		obj = v4l2_ctrls_find_req_obj(hdl, req, set);
 		if (IS_ERR(obj)) {
+			dprintk(vdev,
+				"%s: cannot find request object for request fd %d\n",
+				video_device_node_name(vdev),
+				cs->request_fd);
 			media_request_unlock_for_update(req);
 			media_request_put(req);
 			return PTR_ERR(obj);
@@ -3821,7 +3951,11 @@
 				   req_obj);
 	}
 
-	ret = try_set_ext_ctrls_common(fh, hdl, cs, set);
+	ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set);
+	if (ret)
+		dprintk(vdev,
+			"%s: try_set_ext_ctrls_common failed (%d)\n",
+			video_device_node_name(vdev), ret);
 
 	if (obj) {
 		media_request_unlock_for_update(req);
@@ -3832,17 +3966,22 @@
 	return ret;
 }
 
-int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct media_device *mdev,
+int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl,
+		       struct video_device *vdev,
+		       struct media_device *mdev,
 		       struct v4l2_ext_controls *cs)
 {
-	return try_set_ext_ctrls(NULL, hdl, mdev, cs, false);
+	return try_set_ext_ctrls(NULL, hdl, vdev, mdev, cs, false);
 }
 EXPORT_SYMBOL(v4l2_try_ext_ctrls);
 
-int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
-		     struct media_device *mdev, struct v4l2_ext_controls *cs)
+int v4l2_s_ext_ctrls(struct v4l2_fh *fh,
+		     struct v4l2_ctrl_handler *hdl,
+		     struct video_device *vdev,
+		     struct media_device *mdev,
+		     struct v4l2_ext_controls *cs)
 {
-	return try_set_ext_ctrls(fh, hdl, mdev, cs, true);
+	return try_set_ext_ctrls(fh, hdl, vdev, mdev, cs, true);
 }
 EXPORT_SYMBOL(v4l2_s_ext_ctrls);
 
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index cbb74f7..4037689 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -859,6 +859,9 @@
 	/* the v4l2_dev pointer MUST be present */
 	if (WARN_ON(!vdev->v4l2_dev))
 		return -EINVAL;
+	/* the device_caps field MUST be set for all but subdevs */
+	if (WARN_ON(type != VFL_TYPE_SUBDEV && !vdev->device_caps))
+		return -EINVAL;
 
 	/* v4l2_fh support */
 	spin_lock_init(&vdev->fh_lock);
@@ -1089,7 +1092,7 @@
 subsys_initcall(videodev_init);
 module_exit(videodev_exit)
 
-MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@kernel.org>");
-MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
+MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@kernel.org>, Bill Dirks, Justin Schoeman, Gerd Knorr");
+MODULE_DESCRIPTION("Video4Linux2 core driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR);
diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
index aa277f5..63d6b14 100644
--- a/drivers/media/v4l2-core/v4l2-device.c
+++ b/drivers/media/v4l2-core/v4l2-device.c
@@ -9,11 +9,7 @@
 #include <linux/types.h>
 #include <linux/ioctl.h>
 #include <linux/module.h>
-#include <linux/i2c.h>
 #include <linux/slab.h>
-#if defined(CONFIG_SPI)
-#include <linux/spi/spi.h>
-#endif
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
@@ -102,37 +98,10 @@
 	/* Unregister subdevs */
 	list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) {
 		v4l2_device_unregister_subdev(sd);
-#if IS_ENABLED(CONFIG_I2C)
-		if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) {
-			struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-			/*
-			 * We need to unregister the i2c client
-			 * explicitly. We cannot rely on
-			 * i2c_del_adapter to always unregister
-			 * clients for us, since if the i2c bus is a
-			 * platform bus, then it is never deleted.
-			 *
-			 * Device tree or ACPI based devices must not
-			 * be unregistered as they have not been
-			 * registered by us, and would not be
-			 * re-created by just probing the V4L2 driver.
-			 */
-			if (client &&
-			    !client->dev.of_node && !client->dev.fwnode)
-				i2c_unregister_device(client);
-			continue;
-		}
-#endif
-#if defined(CONFIG_SPI)
-		if (sd->flags & V4L2_SUBDEV_FL_IS_SPI) {
-			struct spi_device *spi = v4l2_get_subdevdata(sd);
-
-			if (spi && !spi->dev.of_node && !spi->dev.fwnode)
-				spi_unregister_device(spi);
-			continue;
-		}
-#endif
+		if (sd->flags & V4L2_SUBDEV_FL_IS_I2C)
+			v4l2_i2c_subdev_unregister(sd);
+		else if (sd->flags & V4L2_SUBDEV_FL_IS_SPI)
+			v4l2_spi_subdev_unregister(sd);
 	}
 	/* Mark as unregistered, thus preventing duplicate unregistrations */
 	v4l2_dev->name[0] = '\0';
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index 7e740d3..3bd1888 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -163,7 +163,7 @@
 			pr_debug("no lane mapping given, using defaults\n");
 	}
 
-	rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0);
+	rval = fwnode_property_count_u32(fwnode, "data-lanes");
 	if (rval > 0) {
 		num_data_lanes =
 			min_t(int, V4L2_FWNODE_CSI2_MAX_DATA_LANES, rval);
@@ -191,8 +191,7 @@
 			pr_debug("lane %u position %u\n", i, array[i]);
 	}
 
-	rval = fwnode_property_read_u32_array(fwnode, "lane-polarities", NULL,
-					      0);
+	rval = fwnode_property_count_u32(fwnode, "lane-polarities");
 	if (rval > 0) {
 		if (rval != 1 + num_data_lanes /* clock+data */) {
 			pr_warn("invalid number of lane-polarities entries (need %u, got %u)\n",
@@ -525,8 +524,7 @@
 	if (rval < 0)
 		return rval;
 
-	rval = fwnode_property_read_u64_array(fwnode, "link-frequencies",
-					      NULL, 0);
+	rval = fwnode_property_count_u64(fwnode, "link-frequencies");
 	if (rval > 0) {
 		unsigned int i;
 
@@ -777,23 +775,17 @@
 		asd = v4l2_async_notifier_add_fwnode_subdev(notifier,
 							    args.fwnode,
 							    sizeof(*asd));
+		fwnode_handle_put(args.fwnode);
 		if (IS_ERR(asd)) {
-			ret = PTR_ERR(asd);
 			/* not an error if asd already exists */
-			if (ret == -EEXIST) {
-				fwnode_handle_put(args.fwnode);
+			if (PTR_ERR(asd) == -EEXIST)
 				continue;
-			}
 
-			goto error;
+			return PTR_ERR(asd);
 		}
 	}
 
 	return 0;
-
-error:
-	fwnode_handle_put(args.fwnode);
-	return ret;
 }
 
 /*
@@ -1083,23 +1075,18 @@
 
 		asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode,
 							    sizeof(*asd));
+		fwnode_handle_put(fwnode);
 		if (IS_ERR(asd)) {
 			ret = PTR_ERR(asd);
 			/* not an error if asd already exists */
-			if (ret == -EEXIST) {
-				fwnode_handle_put(fwnode);
+			if (ret == -EEXIST)
 				continue;
-			}
 
-			goto error;
+			return PTR_ERR(asd);
 		}
 	}
 
 	return !fwnode || PTR_ERR(fwnode) == -ENOENT ? 0 : PTR_ERR(fwnode);
-
-error:
-	fwnode_handle_put(fwnode);
-	return ret;
 }
 
 int v4l2_async_notifier_parse_fwnode_sensor_common(struct device *dev,
diff --git a/drivers/media/v4l2-core/v4l2-i2c.c b/drivers/media/v4l2-core/v4l2-i2c.c
new file mode 100644
index 0000000..5bf99e7
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-i2c.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * v4l2-i2c - I2C helpers for Video4Linux2
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+
+void v4l2_i2c_subdev_unregister(struct v4l2_subdev *sd)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	/*
+	 * We need to unregister the i2c client
+	 * explicitly. We cannot rely on
+	 * i2c_del_adapter to always unregister
+	 * clients for us, since if the i2c bus is a
+	 * platform bus, then it is never deleted.
+	 *
+	 * Device tree or ACPI based devices must not
+	 * be unregistered as they have not been
+	 * registered by us, and would not be
+	 * re-created by just probing the V4L2 driver.
+	 */
+	if (client && !client->dev.of_node && !client->dev.fwnode)
+		i2c_unregister_device(client);
+}
+
+void v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd,
+			      struct i2c_client *client,
+			      const char *devname, const char *postfix)
+{
+	if (!devname)
+		devname = client->dev.driver->name;
+	if (!postfix)
+		postfix = "";
+
+	snprintf(sd->name, sizeof(sd->name), "%s%s %d-%04x", devname, postfix,
+		 i2c_adapter_id(client->adapter), client->addr);
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_set_name);
+
+void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
+			  const struct v4l2_subdev_ops *ops)
+{
+	v4l2_subdev_init(sd, ops);
+	sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
+	/* the owner is the same as the i2c_client's driver owner */
+	sd->owner = client->dev.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);
+	v4l2_i2c_subdev_set_name(sd, client, NULL, NULL);
+}
+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,
+			   const unsigned short *probe_addrs)
+{
+	struct v4l2_subdev *sd = NULL;
+	struct i2c_client *client;
+
+	if (!v4l2_dev)
+		return NULL;
+
+	request_module(I2C_MODULE_PREFIX "%s", info->type);
+
+	/* Create the i2c client */
+	if (info->addr == 0 && probe_addrs)
+		client = i2c_new_probed_device(adapter, info, probe_addrs,
+					       NULL);
+	else
+		client = i2c_new_device(adapter, info);
+
+	/*
+	 * Note: by loading the module first we are certain that c->driver
+	 * will be set if the driver was found. If the module was not loaded
+	 * first, then the i2c core tries to delay-load the module for us,
+	 * and then c->driver is still NULL until the module is finally
+	 * loaded. This delay-load mechanism doesn't work if other drivers
+	 * want to use the i2c device, so explicitly loading the module
+	 * is the best alternative.
+	 */
+	if (!client || !client->dev.driver)
+		goto error;
+
+	/* Lock the module so we can safely get the v4l2_subdev pointer */
+	if (!try_module_get(client->dev.driver->owner))
+		goto error;
+	sd = i2c_get_clientdata(client);
+
+	/*
+	 * Register with the v4l2_device which increases the module's
+	 * use count as well.
+	 */
+	if (v4l2_device_register_subdev(v4l2_dev, sd))
+		sd = NULL;
+	/* Decrease the module use count to match the first try_module_get. */
+	module_put(client->dev.driver->owner);
+
+error:
+	/*
+	 * If we have a client but no subdev, then something went wrong and
+	 * we must unregister the client.
+	 */
+	if (client && !sd)
+		i2c_unregister_device(client);
+	return sd;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
+
+struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
+					struct i2c_adapter *adapter,
+					const char *client_type,
+					u8 addr,
+					const unsigned short *probe_addrs)
+{
+	struct i2c_board_info info;
+
+	/*
+	 * Setup the i2c board info with the device type and
+	 * the device address.
+	 */
+	memset(&info, 0, sizeof(info));
+	strscpy(info.type, client_type, sizeof(info.type));
+	info.addr = addr;
+
+	return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info,
+					 probe_addrs);
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
+
+/* Return i2c client address of v4l2_subdev. */
+unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return client ? client->addr : I2C_CLIENT_END;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
+
+/*
+ * Return a list of I2C tuner addresses to probe. Use only if the tuner
+ * addresses are unknown.
+ */
+const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
+{
+	static const unsigned short radio_addrs[] = {
+#if IS_ENABLED(CONFIG_MEDIA_TUNER_TEA5761)
+		0x10,
+#endif
+		0x60,
+		I2C_CLIENT_END
+	};
+	static const unsigned short demod_addrs[] = {
+		0x42, 0x43, 0x4a, 0x4b,
+		I2C_CLIENT_END
+	};
+	static const unsigned short tv_addrs[] = {
+		0x42, 0x43, 0x4a, 0x4b,		/* tda8290 */
+		0x60, 0x61, 0x62, 0x63, 0x64,
+		I2C_CLIENT_END
+	};
+
+	switch (type) {
+	case ADDRS_RADIO:
+		return radio_addrs;
+	case ADDRS_DEMOD:
+		return demod_addrs;
+	case ADDRS_TV:
+		return tv_addrs;
+	case ADDRS_TV_WITH_DEMOD:
+		return tv_addrs + 4;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index b1f4b99..51b9127 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1057,14 +1057,19 @@
 
 	ret = ops->vidioc_querycap(file, fh, cap);
 
-	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
 	/*
-	 * Drivers MUST fill in device_caps, so check for this and
-	 * warn if it was forgotten.
+	 * Drivers must not change device_caps, so check for this and
+	 * warn if this happened.
 	 */
-	WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) ||
-		!cap->device_caps, "Bad caps for driver %s, %x %x",
-		cap->driver, cap->capabilities, cap->device_caps);
+	WARN_ON(cap->device_caps != vfd->device_caps);
+	/*
+	 * Check that capabilities is a superset of
+	 * vfd->device_caps | V4L2_CAP_DEVICE_CAPS
+	 */
+	WARN_ON((cap->capabilities &
+		 (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)) !=
+		(vfd->device_caps | V4L2_CAP_DEVICE_CAPS));
+	cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
 	cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
 
 	return ret;
@@ -1169,9 +1174,21 @@
 	case V4L2_PIX_FMT_RGB444:	descr = "16-bit A/XRGB 4-4-4-4"; break;
 	case V4L2_PIX_FMT_ARGB444:	descr = "16-bit ARGB 4-4-4-4"; break;
 	case V4L2_PIX_FMT_XRGB444:	descr = "16-bit XRGB 4-4-4-4"; break;
+	case V4L2_PIX_FMT_RGBA444:	descr = "16-bit RGBA 4-4-4-4"; break;
+	case V4L2_PIX_FMT_RGBX444:	descr = "16-bit RGBX 4-4-4-4"; break;
+	case V4L2_PIX_FMT_ABGR444:	descr = "16-bit ABGR 4-4-4-4"; break;
+	case V4L2_PIX_FMT_XBGR444:	descr = "16-bit XBGR 4-4-4-4"; break;
+	case V4L2_PIX_FMT_BGRA444:	descr = "16-bit BGRA 4-4-4-4"; break;
+	case V4L2_PIX_FMT_BGRX444:	descr = "16-bit BGRX 4-4-4-4"; break;
 	case V4L2_PIX_FMT_RGB555:	descr = "16-bit A/XRGB 1-5-5-5"; break;
 	case V4L2_PIX_FMT_ARGB555:	descr = "16-bit ARGB 1-5-5-5"; break;
 	case V4L2_PIX_FMT_XRGB555:	descr = "16-bit XRGB 1-5-5-5"; break;
+	case V4L2_PIX_FMT_ABGR555:	descr = "16-bit ABGR 1-5-5-5"; break;
+	case V4L2_PIX_FMT_XBGR555:	descr = "16-bit XBGR 1-5-5-5"; break;
+	case V4L2_PIX_FMT_RGBA555:	descr = "16-bit RGBA 5-5-5-1"; break;
+	case V4L2_PIX_FMT_RGBX555:	descr = "16-bit RGBX 5-5-5-1"; break;
+	case V4L2_PIX_FMT_BGRA555:	descr = "16-bit BGRA 5-5-5-1"; break;
+	case V4L2_PIX_FMT_BGRX555:	descr = "16-bit BGRX 5-5-5-1"; break;
 	case V4L2_PIX_FMT_RGB565:	descr = "16-bit RGB 5-6-5"; break;
 	case V4L2_PIX_FMT_RGB555X:	descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
 	case V4L2_PIX_FMT_ARGB555X:	descr = "16-bit ARGB 1-5-5-5 BE"; break;
@@ -1186,6 +1203,10 @@
 	case V4L2_PIX_FMT_RGB32:	descr = "32-bit A/XRGB 8-8-8-8"; break;
 	case V4L2_PIX_FMT_ARGB32:	descr = "32-bit ARGB 8-8-8-8"; break;
 	case V4L2_PIX_FMT_XRGB32:	descr = "32-bit XRGB 8-8-8-8"; break;
+	case V4L2_PIX_FMT_BGRA32:	descr = "32-bit ABGR 8-8-8-8"; break;
+	case V4L2_PIX_FMT_BGRX32:	descr = "32-bit XBGR 8-8-8-8"; break;
+	case V4L2_PIX_FMT_RGBA32:	descr = "32-bit RGBA 8-8-8-8"; break;
+	case V4L2_PIX_FMT_RGBX32:	descr = "32-bit RGBX 8-8-8-8"; break;
 	case V4L2_PIX_FMT_GREY:		descr = "8-bit Greyscale"; break;
 	case V4L2_PIX_FMT_Y4:		descr = "4-bit Greyscale"; break;
 	case V4L2_PIX_FMT_Y6:		descr = "6-bit Greyscale"; break;
@@ -1301,13 +1322,14 @@
 	case V4L2_SDR_FMT_PCU16BE:	descr = "Planar Complex U16BE"; break;
 	case V4L2_SDR_FMT_PCU18BE:	descr = "Planar Complex U18BE"; break;
 	case V4L2_SDR_FMT_PCU20BE:	descr = "Planar Complex U20BE"; break;
-	case V4L2_TCH_FMT_DELTA_TD16:	descr = "16-bit signed deltas"; break;
-	case V4L2_TCH_FMT_DELTA_TD08:	descr = "8-bit signed deltas"; break;
-	case V4L2_TCH_FMT_TU16:		descr = "16-bit unsigned touch data"; break;
-	case V4L2_TCH_FMT_TU08:		descr = "8-bit unsigned touch data"; break;
+	case V4L2_TCH_FMT_DELTA_TD16:	descr = "16-bit Signed Deltas"; break;
+	case V4L2_TCH_FMT_DELTA_TD08:	descr = "8-bit Signed Deltas"; break;
+	case V4L2_TCH_FMT_TU16:		descr = "16-bit Unsigned Touch Data"; break;
+	case V4L2_TCH_FMT_TU08:		descr = "8-bit Unsigned Touch Data"; break;
 	case V4L2_META_FMT_VSP1_HGO:	descr = "R-Car VSP1 1-D Histogram"; break;
 	case V4L2_META_FMT_VSP1_HGT:	descr = "R-Car VSP1 2-D Histogram"; break;
-	case V4L2_META_FMT_UVC:		descr = "UVC payload header metadata"; break;
+	case V4L2_META_FMT_UVC:		descr = "UVC Payload Header Metadata"; break;
+	case V4L2_META_FMT_D4XX:	descr = "Intel D4xx UVC Metadata"; break;
 
 	default:
 		/* Compressed formats */
@@ -1321,16 +1343,17 @@
 		case V4L2_PIX_FMT_H264:		descr = "H.264"; break;
 		case V4L2_PIX_FMT_H264_NO_SC:	descr = "H.264 (No Start Codes)"; break;
 		case V4L2_PIX_FMT_H264_MVC:	descr = "H.264 MVC"; break;
-		case V4L2_PIX_FMT_H264_SLICE_RAW:	descr = "H.264 Parsed Slice Data"; break;
+		case V4L2_PIX_FMT_H264_SLICE:	descr = "H.264 Parsed Slice Data"; break;
 		case V4L2_PIX_FMT_H263:		descr = "H.263"; break;
 		case V4L2_PIX_FMT_MPEG1:	descr = "MPEG-1 ES"; break;
 		case V4L2_PIX_FMT_MPEG2:	descr = "MPEG-2 ES"; break;
 		case V4L2_PIX_FMT_MPEG2_SLICE:	descr = "MPEG-2 Parsed Slice Data"; break;
-		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 part 2 ES"; break;
+		case V4L2_PIX_FMT_MPEG4:	descr = "MPEG-4 Part 2 ES"; break;
 		case V4L2_PIX_FMT_XVID:		descr = "Xvid"; break;
 		case V4L2_PIX_FMT_VC1_ANNEX_G:	descr = "VC-1 (SMPTE 412M Annex G)"; break;
 		case V4L2_PIX_FMT_VC1_ANNEX_L:	descr = "VC-1 (SMPTE 412M Annex L)"; break;
 		case V4L2_PIX_FMT_VP8:		descr = "VP8"; break;
+		case V4L2_PIX_FMT_VP8_FRAME:    descr = "VP8 Frame"; break;
 		case V4L2_PIX_FMT_VP9:		descr = "VP9"; break;
 		case V4L2_PIX_FMT_HEVC:		descr = "HEVC"; break; /* aka H.265 */
 		case V4L2_PIX_FMT_FWHT:		descr = "FWHT"; break; /* used in vicodec */
@@ -1365,14 +1388,14 @@
 					(char)((fmt->pixelformat >> 8) & 0x7f),
 					(char)((fmt->pixelformat >> 16) & 0x7f),
 					(char)((fmt->pixelformat >> 24) & 0x7f),
-					(fmt->pixelformat & (1 << 31)) ? "-BE" : "");
+					(fmt->pixelformat & (1UL << 31)) ? "-BE" : "");
 			break;
 		}
 	}
 
 	if (descr)
 		WARN_ON(strscpy(fmt->description, descr, sz) < 0);
-	fmt->flags = flags;
+	fmt->flags |= flags;
 }
 
 static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
@@ -1645,6 +1668,7 @@
 				struct file *file, void *fh, void *arg)
 {
 	struct v4l2_format *p = arg;
+	struct video_device *vfd = video_devdata(file);
 	int ret = check_fmt(file, p->type);
 	unsigned int i;
 
@@ -1661,6 +1685,8 @@
 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
 		/* just in case the driver zeroed it again */
 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
+		if (vfd->vfl_type == VFL_TYPE_TOUCH)
+			v4l_pix_format_touch(&p->fmt.pix);
 		return ret;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 		if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
@@ -2165,9 +2191,11 @@
 
 	p->error_idx = p->count;
 	if (vfh && vfh->ctrl_handler)
-		return v4l2_g_ext_ctrls(vfh->ctrl_handler, vfd->v4l2_dev->mdev, p);
+		return v4l2_g_ext_ctrls(vfh->ctrl_handler,
+					vfd, vfd->v4l2_dev->mdev, p);
 	if (vfd->ctrl_handler)
-		return v4l2_g_ext_ctrls(vfd->ctrl_handler, vfd->v4l2_dev->mdev, p);
+		return v4l2_g_ext_ctrls(vfd->ctrl_handler,
+					vfd, vfd->v4l2_dev->mdev, p);
 	if (ops->vidioc_g_ext_ctrls == NULL)
 		return -ENOTTY;
 	return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) :
@@ -2184,9 +2212,11 @@
 
 	p->error_idx = p->count;
 	if (vfh && vfh->ctrl_handler)
-		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, vfd->v4l2_dev->mdev, p);
+		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,
+					vfd, vfd->v4l2_dev->mdev, p);
 	if (vfd->ctrl_handler)
-		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, vfd->v4l2_dev->mdev, p);
+		return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler,
+					vfd, vfd->v4l2_dev->mdev, p);
 	if (ops->vidioc_s_ext_ctrls == NULL)
 		return -ENOTTY;
 	return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) :
@@ -2203,9 +2233,11 @@
 
 	p->error_idx = p->count;
 	if (vfh && vfh->ctrl_handler)
-		return v4l2_try_ext_ctrls(vfh->ctrl_handler, vfd->v4l2_dev->mdev, p);
+		return v4l2_try_ext_ctrls(vfh->ctrl_handler,
+					  vfd, vfd->v4l2_dev->mdev, p);
 	if (vfd->ctrl_handler)
-		return v4l2_try_ext_ctrls(vfd->ctrl_handler, vfd->v4l2_dev->mdev, p);
+		return v4l2_try_ext_ctrls(vfd->ctrl_handler,
+					  vfd, vfd->v4l2_dev->mdev, p);
 	if (ops->vidioc_try_ext_ctrls == NULL)
 		return -ENOTTY;
 	return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) :
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 4f51767..19937dd 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -603,11 +603,10 @@
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff);
 
-__poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
-			   struct poll_table_struct *wait)
+static __poll_t v4l2_m2m_poll_for_data(struct file *file,
+				       struct v4l2_m2m_ctx *m2m_ctx,
+				       struct poll_table_struct *wait)
 {
-	struct video_device *vfd = video_devdata(file);
-	__poll_t req_events = poll_requested_events(wait);
 	struct vb2_queue *src_q, *dst_q;
 	struct vb2_buffer *src_vb = NULL, *dst_vb = NULL;
 	__poll_t rc = 0;
@@ -619,16 +618,6 @@
 	poll_wait(file, &src_q->done_wq, wait);
 	poll_wait(file, &dst_q->done_wq, wait);
 
-	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
-		struct v4l2_fh *fh = file->private_data;
-
-		poll_wait(file, &fh->wait, wait);
-		if (v4l2_event_pending(fh))
-			rc = EPOLLPRI;
-		if (!(req_events & (EPOLLOUT | EPOLLWRNORM | EPOLLIN | EPOLLRDNORM)))
-			return rc;
-	}
-
 	/*
 	 * There has to be at least one buffer queued on each queued_list, which
 	 * means either in driver already or waiting for driver to claim it
@@ -637,10 +626,8 @@
 	if ((!src_q->streaming || src_q->error ||
 	     list_empty(&src_q->queued_list)) &&
 	    (!dst_q->streaming || dst_q->error ||
-	     list_empty(&dst_q->queued_list))) {
-		rc |= EPOLLERR;
-		goto end;
-	}
+	     list_empty(&dst_q->queued_list)))
+		return EPOLLERR;
 
 	spin_lock_irqsave(&dst_q->done_lock, flags);
 	if (list_empty(&dst_q->done_list)) {
@@ -650,7 +637,7 @@
 		 */
 		if (dst_q->last_buffer_dequeued) {
 			spin_unlock_irqrestore(&dst_q->done_lock, flags);
-			return rc | EPOLLIN | EPOLLRDNORM;
+			return EPOLLIN | EPOLLRDNORM;
 		}
 	}
 	spin_unlock_irqrestore(&dst_q->done_lock, flags);
@@ -673,7 +660,27 @@
 		rc |= EPOLLIN | EPOLLRDNORM;
 	spin_unlock_irqrestore(&dst_q->done_lock, flags);
 
-end:
+	return rc;
+}
+
+__poll_t v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+		       struct poll_table_struct *wait)
+{
+	struct video_device *vfd = video_devdata(file);
+	__poll_t req_events = poll_requested_events(wait);
+	__poll_t rc = 0;
+
+	if (req_events & (EPOLLOUT | EPOLLWRNORM | EPOLLIN | EPOLLRDNORM))
+		rc = v4l2_m2m_poll_for_data(file, m2m_ctx, wait);
+
+	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
+		struct v4l2_fh *fh = file->private_data;
+
+		poll_wait(file, &fh->wait, wait);
+		if (v4l2_event_pending(fh))
+			rc |= EPOLLPRI;
+	}
+
 	return rc;
 }
 EXPORT_SYMBOL_GPL(v4l2_m2m_poll);
diff --git a/drivers/media/v4l2-core/v4l2-spi.c b/drivers/media/v4l2-core/v4l2-spi.c
new file mode 100644
index 0000000..eadecdf
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-spi.c
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * v4l2-spi - SPI helpers for Video4Linux2
+ */
+
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+
+void v4l2_spi_subdev_unregister(struct v4l2_subdev *sd)
+{
+	struct spi_device *spi = v4l2_get_subdevdata(sd);
+
+	if (spi && !spi->dev.of_node && !spi->dev.fwnode)
+		spi_unregister_device(spi);
+}
+
+void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
+			  const struct v4l2_subdev_ops *ops)
+{
+	v4l2_subdev_init(sd, ops);
+	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);
+	/* initialize name */
+	snprintf(sd->name, sizeof(sd->name), "%s %s",
+		 spi->dev.driver->name, dev_name(&spi->dev));
+}
+EXPORT_SYMBOL_GPL(v4l2_spi_subdev_init);
+
+struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
+					struct spi_master *master,
+					struct spi_board_info *info)
+{
+	struct v4l2_subdev *sd = NULL;
+	struct spi_device *spi = NULL;
+
+	if (!v4l2_dev)
+		return NULL;
+	if (info->modalias[0])
+		request_module(info->modalias);
+
+	spi = spi_new_device(master, info);
+
+	if (!spi || !spi->dev.driver)
+		goto error;
+
+	if (!try_module_get(spi->dev.driver->owner))
+		goto error;
+
+	sd = spi_get_drvdata(spi);
+
+	/*
+	 * Register with the v4l2_device which increases the module's
+	 * use count as well.
+	 */
+	if (v4l2_device_register_subdev(v4l2_dev, sd))
+		sd = NULL;
+
+	/* Decrease the module use count to match the first try_module_get. */
+	module_put(spi->dev.driver->owner);
+
+error:
+	/*
+	 * If we have a client but no subdev, then something went wrong and
+	 * we must unregister the client.
+	 */
+	if (!sd)
+		spi_unregister_device(spi);
+
+	return sd;
+}
+EXPORT_SYMBOL_GPL(v4l2_spi_new_subdev);
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 25c73c1..f725cd9 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -372,19 +372,19 @@
 		if (!vfh->ctrl_handler)
 			return -ENOTTY;
 		return v4l2_g_ext_ctrls(vfh->ctrl_handler,
-					sd->v4l2_dev->mdev, arg);
+					vdev, sd->v4l2_dev->mdev, arg);
 
 	case VIDIOC_S_EXT_CTRLS:
 		if (!vfh->ctrl_handler)
 			return -ENOTTY;
 		return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler,
-					sd->v4l2_dev->mdev, arg);
+					vdev, sd->v4l2_dev->mdev, arg);
 
 	case VIDIOC_TRY_EXT_CTRLS:
 		if (!vfh->ctrl_handler)
 			return -ENOTTY;
 		return v4l2_try_ext_ctrls(vfh->ctrl_handler,
-					  sd->v4l2_dev->mdev, arg);
+					  vdev, sd->v4l2_dev->mdev, arg);
 
 	case VIDIOC_DQEVENT:
 		if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
diff --git a/drivers/media/v4l2-core/videobuf-core.c b/drivers/media/v4l2-core/videobuf-core.c
index 7ef3e4d..939fc11 100644
--- a/drivers/media/v4l2-core/videobuf-core.c
+++ b/drivers/media/v4l2-core/videobuf-core.c
@@ -1123,7 +1123,6 @@
 	struct videobuf_buffer *buf = NULL;
 	__poll_t rc = 0;
 
-	poll_wait(file, &buf->done, wait);
 	videobuf_queue_lock(q);
 	if (q->streaming) {
 		if (!list_empty(&q->stream))
@@ -1143,7 +1142,9 @@
 		}
 		buf = q->read_buf;
 	}
-	if (!buf)
+	if (buf)
+		poll_wait(file, &buf->done, wait);
+	else
 		rc = EPOLLERR;
 
 	if (0 == rc) {
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index 534d85d..642adc4 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -22,10 +22,6 @@
 # Please keep them in alphabetic order
 source "drivers/staging/media/allegro-dvt/Kconfig"
 
-source "drivers/staging/media/bcm2048/Kconfig"
-
-source "drivers/staging/media/davinci_vpfe/Kconfig"
-
 source "drivers/staging/media/hantro/Kconfig"
 
 source "drivers/staging/media/imx/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index c486298..2f1711a 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -1,8 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_VIDEO_ALLEGRO_DVT)	+= allegro-dvt/
-obj-$(CONFIG_I2C_BCM2048)	+= bcm2048/
 obj-$(CONFIG_VIDEO_IMX_MEDIA)	+= imx/
-obj-$(CONFIG_VIDEO_DM365_VPFE)	+= davinci_vpfe/
 obj-$(CONFIG_VIDEO_MESON_VDEC)	+= meson/vdec/
 obj-$(CONFIG_VIDEO_OMAP4)	+= omap4iss/
 obj-$(CONFIG_VIDEO_SUNXI)	+= sunxi/
diff --git a/drivers/staging/media/bcm2048/Kconfig b/drivers/staging/media/bcm2048/Kconfig
deleted file mode 100644
index ab2d50c..0000000
--- a/drivers/staging/media/bcm2048/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Multimedia Video device configuration
-#
-
-config I2C_BCM2048
-	tristate "Broadcom BCM2048 FM Radio Receiver support"
-	depends on I2C && VIDEO_V4L2 && RADIO_ADAPTERS
-	help
-	  Say Y here if you want support to BCM2048 FM Radio Receiver.
-	  This device driver supports only i2c bus.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called radio-bcm2048.
diff --git a/drivers/staging/media/bcm2048/Makefile b/drivers/staging/media/bcm2048/Makefile
deleted file mode 100644
index f420568..0000000
--- a/drivers/staging/media/bcm2048/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_I2C_BCM2048) += radio-bcm2048.o
diff --git a/drivers/staging/media/bcm2048/TODO b/drivers/staging/media/bcm2048/TODO
deleted file mode 100644
index 6bee2a2da..0000000
--- a/drivers/staging/media/bcm2048/TODO
+++ /dev/null
@@ -1,24 +0,0 @@
-TODO:
-
-From the initial code review:
-
-The main thing you need to do is to implement all the controls using the
-control framework (see Documentation/media/kapi/v4l2-controls.rst).
-Most drivers are by now converted to the control framework, so you will
-find many examples of how to do this in drivers/media/radio.
-
-The sysfs stuff should be replaced by controls as well. A lot of the RDS
-support is now available as controls (although there may well be some
-missing features, but that is easy enough to add). Since the RDS data is
-actually read() from the device I am not sure whether the RDS
-properties/controls should be there at all.
-
-Correct Coding Style, as this driver also violates several Style
-rules, and do evil tricks, like returning from a function inside a
-macro.
-
-Finally this driver should probably be split up into two parts: one
-v4l2_subdev-based core driver and one platform driver. See e.g.
-radio-si4713/si4713-i2c.c as a good example. But I would wait with that
-until the rest of the driver is cleaned up. Then I have a better idea of
-whether this is necessary or not.
diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c
deleted file mode 100644
index 2c60a1f..0000000
--- a/drivers/staging/media/bcm2048/radio-bcm2048.c
+++ /dev/null
@@ -1,2689 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * drivers/staging/media/radio-bcm2048.c
- *
- * Driver for I2C Broadcom BCM2048 FM Radio Receiver:
- *
- * Copyright (C) Nokia Corporation
- * Contact: Eero Nurkkala <ext-eero.nurkkala@nokia.com>
- *
- * Copyright (C) Nils Faerber <nils.faerber@kernelconcepts.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- */
-
-/*
- * History:
- *		Eero Nurkkala <ext-eero.nurkkala@nokia.com>
- *		Version 0.0.1
- *		- Initial implementation
- * 2010-02-21	Nils Faerber <nils.faerber@kernelconcepts.de>
- *		Version 0.0.2
- *		- Add support for interrupt driven rds data reading
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/version.h>
-#include <linux/interrupt.h>
-#include <linux/sysfs.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/videodev2.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include "radio-bcm2048.h"
-
-/* driver definitions */
-#define BCM2048_DRIVER_AUTHOR	"Eero Nurkkala <ext-eero.nurkkala@nokia.com>"
-#define BCM2048_DRIVER_NAME	BCM2048_NAME
-#define BCM2048_DRIVER_CARD	"Broadcom bcm2048 FM Radio Receiver"
-#define BCM2048_DRIVER_DESC	"I2C driver for BCM2048 FM Radio Receiver"
-
-/* I2C Control Registers */
-#define BCM2048_I2C_FM_RDS_SYSTEM	0x00
-#define BCM2048_I2C_FM_CTRL		0x01
-#define BCM2048_I2C_RDS_CTRL0		0x02
-#define BCM2048_I2C_RDS_CTRL1		0x03
-#define BCM2048_I2C_FM_AUDIO_PAUSE	0x04
-#define BCM2048_I2C_FM_AUDIO_CTRL0	0x05
-#define BCM2048_I2C_FM_AUDIO_CTRL1	0x06
-#define BCM2048_I2C_FM_SEARCH_CTRL0	0x07
-#define BCM2048_I2C_FM_SEARCH_CTRL1	0x08
-#define BCM2048_I2C_FM_SEARCH_TUNE_MODE	0x09
-#define BCM2048_I2C_FM_FREQ0		0x0a
-#define BCM2048_I2C_FM_FREQ1		0x0b
-#define BCM2048_I2C_FM_AF_FREQ0		0x0c
-#define BCM2048_I2C_FM_AF_FREQ1		0x0d
-#define BCM2048_I2C_FM_CARRIER		0x0e
-#define BCM2048_I2C_FM_RSSI		0x0f
-#define BCM2048_I2C_FM_RDS_MASK0	0x10
-#define BCM2048_I2C_FM_RDS_MASK1	0x11
-#define BCM2048_I2C_FM_RDS_FLAG0	0x12
-#define BCM2048_I2C_FM_RDS_FLAG1	0x13
-#define BCM2048_I2C_RDS_WLINE		0x14
-#define BCM2048_I2C_RDS_BLKB_MATCH0	0x16
-#define BCM2048_I2C_RDS_BLKB_MATCH1	0x17
-#define BCM2048_I2C_RDS_BLKB_MASK0	0x18
-#define BCM2048_I2C_RDS_BLKB_MASK1	0x19
-#define BCM2048_I2C_RDS_PI_MATCH0	0x1a
-#define BCM2048_I2C_RDS_PI_MATCH1	0x1b
-#define BCM2048_I2C_RDS_PI_MASK0	0x1c
-#define BCM2048_I2C_RDS_PI_MASK1	0x1d
-#define BCM2048_I2C_SPARE1		0x20
-#define BCM2048_I2C_SPARE2		0x21
-#define BCM2048_I2C_FM_RDS_REV		0x28
-#define BCM2048_I2C_SLAVE_CONFIGURATION	0x29
-#define BCM2048_I2C_RDS_DATA		0x80
-#define BCM2048_I2C_FM_BEST_TUNE_MODE	0x90
-
-/* BCM2048_I2C_FM_RDS_SYSTEM */
-#define BCM2048_FM_ON			0x01
-#define BCM2048_RDS_ON			0x02
-
-/* BCM2048_I2C_FM_CTRL */
-#define BCM2048_BAND_SELECT			0x01
-#define BCM2048_STEREO_MONO_AUTO_SELECT		0x02
-#define BCM2048_STEREO_MONO_MANUAL_SELECT	0x04
-#define BCM2048_STEREO_MONO_BLEND_SWITCH	0x08
-#define BCM2048_HI_LO_INJECTION			0x10
-
-/* BCM2048_I2C_RDS_CTRL0 */
-#define BCM2048_RBDS_RDS_SELECT		0x01
-#define BCM2048_FLUSH_FIFO		0x02
-
-/* BCM2048_I2C_FM_AUDIO_PAUSE */
-#define BCM2048_AUDIO_PAUSE_RSSI_TRESH	0x0f
-#define BCM2048_AUDIO_PAUSE_DURATION	0xf0
-
-/* BCM2048_I2C_FM_AUDIO_CTRL0 */
-#define BCM2048_RF_MUTE			0x01
-#define BCM2048_MANUAL_MUTE		0x02
-#define BCM2048_DAC_OUTPUT_LEFT		0x04
-#define BCM2048_DAC_OUTPUT_RIGHT	0x08
-#define BCM2048_AUDIO_ROUTE_DAC		0x10
-#define BCM2048_AUDIO_ROUTE_I2S		0x20
-#define BCM2048_DE_EMPHASIS_SELECT	0x40
-#define BCM2048_AUDIO_BANDWIDTH_SELECT	0x80
-
-/* BCM2048_I2C_FM_SEARCH_CTRL0 */
-#define BCM2048_SEARCH_RSSI_THRESHOLD	0x7f
-#define BCM2048_SEARCH_DIRECTION	0x80
-
-/* BCM2048_I2C_FM_SEARCH_TUNE_MODE */
-#define BCM2048_FM_AUTO_SEARCH		0x03
-
-/* BCM2048_I2C_FM_RSSI */
-#define BCM2048_RSSI_VALUE		0xff
-
-/* BCM2048_I2C_FM_RDS_MASK0 */
-/* BCM2048_I2C_FM_RDS_MASK1 */
-#define BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED	0x01
-#define BCM2048_FM_FLAG_SEARCH_TUNE_FAIL	0x02
-#define BCM2048_FM_FLAG_RSSI_LOW		0x04
-#define BCM2048_FM_FLAG_CARRIER_ERROR_HIGH	0x08
-#define BCM2048_FM_FLAG_AUDIO_PAUSE_INDICATION	0x10
-#define BCM2048_FLAG_STEREO_DETECTED		0x20
-#define BCM2048_FLAG_STEREO_ACTIVE		0x40
-
-/* BCM2048_I2C_RDS_DATA */
-#define BCM2048_SLAVE_ADDRESS			0x3f
-#define BCM2048_SLAVE_ENABLE			0x80
-
-/* BCM2048_I2C_FM_BEST_TUNE_MODE */
-#define BCM2048_BEST_TUNE_MODE			0x80
-
-#define BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED	0x01
-#define BCM2048_FM_FLAG_SEARCH_TUNE_FAIL	0x02
-#define BCM2048_FM_FLAG_RSSI_LOW		0x04
-#define BCM2048_FM_FLAG_CARRIER_ERROR_HIGH	0x08
-#define BCM2048_FM_FLAG_AUDIO_PAUSE_INDICATION	0x10
-#define BCM2048_FLAG_STEREO_DETECTED		0x20
-#define BCM2048_FLAG_STEREO_ACTIVE		0x40
-
-#define BCM2048_RDS_FLAG_FIFO_WLINE		0x02
-#define BCM2048_RDS_FLAG_B_BLOCK_MATCH		0x08
-#define BCM2048_RDS_FLAG_SYNC_LOST		0x10
-#define BCM2048_RDS_FLAG_PI_MATCH		0x20
-
-#define BCM2048_RDS_MARK_END_BYTE0		0x7C
-#define BCM2048_RDS_MARK_END_BYTEN		0xFF
-
-#define BCM2048_FM_FLAGS_ALL	(FM_FLAG_SEARCH_TUNE_FINISHED | \
-				 FM_FLAG_SEARCH_TUNE_FAIL | \
-				 FM_FLAG_RSSI_LOW | \
-				 FM_FLAG_CARRIER_ERROR_HIGH | \
-				 FM_FLAG_AUDIO_PAUSE_INDICATION | \
-				 FLAG_STEREO_DETECTED | FLAG_STEREO_ACTIVE)
-
-#define BCM2048_RDS_FLAGS_ALL	(RDS_FLAG_FIFO_WLINE | \
-				 RDS_FLAG_B_BLOCK_MATCH | \
-				 RDS_FLAG_SYNC_LOST | RDS_FLAG_PI_MATCH)
-
-#define BCM2048_DEFAULT_TIMEOUT		1500
-#define BCM2048_AUTO_SEARCH_TIMEOUT	3000
-
-#define BCM2048_FREQDEV_UNIT		10000
-#define BCM2048_FREQV4L2_MULTI		625
-#define dev_to_v4l2(f)	(((f) * BCM2048_FREQDEV_UNIT) / BCM2048_FREQV4L2_MULTI)
-#define v4l2_to_dev(f)	(((f) * BCM2048_FREQV4L2_MULTI) / BCM2048_FREQDEV_UNIT)
-
-#define msb(x)                  ((u8)((u16)(x) >> 8))
-#define lsb(x)                  ((u8)((u16)(x) &  0x00FF))
-#define compose_u16(msb, lsb)	(((u16)(msb) << 8) | (lsb))
-
-#define BCM2048_DEFAULT_POWERING_DELAY	20
-#define BCM2048_DEFAULT_REGION		0x02
-#define BCM2048_DEFAULT_MUTE		0x01
-#define BCM2048_DEFAULT_RSSI_THRESHOLD	0x64
-#define BCM2048_DEFAULT_RDS_WLINE	0x7E
-
-#define BCM2048_FM_SEARCH_INACTIVE	0x00
-#define BCM2048_FM_PRE_SET_MODE		0x01
-#define BCM2048_FM_AUTO_SEARCH_MODE	0x02
-#define BCM2048_FM_AF_JUMP_MODE		0x03
-
-#define BCM2048_FREQUENCY_BASE		64000
-
-#define BCM2048_POWER_ON		0x01
-#define BCM2048_POWER_OFF		0x00
-
-#define BCM2048_ITEM_ENABLED		0x01
-#define BCM2048_SEARCH_DIRECTION_UP	0x01
-
-#define BCM2048_DE_EMPHASIS_75us	75
-#define BCM2048_DE_EMPHASIS_50us	50
-
-#define BCM2048_SCAN_FAIL		0x00
-#define BCM2048_SCAN_OK			0x01
-
-#define BCM2048_FREQ_ERROR_FLOOR	-20
-#define BCM2048_FREQ_ERROR_ROOF		20
-
-/* -60 dB is reported as full signal strength */
-#define BCM2048_RSSI_LEVEL_BASE		-60
-#define BCM2048_RSSI_LEVEL_ROOF		-100
-#define BCM2048_RSSI_LEVEL_ROOF_NEG	100
-#define BCM2048_SIGNAL_MULTIPLIER	(0xFFFF / \
-					 (BCM2048_RSSI_LEVEL_ROOF_NEG + \
-					  BCM2048_RSSI_LEVEL_BASE))
-
-#define BCM2048_RDS_FIFO_DUPLE_SIZE	0x03
-#define BCM2048_RDS_CRC_MASK		0x0F
-#define BCM2048_RDS_CRC_NONE		0x00
-#define BCM2048_RDS_CRC_MAX_2BITS	0x04
-#define BCM2048_RDS_CRC_LEAST_2BITS	0x08
-#define BCM2048_RDS_CRC_UNRECOVARABLE	0x0C
-
-#define BCM2048_RDS_BLOCK_MASK		0xF0
-#define BCM2048_RDS_BLOCK_A		0x00
-#define BCM2048_RDS_BLOCK_B		0x10
-#define BCM2048_RDS_BLOCK_C		0x20
-#define BCM2048_RDS_BLOCK_D		0x30
-#define BCM2048_RDS_BLOCK_C_SCORED	0x40
-#define BCM2048_RDS_BLOCK_E		0x60
-
-#define BCM2048_RDS_RT			0x20
-#define BCM2048_RDS_PS			0x00
-
-#define BCM2048_RDS_GROUP_AB_MASK	0x08
-#define BCM2048_RDS_GROUP_A		0x00
-#define BCM2048_RDS_GROUP_B		0x08
-
-#define BCM2048_RDS_RT_AB_MASK		0x10
-#define BCM2048_RDS_RT_A		0x00
-#define BCM2048_RDS_RT_B		0x10
-#define BCM2048_RDS_RT_INDEX		0x0F
-
-#define BCM2048_RDS_PS_INDEX		0x03
-
-struct rds_info {
-	u16 rds_pi;
-#define BCM2048_MAX_RDS_RT (64 + 1)
-	u8 rds_rt[BCM2048_MAX_RDS_RT];
-	u8 rds_rt_group_b;
-	u8 rds_rt_ab;
-#define BCM2048_MAX_RDS_PS (8 + 1)
-	u8 rds_ps[BCM2048_MAX_RDS_PS];
-	u8 rds_ps_group;
-	u8 rds_ps_group_cnt;
-#define BCM2048_MAX_RDS_RADIO_TEXT 255
-	u8 radio_text[BCM2048_MAX_RDS_RADIO_TEXT + 3];
-	u8 text_len;
-};
-
-struct region_info {
-	u32 bottom_frequency;
-	u32 top_frequency;
-	u8 deemphasis;
-	u8 channel_spacing;
-	u8 region;
-};
-
-struct bcm2048_device {
-	struct i2c_client *client;
-	struct video_device videodev;
-	struct work_struct work;
-	struct completion compl;
-	struct mutex mutex;
-	struct bcm2048_platform_data *platform_data;
-	struct rds_info rds_info;
-	struct region_info region_info;
-	u16 frequency;
-	u8 cache_fm_rds_system;
-	u8 cache_fm_ctrl;
-	u8 cache_fm_audio_ctrl0;
-	u8 cache_fm_search_ctrl0;
-	u8 power_state;
-	u8 rds_state;
-	u8 fifo_size;
-	u8 scan_state;
-	u8 mute_state;
-
-	/* for rds data device read */
-	wait_queue_head_t read_queue;
-	unsigned int users;
-	unsigned char rds_data_available;
-	unsigned int rd_index;
-};
-
-static int radio_nr = -1;	/* radio device minor (-1 ==> auto assign) */
-module_param(radio_nr, int, 0000);
-MODULE_PARM_DESC(radio_nr,
-		 "Minor number for radio device (-1 ==> auto assign)");
-
-static const struct region_info region_configs[] = {
-	/* USA */
-	{
-		.channel_spacing	= 20,
-		.bottom_frequency	= 87500,
-		.top_frequency		= 108000,
-		.deemphasis		= 75,
-		.region			= 0,
-	},
-	/* Australia */
-	{
-		.channel_spacing	= 20,
-		.bottom_frequency	= 87500,
-		.top_frequency		= 108000,
-		.deemphasis		= 50,
-		.region			= 1,
-	},
-	/* Europe */
-	{
-		.channel_spacing	= 10,
-		.bottom_frequency	= 87500,
-		.top_frequency		= 108000,
-		.deemphasis		= 50,
-		.region			= 2,
-	},
-	/* Japan */
-	{
-		.channel_spacing	= 10,
-		.bottom_frequency	= 76000,
-		.top_frequency		= 90000,
-		.deemphasis		= 50,
-		.region			= 3,
-	},
-};
-
-/*
- *	I2C Interface read / write
- */
-static int bcm2048_send_command(struct bcm2048_device *bdev, unsigned int reg,
-				unsigned int value)
-{
-	struct i2c_client *client = bdev->client;
-	u8 data[2];
-
-	if (!bdev->power_state) {
-		dev_err(&bdev->client->dev, "bcm2048: chip not powered!\n");
-		return -EIO;
-	}
-
-	data[0] = reg & 0xff;
-	data[1] = value & 0xff;
-
-	if (i2c_master_send(client, data, 2) == 2)
-		return 0;
-
-	dev_err(&bdev->client->dev, "BCM I2C error!\n");
-	dev_err(&bdev->client->dev, "Is Bluetooth up and running?\n");
-	return -EIO;
-}
-
-static int bcm2048_recv_command(struct bcm2048_device *bdev, unsigned int reg,
-				u8 *value)
-{
-	struct i2c_client *client = bdev->client;
-
-	if (!bdev->power_state) {
-		dev_err(&bdev->client->dev, "bcm2048: chip not powered!\n");
-		return -EIO;
-	}
-
-	value[0] = i2c_smbus_read_byte_data(client, reg & 0xff);
-
-	return 0;
-}
-
-static int bcm2048_recv_duples(struct bcm2048_device *bdev, unsigned int reg,
-			       u8 *value, u8 duples)
-{
-	struct i2c_client *client = bdev->client;
-	struct i2c_adapter *adap = client->adapter;
-	struct i2c_msg msg[2];
-	u8 buf;
-
-	if (!bdev->power_state) {
-		dev_err(&bdev->client->dev, "bcm2048: chip not powered!\n");
-		return -EIO;
-	}
-
-	buf = reg & 0xff;
-
-	msg[0].addr = client->addr;
-	msg[0].flags = client->flags & I2C_M_TEN;
-	msg[0].len = 1;
-	msg[0].buf = &buf;
-
-	msg[1].addr = client->addr;
-	msg[1].flags = client->flags & I2C_M_TEN;
-	msg[1].flags |= I2C_M_RD;
-	msg[1].len = duples;
-	msg[1].buf = value;
-
-	return i2c_transfer(adap, msg, 2);
-}
-
-/*
- *	BCM2048 - I2C register programming helpers
- */
-static int bcm2048_set_power_state(struct bcm2048_device *bdev, u8 power)
-{
-	int err = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	if (power) {
-		bdev->power_state = BCM2048_POWER_ON;
-		bdev->cache_fm_rds_system |= BCM2048_FM_ON;
-	} else {
-		bdev->cache_fm_rds_system &= ~BCM2048_FM_ON;
-	}
-
-	/*
-	 * Warning! FM cannot be turned off because then
-	 * the I2C communications get ruined!
-	 * Comment off the "if (power)" when the chip works!
-	 */
-	if (power)
-		err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM,
-					   bdev->cache_fm_rds_system);
-	msleep(BCM2048_DEFAULT_POWERING_DELAY);
-
-	if (!power)
-		bdev->power_state = BCM2048_POWER_OFF;
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_power_state(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM, &value);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err && (value & BCM2048_FM_ON))
-		return BCM2048_POWER_ON;
-
-	return err;
-}
-
-static int bcm2048_set_rds_no_lock(struct bcm2048_device *bdev, u8 rds_on)
-{
-	int err;
-	u8 flags;
-
-	bdev->cache_fm_rds_system &= ~BCM2048_RDS_ON;
-
-	if (rds_on) {
-		bdev->cache_fm_rds_system |= BCM2048_RDS_ON;
-		bdev->rds_state = BCM2048_RDS_ON;
-		flags =	BCM2048_RDS_FLAG_FIFO_WLINE;
-		err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
-					   flags);
-	} else {
-		flags =	0;
-		bdev->rds_state = 0;
-		err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
-					   flags);
-		memset(&bdev->rds_info, 0, sizeof(bdev->rds_info));
-	}
-	if (err)
-		return err;
-
-	return bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM,
-				    bdev->cache_fm_rds_system);
-}
-
-static int bcm2048_get_rds_no_lock(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_SYSTEM, &value);
-
-	if (!err && (value & BCM2048_RDS_ON))
-		return BCM2048_ITEM_ENABLED;
-
-	return err;
-}
-
-static int bcm2048_set_rds(struct bcm2048_device *bdev, u8 rds_on)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_set_rds_no_lock(bdev, rds_on);
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_rds(struct bcm2048_device *bdev)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_get_rds_no_lock(bdev);
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_rds_pi(struct bcm2048_device *bdev)
-{
-	return bdev->rds_info.rds_pi;
-}
-
-static int bcm2048_set_fm_automatic_stereo_mono(struct bcm2048_device *bdev,
-						u8 enabled)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	bdev->cache_fm_ctrl &= ~BCM2048_STEREO_MONO_AUTO_SELECT;
-
-	if (enabled)
-		bdev->cache_fm_ctrl |= BCM2048_STEREO_MONO_AUTO_SELECT;
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL,
-				   bdev->cache_fm_ctrl);
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_set_fm_hi_lo_injection(struct bcm2048_device *bdev,
-					  u8 hi_lo)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	bdev->cache_fm_ctrl &= ~BCM2048_HI_LO_INJECTION;
-
-	if (hi_lo)
-		bdev->cache_fm_ctrl |= BCM2048_HI_LO_INJECTION;
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL,
-				   bdev->cache_fm_ctrl);
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_fm_hi_lo_injection(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_CTRL, &value);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err && (value & BCM2048_HI_LO_INJECTION))
-		return BCM2048_ITEM_ENABLED;
-
-	return err;
-}
-
-static int bcm2048_set_fm_frequency(struct bcm2048_device *bdev, u32 frequency)
-{
-	int err;
-
-	if (frequency < bdev->region_info.bottom_frequency ||
-	    frequency > bdev->region_info.top_frequency)
-		return -EDOM;
-
-	frequency -= BCM2048_FREQUENCY_BASE;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_FREQ0, lsb(frequency));
-	err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_FREQ1,
-				    msb(frequency));
-
-	if (!err)
-		bdev->frequency = frequency;
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_fm_frequency(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 lsb = 0, msb = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_FREQ0, &lsb);
-	err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_FREQ1, &msb);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (err)
-		return err;
-
-	err = compose_u16(msb, lsb);
-	err += BCM2048_FREQUENCY_BASE;
-
-	return err;
-}
-
-static int bcm2048_set_fm_af_frequency(struct bcm2048_device *bdev,
-				       u32 frequency)
-{
-	int err;
-
-	if (frequency < bdev->region_info.bottom_frequency ||
-	    frequency > bdev->region_info.top_frequency)
-		return -EDOM;
-
-	frequency -= BCM2048_FREQUENCY_BASE;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AF_FREQ0,
-				   lsb(frequency));
-	err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_AF_FREQ1,
-				    msb(frequency));
-	if (!err)
-		bdev->frequency = frequency;
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_fm_af_frequency(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 lsb = 0, msb = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AF_FREQ0, &lsb);
-	err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_AF_FREQ1, &msb);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (err)
-		return err;
-
-	err = compose_u16(msb, lsb);
-	err += BCM2048_FREQUENCY_BASE;
-
-	return err;
-}
-
-static int bcm2048_set_fm_deemphasis(struct bcm2048_device *bdev, int d)
-{
-	int err;
-	u8 deemphasis;
-
-	if (d == BCM2048_DE_EMPHASIS_75us)
-		deemphasis = BCM2048_DE_EMPHASIS_SELECT;
-	else
-		deemphasis = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	bdev->cache_fm_audio_ctrl0 &= ~BCM2048_DE_EMPHASIS_SELECT;
-	bdev->cache_fm_audio_ctrl0 |= deemphasis;
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
-				   bdev->cache_fm_audio_ctrl0);
-
-	if (!err)
-		bdev->region_info.deemphasis = d;
-
-	mutex_unlock(&bdev->mutex);
-
-	return err;
-}
-
-static int bcm2048_get_fm_deemphasis(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, &value);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err) {
-		if (value & BCM2048_DE_EMPHASIS_SELECT)
-			return BCM2048_DE_EMPHASIS_75us;
-
-		return BCM2048_DE_EMPHASIS_50us;
-	}
-
-	return err;
-}
-
-static int bcm2048_set_region(struct bcm2048_device *bdev, u8 region)
-{
-	int err;
-	u32 new_frequency = 0;
-
-	if (region >= ARRAY_SIZE(region_configs))
-		return -EINVAL;
-
-	mutex_lock(&bdev->mutex);
-	bdev->region_info = region_configs[region];
-
-	if (region_configs[region].bottom_frequency < 87500)
-		bdev->cache_fm_ctrl |= BCM2048_BAND_SELECT;
-	else
-		bdev->cache_fm_ctrl &= ~BCM2048_BAND_SELECT;
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_CTRL,
-				   bdev->cache_fm_ctrl);
-	if (err) {
-		mutex_unlock(&bdev->mutex);
-		goto done;
-	}
-	mutex_unlock(&bdev->mutex);
-
-	if (bdev->frequency < region_configs[region].bottom_frequency ||
-	    bdev->frequency > region_configs[region].top_frequency)
-		new_frequency = region_configs[region].bottom_frequency;
-
-	if (new_frequency > 0) {
-		err = bcm2048_set_fm_frequency(bdev, new_frequency);
-
-		if (err)
-			goto done;
-	}
-
-	err = bcm2048_set_fm_deemphasis(bdev,
-					region_configs[region].deemphasis);
-
-done:
-	return err;
-}
-
-static int bcm2048_get_region(struct bcm2048_device *bdev)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-	err = bdev->region_info.region;
-	mutex_unlock(&bdev->mutex);
-
-	return err;
-}
-
-static int bcm2048_set_mute(struct bcm2048_device *bdev, u16 mute)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	bdev->cache_fm_audio_ctrl0 &= ~(BCM2048_RF_MUTE | BCM2048_MANUAL_MUTE);
-
-	if (mute)
-		bdev->cache_fm_audio_ctrl0 |= (BCM2048_RF_MUTE |
-					       BCM2048_MANUAL_MUTE);
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
-				   bdev->cache_fm_audio_ctrl0);
-
-	if (!err)
-		bdev->mute_state = mute;
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_mute(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	if (bdev->power_state) {
-		err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
-					   &value);
-		if (!err)
-			err = value & (BCM2048_RF_MUTE | BCM2048_MANUAL_MUTE);
-	} else {
-		err = bdev->mute_state;
-	}
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_set_audio_route(struct bcm2048_device *bdev, u8 route)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	route &= (BCM2048_AUDIO_ROUTE_DAC | BCM2048_AUDIO_ROUTE_I2S);
-	bdev->cache_fm_audio_ctrl0 &= ~(BCM2048_AUDIO_ROUTE_DAC |
-					BCM2048_AUDIO_ROUTE_I2S);
-	bdev->cache_fm_audio_ctrl0 |= route;
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
-				   bdev->cache_fm_audio_ctrl0);
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_audio_route(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, &value);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return value & (BCM2048_AUDIO_ROUTE_DAC |
-				BCM2048_AUDIO_ROUTE_I2S);
-
-	return err;
-}
-
-static int bcm2048_set_dac_output(struct bcm2048_device *bdev, u8 channels)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	bdev->cache_fm_audio_ctrl0 &= ~(BCM2048_DAC_OUTPUT_LEFT |
-					BCM2048_DAC_OUTPUT_RIGHT);
-	bdev->cache_fm_audio_ctrl0 |= channels;
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0,
-				   bdev->cache_fm_audio_ctrl0);
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_dac_output(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_AUDIO_CTRL0, &value);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return value & (BCM2048_DAC_OUTPUT_LEFT |
-				BCM2048_DAC_OUTPUT_RIGHT);
-
-	return err;
-}
-
-static int bcm2048_set_fm_search_rssi_threshold(struct bcm2048_device *bdev,
-						u8 threshold)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	threshold &= BCM2048_SEARCH_RSSI_THRESHOLD;
-	bdev->cache_fm_search_ctrl0 &= ~BCM2048_SEARCH_RSSI_THRESHOLD;
-	bdev->cache_fm_search_ctrl0 |= threshold;
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0,
-				   bdev->cache_fm_search_ctrl0);
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_fm_search_rssi_threshold(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0, &value);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return value & BCM2048_SEARCH_RSSI_THRESHOLD;
-
-	return err;
-}
-
-static int bcm2048_set_fm_search_mode_direction(struct bcm2048_device *bdev,
-						u8 direction)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	bdev->cache_fm_search_ctrl0 &= ~BCM2048_SEARCH_DIRECTION;
-
-	if (direction)
-		bdev->cache_fm_search_ctrl0 |= BCM2048_SEARCH_DIRECTION;
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0,
-				   bdev->cache_fm_search_ctrl0);
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_fm_search_mode_direction(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_SEARCH_CTRL0, &value);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err && (value & BCM2048_SEARCH_DIRECTION))
-		return BCM2048_SEARCH_DIRECTION_UP;
-
-	return err;
-}
-
-static int bcm2048_set_fm_search_tune_mode(struct bcm2048_device *bdev,
-					   u8 mode)
-{
-	int err, timeout, restart_rds = 0;
-	u8 value, flags;
-
-	value = mode & BCM2048_FM_AUTO_SEARCH;
-
-	flags =	BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED |
-		BCM2048_FM_FLAG_SEARCH_TUNE_FAIL;
-
-	mutex_lock(&bdev->mutex);
-
-	/*
-	 * If RDS is enabled, and frequency is changed, RDS quits working.
-	 * Thus, always restart RDS if it's enabled. Moreover, RDS must
-	 * not be enabled while changing the frequency because it can
-	 * provide a race to the mutex from the workqueue handler if RDS
-	 * IRQ occurs while waiting for frequency changed IRQ.
-	 */
-	if (bcm2048_get_rds_no_lock(bdev)) {
-		err = bcm2048_set_rds_no_lock(bdev, 0);
-		if (err)
-			goto unlock;
-		restart_rds = 1;
-	}
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK0, flags);
-
-	if (err)
-		goto unlock;
-
-	bcm2048_send_command(bdev, BCM2048_I2C_FM_SEARCH_TUNE_MODE, value);
-
-	if (mode != BCM2048_FM_AUTO_SEARCH_MODE)
-		timeout = BCM2048_DEFAULT_TIMEOUT;
-	else
-		timeout = BCM2048_AUTO_SEARCH_TIMEOUT;
-
-	if (!wait_for_completion_timeout(&bdev->compl,
-					 msecs_to_jiffies(timeout)))
-		dev_err(&bdev->client->dev, "IRQ timeout.\n");
-
-	if (value)
-		if (!bdev->scan_state)
-			err = -EIO;
-
-unlock:
-	if (restart_rds)
-		err |= bcm2048_set_rds_no_lock(bdev, 1);
-
-	mutex_unlock(&bdev->mutex);
-
-	return err;
-}
-
-static int bcm2048_get_fm_search_tune_mode(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_SEARCH_TUNE_MODE,
-				   &value);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return value & BCM2048_FM_AUTO_SEARCH;
-
-	return err;
-}
-
-static int bcm2048_set_rds_b_block_mask(struct bcm2048_device *bdev, u16 mask)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MASK0,
-				   lsb(mask));
-	err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MASK1,
-				    msb(mask));
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_rds_b_block_mask(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 lsb = 0, msb = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MASK0, &lsb);
-	err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MASK1, &msb);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return compose_u16(msb, lsb);
-
-	return err;
-}
-
-static int bcm2048_set_rds_b_block_match(struct bcm2048_device *bdev,
-					 u16 match)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH0,
-				   lsb(match));
-	err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH1,
-				    msb(match));
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_rds_b_block_match(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 lsb = 0, msb = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH0, &lsb);
-	err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_BLKB_MATCH1, &msb);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return compose_u16(msb, lsb);
-
-	return err;
-}
-
-static int bcm2048_set_rds_pi_mask(struct bcm2048_device *bdev, u16 mask)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MASK0, lsb(mask));
-	err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MASK1, msb(mask));
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_rds_pi_mask(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 lsb = 0, msb = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MASK0, &lsb);
-	err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MASK1, &msb);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return compose_u16(msb, lsb);
-
-	return err;
-}
-
-static int bcm2048_set_rds_pi_match(struct bcm2048_device *bdev, u16 match)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MATCH0,
-				   lsb(match));
-	err |= bcm2048_send_command(bdev, BCM2048_I2C_RDS_PI_MATCH1,
-				    msb(match));
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_rds_pi_match(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 lsb = 0, msb = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MATCH0, &lsb);
-	err |= bcm2048_recv_command(bdev, BCM2048_I2C_RDS_PI_MATCH1, &msb);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return compose_u16(msb, lsb);
-
-	return err;
-}
-
-static int bcm2048_set_fm_rds_mask(struct bcm2048_device *bdev, u16 mask)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK0, lsb(mask));
-	err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1, msb(mask));
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_fm_rds_mask(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value0 = 0, value1 = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_MASK0, &value0);
-	err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_MASK1, &value1);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return compose_u16(value1, value0);
-
-	return err;
-}
-
-static int bcm2048_get_fm_rds_flags(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value0 = 0, value1 = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG0, &value0);
-	err |= bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG1, &value1);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return compose_u16(value1, value0);
-
-	return err;
-}
-
-static int bcm2048_get_region_bottom_frequency(struct bcm2048_device *bdev)
-{
-	return bdev->region_info.bottom_frequency;
-}
-
-static int bcm2048_get_region_top_frequency(struct bcm2048_device *bdev)
-{
-	return bdev->region_info.top_frequency;
-}
-
-static int bcm2048_set_fm_best_tune_mode(struct bcm2048_device *bdev, u8 mode)
-{
-	int err;
-	u8 value = 0;
-
-	mutex_lock(&bdev->mutex);
-
-	/* Perform read as the manual indicates */
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE,
-				   &value);
-	value &= ~BCM2048_BEST_TUNE_MODE;
-
-	if (mode)
-		value |= BCM2048_BEST_TUNE_MODE;
-	err |= bcm2048_send_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE,
-				    value);
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_fm_best_tune_mode(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_BEST_TUNE_MODE,
-				   &value);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err && (value & BCM2048_BEST_TUNE_MODE))
-		return BCM2048_ITEM_ENABLED;
-
-	return err;
-}
-
-static int bcm2048_get_fm_carrier_error(struct bcm2048_device *bdev)
-{
-	int err = 0;
-	s8 value;
-
-	mutex_lock(&bdev->mutex);
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_CARRIER, &value);
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return value;
-
-	return err;
-}
-
-static int bcm2048_get_fm_rssi(struct bcm2048_device *bdev)
-{
-	int err;
-	s8 value;
-
-	mutex_lock(&bdev->mutex);
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RSSI, &value);
-	mutex_unlock(&bdev->mutex);
-
-	if (!err)
-		return value;
-
-	return err;
-}
-
-static int bcm2048_set_rds_wline(struct bcm2048_device *bdev, u8 wline)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_send_command(bdev, BCM2048_I2C_RDS_WLINE, wline);
-
-	if (!err)
-		bdev->fifo_size = wline;
-
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_rds_wline(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 value;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_RDS_WLINE, &value);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err) {
-		bdev->fifo_size = value;
-		return value;
-	}
-
-	return err;
-}
-
-static int bcm2048_checkrev(struct bcm2048_device *bdev)
-{
-	int err;
-	u8 version;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_REV, &version);
-
-	mutex_unlock(&bdev->mutex);
-
-	if (!err) {
-		dev_info(&bdev->client->dev, "BCM2048 Version 0x%x\n",
-			 version);
-		return version;
-	}
-
-	return err;
-}
-
-static int bcm2048_get_rds_rt(struct bcm2048_device *bdev, char *data)
-{
-	int err = 0, i, j = 0, ce = 0, cr = 0;
-	char data_buffer[BCM2048_MAX_RDS_RT + 1];
-
-	mutex_lock(&bdev->mutex);
-
-	if (!bdev->rds_info.text_len) {
-		err = -EINVAL;
-		goto unlock;
-	}
-
-	for (i = 0; i < BCM2048_MAX_RDS_RT; i++) {
-		if (bdev->rds_info.rds_rt[i]) {
-			ce = i;
-			/* Skip the carriage return */
-			if (bdev->rds_info.rds_rt[i] != 0x0d) {
-				data_buffer[j++] = bdev->rds_info.rds_rt[i];
-			} else {
-				cr = i;
-				break;
-			}
-		}
-	}
-
-	if (j <= BCM2048_MAX_RDS_RT)
-		data_buffer[j] = 0;
-
-	for (i = 0; i < BCM2048_MAX_RDS_RT; i++) {
-		if (!bdev->rds_info.rds_rt[i]) {
-			if (cr && (i < cr)) {
-				err = -EBUSY;
-				goto unlock;
-			}
-			if (i < ce) {
-				if (cr && (i >= cr))
-					break;
-				err = -EBUSY;
-				goto unlock;
-			}
-		}
-	}
-
-	memcpy(data, data_buffer, sizeof(data_buffer));
-
-unlock:
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static int bcm2048_get_rds_ps(struct bcm2048_device *bdev, char *data)
-{
-	int err = 0, i, j = 0;
-	char data_buffer[BCM2048_MAX_RDS_PS + 1];
-
-	mutex_lock(&bdev->mutex);
-
-	if (!bdev->rds_info.text_len) {
-		err = -EINVAL;
-		goto unlock;
-	}
-
-	for (i = 0; i < BCM2048_MAX_RDS_PS; i++) {
-		if (bdev->rds_info.rds_ps[i]) {
-			data_buffer[j++] = bdev->rds_info.rds_ps[i];
-		} else {
-			if (i < (BCM2048_MAX_RDS_PS - 1)) {
-				err = -EBUSY;
-				goto unlock;
-			}
-		}
-	}
-
-	if (j <= BCM2048_MAX_RDS_PS)
-		data_buffer[j] = 0;
-
-	memcpy(data, data_buffer, sizeof(data_buffer));
-
-unlock:
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-static void bcm2048_parse_rds_pi(struct bcm2048_device *bdev)
-{
-	int i, cnt = 0;
-	u16 pi;
-
-	for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) {
-		/* Block A match, only data without crc errors taken */
-		if (bdev->rds_info.radio_text[i] == BCM2048_RDS_BLOCK_A) {
-			pi = (bdev->rds_info.radio_text[i + 1] << 8) +
-				bdev->rds_info.radio_text[i + 2];
-
-			if (!bdev->rds_info.rds_pi) {
-				bdev->rds_info.rds_pi = pi;
-				return;
-			}
-			if (pi != bdev->rds_info.rds_pi) {
-				cnt++;
-				if (cnt > 3) {
-					bdev->rds_info.rds_pi = pi;
-					cnt = 0;
-				}
-			} else {
-				cnt = 0;
-			}
-		}
-	}
-}
-
-static int bcm2048_rds_block_crc(struct bcm2048_device *bdev, int i)
-{
-	return bdev->rds_info.radio_text[i] & BCM2048_RDS_CRC_MASK;
-}
-
-static void bcm2048_parse_rds_rt_block(struct bcm2048_device *bdev, int i,
-				       int index, int crc)
-{
-	/* Good data will overwrite poor data */
-	if (crc) {
-		if (!bdev->rds_info.rds_rt[index])
-			bdev->rds_info.rds_rt[index] =
-				bdev->rds_info.radio_text[i + 1];
-		if (!bdev->rds_info.rds_rt[index + 1])
-			bdev->rds_info.rds_rt[index + 1] =
-				bdev->rds_info.radio_text[i + 2];
-	} else {
-		bdev->rds_info.rds_rt[index] =
-			bdev->rds_info.radio_text[i + 1];
-		bdev->rds_info.rds_rt[index + 1] =
-			bdev->rds_info.radio_text[i + 2];
-	}
-}
-
-static int bcm2048_parse_rt_match_b(struct bcm2048_device *bdev, int i)
-{
-	int crc, rt_id, rt_group_b, rt_ab, index = 0;
-
-	crc = bcm2048_rds_block_crc(bdev, i);
-
-	if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
-		return -EIO;
-
-	if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
-	    BCM2048_RDS_BLOCK_B) {
-		rt_id = bdev->rds_info.radio_text[i + 1] &
-			BCM2048_RDS_BLOCK_MASK;
-		rt_group_b = bdev->rds_info.radio_text[i + 1] &
-			BCM2048_RDS_GROUP_AB_MASK;
-		rt_ab = bdev->rds_info.radio_text[i + 2] &
-				BCM2048_RDS_RT_AB_MASK;
-
-		if (rt_group_b != bdev->rds_info.rds_rt_group_b) {
-			memset(bdev->rds_info.rds_rt, 0,
-			       sizeof(bdev->rds_info.rds_rt));
-			bdev->rds_info.rds_rt_group_b = rt_group_b;
-		}
-
-		if (rt_id == BCM2048_RDS_RT) {
-			/* A to B or (vice versa), means: clear screen */
-			if (rt_ab != bdev->rds_info.rds_rt_ab) {
-				memset(bdev->rds_info.rds_rt, 0,
-				       sizeof(bdev->rds_info.rds_rt));
-				bdev->rds_info.rds_rt_ab = rt_ab;
-			}
-
-			index = bdev->rds_info.radio_text[i + 2] &
-					BCM2048_RDS_RT_INDEX;
-
-			if (bdev->rds_info.rds_rt_group_b)
-				index <<= 1;
-			else
-				index <<= 2;
-
-			return index;
-		}
-	}
-
-	return -EIO;
-}
-
-static int bcm2048_parse_rt_match_c(struct bcm2048_device *bdev, int i,
-				    int index)
-{
-	int crc;
-
-	crc = bcm2048_rds_block_crc(bdev, i);
-
-	if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
-		return 0;
-
-	if ((index + 2) >= BCM2048_MAX_RDS_RT) {
-		dev_err(&bdev->client->dev,
-			"Incorrect index = %d\n", index);
-		return 0;
-	}
-
-	if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
-		BCM2048_RDS_BLOCK_C) {
-		if (bdev->rds_info.rds_rt_group_b)
-			return 1;
-		bcm2048_parse_rds_rt_block(bdev, i, index, crc);
-		return 1;
-	}
-
-	return 0;
-}
-
-static void bcm2048_parse_rt_match_d(struct bcm2048_device *bdev, int i,
-				     int index)
-{
-	int crc;
-
-	crc = bcm2048_rds_block_crc(bdev, i);
-
-	if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
-		return;
-
-	if ((index + 4) >= BCM2048_MAX_RDS_RT) {
-		dev_err(&bdev->client->dev,
-			"Incorrect index = %d\n", index);
-		return;
-	}
-
-	if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
-	    BCM2048_RDS_BLOCK_D)
-		bcm2048_parse_rds_rt_block(bdev, i, index + 2, crc);
-}
-
-static void bcm2048_parse_rds_rt(struct bcm2048_device *bdev)
-{
-	int i, index = 0, crc, match_b = 0, match_c = 0, match_d = 0;
-
-	for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) {
-		if (match_b) {
-			match_b = 0;
-			index = bcm2048_parse_rt_match_b(bdev, i);
-			if (index >= 0 && index <= (BCM2048_MAX_RDS_RT - 5))
-				match_c = 1;
-			continue;
-		} else if (match_c) {
-			match_c = 0;
-			if (bcm2048_parse_rt_match_c(bdev, i, index))
-				match_d = 1;
-			continue;
-		} else if (match_d) {
-			match_d = 0;
-			bcm2048_parse_rt_match_d(bdev, i, index);
-			continue;
-		}
-
-		/* Skip erroneous blocks due to messed up A block altogether */
-		if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
-		    BCM2048_RDS_BLOCK_A) {
-			crc = bcm2048_rds_block_crc(bdev, i);
-			if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
-				continue;
-			/* Synchronize to a good RDS PI */
-			if (((bdev->rds_info.radio_text[i + 1] << 8) +
-			    bdev->rds_info.radio_text[i + 2]) ==
-			    bdev->rds_info.rds_pi)
-				match_b = 1;
-		}
-	}
-}
-
-static void bcm2048_parse_rds_ps_block(struct bcm2048_device *bdev, int i,
-				       int index, int crc)
-{
-	/* Good data will overwrite poor data */
-	if (crc) {
-		if (!bdev->rds_info.rds_ps[index])
-			bdev->rds_info.rds_ps[index] =
-				bdev->rds_info.radio_text[i + 1];
-		if (!bdev->rds_info.rds_ps[index + 1])
-			bdev->rds_info.rds_ps[index + 1] =
-				bdev->rds_info.radio_text[i + 2];
-	} else {
-		bdev->rds_info.rds_ps[index] =
-			bdev->rds_info.radio_text[i + 1];
-		bdev->rds_info.rds_ps[index + 1] =
-			bdev->rds_info.radio_text[i + 2];
-	}
-}
-
-static int bcm2048_parse_ps_match_c(struct bcm2048_device *bdev, int i,
-				    int index)
-{
-	int crc;
-
-	crc = bcm2048_rds_block_crc(bdev, i);
-
-	if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
-		return 0;
-
-	if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
-	    BCM2048_RDS_BLOCK_C)
-		return 1;
-
-	return 0;
-}
-
-static void bcm2048_parse_ps_match_d(struct bcm2048_device *bdev, int i,
-				     int index)
-{
-	int crc;
-
-	crc = bcm2048_rds_block_crc(bdev, i);
-
-	if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
-		return;
-
-	if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
-	    BCM2048_RDS_BLOCK_D)
-		bcm2048_parse_rds_ps_block(bdev, i, index, crc);
-}
-
-static int bcm2048_parse_ps_match_b(struct bcm2048_device *bdev, int i)
-{
-	int crc, index, ps_id, ps_group;
-
-	crc = bcm2048_rds_block_crc(bdev, i);
-
-	if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
-		return -EIO;
-
-	/* Block B Radio PS match */
-	if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
-	    BCM2048_RDS_BLOCK_B) {
-		ps_id = bdev->rds_info.radio_text[i + 1] &
-			BCM2048_RDS_BLOCK_MASK;
-		ps_group = bdev->rds_info.radio_text[i + 1] &
-			BCM2048_RDS_GROUP_AB_MASK;
-
-		/*
-		 * Poor RSSI will lead to RDS data corruption
-		 * So using 3 (same) sequential values to justify major changes
-		 */
-		if (ps_group != bdev->rds_info.rds_ps_group) {
-			if (crc == BCM2048_RDS_CRC_NONE) {
-				bdev->rds_info.rds_ps_group_cnt++;
-				if (bdev->rds_info.rds_ps_group_cnt > 2) {
-					bdev->rds_info.rds_ps_group = ps_group;
-					bdev->rds_info.rds_ps_group_cnt	= 0;
-					dev_err(&bdev->client->dev,
-						"RDS PS Group change!\n");
-				} else {
-					return -EIO;
-				}
-			} else {
-				bdev->rds_info.rds_ps_group_cnt = 0;
-			}
-		}
-
-		if (ps_id == BCM2048_RDS_PS) {
-			index = bdev->rds_info.radio_text[i + 2] &
-				BCM2048_RDS_PS_INDEX;
-			index <<= 1;
-			return index;
-		}
-	}
-
-	return -EIO;
-}
-
-static void bcm2048_parse_rds_ps(struct bcm2048_device *bdev)
-{
-	int i, index = 0, crc, match_b = 0, match_c = 0, match_d = 0;
-
-	for (i = 0; i < bdev->fifo_size; i += BCM2048_RDS_FIFO_DUPLE_SIZE) {
-		if (match_b) {
-			match_b = 0;
-			index = bcm2048_parse_ps_match_b(bdev, i);
-			if (index >= 0 && index < (BCM2048_MAX_RDS_PS - 1))
-				match_c = 1;
-			continue;
-		} else if (match_c) {
-			match_c = 0;
-			if (bcm2048_parse_ps_match_c(bdev, i, index))
-				match_d = 1;
-			continue;
-		} else if (match_d) {
-			match_d = 0;
-			bcm2048_parse_ps_match_d(bdev, i, index);
-			continue;
-		}
-
-		/* Skip erroneous blocks due to messed up A block altogether */
-		if ((bdev->rds_info.radio_text[i] & BCM2048_RDS_BLOCK_MASK) ==
-		    BCM2048_RDS_BLOCK_A) {
-			crc = bcm2048_rds_block_crc(bdev, i);
-			if (crc == BCM2048_RDS_CRC_UNRECOVARABLE)
-				continue;
-			/* Synchronize to a good RDS PI */
-			if (((bdev->rds_info.radio_text[i + 1] << 8) +
-			    bdev->rds_info.radio_text[i + 2]) ==
-			    bdev->rds_info.rds_pi)
-				match_b = 1;
-		}
-	}
-}
-
-static void bcm2048_rds_fifo_receive(struct bcm2048_device *bdev)
-{
-	int err;
-
-	mutex_lock(&bdev->mutex);
-
-	err = bcm2048_recv_duples(bdev, BCM2048_I2C_RDS_DATA,
-				  bdev->rds_info.radio_text, bdev->fifo_size);
-	if (err != 2) {
-		dev_err(&bdev->client->dev, "RDS Read problem\n");
-		mutex_unlock(&bdev->mutex);
-		return;
-	}
-
-	bdev->rds_info.text_len = bdev->fifo_size;
-
-	bcm2048_parse_rds_pi(bdev);
-	bcm2048_parse_rds_rt(bdev);
-	bcm2048_parse_rds_ps(bdev);
-
-	mutex_unlock(&bdev->mutex);
-
-	wake_up_interruptible(&bdev->read_queue);
-}
-
-static int bcm2048_get_rds_data(struct bcm2048_device *bdev, char *data)
-{
-	int err = 0, i, p = 0;
-	char *data_buffer;
-
-	mutex_lock(&bdev->mutex);
-
-	if (!bdev->rds_info.text_len) {
-		err = -EINVAL;
-		goto unlock;
-	}
-
-	data_buffer = kcalloc(BCM2048_MAX_RDS_RADIO_TEXT, 5, GFP_KERNEL);
-	if (!data_buffer) {
-		err = -ENOMEM;
-		goto unlock;
-	}
-
-	for (i = 0; i < bdev->rds_info.text_len; i++) {
-		p += sprintf(data_buffer + p, "%x ",
-			     bdev->rds_info.radio_text[i]);
-	}
-
-	memcpy(data, data_buffer, p);
-	kfree(data_buffer);
-
-unlock:
-	mutex_unlock(&bdev->mutex);
-	return err;
-}
-
-/*
- *	BCM2048 default initialization sequence
- */
-static int bcm2048_init(struct bcm2048_device *bdev)
-{
-	int err;
-
-	err = bcm2048_set_power_state(bdev, BCM2048_POWER_ON);
-	if (err < 0)
-		goto exit;
-
-	err = bcm2048_set_audio_route(bdev, BCM2048_AUDIO_ROUTE_DAC);
-	if (err < 0)
-		goto exit;
-
-	err = bcm2048_set_dac_output(bdev, BCM2048_DAC_OUTPUT_LEFT |
-				     BCM2048_DAC_OUTPUT_RIGHT);
-
-exit:
-	return err;
-}
-
-/*
- *	BCM2048 default deinitialization sequence
- */
-static int bcm2048_deinit(struct bcm2048_device *bdev)
-{
-	int err;
-
-	err = bcm2048_set_audio_route(bdev, 0);
-	if (err < 0)
-		return err;
-
-	err = bcm2048_set_dac_output(bdev, 0);
-	if (err < 0)
-		return err;
-
-	return bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
-}
-
-/*
- *	BCM2048 probe sequence
- */
-static int bcm2048_probe(struct bcm2048_device *bdev)
-{
-	int err;
-
-	err = bcm2048_set_power_state(bdev, BCM2048_POWER_ON);
-	if (err < 0)
-		goto unlock;
-
-	err = bcm2048_checkrev(bdev);
-	if (err < 0)
-		goto unlock;
-
-	err = bcm2048_set_mute(bdev, BCM2048_DEFAULT_MUTE);
-	if (err < 0)
-		goto unlock;
-
-	err = bcm2048_set_region(bdev, BCM2048_DEFAULT_REGION);
-	if (err < 0)
-		goto unlock;
-
-	err = bcm2048_set_fm_search_rssi_threshold(bdev,
-					BCM2048_DEFAULT_RSSI_THRESHOLD);
-	if (err < 0)
-		goto unlock;
-
-	err = bcm2048_set_fm_automatic_stereo_mono(bdev, BCM2048_ITEM_ENABLED);
-	if (err < 0)
-		goto unlock;
-
-	err = bcm2048_get_rds_wline(bdev);
-	if (err < BCM2048_DEFAULT_RDS_WLINE)
-		err = bcm2048_set_rds_wline(bdev, BCM2048_DEFAULT_RDS_WLINE);
-	if (err < 0)
-		goto unlock;
-
-	err = bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
-
-	init_waitqueue_head(&bdev->read_queue);
-	bdev->rds_data_available = 0;
-	bdev->rd_index = 0;
-	bdev->users = 0;
-
-unlock:
-	return err;
-}
-
-/*
- *	BCM2048 workqueue handler
- */
-static void bcm2048_work(struct work_struct *work)
-{
-	struct bcm2048_device *bdev;
-	u8 flag_lsb = 0, flag_msb = 0, flags;
-
-	bdev = container_of(work, struct bcm2048_device, work);
-	bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG0, &flag_lsb);
-	bcm2048_recv_command(bdev, BCM2048_I2C_FM_RDS_FLAG1, &flag_msb);
-
-	if (flag_lsb & (BCM2048_FM_FLAG_SEARCH_TUNE_FINISHED |
-			BCM2048_FM_FLAG_SEARCH_TUNE_FAIL)) {
-		if (flag_lsb & BCM2048_FM_FLAG_SEARCH_TUNE_FAIL)
-			bdev->scan_state = BCM2048_SCAN_FAIL;
-		else
-			bdev->scan_state = BCM2048_SCAN_OK;
-
-		complete(&bdev->compl);
-	}
-
-	if (flag_msb & BCM2048_RDS_FLAG_FIFO_WLINE) {
-		bcm2048_rds_fifo_receive(bdev);
-		if (bdev->rds_state) {
-			flags =	BCM2048_RDS_FLAG_FIFO_WLINE;
-			bcm2048_send_command(bdev, BCM2048_I2C_FM_RDS_MASK1,
-					     flags);
-		}
-		bdev->rds_data_available = 1;
-		bdev->rd_index = 0; /* new data, new start */
-	}
-}
-
-/*
- *	BCM2048 interrupt handler
- */
-static irqreturn_t bcm2048_handler(int irq, void *dev)
-{
-	struct bcm2048_device *bdev = dev;
-
-	dev_dbg(&bdev->client->dev, "IRQ called, queuing work\n");
-	if (bdev->power_state)
-		schedule_work(&bdev->work);
-
-	return IRQ_HANDLED;
-}
-
-/*
- *	BCM2048 sysfs interface definitions
- */
-#define property_write(prop, type, mask, check)				\
-static ssize_t bcm2048_##prop##_write(struct device *dev,		\
-					struct device_attribute *attr,	\
-					const char *buf,		\
-					size_t count)			\
-{									\
-	struct bcm2048_device *bdev = dev_get_drvdata(dev);		\
-	type value;							\
-	int err;							\
-									\
-	if (!bdev)							\
-		return -ENODEV;						\
-									\
-	if (sscanf(buf, mask, &value) != 1)				\
-		return -EINVAL;						\
-									\
-	if (check)							\
-		return -EDOM;						\
-									\
-	err = bcm2048_set_##prop(bdev, value);				\
-									\
-	return err < 0 ? err : count;					\
-}
-
-#define property_read(prop, mask)					\
-static ssize_t bcm2048_##prop##_read(struct device *dev,		\
-					struct device_attribute *attr,	\
-					char *buf)			\
-{									\
-	struct bcm2048_device *bdev = dev_get_drvdata(dev);		\
-	int value;							\
-									\
-	if (!bdev)							\
-		return -ENODEV;						\
-									\
-	value = bcm2048_get_##prop(bdev);				\
-									\
-	if (value >= 0)							\
-		value = sprintf(buf, mask "\n", value);			\
-									\
-	return value;							\
-}
-
-#define property_signed_read(prop, size, mask)				\
-static ssize_t bcm2048_##prop##_read(struct device *dev,		\
-					struct device_attribute *attr,	\
-					char *buf)			\
-{									\
-	struct bcm2048_device *bdev = dev_get_drvdata(dev);		\
-	size value;							\
-									\
-	if (!bdev)							\
-		return -ENODEV;						\
-									\
-	value = bcm2048_get_##prop(bdev);				\
-									\
-	return sprintf(buf, mask "\n", value);				\
-}
-
-#define DEFINE_SYSFS_PROPERTY(prop, prop_type, mask, check)		\
-property_write(prop, prop_type, mask, check)				\
-property_read(prop, mask)						\
-
-#define property_str_read(prop, size)					\
-static ssize_t bcm2048_##prop##_read(struct device *dev,		\
-					struct device_attribute *attr,	\
-					char *buf)			\
-{									\
-	struct bcm2048_device *bdev = dev_get_drvdata(dev);		\
-	int count;							\
-	u8 *out;							\
-									\
-	if (!bdev)							\
-		return -ENODEV;						\
-									\
-	out = kzalloc((size) + 1, GFP_KERNEL);				\
-	if (!out)							\
-		return -ENOMEM;						\
-									\
-	bcm2048_get_##prop(bdev, out);					\
-	count = sprintf(buf, "%s\n", out);				\
-									\
-	kfree(out);							\
-									\
-	return count;							\
-}
-
-DEFINE_SYSFS_PROPERTY(power_state, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(mute, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(audio_route, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(dac_output, unsigned int, "%u", 0)
-
-DEFINE_SYSFS_PROPERTY(fm_hi_lo_injection, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(fm_frequency, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(fm_af_frequency, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(fm_deemphasis, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(fm_rds_mask, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(fm_best_tune_mode, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(fm_search_rssi_threshold, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(fm_search_mode_direction, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(fm_search_tune_mode, unsigned int, "%u", value > 3)
-
-DEFINE_SYSFS_PROPERTY(rds, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(rds_b_block_mask, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(rds_b_block_match, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(rds_pi_mask, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(rds_pi_match, unsigned int, "%u", 0)
-DEFINE_SYSFS_PROPERTY(rds_wline, unsigned int, "%u", 0)
-property_read(rds_pi, "%x")
-property_str_read(rds_rt, (BCM2048_MAX_RDS_RT + 1))
-property_str_read(rds_ps, (BCM2048_MAX_RDS_PS + 1))
-
-property_read(fm_rds_flags, "%u")
-property_str_read(rds_data, BCM2048_MAX_RDS_RADIO_TEXT * 5)
-
-property_read(region_bottom_frequency, "%u")
-property_read(region_top_frequency, "%u")
-property_signed_read(fm_carrier_error, int, "%d")
-property_signed_read(fm_rssi, int, "%d")
-DEFINE_SYSFS_PROPERTY(region, unsigned int, "%u", 0)
-
-static struct device_attribute attrs[] = {
-	__ATTR(power_state, 0644, bcm2048_power_state_read,
-	       bcm2048_power_state_write),
-	__ATTR(mute, 0644, bcm2048_mute_read,
-	       bcm2048_mute_write),
-	__ATTR(audio_route, 0644, bcm2048_audio_route_read,
-	       bcm2048_audio_route_write),
-	__ATTR(dac_output, 0644, bcm2048_dac_output_read,
-	       bcm2048_dac_output_write),
-	__ATTR(fm_hi_lo_injection, 0644,
-	       bcm2048_fm_hi_lo_injection_read,
-	       bcm2048_fm_hi_lo_injection_write),
-	__ATTR(fm_frequency, 0644, bcm2048_fm_frequency_read,
-	       bcm2048_fm_frequency_write),
-	__ATTR(fm_af_frequency, 0644,
-	       bcm2048_fm_af_frequency_read,
-	       bcm2048_fm_af_frequency_write),
-	__ATTR(fm_deemphasis, 0644, bcm2048_fm_deemphasis_read,
-	       bcm2048_fm_deemphasis_write),
-	__ATTR(fm_rds_mask, 0644, bcm2048_fm_rds_mask_read,
-	       bcm2048_fm_rds_mask_write),
-	__ATTR(fm_best_tune_mode, 0644,
-	       bcm2048_fm_best_tune_mode_read,
-	       bcm2048_fm_best_tune_mode_write),
-	__ATTR(fm_search_rssi_threshold, 0644,
-	       bcm2048_fm_search_rssi_threshold_read,
-	       bcm2048_fm_search_rssi_threshold_write),
-	__ATTR(fm_search_mode_direction, 0644,
-	       bcm2048_fm_search_mode_direction_read,
-	       bcm2048_fm_search_mode_direction_write),
-	__ATTR(fm_search_tune_mode, 0644,
-	       bcm2048_fm_search_tune_mode_read,
-	       bcm2048_fm_search_tune_mode_write),
-	__ATTR(rds, 0644, bcm2048_rds_read,
-	       bcm2048_rds_write),
-	__ATTR(rds_b_block_mask, 0644,
-	       bcm2048_rds_b_block_mask_read,
-	       bcm2048_rds_b_block_mask_write),
-	__ATTR(rds_b_block_match, 0644,
-	       bcm2048_rds_b_block_match_read,
-	       bcm2048_rds_b_block_match_write),
-	__ATTR(rds_pi_mask, 0644, bcm2048_rds_pi_mask_read,
-	       bcm2048_rds_pi_mask_write),
-	__ATTR(rds_pi_match, 0644, bcm2048_rds_pi_match_read,
-	       bcm2048_rds_pi_match_write),
-	__ATTR(rds_wline, 0644, bcm2048_rds_wline_read,
-	       bcm2048_rds_wline_write),
-	__ATTR(rds_pi, 0444, bcm2048_rds_pi_read, NULL),
-	__ATTR(rds_rt, 0444, bcm2048_rds_rt_read, NULL),
-	__ATTR(rds_ps, 0444, bcm2048_rds_ps_read, NULL),
-	__ATTR(fm_rds_flags, 0444, bcm2048_fm_rds_flags_read, NULL),
-	__ATTR(region_bottom_frequency, 0444,
-	       bcm2048_region_bottom_frequency_read, NULL),
-	__ATTR(region_top_frequency, 0444,
-	       bcm2048_region_top_frequency_read, NULL),
-	__ATTR(fm_carrier_error, 0444,
-	       bcm2048_fm_carrier_error_read, NULL),
-	__ATTR(fm_rssi, 0444,
-	       bcm2048_fm_rssi_read, NULL),
-	__ATTR(region, 0644, bcm2048_region_read,
-	       bcm2048_region_write),
-	__ATTR(rds_data, 0444, bcm2048_rds_data_read, NULL),
-};
-
-static int bcm2048_sysfs_unregister_properties(struct bcm2048_device *bdev,
-					       int size)
-{
-	int i;
-
-	for (i = 0; i < size; i++)
-		device_remove_file(&bdev->client->dev, &attrs[i]);
-
-	return 0;
-}
-
-static int bcm2048_sysfs_register_properties(struct bcm2048_device *bdev)
-{
-	int err = 0;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(attrs); i++) {
-		if (device_create_file(&bdev->client->dev, &attrs[i]) != 0) {
-			dev_err(&bdev->client->dev,
-				"could not register sysfs entry\n");
-			err = -EBUSY;
-			bcm2048_sysfs_unregister_properties(bdev, i);
-			break;
-		}
-	}
-
-	return err;
-}
-
-static int bcm2048_fops_open(struct file *file)
-{
-	struct bcm2048_device *bdev = video_drvdata(file);
-
-	bdev->users++;
-	bdev->rd_index = 0;
-	bdev->rds_data_available = 0;
-
-	return 0;
-}
-
-static int bcm2048_fops_release(struct file *file)
-{
-	struct bcm2048_device *bdev = video_drvdata(file);
-
-	bdev->users--;
-
-	return 0;
-}
-
-static __poll_t bcm2048_fops_poll(struct file *file,
-				  struct poll_table_struct *pts)
-{
-	struct bcm2048_device *bdev = video_drvdata(file);
-	__poll_t retval = 0;
-
-	poll_wait(file, &bdev->read_queue, pts);
-
-	if (bdev->rds_data_available)
-		retval = EPOLLIN | EPOLLRDNORM;
-
-	return retval;
-}
-
-static ssize_t bcm2048_fops_read(struct file *file, char __user *buf,
-				 size_t count, loff_t *ppos)
-{
-	struct bcm2048_device *bdev = video_drvdata(file);
-	int i;
-	int retval = 0;
-
-	/* we return at least 3 bytes, one block */
-	count = (count / 3) * 3; /* only multiples of 3 */
-	if (count < 3)
-		return -ENOBUFS;
-
-	while (!bdev->rds_data_available) {
-		if (file->f_flags & O_NONBLOCK) {
-			retval = -EWOULDBLOCK;
-			goto done;
-		}
-		/* interruptible_sleep_on(&bdev->read_queue); */
-		if (wait_event_interruptible(bdev->read_queue,
-					     bdev->rds_data_available) < 0) {
-			retval = -EINTR;
-			goto done;
-		}
-	}
-
-	mutex_lock(&bdev->mutex);
-	/* copy data to userspace */
-	i = bdev->fifo_size - bdev->rd_index;
-	if (count > i)
-		count = (i / 3) * 3;
-
-	i = 0;
-	while (i < count) {
-		unsigned char tmpbuf[3];
-
-		tmpbuf[i] = bdev->rds_info.radio_text[bdev->rd_index + i + 2];
-		tmpbuf[i + 1] =
-			bdev->rds_info.radio_text[bdev->rd_index + i + 1];
-		tmpbuf[i + 2] =
-			(bdev->rds_info.radio_text[bdev->rd_index + i] &
-			 0xf0) >> 4;
-		if ((bdev->rds_info.radio_text[bdev->rd_index + i] &
-		    BCM2048_RDS_CRC_MASK) == BCM2048_RDS_CRC_UNRECOVARABLE)
-			tmpbuf[i + 2] |= 0x80;
-		if (copy_to_user(buf + i, tmpbuf, 3)) {
-			retval = -EFAULT;
-			break;
-		}
-		i += 3;
-	}
-
-	bdev->rd_index += i;
-	if (bdev->rd_index >= bdev->fifo_size)
-		bdev->rds_data_available = 0;
-
-	mutex_unlock(&bdev->mutex);
-	if (retval == 0)
-		retval = i;
-
-done:
-	return retval;
-}
-
-/*
- *	bcm2048_fops - file operations interface
- */
-static const struct v4l2_file_operations bcm2048_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
-	/* for RDS read support */
-	.open		= bcm2048_fops_open,
-	.release	= bcm2048_fops_release,
-	.read		= bcm2048_fops_read,
-	.poll		= bcm2048_fops_poll
-};
-
-/*
- *	Video4Linux Interface
- */
-static struct v4l2_queryctrl bcm2048_v4l2_queryctrl[] = {
-	{
-		.id		= V4L2_CID_AUDIO_VOLUME,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_BALANCE,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_BASS,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_TREBLE,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_MUTE,
-		.type		= V4L2_CTRL_TYPE_BOOLEAN,
-		.name		= "Mute",
-		.minimum	= 0,
-		.maximum	= 1,
-		.step		= 1,
-		.default_value	= 1,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_LOUDNESS,
-		.flags		= V4L2_CTRL_FLAG_DISABLED,
-	},
-};
-
-static int bcm2048_vidioc_querycap(struct file *file, void *priv,
-				   struct v4l2_capability *capability)
-{
-	struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
-
-	strscpy(capability->driver, BCM2048_DRIVER_NAME,
-		sizeof(capability->driver));
-	strscpy(capability->card, BCM2048_DRIVER_CARD,
-		sizeof(capability->card));
-	snprintf(capability->bus_info, 32, "I2C: 0x%X", bdev->client->addr);
-	return 0;
-}
-
-static int bcm2048_vidioc_g_input(struct file *filp, void *priv,
-				  unsigned int *i)
-{
-	*i = 0;
-
-	return 0;
-}
-
-static int bcm2048_vidioc_s_input(struct file *filp, void *priv,
-				  unsigned int i)
-{
-	if (i)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int bcm2048_vidioc_queryctrl(struct file *file, void *priv,
-				    struct v4l2_queryctrl *qc)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(bcm2048_v4l2_queryctrl); i++) {
-		if (qc->id && qc->id == bcm2048_v4l2_queryctrl[i].id) {
-			*qc = bcm2048_v4l2_queryctrl[i];
-			return 0;
-		}
-	}
-
-	return -EINVAL;
-}
-
-static int bcm2048_vidioc_g_ctrl(struct file *file, void *priv,
-				 struct v4l2_control *ctrl)
-{
-	struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
-	int err = 0;
-
-	if (!bdev)
-		return -ENODEV;
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		err = bcm2048_get_mute(bdev);
-		if (err >= 0)
-			ctrl->value = err;
-		break;
-	}
-
-	return err;
-}
-
-static int bcm2048_vidioc_s_ctrl(struct file *file, void *priv,
-				 struct v4l2_control *ctrl)
-{
-	struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
-	int err = 0;
-
-	if (!bdev)
-		return -ENODEV;
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value) {
-			if (bdev->power_state) {
-				err = bcm2048_set_mute(bdev, ctrl->value);
-				err |= bcm2048_deinit(bdev);
-			}
-		} else {
-			if (!bdev->power_state) {
-				err = bcm2048_init(bdev);
-				err |= bcm2048_set_mute(bdev, ctrl->value);
-			}
-		}
-		break;
-	}
-
-	return err;
-}
-
-static int bcm2048_vidioc_g_audio(struct file *file, void *priv,
-				  struct v4l2_audio *audio)
-{
-	if (audio->index > 1)
-		return -EINVAL;
-
-	strscpy(audio->name, "Radio", sizeof(audio->name));
-	audio->capability = V4L2_AUDCAP_STEREO;
-
-	return 0;
-}
-
-static int bcm2048_vidioc_s_audio(struct file *file, void *priv,
-				  const struct v4l2_audio *audio)
-{
-	if (audio->index != 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int bcm2048_vidioc_g_tuner(struct file *file, void *priv,
-				  struct v4l2_tuner *tuner)
-{
-	struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
-	s8 f_error;
-	s8 rssi;
-
-	if (!bdev)
-		return -ENODEV;
-
-	if (tuner->index > 0)
-		return -EINVAL;
-
-	strscpy(tuner->name, "FM Receiver", sizeof(tuner->name));
-	tuner->type = V4L2_TUNER_RADIO;
-	tuner->rangelow =
-		dev_to_v4l2(bcm2048_get_region_bottom_frequency(bdev));
-	tuner->rangehigh =
-		dev_to_v4l2(bcm2048_get_region_top_frequency(bdev));
-	tuner->rxsubchans = V4L2_TUNER_SUB_STEREO;
-	tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW;
-	tuner->audmode = V4L2_TUNER_MODE_STEREO;
-	tuner->afc = 0;
-	if (bdev->power_state) {
-		/*
-		 * Report frequencies with high carrier errors to have zero
-		 * signal level
-		 */
-		f_error = bcm2048_get_fm_carrier_error(bdev);
-		if (f_error < BCM2048_FREQ_ERROR_FLOOR ||
-		    f_error > BCM2048_FREQ_ERROR_ROOF) {
-			tuner->signal = 0;
-		} else {
-			/*
-			 * RSSI level -60 dB is defined to report full
-			 * signal strength
-			 */
-			rssi = bcm2048_get_fm_rssi(bdev);
-			if (rssi >= BCM2048_RSSI_LEVEL_BASE) {
-				tuner->signal = 0xFFFF;
-			} else if (rssi > BCM2048_RSSI_LEVEL_ROOF) {
-				tuner->signal = (rssi +
-						 BCM2048_RSSI_LEVEL_ROOF_NEG)
-						 * BCM2048_SIGNAL_MULTIPLIER;
-			} else {
-				tuner->signal = 0;
-			}
-		}
-	} else {
-		tuner->signal = 0;
-	}
-
-	return 0;
-}
-
-static int bcm2048_vidioc_s_tuner(struct file *file, void *priv,
-				  const struct v4l2_tuner *tuner)
-{
-	struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
-
-	if (!bdev)
-		return -ENODEV;
-
-	if (tuner->index > 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int bcm2048_vidioc_g_frequency(struct file *file, void *priv,
-				      struct v4l2_frequency *freq)
-{
-	struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
-	int err = 0;
-	int f;
-
-	if (!bdev->power_state)
-		return -ENODEV;
-
-	freq->type = V4L2_TUNER_RADIO;
-	f = bcm2048_get_fm_frequency(bdev);
-
-	if (f < 0)
-		err = f;
-	else
-		freq->frequency = dev_to_v4l2(f);
-
-	return err;
-}
-
-static int bcm2048_vidioc_s_frequency(struct file *file, void *priv,
-				      const struct v4l2_frequency *freq)
-{
-	struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
-	int err;
-
-	if (freq->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-
-	if (!bdev->power_state)
-		return -ENODEV;
-
-	err = bcm2048_set_fm_frequency(bdev, v4l2_to_dev(freq->frequency));
-	err |= bcm2048_set_fm_search_tune_mode(bdev, BCM2048_FM_PRE_SET_MODE);
-
-	return err;
-}
-
-static int bcm2048_vidioc_s_hw_freq_seek(struct file *file, void *priv,
-					 const struct v4l2_hw_freq_seek *seek)
-{
-	struct bcm2048_device *bdev = video_get_drvdata(video_devdata(file));
-	int err;
-
-	if (!bdev->power_state)
-		return -ENODEV;
-
-	if ((seek->tuner != 0) || (seek->type != V4L2_TUNER_RADIO))
-		return -EINVAL;
-
-	err = bcm2048_set_fm_search_mode_direction(bdev, seek->seek_upward);
-	err |= bcm2048_set_fm_search_tune_mode(bdev,
-					       BCM2048_FM_AUTO_SEARCH_MODE);
-
-	return err;
-}
-
-static const struct v4l2_ioctl_ops bcm2048_ioctl_ops = {
-	.vidioc_querycap	= bcm2048_vidioc_querycap,
-	.vidioc_g_input		= bcm2048_vidioc_g_input,
-	.vidioc_s_input		= bcm2048_vidioc_s_input,
-	.vidioc_queryctrl	= bcm2048_vidioc_queryctrl,
-	.vidioc_g_ctrl		= bcm2048_vidioc_g_ctrl,
-	.vidioc_s_ctrl		= bcm2048_vidioc_s_ctrl,
-	.vidioc_g_audio		= bcm2048_vidioc_g_audio,
-	.vidioc_s_audio		= bcm2048_vidioc_s_audio,
-	.vidioc_g_tuner		= bcm2048_vidioc_g_tuner,
-	.vidioc_s_tuner		= bcm2048_vidioc_s_tuner,
-	.vidioc_g_frequency	= bcm2048_vidioc_g_frequency,
-	.vidioc_s_frequency	= bcm2048_vidioc_s_frequency,
-	.vidioc_s_hw_freq_seek  = bcm2048_vidioc_s_hw_freq_seek,
-};
-
-/*
- * bcm2048_viddev_template - video device interface
- */
-static const struct video_device bcm2048_viddev_template = {
-	.fops			= &bcm2048_fops,
-	.name			= BCM2048_DRIVER_NAME,
-	.release		= video_device_release_empty,
-	.ioctl_ops		= &bcm2048_ioctl_ops,
-	.device_caps		= V4L2_CAP_TUNER | V4L2_CAP_RADIO |
-				  V4L2_CAP_HW_FREQ_SEEK,
-};
-
-/*
- *	I2C driver interface
- */
-static int bcm2048_i2c_driver_probe(struct i2c_client *client)
-{
-	struct bcm2048_device *bdev;
-	int err;
-
-	bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
-	if (!bdev) {
-		err = -ENOMEM;
-		goto exit;
-	}
-
-	bdev->client = client;
-	i2c_set_clientdata(client, bdev);
-	mutex_init(&bdev->mutex);
-	init_completion(&bdev->compl);
-	INIT_WORK(&bdev->work, bcm2048_work);
-
-	if (client->irq) {
-		err = request_irq(client->irq,
-				  bcm2048_handler, IRQF_TRIGGER_FALLING,
-				  client->name, bdev);
-		if (err < 0) {
-			dev_err(&client->dev, "Could not request IRQ\n");
-			goto free_bdev;
-		}
-		dev_dbg(&client->dev, "IRQ requested.\n");
-	} else {
-		dev_dbg(&client->dev, "IRQ not configured. Using timeouts.\n");
-	}
-
-	bdev->videodev = bcm2048_viddev_template;
-	video_set_drvdata(&bdev->videodev, bdev);
-	if (video_register_device(&bdev->videodev, VFL_TYPE_RADIO, radio_nr)) {
-		dev_dbg(&client->dev, "Could not register video device.\n");
-		err = -EIO;
-		goto free_irq;
-	}
-
-	err = bcm2048_sysfs_register_properties(bdev);
-	if (err < 0) {
-		dev_dbg(&client->dev, "Could not register sysfs interface.\n");
-		goto free_registration;
-	}
-
-	err = bcm2048_probe(bdev);
-	if (err < 0) {
-		dev_dbg(&client->dev, "Failed to probe device information.\n");
-		goto free_sysfs;
-	}
-
-	return 0;
-
-free_sysfs:
-	bcm2048_sysfs_unregister_properties(bdev, ARRAY_SIZE(attrs));
-free_registration:
-	video_unregister_device(&bdev->videodev);
-free_irq:
-	if (client->irq)
-		free_irq(client->irq, bdev);
-free_bdev:
-	i2c_set_clientdata(client, NULL);
-	kfree(bdev);
-exit:
-	return err;
-}
-
-static int bcm2048_i2c_driver_remove(struct i2c_client *client)
-{
-	struct bcm2048_device *bdev = i2c_get_clientdata(client);
-
-	if (!client->adapter)
-		return -ENODEV;
-
-	if (bdev) {
-		bcm2048_sysfs_unregister_properties(bdev, ARRAY_SIZE(attrs));
-		video_unregister_device(&bdev->videodev);
-
-		if (bdev->power_state)
-			bcm2048_set_power_state(bdev, BCM2048_POWER_OFF);
-
-		if (client->irq > 0)
-			free_irq(client->irq, bdev);
-
-		cancel_work_sync(&bdev->work);
-
-		kfree(bdev);
-	}
-
-	return 0;
-}
-
-/*
- *	bcm2048_i2c_driver - i2c driver interface
- */
-static const struct i2c_device_id bcm2048_id[] = {
-	{ "bcm2048", 0 },
-	{ },
-};
-MODULE_DEVICE_TABLE(i2c, bcm2048_id);
-
-static struct i2c_driver bcm2048_i2c_driver = {
-	.driver		= {
-		.name	= BCM2048_DRIVER_NAME,
-	},
-	.probe_new	= bcm2048_i2c_driver_probe,
-	.remove		= bcm2048_i2c_driver_remove,
-	.id_table	= bcm2048_id,
-};
-
-module_i2c_driver(bcm2048_i2c_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR(BCM2048_DRIVER_AUTHOR);
-MODULE_DESCRIPTION(BCM2048_DRIVER_DESC);
-MODULE_VERSION("0.0.2");
diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.h b/drivers/staging/media/bcm2048/radio-bcm2048.h
deleted file mode 100644
index 22887a0..0000000
--- a/drivers/staging/media/bcm2048/radio-bcm2048.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * drivers/staging/media/radio-bcm2048.h
- *
- * Property and command definitions for bcm2048 radio receiver chip.
- *
- * Copyright (C) Nokia Corporation
- * Contact: Eero Nurkkala <ext-eero.nurkkala@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-
-#ifndef BCM2048_H
-#define BCM2048_H
-
-#define BCM2048_NAME		"bcm2048"
-#define BCM2048_I2C_ADDR	0x22
-
-#endif	/* ifndef BCM2048_H */
diff --git a/drivers/staging/media/davinci_vpfe/Kconfig b/drivers/staging/media/davinci_vpfe/Kconfig
deleted file mode 100644
index 94bf674..0000000
--- a/drivers/staging/media/davinci_vpfe/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-config VIDEO_DM365_VPFE
-	tristate "DM365 VPFE Media Controller Capture Driver"
-	depends on VIDEO_V4L2
-	depends on (ARCH_DAVINCI_DM365 && !VIDEO_DM365_ISIF) || (COMPILE_TEST && !ARCH_OMAP1)
-	depends on VIDEO_V4L2_SUBDEV_API
-	depends on VIDEO_DAVINCI_VPBE_DISPLAY
-	select VIDEOBUF2_DMA_CONTIG
-	help
-	  Support for DM365 VPFE based Media Controller Capture driver.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called vpfe-mc-capture.
diff --git a/drivers/staging/media/davinci_vpfe/Makefile b/drivers/staging/media/davinci_vpfe/Makefile
deleted file mode 100644
index 0ae8c50..0000000
--- a/drivers/staging/media/davinci_vpfe/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci-vfpe.o
-
-davinci-vfpe-objs := \
-	dm365_isif.o dm365_ipipe_hw.o dm365_ipipe.o \
-	dm365_resizer.o dm365_ipipeif.o vpfe_mc_capture.o vpfe_video.o
-
-# Allow building it with COMPILE_TEST on other archs
-ifndef CONFIG_ARCH_DAVINCI
-ccflags-y += -I $(srctree)/arch/arm/mach-davinci/include/
-endif
diff --git a/drivers/staging/media/davinci_vpfe/TODO b/drivers/staging/media/davinci_vpfe/TODO
deleted file mode 100644
index cc8bd93..0000000
--- a/drivers/staging/media/davinci_vpfe/TODO
+++ /dev/null
@@ -1,38 +0,0 @@
-TODO (general):
-==================================
-
-- User space interface refinement
-	- Controls should be used when possible rather than private ioctl
-	- No enums should be used
-	- Use of MC and V4L2 subdev APIs when applicable
-	- Single interface header might suffice
-	- Current interface forces to configure everything at once
-- Get rid of the dm365_ipipe_hw.[ch] layer
-- Active external sub-devices defined by link configuration; no strcmp
-  needed
-- More generic platform data (i2c adapters)
-- The driver should have no knowledge of possible external subdevs; see
-  struct vpfe_subdev_id
-- Some of the hardware control should be refactorede
-- Check proper serialisation (through mutexes and spinlocks)
-- Names that are visible in kernel global namespace should have a common
-  prefix (or a few)
-- While replacing the older driver in media folder, provide a compatibility
-  layer and compatibility tests that warrants (using the libv4l's LD_PRELOAD
-  approach) there is no regression for the users using the older driver.
-- make it independent of arch-specific APIs (mach/mux.h).
-
-Building of uImage and Applications:
-==================================
-
-As of now since the interface will undergo few changes all the include
-files are present in staging itself, to build for dm365 follow below steps,
-
-- copy vpfe.h from drivers/staging/media/davinci_vpfe/ to
-  include/media/davinci/ folder for building the uImage.
-- copy davinci_vpfe_user.h from drivers/staging/media/davinci_vpfe/ to
-  include/uapi/linux/davinci_vpfe.h, and add a entry in Kbuild (required
-  for building application).
-- copy dm365_ipipeif_user.h from drivers/staging/media/davinci_vpfe/ to
-  include/uapi/linux/dm365_ipipeif.h and a entry in Kbuild (required
-  for building application).
diff --git a/drivers/staging/media/davinci_vpfe/davinci-vpfe-mc.txt b/drivers/staging/media/davinci_vpfe/davinci-vpfe-mc.txt
deleted file mode 100644
index a1e9177..0000000
--- a/drivers/staging/media/davinci_vpfe/davinci-vpfe-mc.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-Davinci Video processing Front End (VPFE) driver
-
-Copyright (C) 2012 Texas Instruments Inc
-
-Contacts: Manjunath Hadli <manjunath.hadli@ti.com>
-	  Prabhakar Lad <prabhakar.lad@ti.com>
-
-
-Introduction
-============
-
-This file documents the Texas Instruments Davinci Video processing Front End
-(VPFE) driver located under drivers/media/platform/davinci. The original driver
-exists for Davinci VPFE, which is now being changed to Media Controller
-Framework.
-
-Currently the driver has been successfully used on the following
-version of Davinci:
-
-	DM365/DM368
-
-The driver implements V4L2, Media controller and v4l2_subdev interfaces. Sensor,
-lens and flash drivers using the v4l2_subdev interface in the kernel are
-supported.
-
-
-Split to subdevs
-================
-
-The Davinci VPFE is split into V4L2 subdevs, each of the blocks inside the VPFE
-having one subdev to represent it. Each of the subdevs provide a V4L2 subdev
-interface to userspace.
-
-	DAVINCI ISIF
-	DAVINCI IPIPEIF
-	DAVINCI IPIPE
-	DAVINCI CROP RESIZER
-	DAVINCI RESIZER A
-	DAVINCI RESIZER B
-
-Each possible link in the VPFE is modelled by a link in the Media controller
-interface. For an example program see [1].
-
-
-ISIF, IPIPE, and RESIZER block IOCTLs
-======================================
-
-The Davinci Video processing Front End (VPFE) driver supports standard V4L2
-IOCTLs and controls where possible and practical. Much of the functions provided
-by the VPFE, however, does not fall under the standard IOCTL's.
-
-In general, there is a private ioctl for configuring each of the blocks
-containing hardware-dependent functions.
-
-The following private IOCTLs are supported:
-
-	VIDIOC_VPFE_ISIF_[S/G]_RAW_PARAMS
-	VIDIOC_VPFE_IPIPE_[S/G]_CONFIG
-	VIDIOC_VPFE_RSZ_[S/G]_CONFIG
-
-The parameter structures used by these ioctl's are described in
-include/uapi/linux/davinci_vpfe.h.
-
-The VIDIOC_VPFE_ISIF_S_RAW_PARAMS, VIDIOC_VPFE_IPIPE_S_CONFIG and
-VIDIOC_VPFE_RSZ_S_CONFIG are used to configure, enable and disable functions in
-the isif, ipipe and resizer blocks respectively. These IOCTL's control several
-functions in the blocks they control. VIDIOC_VPFE_ISIF_S_RAW_PARAMS IOCTL
-accepts a pointer to struct vpfe_isif_raw_config as its argument. Similarly
-VIDIOC_VPFE_IPIPE_S_CONFIG accepts a pointer to struct vpfe_ipipe_config. And
-VIDIOC_VPFE_RSZ_S_CONFIG accepts a pointer to struct vpfe_rsz_config as its
-argument. Similarly VIDIOC_VPFE_ISIF_G_RAW_PARAMS, VIDIOC_VPFE_IPIPE_G_CONFIG
-and VIDIOC_VPFE_RSZ_G_CONFIG are used to get the current configuration set in
-the isif, ipipe and resizer blocks respectively.
-
-The detailed functions of the VPFE itself related to a given VPFE block is
-described in the Technical Reference Manuals (TRMs) --- see the end of the
-document for those.
-
-
-IPIPEIF block IOCTLs
-======================================
-
-The following private IOCTLs are supported:
-
-	VIDIOC_VPFE_IPIPEIF_[S/G]_CONFIG
-
-The parameter structures used by these ioctl's are described in
-include/uapi/linux/dm365_ipipeif.h
-
-The VIDIOC_VPFE_IPIPEIF_S_CONFIG is used to configure the ipipeif
-hardware block. The VIDIOC_VPFE_IPIPEIF_S_CONFIG and
-VIDIOC_VPFE_IPIPEIF_G_CONFIG accepts a pointer to struct ipipeif_params
-as its argument.
-
-
-VPFE Operating Modes
-==========================================
-
-a: Continuous Modes
-------------------------
-
-1: tvp514x/tvp7002/mt9p031---> DAVINCI ISIF---> SDRAM
-
-2: tvp514x/tvp7002/mt9p031---> DAVINCI ISIF---> DAVINCI IPIPEIF--->|
-                                                                   |
-   <--------------------<----------------<---------------------<---|
-   |
-   V
- DAVINCI CROP RESIZER--->DAVINCI RESIZER [A/B]---> SDRAM
-
-3: tvp514x/tvp7002/mt9p031---> DAVINCI ISIF---> DAVINCI IPIPEIF--->|
-                                                                   |
-   <--------------------<----------------<---------------------<---|
-   |
-   V
- DAVINCI IPIPE---> DAVINCI CROP RESIZER--->DAVINCI RESIZER [A/B]---> SDRAM
-
-a: Single Shot Modes
-------------------------
-
-1: SDRAM---> DAVINCI IPIPEIF---> DAVINCI IPIPE---> DAVINCI CROP RESIZER--->|
-                                                                           |
-   <----------------<----------------<------------------<---------------<--|
-   |
-   V
-DAVINCI RESIZER [A/B]---> SDRAM
-
-2: SDRAM---> DAVINCI IPIPEIF---> DAVINCI CROP RESIZER--->|
-                                                         |
-   <----------------<----------------<---------------<---|
-   |
-   V
-DAVINCI RESIZER [A/B]---> SDRAM
-
-
-Technical reference manuals (TRMs) and other documentation
-==========================================================
-
-Davinci DM365 TRM:
-<URL:http://www.ti.com/lit/ds/sprs457e/sprs457e.pdf>
-Referenced MARCH 2009-REVISED JUNE 2011
-
-Davinci DM368 TRM:
-<URL:http://www.ti.com/lit/ds/sprs668c/sprs668c.pdf>
-Referenced APRIL 2010-REVISED JUNE 2011
-
-Davinci Video Processing Front End (VPFE) DM36x
-<URL:http://www.ti.com/lit/ug/sprufg8c/sprufg8c.pdf>
-
-
-References
-==========
-
-[1] http://git.ideasonboard.org/?p=media-ctl.git;a=summary
diff --git a/drivers/staging/media/davinci_vpfe/davinci_vpfe_user.h b/drivers/staging/media/davinci_vpfe/davinci_vpfe_user.h
deleted file mode 100644
index 8d77202..0000000
--- a/drivers/staging/media/davinci_vpfe/davinci_vpfe_user.h
+++ /dev/null
@@ -1,1287 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _DAVINCI_VPFE_USER_H
-#define _DAVINCI_VPFE_USER_H
-
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-/*
- * Private IOCTL
- *
- * VIDIOC_VPFE_ISIF_S_RAW_PARAMS: Set raw params in isif
- * VIDIOC_VPFE_ISIF_G_RAW_PARAMS: Get raw params from isif
- * VIDIOC_VPFE_PRV_S_CONFIG: Set ipipe engine configuration
- * VIDIOC_VPFE_PRV_G_CONFIG: Get ipipe engine configuration
- * VIDIOC_VPFE_RSZ_S_CONFIG: Set resizer engine configuration
- * VIDIOC_VPFE_RSZ_G_CONFIG: Get resizer engine configuration
- */
-
-#define VIDIOC_VPFE_ISIF_S_RAW_PARAMS \
-	_IOW('V', BASE_VIDIOC_PRIVATE + 1,  struct vpfe_isif_raw_config)
-#define VIDIOC_VPFE_ISIF_G_RAW_PARAMS \
-	_IOR('V', BASE_VIDIOC_PRIVATE + 2, struct vpfe_isif_raw_config)
-#define VIDIOC_VPFE_IPIPE_S_CONFIG \
-	_IOWR('P', BASE_VIDIOC_PRIVATE + 3, struct vpfe_ipipe_config)
-#define VIDIOC_VPFE_IPIPE_G_CONFIG \
-	_IOWR('P', BASE_VIDIOC_PRIVATE + 4, struct vpfe_ipipe_config)
-#define VIDIOC_VPFE_RSZ_S_CONFIG \
-	_IOWR('R', BASE_VIDIOC_PRIVATE + 5, struct vpfe_rsz_config)
-#define VIDIOC_VPFE_RSZ_G_CONFIG \
-	_IOWR('R', BASE_VIDIOC_PRIVATE + 6, struct vpfe_rsz_config)
-
-/*
- * Private Control's for ISIF
- */
-#define VPFE_ISIF_CID_CRGAIN		(V4L2_CID_USER_BASE | 0xa001)
-#define VPFE_ISIF_CID_CGRGAIN		(V4L2_CID_USER_BASE | 0xa002)
-#define VPFE_ISIF_CID_CGBGAIN		(V4L2_CID_USER_BASE | 0xa003)
-#define VPFE_ISIF_CID_CBGAIN		(V4L2_CID_USER_BASE | 0xa004)
-#define VPFE_ISIF_CID_GAIN_OFFSET	(V4L2_CID_USER_BASE | 0xa005)
-
-/*
- * Private Control's for ISIF and IPIPEIF
- */
-#define VPFE_CID_DPCM_PREDICTOR		(V4L2_CID_USER_BASE | 0xa006)
-
-/************************************************************************
- *   Vertical Defect Correction parameters
- ***********************************************************************/
-
-/**
- * vertical defect correction methods
- */
-enum vpfe_isif_vdfc_corr_mode {
-	/* Defect level subtraction. Just fed through if saturating */
-	VPFE_ISIF_VDFC_NORMAL,
-	/**
-	 * Defect level subtraction. Horizontal interpolation ((i-2)+(i+2))/2
-	 * if data saturating
-	 */
-	VPFE_ISIF_VDFC_HORZ_INTERPOL_IF_SAT,
-	/* Horizontal interpolation (((i-2)+(i+2))/2) */
-	VPFE_ISIF_VDFC_HORZ_INTERPOL
-};
-
-/**
- * Max Size of the Vertical Defect Correction table
- */
-#define VPFE_ISIF_VDFC_TABLE_SIZE	8
-
-/**
- * Values used for shifting up the vdfc defect level
- */
-enum vpfe_isif_vdfc_shift {
-	/* No Shift */
-	VPFE_ISIF_VDFC_NO_SHIFT,
-	/* Shift by 1 bit */
-	VPFE_ISIF_VDFC_SHIFT_1,
-	/* Shift by 2 bit */
-	VPFE_ISIF_VDFC_SHIFT_2,
-	/* Shift by 3 bit */
-	VPFE_ISIF_VDFC_SHIFT_3,
-	/* Shift by 4 bit */
-	VPFE_ISIF_VDFC_SHIFT_4
-};
-
-/**
- * Defect Correction (DFC) table entry
- */
-struct vpfe_isif_vdfc_entry {
-	/* vertical position of defect */
-	unsigned short pos_vert;
-	/* horizontal position of defect */
-	unsigned short pos_horz;
-	/**
-	 * Defect level of Vertical line defect position. This is subtracted
-	 * from the data at the defect position
-	 */
-	unsigned char level_at_pos;
-	/**
-	 * Defect level of the pixels upper than the vertical line defect.
-	 * This is subtracted from the data
-	 */
-	unsigned char level_up_pixels;
-	/**
-	 * Defect level of the pixels lower than the vertical line defect.
-	 * This is subtracted from the data
-	 */
-	unsigned char level_low_pixels;
-};
-
-/**
- * Structure for Defect Correction (DFC) parameter
- */
-struct vpfe_isif_dfc {
-	/* enable vertical defect correction */
-	unsigned char en;
-	/* Correction methods */
-	enum vpfe_isif_vdfc_corr_mode corr_mode;
-	/**
-	 * 0 - whole line corrected, 1 - not
-	 * pixels upper than the defect
-	 */
-	unsigned char corr_whole_line;
-	/**
-	 * defect level shift value. level_at_pos, level_upper_pos,
-	 * and level_lower_pos can be shifted up by this value
-	 */
-	enum vpfe_isif_vdfc_shift def_level_shift;
-	/* defect saturation level */
-	unsigned short def_sat_level;
-	/* number of vertical defects. Max is VPFE_ISIF_VDFC_TABLE_SIZE */
-	short num_vdefects;
-	/* VDFC table ptr */
-	struct vpfe_isif_vdfc_entry table[VPFE_ISIF_VDFC_TABLE_SIZE];
-};
-
-/************************************************************************
- *   Digital/Black clamp or DC Subtract parameters
- ************************************************************************/
-/**
- * Horizontal Black Clamp modes
- */
-enum vpfe_isif_horz_bc_mode {
-	/**
-	 * Horizontal clamp disabled. Only vertical clamp
-	 * value is subtracted
-	 */
-	VPFE_ISIF_HORZ_BC_DISABLE,
-	/**
-	 * Horizontal clamp value is calculated and subtracted
-	 * from image data along with vertical clamp value
-	 */
-	VPFE_ISIF_HORZ_BC_CLAMP_CALC_ENABLED,
-	/**
-	 * Horizontal clamp value calculated from previous image
-	 * is subtracted from image data along with vertical clamp
-	 * value. How the horizontal clamp value for the first image
-	 * is calculated in this case ???
-	 */
-	VPFE_ISIF_HORZ_BC_CLAMP_NOT_UPDATED
-};
-
-/**
- * Base window selection for Horizontal Black Clamp calculations
- */
-enum vpfe_isif_horz_bc_base_win_sel {
-	/* Select Most left window for bc calculation */
-	VPFE_ISIF_SEL_MOST_LEFT_WIN,
-
-	/* Select Most right window for bc calculation */
-	VPFE_ISIF_SEL_MOST_RIGHT_WIN,
-};
-
-/* Size of window in horizontal direction for horizontal bc */
-enum vpfe_isif_horz_bc_sz_h {
-	VPFE_ISIF_HORZ_BC_SZ_H_2PIXELS,
-	VPFE_ISIF_HORZ_BC_SZ_H_4PIXELS,
-	VPFE_ISIF_HORZ_BC_SZ_H_8PIXELS,
-	VPFE_ISIF_HORZ_BC_SZ_H_16PIXELS
-};
-
-/* Size of window in vertcal direction for vertical bc */
-enum vpfe_isif_horz_bc_sz_v {
-	VPFE_ISIF_HORZ_BC_SZ_H_32PIXELS,
-	VPFE_ISIF_HORZ_BC_SZ_H_64PIXELS,
-	VPFE_ISIF_HORZ_BC_SZ_H_128PIXELS,
-	VPFE_ISIF_HORZ_BC_SZ_H_256PIXELS
-};
-
-/**
- * Structure for Horizontal Black Clamp config params
- */
-struct vpfe_isif_horz_bclamp {
-	/* horizontal clamp mode */
-	enum vpfe_isif_horz_bc_mode mode;
-	/**
-	 * pixel value limit enable.
-	 *  0 - limit disabled
-	 *  1 - pixel value limited to 1023
-	 */
-	unsigned char clamp_pix_limit;
-	/**
-	 * Select most left or right window for clamp val
-	 * calculation
-	 */
-	enum vpfe_isif_horz_bc_base_win_sel base_win_sel_calc;
-	/* Window count per color for calculation. range 1-32 */
-	unsigned char win_count_calc;
-	/* Window start position - horizontal for calculation. 0 - 8191 */
-	unsigned short win_start_h_calc;
-	/* Window start position - vertical for calculation 0 - 8191 */
-	unsigned short win_start_v_calc;
-	/* Width of the sample window in pixels for calculation */
-	enum vpfe_isif_horz_bc_sz_h win_h_sz_calc;
-	/* Height of the sample window in pixels for calculation */
-	enum vpfe_isif_horz_bc_sz_v win_v_sz_calc;
-};
-
-/**
- * Black Clamp vertical reset values
- */
-enum vpfe_isif_vert_bc_reset_val_sel {
-	/* Reset value used is the clamp value calculated */
-	VPFE_ISIF_VERT_BC_USE_HORZ_CLAMP_VAL,
-	/* Reset value used is reset_clamp_val configured */
-	VPFE_ISIF_VERT_BC_USE_CONFIG_CLAMP_VAL,
-	/* No update, previous image value is used */
-	VPFE_ISIF_VERT_BC_NO_UPDATE
-};
-
-enum vpfe_isif_vert_bc_sz_h {
-	VPFE_ISIF_VERT_BC_SZ_H_2PIXELS,
-	VPFE_ISIF_VERT_BC_SZ_H_4PIXELS,
-	VPFE_ISIF_VERT_BC_SZ_H_8PIXELS,
-	VPFE_ISIF_VERT_BC_SZ_H_16PIXELS,
-	VPFE_ISIF_VERT_BC_SZ_H_32PIXELS,
-	VPFE_ISIF_VERT_BC_SZ_H_64PIXELS
-};
-
-/**
- * Structure for Vertical Black Clamp configuration params
- */
-struct vpfe_isif_vert_bclamp {
-	/* Reset value selection for vertical clamp calculation */
-	enum vpfe_isif_vert_bc_reset_val_sel reset_val_sel;
-	/* U12 value if reset_sel = ISIF_BC_VERT_USE_CONFIG_CLAMP_VAL */
-	unsigned short reset_clamp_val;
-	/**
-	 * U8Q8. Line average coefficient used in vertical clamp
-	 * calculation
-	 */
-	unsigned char line_ave_coef;
-	/* Width in pixels of the optical black region used for calculation. */
-	enum vpfe_isif_vert_bc_sz_h ob_h_sz_calc;
-	/* Height of the optical black region for calculation */
-	unsigned short ob_v_sz_calc;
-	/* Optical black region start position - horizontal. 0 - 8191 */
-	unsigned short ob_start_h;
-	/* Optical black region start position - vertical 0 - 8191 */
-	unsigned short ob_start_v;
-};
-
-/**
- * Structure for Black Clamp configuration params
- */
-struct vpfe_isif_black_clamp {
-	/**
-	 * this offset value is added irrespective of the clamp
-	 * enable status. S13
-	 */
-	unsigned short dc_offset;
-	/**
-	 * Enable black/digital clamp value to be subtracted
-	 * from the image data
-	 */
-	unsigned char en;
-	/**
-	 * black clamp mode. same/separate clamp for 4 colors
-	 * 0 - disable - same clamp value for all colors
-	 * 1 - clamp value calculated separately for all colors
-	 */
-	unsigned char bc_mode_color;
-	/* Vertical start position for bc subtraction */
-	unsigned short vert_start_sub;
-	/* Black clamp for horizontal direction */
-	struct vpfe_isif_horz_bclamp horz;
-	/* Black clamp for vertical direction */
-	struct vpfe_isif_vert_bclamp vert;
-};
-
-/*************************************************************************
- ** Color Space Conversion (CSC)
- *************************************************************************/
-/**
- * Number of Coefficient values used for CSC
- */
-#define VPFE_ISIF_CSC_NUM_COEFF 16
-
-struct float_8_bit {
-	/* 8 bit integer part */
-	__u8 integer;
-	/* 8 bit decimal part */
-	__u8 decimal;
-};
-
-struct float_16_bit {
-	/* 16 bit integer part */
-	__u16 integer;
-	/* 16 bit decimal part */
-	__u16 decimal;
-};
-
-/*************************************************************************
- **  Color Space Conversion parameters
- *************************************************************************/
-/**
- * Structure used for CSC config params
- */
-struct vpfe_isif_color_space_conv {
-	/* Enable color space conversion */
-	unsigned char en;
-	/**
-	 * csc coefficient table. S8Q5, M00 at index 0, M01 at index 1, and
-	 * so forth
-	 */
-	struct float_8_bit coeff[VPFE_ISIF_CSC_NUM_COEFF];
-};
-
-enum vpfe_isif_datasft {
-	/* No Shift */
-	VPFE_ISIF_NO_SHIFT,
-	/* 1 bit Shift */
-	VPFE_ISIF_1BIT_SHIFT,
-	/* 2 bit Shift */
-	VPFE_ISIF_2BIT_SHIFT,
-	/* 3 bit Shift */
-	VPFE_ISIF_3BIT_SHIFT,
-	/* 4 bit Shift */
-	VPFE_ISIF_4BIT_SHIFT,
-	/* 5 bit Shift */
-	VPFE_ISIF_5BIT_SHIFT,
-	/* 6 bit Shift */
-	VPFE_ISIF_6BIT_SHIFT
-};
-
-#define VPFE_ISIF_LINEAR_TAB_SIZE		192
-/*************************************************************************
- **  Linearization parameters
- *************************************************************************/
-/**
- * Structure for Sensor data linearization
- */
-struct vpfe_isif_linearize {
-	/* Enable or Disable linearization of data */
-	unsigned char en;
-	/* Shift value applied */
-	enum vpfe_isif_datasft corr_shft;
-	/* scale factor applied U11Q10 */
-	struct float_16_bit scale_fact;
-	/* Size of the linear table */
-	unsigned short table[VPFE_ISIF_LINEAR_TAB_SIZE];
-};
-
-/*************************************************************************
- **  ISIF Raw configuration parameters
- *************************************************************************/
-enum vpfe_isif_fmt_mode {
-	VPFE_ISIF_SPLIT,
-	VPFE_ISIF_COMBINE
-};
-
-enum vpfe_isif_lnum {
-	VPFE_ISIF_1LINE,
-	VPFE_ISIF_2LINES,
-	VPFE_ISIF_3LINES,
-	VPFE_ISIF_4LINES
-};
-
-enum vpfe_isif_line {
-	VPFE_ISIF_1STLINE,
-	VPFE_ISIF_2NDLINE,
-	VPFE_ISIF_3RDLINE,
-	VPFE_ISIF_4THLINE
-};
-
-struct vpfe_isif_fmtplen {
-	/**
-	 * number of program entries for SET0, range 1 - 16
-	 * when fmtmode is ISIF_SPLIT, 1 - 8 when fmtmode is
-	 * ISIF_COMBINE
-	 */
-	unsigned short plen0;
-	/**
-	 * number of program entries for SET1, range 1 - 16
-	 * when fmtmode is ISIF_SPLIT, 1 - 8 when fmtmode is
-	 * ISIF_COMBINE
-	 */
-	unsigned short plen1;
-	/**
-	 * number of program entries for SET2, range 1 - 16
-	 * when fmtmode is ISIF_SPLIT, 1 - 8 when fmtmode is
-	 * ISIF_COMBINE
-	 */
-	unsigned short plen2;
-	/**
-	 * number of program entries for SET3, range 1 - 16
-	 * when fmtmode is ISIF_SPLIT, 1 - 8 when fmtmode is
-	 * ISIF_COMBINE
-	 */
-	unsigned short plen3;
-};
-
-struct vpfe_isif_fmt_cfg {
-	/* Split or combine or line alternate */
-	enum vpfe_isif_fmt_mode fmtmode;
-	/* enable or disable line alternating mode */
-	unsigned char ln_alter_en;
-	/* Split/combine line number */
-	enum vpfe_isif_lnum lnum;
-	/* Address increment Range 1 - 16 */
-	unsigned int addrinc;
-};
-
-struct vpfe_isif_fmt_addr_ptr {
-	/* Initial address */
-	unsigned int init_addr;
-	/* output line number */
-	enum vpfe_isif_line out_line;
-};
-
-struct vpfe_isif_fmtpgm_ap {
-	/* program address pointer */
-	unsigned char pgm_aptr;
-	/* program address increment or decrement */
-	unsigned char pgmupdt;
-};
-
-struct vpfe_isif_data_formatter {
-	/* Enable/Disable data formatter */
-	unsigned char en;
-	/* data formatter configuration */
-	struct vpfe_isif_fmt_cfg cfg;
-	/* Formatter program entries length */
-	struct vpfe_isif_fmtplen plen;
-	/* first pixel in a line fed to formatter */
-	unsigned short fmtrlen;
-	/* HD interval for output line. Only valid when split line */
-	unsigned short fmthcnt;
-	/* formatter address pointers */
-	struct vpfe_isif_fmt_addr_ptr fmtaddr_ptr[16];
-	/* program enable/disable */
-	unsigned char pgm_en[32];
-	/* program address pointers */
-	struct vpfe_isif_fmtpgm_ap fmtpgm_ap[32];
-};
-
-struct vpfe_isif_df_csc {
-	/* Color Space Conversion configuration, 0 - csc, 1 - df */
-	unsigned int df_or_csc;
-	/* csc configuration valid if df_or_csc is 0 */
-	struct vpfe_isif_color_space_conv csc;
-	/* data formatter configuration valid if df_or_csc is 1 */
-	struct vpfe_isif_data_formatter df;
-	/* start pixel in a line at the input */
-	unsigned int start_pix;
-	/* number of pixels in input line */
-	unsigned int num_pixels;
-	/* start line at the input */
-	unsigned int start_line;
-	/* number of lines at the input */
-	unsigned int num_lines;
-};
-
-struct vpfe_isif_gain_offsets_adj {
-	/* Enable or Disable Gain adjustment for SDRAM data */
-	unsigned char gain_sdram_en;
-	/* Enable or Disable Gain adjustment for IPIPE data */
-	unsigned char gain_ipipe_en;
-	/* Enable or Disable Gain adjustment for H3A data */
-	unsigned char gain_h3a_en;
-	/* Enable or Disable Gain adjustment for SDRAM data */
-	unsigned char offset_sdram_en;
-	/* Enable or Disable Gain adjustment for IPIPE data */
-	unsigned char offset_ipipe_en;
-	/* Enable or Disable Gain adjustment for H3A data */
-	unsigned char offset_h3a_en;
-};
-
-struct vpfe_isif_cul {
-	/* Horizontal Cull pattern for odd lines */
-	unsigned char hcpat_odd;
-	/* Horizontal Cull pattern for even lines */
-	unsigned char hcpat_even;
-	/* Vertical Cull pattern */
-	unsigned char vcpat;
-	/* Enable or disable lpf. Apply when cull is enabled */
-	unsigned char en_lpf;
-};
-
-/* all the stuff in this struct will be provided by userland */
-struct vpfe_isif_raw_config {
-	/* Linearization parameters for image sensor data input */
-	struct vpfe_isif_linearize linearize;
-	/* Data formatter or CSC */
-	struct vpfe_isif_df_csc df_csc;
-	/* Defect Pixel Correction (DFC) confguration */
-	struct vpfe_isif_dfc dfc;
-	/* Black/Digital Clamp configuration */
-	struct vpfe_isif_black_clamp bclamp;
-	/* Gain, offset adjustments */
-	struct vpfe_isif_gain_offsets_adj gain_offset;
-	/* Culling */
-	struct vpfe_isif_cul culling;
-	/* horizontal offset for Gain/LSC/DFC */
-	unsigned short horz_offset;
-	/* vertical offset for Gain/LSC/DFC */
-	unsigned short vert_offset;
-};
-
-/**********************************************************************
- *	IPIPE API Structures
- **********************************************************************/
-
-/* IPIPE module configurations */
-
-/* IPIPE input configuration */
-#define VPFE_IPIPE_INPUT_CONFIG		BIT(0)
-/* LUT based Defect Pixel Correction */
-#define VPFE_IPIPE_LUTDPC		BIT(1)
-/* On the fly (OTF) Defect Pixel Correction */
-#define VPFE_IPIPE_OTFDPC		BIT(2)
-/* Noise Filter - 1 */
-#define VPFE_IPIPE_NF1			BIT(3)
-/* Noise Filter - 2 */
-#define VPFE_IPIPE_NF2			BIT(4)
-/* White Balance.  Also a control ID */
-#define VPFE_IPIPE_WB			BIT(5)
-/* 1st RGB to RBG Blend module */
-#define VPFE_IPIPE_RGB2RGB_1		BIT(6)
-/* 2nd RGB to RBG Blend module */
-#define VPFE_IPIPE_RGB2RGB_2		BIT(7)
-/* Gamma Correction */
-#define VPFE_IPIPE_GAMMA		BIT(8)
-/* 3D LUT color conversion */
-#define VPFE_IPIPE_3D_LUT		BIT(9)
-/* RGB to YCbCr module */
-#define VPFE_IPIPE_RGB2YUV		BIT(10)
-/* YUV 422 conversion module */
-#define VPFE_IPIPE_YUV422_CONV		BIT(11)
-/* Edge Enhancement */
-#define VPFE_IPIPE_YEE			BIT(12)
-/* Green Imbalance Correction */
-#define VPFE_IPIPE_GIC			BIT(13)
-/* CFA Interpolation */
-#define VPFE_IPIPE_CFA			BIT(14)
-/* Chroma Artifact Reduction */
-#define VPFE_IPIPE_CAR			BIT(15)
-/* Chroma Gain Suppression */
-#define VPFE_IPIPE_CGS			BIT(16)
-/* Global brightness and contrast control */
-#define VPFE_IPIPE_GBCE			BIT(17)
-
-#define VPFE_IPIPE_MAX_MODULES		18
-
-struct ipipe_float_u16 {
-	unsigned short integer;
-	unsigned short decimal;
-};
-
-struct ipipe_float_s16 {
-	short integer;
-	unsigned short decimal;
-};
-
-struct ipipe_float_u8 {
-	unsigned char integer;
-	unsigned char decimal;
-};
-
-/* Copy method selection for vertical correction
- *  Used when ipipe_dfc_corr_meth is IPIPE_DPC_CTORB_AFTER_HINT
- */
-enum vpfe_ipipe_dpc_corr_meth {
-	/* replace by black or white dot specified by repl_white */
-	VPFE_IPIPE_DPC_REPL_BY_DOT = 0,
-	/* Copy from left */
-	VPFE_IPIPE_DPC_CL = 1,
-	/* Copy from right */
-	VPFE_IPIPE_DPC_CR = 2,
-	/* Horizontal interpolation */
-	VPFE_IPIPE_DPC_H_INTP = 3,
-	/* Vertical interpolation */
-	VPFE_IPIPE_DPC_V_INTP = 4,
-	/* Copy from top  */
-	VPFE_IPIPE_DPC_CT = 5,
-	/* Copy from bottom */
-	VPFE_IPIPE_DPC_CB = 6,
-	/* 2D interpolation */
-	VPFE_IPIPE_DPC_2D_INTP = 7,
-};
-
-struct vpfe_ipipe_lutdpc_entry {
-	/* Horizontal position */
-	unsigned short horz_pos;
-	/* vertical position */
-	unsigned short vert_pos;
-	enum vpfe_ipipe_dpc_corr_meth method;
-};
-
-#define VPFE_IPIPE_MAX_SIZE_DPC 256
-
-/* Structure for configuring DPC module */
-struct vpfe_ipipe_lutdpc {
-	/* 0 - disable, 1 - enable */
-	unsigned char en;
-	/* 0 - replace with black dot, 1 - white dot when correction
-	 * method is  IPIPE_DFC_REPL_BY_DOT=0,
-	 */
-	unsigned char repl_white;
-	/* number of entries in the correction table. Currently only
-	 * support up-to 256 entries. infinite mode is not supported
-	 */
-	unsigned short dpc_size;
-	struct vpfe_ipipe_lutdpc_entry table[VPFE_IPIPE_MAX_SIZE_DPC];
-};
-
-enum vpfe_ipipe_otfdpc_det_meth {
-	VPFE_IPIPE_DPC_OTF_MIN_MAX,
-	VPFE_IPIPE_DPC_OTF_MIN_MAX2
-};
-
-struct vpfe_ipipe_otfdpc_thr {
-	unsigned short r;
-	unsigned short gr;
-	unsigned short gb;
-	unsigned short b;
-};
-
-enum vpfe_ipipe_otfdpc_alg {
-	VPFE_IPIPE_OTFDPC_2_0,
-	VPFE_IPIPE_OTFDPC_3_0
-};
-
-struct vpfe_ipipe_otfdpc_2_0_cfg {
-	/* defect detection threshold for MIN_MAX2 method  (DPC 2.0 alg) */
-	struct vpfe_ipipe_otfdpc_thr det_thr;
-	/* defect correction threshold for MIN_MAX2 method (DPC 2.0 alg) or
-	 * maximum value for MIN_MAX method
-	 */
-	struct vpfe_ipipe_otfdpc_thr corr_thr;
-};
-
-struct vpfe_ipipe_otfdpc_3_0_cfg {
-	/* DPC3.0 activity adj shf. activity = (max2-min2) >> (6 -shf)
-	 */
-	unsigned char act_adj_shf;
-	/* DPC3.0 detection threshold, THR */
-	unsigned short det_thr;
-	/* DPC3.0 detection threshold slope, SLP */
-	unsigned short det_slp;
-	/* DPC3.0 detection threshold min, MIN */
-	unsigned short det_thr_min;
-	/* DPC3.0 detection threshold max, MAX */
-	unsigned short det_thr_max;
-	/* DPC3.0 correction threshold, THR */
-	unsigned short corr_thr;
-	/* DPC3.0 correction threshold slope, SLP */
-	unsigned short corr_slp;
-	/* DPC3.0 correction threshold min, MIN */
-	unsigned short corr_thr_min;
-	/* DPC3.0 correction threshold max, MAX */
-	unsigned short corr_thr_max;
-};
-
-struct vpfe_ipipe_otfdpc {
-	/* 0 - disable, 1 - enable */
-	unsigned char en;
-	/* defect detection method */
-	enum vpfe_ipipe_otfdpc_det_meth det_method;
-	/* Algorithm used. Applicable only when IPIPE_DPC_OTF_MIN_MAX2 is
-	 * used
-	 */
-	enum vpfe_ipipe_otfdpc_alg alg;
-	union {
-		/* if alg is IPIPE_OTFDPC_2_0 */
-		struct vpfe_ipipe_otfdpc_2_0_cfg dpc_2_0;
-		/* if alg is IPIPE_OTFDPC_3_0 */
-		struct vpfe_ipipe_otfdpc_3_0_cfg dpc_3_0;
-	} alg_cfg;
-};
-
-/* Threshold values table size */
-#define VPFE_IPIPE_NF_THR_TABLE_SIZE		8
-/* Intensity values table size */
-#define VPFE_IPIPE_NF_STR_TABLE_SIZE		8
-
-/* NF, sampling method for green pixels */
-enum vpfe_ipipe_nf_sampl_meth {
-	/* Same as R or B */
-	VPFE_IPIPE_NF_BOX,
-	/* Diamond mode */
-	VPFE_IPIPE_NF_DIAMOND
-};
-
-/* Structure for configuring NF module */
-struct vpfe_ipipe_nf {
-	/* 0 - disable, 1 - enable */
-	unsigned char en;
-	/* Sampling method for green pixels */
-	enum vpfe_ipipe_nf_sampl_meth gr_sample_meth;
-	/* Down shift value in LUT reference address
-	 */
-	unsigned char shft_val;
-	/* Spread value in NF algorithm
-	 */
-	unsigned char spread_val;
-	/* Apply LSC gain to threshold. Enable this only if
-	 * LSC is enabled in ISIF
-	 */
-	unsigned char apply_lsc_gain;
-	/* Threshold values table */
-	unsigned short thr[VPFE_IPIPE_NF_THR_TABLE_SIZE];
-	/* intensity values table */
-	unsigned char str[VPFE_IPIPE_NF_STR_TABLE_SIZE];
-	/* Edge detection minimum threshold */
-	unsigned short edge_det_min_thr;
-	/* Edge detection maximum threshold */
-	unsigned short edge_det_max_thr;
-};
-
-enum vpfe_ipipe_gic_alg {
-	VPFE_IPIPE_GIC_ALG_CONST_GAIN,
-	VPFE_IPIPE_GIC_ALG_ADAPT_GAIN
-};
-
-enum vpfe_ipipe_gic_thr_sel {
-	VPFE_IPIPE_GIC_THR_REG,
-	VPFE_IPIPE_GIC_THR_NF
-};
-
-enum vpfe_ipipe_gic_wt_fn_type {
-	/* Use difference as index */
-	VPFE_IPIPE_GIC_WT_FN_TYP_DIF,
-	/* Use weight function as index */
-	VPFE_IPIPE_GIC_WT_FN_TYP_HP_VAL
-};
-
-/* structure for Green Imbalance Correction */
-struct vpfe_ipipe_gic {
-	/* 0 - disable, 1 - enable */
-	unsigned char en;
-	/* 0 - Constant gain , 1 - Adaptive gain algorithm */
-	enum vpfe_ipipe_gic_alg gic_alg;
-	/* GIC gain or weight. Used for Constant gain and Adaptive algorithms
-	 */
-	unsigned short gain;
-	/* Threshold selection. GIC register values or NF2 thr table */
-	enum vpfe_ipipe_gic_thr_sel thr_sel;
-	/* thr1. Used when thr_sel is  IPIPE_GIC_THR_REG */
-	unsigned short thr;
-	/* this value is used for thr2-thr1, thr3-thr2 or
-	 * thr4-thr3 when wt_fn_type is index. Otherwise it
-	 * is the
-	 */
-	unsigned short slope;
-	/* Apply LSC gain to threshold. Enable this only if
-	 * LSC is enabled in ISIF & thr_sel is IPIPE_GIC_THR_REG
-	 */
-	unsigned char apply_lsc_gain;
-	/* Multiply Nf2 threshold by this gain. Use this when thr_sel
-	 * is IPIPE_GIC_THR_NF
-	 */
-	struct ipipe_float_u8 nf2_thr_gain;
-	/* Weight function uses difference as index or high pass value.
-	 * Used for adaptive gain algorithm
-	 */
-	enum vpfe_ipipe_gic_wt_fn_type wt_fn_type;
-};
-
-/* Structure for configuring WB module */
-struct vpfe_ipipe_wb {
-	/* Offset (S12) for R */
-	short ofst_r;
-	/* Offset (S12) for Gr */
-	short ofst_gr;
-	/* Offset (S12) for Gb */
-	short ofst_gb;
-	/* Offset (S12) for B */
-	short ofst_b;
-	/* Gain (U13Q9) for Red */
-	struct ipipe_float_u16 gain_r;
-	/* Gain (U13Q9) for Gr */
-	struct ipipe_float_u16 gain_gr;
-	/* Gain (U13Q9) for Gb */
-	struct ipipe_float_u16 gain_gb;
-	/* Gain (U13Q9) for Blue */
-	struct ipipe_float_u16 gain_b;
-};
-
-enum vpfe_ipipe_cfa_alg {
-	/* Algorithm is 2DirAC */
-	VPFE_IPIPE_CFA_ALG_2DIRAC,
-	/* Algorithm is 2DirAC + Digital Antialiasing (DAA) */
-	VPFE_IPIPE_CFA_ALG_2DIRAC_DAA,
-	/* Algorithm is DAA */
-	VPFE_IPIPE_CFA_ALG_DAA
-};
-
-/* Structure for CFA Interpolation */
-struct vpfe_ipipe_cfa {
-	/* 2DirAC or 2DirAC + DAA */
-	enum vpfe_ipipe_cfa_alg alg;
-	/* 2Dir CFA HP value Low Threshold */
-	unsigned short hpf_thr_2dir;
-	/* 2Dir CFA HP value slope */
-	unsigned short hpf_slp_2dir;
-	/* 2Dir CFA HP mix threshold */
-	unsigned short hp_mix_thr_2dir;
-	/* 2Dir CFA HP mix slope */
-	unsigned short hp_mix_slope_2dir;
-	/* 2Dir Direction threshold */
-	unsigned short dir_thr_2dir;
-	/* 2Dir Direction slope */
-	unsigned short dir_slope_2dir;
-	/* 2Dir Non Directional Weight */
-	unsigned short nd_wt_2dir;
-	/* DAA Mono Hue Fraction */
-	unsigned short hue_fract_daa;
-	/* DAA Mono Edge threshold */
-	unsigned short edge_thr_daa;
-	/* DAA Mono threshold minimum */
-	unsigned short thr_min_daa;
-	/* DAA Mono threshold slope */
-	unsigned short thr_slope_daa;
-	/* DAA Mono slope minimum */
-	unsigned short slope_min_daa;
-	/* DAA Mono slope slope */
-	unsigned short slope_slope_daa;
-	/* DAA Mono LP wight */
-	unsigned short lp_wt_daa;
-};
-
-/* Struct for configuring RGB2RGB blending module */
-struct vpfe_ipipe_rgb2rgb {
-	/* Matrix coefficient for RR S12Q8 for ID = 1 and S11Q8 for ID = 2 */
-	struct ipipe_float_s16 coef_rr;
-	/* Matrix coefficient for GR S12Q8/S11Q8 */
-	struct ipipe_float_s16 coef_gr;
-	/* Matrix coefficient for BR S12Q8/S11Q8 */
-	struct ipipe_float_s16 coef_br;
-	/* Matrix coefficient for RG S12Q8/S11Q8 */
-	struct ipipe_float_s16 coef_rg;
-	/* Matrix coefficient for GG S12Q8/S11Q8 */
-	struct ipipe_float_s16 coef_gg;
-	/* Matrix coefficient for BG S12Q8/S11Q8 */
-	struct ipipe_float_s16 coef_bg;
-	/* Matrix coefficient for RB S12Q8/S11Q8 */
-	struct ipipe_float_s16 coef_rb;
-	/* Matrix coefficient for GB S12Q8/S11Q8 */
-	struct ipipe_float_s16 coef_gb;
-	/* Matrix coefficient for BB S12Q8/S11Q8 */
-	struct ipipe_float_s16 coef_bb;
-	/* Output offset for R S13/S11 */
-	int out_ofst_r;
-	/* Output offset for G S13/S11 */
-	int out_ofst_g;
-	/* Output offset for B S13/S11 */
-	int out_ofst_b;
-};
-
-#define VPFE_IPIPE_MAX_SIZE_GAMMA		512
-
-enum vpfe_ipipe_gamma_tbl_size {
-	VPFE_IPIPE_GAMMA_TBL_SZ_64 = 64,
-	VPFE_IPIPE_GAMMA_TBL_SZ_128 = 128,
-	VPFE_IPIPE_GAMMA_TBL_SZ_256 = 256,
-	VPFE_IPIPE_GAMMA_TBL_SZ_512 = 512,
-};
-
-enum vpfe_ipipe_gamma_tbl_sel {
-	VPFE_IPIPE_GAMMA_TBL_RAM = 0,
-	VPFE_IPIPE_GAMMA_TBL_ROM = 1,
-};
-
-struct vpfe_ipipe_gamma_entry {
-	/* 10 bit slope */
-	short slope;
-	/* 10 bit offset */
-	unsigned short offset;
-};
-
-/* Structure for configuring Gamma correction module */
-struct vpfe_ipipe_gamma {
-	/* 0 - Enable Gamma correction for Red
-	 * 1 - bypass Gamma correction. Data is divided by 16
-	 */
-	unsigned char bypass_r;
-	/* 0 - Enable Gamma correction for Blue
-	 * 1 - bypass Gamma correction. Data is divided by 16
-	 */
-	unsigned char bypass_b;
-	/* 0 - Enable Gamma correction for Green
-	 * 1 - bypass Gamma correction. Data is divided by 16
-	 */
-	unsigned char bypass_g;
-	/* IPIPE_GAMMA_TBL_RAM or IPIPE_GAMMA_TBL_ROM */
-	enum vpfe_ipipe_gamma_tbl_sel tbl_sel;
-	/* Table size for RAM gamma table.
-	 */
-	enum vpfe_ipipe_gamma_tbl_size tbl_size;
-	/* R table */
-	struct vpfe_ipipe_gamma_entry table_r[VPFE_IPIPE_MAX_SIZE_GAMMA];
-	/* Blue table */
-	struct vpfe_ipipe_gamma_entry table_b[VPFE_IPIPE_MAX_SIZE_GAMMA];
-	/* Green table */
-	struct vpfe_ipipe_gamma_entry table_g[VPFE_IPIPE_MAX_SIZE_GAMMA];
-};
-
-#define VPFE_IPIPE_MAX_SIZE_3D_LUT		729
-
-struct vpfe_ipipe_3d_lut_entry {
-	/* 10 bit entry for red */
-	unsigned short r;
-	/* 10 bit entry for green */
-	unsigned short g;
-	/* 10 bit entry for blue */
-	unsigned short b;
-};
-
-/* structure for 3D-LUT */
-struct vpfe_ipipe_3d_lut {
-	/* enable/disable 3D lut */
-	unsigned char en;
-	/* 3D - LUT table entry */
-	struct vpfe_ipipe_3d_lut_entry table[VPFE_IPIPE_MAX_SIZE_3D_LUT];
-};
-
-/* Struct for configuring rgb2ycbcr module */
-struct vpfe_ipipe_rgb2yuv {
-	/* Matrix coefficient for RY S12Q8 */
-	struct ipipe_float_s16 coef_ry;
-	/* Matrix coefficient for GY S12Q8 */
-	struct ipipe_float_s16 coef_gy;
-	/* Matrix coefficient for BY S12Q8 */
-	struct ipipe_float_s16 coef_by;
-	/* Matrix coefficient for RCb S12Q8 */
-	struct ipipe_float_s16 coef_rcb;
-	/* Matrix coefficient for GCb S12Q8 */
-	struct ipipe_float_s16 coef_gcb;
-	/* Matrix coefficient for BCb S12Q8 */
-	struct ipipe_float_s16 coef_bcb;
-	/* Matrix coefficient for RCr S12Q8 */
-	struct ipipe_float_s16 coef_rcr;
-	/* Matrix coefficient for GCr S12Q8 */
-	struct ipipe_float_s16 coef_gcr;
-	/* Matrix coefficient for BCr S12Q8 */
-	struct ipipe_float_s16 coef_bcr;
-	/* Output offset for R S11 */
-	int out_ofst_y;
-	/* Output offset for Cb S11 */
-	int out_ofst_cb;
-	/* Output offset for Cr S11 */
-	int out_ofst_cr;
-};
-
-enum vpfe_ipipe_gbce_type {
-	VPFE_IPIPE_GBCE_Y_VAL_TBL = 0,
-	VPFE_IPIPE_GBCE_GAIN_TBL = 1,
-};
-
-#define VPFE_IPIPE_MAX_SIZE_GBCE_LUT		1024
-
-/* structure for Global brightness and Contrast */
-struct vpfe_ipipe_gbce {
-	/* enable/disable GBCE */
-	unsigned char en;
-	/* Y - value table or Gain table */
-	enum vpfe_ipipe_gbce_type type;
-	/* ptr to LUT for GBCE with 1024 entries */
-	unsigned short table[VPFE_IPIPE_MAX_SIZE_GBCE_LUT];
-};
-
-/* Chrominance position. Applicable only for YCbCr input
- * Applied after edge enhancement
- */
-enum vpfe_chr_pos {
-	/* Co-siting, same position with luminance */
-	VPFE_IPIPE_YUV422_CHR_POS_COSITE = 0,
-	/* Centering, In the middle of luminance */
-	VPFE_IPIPE_YUV422_CHR_POS_CENTRE = 1,
-};
-
-/* Structure for configuring yuv422 conversion module */
-struct vpfe_ipipe_yuv422_conv {
-	/* Max Chrominance value */
-	unsigned char en_chrom_lpf;
-	/* 1 - enable LPF for chrminance, 0 - disable */
-	enum vpfe_chr_pos chrom_pos;
-};
-
-#define VPFE_IPIPE_MAX_SIZE_YEE_LUT		1024
-
-enum vpfe_ipipe_yee_merge_meth {
-	VPFE_IPIPE_YEE_ABS_MAX = 0,
-	VPFE_IPIPE_YEE_EE_ES = 1,
-};
-
-/* Structure for configuring YUV Edge Enhancement module */
-struct vpfe_ipipe_yee {
-	/* 1 - enable enhancement, 0 - disable */
-	unsigned char en;
-	/* enable/disable halo reduction in edge sharpner */
-	unsigned char en_halo_red;
-	/* Merge method between Edge Enhancer and Edge sharpner */
-	enum vpfe_ipipe_yee_merge_meth merge_meth;
-	/* HPF Shift length */
-	unsigned char hpf_shft;
-	/* HPF Coefficient 00, S10 */
-	short hpf_coef_00;
-	/* HPF Coefficient 01, S10 */
-	short hpf_coef_01;
-	/* HPF Coefficient 02, S10 */
-	short hpf_coef_02;
-	/* HPF Coefficient 10, S10 */
-	short hpf_coef_10;
-	/* HPF Coefficient 11, S10 */
-	short hpf_coef_11;
-	/* HPF Coefficient 12, S10 */
-	short hpf_coef_12;
-	/* HPF Coefficient 20, S10 */
-	short hpf_coef_20;
-	/* HPF Coefficient 21, S10 */
-	short hpf_coef_21;
-	/* HPF Coefficient 22, S10 */
-	short hpf_coef_22;
-	/* Lower threshold before referring to LUT */
-	unsigned short yee_thr;
-	/* Edge sharpener Gain */
-	unsigned short es_gain;
-	/* Edge sharpener lower threshold */
-	unsigned short es_thr1;
-	/* Edge sharpener upper threshold */
-	unsigned short es_thr2;
-	/* Edge sharpener gain on gradient */
-	unsigned short es_gain_grad;
-	/* Edge sharpener offset on gradient */
-	unsigned short es_ofst_grad;
-	/* Ptr to EE table. Must have 1024 entries */
-	short table[VPFE_IPIPE_MAX_SIZE_YEE_LUT];
-};
-
-enum vpfe_ipipe_car_meth {
-	/* Chromatic Gain Control */
-	VPFE_IPIPE_CAR_CHR_GAIN_CTRL = 0,
-	/* Dynamic switching between CHR_GAIN_CTRL
-	 * and MED_FLTR
-	 */
-	VPFE_IPIPE_CAR_DYN_SWITCH = 1,
-	/* Median Filter */
-	VPFE_IPIPE_CAR_MED_FLTR = 2,
-};
-
-enum vpfe_ipipe_car_hpf_type {
-	VPFE_IPIPE_CAR_HPF_Y = 0,
-	VPFE_IPIPE_CAR_HPF_H = 1,
-	VPFE_IPIPE_CAR_HPF_V = 2,
-	VPFE_IPIPE_CAR_HPF_2D = 3,
-	/* 2D HPF from YUV Edge Enhancement */
-	VPFE_IPIPE_CAR_HPF_2D_YEE = 4,
-};
-
-struct vpfe_ipipe_car_gain {
-	/* csup_gain */
-	unsigned char gain;
-	/* csup_shf. */
-	unsigned char shft;
-	/* gain minimum */
-	unsigned short gain_min;
-};
-
-/* Structure for Chromatic Artifact Reduction */
-struct vpfe_ipipe_car {
-	/* enable/disable */
-	unsigned char en;
-	/* Gain control or Dynamic switching */
-	enum vpfe_ipipe_car_meth meth;
-	/* Gain1 function configuration for Gain control */
-	struct vpfe_ipipe_car_gain gain1;
-	/* Gain2 function configuration for Gain control */
-	struct vpfe_ipipe_car_gain gain2;
-	/* HPF type used for CAR */
-	enum vpfe_ipipe_car_hpf_type hpf;
-	/* csup_thr: HPF threshold for Gain control */
-	unsigned char hpf_thr;
-	/* Down shift value for hpf. 2 bits */
-	unsigned char hpf_shft;
-	/* switch limit for median filter */
-	unsigned char sw0;
-	/* switch coefficient for Gain control */
-	unsigned char sw1;
-};
-
-/* structure for Chromatic Gain Suppression */
-struct vpfe_ipipe_cgs {
-	/* enable/disable */
-	unsigned char en;
-	/* gain1 bright side threshold */
-	unsigned char h_thr;
-	/* gain1 bright side slope */
-	unsigned char h_slope;
-	/* gain1 down shift value for bright side */
-	unsigned char h_shft;
-	/* gain1 bright side minimum gain */
-	unsigned char h_min;
-};
-
-/* Max pixels allowed in the input. If above this either decimation
- * or frame division mode to be enabled
- */
-#define VPFE_IPIPE_MAX_INPUT_WIDTH	2600
-
-struct vpfe_ipipe_input_config {
-	unsigned int vst;
-	unsigned int hst;
-};
-
-/**
- * struct vpfe_ipipe_config - IPIPE engine configuration (user)
- * @input_config: Pointer to structure for ipipe configuration.
- * @flag: Specifies which ISP IPIPE functions should be enabled.
- * @lutdpc: Pointer to luma enhancement structure.
- * @otfdpc: Pointer to structure for defect correction.
- * @nf1: Pointer to structure for Noise Filter.
- * @nf2: Pointer to structure for Noise Filter.
- * @gic: Pointer to structure for Green Imbalance.
- * @wbal: Pointer to structure for White Balance.
- * @cfa: Pointer to structure containing the CFA interpolation.
- * @rgb2rgb1: Pointer to structure for RGB to RGB Blending.
- * @rgb2rgb2: Pointer to structure for RGB to RGB Blending.
- * @gamma: Pointer to gamma structure.
- * @lut: Pointer to structure for 3D LUT.
- * @rgb2yuv: Pointer to structure for RGB-YCbCr conversion.
- * @gbce: Pointer to structure for Global Brightness,Contrast Control.
- * @yuv422_conv: Pointer to structure for YUV 422 conversion.
- * @yee: Pointer to structure for Edge Enhancer.
- * @car: Pointer to structure for Chromatic Artifact Reduction.
- * @cgs: Pointer to structure for Chromatic Gain Suppression.
- */
-struct vpfe_ipipe_config {
-	__u32 flag;
-	struct vpfe_ipipe_input_config __user *input_config;
-	struct vpfe_ipipe_lutdpc __user *lutdpc;
-	struct vpfe_ipipe_otfdpc __user *otfdpc;
-	struct vpfe_ipipe_nf __user *nf1;
-	struct vpfe_ipipe_nf __user *nf2;
-	struct vpfe_ipipe_gic __user *gic;
-	struct vpfe_ipipe_wb __user *wbal;
-	struct vpfe_ipipe_cfa __user *cfa;
-	struct vpfe_ipipe_rgb2rgb __user *rgb2rgb1;
-	struct vpfe_ipipe_rgb2rgb __user *rgb2rgb2;
-	struct vpfe_ipipe_gamma __user *gamma;
-	struct vpfe_ipipe_3d_lut __user *lut;
-	struct vpfe_ipipe_rgb2yuv __user *rgb2yuv;
-	struct vpfe_ipipe_gbce __user *gbce;
-	struct vpfe_ipipe_yuv422_conv __user *yuv422_conv;
-	struct vpfe_ipipe_yee __user *yee;
-	struct vpfe_ipipe_car __user *car;
-	struct vpfe_ipipe_cgs __user *cgs;
-};
-
-/*******************************************************************
- **  Resizer API structures
- *******************************************************************/
-/* Interpolation types used for horizontal rescale */
-enum vpfe_rsz_intp_t {
-	VPFE_RSZ_INTP_CUBIC,
-	VPFE_RSZ_INTP_LINEAR
-};
-
-/* Horizontal LPF intensity selection */
-enum vpfe_rsz_h_lpf_lse_t {
-	VPFE_RSZ_H_LPF_LSE_INTERN,
-	VPFE_RSZ_H_LPF_LSE_USER_VAL
-};
-
-enum vpfe_rsz_down_scale_ave_sz {
-	VPFE_IPIPE_DWN_SCALE_1_OVER_2,
-	VPFE_IPIPE_DWN_SCALE_1_OVER_4,
-	VPFE_IPIPE_DWN_SCALE_1_OVER_8,
-	VPFE_IPIPE_DWN_SCALE_1_OVER_16,
-	VPFE_IPIPE_DWN_SCALE_1_OVER_32,
-	VPFE_IPIPE_DWN_SCALE_1_OVER_64,
-	VPFE_IPIPE_DWN_SCALE_1_OVER_128,
-	VPFE_IPIPE_DWN_SCALE_1_OVER_256
-};
-
-struct vpfe_rsz_output_spec {
-	/* enable horizontal flip */
-	unsigned char h_flip;
-	/* enable vertical flip */
-	unsigned char v_flip;
-	/* line start offset for y. */
-	unsigned int vst_y;
-	/* line start offset for c. Only for 420 */
-	unsigned int vst_c;
-	/* vertical rescale interpolation type, YCbCr or Luminance */
-	enum vpfe_rsz_intp_t v_typ_y;
-	/* vertical rescale interpolation type for Chrominance */
-	enum vpfe_rsz_intp_t v_typ_c;
-	/* vertical lpf intensity - Luminance */
-	unsigned char v_lpf_int_y;
-	/* vertical lpf intensity - Chrominance */
-	unsigned char v_lpf_int_c;
-	/* horizontal rescale interpolation types, YCbCr or Luminance  */
-	enum vpfe_rsz_intp_t h_typ_y;
-	/* horizontal rescale interpolation types, Chrominance */
-	enum vpfe_rsz_intp_t h_typ_c;
-	/* horizontal lpf intensity - Luminance */
-	unsigned char h_lpf_int_y;
-	/* horizontal lpf intensity - Chrominance */
-	unsigned char h_lpf_int_c;
-	/* Use down scale mode for scale down */
-	unsigned char en_down_scale;
-	/* if downscale, set the downscale more average size for horizontal
-	 * direction. Used only if output width and height is less than
-	 * input sizes
-	 */
-	enum vpfe_rsz_down_scale_ave_sz h_dscale_ave_sz;
-	/* if downscale, set the downscale more average size for vertical
-	 * direction. Used only if output width and height is less than
-	 * input sizes
-	 */
-	enum vpfe_rsz_down_scale_ave_sz v_dscale_ave_sz;
-	/* Y offset. If set, the offset would be added to the base address
-	 */
-	unsigned int user_y_ofst;
-	/* C offset. If set, the offset would be added to the base address
-	 */
-	unsigned int user_c_ofst;
-};
-
-struct vpfe_rsz_config_params {
-	unsigned int vst;
-	/* horizontal start position of the image
-	 * data to IPIPE
-	 */
-	unsigned int hst;
-	/* output spec of the image data coming out of resizer - 0(UYVY).
-	 */
-	struct vpfe_rsz_output_spec output1;
-	/* output spec of the image data coming out of resizer - 1(UYVY).
-	 */
-	struct vpfe_rsz_output_spec output2;
-	/* 0 , chroma sample at odd pixel, 1 - even pixel */
-	unsigned char chroma_sample_even;
-	unsigned char frame_div_mode_en;
-	unsigned char yuv_y_min;
-	unsigned char yuv_y_max;
-	unsigned char yuv_c_min;
-	unsigned char yuv_c_max;
-	enum vpfe_chr_pos out_chr_pos;
-	unsigned char bypass;
-};
-
-/* Structure for VIDIOC_VPFE_RSZ_[S/G]_CONFIG IOCTLs */
-struct vpfe_rsz_config {
-	struct vpfe_rsz_config_params *config;
-};
-
-#endif		/* _DAVINCI_VPFE_USER_H */
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
deleted file mode 100644
index 52397ad..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ /dev/null
@@ -1,1852 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- *
- *
- * IPIPE allows fine tuning of the input image using different
- * tuning modules in IPIPE. Some examples :- Noise filter, Defect
- * pixel correction etc. It essentially operate on Bayer Raw data
- * or YUV raw data. To do image tuning, application call,
- *
- */
-
-#include <linux/slab.h>
-#include <linux/bitops.h>
-
-#include "dm365_ipipe.h"
-#include "dm365_ipipe_hw.h"
-#include "vpfe_mc_capture.h"
-
-#define MIN_OUT_WIDTH	32
-#define MIN_OUT_HEIGHT	32
-
-/* ipipe input format's */
-static const unsigned int ipipe_input_fmts[] = {
-	MEDIA_BUS_FMT_UYVY8_2X8,
-	MEDIA_BUS_FMT_SGRBG12_1X12,
-	MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
-	MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
-};
-
-/* ipipe output format's */
-static const unsigned int ipipe_output_fmts[] = {
-	MEDIA_BUS_FMT_UYVY8_2X8,
-};
-
-static int ipipe_validate_lutdpc_params(struct vpfe_ipipe_lutdpc *lutdpc)
-{
-	int i;
-
-	if (lutdpc->en > 1 || lutdpc->repl_white > 1 ||
-	    lutdpc->dpc_size > LUT_DPC_MAX_SIZE)
-		return -EINVAL;
-
-	if (lutdpc->en)
-		return -EINVAL;
-
-	for (i = 0; i < lutdpc->dpc_size; i++)
-		if (lutdpc->table[i].horz_pos > LUT_DPC_H_POS_MASK ||
-		    lutdpc->table[i].vert_pos > LUT_DPC_V_POS_MASK)
-			return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_lutdpc_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_lutdpc *lutdpc = &ipipe->config.lutdpc;
-	struct vpfe_ipipe_lutdpc *dpc_param;
-
-	if (!param) {
-		memset((void *)lutdpc, 0, sizeof(struct vpfe_ipipe_lutdpc));
-		goto success;
-	}
-
-	dpc_param = param;
-	lutdpc->en = dpc_param->en;
-	lutdpc->repl_white = dpc_param->repl_white;
-	lutdpc->dpc_size = dpc_param->dpc_size;
-	memcpy(&lutdpc->table, &dpc_param->table,
-	       (dpc_param->dpc_size * sizeof(struct vpfe_ipipe_lutdpc_entry)));
-	if (ipipe_validate_lutdpc_params(lutdpc) < 0)
-		return -EINVAL;
-
-success:
-	ipipe_set_lutdpc_regs(ipipe->base_addr, ipipe->isp5_base_addr, lutdpc);
-
-	return 0;
-}
-
-static int ipipe_get_lutdpc_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_lutdpc *lut_param = param;
-	struct vpfe_ipipe_lutdpc *lutdpc = &ipipe->config.lutdpc;
-
-	lut_param->en = lutdpc->en;
-	lut_param->repl_white = lutdpc->repl_white;
-	lut_param->dpc_size = lutdpc->dpc_size;
-	memcpy(&lut_param->table, &lutdpc->table,
-	       (lutdpc->dpc_size * sizeof(struct vpfe_ipipe_lutdpc_entry)));
-
-	return 0;
-}
-
-static int ipipe_set_input_config(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_input_config *config = &ipipe->config.input_config;
-
-	if (!param)
-		memset(config, 0, sizeof(struct vpfe_ipipe_input_config));
-	else
-		memcpy(config, param, sizeof(struct vpfe_ipipe_input_config));
-	return 0;
-}
-
-static int ipipe_get_input_config(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_input_config *config = &ipipe->config.input_config;
-
-	if (!param)
-		return -EINVAL;
-
-	memcpy(param, config, sizeof(struct vpfe_ipipe_input_config));
-
-	return 0;
-}
-
-static int ipipe_validate_otfdpc_params(struct vpfe_ipipe_otfdpc *dpc_param)
-{
-	struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_2_0;
-	struct vpfe_ipipe_otfdpc_3_0_cfg *dpc_3_0;
-
-	if (dpc_param->en > 1)
-		return -EINVAL;
-
-	if (dpc_param->alg == VPFE_IPIPE_OTFDPC_2_0) {
-		dpc_2_0 = &dpc_param->alg_cfg.dpc_2_0;
-		if (dpc_2_0->det_thr.r > OTFDPC_DPC2_THR_MASK ||
-		    dpc_2_0->det_thr.gr > OTFDPC_DPC2_THR_MASK ||
-		    dpc_2_0->det_thr.gb > OTFDPC_DPC2_THR_MASK ||
-		    dpc_2_0->det_thr.b > OTFDPC_DPC2_THR_MASK ||
-		    dpc_2_0->corr_thr.r > OTFDPC_DPC2_THR_MASK ||
-		    dpc_2_0->corr_thr.gr > OTFDPC_DPC2_THR_MASK ||
-		    dpc_2_0->corr_thr.gb > OTFDPC_DPC2_THR_MASK ||
-		    dpc_2_0->corr_thr.b > OTFDPC_DPC2_THR_MASK)
-			return -EINVAL;
-		return 0;
-	}
-
-	dpc_3_0 = &dpc_param->alg_cfg.dpc_3_0;
-
-	if (dpc_3_0->act_adj_shf > OTF_DPC3_0_SHF_MASK ||
-	    dpc_3_0->det_thr > OTF_DPC3_0_DET_MASK ||
-	    dpc_3_0->det_slp > OTF_DPC3_0_SLP_MASK ||
-	    dpc_3_0->det_thr_min > OTF_DPC3_0_DET_MASK ||
-	    dpc_3_0->det_thr_max > OTF_DPC3_0_DET_MASK ||
-	    dpc_3_0->corr_thr > OTF_DPC3_0_CORR_MASK ||
-	    dpc_3_0->corr_slp > OTF_DPC3_0_SLP_MASK ||
-	    dpc_3_0->corr_thr_min > OTF_DPC3_0_CORR_MASK ||
-	    dpc_3_0->corr_thr_max > OTF_DPC3_0_CORR_MASK)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_otfdpc_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_otfdpc *dpc_param = param;
-	struct vpfe_ipipe_otfdpc *otfdpc = &ipipe->config.otfdpc;
-	struct device *dev;
-
-	if (!param) {
-		memset((void *)otfdpc, 0, sizeof(struct ipipe_otfdpc_2_0));
-		goto success;
-	}
-	dev = ipipe->subdev.v4l2_dev->dev;
-	memcpy(otfdpc, dpc_param, sizeof(struct vpfe_ipipe_otfdpc));
-	if (ipipe_validate_otfdpc_params(otfdpc) < 0) {
-		dev_err(dev, "Invalid otfdpc params\n");
-		return -EINVAL;
-	}
-
-success:
-	ipipe_set_otfdpc_regs(ipipe->base_addr, otfdpc);
-
-	return 0;
-}
-
-static int ipipe_get_otfdpc_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_otfdpc *dpc_param = param;
-	struct vpfe_ipipe_otfdpc *otfdpc = &ipipe->config.otfdpc;
-
-	memcpy(dpc_param, otfdpc, sizeof(struct vpfe_ipipe_otfdpc));
-	return 0;
-}
-
-static int ipipe_validate_nf_params(struct vpfe_ipipe_nf *nf_param)
-{
-	int i;
-
-	if (nf_param->en > 1 || nf_param->shft_val > D2F_SHFT_VAL_MASK ||
-	    nf_param->spread_val > D2F_SPR_VAL_MASK ||
-	    nf_param->apply_lsc_gain > 1 ||
-	    nf_param->edge_det_min_thr > D2F_EDGE_DET_THR_MASK ||
-	    nf_param->edge_det_max_thr > D2F_EDGE_DET_THR_MASK)
-		return -EINVAL;
-
-	for (i = 0; i < VPFE_IPIPE_NF_THR_TABLE_SIZE; i++)
-		if (nf_param->thr[i] > D2F_THR_VAL_MASK)
-			return -EINVAL;
-
-	for (i = 0; i < VPFE_IPIPE_NF_STR_TABLE_SIZE; i++)
-		if (nf_param->str[i] > D2F_STR_VAL_MASK)
-			return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_nf_params(struct vpfe_ipipe_device *ipipe,
-			       unsigned int id, void *param)
-{
-	struct vpfe_ipipe_nf *nf_param = param;
-	struct vpfe_ipipe_nf *nf = &ipipe->config.nf1;
-	struct device *dev;
-
-	if (id == IPIPE_D2F_2ND)
-		nf = &ipipe->config.nf2;
-
-	if (!nf_param) {
-		memset((void *)nf, 0, sizeof(struct vpfe_ipipe_nf));
-		goto success;
-	}
-
-	dev = ipipe->subdev.v4l2_dev->dev;
-	memcpy(nf, nf_param, sizeof(struct vpfe_ipipe_nf));
-	if (ipipe_validate_nf_params(nf) < 0) {
-		dev_err(dev, "Invalid nf params\n");
-		return -EINVAL;
-	}
-
-success:
-	ipipe_set_d2f_regs(ipipe->base_addr, id, nf);
-
-	return 0;
-}
-
-static int ipipe_set_nf1_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	return ipipe_set_nf_params(ipipe, IPIPE_D2F_1ST, param);
-}
-
-static int ipipe_set_nf2_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	return ipipe_set_nf_params(ipipe, IPIPE_D2F_2ND, param);
-}
-
-static int ipipe_get_nf_params(struct vpfe_ipipe_device *ipipe,
-			       unsigned int id, void *param)
-{
-	struct vpfe_ipipe_nf *nf_param = param;
-	struct vpfe_ipipe_nf *nf = &ipipe->config.nf1;
-
-	if (id == IPIPE_D2F_2ND)
-		nf = &ipipe->config.nf2;
-
-	memcpy(nf_param, nf, sizeof(struct vpfe_ipipe_nf));
-
-	return 0;
-}
-
-static int ipipe_get_nf1_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	return ipipe_get_nf_params(ipipe, IPIPE_D2F_1ST, param);
-}
-
-static int ipipe_get_nf2_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	return ipipe_get_nf_params(ipipe, IPIPE_D2F_2ND, param);
-}
-
-static int ipipe_validate_gic_params(struct vpfe_ipipe_gic *gic)
-{
-	if (gic->en > 1 || gic->gain > GIC_GAIN_MASK ||
-	    gic->thr > GIC_THR_MASK || gic->slope > GIC_SLOPE_MASK ||
-	    gic->apply_lsc_gain > 1 ||
-	    gic->nf2_thr_gain.integer > GIC_NFGAN_INT_MASK ||
-	    gic->nf2_thr_gain.decimal > GIC_NFGAN_DECI_MASK)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_gic_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_gic *gic_param = param;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-	struct vpfe_ipipe_gic *gic = &ipipe->config.gic;
-
-	if (!gic_param) {
-		memset((void *)gic, 0, sizeof(struct vpfe_ipipe_gic));
-		goto success;
-	}
-
-	memcpy(gic, gic_param, sizeof(struct vpfe_ipipe_gic));
-	if (ipipe_validate_gic_params(gic) < 0) {
-		dev_err(dev, "Invalid gic params\n");
-		return -EINVAL;
-	}
-
-success:
-	ipipe_set_gic_regs(ipipe->base_addr, gic);
-
-	return 0;
-}
-
-static int ipipe_get_gic_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_gic *gic_param = param;
-	struct vpfe_ipipe_gic *gic = &ipipe->config.gic;
-
-	memcpy(gic_param, gic, sizeof(struct vpfe_ipipe_gic));
-
-	return 0;
-}
-
-static int ipipe_validate_wb_params(struct vpfe_ipipe_wb *wbal)
-{
-	if (wbal->ofst_r > WB_OFFSET_MASK ||
-	    wbal->ofst_gr > WB_OFFSET_MASK ||
-	    wbal->ofst_gb > WB_OFFSET_MASK ||
-	    wbal->ofst_b > WB_OFFSET_MASK ||
-	    wbal->gain_r.integer > WB_GAIN_INT_MASK ||
-	    wbal->gain_r.decimal > WB_GAIN_DECI_MASK ||
-	    wbal->gain_gr.integer > WB_GAIN_INT_MASK ||
-	    wbal->gain_gr.decimal > WB_GAIN_DECI_MASK ||
-	    wbal->gain_gb.integer > WB_GAIN_INT_MASK ||
-	    wbal->gain_gb.decimal > WB_GAIN_DECI_MASK ||
-	    wbal->gain_b.integer > WB_GAIN_INT_MASK ||
-	    wbal->gain_b.decimal > WB_GAIN_DECI_MASK)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_wb_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_wb *wb_param = param;
-	struct vpfe_ipipe_wb *wbal = &ipipe->config.wbal;
-
-	if (!wb_param) {
-		const struct vpfe_ipipe_wb wb_defaults = {
-			.gain_r  = {2, 0x0},
-			.gain_gr = {2, 0x0},
-			.gain_gb = {2, 0x0},
-			.gain_b  = {2, 0x0}
-		};
-		memcpy(wbal, &wb_defaults, sizeof(struct vpfe_ipipe_wb));
-		goto success;
-	}
-
-	memcpy(wbal, wb_param, sizeof(struct vpfe_ipipe_wb));
-	if (ipipe_validate_wb_params(wbal) < 0)
-		return -EINVAL;
-
-success:
-	ipipe_set_wb_regs(ipipe->base_addr, wbal);
-
-	return 0;
-}
-
-static int ipipe_get_wb_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_wb *wb_param = param;
-	struct vpfe_ipipe_wb *wbal = &ipipe->config.wbal;
-
-	memcpy(wb_param, wbal, sizeof(struct vpfe_ipipe_wb));
-	return 0;
-}
-
-static int ipipe_validate_cfa_params(struct vpfe_ipipe_cfa *cfa)
-{
-	if (cfa->hpf_thr_2dir > CFA_HPF_THR_2DIR_MASK ||
-	    cfa->hpf_slp_2dir > CFA_HPF_SLOPE_2DIR_MASK ||
-	    cfa->hp_mix_thr_2dir > CFA_HPF_MIX_THR_2DIR_MASK ||
-	    cfa->hp_mix_slope_2dir > CFA_HPF_MIX_SLP_2DIR_MASK ||
-	    cfa->dir_thr_2dir > CFA_DIR_THR_2DIR_MASK ||
-	    cfa->dir_slope_2dir > CFA_DIR_SLP_2DIR_MASK ||
-	    cfa->nd_wt_2dir > CFA_ND_WT_2DIR_MASK ||
-	    cfa->hue_fract_daa > CFA_DAA_HUE_FRA_MASK ||
-	    cfa->edge_thr_daa > CFA_DAA_EDG_THR_MASK ||
-	    cfa->thr_min_daa > CFA_DAA_THR_MIN_MASK ||
-	    cfa->thr_slope_daa > CFA_DAA_THR_SLP_MASK ||
-	    cfa->slope_min_daa > CFA_DAA_SLP_MIN_MASK ||
-	    cfa->slope_slope_daa > CFA_DAA_SLP_SLP_MASK ||
-	    cfa->lp_wt_daa > CFA_DAA_LP_WT_MASK)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_cfa_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_cfa *cfa_param = param;
-	struct vpfe_ipipe_cfa *cfa = &ipipe->config.cfa;
-
-	if (!cfa_param) {
-		memset(cfa, 0, sizeof(struct vpfe_ipipe_cfa));
-		cfa->alg = VPFE_IPIPE_CFA_ALG_2DIRAC;
-		goto success;
-	}
-
-	memcpy(cfa, cfa_param, sizeof(struct vpfe_ipipe_cfa));
-	if (ipipe_validate_cfa_params(cfa) < 0)
-		return -EINVAL;
-
-success:
-	ipipe_set_cfa_regs(ipipe->base_addr, cfa);
-
-	return 0;
-}
-
-static int ipipe_get_cfa_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_cfa *cfa_param = param;
-	struct vpfe_ipipe_cfa *cfa = &ipipe->config.cfa;
-
-	memcpy(cfa_param, cfa, sizeof(struct vpfe_ipipe_cfa));
-	return 0;
-}
-
-static int
-ipipe_validate_rgb2rgb_params(struct vpfe_ipipe_rgb2rgb *rgb2rgb,
-			      unsigned int id)
-{
-	u32 gain_int_upper = RGB2RGB_1_GAIN_INT_MASK;
-	u32 offset_upper = RGB2RGB_1_OFST_MASK;
-
-	if (id == IPIPE_RGB2RGB_2) {
-		offset_upper = RGB2RGB_2_OFST_MASK;
-		gain_int_upper = RGB2RGB_2_GAIN_INT_MASK;
-	}
-
-	if (rgb2rgb->coef_rr.decimal > RGB2RGB_GAIN_DECI_MASK ||
-	    rgb2rgb->coef_rr.integer > gain_int_upper)
-		return -EINVAL;
-
-	if (rgb2rgb->coef_gr.decimal > RGB2RGB_GAIN_DECI_MASK ||
-	    rgb2rgb->coef_gr.integer > gain_int_upper)
-		return -EINVAL;
-
-	if (rgb2rgb->coef_br.decimal > RGB2RGB_GAIN_DECI_MASK ||
-	    rgb2rgb->coef_br.integer > gain_int_upper)
-		return -EINVAL;
-
-	if (rgb2rgb->coef_rg.decimal > RGB2RGB_GAIN_DECI_MASK ||
-	    rgb2rgb->coef_rg.integer > gain_int_upper)
-		return -EINVAL;
-
-	if (rgb2rgb->coef_gg.decimal > RGB2RGB_GAIN_DECI_MASK ||
-	    rgb2rgb->coef_gg.integer > gain_int_upper)
-		return -EINVAL;
-
-	if (rgb2rgb->coef_bg.decimal > RGB2RGB_GAIN_DECI_MASK ||
-	    rgb2rgb->coef_bg.integer > gain_int_upper)
-		return -EINVAL;
-
-	if (rgb2rgb->coef_rb.decimal > RGB2RGB_GAIN_DECI_MASK ||
-	    rgb2rgb->coef_rb.integer > gain_int_upper)
-		return -EINVAL;
-
-	if (rgb2rgb->coef_gb.decimal > RGB2RGB_GAIN_DECI_MASK ||
-	    rgb2rgb->coef_gb.integer > gain_int_upper)
-		return -EINVAL;
-
-	if (rgb2rgb->coef_bb.decimal > RGB2RGB_GAIN_DECI_MASK ||
-	    rgb2rgb->coef_bb.integer > gain_int_upper)
-		return -EINVAL;
-
-	if (rgb2rgb->out_ofst_r > offset_upper ||
-	    rgb2rgb->out_ofst_g > offset_upper ||
-	    rgb2rgb->out_ofst_b > offset_upper)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_rgb2rgb_params(struct vpfe_ipipe_device *ipipe,
-				    unsigned int id, void *param)
-{
-	struct vpfe_ipipe_rgb2rgb *rgb2rgb = &ipipe->config.rgb2rgb1;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-	struct vpfe_ipipe_rgb2rgb *rgb2rgb_param;
-
-	rgb2rgb_param = param;
-
-	if (id == IPIPE_RGB2RGB_2)
-		rgb2rgb = &ipipe->config.rgb2rgb2;
-
-	if (!rgb2rgb_param) {
-		const struct vpfe_ipipe_rgb2rgb rgb2rgb_defaults = {
-			.coef_rr = {1, 0},	/* 256 */
-			.coef_gr = {0, 0},
-			.coef_br = {0, 0},
-			.coef_rg = {0, 0},
-			.coef_gg = {1, 0},	/* 256 */
-			.coef_bg = {0, 0},
-			.coef_rb = {0, 0},
-			.coef_gb = {0, 0},
-			.coef_bb = {1, 0},	/* 256 */
-		};
-		/* Copy defaults for rgb2rgb conversion */
-		memcpy(rgb2rgb, &rgb2rgb_defaults,
-		       sizeof(struct vpfe_ipipe_rgb2rgb));
-		goto success;
-	}
-
-	memcpy(rgb2rgb, rgb2rgb_param, sizeof(struct vpfe_ipipe_rgb2rgb));
-	if (ipipe_validate_rgb2rgb_params(rgb2rgb, id) < 0) {
-		dev_err(dev, "Invalid rgb2rgb params\n");
-		return -EINVAL;
-	}
-
-success:
-	ipipe_set_rgb2rgb_regs(ipipe->base_addr, id, rgb2rgb);
-
-	return 0;
-}
-
-static int
-ipipe_set_rgb2rgb_1_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	return ipipe_set_rgb2rgb_params(ipipe, IPIPE_RGB2RGB_1, param);
-}
-
-static int
-ipipe_set_rgb2rgb_2_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	return ipipe_set_rgb2rgb_params(ipipe, IPIPE_RGB2RGB_2, param);
-}
-
-static int ipipe_get_rgb2rgb_params(struct vpfe_ipipe_device *ipipe,
-				    unsigned int id, void *param)
-{
-	struct vpfe_ipipe_rgb2rgb *rgb2rgb = &ipipe->config.rgb2rgb1;
-	struct vpfe_ipipe_rgb2rgb *rgb2rgb_param;
-
-	rgb2rgb_param = param;
-
-	if (id == IPIPE_RGB2RGB_2)
-		rgb2rgb = &ipipe->config.rgb2rgb2;
-
-	memcpy(rgb2rgb_param, rgb2rgb, sizeof(struct vpfe_ipipe_rgb2rgb));
-
-	return 0;
-}
-
-static int
-ipipe_get_rgb2rgb_1_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	return ipipe_get_rgb2rgb_params(ipipe, IPIPE_RGB2RGB_1, param);
-}
-
-static int
-ipipe_get_rgb2rgb_2_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	return ipipe_get_rgb2rgb_params(ipipe, IPIPE_RGB2RGB_2, param);
-}
-
-static int
-ipipe_validate_gamma_entry(struct vpfe_ipipe_gamma_entry *table, int size)
-{
-	int i;
-
-	if (!table)
-		return -EINVAL;
-
-	for (i = 0; i < size; i++)
-		if (table[i].slope > GAMMA_MASK ||
-		    table[i].offset > GAMMA_MASK)
-			return -EINVAL;
-
-	return 0;
-}
-
-static int
-ipipe_validate_gamma_params(struct vpfe_ipipe_gamma *gamma, struct device *dev)
-{
-	int table_size;
-	int err;
-
-	if (gamma->bypass_r > 1 ||
-	    gamma->bypass_b > 1 ||
-	    gamma->bypass_g > 1)
-		return -EINVAL;
-
-	if (gamma->tbl_sel != VPFE_IPIPE_GAMMA_TBL_RAM)
-		return 0;
-
-	table_size = gamma->tbl_size;
-	if (!gamma->bypass_r) {
-		err = ipipe_validate_gamma_entry(gamma->table_r, table_size);
-		if (err) {
-			dev_err(dev, "GAMMA R - table entry invalid\n");
-			return err;
-		}
-	}
-
-	if (!gamma->bypass_b) {
-		err = ipipe_validate_gamma_entry(gamma->table_b, table_size);
-		if (err) {
-			dev_err(dev, "GAMMA B - table entry invalid\n");
-			return err;
-		}
-	}
-
-	if (!gamma->bypass_g) {
-		err = ipipe_validate_gamma_entry(gamma->table_g, table_size);
-		if (err) {
-			dev_err(dev, "GAMMA G - table entry invalid\n");
-			return err;
-		}
-	}
-
-	return 0;
-}
-
-static int
-ipipe_set_gamma_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_gamma *gamma_param = param;
-	struct vpfe_ipipe_gamma *gamma = &ipipe->config.gamma;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-	int table_size;
-
-	if (!gamma_param) {
-		memset(gamma, 0, sizeof(struct vpfe_ipipe_gamma));
-		gamma->tbl_sel = VPFE_IPIPE_GAMMA_TBL_ROM;
-		goto success;
-	}
-
-	gamma->bypass_r = gamma_param->bypass_r;
-	gamma->bypass_b = gamma_param->bypass_b;
-	gamma->bypass_g = gamma_param->bypass_g;
-	gamma->tbl_sel = gamma_param->tbl_sel;
-	gamma->tbl_size = gamma_param->tbl_size;
-
-	if (ipipe_validate_gamma_params(gamma, dev) < 0)
-		return -EINVAL;
-
-	if (gamma_param->tbl_sel != VPFE_IPIPE_GAMMA_TBL_RAM)
-		goto success;
-
-	table_size = gamma->tbl_size;
-	if (!gamma_param->bypass_r)
-		memcpy(&gamma->table_r, &gamma_param->table_r,
-		       (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
-
-	if (!gamma_param->bypass_b)
-		memcpy(&gamma->table_b, &gamma_param->table_b,
-		       (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
-
-	if (!gamma_param->bypass_g)
-		memcpy(&gamma->table_g, &gamma_param->table_g,
-		       (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
-
-success:
-	ipipe_set_gamma_regs(ipipe->base_addr, ipipe->isp5_base_addr, gamma);
-
-	return 0;
-}
-
-static int ipipe_get_gamma_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_gamma *gamma_param = param;
-	struct vpfe_ipipe_gamma *gamma = &ipipe->config.gamma;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-	int table_size;
-
-	gamma_param->bypass_r = gamma->bypass_r;
-	gamma_param->bypass_g = gamma->bypass_g;
-	gamma_param->bypass_b = gamma->bypass_b;
-	gamma_param->tbl_sel = gamma->tbl_sel;
-	gamma_param->tbl_size = gamma->tbl_size;
-
-	if (gamma->tbl_sel != VPFE_IPIPE_GAMMA_TBL_RAM)
-		return 0;
-
-	table_size = gamma->tbl_size;
-
-	if (!gamma->bypass_r) {
-		dev_err(dev,
-			"%s: table ptr empty for R\n", __func__);
-		return -EINVAL;
-	}
-	memcpy(gamma_param->table_r, gamma->table_r,
-	       (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
-
-	if (!gamma->bypass_g) {
-		dev_err(dev, "%s: table ptr empty for G\n", __func__);
-		return -EINVAL;
-	}
-	memcpy(gamma_param->table_g, gamma->table_g,
-	       (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
-
-	if (!gamma->bypass_b) {
-		dev_err(dev, "%s: table ptr empty for B\n", __func__);
-		return -EINVAL;
-	}
-	memcpy(gamma_param->table_b, gamma->table_b,
-	       (table_size * sizeof(struct vpfe_ipipe_gamma_entry)));
-
-	return 0;
-}
-
-static int ipipe_validate_3d_lut_params(struct vpfe_ipipe_3d_lut *lut)
-{
-	int i;
-
-	if (!lut->en)
-		return 0;
-
-	for (i = 0; i < VPFE_IPIPE_MAX_SIZE_3D_LUT; i++)
-		if (lut->table[i].r > D3_LUT_ENTRY_MASK ||
-		    lut->table[i].g > D3_LUT_ENTRY_MASK ||
-		    lut->table[i].b > D3_LUT_ENTRY_MASK)
-			return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_get_3d_lut_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_3d_lut *lut_param = param;
-	struct vpfe_ipipe_3d_lut *lut = &ipipe->config.lut;
-
-	lut_param->en = lut->en;
-
-	memcpy(lut_param->table, &lut->table,
-	       (VPFE_IPIPE_MAX_SIZE_3D_LUT *
-	       sizeof(struct vpfe_ipipe_3d_lut_entry)));
-
-	return 0;
-}
-
-static int
-ipipe_set_3d_lut_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_3d_lut *lut_param = param;
-	struct vpfe_ipipe_3d_lut *lut = &ipipe->config.lut;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-
-	if (!lut_param) {
-		memset(lut, 0, sizeof(struct vpfe_ipipe_3d_lut));
-		goto success;
-	}
-
-	memcpy(lut, lut_param, sizeof(struct vpfe_ipipe_3d_lut));
-	if (ipipe_validate_3d_lut_params(lut) < 0) {
-		dev_err(dev, "Invalid 3D-LUT Params\n");
-		return -EINVAL;
-	}
-
-success:
-	ipipe_set_3d_lut_regs(ipipe->base_addr, ipipe->isp5_base_addr, lut);
-
-	return 0;
-}
-
-static int ipipe_validate_rgb2yuv_params(struct vpfe_ipipe_rgb2yuv *rgb2yuv)
-{
-	if (rgb2yuv->coef_ry.decimal > RGB2YCBCR_COEF_DECI_MASK ||
-	    rgb2yuv->coef_ry.integer > RGB2YCBCR_COEF_INT_MASK)
-		return -EINVAL;
-
-	if (rgb2yuv->coef_gy.decimal > RGB2YCBCR_COEF_DECI_MASK ||
-	    rgb2yuv->coef_gy.integer > RGB2YCBCR_COEF_INT_MASK)
-		return -EINVAL;
-
-	if (rgb2yuv->coef_by.decimal > RGB2YCBCR_COEF_DECI_MASK ||
-	    rgb2yuv->coef_by.integer > RGB2YCBCR_COEF_INT_MASK)
-		return -EINVAL;
-
-	if (rgb2yuv->coef_rcb.decimal > RGB2YCBCR_COEF_DECI_MASK ||
-	    rgb2yuv->coef_rcb.integer > RGB2YCBCR_COEF_INT_MASK)
-		return -EINVAL;
-
-	if (rgb2yuv->coef_gcb.decimal > RGB2YCBCR_COEF_DECI_MASK ||
-	    rgb2yuv->coef_gcb.integer > RGB2YCBCR_COEF_INT_MASK)
-		return -EINVAL;
-
-	if (rgb2yuv->coef_bcb.decimal > RGB2YCBCR_COEF_DECI_MASK ||
-	    rgb2yuv->coef_bcb.integer > RGB2YCBCR_COEF_INT_MASK)
-		return -EINVAL;
-
-	if (rgb2yuv->coef_rcr.decimal > RGB2YCBCR_COEF_DECI_MASK ||
-	    rgb2yuv->coef_rcr.integer > RGB2YCBCR_COEF_INT_MASK)
-		return -EINVAL;
-
-	if (rgb2yuv->coef_gcr.decimal > RGB2YCBCR_COEF_DECI_MASK ||
-	    rgb2yuv->coef_gcr.integer > RGB2YCBCR_COEF_INT_MASK)
-		return -EINVAL;
-
-	if (rgb2yuv->coef_bcr.decimal > RGB2YCBCR_COEF_DECI_MASK ||
-	    rgb2yuv->coef_bcr.integer > RGB2YCBCR_COEF_INT_MASK)
-		return -EINVAL;
-
-	if (rgb2yuv->out_ofst_y > RGB2YCBCR_OFST_MASK ||
-	    rgb2yuv->out_ofst_cb > RGB2YCBCR_OFST_MASK ||
-	    rgb2yuv->out_ofst_cr > RGB2YCBCR_OFST_MASK)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int
-ipipe_set_rgb2yuv_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_rgb2yuv *rgb2yuv = &ipipe->config.rgb2yuv;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-	struct vpfe_ipipe_rgb2yuv *rgb2yuv_param;
-
-	rgb2yuv_param = param;
-	if (!rgb2yuv_param) {
-		/* Defaults for rgb2yuv conversion */
-		const struct vpfe_ipipe_rgb2yuv rgb2yuv_defaults = {
-			.coef_ry  = {0, 0x4d},
-			.coef_gy  = {0, 0x96},
-			.coef_by  = {0, 0x1d},
-			.coef_rcb = {0xf, 0xd5},
-			.coef_gcb = {0xf, 0xab},
-			.coef_bcb = {0, 0x80},
-			.coef_rcr = {0, 0x80},
-			.coef_gcr = {0xf, 0x95},
-			.coef_bcr = {0xf, 0xeb},
-			.out_ofst_cb = 0x80,
-			.out_ofst_cr = 0x80,
-		};
-		/* Copy defaults for rgb2yuv conversion  */
-		memcpy(rgb2yuv, &rgb2yuv_defaults,
-		       sizeof(struct vpfe_ipipe_rgb2yuv));
-		goto success;
-	}
-
-	memcpy(rgb2yuv, rgb2yuv_param, sizeof(struct vpfe_ipipe_rgb2yuv));
-	if (ipipe_validate_rgb2yuv_params(rgb2yuv) < 0) {
-		dev_err(dev, "Invalid rgb2yuv params\n");
-		return -EINVAL;
-	}
-
-success:
-	ipipe_set_rgb2ycbcr_regs(ipipe->base_addr, rgb2yuv);
-
-	return 0;
-}
-
-static int
-ipipe_get_rgb2yuv_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_rgb2yuv *rgb2yuv = &ipipe->config.rgb2yuv;
-	struct vpfe_ipipe_rgb2yuv *rgb2yuv_param;
-
-	rgb2yuv_param = param;
-	memcpy(rgb2yuv_param, rgb2yuv, sizeof(struct vpfe_ipipe_rgb2yuv));
-	return 0;
-}
-
-static int ipipe_validate_gbce_params(struct vpfe_ipipe_gbce *gbce)
-{
-	u32 max = GBCE_Y_VAL_MASK;
-	int i;
-
-	if (!gbce->en)
-		return 0;
-
-	if (gbce->type == VPFE_IPIPE_GBCE_GAIN_TBL)
-		max = GBCE_GAIN_VAL_MASK;
-
-	for (i = 0; i < VPFE_IPIPE_MAX_SIZE_GBCE_LUT; i++)
-		if (gbce->table[i] > max)
-			return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_gbce_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_gbce *gbce_param = param;
-	struct vpfe_ipipe_gbce *gbce = &ipipe->config.gbce;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-
-	if (!gbce_param) {
-		memset(gbce, 0, sizeof(struct vpfe_ipipe_gbce));
-	} else {
-		memcpy(gbce, gbce_param, sizeof(struct vpfe_ipipe_gbce));
-		if (ipipe_validate_gbce_params(gbce) < 0) {
-			dev_err(dev, "Invalid gbce params\n");
-			return -EINVAL;
-		}
-	}
-
-	ipipe_set_gbce_regs(ipipe->base_addr, ipipe->isp5_base_addr, gbce);
-
-	return 0;
-}
-
-static int ipipe_get_gbce_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_gbce *gbce_param = param;
-	struct vpfe_ipipe_gbce *gbce = &ipipe->config.gbce;
-
-	gbce_param->en = gbce->en;
-	gbce_param->type = gbce->type;
-
-	memcpy(gbce_param->table, gbce->table,
-	       (VPFE_IPIPE_MAX_SIZE_GBCE_LUT * sizeof(unsigned short)));
-
-	return 0;
-}
-
-static int
-ipipe_validate_yuv422_conv_params(struct vpfe_ipipe_yuv422_conv *yuv422_conv)
-{
-	if (yuv422_conv->en_chrom_lpf > 1)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int
-ipipe_set_yuv422_conv_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_yuv422_conv *yuv422_conv = &ipipe->config.yuv422_conv;
-	struct vpfe_ipipe_yuv422_conv *yuv422_conv_param;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-
-	yuv422_conv_param = param;
-	if (!yuv422_conv_param) {
-		memset(yuv422_conv, 0, sizeof(struct vpfe_ipipe_yuv422_conv));
-		yuv422_conv->chrom_pos = VPFE_IPIPE_YUV422_CHR_POS_COSITE;
-	} else {
-		memcpy(yuv422_conv, yuv422_conv_param,
-		       sizeof(struct vpfe_ipipe_yuv422_conv));
-		if (ipipe_validate_yuv422_conv_params(yuv422_conv) < 0) {
-			dev_err(dev, "Invalid yuv422 params\n");
-			return -EINVAL;
-		}
-	}
-
-	ipipe_set_yuv422_conv_regs(ipipe->base_addr, yuv422_conv);
-
-	return 0;
-}
-
-static int
-ipipe_get_yuv422_conv_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_yuv422_conv *yuv422_conv = &ipipe->config.yuv422_conv;
-	struct vpfe_ipipe_yuv422_conv *yuv422_conv_param;
-
-	yuv422_conv_param = param;
-	memcpy(yuv422_conv_param, yuv422_conv,
-	       sizeof(struct vpfe_ipipe_yuv422_conv));
-
-	return 0;
-}
-
-static int ipipe_validate_yee_params(struct vpfe_ipipe_yee *yee)
-{
-	int i;
-
-	if (yee->en > 1 ||
-	    yee->en_halo_red > 1 ||
-	    yee->hpf_shft > YEE_HPF_SHIFT_MASK)
-		return -EINVAL;
-
-	if (yee->hpf_coef_00 > YEE_COEF_MASK ||
-	    yee->hpf_coef_01 > YEE_COEF_MASK ||
-	    yee->hpf_coef_02 > YEE_COEF_MASK ||
-	    yee->hpf_coef_10 > YEE_COEF_MASK ||
-	    yee->hpf_coef_11 > YEE_COEF_MASK ||
-	    yee->hpf_coef_12 > YEE_COEF_MASK ||
-	    yee->hpf_coef_20 > YEE_COEF_MASK ||
-	    yee->hpf_coef_21 > YEE_COEF_MASK ||
-	    yee->hpf_coef_22 > YEE_COEF_MASK)
-		return -EINVAL;
-
-	if (yee->yee_thr > YEE_THR_MASK ||
-	    yee->es_gain > YEE_ES_GAIN_MASK ||
-	    yee->es_thr1 > YEE_ES_THR1_MASK ||
-	    yee->es_thr2 > YEE_THR_MASK ||
-	    yee->es_gain_grad > YEE_THR_MASK ||
-	    yee->es_ofst_grad > YEE_THR_MASK)
-		return -EINVAL;
-
-	for (i = 0; i < VPFE_IPIPE_MAX_SIZE_YEE_LUT; i++)
-		if (yee->table[i] > YEE_ENTRY_MASK)
-			return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_yee_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_yee *yee_param = param;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-	struct vpfe_ipipe_yee *yee = &ipipe->config.yee;
-
-	if (!yee_param) {
-		memset(yee, 0, sizeof(struct vpfe_ipipe_yee));
-	} else {
-		memcpy(yee, yee_param, sizeof(struct vpfe_ipipe_yee));
-		if (ipipe_validate_yee_params(yee) < 0) {
-			dev_err(dev, "Invalid yee params\n");
-			return -EINVAL;
-		}
-	}
-
-	ipipe_set_ee_regs(ipipe->base_addr, ipipe->isp5_base_addr, yee);
-
-	return 0;
-}
-
-static int ipipe_get_yee_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_yee *yee_param = param;
-	struct vpfe_ipipe_yee *yee = &ipipe->config.yee;
-
-	yee_param->en = yee->en;
-	yee_param->en_halo_red = yee->en_halo_red;
-	yee_param->merge_meth = yee->merge_meth;
-	yee_param->hpf_shft = yee->hpf_shft;
-	yee_param->hpf_coef_00 = yee->hpf_coef_00;
-	yee_param->hpf_coef_01 = yee->hpf_coef_01;
-	yee_param->hpf_coef_02 = yee->hpf_coef_02;
-	yee_param->hpf_coef_10 = yee->hpf_coef_10;
-	yee_param->hpf_coef_11 = yee->hpf_coef_11;
-	yee_param->hpf_coef_12 = yee->hpf_coef_12;
-	yee_param->hpf_coef_20 = yee->hpf_coef_20;
-	yee_param->hpf_coef_21 = yee->hpf_coef_21;
-	yee_param->hpf_coef_22 = yee->hpf_coef_22;
-	yee_param->yee_thr = yee->yee_thr;
-	yee_param->es_gain = yee->es_gain;
-	yee_param->es_thr1 = yee->es_thr1;
-	yee_param->es_thr2 = yee->es_thr2;
-	yee_param->es_gain_grad = yee->es_gain_grad;
-	yee_param->es_ofst_grad = yee->es_ofst_grad;
-	memcpy(yee_param->table, &yee->table,
-	       (VPFE_IPIPE_MAX_SIZE_YEE_LUT * sizeof(short)));
-
-	return 0;
-}
-
-static int ipipe_validate_car_params(struct vpfe_ipipe_car *car)
-{
-	if (car->en > 1 || car->hpf_shft > CAR_HPF_SHIFT_MASK ||
-	    car->gain1.shft > CAR_GAIN1_SHFT_MASK ||
-	    car->gain1.gain_min > CAR_GAIN_MIN_MASK ||
-	    car->gain2.shft > CAR_GAIN2_SHFT_MASK ||
-	    car->gain2.gain_min > CAR_GAIN_MIN_MASK)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_car_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_car *car_param = param;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-	struct vpfe_ipipe_car *car = &ipipe->config.car;
-
-	if (!car_param) {
-		memset(car, 0, sizeof(struct vpfe_ipipe_car));
-	} else {
-		memcpy(car, car_param, sizeof(struct vpfe_ipipe_car));
-		if (ipipe_validate_car_params(car) < 0) {
-			dev_err(dev, "Invalid car params\n");
-			return -EINVAL;
-		}
-	}
-
-	ipipe_set_car_regs(ipipe->base_addr, car);
-
-	return 0;
-}
-
-static int ipipe_get_car_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_car *car_param = param;
-	struct vpfe_ipipe_car *car = &ipipe->config.car;
-
-	memcpy(car_param, car, sizeof(struct vpfe_ipipe_car));
-	return 0;
-}
-
-static int ipipe_validate_cgs_params(struct vpfe_ipipe_cgs *cgs)
-{
-	if (cgs->en > 1 || cgs->h_shft > CAR_SHIFT_MASK)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int ipipe_set_cgs_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_cgs *cgs_param = param;
-	struct device *dev = ipipe->subdev.v4l2_dev->dev;
-	struct vpfe_ipipe_cgs *cgs = &ipipe->config.cgs;
-
-	if (!cgs_param) {
-		memset(cgs, 0, sizeof(struct vpfe_ipipe_cgs));
-	} else {
-		memcpy(cgs, cgs_param, sizeof(struct vpfe_ipipe_cgs));
-		if (ipipe_validate_cgs_params(cgs) < 0) {
-			dev_err(dev, "Invalid cgs params\n");
-			return -EINVAL;
-		}
-	}
-
-	ipipe_set_cgs_regs(ipipe->base_addr, cgs);
-
-	return 0;
-}
-
-static int ipipe_get_cgs_params(struct vpfe_ipipe_device *ipipe, void *param)
-{
-	struct vpfe_ipipe_cgs *cgs_param = param;
-	struct vpfe_ipipe_cgs *cgs = &ipipe->config.cgs;
-
-	memcpy(cgs_param, cgs, sizeof(struct vpfe_ipipe_cgs));
-
-	return 0;
-}
-
-static const struct ipipe_module_if ipipe_modules[VPFE_IPIPE_MAX_MODULES] = {
-	/* VPFE_IPIPE_INPUT_CONFIG */ {
-		offsetof(struct ipipe_module_params, input_config),
-		FIELD_SIZEOF(struct ipipe_module_params, input_config),
-		offsetof(struct vpfe_ipipe_config, input_config),
-		ipipe_set_input_config,
-		ipipe_get_input_config,
-	}, /* VPFE_IPIPE_LUTDPC */ {
-		offsetof(struct ipipe_module_params, lutdpc),
-		FIELD_SIZEOF(struct ipipe_module_params, lutdpc),
-		offsetof(struct vpfe_ipipe_config, lutdpc),
-		ipipe_set_lutdpc_params,
-		ipipe_get_lutdpc_params,
-	}, /* VPFE_IPIPE_OTFDPC */ {
-		offsetof(struct ipipe_module_params, otfdpc),
-		FIELD_SIZEOF(struct ipipe_module_params, otfdpc),
-		offsetof(struct vpfe_ipipe_config, otfdpc),
-		ipipe_set_otfdpc_params,
-		ipipe_get_otfdpc_params,
-	}, /* VPFE_IPIPE_NF1 */ {
-		offsetof(struct ipipe_module_params, nf1),
-		FIELD_SIZEOF(struct ipipe_module_params, nf1),
-		offsetof(struct vpfe_ipipe_config, nf1),
-		ipipe_set_nf1_params,
-		ipipe_get_nf1_params,
-	}, /* VPFE_IPIPE_NF2 */ {
-		offsetof(struct ipipe_module_params, nf2),
-		FIELD_SIZEOF(struct ipipe_module_params, nf2),
-		offsetof(struct vpfe_ipipe_config, nf2),
-		ipipe_set_nf2_params,
-		ipipe_get_nf2_params,
-	}, /* VPFE_IPIPE_WB */ {
-		offsetof(struct ipipe_module_params, wbal),
-		FIELD_SIZEOF(struct ipipe_module_params, wbal),
-		offsetof(struct vpfe_ipipe_config, wbal),
-		ipipe_set_wb_params,
-		ipipe_get_wb_params,
-	}, /* VPFE_IPIPE_RGB2RGB_1 */ {
-		offsetof(struct ipipe_module_params, rgb2rgb1),
-		FIELD_SIZEOF(struct ipipe_module_params, rgb2rgb1),
-		offsetof(struct vpfe_ipipe_config, rgb2rgb1),
-		ipipe_set_rgb2rgb_1_params,
-		ipipe_get_rgb2rgb_1_params,
-	}, /* VPFE_IPIPE_RGB2RGB_2 */ {
-		offsetof(struct ipipe_module_params, rgb2rgb2),
-		FIELD_SIZEOF(struct ipipe_module_params, rgb2rgb2),
-		offsetof(struct vpfe_ipipe_config, rgb2rgb2),
-		ipipe_set_rgb2rgb_2_params,
-		ipipe_get_rgb2rgb_2_params,
-	}, /* VPFE_IPIPE_GAMMA */ {
-		offsetof(struct ipipe_module_params, gamma),
-		FIELD_SIZEOF(struct ipipe_module_params, gamma),
-		offsetof(struct vpfe_ipipe_config, gamma),
-		ipipe_set_gamma_params,
-		ipipe_get_gamma_params,
-	}, /* VPFE_IPIPE_3D_LUT */ {
-		offsetof(struct ipipe_module_params, lut),
-		FIELD_SIZEOF(struct ipipe_module_params, lut),
-		offsetof(struct vpfe_ipipe_config, lut),
-		ipipe_set_3d_lut_params,
-		ipipe_get_3d_lut_params,
-	}, /* VPFE_IPIPE_RGB2YUV */ {
-		offsetof(struct ipipe_module_params, rgb2yuv),
-		FIELD_SIZEOF(struct ipipe_module_params, rgb2yuv),
-		offsetof(struct vpfe_ipipe_config, rgb2yuv),
-		ipipe_set_rgb2yuv_params,
-		ipipe_get_rgb2yuv_params,
-	}, /* VPFE_IPIPE_YUV422_CONV */ {
-		offsetof(struct ipipe_module_params, yuv422_conv),
-		FIELD_SIZEOF(struct ipipe_module_params, yuv422_conv),
-		offsetof(struct vpfe_ipipe_config, yuv422_conv),
-		ipipe_set_yuv422_conv_params,
-		ipipe_get_yuv422_conv_params,
-	}, /* VPFE_IPIPE_YEE */ {
-		offsetof(struct ipipe_module_params, yee),
-		FIELD_SIZEOF(struct ipipe_module_params, yee),
-		offsetof(struct vpfe_ipipe_config, yee),
-		ipipe_set_yee_params,
-		ipipe_get_yee_params,
-	}, /* VPFE_IPIPE_GIC */ {
-		offsetof(struct ipipe_module_params, gic),
-		FIELD_SIZEOF(struct ipipe_module_params, gic),
-		offsetof(struct vpfe_ipipe_config, gic),
-		ipipe_set_gic_params,
-		ipipe_get_gic_params,
-	}, /* VPFE_IPIPE_CFA */ {
-		offsetof(struct ipipe_module_params, cfa),
-		FIELD_SIZEOF(struct ipipe_module_params, cfa),
-		offsetof(struct vpfe_ipipe_config, cfa),
-		ipipe_set_cfa_params,
-		ipipe_get_cfa_params,
-	}, /* VPFE_IPIPE_CAR */ {
-		offsetof(struct ipipe_module_params, car),
-		FIELD_SIZEOF(struct ipipe_module_params, car),
-		offsetof(struct vpfe_ipipe_config, car),
-		ipipe_set_car_params,
-		ipipe_get_car_params,
-	}, /* VPFE_IPIPE_CGS */ {
-		offsetof(struct ipipe_module_params, cgs),
-		FIELD_SIZEOF(struct ipipe_module_params, cgs),
-		offsetof(struct vpfe_ipipe_config, cgs),
-		ipipe_set_cgs_params,
-		ipipe_get_cgs_params,
-	}, /* VPFE_IPIPE_GBCE */ {
-		offsetof(struct ipipe_module_params, gbce),
-		FIELD_SIZEOF(struct ipipe_module_params, gbce),
-		offsetof(struct vpfe_ipipe_config, gbce),
-		ipipe_set_gbce_params,
-		ipipe_get_gbce_params,
-	},
-};
-
-static int ipipe_s_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg)
-{
-	struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
-	unsigned int i;
-	int rval = 0;
-	struct ipipe_module_params *params;
-
-	for (i = 0; i < ARRAY_SIZE(ipipe_modules); i++) {
-		const struct ipipe_module_if *module_if;
-		void *from, *to;
-		size_t size;
-
-		if (!(cfg->flag & BIT(i)))
-			continue;
-
-		module_if = &ipipe_modules[i];
-		from = *(void **)((void *)cfg + module_if->config_offset);
-
-		params = kmalloc(sizeof(*params), GFP_KERNEL);
-		if (!params)
-			return -ENOMEM;
-		to = (void *)params + module_if->param_offset;
-		size = module_if->param_size;
-
-		if (to && from && size) {
-			if (copy_from_user(to, (void __user *)from, size)) {
-				rval = -EFAULT;
-				goto error_free;
-			}
-			rval = module_if->set(ipipe, to);
-			if (rval)
-				goto error_free;
-		} else if (to && !from && size) {
-			rval = module_if->set(ipipe, NULL);
-			if (rval)
-				goto error_free;
-		}
-		kfree(params);
-	}
-	return rval;
-
-error_free:
-	kfree(params);
-	return rval;
-}
-
-static int ipipe_g_config(struct v4l2_subdev *sd, struct vpfe_ipipe_config *cfg)
-{
-	struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
-	unsigned int i;
-	int rval = 0;
-
-	for (i = 1; i < ARRAY_SIZE(ipipe_modules); i++) {
-		const struct ipipe_module_if *module_if;
-		struct ipipe_module_params *params;
-		void *from, *to;
-		size_t size;
-
-		if (!(cfg->flag & BIT(i)))
-			continue;
-
-		module_if = &ipipe_modules[i];
-		to = *(void **)((void *)cfg + module_if->config_offset);
-
-		params = kmalloc(sizeof(*params), GFP_KERNEL);
-		from = (void *)params + module_if->param_offset;
-		size = module_if->param_size;
-
-		if (to && from && size) {
-			rval = module_if->get(ipipe, from);
-			if (rval)
-				goto error;
-			if (copy_to_user((void __user *)to, from, size)) {
-				rval = -EFAULT;
-				break;
-			}
-		}
-		kfree(params);
-	}
-error:
-	return rval;
-}
-
-/*
- * ipipe_ioctl() - Handle ipipe module private ioctl's
- * @sd: pointer to v4l2 subdev structure
- * @cmd: configuration command
- * @arg: configuration argument
- */
-static long ipipe_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	switch (cmd) {
-	case VIDIOC_VPFE_IPIPE_S_CONFIG:
-		return ipipe_s_config(sd, arg);
-
-	case VIDIOC_VPFE_IPIPE_G_CONFIG:
-		return ipipe_g_config(sd, arg);
-
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-void vpfe_ipipe_enable(struct vpfe_device *vpfe_dev, int en)
-{
-	struct vpfe_ipipeif_device *ipipeif = &vpfe_dev->vpfe_ipipeif;
-	struct vpfe_ipipe_device *ipipe = &vpfe_dev->vpfe_ipipe;
-	unsigned char val;
-
-	if (ipipe->input == IPIPE_INPUT_NONE)
-		return;
-
-	/* ipipe is set to single shot */
-	if (ipipeif->input == IPIPEIF_INPUT_MEMORY && en) {
-		/* for single-shot mode, need to wait for h/w to
-		 * reset many register bits
-		 */
-		do {
-			val = regr_ip(vpfe_dev->vpfe_ipipe.base_addr,
-				      IPIPE_SRC_EN);
-		} while (val);
-	}
-	regw_ip(vpfe_dev->vpfe_ipipe.base_addr, en, IPIPE_SRC_EN);
-}
-
-/*
- * ipipe_set_stream() - Enable/Disable streaming on the ipipe subdevice
- * @sd: pointer to v4l2 subdev structure
- * @enable: 1 == Enable, 0 == Disable
- */
-static int ipipe_set_stream(struct v4l2_subdev *sd, int enable)
-{
-	struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
-	struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe);
-
-	if (enable && ipipe->input != IPIPE_INPUT_NONE &&
-	    ipipe->output != IPIPE_OUTPUT_NONE) {
-		if (config_ipipe_hw(ipipe) < 0)
-			return -EINVAL;
-	}
-
-	vpfe_ipipe_enable(vpfe_dev, enable);
-
-	return 0;
-}
-
-/*
- * __ipipe_get_format() - helper function for getting ipipe format
- * @ipipe: pointer to ipipe private structure.
- * @pad: pad number.
- * @cfg: V4L2 subdev pad config
- * @which: wanted subdev format.
- *
- */
-static struct v4l2_mbus_framefmt *
-__ipipe_get_format(struct vpfe_ipipe_device *ipipe,
-		   struct v4l2_subdev_pad_config *cfg, unsigned int pad,
-		   enum v4l2_subdev_format_whence which)
-{
-	if (which == V4L2_SUBDEV_FORMAT_TRY)
-		return v4l2_subdev_get_try_format(&ipipe->subdev, cfg, pad);
-
-	return &ipipe->formats[pad];
-}
-
-/*
- * ipipe_try_format() - Handle try format by pad subdev method
- * @ipipe: VPFE ipipe device.
- * @cfg: V4L2 subdev pad config
- * @pad: pad num.
- * @fmt: pointer to v4l2 format structure.
- * @which : wanted subdev format
- */
-static void
-ipipe_try_format(struct vpfe_ipipe_device *ipipe,
-		 struct v4l2_subdev_pad_config *cfg, unsigned int pad,
-		 struct v4l2_mbus_framefmt *fmt,
-		 enum v4l2_subdev_format_whence which)
-{
-	unsigned int max_out_height;
-	unsigned int max_out_width;
-	unsigned int i;
-
-	max_out_width = IPIPE_MAX_OUTPUT_WIDTH_A;
-	max_out_height = IPIPE_MAX_OUTPUT_HEIGHT_A;
-
-	if (pad == IPIPE_PAD_SINK) {
-		for (i = 0; i < ARRAY_SIZE(ipipe_input_fmts); i++)
-			if (fmt->code == ipipe_input_fmts[i])
-				break;
-
-		/* If not found, use SBGGR10 as default */
-		if (i >= ARRAY_SIZE(ipipe_input_fmts))
-			fmt->code = MEDIA_BUS_FMT_SGRBG12_1X12;
-	} else if (pad == IPIPE_PAD_SOURCE) {
-		for (i = 0; i < ARRAY_SIZE(ipipe_output_fmts); i++)
-			if (fmt->code == ipipe_output_fmts[i])
-				break;
-
-		/* If not found, use UYVY as default */
-		if (i >= ARRAY_SIZE(ipipe_output_fmts))
-			fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
-	}
-
-	fmt->width = clamp_t(u32, fmt->width, MIN_OUT_HEIGHT, max_out_width);
-	fmt->height = clamp_t(u32, fmt->height, MIN_OUT_WIDTH, max_out_height);
-}
-
-/*
- * ipipe_set_format() - Handle set format by pads subdev method
- * @sd: pointer to v4l2 subdev structure
- * @cfg: V4L2 subdev pad config
- * @fmt: pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int
-ipipe_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-		 struct v4l2_subdev_format *fmt)
-{
-	struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *format;
-
-	format = __ipipe_get_format(ipipe, cfg, fmt->pad, fmt->which);
-	if (!format)
-		return -EINVAL;
-
-	ipipe_try_format(ipipe, cfg, fmt->pad, &fmt->format, fmt->which);
-	*format = fmt->format;
-
-	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
-		return 0;
-
-	if (fmt->pad == IPIPE_PAD_SINK &&
-	    (ipipe->input == IPIPE_INPUT_CCDC ||
-	    ipipe->input == IPIPE_INPUT_MEMORY))
-		ipipe->formats[fmt->pad] = fmt->format;
-	else if (fmt->pad == IPIPE_PAD_SOURCE &&
-		 ipipe->output == IPIPE_OUTPUT_RESIZER)
-		ipipe->formats[fmt->pad] = fmt->format;
-	else
-		return -EINVAL;
-
-	return 0;
-}
-
-/*
- * ipipe_get_format() - Handle get format by pads subdev method.
- * @sd: pointer to v4l2 subdev structure.
- * @cfg: V4L2 subdev pad config
- * @fmt: pointer to v4l2 subdev format structure.
- */
-static int
-ipipe_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-		 struct v4l2_subdev_format *fmt)
-{
-	struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
-
-	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-		fmt->format = ipipe->formats[fmt->pad];
-	else
-		fmt->format = *(v4l2_subdev_get_try_format(sd, cfg, fmt->pad));
-
-	return 0;
-}
-
-/*
- * ipipe_enum_frame_size() - enum frame sizes on pads
- * @sd: pointer to v4l2 subdev structure.
- * @cfg: V4L2 subdev pad config
- * @fse: pointer to v4l2_subdev_frame_size_enum structure.
- */
-static int
-ipipe_enum_frame_size(struct v4l2_subdev *sd,
-		      struct v4l2_subdev_pad_config *cfg,
-		      struct v4l2_subdev_frame_size_enum *fse)
-{
-	struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt format;
-
-	if (fse->index != 0)
-		return -EINVAL;
-
-	format.code = fse->code;
-	format.width = 1;
-	format.height = 1;
-	ipipe_try_format(ipipe, cfg, fse->pad, &format, fse->which);
-	fse->min_width = format.width;
-	fse->min_height = format.height;
-
-	if (format.code != fse->code)
-		return -EINVAL;
-
-	format.code = fse->code;
-	format.width = -1;
-	format.height = -1;
-	ipipe_try_format(ipipe, cfg, fse->pad, &format, fse->which);
-	fse->max_width = format.width;
-	fse->max_height = format.height;
-
-	return 0;
-}
-
-/*
- * ipipe_enum_mbus_code() - enum mbus codes for pads
- * @sd: pointer to v4l2 subdev structure.
- * @cfg: V4L2 subdev pad config
- * @code: pointer to v4l2_subdev_mbus_code_enum structure
- */
-static int
-ipipe_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-		     struct v4l2_subdev_mbus_code_enum *code)
-{
-	switch (code->pad) {
-	case IPIPE_PAD_SINK:
-		if (code->index >= ARRAY_SIZE(ipipe_input_fmts))
-			return -EINVAL;
-		code->code = ipipe_input_fmts[code->index];
-		break;
-
-	case IPIPE_PAD_SOURCE:
-		if (code->index >= ARRAY_SIZE(ipipe_output_fmts))
-			return -EINVAL;
-		code->code = ipipe_output_fmts[code->index];
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * ipipe_s_ctrl() - Handle set control subdev method
- * @ctrl: pointer to v4l2 control structure
- */
-static int ipipe_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vpfe_ipipe_device *ipipe =
-	     container_of(ctrl->handler, struct vpfe_ipipe_device, ctrls);
-	struct ipipe_lum_adj *lum_adj = &ipipe->config.lum_adj;
-
-	switch (ctrl->id) {
-	case V4L2_CID_BRIGHTNESS:
-		lum_adj->brightness = ctrl->val;
-		ipipe_set_lum_adj_regs(ipipe->base_addr, lum_adj);
-		break;
-
-	case V4L2_CID_CONTRAST:
-		lum_adj->contrast = ctrl->val;
-		ipipe_set_lum_adj_regs(ipipe->base_addr, lum_adj);
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * ipipe_init_formats() - Initialize formats on all pads
- * @sd: pointer to v4l2 subdev structure.
- * @fh: V4L2 subdev file handle
- *
- * Initialize all pad formats with default values. Try formats are initialized
- * on the file handle.
- */
-static int
-ipipe_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-	struct v4l2_subdev_format format;
-
-	memset(&format, 0, sizeof(format));
-	format.pad = IPIPE_PAD_SINK;
-	format.which = V4L2_SUBDEV_FORMAT_TRY;
-	format.format.code = MEDIA_BUS_FMT_SGRBG12_1X12;
-	format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A;
-	format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A;
-	ipipe_set_format(sd, fh->pad, &format);
-
-	memset(&format, 0, sizeof(format));
-	format.pad = IPIPE_PAD_SOURCE;
-	format.which = V4L2_SUBDEV_FORMAT_TRY;
-	format.format.code = MEDIA_BUS_FMT_UYVY8_2X8;
-	format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A;
-	format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A;
-	ipipe_set_format(sd, fh->pad, &format);
-
-	return 0;
-}
-
-/* subdev core operations */
-static const struct v4l2_subdev_core_ops ipipe_v4l2_core_ops = {
-	.ioctl = ipipe_ioctl,
-};
-
-static const struct v4l2_ctrl_ops ipipe_ctrl_ops = {
-	.s_ctrl = ipipe_s_ctrl,
-};
-
-/* subdev file operations */
-static const struct  v4l2_subdev_internal_ops ipipe_v4l2_internal_ops = {
-	.open = ipipe_init_formats,
-};
-
-/* subdev video operations */
-static const struct v4l2_subdev_video_ops ipipe_v4l2_video_ops = {
-	.s_stream = ipipe_set_stream,
-};
-
-/* subdev pad operations */
-static const struct v4l2_subdev_pad_ops ipipe_v4l2_pad_ops = {
-	.enum_mbus_code = ipipe_enum_mbus_code,
-	.enum_frame_size = ipipe_enum_frame_size,
-	.get_fmt = ipipe_get_format,
-	.set_fmt = ipipe_set_format,
-};
-
-/* v4l2 subdev operation */
-static const struct v4l2_subdev_ops ipipe_v4l2_ops = {
-	.core = &ipipe_v4l2_core_ops,
-	.video = &ipipe_v4l2_video_ops,
-	.pad = &ipipe_v4l2_pad_ops,
-};
-
-/*
- * Media entity operations
- */
-
-/*
- * ipipe_link_setup() - Setup ipipe connections
- * @entity: ipipe media entity
- * @local: Pad at the local end of the link
- * @remote: Pad at the remote end of the link
- * @flags: Link flags
- *
- * return -EINVAL or zero on success
- */
-static int
-ipipe_link_setup(struct media_entity *entity, const struct media_pad *local,
-		 const struct media_pad *remote, u32 flags)
-{
-	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
-	struct vpfe_ipipe_device *ipipe = v4l2_get_subdevdata(sd);
-	struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe);
-	u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input;
-
-	if (!is_media_entity_v4l2_subdev(remote->entity))
-		return -EINVAL;
-
-	switch (local->index) {
-	case IPIPE_PAD_SINK:
-		if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-			ipipe->input = IPIPE_INPUT_NONE;
-			break;
-		}
-		if (ipipe->input != IPIPE_INPUT_NONE)
-			return -EBUSY;
-		if (ipipeif_sink == IPIPEIF_INPUT_MEMORY)
-			ipipe->input = IPIPE_INPUT_MEMORY;
-		else
-			ipipe->input = IPIPE_INPUT_CCDC;
-		break;
-
-	case IPIPE_PAD_SOURCE:
-		/* out to RESIZER */
-		if (flags & MEDIA_LNK_FL_ENABLED)
-			ipipe->output = IPIPE_OUTPUT_RESIZER;
-		else
-			ipipe->output = IPIPE_OUTPUT_NONE;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static const struct media_entity_operations ipipe_media_ops = {
-	.link_setup = ipipe_link_setup,
-};
-
-/*
- * vpfe_ipipe_unregister_entities() - ipipe unregister entity
- * @vpfe_ipipe: pointer to ipipe subdevice structure.
- */
-void vpfe_ipipe_unregister_entities(struct vpfe_ipipe_device *vpfe_ipipe)
-{
-	/* unregister subdev */
-	v4l2_device_unregister_subdev(&vpfe_ipipe->subdev);
-	/* cleanup entity */
-	media_entity_cleanup(&vpfe_ipipe->subdev.entity);
-}
-
-/*
- * vpfe_ipipe_register_entities() - ipipe register entity
- * @ipipe: pointer to ipipe subdevice structure.
- * @vdev: pointer to v4l2 device structure.
- */
-int
-vpfe_ipipe_register_entities(struct vpfe_ipipe_device *ipipe,
-			     struct v4l2_device *vdev)
-{
-	int ret;
-
-	/* Register the subdev */
-	ret = v4l2_device_register_subdev(vdev, &ipipe->subdev);
-	if (ret) {
-		pr_err("Failed to register ipipe as v4l2 subdevice\n");
-		return ret;
-	}
-
-	return ret;
-}
-
-#define IPIPE_CONTRAST_HIGH		0xff
-#define IPIPE_BRIGHT_HIGH		0xff
-
-/*
- * vpfe_ipipe_init() - ipipe module initialization.
- * @ipipe: pointer to ipipe subdevice structure.
- * @pdev: platform device pointer.
- */
-int
-vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe, struct platform_device *pdev)
-{
-	struct media_pad *pads = &ipipe->pads[0];
-	struct v4l2_subdev *sd = &ipipe->subdev;
-	struct media_entity *me = &sd->entity;
-	struct resource *res, *res2, *memres;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 4);
-	if (!res)
-		return -ENOENT;
-
-	memres = request_mem_region(res->start, resource_size(res), res->name);
-	if (!memres)
-		return -EBUSY;
-	ipipe->base_addr = ioremap_nocache(memres->start,
-					   resource_size(memres));
-	if (!ipipe->base_addr)
-		goto error_release;
-
-	res2 = platform_get_resource(pdev, IORESOURCE_MEM, 6);
-	if (!res2)
-		goto error_unmap;
-	ipipe->isp5_base_addr = ioremap_nocache(res2->start,
-						resource_size(res2));
-	if (!ipipe->isp5_base_addr)
-		goto error_unmap;
-
-	v4l2_subdev_init(sd, &ipipe_v4l2_ops);
-	sd->internal_ops = &ipipe_v4l2_internal_ops;
-	strscpy(sd->name, "DAVINCI IPIPE", sizeof(sd->name));
-	sd->grp_id = 1 << 16;	/* group ID for davinci subdevs */
-	v4l2_set_subdevdata(sd, ipipe);
-	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
-	pads[IPIPE_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-	pads[IPIPE_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-
-	ipipe->input = IPIPE_INPUT_NONE;
-	ipipe->output = IPIPE_OUTPUT_NONE;
-
-	me->ops = &ipipe_media_ops;
-	v4l2_ctrl_handler_init(&ipipe->ctrls, 2);
-	v4l2_ctrl_new_std(&ipipe->ctrls, &ipipe_ctrl_ops,
-			  V4L2_CID_BRIGHTNESS, 0,
-			  IPIPE_BRIGHT_HIGH, 1, 16);
-	v4l2_ctrl_new_std(&ipipe->ctrls, &ipipe_ctrl_ops,
-			  V4L2_CID_CONTRAST, 0,
-			  IPIPE_CONTRAST_HIGH, 1, 16);
-	v4l2_ctrl_handler_setup(&ipipe->ctrls);
-	sd->ctrl_handler = &ipipe->ctrls;
-
-	return media_entity_pads_init(me, IPIPE_PADS_NUM, pads);
-
-error_unmap:
-	iounmap(ipipe->base_addr);
-error_release:
-	release_mem_region(memres->start, resource_size(memres));
-	return -ENOMEM;
-}
-
-/*
- * vpfe_ipipe_cleanup() - ipipe subdevice cleanup.
- * @ipipe: pointer to ipipe subdevice
- * @dev: pointer to platform device
- */
-void vpfe_ipipe_cleanup(struct vpfe_ipipe_device *ipipe,
-			struct platform_device *pdev)
-{
-	struct resource *res;
-
-	v4l2_ctrl_handler_free(&ipipe->ctrls);
-
-	iounmap(ipipe->base_addr);
-	iounmap(ipipe->isp5_base_addr);
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 4);
-	if (res)
-		release_mem_region(res->start, resource_size(res));
-}
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.h b/drivers/staging/media/davinci_vpfe/dm365_ipipe.h
deleted file mode 100644
index 866ae12..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _DAVINCI_VPFE_DM365_IPIPE_H
-#define _DAVINCI_VPFE_DM365_IPIPE_H
-
-#include <linux/platform_device.h>
-
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-subdev.h>
-
-#include "davinci_vpfe_user.h"
-#include "vpfe_video.h"
-
-enum ipipe_noise_filter {
-	IPIPE_D2F_1ST = 0,
-	IPIPE_D2F_2ND = 1,
-};
-
-/* Used for driver storage */
-struct ipipe_otfdpc_2_0 {
-	/* 0 - disable, 1 - enable */
-	unsigned char en;
-	/* defect detection method */
-	enum vpfe_ipipe_otfdpc_det_meth det_method;
-	/* Algorithm used. Applicable only when IPIPE_DPC_OTF_MIN_MAX2 is
-	 * used
-	 */
-	enum vpfe_ipipe_otfdpc_alg alg;
-	struct vpfe_ipipe_otfdpc_2_0_cfg otfdpc_2_0;
-};
-
-struct ipipe_otfdpc_3_0 {
-	/* 0 - disable, 1 - enable */
-	unsigned char en;
-	/* defect detection method */
-	enum vpfe_ipipe_otfdpc_det_meth det_method;
-	/* Algorithm used. Applicable only when IPIPE_DPC_OTF_MIN_MAX2 is
-	 * used
-	 */
-	enum vpfe_ipipe_otfdpc_alg alg;
-	struct vpfe_ipipe_otfdpc_3_0_cfg otfdpc_3_0;
-};
-
-/* Structure for configuring Luminance Adjustment module */
-struct ipipe_lum_adj {
-	/* Brightness adjustments */
-	unsigned char brightness;
-	/* contrast adjustments */
-	unsigned char contrast;
-};
-
-enum ipipe_rgb2rgb {
-	IPIPE_RGB2RGB_1 = 0,
-	IPIPE_RGB2RGB_2 = 1,
-};
-
-struct ipipe_module_params {
-	__u32 flag;
-	struct vpfe_ipipe_input_config input_config;
-	struct vpfe_ipipe_lutdpc lutdpc;
-	struct vpfe_ipipe_otfdpc otfdpc;
-	struct vpfe_ipipe_nf nf1;
-	struct vpfe_ipipe_nf nf2;
-	struct vpfe_ipipe_gic gic;
-	struct vpfe_ipipe_wb wbal;
-	struct vpfe_ipipe_cfa cfa;
-	struct vpfe_ipipe_rgb2rgb rgb2rgb1;
-	struct vpfe_ipipe_rgb2rgb rgb2rgb2;
-	struct vpfe_ipipe_gamma gamma;
-	struct vpfe_ipipe_3d_lut lut;
-	struct vpfe_ipipe_rgb2yuv rgb2yuv;
-	struct vpfe_ipipe_gbce gbce;
-	struct vpfe_ipipe_yuv422_conv yuv422_conv;
-	struct vpfe_ipipe_yee yee;
-	struct vpfe_ipipe_car car;
-	struct vpfe_ipipe_cgs cgs;
-	struct ipipe_lum_adj lum_adj;
-};
-
-#define IPIPE_PAD_SINK			0
-#define IPIPE_PAD_SOURCE		1
-
-#define IPIPE_PADS_NUM			2
-
-#define IPIPE_OUTPUT_NONE		0
-#define IPIPE_OUTPUT_RESIZER		(1 << 0)
-
-enum ipipe_input_entity {
-	IPIPE_INPUT_NONE = 0,
-	IPIPE_INPUT_MEMORY = 1,
-	IPIPE_INPUT_CCDC = 2,
-};
-
-
-struct vpfe_ipipe_device {
-	struct v4l2_subdev subdev;
-	struct media_pad pads[IPIPE_PADS_NUM];
-	struct v4l2_mbus_framefmt formats[IPIPE_PADS_NUM];
-	enum ipipe_input_entity input;
-	unsigned int output;
-	struct v4l2_ctrl_handler ctrls;
-	void __iomem *base_addr;
-	void __iomem *isp5_base_addr;
-	struct ipipe_module_params config;
-};
-
-struct ipipe_module_if {
-	unsigned int param_offset;
-	unsigned int param_size;
-	unsigned int config_offset;
-	int (*set)(struct vpfe_ipipe_device *ipipe, void *param);
-	int (*get)(struct vpfe_ipipe_device *ipipe, void *param);
-};
-
-/* data paths */
-enum ipipe_data_paths {
-	IPIPE_RAW2YUV,
-	/* Bayer RAW input to YCbCr output */
-	IPIPE_RAW2RAW,
-	/* Bayer Raw to Bayer output */
-	IPIPE_RAW2BOX,
-	/* Bayer Raw to Boxcar output */
-	IPIPE_YUV2YUV
-	/* YUV Raw to YUV Raw output */
-};
-
-#define IPIPE_COLPTN_R_Ye	0x0
-#define IPIPE_COLPTN_Gr_Cy	0x1
-#define IPIPE_COLPTN_Gb_G	0x2
-#define IPIPE_COLPTN_B_Mg	0x3
-
-#define COLPAT_EE_SHIFT		0
-#define COLPAT_EO_SHIFT		2
-#define COLPAT_OE_SHIFT		4
-#define COLPAT_OO_SHIFT		6
-
-#define ipipe_sgrbg_pattern \
-	(IPIPE_COLPTN_Gr_Cy <<  COLPAT_EE_SHIFT | \
-	IPIPE_COLPTN_R_Ye  << COLPAT_EO_SHIFT | \
-	IPIPE_COLPTN_B_Mg  << COLPAT_OE_SHIFT | \
-	IPIPE_COLPTN_Gb_G  << COLPAT_OO_SHIFT)
-
-#define ipipe_srggb_pattern \
-	(IPIPE_COLPTN_R_Ye <<  COLPAT_EE_SHIFT | \
-	IPIPE_COLPTN_Gr_Cy  << COLPAT_EO_SHIFT | \
-	IPIPE_COLPTN_Gb_G  << COLPAT_OE_SHIFT | \
-	IPIPE_COLPTN_B_Mg  << COLPAT_OO_SHIFT)
-
-int vpfe_ipipe_register_entities(struct vpfe_ipipe_device *ipipe,
-		struct v4l2_device *v4l2_dev);
-int vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe,
-		struct platform_device *pdev);
-void vpfe_ipipe_unregister_entities(struct vpfe_ipipe_device *ipipe);
-void vpfe_ipipe_cleanup(struct vpfe_ipipe_device *ipipe,
-		struct platform_device *pdev);
-void vpfe_ipipe_enable(struct vpfe_device *vpfe_dev, int en);
-
-#endif		/* _DAVINCI_VPFE_DM365_IPIPE_H */
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c
deleted file mode 100644
index 110473c..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#include "dm365_ipipe_hw.h"
-
-#define IPIPE_MODE_CONTINUOUS		0
-#define IPIPE_MODE_SINGLE_SHOT		1
-
-static void ipipe_clock_enable(void __iomem *base_addr)
-{
-	/* enable IPIPE MMR for register write access */
-	regw_ip(base_addr, IPIPE_GCK_MMR_DEFAULT, IPIPE_GCK_MMR);
-
-	/* enable the clock wb,cfa,dfc,d2f,pre modules */
-	regw_ip(base_addr, IPIPE_GCK_PIX_DEFAULT, IPIPE_GCK_PIX);
-}
-
-static void
-rsz_set_common_params(void __iomem *rsz_base, struct resizer_params *params)
-{
-	struct rsz_common_params *rsz_common = &params->rsz_common;
-	u32 val;
-
-	/* Set mode */
-	regw_rsz(rsz_base, params->oper_mode, RSZ_SRC_MODE);
-
-	/* data source selection  and bypass */
-	val = (rsz_common->passthrough << RSZ_BYPASS_SHIFT) |
-	      rsz_common->source;
-	regw_rsz(rsz_base, val, RSZ_SRC_FMT0);
-
-	/* src image selection */
-	val = (rsz_common->raw_flip & 1) |
-	      (rsz_common->src_img_fmt << RSZ_SRC_IMG_FMT_SHIFT) |
-	      ((rsz_common->y_c & 1) << RSZ_SRC_Y_C_SEL_SHIFT);
-	regw_rsz(rsz_base, val, RSZ_SRC_FMT1);
-
-	regw_rsz(rsz_base, rsz_common->vps & IPIPE_RSZ_VPS_MASK, RSZ_SRC_VPS);
-	regw_rsz(rsz_base, rsz_common->hps & IPIPE_RSZ_HPS_MASK, RSZ_SRC_HPS);
-	regw_rsz(rsz_base, rsz_common->vsz & IPIPE_RSZ_VSZ_MASK, RSZ_SRC_VSZ);
-	regw_rsz(rsz_base, rsz_common->hsz & IPIPE_RSZ_HSZ_MASK, RSZ_SRC_HSZ);
-	regw_rsz(rsz_base, rsz_common->yuv_y_min, RSZ_YUV_Y_MIN);
-	regw_rsz(rsz_base, rsz_common->yuv_y_max, RSZ_YUV_Y_MAX);
-	regw_rsz(rsz_base, rsz_common->yuv_c_min, RSZ_YUV_C_MIN);
-	regw_rsz(rsz_base, rsz_common->yuv_c_max, RSZ_YUV_C_MAX);
-	/* chromatic position */
-	regw_rsz(rsz_base, rsz_common->out_chr_pos, RSZ_YUV_PHS);
-}
-
-static void
-rsz_set_rsz_regs(void __iomem *rsz_base, unsigned int rsz_id,
-		 struct resizer_params *params)
-{
-	struct resizer_scale_param *rsc_params;
-	struct rsz_ext_mem_param *ext_mem;
-	struct resizer_rgb *rgb;
-	u32 reg_base;
-	u32 val;
-
-	rsc_params = &params->rsz_rsc_param[rsz_id];
-	rgb = &params->rsz2rgb[rsz_id];
-	ext_mem = &params->ext_mem_param[rsz_id];
-
-	if (rsz_id == RSZ_A) {
-		val = rsc_params->h_flip << RSZA_H_FLIP_SHIFT;
-		val |= rsc_params->v_flip << RSZA_V_FLIP_SHIFT;
-		reg_base = RSZ_EN_A;
-	} else {
-		val = rsc_params->h_flip << RSZB_H_FLIP_SHIFT;
-		val |= rsc_params->v_flip << RSZB_V_FLIP_SHIFT;
-		reg_base = RSZ_EN_B;
-	}
-	/* update flip settings */
-	regw_rsz(rsz_base, val, RSZ_SEQ);
-
-	regw_rsz(rsz_base, params->oper_mode, reg_base + RSZ_MODE);
-
-	val = (rsc_params->cen << RSZ_CEN_SHIFT) | rsc_params->yen;
-	regw_rsz(rsz_base, val, reg_base + RSZ_420);
-
-	regw_rsz(rsz_base, rsc_params->i_vps & RSZ_VPS_MASK,
-		 reg_base + RSZ_I_VPS);
-	regw_rsz(rsz_base, rsc_params->i_hps & RSZ_HPS_MASK,
-		 reg_base + RSZ_I_HPS);
-	regw_rsz(rsz_base, rsc_params->o_vsz & RSZ_O_VSZ_MASK,
-		 reg_base + RSZ_O_VSZ);
-	regw_rsz(rsz_base, rsc_params->o_hsz & RSZ_O_HSZ_MASK,
-		 reg_base + RSZ_O_HSZ);
-	regw_rsz(rsz_base, rsc_params->v_phs_y & RSZ_V_PHS_MASK,
-		 reg_base + RSZ_V_PHS_Y);
-	regw_rsz(rsz_base, rsc_params->v_phs_c & RSZ_V_PHS_MASK,
-		 reg_base + RSZ_V_PHS_C);
-
-	/* keep this additional adjustment to zero for now */
-	regw_rsz(rsz_base, rsc_params->v_dif & RSZ_V_DIF_MASK,
-		 reg_base + RSZ_V_DIF);
-
-	val = (rsc_params->v_typ_y & 1) |
-	      ((rsc_params->v_typ_c & 1) << RSZ_TYP_C_SHIFT);
-	regw_rsz(rsz_base, val, reg_base + RSZ_V_TYP);
-
-	val = (rsc_params->v_lpf_int_y & RSZ_LPF_INT_MASK) |
-	      ((rsc_params->v_lpf_int_c & RSZ_LPF_INT_MASK) <<
-	      RSZ_LPF_INT_C_SHIFT);
-	regw_rsz(rsz_base, val, reg_base + RSZ_V_LPF);
-
-	regw_rsz(rsz_base, rsc_params->h_phs &
-		RSZ_H_PHS_MASK, reg_base + RSZ_H_PHS);
-
-	regw_rsz(rsz_base, 0, reg_base + RSZ_H_PHS_ADJ);
-	regw_rsz(rsz_base, rsc_params->h_dif &
-		RSZ_H_DIF_MASK, reg_base + RSZ_H_DIF);
-
-	val = (rsc_params->h_typ_y & 1) |
-	      ((rsc_params->h_typ_c & 1) << RSZ_TYP_C_SHIFT);
-	regw_rsz(rsz_base, val, reg_base + RSZ_H_TYP);
-
-	val = (rsc_params->h_lpf_int_y & RSZ_LPF_INT_MASK) |
-		 ((rsc_params->h_lpf_int_c & RSZ_LPF_INT_MASK) <<
-		 RSZ_LPF_INT_C_SHIFT);
-	regw_rsz(rsz_base, val, reg_base + RSZ_H_LPF);
-
-	regw_rsz(rsz_base, rsc_params->dscale_en & 1, reg_base + RSZ_DWN_EN);
-
-	val = (rsc_params->h_dscale_ave_sz & RSZ_DWN_SCALE_AV_SZ_MASK) |
-	      ((rsc_params->v_dscale_ave_sz & RSZ_DWN_SCALE_AV_SZ_MASK) <<
-	      RSZ_DWN_SCALE_AV_SZ_V_SHIFT);
-	regw_rsz(rsz_base, val, reg_base + RSZ_DWN_AV);
-
-	/* setting rgb conversion parameters */
-	regw_rsz(rsz_base, rgb->rgb_en, reg_base + RSZ_RGB_EN);
-
-	val = (rgb->rgb_typ << RSZ_RGB_TYP_SHIFT) |
-	      (rgb->rgb_msk0 << RSZ_RGB_MSK0_SHIFT) |
-	      (rgb->rgb_msk1 << RSZ_RGB_MSK1_SHIFT);
-	regw_rsz(rsz_base, val, reg_base + RSZ_RGB_TYP);
-
-	regw_rsz(rsz_base, rgb->rgb_alpha_val & RSZ_RGB_ALPHA_MASK,
-		reg_base + RSZ_RGB_BLD);
-
-	/* setting external memory parameters */
-	regw_rsz(rsz_base, ext_mem->rsz_sdr_oft_y, reg_base + RSZ_SDR_Y_OFT);
-	regw_rsz(rsz_base, ext_mem->rsz_sdr_ptr_s_y,
-		 reg_base + RSZ_SDR_Y_PTR_S);
-	regw_rsz(rsz_base, ext_mem->rsz_sdr_ptr_e_y,
-		 reg_base + RSZ_SDR_Y_PTR_E);
-	regw_rsz(rsz_base, ext_mem->rsz_sdr_oft_c, reg_base + RSZ_SDR_C_OFT);
-	regw_rsz(rsz_base, ext_mem->rsz_sdr_ptr_s_c,
-		 reg_base + RSZ_SDR_C_PTR_S);
-	regw_rsz(rsz_base, (ext_mem->rsz_sdr_ptr_e_c >> 1),
-		 reg_base + RSZ_SDR_C_PTR_E);
-}
-
-/*set the registers of either RSZ0 or RSZ1 */
-static void
-ipipe_setup_resizer(void __iomem *rsz_base, struct resizer_params *params)
-{
-	/* enable MMR gate to write to Resizer */
-	regw_rsz(rsz_base, 1, RSZ_GCK_MMR);
-
-	/* Enable resizer if it is not in bypass mode */
-	if (params->rsz_common.passthrough)
-		regw_rsz(rsz_base, 0, RSZ_GCK_SDR);
-	else
-		regw_rsz(rsz_base, 1, RSZ_GCK_SDR);
-
-	rsz_set_common_params(rsz_base, params);
-
-	regw_rsz(rsz_base, params->rsz_en[RSZ_A], RSZ_EN_A);
-
-	if (params->rsz_en[RSZ_A])
-		/*setting rescale parameters */
-		rsz_set_rsz_regs(rsz_base, RSZ_A, params);
-
-	regw_rsz(rsz_base, params->rsz_en[RSZ_B], RSZ_EN_B);
-
-	if (params->rsz_en[RSZ_B])
-		rsz_set_rsz_regs(rsz_base, RSZ_B, params);
-}
-
-static u32 ipipe_get_color_pat(u32 pix)
-{
-	switch (pix) {
-	case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
-	case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
-	case MEDIA_BUS_FMT_SGRBG12_1X12:
-		return ipipe_sgrbg_pattern;
-
-	default:
-		return ipipe_srggb_pattern;
-	}
-}
-
-static int ipipe_get_data_path(struct vpfe_ipipe_device *ipipe)
-{
-	u32 temp_pix_fmt;
-
-	switch (ipipe->formats[IPIPE_PAD_SINK].code) {
-	case MEDIA_BUS_FMT_SBGGR8_1X8:
-	case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
-	case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
-	case MEDIA_BUS_FMT_SGRBG12_1X12:
-		temp_pix_fmt = MEDIA_BUS_FMT_SGRBG12_1X12;
-		break;
-
-	default:
-		temp_pix_fmt = MEDIA_BUS_FMT_UYVY8_2X8;
-	}
-
-	if (temp_pix_fmt == MEDIA_BUS_FMT_SGRBG12_1X12) {
-		if (ipipe->formats[IPIPE_PAD_SOURCE].code ==
-			MEDIA_BUS_FMT_SGRBG12_1X12)
-			return IPIPE_RAW2RAW;
-		return IPIPE_RAW2YUV;
-	}
-
-	return IPIPE_YUV2YUV;
-}
-
-static int get_ipipe_mode(struct vpfe_ipipe_device *ipipe)
-{
-	struct vpfe_device *vpfe_dev = to_vpfe_device(ipipe);
-	u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input;
-
-	if (ipipeif_sink == IPIPEIF_INPUT_MEMORY)
-		return IPIPE_MODE_SINGLE_SHOT;
-	if (ipipeif_sink == IPIPEIF_INPUT_ISIF)
-		return IPIPE_MODE_CONTINUOUS;
-
-	return -EINVAL;
-}
-
-int config_ipipe_hw(struct vpfe_ipipe_device *ipipe)
-{
-	struct vpfe_ipipe_input_config *config = &ipipe->config.input_config;
-	void __iomem *ipipe_base = ipipe->base_addr;
-	struct v4l2_mbus_framefmt *outformat;
-	u32 color_pat;
-	int ipipe_mode;
-	u32 data_path;
-
-	/* enable clock to IPIPE */
-	vpss_enable_clock(VPSS_IPIPE_CLOCK, 1);
-	ipipe_clock_enable(ipipe_base);
-
-	if (ipipe->input == IPIPE_INPUT_NONE) {
-		regw_ip(ipipe_base, 0, IPIPE_SRC_EN);
-		return 0;
-	}
-
-	ipipe_mode = get_ipipe_mode(ipipe);
-	if (ipipe_mode < 0) {
-		pr_err("Failed to get ipipe mode");
-		return -EINVAL;
-	}
-	regw_ip(ipipe_base, ipipe_mode, IPIPE_SRC_MODE);
-
-	data_path = ipipe_get_data_path(ipipe);
-	regw_ip(ipipe_base, data_path, IPIPE_SRC_FMT);
-
-	regw_ip(ipipe_base, config->vst & IPIPE_RSZ_VPS_MASK, IPIPE_SRC_VPS);
-	regw_ip(ipipe_base, config->hst & IPIPE_RSZ_HPS_MASK, IPIPE_SRC_HPS);
-
-	outformat = &ipipe->formats[IPIPE_PAD_SOURCE];
-	regw_ip(ipipe_base, (outformat->height + 1) & IPIPE_RSZ_VSZ_MASK,
-		IPIPE_SRC_VSZ);
-	regw_ip(ipipe_base, (outformat->width + 1) & IPIPE_RSZ_HSZ_MASK,
-		IPIPE_SRC_HSZ);
-
-	if (data_path == IPIPE_RAW2YUV ||
-	    data_path == IPIPE_RAW2RAW) {
-		color_pat =
-		ipipe_get_color_pat(ipipe->formats[IPIPE_PAD_SINK].code);
-		regw_ip(ipipe_base, color_pat, IPIPE_SRC_COL);
-	}
-
-	return 0;
-}
-
-/*
- * config_rsz_hw() - Performs hardware setup of resizer.
- */
-int config_rsz_hw(struct vpfe_resizer_device *resizer,
-		  struct resizer_params *config)
-{
-	struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
-	void __iomem *ipipe_base = vpfe_dev->vpfe_ipipe.base_addr;
-	void __iomem *rsz_base = vpfe_dev->vpfe_resizer.base_addr;
-
-	/* enable VPSS clock */
-	vpss_enable_clock(VPSS_IPIPE_CLOCK, 1);
-	ipipe_clock_enable(ipipe_base);
-
-	ipipe_setup_resizer(rsz_base, config);
-
-	return 0;
-}
-
-static void
-rsz_set_y_address(void __iomem *rsz_base, unsigned int address,
-		  unsigned int offset)
-{
-	u32 val;
-
-	val = address & SET_LOW_ADDR;
-	regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_BAD_L);
-	regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_SAD_L);
-
-	val = (address & SET_HIGH_ADDR) >> 16;
-	regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_BAD_H);
-	regw_rsz(rsz_base, val, offset + RSZ_SDR_Y_SAD_H);
-}
-
-static void
-rsz_set_c_address(void __iomem *rsz_base, unsigned int address,
-		  unsigned int offset)
-{
-	u32 val;
-
-	val = address & SET_LOW_ADDR;
-	regw_rsz(rsz_base, val, offset + RSZ_SDR_C_BAD_L);
-	regw_rsz(rsz_base, val, offset + RSZ_SDR_C_SAD_L);
-
-	val = (address & SET_HIGH_ADDR) >> 16;
-	regw_rsz(rsz_base, val, offset + RSZ_SDR_C_BAD_H);
-	regw_rsz(rsz_base, val, offset + RSZ_SDR_C_SAD_H);
-}
-
-/*
- * resizer_set_outaddr() - set the address for given resize_no
- * @rsz_base: resizer base address
- * @params: pointer to ipipe_params structure
- * @resize_no: 0 - Resizer-A, 1 - Resizer B
- * @address: the address to set
- */
-int
-resizer_set_outaddr(void __iomem *rsz_base, struct resizer_params *params,
-		    int resize_no, unsigned int address)
-{
-	struct resizer_scale_param *rsc_param;
-	struct rsz_ext_mem_param *mem_param;
-	struct rsz_common_params *rsz_common;
-	unsigned int rsz_start_add;
-	unsigned int val;
-
-	if (resize_no != RSZ_A && resize_no != RSZ_B)
-		return -EINVAL;
-
-	mem_param = &params->ext_mem_param[resize_no];
-	rsc_param = &params->rsz_rsc_param[resize_no];
-	rsz_common = &params->rsz_common;
-
-	if (resize_no == RSZ_A)
-		rsz_start_add = RSZ_EN_A;
-	else
-		rsz_start_add = RSZ_EN_B;
-
-	/* y_c = 0 for y, = 1 for c */
-	if (rsz_common->src_img_fmt == RSZ_IMG_420) {
-		if (rsz_common->y_c) {
-			/* C channel */
-			val = address + mem_param->flip_ofst_c;
-			rsz_set_c_address(rsz_base, val, rsz_start_add);
-		} else {
-			val = address + mem_param->flip_ofst_y;
-			rsz_set_y_address(rsz_base, val, rsz_start_add);
-		}
-	} else {
-		if (rsc_param->cen && rsc_param->yen) {
-			/* 420 */
-			val = address + mem_param->c_offset +
-			      mem_param->flip_ofst_c +
-			      mem_param->user_y_ofst +
-			      mem_param->user_c_ofst;
-			if (resize_no == RSZ_B)
-				val +=
-				params->ext_mem_param[RSZ_A].user_y_ofst +
-				params->ext_mem_param[RSZ_A].user_c_ofst;
-			/* set C address */
-			rsz_set_c_address(rsz_base, val, rsz_start_add);
-		}
-		val = address + mem_param->flip_ofst_y + mem_param->user_y_ofst;
-		if (resize_no == RSZ_B)
-			val += params->ext_mem_param[RSZ_A].user_y_ofst +
-				params->ext_mem_param[RSZ_A].user_c_ofst;
-		/* set Y address */
-		rsz_set_y_address(rsz_base, val, rsz_start_add);
-	}
-	/* resizer must be enabled */
-	regw_rsz(rsz_base, params->rsz_en[resize_no], rsz_start_add);
-
-	return 0;
-}
-
-void
-ipipe_set_lutdpc_regs(void __iomem *base_addr, void __iomem *isp5_base_addr,
-		      struct vpfe_ipipe_lutdpc *dpc)
-{
-	u32 max_tbl_size = LUT_DPC_MAX_SIZE >> 1;
-	u32 lut_start_addr = DPC_TB0_START_ADDR;
-	u32 val;
-	u32 count;
-
-	ipipe_clock_enable(base_addr);
-	regw_ip(base_addr, dpc->en, DPC_LUT_EN);
-
-	if (dpc->en != 1)
-		return;
-
-	val = LUTDPC_TBL_256_EN | (dpc->repl_white & 1);
-	regw_ip(base_addr, val, DPC_LUT_SEL);
-	regw_ip(base_addr, LUT_DPC_START_ADDR, DPC_LUT_ADR);
-	regw_ip(base_addr, dpc->dpc_size, DPC_LUT_SIZ & LUT_DPC_SIZE_MASK);
-
-	for (count = 0; count < dpc->dpc_size; count++) {
-		if (count >= max_tbl_size)
-			lut_start_addr = DPC_TB1_START_ADDR;
-		val = (dpc->table[count].horz_pos & LUT_DPC_H_POS_MASK) |
-		      ((dpc->table[count].vert_pos & LUT_DPC_V_POS_MASK) <<
-			LUT_DPC_V_POS_SHIFT) | (dpc->table[count].method <<
-			LUT_DPC_CORR_METH_SHIFT);
-		w_ip_table(isp5_base_addr, val, (lut_start_addr +
-		((count % max_tbl_size) << 2)));
-	}
-}
-
-static void
-set_dpc_thresholds(void __iomem *base_addr,
-		   struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_thr)
-{
-	regw_ip(base_addr, dpc_thr->corr_thr.r & OTFDPC_DPC2_THR_MASK,
-		DPC_OTF_2C_THR_R);
-	regw_ip(base_addr, dpc_thr->corr_thr.gr & OTFDPC_DPC2_THR_MASK,
-		DPC_OTF_2C_THR_GR);
-	regw_ip(base_addr, dpc_thr->corr_thr.gb & OTFDPC_DPC2_THR_MASK,
-		DPC_OTF_2C_THR_GB);
-	regw_ip(base_addr, dpc_thr->corr_thr.b & OTFDPC_DPC2_THR_MASK,
-		DPC_OTF_2C_THR_B);
-	regw_ip(base_addr, dpc_thr->det_thr.r & OTFDPC_DPC2_THR_MASK,
-		DPC_OTF_2D_THR_R);
-	regw_ip(base_addr, dpc_thr->det_thr.gr & OTFDPC_DPC2_THR_MASK,
-		DPC_OTF_2D_THR_GR);
-	regw_ip(base_addr, dpc_thr->det_thr.gb & OTFDPC_DPC2_THR_MASK,
-		DPC_OTF_2D_THR_GB);
-	regw_ip(base_addr, dpc_thr->det_thr.b & OTFDPC_DPC2_THR_MASK,
-		DPC_OTF_2D_THR_B);
-}
-
-void ipipe_set_otfdpc_regs(void __iomem *base_addr,
-			   struct vpfe_ipipe_otfdpc *otfdpc)
-{
-	struct vpfe_ipipe_otfdpc_2_0_cfg *dpc_2_0 = &otfdpc->alg_cfg.dpc_2_0;
-	struct vpfe_ipipe_otfdpc_3_0_cfg *dpc_3_0 = &otfdpc->alg_cfg.dpc_3_0;
-	u32 val;
-
-	ipipe_clock_enable(base_addr);
-
-	regw_ip(base_addr, (otfdpc->en & 1), DPC_OTF_EN);
-	if (!otfdpc->en)
-		return;
-
-	/* dpc enabled */
-	val = (otfdpc->det_method << OTF_DET_METHOD_SHIFT) | otfdpc->alg;
-	regw_ip(base_addr, val, DPC_OTF_TYP);
-
-	if (otfdpc->det_method == VPFE_IPIPE_DPC_OTF_MIN_MAX) {
-		/* ALG= 0, TYP = 0, DPC_OTF_2D_THR_[x]=0
-		 * DPC_OTF_2C_THR_[x] = Maximum thresohld
-		 * MinMax method
-		 */
-		dpc_2_0->det_thr.r = dpc_2_0->det_thr.gb =
-		dpc_2_0->det_thr.gr = dpc_2_0->det_thr.b = 0;
-		set_dpc_thresholds(base_addr, dpc_2_0);
-		return;
-	}
-	/* MinMax2 */
-	if (otfdpc->alg == VPFE_IPIPE_OTFDPC_2_0) {
-		set_dpc_thresholds(base_addr, dpc_2_0);
-		return;
-	}
-	regw_ip(base_addr, dpc_3_0->act_adj_shf &
-		OTF_DPC3_0_SHF_MASK, DPC_OTF_3_SHF);
-	/* Detection thresholds */
-	regw_ip(base_addr, ((dpc_3_0->det_thr & OTF_DPC3_0_THR_MASK) <<
-		OTF_DPC3_0_THR_SHIFT), DPC_OTF_3D_THR);
-	regw_ip(base_addr, dpc_3_0->det_slp &
-		OTF_DPC3_0_SLP_MASK, DPC_OTF_3D_SLP);
-	regw_ip(base_addr, dpc_3_0->det_thr_min &
-		OTF_DPC3_0_DET_MASK, DPC_OTF_3D_MIN);
-	regw_ip(base_addr, dpc_3_0->det_thr_max &
-		OTF_DPC3_0_DET_MASK, DPC_OTF_3D_MAX);
-	/* Correction thresholds */
-	regw_ip(base_addr, ((dpc_3_0->corr_thr & OTF_DPC3_0_THR_MASK) <<
-		OTF_DPC3_0_THR_SHIFT), DPC_OTF_3C_THR);
-	regw_ip(base_addr, dpc_3_0->corr_slp &
-		OTF_DPC3_0_SLP_MASK, DPC_OTF_3C_SLP);
-	regw_ip(base_addr, dpc_3_0->corr_thr_min &
-		OTF_DPC3_0_CORR_MASK, DPC_OTF_3C_MIN);
-	regw_ip(base_addr, dpc_3_0->corr_thr_max &
-		OTF_DPC3_0_CORR_MASK, DPC_OTF_3C_MAX);
-}
-
-/* 2D Noise filter */
-void
-ipipe_set_d2f_regs(void __iomem *base_addr, unsigned int id,
-		   struct vpfe_ipipe_nf *noise_filter)
-{
-
-	u32 offset = D2F_1ST;
-	int count;
-	u32 val;
-
-	if (id == IPIPE_D2F_2ND)
-		offset = D2F_2ND;
-
-	ipipe_clock_enable(base_addr);
-	regw_ip(base_addr, noise_filter->en & 1, offset + D2F_EN);
-	if (!noise_filter->en)
-		return;
-
-	/*noise filter enabled */
-	/* Combine all the fields to make D2F_CFG register of IPIPE */
-	val = ((noise_filter->spread_val & D2F_SPR_VAL_MASK) <<
-		D2F_SPR_VAL_SHIFT) | ((noise_filter->shft_val &
-		D2F_SHFT_VAL_MASK) << D2F_SHFT_VAL_SHIFT) |
-		(noise_filter->gr_sample_meth << D2F_SAMPLE_METH_SHIFT) |
-		((noise_filter->apply_lsc_gain & 1) <<
-		D2F_APPLY_LSC_GAIN_SHIFT) | D2F_USE_SPR_REG_VAL;
-	regw_ip(base_addr, val, offset + D2F_TYP);
-
-	/* edge detection minimum */
-	regw_ip(base_addr, noise_filter->edge_det_min_thr &
-		D2F_EDGE_DET_THR_MASK, offset + D2F_EDG_MIN);
-
-	/* edge detection maximum */
-	regw_ip(base_addr, noise_filter->edge_det_max_thr &
-		D2F_EDGE_DET_THR_MASK, offset + D2F_EDG_MAX);
-
-	for (count = 0; count < VPFE_IPIPE_NF_STR_TABLE_SIZE; count++)
-		regw_ip(base_addr,
-			(noise_filter->str[count] & D2F_STR_VAL_MASK),
-			offset + D2F_STR + count * 4);
-
-	for (count = 0; count < VPFE_IPIPE_NF_THR_TABLE_SIZE; count++)
-		regw_ip(base_addr, noise_filter->thr[count] & D2F_THR_VAL_MASK,
-			offset + D2F_THR + count * 4);
-}
-
-#define IPIPE_U8Q5(decimal, integer) \
-	(((decimal & 0x1f) | ((integer & 0x7) << 5)))
-
-/* Green Imbalance Correction */
-void ipipe_set_gic_regs(void __iomem *base_addr, struct vpfe_ipipe_gic *gic)
-{
-	u32 val;
-
-	ipipe_clock_enable(base_addr);
-	regw_ip(base_addr, gic->en & 1, GIC_EN);
-
-	if (!gic->en)
-		return;
-
-	/*gic enabled */
-	val = (gic->wt_fn_type << GIC_TYP_SHIFT) |
-	      (gic->thr_sel << GIC_THR_SEL_SHIFT) |
-	      ((gic->apply_lsc_gain & 1) << GIC_APPLY_LSC_GAIN_SHIFT);
-	regw_ip(base_addr, val, GIC_TYP);
-
-	regw_ip(base_addr, gic->gain & GIC_GAIN_MASK, GIC_GAN);
-
-	if (gic->gic_alg != VPFE_IPIPE_GIC_ALG_ADAPT_GAIN) {
-		/* Constant Gain. Set threshold to maximum */
-		regw_ip(base_addr, GIC_THR_MASK, GIC_THR);
-		return;
-	}
-
-	if (gic->thr_sel == VPFE_IPIPE_GIC_THR_REG) {
-		regw_ip(base_addr, gic->thr & GIC_THR_MASK, GIC_THR);
-		regw_ip(base_addr, gic->slope & GIC_SLOPE_MASK, GIC_SLP);
-	} else {
-		/* Use NF thresholds */
-		val = IPIPE_U8Q5(gic->nf2_thr_gain.decimal,
-				gic->nf2_thr_gain.integer);
-		regw_ip(base_addr, val, GIC_NFGAN);
-	}
-}
-
-#define IPIPE_U13Q9(decimal, integer) \
-	(((decimal & 0x1ff) | ((integer & 0xf) << 9)))
-/* White balance */
-void ipipe_set_wb_regs(void __iomem *base_addr, struct vpfe_ipipe_wb *wb)
-{
-	u32 val;
-
-	ipipe_clock_enable(base_addr);
-	/* Ofsets. S12 */
-	regw_ip(base_addr, wb->ofst_r & WB_OFFSET_MASK, WB2_OFT_R);
-	regw_ip(base_addr, wb->ofst_gr & WB_OFFSET_MASK, WB2_OFT_GR);
-	regw_ip(base_addr, wb->ofst_gb & WB_OFFSET_MASK, WB2_OFT_GB);
-	regw_ip(base_addr, wb->ofst_b & WB_OFFSET_MASK, WB2_OFT_B);
-
-	/* Gains. U13Q9 */
-	val = IPIPE_U13Q9(wb->gain_r.decimal, wb->gain_r.integer);
-	regw_ip(base_addr, val, WB2_WGN_R);
-
-	val = IPIPE_U13Q9(wb->gain_gr.decimal, wb->gain_gr.integer);
-	regw_ip(base_addr, val, WB2_WGN_GR);
-
-	val = IPIPE_U13Q9(wb->gain_gb.decimal, wb->gain_gb.integer);
-	regw_ip(base_addr, val, WB2_WGN_GB);
-
-	val = IPIPE_U13Q9(wb->gain_b.decimal, wb->gain_b.integer);
-	regw_ip(base_addr, val, WB2_WGN_B);
-}
-
-/* CFA */
-void ipipe_set_cfa_regs(void __iomem *base_addr, struct vpfe_ipipe_cfa *cfa)
-{
-	ipipe_clock_enable(base_addr);
-
-	regw_ip(base_addr, cfa->alg, CFA_MODE);
-	regw_ip(base_addr, cfa->hpf_thr_2dir & CFA_HPF_THR_2DIR_MASK,
-		CFA_2DIR_HPF_THR);
-	regw_ip(base_addr, cfa->hpf_slp_2dir & CFA_HPF_SLOPE_2DIR_MASK,
-		CFA_2DIR_HPF_SLP);
-	regw_ip(base_addr, cfa->hp_mix_thr_2dir & CFA_HPF_MIX_THR_2DIR_MASK,
-		CFA_2DIR_MIX_THR);
-	regw_ip(base_addr, cfa->hp_mix_slope_2dir & CFA_HPF_MIX_SLP_2DIR_MASK,
-		CFA_2DIR_MIX_SLP);
-	regw_ip(base_addr, cfa->dir_thr_2dir & CFA_DIR_THR_2DIR_MASK,
-		CFA_2DIR_DIR_THR);
-	regw_ip(base_addr, cfa->dir_slope_2dir & CFA_DIR_SLP_2DIR_MASK,
-		CFA_2DIR_DIR_SLP);
-	regw_ip(base_addr, cfa->nd_wt_2dir & CFA_ND_WT_2DIR_MASK,
-		CFA_2DIR_NDWT);
-	regw_ip(base_addr, cfa->hue_fract_daa & CFA_DAA_HUE_FRA_MASK,
-		CFA_MONO_HUE_FRA);
-	regw_ip(base_addr, cfa->edge_thr_daa & CFA_DAA_EDG_THR_MASK,
-		CFA_MONO_EDG_THR);
-	regw_ip(base_addr, cfa->thr_min_daa & CFA_DAA_THR_MIN_MASK,
-		CFA_MONO_THR_MIN);
-	regw_ip(base_addr, cfa->thr_slope_daa & CFA_DAA_THR_SLP_MASK,
-		CFA_MONO_THR_SLP);
-	regw_ip(base_addr, cfa->slope_min_daa & CFA_DAA_SLP_MIN_MASK,
-		CFA_MONO_SLP_MIN);
-	regw_ip(base_addr, cfa->slope_slope_daa & CFA_DAA_SLP_SLP_MASK,
-		CFA_MONO_SLP_SLP);
-	regw_ip(base_addr, cfa->lp_wt_daa & CFA_DAA_LP_WT_MASK,
-		CFA_MONO_LPWT);
-}
-
-void
-ipipe_set_rgb2rgb_regs(void __iomem *base_addr, unsigned int id,
-		       struct vpfe_ipipe_rgb2rgb *rgb)
-{
-	u32 offset_mask = RGB2RGB_1_OFST_MASK;
-	u32 offset = RGB1_MUL_BASE;
-	u32 integ_mask = 0xf;
-	u32 val;
-
-	ipipe_clock_enable(base_addr);
-
-	if (id == IPIPE_RGB2RGB_2) {
-		/*
-		 * For second RGB module, gain integer is 3 bits instead
-		 * of 4, offset has 11 bits insread of 13
-		 */
-		offset = RGB2_MUL_BASE;
-		integ_mask = 0x7;
-		offset_mask = RGB2RGB_2_OFST_MASK;
-	}
-	/* Gains */
-	val = (rgb->coef_rr.decimal & 0xff) |
-		((rgb->coef_rr.integer & integ_mask) << 8);
-	regw_ip(base_addr, val, offset + RGB_MUL_RR);
-	val = (rgb->coef_gr.decimal & 0xff) |
-		((rgb->coef_gr.integer & integ_mask) << 8);
-	regw_ip(base_addr, val, offset + RGB_MUL_GR);
-	val = (rgb->coef_br.decimal & 0xff) |
-		((rgb->coef_br.integer & integ_mask) << 8);
-	regw_ip(base_addr, val, offset + RGB_MUL_BR);
-	val = (rgb->coef_rg.decimal & 0xff) |
-		((rgb->coef_rg.integer & integ_mask) << 8);
-	regw_ip(base_addr, val, offset + RGB_MUL_RG);
-	val = (rgb->coef_gg.decimal & 0xff) |
-		((rgb->coef_gg.integer & integ_mask) << 8);
-	regw_ip(base_addr, val, offset + RGB_MUL_GG);
-	val = (rgb->coef_bg.decimal & 0xff) |
-		((rgb->coef_bg.integer & integ_mask) << 8);
-	regw_ip(base_addr, val, offset + RGB_MUL_BG);
-	val = (rgb->coef_rb.decimal & 0xff) |
-		((rgb->coef_rb.integer & integ_mask) << 8);
-	regw_ip(base_addr, val, offset + RGB_MUL_RB);
-	val = (rgb->coef_gb.decimal & 0xff) |
-		((rgb->coef_gb.integer & integ_mask) << 8);
-	regw_ip(base_addr, val, offset + RGB_MUL_GB);
-	val = (rgb->coef_bb.decimal & 0xff) |
-		((rgb->coef_bb.integer & integ_mask) << 8);
-	regw_ip(base_addr, val, offset + RGB_MUL_BB);
-
-	/* Offsets */
-	regw_ip(base_addr, rgb->out_ofst_r & offset_mask, offset + RGB_OFT_OR);
-	regw_ip(base_addr, rgb->out_ofst_g & offset_mask, offset + RGB_OFT_OG);
-	regw_ip(base_addr, rgb->out_ofst_b & offset_mask, offset + RGB_OFT_OB);
-}
-
-static void
-ipipe_update_gamma_tbl(void __iomem *isp5_base_addr,
-	struct vpfe_ipipe_gamma_entry *table, int size, u32 addr)
-{
-	int count;
-	u32 val;
-
-	for (count = 0; count < size; count++) {
-		val = table[count].slope & GAMMA_MASK;
-		val |= (table[count].offset & GAMMA_MASK) << GAMMA_SHIFT;
-		w_ip_table(isp5_base_addr, val, (addr + (count * 4)));
-	}
-}
-
-void
-ipipe_set_gamma_regs(void __iomem *base_addr, void __iomem *isp5_base_addr,
-			  struct vpfe_ipipe_gamma *gamma)
-{
-	int table_size;
-	u32 val;
-
-	ipipe_clock_enable(base_addr);
-	val = (gamma->bypass_r << GAMMA_BYPR_SHIFT) |
-		(gamma->bypass_b << GAMMA_BYPG_SHIFT) |
-		(gamma->bypass_g << GAMMA_BYPB_SHIFT) |
-		(gamma->tbl_sel << GAMMA_TBL_SEL_SHIFT) |
-		(gamma->tbl_size << GAMMA_TBL_SIZE_SHIFT);
-
-	regw_ip(base_addr, val, GMM_CFG);
-
-	if (gamma->tbl_sel != VPFE_IPIPE_GAMMA_TBL_RAM)
-		return;
-
-	table_size = gamma->tbl_size;
-
-	if (!gamma->bypass_r)
-		ipipe_update_gamma_tbl(isp5_base_addr, gamma->table_r,
-			table_size, GAMMA_R_START_ADDR);
-	if (!gamma->bypass_b)
-		ipipe_update_gamma_tbl(isp5_base_addr, gamma->table_b,
-			table_size, GAMMA_B_START_ADDR);
-	if (!gamma->bypass_g)
-		ipipe_update_gamma_tbl(isp5_base_addr, gamma->table_g,
-			table_size, GAMMA_G_START_ADDR);
-}
-
-void
-ipipe_set_3d_lut_regs(void __iomem *base_addr, void __iomem *isp5_base_addr,
-			   struct vpfe_ipipe_3d_lut *lut_3d)
-{
-	struct vpfe_ipipe_3d_lut_entry *tbl;
-	u32 bnk_index;
-	u32 tbl_index;
-	u32 val;
-	u32 i;
-
-	ipipe_clock_enable(base_addr);
-	regw_ip(base_addr, lut_3d->en, D3LUT_EN);
-
-	if (!lut_3d->en)
-		return;
-
-	/* valid table */
-	tbl = lut_3d->table;
-	for (i = 0; i < VPFE_IPIPE_MAX_SIZE_3D_LUT; i++) {
-		/*
-		 * Each entry has 0-9 (B), 10-19 (G) and
-		 * 20-29 R values
-		 */
-		val = tbl[i].b & D3_LUT_ENTRY_MASK;
-		val |= (tbl[i].g & D3_LUT_ENTRY_MASK) <<
-			 D3_LUT_ENTRY_G_SHIFT;
-		val |= (tbl[i].r & D3_LUT_ENTRY_MASK) <<
-			 D3_LUT_ENTRY_R_SHIFT;
-		bnk_index = i % 4;
-		tbl_index = i >> 2;
-		tbl_index <<= 2;
-		if (bnk_index == 0)
-			w_ip_table(isp5_base_addr, val,
-				   tbl_index + D3L_TB0_START_ADDR);
-		else if (bnk_index == 1)
-			w_ip_table(isp5_base_addr, val,
-				   tbl_index + D3L_TB1_START_ADDR);
-		else if (bnk_index == 2)
-			w_ip_table(isp5_base_addr, val,
-				   tbl_index + D3L_TB2_START_ADDR);
-		else
-			w_ip_table(isp5_base_addr, val,
-				   tbl_index + D3L_TB3_START_ADDR);
-	}
-}
-
-/* Lumina adjustments */
-void
-ipipe_set_lum_adj_regs(void __iomem *base_addr, struct ipipe_lum_adj *lum_adj)
-{
-	u32 val;
-
-	ipipe_clock_enable(base_addr);
-
-	/* combine fields of YUV_ADJ to set brightness and contrast */
-	val = lum_adj->contrast << LUM_ADJ_CONTR_SHIFT |
-	      lum_adj->brightness << LUM_ADJ_BRIGHT_SHIFT;
-	regw_ip(base_addr, val, YUV_ADJ);
-}
-
-inline u32 ipipe_s12q8(unsigned short decimal, short integer)
-{
-	return (decimal & 0xff) | ((integer & 0xf) << 8);
-}
-
-void ipipe_set_rgb2ycbcr_regs(void __iomem *base_addr,
-			      struct vpfe_ipipe_rgb2yuv *yuv)
-{
-	u32 val;
-
-	/* S10Q8 */
-	ipipe_clock_enable(base_addr);
-	val = ipipe_s12q8(yuv->coef_ry.decimal, yuv->coef_ry.integer);
-	regw_ip(base_addr, val, YUV_MUL_RY);
-	val = ipipe_s12q8(yuv->coef_gy.decimal, yuv->coef_gy.integer);
-	regw_ip(base_addr, val, YUV_MUL_GY);
-	val = ipipe_s12q8(yuv->coef_by.decimal, yuv->coef_by.integer);
-	regw_ip(base_addr, val, YUV_MUL_BY);
-	val = ipipe_s12q8(yuv->coef_rcb.decimal, yuv->coef_rcb.integer);
-	regw_ip(base_addr, val, YUV_MUL_RCB);
-	val = ipipe_s12q8(yuv->coef_gcb.decimal, yuv->coef_gcb.integer);
-	regw_ip(base_addr, val, YUV_MUL_GCB);
-	val = ipipe_s12q8(yuv->coef_bcb.decimal, yuv->coef_bcb.integer);
-	regw_ip(base_addr, val, YUV_MUL_BCB);
-	val = ipipe_s12q8(yuv->coef_rcr.decimal, yuv->coef_rcr.integer);
-	regw_ip(base_addr, val, YUV_MUL_RCR);
-	val = ipipe_s12q8(yuv->coef_gcr.decimal, yuv->coef_gcr.integer);
-	regw_ip(base_addr, val, YUV_MUL_GCR);
-	val = ipipe_s12q8(yuv->coef_bcr.decimal, yuv->coef_bcr.integer);
-	regw_ip(base_addr, val, YUV_MUL_BCR);
-	regw_ip(base_addr, yuv->out_ofst_y & RGB2YCBCR_OFST_MASK, YUV_OFT_Y);
-	regw_ip(base_addr, yuv->out_ofst_cb & RGB2YCBCR_OFST_MASK, YUV_OFT_CB);
-	regw_ip(base_addr, yuv->out_ofst_cr & RGB2YCBCR_OFST_MASK, YUV_OFT_CR);
-}
-
-/* YUV 422 conversion */
-void
-ipipe_set_yuv422_conv_regs(void __iomem *base_addr,
-			   struct vpfe_ipipe_yuv422_conv *conv)
-{
-	u32 val;
-
-	ipipe_clock_enable(base_addr);
-
-	/* Combine all the fields to make YUV_PHS register of IPIPE */
-	val = (conv->chrom_pos << 0) | (conv->en_chrom_lpf << 1);
-	regw_ip(base_addr, val, YUV_PHS);
-}
-
-void
-ipipe_set_gbce_regs(void __iomem *base_addr, void __iomem *isp5_base_addr,
-		    struct vpfe_ipipe_gbce *gbce)
-{
-	unsigned int count;
-	u32 mask = GBCE_Y_VAL_MASK;
-
-	if (gbce->type == VPFE_IPIPE_GBCE_GAIN_TBL)
-		mask = GBCE_GAIN_VAL_MASK;
-
-	ipipe_clock_enable(base_addr);
-	regw_ip(base_addr, gbce->en & 1, GBCE_EN);
-
-	if (!gbce->en)
-		return;
-
-	regw_ip(base_addr, gbce->type, GBCE_TYP);
-
-	for (count = 0; count < VPFE_IPIPE_MAX_SIZE_GBCE_LUT; count += 2)
-		w_ip_table(isp5_base_addr, ((gbce->table[count + 1] & mask) <<
-		GBCE_ENTRY_SHIFT) | (gbce->table[count] & mask),
-		((count/2) << 2) + GBCE_TB_START_ADDR);
-}
-
-void
-ipipe_set_ee_regs(void __iomem *base_addr, void __iomem *isp5_base_addr,
-		  struct vpfe_ipipe_yee *ee)
-{
-	unsigned int count;
-	u32 val;
-
-	ipipe_clock_enable(base_addr);
-	regw_ip(base_addr, ee->en, YEE_EN);
-
-	if (!ee->en)
-		return;
-
-	val = ee->en_halo_red & 1;
-	val |= ee->merge_meth << YEE_HALO_RED_EN_SHIFT;
-	regw_ip(base_addr, val, YEE_TYP);
-
-	regw_ip(base_addr, ee->hpf_shft, YEE_SHF);
-	regw_ip(base_addr, ee->hpf_coef_00 & YEE_COEF_MASK, YEE_MUL_00);
-	regw_ip(base_addr, ee->hpf_coef_01 & YEE_COEF_MASK, YEE_MUL_01);
-	regw_ip(base_addr, ee->hpf_coef_02 & YEE_COEF_MASK, YEE_MUL_02);
-	regw_ip(base_addr, ee->hpf_coef_10 & YEE_COEF_MASK, YEE_MUL_10);
-	regw_ip(base_addr, ee->hpf_coef_11 & YEE_COEF_MASK, YEE_MUL_11);
-	regw_ip(base_addr, ee->hpf_coef_12 & YEE_COEF_MASK, YEE_MUL_12);
-	regw_ip(base_addr, ee->hpf_coef_20 & YEE_COEF_MASK, YEE_MUL_20);
-	regw_ip(base_addr, ee->hpf_coef_21 & YEE_COEF_MASK, YEE_MUL_21);
-	regw_ip(base_addr, ee->hpf_coef_22 & YEE_COEF_MASK, YEE_MUL_22);
-	regw_ip(base_addr, ee->yee_thr & YEE_THR_MASK, YEE_THR);
-	regw_ip(base_addr, ee->es_gain & YEE_ES_GAIN_MASK, YEE_E_GAN);
-	regw_ip(base_addr, ee->es_thr1 & YEE_ES_THR1_MASK, YEE_E_THR1);
-	regw_ip(base_addr, ee->es_thr2 & YEE_THR_MASK, YEE_E_THR2);
-	regw_ip(base_addr, ee->es_gain_grad & YEE_THR_MASK, YEE_G_GAN);
-	regw_ip(base_addr, ee->es_ofst_grad & YEE_THR_MASK, YEE_G_OFT);
-
-	for (count = 0; count < VPFE_IPIPE_MAX_SIZE_YEE_LUT; count += 2)
-		w_ip_table(isp5_base_addr, ((ee->table[count + 1] &
-		YEE_ENTRY_MASK) << YEE_ENTRY_SHIFT) |
-		(ee->table[count] & YEE_ENTRY_MASK),
-		((count/2) << 2) + YEE_TB_START_ADDR);
-}
-
-/* Chromatic Artifact Correction. CAR */
-static void ipipe_set_mf(void __iomem *base_addr)
-{
-	/* typ to dynamic switch */
-	regw_ip(base_addr, VPFE_IPIPE_CAR_DYN_SWITCH, CAR_TYP);
-	/* Set SW0 to maximum */
-	regw_ip(base_addr, CAR_MF_THR, CAR_SW);
-}
-
-static void
-ipipe_set_gain_ctrl(void __iomem *base_addr, struct vpfe_ipipe_car *car)
-{
-	regw_ip(base_addr, VPFE_IPIPE_CAR_CHR_GAIN_CTRL, CAR_TYP);
-	regw_ip(base_addr, car->hpf, CAR_HPF_TYP);
-	regw_ip(base_addr, car->hpf_shft & CAR_HPF_SHIFT_MASK, CAR_HPF_SHF);
-	regw_ip(base_addr, car->hpf_thr, CAR_HPF_THR);
-	regw_ip(base_addr, car->gain1.gain, CAR_GN1_GAN);
-	regw_ip(base_addr, car->gain1.shft & CAR_GAIN1_SHFT_MASK, CAR_GN1_SHF);
-	regw_ip(base_addr, car->gain1.gain_min & CAR_GAIN_MIN_MASK,
-		CAR_GN1_MIN);
-	regw_ip(base_addr, car->gain2.gain, CAR_GN2_GAN);
-	regw_ip(base_addr, car->gain2.shft & CAR_GAIN2_SHFT_MASK, CAR_GN2_SHF);
-	regw_ip(base_addr, car->gain2.gain_min & CAR_GAIN_MIN_MASK,
-		CAR_GN2_MIN);
-}
-
-void ipipe_set_car_regs(void __iomem *base_addr, struct vpfe_ipipe_car *car)
-{
-	u32 val;
-
-	ipipe_clock_enable(base_addr);
-	regw_ip(base_addr, car->en, CAR_EN);
-
-	if (!car->en)
-		return;
-
-	switch (car->meth) {
-	case VPFE_IPIPE_CAR_MED_FLTR:
-		ipipe_set_mf(base_addr);
-		break;
-
-	case VPFE_IPIPE_CAR_CHR_GAIN_CTRL:
-		ipipe_set_gain_ctrl(base_addr, car);
-		break;
-
-	default:
-		/* Dynamic switch between MF and Gain Ctrl. */
-		ipipe_set_mf(base_addr);
-		ipipe_set_gain_ctrl(base_addr, car);
-		/* Set the threshold for switching between
-		 * the two Here we overwrite the MF SW0 value
-		 */
-		regw_ip(base_addr, VPFE_IPIPE_CAR_DYN_SWITCH, CAR_TYP);
-		val = car->sw1;
-		val <<= CAR_SW1_SHIFT;
-		val |= car->sw0;
-		regw_ip(base_addr, val, CAR_SW);
-	}
-}
-
-/* Chromatic Gain Suppression */
-void ipipe_set_cgs_regs(void __iomem *base_addr, struct vpfe_ipipe_cgs *cgs)
-{
-	ipipe_clock_enable(base_addr);
-	regw_ip(base_addr, cgs->en, CGS_EN);
-
-	if (!cgs->en)
-		return;
-
-	/* Set the bright side parameters */
-	regw_ip(base_addr, cgs->h_thr, CGS_GN1_H_THR);
-	regw_ip(base_addr, cgs->h_slope, CGS_GN1_H_GAN);
-	regw_ip(base_addr, cgs->h_shft & CAR_SHIFT_MASK, CGS_GN1_H_SHF);
-	regw_ip(base_addr, cgs->h_min, CGS_GN1_H_MIN);
-}
-
-void rsz_src_enable(void __iomem *rsz_base, int enable)
-{
-	regw_rsz(rsz_base, enable, RSZ_SRC_EN);
-}
-
-int rsz_enable(void __iomem *rsz_base, int rsz_id, int enable)
-{
-	if (rsz_id == RSZ_A) {
-		regw_rsz(rsz_base, enable, RSZ_EN_A);
-		/* We always enable RSZ_A. RSZ_B is enable upon request from
-		 * application. So enable RSZ_SRC_EN along with RSZ_A
-		 */
-		regw_rsz(rsz_base, enable, RSZ_SRC_EN);
-	} else if (rsz_id == RSZ_B) {
-		regw_rsz(rsz_base, enable, RSZ_EN_B);
-	} else {
-		BUG();
-	}
-
-	return 0;
-}
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h b/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h
deleted file mode 100644
index 16b6a14..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe_hw.h
+++ /dev/null
@@ -1,556 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _DAVINCI_VPFE_DM365_IPIPE_HW_H
-#define _DAVINCI_VPFE_DM365_IPIPE_HW_H
-
-#include "vpfe_mc_capture.h"
-
-#define SET_LOW_ADDR     0x0000ffff
-#define SET_HIGH_ADDR    0xffff0000
-
-/* Below are the internal tables */
-#define DPC_TB0_START_ADDR	0x8000
-#define DPC_TB1_START_ADDR	0x8400
-
-#define GAMMA_R_START_ADDR	0xa800
-#define GAMMA_G_START_ADDR	0xb000
-#define GAMMA_B_START_ADDR	0xb800
-
-/* RAM table addresses for edge enhancement correction*/
-#define YEE_TB_START_ADDR	0x8800
-
-/* RAM table address for GBC LUT */
-#define GBCE_TB_START_ADDR	0x9000
-
-/* RAM table for 3D NF LUT */
-#define D3L_TB0_START_ADDR	0x9800
-#define D3L_TB1_START_ADDR	0x9c00
-#define D3L_TB2_START_ADDR	0xa000
-#define D3L_TB3_START_ADDR	0xa400
-
-/* IPIPE Register Offsets from the base address */
-#define IPIPE_SRC_EN		0x0000
-#define IPIPE_SRC_MODE		0x0004
-#define IPIPE_SRC_FMT		0x0008
-#define IPIPE_SRC_COL		0x000c
-#define IPIPE_SRC_VPS		0x0010
-#define IPIPE_SRC_VSZ		0x0014
-#define IPIPE_SRC_HPS		0x0018
-#define IPIPE_SRC_HSZ		0x001c
-
-#define IPIPE_SEL_SBU		0x0020
-
-#define IPIPE_DMA_STA		0x0024
-#define IPIPE_GCK_MMR		0x0028
-#define IPIPE_GCK_PIX		0x002c
-#define IPIPE_RESERVED0		0x0030
-
-/* Defect Correction */
-#define DPC_LUT_EN		0x0034
-#define DPC_LUT_SEL		0x0038
-#define DPC_LUT_ADR		0x003c
-#define DPC_LUT_SIZ		0x0040
-#define DPC_OTF_EN		0x0044
-#define DPC_OTF_TYP		0x0048
-#define DPC_OTF_2D_THR_R	0x004c
-#define DPC_OTF_2D_THR_GR	0x0050
-#define DPC_OTF_2D_THR_GB	0x0054
-#define DPC_OTF_2D_THR_B	0x0058
-#define DPC_OTF_2C_THR_R	0x005c
-#define DPC_OTF_2C_THR_GR	0x0060
-#define DPC_OTF_2C_THR_GB	0x0064
-#define DPC_OTF_2C_THR_B	0x0068
-#define DPC_OTF_3_SHF		0x006c
-#define DPC_OTF_3D_THR		0x0070
-#define DPC_OTF_3D_SLP		0x0074
-#define DPC_OTF_3D_MIN		0x0078
-#define DPC_OTF_3D_MAX		0x007c
-#define DPC_OTF_3C_THR		0x0080
-#define DPC_OTF_3C_SLP		0x0084
-#define DPC_OTF_3C_MIN		0x0088
-#define DPC_OTF_3C_MAX		0x008c
-
-/* Lense Shading Correction */
-#define LSC_VOFT		0x90
-#define LSC_VA2			0x94
-#define LSC_VA1			0x98
-#define LSC_VS			0x9c
-#define LSC_HOFT		0xa0
-#define LSC_HA2			0xa4
-#define LSC_HA1			0xa8
-#define LSC_HS			0xac
-#define LSC_GAIN_R		0xb0
-#define LSC_GAIN_GR		0xb4
-#define LSC_GAIN_GB		0xb8
-#define LSC_GAIN_B		0xbc
-#define LSC_OFT_R		0xc0
-#define LSC_OFT_GR		0xc4
-#define LSC_OFT_GB		0xc8
-#define LSC_OFT_B		0xcc
-#define LSC_SHF			0xd0
-#define LSC_MAX			0xd4
-
-/* Noise Filter 1. Ofsets from start address given */
-#define D2F_1ST			0xd8
-#define D2F_EN			0x0
-#define D2F_TYP			0x4
-#define D2F_THR			0x8
-#define D2F_STR			0x28
-#define D2F_SPR			0x48
-#define D2F_EDG_MIN		0x68
-#define D2F_EDG_MAX		0x6c
-
-/* Noise Filter 2 */
-#define D2F_2ND			0x148
-
-/* GIC */
-#define GIC_EN			0x1b8
-#define GIC_TYP			0x1bc
-#define GIC_GAN			0x1c0
-#define GIC_NFGAN		0x1c4
-#define GIC_THR			0x1c8
-#define GIC_SLP			0x1cc
-
-/* White Balance */
-#define WB2_OFT_R		0x1d0
-#define WB2_OFT_GR		0x1d4
-#define WB2_OFT_GB		0x1d8
-#define WB2_OFT_B		0x1dc
-#define WB2_WGN_R		0x1e0
-#define WB2_WGN_GR		0x1e4
-#define WB2_WGN_GB		0x1e8
-#define WB2_WGN_B		0x1ec
-
-/* CFA interpolation */
-#define CFA_MODE		0x1f0
-#define CFA_2DIR_HPF_THR	0x1f4
-#define CFA_2DIR_HPF_SLP	0x1f8
-#define CFA_2DIR_MIX_THR	0x1fc
-#define CFA_2DIR_MIX_SLP	0x200
-#define CFA_2DIR_DIR_THR	0x204
-#define CFA_2DIR_DIR_SLP	0x208
-#define CFA_2DIR_NDWT		0x20c
-#define CFA_MONO_HUE_FRA	0x210
-#define CFA_MONO_EDG_THR	0x214
-#define CFA_MONO_THR_MIN	0x218
-#define CFA_MONO_THR_SLP	0x21c
-#define CFA_MONO_SLP_MIN	0x220
-#define CFA_MONO_SLP_SLP	0x224
-#define CFA_MONO_LPWT		0x228
-
-/* RGB to RGB conversiona - 1st */
-#define RGB1_MUL_BASE		0x22c
-/* Offsets from base */
-#define RGB_MUL_RR		0x0
-#define RGB_MUL_GR		0x4
-#define RGB_MUL_BR		0x8
-#define RGB_MUL_RG		0xc
-#define RGB_MUL_GG		0x10
-#define RGB_MUL_BG		0x14
-#define RGB_MUL_RB		0x18
-#define RGB_MUL_GB		0x1c
-#define RGB_MUL_BB		0x20
-#define RGB_OFT_OR		0x24
-#define RGB_OFT_OG		0x28
-#define RGB_OFT_OB		0x2c
-
-/* Gamma */
-#define GMM_CFG			0x25c
-
-/* RGB to RGB conversiona - 2nd */
-#define RGB2_MUL_BASE		0x260
-
-/* 3D LUT */
-#define D3LUT_EN		0x290
-
-/* RGB to YUV(YCbCr) conversion */
-#define YUV_ADJ			0x294
-#define YUV_MUL_RY		0x298
-#define YUV_MUL_GY		0x29c
-#define YUV_MUL_BY		0x2a0
-#define YUV_MUL_RCB		0x2a4
-#define YUV_MUL_GCB		0x2a8
-#define YUV_MUL_BCB		0x2ac
-#define YUV_MUL_RCR		0x2b0
-#define YUV_MUL_GCR		0x2b4
-#define YUV_MUL_BCR		0x2b8
-#define YUV_OFT_Y		0x2bc
-#define YUV_OFT_CB		0x2c0
-#define YUV_OFT_CR		0x2c4
-#define YUV_PHS			0x2c8
-
-/* Global Brightness and Contrast */
-#define GBCE_EN			0x2cc
-#define GBCE_TYP		0x2d0
-
-/* Edge Enhancer */
-#define YEE_EN			0x2d4
-#define YEE_TYP			0x2d8
-#define YEE_SHF			0x2dc
-#define YEE_MUL_00		0x2e0
-#define YEE_MUL_01		0x2e4
-#define YEE_MUL_02		0x2e8
-#define YEE_MUL_10		0x2ec
-#define YEE_MUL_11		0x2f0
-#define YEE_MUL_12		0x2f4
-#define YEE_MUL_20		0x2f8
-#define YEE_MUL_21		0x2fc
-#define YEE_MUL_22		0x300
-#define YEE_THR			0x304
-#define YEE_E_GAN		0x308
-#define YEE_E_THR1		0x30c
-#define YEE_E_THR2		0x310
-#define YEE_G_GAN		0x314
-#define YEE_G_OFT		0x318
-
-/* Chroma Artifact Reduction */
-#define CAR_EN			0x31c
-#define CAR_TYP			0x320
-#define CAR_SW			0x324
-#define CAR_HPF_TYP		0x328
-#define CAR_HPF_SHF		0x32c
-#define	CAR_HPF_THR		0x330
-#define CAR_GN1_GAN		0x334
-#define CAR_GN1_SHF		0x338
-#define CAR_GN1_MIN		0x33c
-#define CAR_GN2_GAN		0x340
-#define CAR_GN2_SHF		0x344
-#define CAR_GN2_MIN		0x348
-
-/* Chroma Gain Suppression */
-#define CGS_EN			0x34c
-#define CGS_GN1_L_THR		0x350
-#define CGS_GN1_L_GAN		0x354
-#define CGS_GN1_L_SHF		0x358
-#define CGS_GN1_L_MIN		0x35c
-#define CGS_GN1_H_THR		0x360
-#define CGS_GN1_H_GAN		0x364
-#define CGS_GN1_H_SHF		0x368
-#define CGS_GN1_H_MIN		0x36c
-#define CGS_GN2_L_THR		0x370
-#define CGS_GN2_L_GAN		0x374
-#define CGS_GN2_L_SHF		0x378
-#define CGS_GN2_L_MIN		0x37c
-
-/* Resizer */
-#define RSZ_SRC_EN		0x0
-#define RSZ_SRC_MODE		0x4
-#define RSZ_SRC_FMT0		0x8
-#define RSZ_SRC_FMT1		0xc
-#define RSZ_SRC_VPS		0x10
-#define RSZ_SRC_VSZ		0x14
-#define RSZ_SRC_HPS		0x18
-#define RSZ_SRC_HSZ		0x1c
-#define RSZ_DMA_RZA		0x20
-#define RSZ_DMA_RZB		0x24
-#define RSZ_DMA_STA		0x28
-#define RSZ_GCK_MMR		0x2c
-#define RSZ_RESERVED0		0x30
-#define RSZ_GCK_SDR		0x34
-#define RSZ_IRQ_RZA		0x38
-#define RSZ_IRQ_RZB		0x3c
-#define RSZ_YUV_Y_MIN		0x40
-#define RSZ_YUV_Y_MAX		0x44
-#define RSZ_YUV_C_MIN		0x48
-#define RSZ_YUV_C_MAX		0x4c
-#define RSZ_YUV_PHS		0x50
-#define RSZ_SEQ			0x54
-
-/* Resizer Rescale Parameters */
-#define RSZ_EN_A		0x58
-#define RSZ_EN_B		0xe8
-/*
- * offset of the registers to be added with base register of
- * either RSZ0 or RSZ1
- */
-#define RSZ_MODE		0x4
-#define RSZ_420			0x8
-#define RSZ_I_VPS		0xc
-#define RSZ_I_HPS		0x10
-#define RSZ_O_VSZ		0x14
-#define RSZ_O_HSZ		0x18
-#define RSZ_V_PHS_Y		0x1c
-#define RSZ_V_PHS_C		0x20
-#define RSZ_V_DIF		0x24
-#define RSZ_V_TYP		0x28
-#define RSZ_V_LPF		0x2c
-#define RSZ_H_PHS		0x30
-#define RSZ_H_PHS_ADJ		0x34
-#define RSZ_H_DIF		0x38
-#define RSZ_H_TYP		0x3c
-#define RSZ_H_LPF		0x40
-#define RSZ_DWN_EN		0x44
-#define RSZ_DWN_AV		0x48
-
-/* Resizer RGB Conversion Parameters */
-#define RSZ_RGB_EN		0x4c
-#define RSZ_RGB_TYP		0x50
-#define RSZ_RGB_BLD		0x54
-
-/* Resizer External Memory Parameters */
-#define RSZ_SDR_Y_BAD_H		0x58
-#define RSZ_SDR_Y_BAD_L		0x5c
-#define RSZ_SDR_Y_SAD_H		0x60
-#define RSZ_SDR_Y_SAD_L		0x64
-#define RSZ_SDR_Y_OFT		0x68
-#define RSZ_SDR_Y_PTR_S		0x6c
-#define RSZ_SDR_Y_PTR_E		0x70
-#define RSZ_SDR_C_BAD_H		0x74
-#define RSZ_SDR_C_BAD_L		0x78
-#define RSZ_SDR_C_SAD_H		0x7c
-#define RSZ_SDR_C_SAD_L		0x80
-#define RSZ_SDR_C_OFT		0x84
-#define RSZ_SDR_C_PTR_S		0x88
-#define RSZ_SDR_C_PTR_E		0x8c
-
-/* Macro for resizer */
-#define RSZ_YUV_Y_MIN		0x40
-#define RSZ_YUV_Y_MAX		0x44
-#define RSZ_YUV_C_MIN		0x48
-#define RSZ_YUV_C_MAX		0x4c
-
-#define IPIPE_GCK_MMR_DEFAULT	1
-#define IPIPE_GCK_PIX_DEFAULT	0xe
-#define RSZ_GCK_MMR_DEFAULT	1
-#define RSZ_GCK_SDR_DEFAULT	1
-
-/* LUTDPC */
-#define LUTDPC_TBL_256_EN	0
-#define LUTDPC_INF_TBL_EN	1
-#define LUT_DPC_START_ADDR	0
-#define LUT_DPC_H_POS_MASK	0x1fff
-#define LUT_DPC_V_POS_MASK	0x1fff
-#define LUT_DPC_V_POS_SHIFT	13
-#define LUT_DPC_CORR_METH_SHIFT	26
-#define LUT_DPC_MAX_SIZE	256
-#define LUT_DPC_SIZE_MASK	0x3ff
-
-/* OTFDPC */
-#define OTFDPC_DPC2_THR_MASK	0xfff
-#define OTF_DET_METHOD_SHIFT	1
-#define OTF_DPC3_0_SHF_MASK	3
-#define OTF_DPC3_0_THR_SHIFT	6
-#define OTF_DPC3_0_THR_MASK	0x3f
-#define OTF_DPC3_0_SLP_MASK	0x3f
-#define OTF_DPC3_0_DET_MASK	0xfff
-#define OTF_DPC3_0_CORR_MASK	0xfff
-
-/* NF (D2F) */
-#define D2F_SPR_VAL_MASK		0x1f
-#define D2F_SPR_VAL_SHIFT		0
-#define D2F_SHFT_VAL_MASK		3
-#define D2F_SHFT_VAL_SHIFT		5
-#define D2F_SAMPLE_METH_SHIFT		7
-#define D2F_APPLY_LSC_GAIN_SHIFT	8
-#define D2F_USE_SPR_REG_VAL		0
-#define D2F_STR_VAL_MASK		0x1f
-#define D2F_THR_VAL_MASK		0x3ff
-#define D2F_EDGE_DET_THR_MASK		0x7ff
-
-/* Green Imbalance Correction */
-#define GIC_TYP_SHIFT			0
-#define GIC_THR_SEL_SHIFT		1
-#define	GIC_APPLY_LSC_GAIN_SHIFT	2
-#define GIC_GAIN_MASK			0xff
-#define GIC_THR_MASK			0xfff
-#define GIC_SLOPE_MASK			0xfff
-#define GIC_NFGAN_INT_MASK		7
-#define GIC_NFGAN_DECI_MASK		0x1f
-
-/* WB */
-#define WB_OFFSET_MASK			0xfff
-#define WB_GAIN_INT_MASK		0xf
-#define WB_GAIN_DECI_MASK		0x1ff
-
-/* CFA */
-#define CFA_HPF_THR_2DIR_MASK		0x1fff
-#define CFA_HPF_SLOPE_2DIR_MASK		0x3ff
-#define CFA_HPF_MIX_THR_2DIR_MASK	0x1fff
-#define CFA_HPF_MIX_SLP_2DIR_MASK	0x3ff
-#define CFA_DIR_THR_2DIR_MASK		0x3ff
-#define CFA_DIR_SLP_2DIR_MASK		0x7f
-#define CFA_ND_WT_2DIR_MASK		0x3f
-#define CFA_DAA_HUE_FRA_MASK		0x3f
-#define CFA_DAA_EDG_THR_MASK		0xff
-#define CFA_DAA_THR_MIN_MASK		0x3ff
-#define CFA_DAA_THR_SLP_MASK		0x3ff
-#define CFA_DAA_SLP_MIN_MASK		0x3ff
-#define CFA_DAA_SLP_SLP_MASK		0x3ff
-#define CFA_DAA_LP_WT_MASK		0x3f
-
-/* RGB2RGB */
-#define RGB2RGB_1_OFST_MASK		0x1fff
-#define RGB2RGB_1_GAIN_INT_MASK		0xf
-#define RGB2RGB_GAIN_DECI_MASK		0xff
-#define RGB2RGB_2_OFST_MASK		0x7ff
-#define RGB2RGB_2_GAIN_INT_MASK		0x7
-
-/* Gamma */
-#define GAMMA_BYPR_SHIFT		0
-#define GAMMA_BYPG_SHIFT		1
-#define GAMMA_BYPB_SHIFT		2
-#define GAMMA_TBL_SEL_SHIFT		4
-#define GAMMA_TBL_SIZE_SHIFT		5
-#define GAMMA_MASK			0x3ff
-#define GAMMA_SHIFT			10
-
-/* 3D LUT */
-#define D3_LUT_ENTRY_MASK		0x3ff
-#define D3_LUT_ENTRY_R_SHIFT		20
-#define D3_LUT_ENTRY_G_SHIFT		10
-#define D3_LUT_ENTRY_B_SHIFT		0
-
-/* Lumina adj */
-#define	LUM_ADJ_CONTR_SHIFT		0
-#define	LUM_ADJ_BRIGHT_SHIFT		8
-
-/* RGB2YCbCr */
-#define RGB2YCBCR_OFST_MASK		0x7ff
-#define RGB2YCBCR_COEF_INT_MASK		0xf
-#define RGB2YCBCR_COEF_DECI_MASK	0xff
-
-/* GBCE */
-#define GBCE_Y_VAL_MASK			0xff
-#define GBCE_GAIN_VAL_MASK		0x3ff
-#define GBCE_ENTRY_SHIFT		10
-
-/* Edge Enhancements */
-#define YEE_HALO_RED_EN_SHIFT		1
-#define YEE_HPF_SHIFT_MASK		0xf
-#define YEE_COEF_MASK			0x3ff
-#define YEE_THR_MASK			0x3f
-#define YEE_ES_GAIN_MASK		0xfff
-#define YEE_ES_THR1_MASK		0xfff
-#define YEE_ENTRY_SHIFT			9
-#define YEE_ENTRY_MASK			0x1ff
-
-/* CAR */
-#define CAR_MF_THR			0xff
-#define CAR_SW1_SHIFT			8
-#define CAR_GAIN1_SHFT_MASK		7
-#define CAR_GAIN_MIN_MASK		0x1ff
-#define CAR_GAIN2_SHFT_MASK		0xf
-#define CAR_HPF_SHIFT_MASK		3
-
-/* CGS */
-#define CAR_SHIFT_MASK			3
-
-/* Resizer */
-#define RSZ_BYPASS_SHIFT		1
-#define RSZ_SRC_IMG_FMT_SHIFT		1
-#define RSZ_SRC_Y_C_SEL_SHIFT		2
-#define IPIPE_RSZ_VPS_MASK		0xffff
-#define IPIPE_RSZ_HPS_MASK		0xffff
-#define IPIPE_RSZ_VSZ_MASK		0x1fff
-#define IPIPE_RSZ_HSZ_MASK		0x1fff
-#define RSZ_HPS_MASK			0x1fff
-#define RSZ_VPS_MASK			0x1fff
-#define RSZ_O_HSZ_MASK			0x1fff
-#define RSZ_O_VSZ_MASK			0x1fff
-#define RSZ_V_PHS_MASK			0x3fff
-#define RSZ_V_DIF_MASK			0x3fff
-
-#define RSZA_H_FLIP_SHIFT		0
-#define RSZA_V_FLIP_SHIFT		1
-#define RSZB_H_FLIP_SHIFT		2
-#define RSZB_V_FLIP_SHIFT		3
-#define RSZ_A				0
-#define RSZ_B				1
-#define RSZ_CEN_SHIFT			1
-#define RSZ_YEN_SHIFT			0
-#define RSZ_TYP_Y_SHIFT			0
-#define RSZ_TYP_C_SHIFT			1
-#define RSZ_LPF_INT_MASK		0x3f
-#define RSZ_LPF_INT_C_SHIFT		6
-#define RSZ_H_PHS_MASK			0x3fff
-#define RSZ_H_DIF_MASK			0x3fff
-#define RSZ_DIFF_DOWN_THR		256
-#define RSZ_DWN_SCALE_AV_SZ_V_SHIFT	3
-#define RSZ_DWN_SCALE_AV_SZ_MASK	7
-#define RSZ_RGB_MSK1_SHIFT		2
-#define RSZ_RGB_MSK0_SHIFT		1
-#define RSZ_RGB_TYP_SHIFT		0
-#define RSZ_RGB_ALPHA_MASK		0xff
-
-static inline u32 regr_ip(void __iomem *addr, u32 offset)
-{
-	return readl(addr + offset);
-}
-
-static inline void regw_ip(void __iomem *addr, u32 val, u32 offset)
-{
-	writel(val, addr + offset);
-}
-
-static inline u32 w_ip_table(void __iomem *addr, u32 val, u32 offset)
-{
-	writel(val, addr + offset);
-
-	return val;
-}
-
-static inline u32 regr_rsz(void __iomem *addr, u32 offset)
-{
-	return readl(addr + offset);
-}
-
-static inline u32 regw_rsz(void __iomem *addr, u32 val, u32 offset)
-{
-	writel(val, addr + offset);
-
-	return val;
-}
-
-int config_ipipe_hw(struct vpfe_ipipe_device *ipipe);
-int resizer_set_outaddr(void __iomem *rsz_base, struct resizer_params *params,
-			int resize_no, unsigned int address);
-int rsz_enable(void __iomem *rsz_base, int rsz_id, int enable);
-void rsz_src_enable(void __iomem *rsz_base, int enable);
-void rsz_set_in_pix_format(unsigned char y_c);
-int config_rsz_hw(struct vpfe_resizer_device *resizer,
-		  struct resizer_params *config);
-void ipipe_set_d2f_regs(void __iomem *base_addr, unsigned int id,
-	struct vpfe_ipipe_nf *noise_filter);
-void ipipe_set_rgb2rgb_regs(void __iomem *base_addr, unsigned int id,
-	struct vpfe_ipipe_rgb2rgb *rgb);
-void ipipe_set_yuv422_conv_regs(void __iomem *base_addr,
-	struct vpfe_ipipe_yuv422_conv *conv);
-void ipipe_set_lum_adj_regs(void __iomem *base_addr,
-	struct ipipe_lum_adj *lum_adj);
-void ipipe_set_rgb2ycbcr_regs(void __iomem *base_addr,
-	struct vpfe_ipipe_rgb2yuv *yuv);
-void ipipe_set_lutdpc_regs(void __iomem *base_addr,
-	void __iomem *isp5_base_addr, struct vpfe_ipipe_lutdpc *lutdpc);
-void ipipe_set_otfdpc_regs(void __iomem *base_addr,
-	struct vpfe_ipipe_otfdpc *otfdpc);
-void ipipe_set_3d_lut_regs(void __iomem *base_addr,
-	void __iomem *isp5_base_addr, struct vpfe_ipipe_3d_lut *lut_3d);
-void ipipe_set_gamma_regs(void __iomem *base_addr,
-	void __iomem *isp5_base_addr, struct vpfe_ipipe_gamma *gamma);
-void ipipe_set_ee_regs(void __iomem *base_addr,
-	void __iomem *isp5_base_addr, struct vpfe_ipipe_yee *ee);
-void ipipe_set_gbce_regs(void __iomem *base_addr,
-	void __iomem *isp5_base_addr, struct vpfe_ipipe_gbce *gbce);
-void ipipe_set_gic_regs(void __iomem *base_addr, struct vpfe_ipipe_gic *gic);
-void ipipe_set_cfa_regs(void __iomem *base_addr, struct vpfe_ipipe_cfa *cfa);
-void ipipe_set_car_regs(void __iomem *base_addr, struct vpfe_ipipe_car *car);
-void ipipe_set_cgs_regs(void __iomem *base_addr, struct vpfe_ipipe_cgs *cgs);
-void ipipe_set_wb_regs(void __iomem *base_addr, struct vpfe_ipipe_wb *wb);
-
-#endif		/* _DAVINCI_VPFE_DM365_IPIPE_HW_H */
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
deleted file mode 100644
index 51d4cd1..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ /dev/null
@@ -1,1070 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#include "dm365_ipipeif.h"
-#include "vpfe_mc_capture.h"
-
-static const unsigned int ipipeif_input_fmts[] = {
-	MEDIA_BUS_FMT_UYVY8_2X8,
-	MEDIA_BUS_FMT_SGRBG12_1X12,
-	MEDIA_BUS_FMT_Y8_1X8,
-	MEDIA_BUS_FMT_UV8_1X8,
-	MEDIA_BUS_FMT_YDYUYDYV8_1X16,
-	MEDIA_BUS_FMT_SBGGR8_1X8,
-};
-
-static const unsigned int ipipeif_output_fmts[] = {
-	MEDIA_BUS_FMT_UYVY8_2X8,
-	MEDIA_BUS_FMT_SGRBG12_1X12,
-	MEDIA_BUS_FMT_Y8_1X8,
-	MEDIA_BUS_FMT_UV8_1X8,
-	MEDIA_BUS_FMT_YDYUYDYV8_1X16,
-	MEDIA_BUS_FMT_SBGGR8_1X8,
-	MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
-	MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
-};
-
-static int
-ipipeif_get_pack_mode(u32 in_pix_fmt)
-{
-	switch (in_pix_fmt) {
-	case MEDIA_BUS_FMT_SBGGR8_1X8:
-	case MEDIA_BUS_FMT_Y8_1X8:
-	case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
-	case MEDIA_BUS_FMT_UV8_1X8:
-		return IPIPEIF_5_1_PACK_8_BIT;
-
-	case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
-		return IPIPEIF_5_1_PACK_8_BIT_A_LAW;
-
-	case MEDIA_BUS_FMT_SGRBG12_1X12:
-		return IPIPEIF_5_1_PACK_16_BIT;
-
-	case MEDIA_BUS_FMT_SBGGR12_1X12:
-		return IPIPEIF_5_1_PACK_12_BIT;
-
-	default:
-		return IPIPEIF_5_1_PACK_16_BIT;
-	}
-}
-
-static inline u32 ipipeif_read(void __iomem *addr, u32 offset)
-{
-	return readl(addr + offset);
-}
-
-static inline void ipipeif_write(u32 val, void __iomem *addr, u32 offset)
-{
-	writel(val, addr + offset);
-}
-
-static void ipipeif_config_dpc(void __iomem *addr, struct ipipeif_dpc *dpc)
-{
-	u32 val = 0;
-
-	if (dpc->en) {
-		val = (dpc->en & 1) << IPIPEIF_DPC2_EN_SHIFT;
-		val |= dpc->thr & IPIPEIF_DPC2_THR_MASK;
-	}
-	ipipeif_write(val, addr, IPIPEIF_DPC2);
-}
-
-#define IPIPEIF_MODE_CONTINUOUS			0
-#define IPIPEIF_MODE_ONE_SHOT			1
-
-static int get_oneshot_mode(enum ipipeif_input_entity input)
-{
-	if (input == IPIPEIF_INPUT_MEMORY)
-		return IPIPEIF_MODE_ONE_SHOT;
-	if (input == IPIPEIF_INPUT_ISIF)
-		return IPIPEIF_MODE_CONTINUOUS;
-
-	return -EINVAL;
-}
-
-static int
-ipipeif_get_cfg_src1(struct vpfe_ipipeif_device *ipipeif)
-{
-	struct v4l2_mbus_framefmt *informat;
-
-	informat = &ipipeif->formats[IPIPEIF_PAD_SINK];
-	if (ipipeif->input == IPIPEIF_INPUT_MEMORY &&
-	    (informat->code == MEDIA_BUS_FMT_Y8_1X8 ||
-	    informat->code == MEDIA_BUS_FMT_UV8_1X8))
-		return IPIPEIF_CCDC;
-
-	return IPIPEIF_SRC1_PARALLEL_PORT;
-}
-
-static int
-ipipeif_get_data_shift(struct vpfe_ipipeif_device *ipipeif)
-{
-	struct v4l2_mbus_framefmt *informat;
-
-	informat = &ipipeif->formats[IPIPEIF_PAD_SINK];
-
-	switch (informat->code) {
-	case MEDIA_BUS_FMT_SGRBG12_1X12:
-		return IPIPEIF_5_1_BITS11_0;
-
-	case MEDIA_BUS_FMT_Y8_1X8:
-	case MEDIA_BUS_FMT_UV8_1X8:
-		return IPIPEIF_5_1_BITS11_0;
-
-	default:
-		return IPIPEIF_5_1_BITS7_0;
-	}
-}
-
-static enum ipipeif_input_source
-ipipeif_get_source(struct vpfe_ipipeif_device *ipipeif)
-{
-	struct v4l2_mbus_framefmt *informat;
-
-	informat = &ipipeif->formats[IPIPEIF_PAD_SINK];
-	if (ipipeif->input == IPIPEIF_INPUT_ISIF)
-		return IPIPEIF_CCDC;
-
-	if (informat->code == MEDIA_BUS_FMT_UYVY8_2X8)
-		return IPIPEIF_SDRAM_YUV;
-
-	return IPIPEIF_SDRAM_RAW;
-}
-
-void vpfe_ipipeif_ss_buffer_isr(struct vpfe_ipipeif_device *ipipeif)
-{
-	struct vpfe_video_device *video_in = &ipipeif->video_in;
-
-	if (ipipeif->input != IPIPEIF_INPUT_MEMORY)
-		return;
-
-	spin_lock(&video_in->dma_queue_lock);
-	vpfe_video_process_buffer_complete(video_in);
-	video_in->state = VPFE_VIDEO_BUFFER_NOT_QUEUED;
-	vpfe_video_schedule_next_buffer(video_in);
-	spin_unlock(&video_in->dma_queue_lock);
-}
-
-int vpfe_ipipeif_decimation_enabled(struct vpfe_device *vpfe_dev)
-{
-	struct vpfe_ipipeif_device *ipipeif = &vpfe_dev->vpfe_ipipeif;
-
-	return ipipeif->config.decimation;
-}
-
-int vpfe_ipipeif_get_rsz(struct vpfe_device *vpfe_dev)
-{
-	struct vpfe_ipipeif_device *ipipeif = &vpfe_dev->vpfe_ipipeif;
-
-	return ipipeif->config.rsz;
-}
-
-#define RD_DATA_15_2		0x7
-
-/*
- * ipipeif_hw_setup() - This function sets up IPIPEIF
- * @sd: pointer to v4l2 subdev structure
- * return -EINVAL or zero on success
- */
-static int ipipeif_hw_setup(struct v4l2_subdev *sd)
-{
-	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *informat, *outformat;
-	struct ipipeif_params params = ipipeif->config;
-	enum ipipeif_input_source ipipeif_source;
-	u32 isif_port_if;
-	void __iomem *ipipeif_base_addr;
-	unsigned long val;
-	int data_shift;
-	int pack_mode;
-	int source1;
-	int tmp;
-
-	ipipeif_base_addr = ipipeif->ipipeif_base_addr;
-
-	/* Enable clock to IPIPEIF and IPIPE */
-	vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
-
-	informat = &ipipeif->formats[IPIPEIF_PAD_SINK];
-	outformat = &ipipeif->formats[IPIPEIF_PAD_SOURCE];
-
-	/* Combine all the fields to make CFG1 register of IPIPEIF */
-	tmp = val = get_oneshot_mode(ipipeif->input);
-	if (tmp < 0) {
-		dev_err(&sd->devnode->dev, "ipipeif: links setup required");
-		return -EINVAL;
-	}
-	val <<= ONESHOT_SHIFT;
-
-	ipipeif_source = ipipeif_get_source(ipipeif);
-	val |= ipipeif_source << INPSRC_SHIFT;
-
-	val |= params.clock_select << CLKSEL_SHIFT;
-	val |= params.avg_filter << AVGFILT_SHIFT;
-	val |= params.decimation << DECIM_SHIFT;
-
-	pack_mode = ipipeif_get_pack_mode(informat->code);
-	val |= pack_mode << PACK8IN_SHIFT;
-
-	source1 = ipipeif_get_cfg_src1(ipipeif);
-	val |= source1 << INPSRC1_SHIFT;
-
-	data_shift = ipipeif_get_data_shift(ipipeif);
-	if (ipipeif_source != IPIPEIF_SDRAM_YUV)
-		val |= data_shift << DATASFT_SHIFT;
-	else
-		val &= ~(RD_DATA_15_2 << DATASFT_SHIFT);
-
-	ipipeif_write(val, ipipeif_base_addr, IPIPEIF_CFG1);
-
-	switch (ipipeif_source) {
-	case IPIPEIF_CCDC:
-		ipipeif_write(ipipeif->gain, ipipeif_base_addr, IPIPEIF_GAIN);
-		break;
-
-	case IPIPEIF_SDRAM_RAW:
-	case IPIPEIF_CCDC_DARKFM:
-		ipipeif_write(ipipeif->gain, ipipeif_base_addr, IPIPEIF_GAIN);
-		/* fall through */
-	case IPIPEIF_SDRAM_YUV:
-		val |= data_shift << DATASFT_SHIFT;
-		ipipeif_write(params.ppln, ipipeif_base_addr, IPIPEIF_PPLN);
-		ipipeif_write(params.lpfr, ipipeif_base_addr, IPIPEIF_LPFR);
-		ipipeif_write(informat->width, ipipeif_base_addr, IPIPEIF_HNUM);
-		ipipeif_write(informat->height,
-			      ipipeif_base_addr, IPIPEIF_VNUM);
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/*check if decimation is enable or not */
-	if (params.decimation)
-		ipipeif_write(params.rsz, ipipeif_base_addr, IPIPEIF_RSZ);
-
-	/* Setup sync alignment and initial rsz position */
-	val = params.if_5_1.align_sync & 1;
-	val <<= IPIPEIF_INIRSZ_ALNSYNC_SHIFT;
-	val |= params.if_5_1.rsz_start & IPIPEIF_INIRSZ_MASK;
-	ipipeif_write(val, ipipeif_base_addr, IPIPEIF_INIRSZ);
-	isif_port_if = informat->code;
-
-	if (isif_port_if == MEDIA_BUS_FMT_Y8_1X8)
-		isif_port_if = MEDIA_BUS_FMT_YUYV8_1X16;
-	else if (isif_port_if == MEDIA_BUS_FMT_UV8_1X8)
-		isif_port_if = MEDIA_BUS_FMT_SGRBG12_1X12;
-
-	/* Enable DPCM decompression */
-	switch (ipipeif_source) {
-	case IPIPEIF_SDRAM_RAW:
-		val = 0;
-		if (outformat->code == MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8) {
-			val = 1;
-			val |= (IPIPEIF_DPCM_8BIT_10BIT & 1) <<
-				IPIPEIF_DPCM_BITS_SHIFT;
-			val |= (ipipeif->dpcm_predictor & 1) <<
-				IPIPEIF_DPCM_PRED_SHIFT;
-		}
-		ipipeif_write(val, ipipeif_base_addr, IPIPEIF_DPCM);
-
-		/* set DPC */
-		ipipeif_config_dpc(ipipeif_base_addr, &params.if_5_1.dpc);
-
-		ipipeif_write(params.if_5_1.clip,
-			      ipipeif_base_addr, IPIPEIF_OCLIP);
-
-		/* fall through for SDRAM YUV mode */
-		/* configure CFG2 */
-		val = ipipeif_read(ipipeif_base_addr, IPIPEIF_CFG2);
-		switch (isif_port_if) {
-		case MEDIA_BUS_FMT_YUYV8_1X16:
-		case MEDIA_BUS_FMT_UYVY8_2X8:
-		case MEDIA_BUS_FMT_Y8_1X8:
-			clear_bit(IPIPEIF_CFG2_YUV8_SHIFT, &val);
-			set_bit(IPIPEIF_CFG2_YUV16_SHIFT, &val);
-			ipipeif_write(val, ipipeif_base_addr, IPIPEIF_CFG2);
-			break;
-
-		default:
-			clear_bit(IPIPEIF_CFG2_YUV8_SHIFT, &val);
-			clear_bit(IPIPEIF_CFG2_YUV16_SHIFT, &val);
-			ipipeif_write(val, ipipeif_base_addr, IPIPEIF_CFG2);
-			break;
-		}
-		/* fall through */
-
-	case IPIPEIF_SDRAM_YUV:
-		/* Set clock divider */
-		if (params.clock_select == IPIPEIF_SDRAM_CLK) {
-			val = ipipeif_read(ipipeif_base_addr, IPIPEIF_CLKDIV);
-			val |= (params.if_5_1.clk_div.m - 1) <<
-				IPIPEIF_CLKDIV_M_SHIFT;
-			val |= (params.if_5_1.clk_div.n - 1);
-			ipipeif_write(val, ipipeif_base_addr, IPIPEIF_CLKDIV);
-		}
-		break;
-
-	case IPIPEIF_CCDC:
-	case IPIPEIF_CCDC_DARKFM:
-		/* set DPC */
-		ipipeif_config_dpc(ipipeif_base_addr, &params.if_5_1.dpc);
-
-		/* Set DF gain & threshold control */
-		val = 0;
-		if (params.if_5_1.df_gain_en) {
-			val = params.if_5_1.df_gain_thr &
-				IPIPEIF_DF_GAIN_THR_MASK;
-			ipipeif_write(val, ipipeif_base_addr, IPIPEIF_DFSGTH);
-			val = (params.if_5_1.df_gain_en & 1) <<
-				IPIPEIF_DF_GAIN_EN_SHIFT;
-			val |= params.if_5_1.df_gain &
-				IPIPEIF_DF_GAIN_MASK;
-		}
-		ipipeif_write(val, ipipeif_base_addr, IPIPEIF_DFSGVL);
-		/* configure CFG2 */
-		val = VPFE_PINPOL_POSITIVE << IPIPEIF_CFG2_HDPOL_SHIFT;
-		val |= VPFE_PINPOL_POSITIVE << IPIPEIF_CFG2_VDPOL_SHIFT;
-
-		switch (isif_port_if) {
-		case MEDIA_BUS_FMT_YUYV8_1X16:
-		case MEDIA_BUS_FMT_YUYV10_1X20:
-			clear_bit(IPIPEIF_CFG2_YUV8_SHIFT, &val);
-			set_bit(IPIPEIF_CFG2_YUV16_SHIFT, &val);
-			break;
-
-		case MEDIA_BUS_FMT_YUYV8_2X8:
-		case MEDIA_BUS_FMT_UYVY8_2X8:
-		case MEDIA_BUS_FMT_Y8_1X8:
-		case MEDIA_BUS_FMT_YUYV10_2X10:
-			set_bit(IPIPEIF_CFG2_YUV8_SHIFT, &val);
-			set_bit(IPIPEIF_CFG2_YUV16_SHIFT, &val);
-			val |= IPIPEIF_CBCR_Y << IPIPEIF_CFG2_YUV8P_SHIFT;
-			break;
-
-		default:
-			/* Bayer */
-			ipipeif_write(params.if_5_1.clip, ipipeif_base_addr,
-				      IPIPEIF_OCLIP);
-		}
-		ipipeif_write(val, ipipeif_base_addr, IPIPEIF_CFG2);
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int
-ipipeif_set_config(struct v4l2_subdev *sd, struct ipipeif_params *config)
-{
-	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
-	struct device *dev = ipipeif->subdev.v4l2_dev->dev;
-
-	if (!config) {
-		dev_err(dev, "Invalid configuration pointer\n");
-		return -EINVAL;
-	}
-
-	ipipeif->config.clock_select = config->clock_select;
-	ipipeif->config.ppln = config->ppln;
-	ipipeif->config.lpfr = config->lpfr;
-	ipipeif->config.rsz = config->rsz;
-	ipipeif->config.decimation = config->decimation;
-	if (ipipeif->config.decimation &&
-	    (ipipeif->config.rsz < IPIPEIF_RSZ_MIN ||
-	    ipipeif->config.rsz > IPIPEIF_RSZ_MAX)) {
-		dev_err(dev, "rsz range is %d to %d\n",
-			IPIPEIF_RSZ_MIN, IPIPEIF_RSZ_MAX);
-		return -EINVAL;
-	}
-
-	ipipeif->config.avg_filter = config->avg_filter;
-
-	ipipeif->config.if_5_1.df_gain_thr = config->if_5_1.df_gain_thr;
-	ipipeif->config.if_5_1.df_gain = config->if_5_1.df_gain;
-	ipipeif->config.if_5_1.df_gain_en = config->if_5_1.df_gain_en;
-
-	ipipeif->config.if_5_1.rsz_start = config->if_5_1.rsz_start;
-	ipipeif->config.if_5_1.align_sync = config->if_5_1.align_sync;
-	ipipeif->config.if_5_1.clip = config->if_5_1.clip;
-
-	ipipeif->config.if_5_1.dpc.en = config->if_5_1.dpc.en;
-	ipipeif->config.if_5_1.dpc.thr = config->if_5_1.dpc.thr;
-
-	ipipeif->config.if_5_1.clk_div.m = config->if_5_1.clk_div.m;
-	ipipeif->config.if_5_1.clk_div.n = config->if_5_1.clk_div.n;
-
-	return 0;
-}
-
-static int
-ipipeif_get_config(struct v4l2_subdev *sd, void *arg)
-{
-	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
-	struct ipipeif_params *config = arg;
-	struct device *dev = ipipeif->subdev.v4l2_dev->dev;
-
-	if (!arg) {
-		dev_err(dev, "Invalid configuration pointer\n");
-		return -EINVAL;
-	}
-
-	config->clock_select = ipipeif->config.clock_select;
-	config->ppln = ipipeif->config.ppln;
-	config->lpfr = ipipeif->config.lpfr;
-	config->rsz = ipipeif->config.rsz;
-	config->decimation = ipipeif->config.decimation;
-	config->avg_filter = ipipeif->config.avg_filter;
-
-	config->if_5_1.df_gain_thr = ipipeif->config.if_5_1.df_gain_thr;
-	config->if_5_1.df_gain = ipipeif->config.if_5_1.df_gain;
-	config->if_5_1.df_gain_en = ipipeif->config.if_5_1.df_gain_en;
-
-	config->if_5_1.rsz_start = ipipeif->config.if_5_1.rsz_start;
-	config->if_5_1.align_sync = ipipeif->config.if_5_1.align_sync;
-	config->if_5_1.clip = ipipeif->config.if_5_1.clip;
-
-	config->if_5_1.dpc.en = ipipeif->config.if_5_1.dpc.en;
-	config->if_5_1.dpc.thr = ipipeif->config.if_5_1.dpc.thr;
-
-	config->if_5_1.clk_div.m = ipipeif->config.if_5_1.clk_div.m;
-	config->if_5_1.clk_div.n = ipipeif->config.if_5_1.clk_div.n;
-
-	return 0;
-}
-
-/*
- * ipipeif_ioctl() - Handle ipipeif module private ioctl's
- * @sd: pointer to v4l2 subdev structure
- * @cmd: configuration command
- * @arg: configuration argument
- */
-static long ipipeif_ioctl(struct v4l2_subdev *sd,
-			  unsigned int cmd, void *arg)
-{
-	struct ipipeif_params *config = arg;
-	int ret = -ENOIOCTLCMD;
-
-	switch (cmd) {
-	case VIDIOC_VPFE_IPIPEIF_S_CONFIG:
-		ret = ipipeif_set_config(sd, config);
-		break;
-
-	case VIDIOC_VPFE_IPIPEIF_G_CONFIG:
-		ret = ipipeif_get_config(sd, arg);
-		break;
-	}
-	return ret;
-}
-
-/*
- * ipipeif_s_ctrl() - Handle set control subdev method
- * @ctrl: pointer to v4l2 control structure
- */
-static int ipipeif_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vpfe_ipipeif_device *ipipeif =
-		container_of(ctrl->handler, struct vpfe_ipipeif_device, ctrls);
-
-	switch (ctrl->id) {
-	case VPFE_CID_DPCM_PREDICTOR:
-		ipipeif->dpcm_predictor = ctrl->val;
-		break;
-
-	case V4L2_CID_GAIN:
-		ipipeif->gain = ctrl->val;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-#define ENABLE_IPIPEIF		0x1
-
-void vpfe_ipipeif_enable(struct vpfe_device *vpfe_dev)
-{
-	struct vpfe_ipipeif_device *ipipeif = &vpfe_dev->vpfe_ipipeif;
-	void __iomem *ipipeif_base_addr = ipipeif->ipipeif_base_addr;
-	unsigned char val;
-
-	if (ipipeif->input != IPIPEIF_INPUT_MEMORY)
-		return;
-
-	do {
-		val = ipipeif_read(ipipeif_base_addr, IPIPEIF_ENABLE);
-	} while (val & 0x1);
-
-	ipipeif_write(ENABLE_IPIPEIF, ipipeif_base_addr, IPIPEIF_ENABLE);
-}
-
-/*
- * ipipeif_set_stream() - Enable/Disable streaming on ipipeif subdev
- * @sd: pointer to v4l2 subdev structure
- * @enable: 1 == Enable, 0 == Disable
- */
-static int ipipeif_set_stream(struct v4l2_subdev *sd, int enable)
-{
-	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
-	struct vpfe_device *vpfe_dev = to_vpfe_device(ipipeif);
-	int ret = 0;
-
-	if (!enable)
-		return ret;
-
-	ret = ipipeif_hw_setup(sd);
-	if (!ret)
-		vpfe_ipipeif_enable(vpfe_dev);
-
-	return ret;
-}
-
-/*
- * ipipeif_enum_mbus_code() - Handle pixel format enumeration
- * @sd: pointer to v4l2 subdev structure
- * @cfg: V4L2 subdev pad config
- * @code: pointer to v4l2_subdev_mbus_code_enum structure
- * return -EINVAL or zero on success
- */
-static int ipipeif_enum_mbus_code(struct v4l2_subdev *sd,
-				  struct v4l2_subdev_pad_config *cfg,
-			struct v4l2_subdev_mbus_code_enum *code)
-{
-	switch (code->pad) {
-	case IPIPEIF_PAD_SINK:
-		if (code->index >= ARRAY_SIZE(ipipeif_input_fmts))
-			return -EINVAL;
-
-		code->code = ipipeif_input_fmts[code->index];
-		break;
-
-	case IPIPEIF_PAD_SOURCE:
-		if (code->index >= ARRAY_SIZE(ipipeif_output_fmts))
-			return -EINVAL;
-
-		code->code = ipipeif_output_fmts[code->index];
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * ipipeif_get_format() - Handle get format by pads subdev method
- * @sd: pointer to v4l2 subdev structure
- * @cfg: V4L2 subdev pad config
- * @fmt: pointer to v4l2 subdev format structure
- */
-static int
-ipipeif_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-		   struct v4l2_subdev_format *fmt)
-{
-	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
-
-	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
-		fmt->format = ipipeif->formats[fmt->pad];
-	else
-		fmt->format = *(v4l2_subdev_get_try_format(sd, cfg, fmt->pad));
-
-	return 0;
-}
-
-#define MIN_OUT_WIDTH			32
-#define MIN_OUT_HEIGHT			32
-
-/*
- * ipipeif_try_format() - Handle try format by pad subdev method
- * @ipipeif: VPFE ipipeif device.
- * @cfg: V4L2 subdev pad config
- * @pad: pad num.
- * @fmt: pointer to v4l2 format structure.
- * @which : wanted subdev format
- */
-static void
-ipipeif_try_format(struct vpfe_ipipeif_device *ipipeif,
-		   struct v4l2_subdev_pad_config *cfg, unsigned int pad,
-		   struct v4l2_mbus_framefmt *fmt,
-		   enum v4l2_subdev_format_whence which)
-{
-	unsigned int max_out_height;
-	unsigned int max_out_width;
-	unsigned int i;
-
-	max_out_width = IPIPE_MAX_OUTPUT_WIDTH_A;
-	max_out_height = IPIPE_MAX_OUTPUT_HEIGHT_A;
-
-	if (pad == IPIPEIF_PAD_SINK) {
-		for (i = 0; i < ARRAY_SIZE(ipipeif_input_fmts); i++)
-			if (fmt->code == ipipeif_input_fmts[i])
-				break;
-
-		/* If not found, use SBGGR10 as default */
-		if (i >= ARRAY_SIZE(ipipeif_input_fmts))
-			fmt->code = MEDIA_BUS_FMT_SGRBG12_1X12;
-	} else if (pad == IPIPEIF_PAD_SOURCE) {
-		for (i = 0; i < ARRAY_SIZE(ipipeif_output_fmts); i++)
-			if (fmt->code == ipipeif_output_fmts[i])
-				break;
-
-		/* If not found, use UYVY as default */
-		if (i >= ARRAY_SIZE(ipipeif_output_fmts))
-			fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
-	}
-
-	fmt->width = clamp_t(u32, fmt->width, MIN_OUT_HEIGHT, max_out_width);
-	fmt->height = clamp_t(u32, fmt->height, MIN_OUT_WIDTH, max_out_height);
-}
-
-static int
-ipipeif_enum_frame_size(struct v4l2_subdev *sd,
-			struct v4l2_subdev_pad_config *cfg,
-			struct v4l2_subdev_frame_size_enum *fse)
-{
-	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt format;
-
-	if (fse->index != 0)
-		return -EINVAL;
-
-	format.code = fse->code;
-	format.width = 1;
-	format.height = 1;
-	ipipeif_try_format(ipipeif, cfg, fse->pad, &format, fse->which);
-	fse->min_width = format.width;
-	fse->min_height = format.height;
-
-	if (format.code != fse->code)
-		return -EINVAL;
-
-	format.code = fse->code;
-	format.width = -1;
-	format.height = -1;
-	ipipeif_try_format(ipipeif, cfg, fse->pad, &format, fse->which);
-	fse->max_width = format.width;
-	fse->max_height = format.height;
-
-	return 0;
-}
-
-/*
- * __ipipeif_get_format() - helper function for getting ipipeif format
- * @ipipeif: pointer to ipipeif private structure.
- * @cfg: V4L2 subdev pad config
- * @pad: pad number.
- * @which: wanted subdev format.
- *
- */
-static struct v4l2_mbus_framefmt *
-__ipipeif_get_format(struct vpfe_ipipeif_device *ipipeif,
-		     struct v4l2_subdev_pad_config *cfg, unsigned int pad,
-		     enum v4l2_subdev_format_whence which)
-{
-	if (which == V4L2_SUBDEV_FORMAT_TRY)
-		return v4l2_subdev_get_try_format(&ipipeif->subdev, cfg, pad);
-
-	return &ipipeif->formats[pad];
-}
-
-/*
- * ipipeif_set_format() - Handle set format by pads subdev method
- * @sd: pointer to v4l2 subdev structure
- * @cfg: V4L2 subdev pad config
- * @fmt: pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int
-ipipeif_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-		   struct v4l2_subdev_format *fmt)
-{
-	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *format;
-
-	format = __ipipeif_get_format(ipipeif, cfg, fmt->pad, fmt->which);
-	if (!format)
-		return -EINVAL;
-
-	ipipeif_try_format(ipipeif, cfg, fmt->pad, &fmt->format, fmt->which);
-	*format = fmt->format;
-
-	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
-		return 0;
-
-	if (fmt->pad == IPIPEIF_PAD_SINK &&
-	    ipipeif->input != IPIPEIF_INPUT_NONE)
-		ipipeif->formats[fmt->pad] = fmt->format;
-	else if (fmt->pad == IPIPEIF_PAD_SOURCE &&
-		 ipipeif->output != IPIPEIF_OUTPUT_NONE)
-		ipipeif->formats[fmt->pad] = fmt->format;
-	else
-		return -EINVAL;
-
-	return 0;
-}
-
-static void ipipeif_set_default_config(struct vpfe_ipipeif_device *ipipeif)
-{
-#define WIDTH_I			640
-#define HEIGHT_I		480
-
-	const struct ipipeif_params ipipeif_defaults = {
-		.clock_select = IPIPEIF_SDRAM_CLK,
-		.ppln = WIDTH_I + 8,
-		.lpfr = HEIGHT_I + 10,
-		.rsz = 16,	/* resize ratio 16/rsz */
-		.decimation = IPIPEIF_DECIMATION_OFF,
-		.avg_filter = IPIPEIF_AVG_OFF,
-		.if_5_1 = {
-			.clk_div = {
-				.m = 1,	/* clock = sdram clock * (m/n) */
-				.n = 6
-			},
-			.clip = 4095,
-		},
-	};
-	memcpy(&ipipeif->config, &ipipeif_defaults,
-	       sizeof(struct ipipeif_params));
-}
-
-/*
- * ipipeif_init_formats() - Initialize formats on all pads
- * @sd: VPFE ipipeif V4L2 subdevice
- * @fh: V4L2 subdev file handle
- *
- * Initialize all pad formats with default values. Try formats are initialized
- * on the file handle.
- */
-static int
-ipipeif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
-	struct v4l2_subdev_format format;
-
-	memset(&format, 0, sizeof(format));
-	format.pad = IPIPEIF_PAD_SINK;
-	format.which = V4L2_SUBDEV_FORMAT_TRY;
-	format.format.code = MEDIA_BUS_FMT_SGRBG12_1X12;
-	format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A;
-	format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A;
-	ipipeif_set_format(sd, fh->pad, &format);
-
-	memset(&format, 0, sizeof(format));
-	format.pad = IPIPEIF_PAD_SOURCE;
-	format.which = V4L2_SUBDEV_FORMAT_TRY;
-	format.format.code = MEDIA_BUS_FMT_UYVY8_2X8;
-	format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A;
-	format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A;
-	ipipeif_set_format(sd, fh->pad, &format);
-
-	ipipeif_set_default_config(ipipeif);
-
-	return 0;
-}
-
-/*
- * ipipeif_video_in_queue() - ipipeif video in queue
- * @vpfe_dev: vpfe device pointer
- * @addr: buffer address
- */
-static int
-ipipeif_video_in_queue(struct vpfe_device *vpfe_dev, unsigned long addr)
-{
-	struct vpfe_ipipeif_device *ipipeif = &vpfe_dev->vpfe_ipipeif;
-	void __iomem *ipipeif_base_addr = ipipeif->ipipeif_base_addr;
-	unsigned int adofs;
-	u32 val;
-
-	if (ipipeif->input != IPIPEIF_INPUT_MEMORY)
-		return -EINVAL;
-
-	switch (ipipeif->formats[IPIPEIF_PAD_SINK].code) {
-	case MEDIA_BUS_FMT_Y8_1X8:
-	case MEDIA_BUS_FMT_UV8_1X8:
-	case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
-		adofs = ipipeif->formats[IPIPEIF_PAD_SINK].width;
-		break;
-
-	default:
-		adofs = ipipeif->formats[IPIPEIF_PAD_SINK].width << 1;
-		break;
-	}
-
-	/* adjust the line len to be a multiple of 32 */
-	adofs += 31;
-	adofs &= ~0x1f;
-	val = (adofs >> 5) & IPIPEIF_ADOFS_LSB_MASK;
-	ipipeif_write(val, ipipeif_base_addr, IPIPEIF_ADOFS);
-
-	/* lower sixteen bit */
-	val = (addr >> IPIPEIF_ADDRL_SHIFT) & IPIPEIF_ADDRL_MASK;
-	ipipeif_write(val, ipipeif_base_addr, IPIPEIF_ADDRL);
-
-	/* upper next seven bit */
-	val = (addr >> IPIPEIF_ADDRU_SHIFT) & IPIPEIF_ADDRU_MASK;
-	ipipeif_write(val, ipipeif_base_addr, IPIPEIF_ADDRU);
-
-	return 0;
-}
-
-/* subdev core operations */
-static const struct v4l2_subdev_core_ops ipipeif_v4l2_core_ops = {
-	.ioctl = ipipeif_ioctl,
-};
-
-static const struct v4l2_ctrl_ops ipipeif_ctrl_ops = {
-	.s_ctrl = ipipeif_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config vpfe_ipipeif_dpcm_pred = {
-	.ops = &ipipeif_ctrl_ops,
-	.id = VPFE_CID_DPCM_PREDICTOR,
-	.name = "DPCM Predictor",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 0,
-	.max = 1,
-	.step = 1,
-	.def = 0,
-};
-
-/* subdev file operations */
-static const struct v4l2_subdev_internal_ops ipipeif_v4l2_internal_ops = {
-	.open = ipipeif_init_formats,
-};
-
-/* subdev video operations */
-static const struct v4l2_subdev_video_ops ipipeif_v4l2_video_ops = {
-	.s_stream = ipipeif_set_stream,
-};
-
-/* subdev pad operations */
-static const struct v4l2_subdev_pad_ops ipipeif_v4l2_pad_ops = {
-	.enum_mbus_code = ipipeif_enum_mbus_code,
-	.enum_frame_size = ipipeif_enum_frame_size,
-	.get_fmt = ipipeif_get_format,
-	.set_fmt = ipipeif_set_format,
-};
-
-/* subdev operations */
-static const struct v4l2_subdev_ops ipipeif_v4l2_ops = {
-	.core = &ipipeif_v4l2_core_ops,
-	.video = &ipipeif_v4l2_video_ops,
-	.pad = &ipipeif_v4l2_pad_ops,
-};
-
-static const struct vpfe_video_operations video_in_ops = {
-	.queue = ipipeif_video_in_queue,
-};
-
-static int
-ipipeif_link_setup(struct media_entity *entity, const struct media_pad *local,
-		   const struct media_pad *remote, u32 flags)
-{
-	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
-	struct vpfe_ipipeif_device *ipipeif = v4l2_get_subdevdata(sd);
-	struct vpfe_device *vpfe = to_vpfe_device(ipipeif);
-	unsigned int index = local->index;
-
-	/* FIXME: this is actually a hack! */
-	if (is_media_entity_v4l2_subdev(remote->entity))
-		index |= 2 << 16;
-
-	switch (index) {
-	case IPIPEIF_PAD_SINK:
-		/* Single shot mode */
-		if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-			ipipeif->input = IPIPEIF_INPUT_NONE;
-			break;
-		}
-		ipipeif->input = IPIPEIF_INPUT_MEMORY;
-		break;
-
-	case IPIPEIF_PAD_SINK | 2 << 16:
-		/* read from isif */
-		if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-			ipipeif->input = IPIPEIF_INPUT_NONE;
-			break;
-		}
-		if (ipipeif->input != IPIPEIF_INPUT_NONE)
-			return -EBUSY;
-
-		ipipeif->input = IPIPEIF_INPUT_ISIF;
-		break;
-
-	case IPIPEIF_PAD_SOURCE | 2 << 16:
-		if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-			ipipeif->output = IPIPEIF_OUTPUT_NONE;
-			break;
-		}
-		if (remote->entity == &vpfe->vpfe_ipipe.subdev.entity)
-			/* connencted to ipipe */
-			ipipeif->output = IPIPEIF_OUTPUT_IPIPE;
-		else if (remote->entity == &vpfe->vpfe_resizer.crop_resizer.subdev.entity)
-			/* connected to resizer */
-			ipipeif->output = IPIPEIF_OUTPUT_RESIZER;
-		else
-			return -EINVAL;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static const struct media_entity_operations ipipeif_media_ops = {
-	.link_setup = ipipeif_link_setup,
-};
-
-/*
- * vpfe_ipipeif_unregister_entities() - Unregister entity
- * @ipipeif - pointer to ipipeif subdevice structure.
- */
-void vpfe_ipipeif_unregister_entities(struct vpfe_ipipeif_device *ipipeif)
-{
-	/* unregister video device */
-	vpfe_video_unregister(&ipipeif->video_in);
-
-	/* unregister subdev */
-	v4l2_device_unregister_subdev(&ipipeif->subdev);
-	/* cleanup entity */
-	media_entity_cleanup(&ipipeif->subdev.entity);
-}
-
-int
-vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif,
-			       struct v4l2_device *vdev)
-{
-	struct vpfe_device *vpfe_dev = to_vpfe_device(ipipeif);
-	unsigned int flags;
-	int ret;
-
-	/* Register the subdev */
-	ret = v4l2_device_register_subdev(vdev, &ipipeif->subdev);
-	if (ret < 0)
-		return ret;
-
-	ret = vpfe_video_register(&ipipeif->video_in, vdev);
-	if (ret) {
-		pr_err("Failed to register ipipeif video-in device\n");
-		goto fail;
-	}
-	ipipeif->video_in.vpfe_dev = vpfe_dev;
-
-	flags = 0;
-	ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0,
-				    &ipipeif->subdev.entity, 0, flags);
-	if (ret < 0)
-		goto fail;
-
-	return 0;
-fail:
-	v4l2_device_unregister_subdev(&ipipeif->subdev);
-
-	return ret;
-}
-
-#define IPIPEIF_GAIN_HIGH		0x3ff
-#define IPIPEIF_DEFAULT_GAIN		0x200
-
-int vpfe_ipipeif_init(struct vpfe_ipipeif_device *ipipeif,
-		      struct platform_device *pdev)
-{
-	struct v4l2_subdev *sd = &ipipeif->subdev;
-	struct media_pad *pads = &ipipeif->pads[0];
-	struct media_entity *me = &sd->entity;
-	static resource_size_t  res_len;
-	struct resource *res;
-	int ret;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
-	if (!res)
-		return -ENOENT;
-
-	res_len = resource_size(res);
-	res = request_mem_region(res->start, res_len, res->name);
-	if (!res)
-		return -EBUSY;
-
-	ipipeif->ipipeif_base_addr = ioremap_nocache(res->start, res_len);
-	if (!ipipeif->ipipeif_base_addr) {
-		ret =  -EBUSY;
-		goto fail;
-	}
-
-	v4l2_subdev_init(sd, &ipipeif_v4l2_ops);
-
-	sd->internal_ops = &ipipeif_v4l2_internal_ops;
-	strscpy(sd->name, "DAVINCI IPIPEIF", sizeof(sd->name));
-	sd->grp_id = 1 << 16;	/* group ID for davinci subdevs */
-
-	v4l2_set_subdevdata(sd, ipipeif);
-
-	sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
-	pads[IPIPEIF_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-	pads[IPIPEIF_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-	ipipeif->input = IPIPEIF_INPUT_NONE;
-	ipipeif->output = IPIPEIF_OUTPUT_NONE;
-	me->ops = &ipipeif_media_ops;
-
-	ret = media_entity_pads_init(me, IPIPEIF_NUM_PADS, pads);
-	if (ret)
-		goto fail;
-
-	v4l2_ctrl_handler_init(&ipipeif->ctrls, 2);
-	v4l2_ctrl_new_std(&ipipeif->ctrls, &ipipeif_ctrl_ops,
-			  V4L2_CID_GAIN, 0,
-			  IPIPEIF_GAIN_HIGH, 1, IPIPEIF_DEFAULT_GAIN);
-	v4l2_ctrl_new_custom(&ipipeif->ctrls, &vpfe_ipipeif_dpcm_pred, NULL);
-	v4l2_ctrl_handler_setup(&ipipeif->ctrls);
-	sd->ctrl_handler = &ipipeif->ctrls;
-
-	ipipeif->video_in.ops = &video_in_ops;
-	ipipeif->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-	ret = vpfe_video_init(&ipipeif->video_in, "IPIPEIF");
-	if (ret) {
-		pr_err("Failed to init IPIPEIF video-in device\n");
-		goto fail;
-	}
-	ipipeif_set_default_config(ipipeif);
-	return 0;
-fail:
-	release_mem_region(res->start, res_len);
-	return ret;
-}
-
-void
-vpfe_ipipeif_cleanup(struct vpfe_ipipeif_device *ipipeif,
-		     struct platform_device *pdev)
-{
-	struct resource *res;
-
-	v4l2_ctrl_handler_free(&ipipeif->ctrls);
-	iounmap(ipipeif->ipipeif_base_addr);
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
-	if (res)
-		release_mem_region(res->start, resource_size(res));
-
-}
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h
deleted file mode 100644
index 4d126fc..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _DAVINCI_VPFE_DM365_IPIPEIF_H
-#define _DAVINCI_VPFE_DM365_IPIPEIF_H
-
-#include <linux/platform_device.h>
-
-#include <media/davinci/vpss.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-subdev.h>
-
-#include "dm365_ipipeif_user.h"
-#include "vpfe_video.h"
-
-/* IPIPE base specific types */
-enum ipipeif_data_shift {
-	IPIPEIF_BITS15_2 = 0,
-	IPIPEIF_BITS14_1 = 1,
-	IPIPEIF_BITS13_0 = 2,
-	IPIPEIF_BITS12_0 = 3,
-	IPIPEIF_BITS11_0 = 4,
-	IPIPEIF_BITS10_0 = 5,
-	IPIPEIF_BITS9_0 = 6,
-};
-
-enum ipipeif_clkdiv {
-	IPIPEIF_DIVIDE_HALF = 0,
-	IPIPEIF_DIVIDE_THIRD = 1,
-	IPIPEIF_DIVIDE_FOURTH = 2,
-	IPIPEIF_DIVIDE_FIFTH = 3,
-	IPIPEIF_DIVIDE_SIXTH = 4,
-	IPIPEIF_DIVIDE_EIGHTH = 5,
-	IPIPEIF_DIVIDE_SIXTEENTH = 6,
-	IPIPEIF_DIVIDE_THIRTY = 7,
-};
-
-enum ipipeif_pack_mode  {
-	IPIPEIF_PACK_16_BIT = 0,
-	IPIPEIF_PACK_8_BIT = 1,
-};
-
-enum ipipeif_5_1_pack_mode  {
-	IPIPEIF_5_1_PACK_16_BIT = 0,
-	IPIPEIF_5_1_PACK_8_BIT = 1,
-	IPIPEIF_5_1_PACK_8_BIT_A_LAW = 2,
-	IPIPEIF_5_1_PACK_12_BIT = 3
-};
-
-enum  ipipeif_input_source {
-	IPIPEIF_CCDC = 0,
-	IPIPEIF_SDRAM_RAW = 1,
-	IPIPEIF_CCDC_DARKFM = 2,
-	IPIPEIF_SDRAM_YUV = 3,
-};
-
-enum ipipeif_ialaw {
-	IPIPEIF_ALAW_OFF = 0,
-	IPIPEIF_ALAW_ON = 1,
-};
-
-enum  ipipeif_input_src1 {
-	IPIPEIF_SRC1_PARALLEL_PORT = 0,
-	IPIPEIF_SRC1_SDRAM_RAW = 1,
-	IPIPEIF_SRC1_ISIF_DARKFM = 2,
-	IPIPEIF_SRC1_SDRAM_YUV = 3,
-};
-
-enum ipipeif_dfs_dir {
-	IPIPEIF_PORT_MINUS_SDRAM = 0,
-	IPIPEIF_SDRAM_MINUS_PORT = 1,
-};
-
-enum ipipeif_chroma_phase {
-	IPIPEIF_CBCR_Y = 0,
-	IPIPEIF_Y_CBCR = 1,
-};
-
-enum ipipeif_dpcm_type {
-	IPIPEIF_DPCM_8BIT_10BIT = 0,
-	IPIPEIF_DPCM_8BIT_12BIT = 1,
-};
-
-/* data shift for IPIPE 5.1 */
-enum ipipeif_5_1_data_shift {
-	IPIPEIF_5_1_BITS11_0 = 0,
-	IPIPEIF_5_1_BITS10_0 = 1,
-	IPIPEIF_5_1_BITS9_0 = 2,
-	IPIPEIF_5_1_BITS8_0 = 3,
-	IPIPEIF_5_1_BITS7_0 = 4,
-	IPIPEIF_5_1_BITS15_4 = 5,
-};
-
-#define IPIPEIF_PAD_SINK      0
-#define IPIPEIF_PAD_SOURCE    1
-
-#define IPIPEIF_NUM_PADS	2
-
-enum ipipeif_input_entity {
-	IPIPEIF_INPUT_NONE = 0,
-	IPIPEIF_INPUT_ISIF = 1,
-	IPIPEIF_INPUT_MEMORY = 2,
-};
-
-enum ipipeif_output_entity {
-	IPIPEIF_OUTPUT_NONE = 0,
-	IPIPEIF_OUTPUT_IPIPE = 1,
-	IPIPEIF_OUTPUT_RESIZER = 2,
-};
-
-struct vpfe_ipipeif_device {
-	struct v4l2_subdev subdev;
-	struct media_pad pads[IPIPEIF_NUM_PADS];
-	struct v4l2_mbus_framefmt formats[IPIPEIF_NUM_PADS];
-	enum ipipeif_input_entity input;
-	unsigned int output;
-	struct vpfe_video_device video_in;
-	struct v4l2_ctrl_handler ctrls;
-	void __iomem *ipipeif_base_addr;
-	struct ipipeif_params config;
-	int dpcm_predictor;
-	int gain;
-};
-
-/* IPIPEIF Register Offsets from the base address */
-#define IPIPEIF_ENABLE			0x00
-#define IPIPEIF_CFG1			0x04
-#define IPIPEIF_PPLN			0x08
-#define IPIPEIF_LPFR			0x0c
-#define IPIPEIF_HNUM			0x10
-#define IPIPEIF_VNUM			0x14
-#define IPIPEIF_ADDRU			0x18
-#define IPIPEIF_ADDRL			0x1c
-#define IPIPEIF_ADOFS			0x20
-#define IPIPEIF_RSZ			0x24
-#define IPIPEIF_GAIN			0x28
-
-/* Below registers are available only on IPIPE 5.1 */
-#define IPIPEIF_DPCM			0x2c
-#define IPIPEIF_CFG2			0x30
-#define IPIPEIF_INIRSZ			0x34
-#define IPIPEIF_OCLIP			0x38
-#define IPIPEIF_DTUDF			0x3c
-#define IPIPEIF_CLKDIV			0x40
-#define IPIPEIF_DPC1			0x44
-#define IPIPEIF_DPC2			0x48
-#define IPIPEIF_DFSGVL			0x4c
-#define IPIPEIF_DFSGTH			0x50
-#define IPIPEIF_RSZ3A			0x54
-#define IPIPEIF_INIRSZ3A		0x58
-#define IPIPEIF_RSZ_MIN			16
-#define IPIPEIF_RSZ_MAX			112
-#define IPIPEIF_RSZ_CONST		16
-
-#define IPIPEIF_ADOFS_LSB_MASK		0x1ff
-#define IPIPEIF_ADOFS_LSB_SHIFT		5
-#define IPIPEIF_ADOFS_MSB_MASK		0x200
-#define IPIPEIF_ADDRU_MASK		0x7ff
-#define IPIPEIF_ADDRL_SHIFT		5
-#define IPIPEIF_ADDRL_MASK		0xffff
-#define IPIPEIF_ADDRU_SHIFT		21
-#define IPIPEIF_ADDRMSB_SHIFT		31
-#define IPIPEIF_ADDRMSB_LEFT_SHIFT	10
-
-/* CFG1 Masks and shifts */
-#define ONESHOT_SHIFT			0
-#define DECIM_SHIFT			1
-#define INPSRC_SHIFT			2
-#define CLKDIV_SHIFT			4
-#define AVGFILT_SHIFT			7
-#define PACK8IN_SHIFT			8
-#define IALAW_SHIFT			9
-#define CLKSEL_SHIFT			10
-#define DATASFT_SHIFT			11
-#define INPSRC1_SHIFT			14
-
-/* DPC2 */
-#define IPIPEIF_DPC2_EN_SHIFT		12
-#define IPIPEIF_DPC2_THR_MASK		0xfff
-/* Applicable for IPIPE 5.1 */
-#define IPIPEIF_DF_GAIN_EN_SHIFT	10
-#define IPIPEIF_DF_GAIN_MASK		0x3ff
-#define IPIPEIF_DF_GAIN_THR_MASK	0xfff
-/* DPCM */
-#define IPIPEIF_DPCM_BITS_SHIFT		2
-#define IPIPEIF_DPCM_PRED_SHIFT		1
-/* CFG2 */
-#define IPIPEIF_CFG2_HDPOL_SHIFT	1
-#define IPIPEIF_CFG2_VDPOL_SHIFT	2
-#define IPIPEIF_CFG2_YUV8_SHIFT		6
-#define IPIPEIF_CFG2_YUV16_SHIFT	3
-#define IPIPEIF_CFG2_YUV8P_SHIFT	7
-
-/* INIRSZ */
-#define IPIPEIF_INIRSZ_ALNSYNC_SHIFT	13
-#define IPIPEIF_INIRSZ_MASK		0x1fff
-
-/* CLKDIV */
-#define IPIPEIF_CLKDIV_M_SHIFT		8
-
-void vpfe_ipipeif_enable(struct vpfe_device *vpfe_dev);
-void vpfe_ipipeif_ss_buffer_isr(struct vpfe_ipipeif_device *ipipeif);
-int vpfe_ipipeif_decimation_enabled(struct vpfe_device *vpfe_dev);
-int vpfe_ipipeif_get_rsz(struct vpfe_device *vpfe_dev);
-void vpfe_ipipeif_cleanup(struct vpfe_ipipeif_device *ipipeif,
-			  struct platform_device *pdev);
-int vpfe_ipipeif_init(struct vpfe_ipipeif_device *ipipeif,
-		      struct platform_device *pdev);
-int vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif,
-				   struct v4l2_device *vdev);
-void vpfe_ipipeif_unregister_entities(struct vpfe_ipipeif_device *ipipeif);
-
-#endif		/* _DAVINCI_VPFE_DM365_IPIPEIF_H */
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif_user.h b/drivers/staging/media/davinci_vpfe/dm365_ipipeif_user.h
deleted file mode 100644
index 046dbde..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif_user.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _DAVINCI_VPFE_DM365_IPIPEIF_USER_H
-#define _DAVINCI_VPFE_DM365_IPIPEIF_USER_H
-
-/* clockdiv for IPIPE 5.1 */
-struct ipipeif_5_1_clkdiv {
-	unsigned char m;
-	unsigned char n;
-};
-
-enum ipipeif_decimation {
-	IPIPEIF_DECIMATION_OFF,
-	IPIPEIF_DECIMATION_ON
-};
-
-/* DPC at the if for IPIPE 5.1 */
-struct ipipeif_dpc {
-	/* 0 - disable, 1 - enable */
-	unsigned char en;
-	/* threshold */
-	unsigned short thr;
-};
-
-enum ipipeif_clock {
-	IPIPEIF_PIXCEL_CLK,
-	IPIPEIF_SDRAM_CLK
-};
-
-enum  ipipeif_avg_filter {
-	IPIPEIF_AVG_OFF,
-	IPIPEIF_AVG_ON
-};
-
-struct ipipeif_5_1 {
-	struct ipipeif_5_1_clkdiv clk_div;
-	/* Defect pixel correction */
-	struct ipipeif_dpc dpc;
-	/* clipped to this value */
-	unsigned short clip;
-	/* Align HSync and VSync to rsz_start */
-	unsigned char align_sync;
-	/* resizer start position */
-	unsigned int rsz_start;
-	/* DF gain enable */
-	unsigned char df_gain_en;
-	/* DF gain value */
-	unsigned short df_gain;
-	/* DF gain threshold value */
-	unsigned short df_gain_thr;
-};
-
-struct ipipeif_params {
-	enum ipipeif_clock clock_select;
-	unsigned int ppln;
-	unsigned int lpfr;
-	unsigned char rsz;
-	enum ipipeif_decimation decimation;
-	enum ipipeif_avg_filter avg_filter;
-	/* IPIPE 5.1 */
-	struct ipipeif_5_1 if_5_1;
-};
-
-/*
- * Private IOCTL
- * VIDIOC_VPFE_IPIPEIF_S_CONFIG: Set IPIEIF configuration
- * VIDIOC_VPFE_IPIPEIF_G_CONFIG: Get IPIEIF configuration
- */
-#define VIDIOC_VPFE_IPIPEIF_S_CONFIG \
-	_IOWR('I', BASE_VIDIOC_PRIVATE + 1, struct ipipeif_params)
-#define VIDIOC_VPFE_IPIPEIF_G_CONFIG \
-	_IOWR('I', BASE_VIDIOC_PRIVATE + 2, struct ipipeif_params)
-
-#endif		/* _DAVINCI_VPFE_DM365_IPIPEIF_USER_H */
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
deleted file mode 100644
index 05a997f..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ /dev/null
@@ -1,2097 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#include <linux/delay.h>
-#include "dm365_isif.h"
-#include "vpfe_mc_capture.h"
-
-#define MAX_WIDTH	4096
-#define MAX_HEIGHT	4096
-
-static const unsigned int isif_fmts[] = {
-	MEDIA_BUS_FMT_YUYV8_2X8,
-	MEDIA_BUS_FMT_UYVY8_2X8,
-	MEDIA_BUS_FMT_YUYV8_1X16,
-	MEDIA_BUS_FMT_YUYV10_1X20,
-	MEDIA_BUS_FMT_SGRBG12_1X12,
-	MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8,
-	MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
-};
-
-#define ISIF_COLPTN_R_Ye	0x0
-#define ISIF_COLPTN_Gr_Cy	0x1
-#define ISIF_COLPTN_Gb_G	0x2
-#define ISIF_COLPTN_B_Mg	0x3
-
-#define ISIF_CCOLP_CP01_0	0
-#define ISIF_CCOLP_CP03_2	2
-#define ISIF_CCOLP_CP05_4	4
-#define ISIF_CCOLP_CP07_6	6
-#define ISIF_CCOLP_CP11_0	8
-#define ISIF_CCOLP_CP13_2	10
-#define ISIF_CCOLP_CP15_4	12
-#define ISIF_CCOLP_CP17_6	14
-
-static const u32 isif_sgrbg_pattern =
-	ISIF_COLPTN_Gr_Cy <<  ISIF_CCOLP_CP01_0 |
-	ISIF_COLPTN_R_Ye  << ISIF_CCOLP_CP03_2 |
-	ISIF_COLPTN_B_Mg  << ISIF_CCOLP_CP05_4 |
-	ISIF_COLPTN_Gb_G  << ISIF_CCOLP_CP07_6 |
-	ISIF_COLPTN_Gr_Cy << ISIF_CCOLP_CP11_0 |
-	ISIF_COLPTN_R_Ye  << ISIF_CCOLP_CP13_2 |
-	ISIF_COLPTN_B_Mg  << ISIF_CCOLP_CP15_4 |
-	ISIF_COLPTN_Gb_G  << ISIF_CCOLP_CP17_6;
-
-static const u32 isif_srggb_pattern =
-	ISIF_COLPTN_R_Ye  << ISIF_CCOLP_CP01_0 |
-	ISIF_COLPTN_Gr_Cy << ISIF_CCOLP_CP03_2 |
-	ISIF_COLPTN_Gb_G  << ISIF_CCOLP_CP05_4 |
-	ISIF_COLPTN_B_Mg  << ISIF_CCOLP_CP07_6 |
-	ISIF_COLPTN_R_Ye  << ISIF_CCOLP_CP11_0 |
-	ISIF_COLPTN_Gr_Cy << ISIF_CCOLP_CP13_2 |
-	ISIF_COLPTN_Gb_G  << ISIF_CCOLP_CP15_4 |
-	ISIF_COLPTN_B_Mg  << ISIF_CCOLP_CP17_6;
-
-static inline u32 isif_read(void __iomem *base_addr, u32 offset)
-{
-	return readl(base_addr + offset);
-}
-
-static inline void isif_write(void __iomem *base_addr, u32 val, u32 offset)
-{
-	writel(val, base_addr + offset);
-}
-
-static inline u32 isif_merge(void __iomem *base_addr, u32 mask, u32 val,
-			     u32 offset)
-{
-	u32 new_val = (isif_read(base_addr, offset) & ~mask) | (val & mask);
-
-	isif_write(base_addr, new_val, offset);
-
-	return new_val;
-}
-
-static void isif_enable_output_to_sdram(struct vpfe_isif_device *isif, int en)
-{
-	isif_merge(isif->isif_cfg.base_addr, ISIF_SYNCEN_WEN_MASK,
-		   en << ISIF_SYNCEN_WEN_SHIFT, SYNCEN);
-}
-
-static inline void
-isif_regw_lin_tbl(struct vpfe_isif_device *isif, u32 val, u32 offset, int i)
-{
-	if (!i)
-		writel(val, isif->isif_cfg.linear_tbl0_addr + offset);
-	else
-		writel(val, isif->isif_cfg.linear_tbl1_addr + offset);
-}
-
-static void isif_disable_all_modules(struct vpfe_isif_device *isif)
-{
-	/* disable BC */
-	isif_write(isif->isif_cfg.base_addr, 0, CLAMPCFG);
-	/* disable vdfc */
-	isif_write(isif->isif_cfg.base_addr, 0, DFCCTL);
-	/* disable CSC */
-	isif_write(isif->isif_cfg.base_addr, 0, CSCCTL);
-	/* disable linearization */
-	isif_write(isif->isif_cfg.base_addr, 0, LINCFG0);
-}
-
-static void isif_enable(struct vpfe_isif_device *isif, int en)
-{
-	if (!en)
-		/* Before disable isif, disable all ISIF modules */
-		isif_disable_all_modules(isif);
-
-	/*
-	 * wait for next VD. Assume lowest scan rate is 12 Hz. So
-	 * 100 msec delay is good enough
-	 */
-	msleep(100);
-	isif_merge(isif->isif_cfg.base_addr, ISIF_SYNCEN_VDHDEN_MASK,
-		   en, SYNCEN);
-}
-
-/*
- * ISIF helper functions
- */
-
-#define DM365_ISIF_MDFS_OFFSET		15
-#define DM365_ISIF_MDFS_MASK		0x1
-
-/* get field id in isif hardware */
-enum v4l2_field vpfe_isif_get_fid(struct vpfe_device *vpfe_dev)
-{
-	struct vpfe_isif_device *isif = &vpfe_dev->vpfe_isif;
-	u32 field_status;
-
-	field_status = isif_read(isif->isif_cfg.base_addr, MODESET);
-	return (field_status >> DM365_ISIF_MDFS_OFFSET) &
-		DM365_ISIF_MDFS_MASK;
-}
-
-static int
-isif_set_pixel_format(struct vpfe_isif_device *isif, unsigned int pixfmt)
-{
-	if (isif->formats[ISIF_PAD_SINK].code == MEDIA_BUS_FMT_SGRBG12_1X12) {
-		if (pixfmt == V4L2_PIX_FMT_SBGGR16)
-			isif->isif_cfg.data_pack = ISIF_PACK_16BIT;
-		else if ((pixfmt == V4L2_PIX_FMT_SGRBG10DPCM8) ||
-				(pixfmt == V4L2_PIX_FMT_SGRBG10ALAW8))
-			isif->isif_cfg.data_pack = ISIF_PACK_8BIT;
-		else
-			return -EINVAL;
-
-		isif->isif_cfg.bayer.pix_fmt = ISIF_PIXFMT_RAW;
-		isif->isif_cfg.bayer.v4l2_pix_fmt = pixfmt;
-	} else {
-		if (pixfmt == V4L2_PIX_FMT_YUYV)
-			isif->isif_cfg.ycbcr.pix_order = ISIF_PIXORDER_YCBYCR;
-		else if (pixfmt == V4L2_PIX_FMT_UYVY)
-			isif->isif_cfg.ycbcr.pix_order = ISIF_PIXORDER_CBYCRY;
-		else
-			return -EINVAL;
-
-		isif->isif_cfg.data_pack = ISIF_PACK_8BIT;
-		isif->isif_cfg.ycbcr.v4l2_pix_fmt = pixfmt;
-	}
-
-	return 0;
-}
-
-static int
-isif_set_frame_format(struct vpfe_isif_device *isif,
-		      enum isif_frmfmt frm_fmt)
-{
-	if (isif->formats[ISIF_PAD_SINK].code == MEDIA_BUS_FMT_SGRBG12_1X12)
-		isif->isif_cfg.bayer.frm_fmt = frm_fmt;
-	else
-		isif->isif_cfg.ycbcr.frm_fmt = frm_fmt;
-
-	return 0;
-}
-
-static int isif_set_image_window(struct vpfe_isif_device *isif)
-{
-	struct v4l2_rect *win = &isif->crop;
-
-	if (isif->formats[ISIF_PAD_SINK].code == MEDIA_BUS_FMT_SGRBG12_1X12) {
-		isif->isif_cfg.bayer.win.top = win->top;
-		isif->isif_cfg.bayer.win.left = win->left;
-		isif->isif_cfg.bayer.win.width = win->width;
-		isif->isif_cfg.bayer.win.height = win->height;
-		return 0;
-	}
-	isif->isif_cfg.ycbcr.win.top = win->top;
-	isif->isif_cfg.ycbcr.win.left = win->left;
-	isif->isif_cfg.ycbcr.win.width = win->width;
-	isif->isif_cfg.ycbcr.win.height = win->height;
-
-	return 0;
-}
-
-static int
-isif_set_buftype(struct vpfe_isif_device *isif, enum isif_buftype buf_type)
-{
-	if (isif->formats[ISIF_PAD_SINK].code == MEDIA_BUS_FMT_SGRBG12_1X12)
-		isif->isif_cfg.bayer.buf_type = buf_type;
-	else
-		isif->isif_cfg.ycbcr.buf_type = buf_type;
-
-	return 0;
-}
-
-/* configure format in isif hardware */
-static int
-isif_config_format(struct vpfe_device *vpfe_dev, unsigned int pad)
-{
-	struct vpfe_isif_device *vpfe_isif = &vpfe_dev->vpfe_isif;
-	enum isif_frmfmt frm_fmt = ISIF_FRMFMT_INTERLACED;
-	struct v4l2_pix_format format;
-	int ret = 0;
-
-	v4l2_fill_pix_format(&format, &vpfe_dev->vpfe_isif.formats[pad]);
-	mbus_to_pix(&vpfe_dev->vpfe_isif.formats[pad], &format);
-
-	if (isif_set_pixel_format(vpfe_isif, format.pixelformat) < 0) {
-		v4l2_err(&vpfe_dev->v4l2_dev,
-			 "Failed to set pixel format in isif\n");
-		return -EINVAL;
-	}
-
-	/* call for s_crop will override these values */
-	vpfe_isif->crop.left = 0;
-	vpfe_isif->crop.top = 0;
-	vpfe_isif->crop.width = format.width;
-	vpfe_isif->crop.height = format.height;
-
-	/* configure the image window */
-	isif_set_image_window(vpfe_isif);
-
-	switch (vpfe_dev->vpfe_isif.formats[pad].field) {
-	case V4L2_FIELD_INTERLACED:
-		/* do nothing, since it is default */
-		ret = isif_set_buftype(vpfe_isif, ISIF_BUFTYPE_FLD_INTERLEAVED);
-		break;
-
-	case V4L2_FIELD_NONE:
-		frm_fmt = ISIF_FRMFMT_PROGRESSIVE;
-		/* buffer type only applicable for interlaced scan */
-		break;
-
-	case V4L2_FIELD_SEQ_TB:
-		ret = isif_set_buftype(vpfe_isif, ISIF_BUFTYPE_FLD_SEPARATED);
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* set the frame format */
-	if (!ret)
-		ret = isif_set_frame_format(vpfe_isif, frm_fmt);
-
-	return ret;
-}
-
-/*
- * isif_try_format() - Try video format on a pad
- * @isif: VPFE isif device
- * @cfg: V4L2 subdev pad config
- * @fmt: pointer to v4l2 subdev format structure
- */
-static void
-isif_try_format(struct vpfe_isif_device *isif,
-		struct v4l2_subdev_pad_config *cfg,
-		struct v4l2_subdev_format *fmt)
-{
-	unsigned int width = fmt->format.width;
-	unsigned int height = fmt->format.height;
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(isif_fmts); i++) {
-		if (fmt->format.code == isif_fmts[i])
-			break;
-	}
-
-	/* If not found, use YUYV8_2x8 as default */
-	if (i >= ARRAY_SIZE(isif_fmts))
-		fmt->format.code = MEDIA_BUS_FMT_YUYV8_2X8;
-
-	/* Clamp the size. */
-	fmt->format.width = clamp_t(u32, width, 32, MAX_WIDTH);
-	fmt->format.height = clamp_t(u32, height, 32, MAX_HEIGHT);
-
-	/* The data formatter truncates the number of horizontal output
-	 * pixels to a multiple of 16. To avoid clipping data, allow
-	 * callers to request an output size bigger than the input size
-	 * up to the nearest multiple of 16.
-	 */
-	if (fmt->pad == ISIF_PAD_SOURCE)
-		fmt->format.width &= ~15;
-}
-
-/*
- * vpfe_isif_buffer_isr() - isif module non-progressive buffer scheduling isr
- * @isif: Pointer to isif subdevice.
- */
-void vpfe_isif_buffer_isr(struct vpfe_isif_device *isif)
-{
-	struct vpfe_device *vpfe_dev = to_vpfe_device(isif);
-	struct vpfe_video_device *video = &isif->video_out;
-	enum v4l2_field field;
-	int fid;
-
-	if (!video->started)
-		return;
-
-	field = video->fmt.fmt.pix.field;
-
-	if (field == V4L2_FIELD_NONE) {
-		/* handle progressive frame capture */
-		if (video->cur_frm != video->next_frm)
-			vpfe_video_process_buffer_complete(video);
-		return;
-	}
-
-	/* interlaced or TB capture check which field we
-	 * are in hardware
-	 */
-	fid = vpfe_isif_get_fid(vpfe_dev);
-
-	/* switch the software maintained field id */
-	video->field_id ^= 1;
-	if (fid == video->field_id) {
-		/* we are in-sync here,continue */
-		if (fid == 0) {
-			/*
-			 * One frame is just being captured. If the
-			 * next frame is available, release the current
-			 * frame and move on
-			 */
-			if (video->cur_frm != video->next_frm)
-				vpfe_video_process_buffer_complete(video);
-			/*
-			 * based on whether the two fields are stored
-			 * interleavely or separately in memory,
-			 * reconfigure the ISIF memory address
-			 */
-			if (field == V4L2_FIELD_SEQ_TB)
-				vpfe_video_schedule_bottom_field(video);
-			return;
-		}
-		/*
-		 * if one field is just being captured configure
-		 * the next frame get the next frame from the
-		 * empty queue if no frame is available hold on
-		 * to the current buffer
-		 */
-		spin_lock(&video->dma_queue_lock);
-		if (!list_empty(&video->dma_queue) &&
-		video->cur_frm == video->next_frm)
-			vpfe_video_schedule_next_buffer(video);
-		spin_unlock(&video->dma_queue_lock);
-	} else if (fid == 0) {
-		/*
-		 * out of sync. Recover from any hardware out-of-sync.
-		 * May loose one frame
-		 */
-		video->field_id = fid;
-	}
-}
-
-/*
- * vpfe_isif_vidint1_isr() - ISIF module progressive buffer scheduling isr
- * @isif: Pointer to isif subdevice.
- */
-void vpfe_isif_vidint1_isr(struct vpfe_isif_device *isif)
-{
-	struct vpfe_video_device *video = &isif->video_out;
-
-	if (!video->started)
-		return;
-
-	spin_lock(&video->dma_queue_lock);
-	if (video->fmt.fmt.pix.field == V4L2_FIELD_NONE &&
-	    !list_empty(&video->dma_queue) && video->cur_frm == video->next_frm)
-		vpfe_video_schedule_next_buffer(video);
-
-	spin_unlock(&video->dma_queue_lock);
-}
-
-/*
- * VPFE video operations
- */
-
-static int isif_video_queue(struct vpfe_device *vpfe_dev, unsigned long addr)
-{
-	struct vpfe_isif_device *isif = &vpfe_dev->vpfe_isif;
-
-	isif_write(isif->isif_cfg.base_addr, (addr >> 21) &
-		ISIF_CADU_BITS, CADU);
-	isif_write(isif->isif_cfg.base_addr, (addr >> 5) &
-		ISIF_CADL_BITS, CADL);
-
-	return 0;
-}
-
-static const struct vpfe_video_operations isif_video_ops = {
-	.queue = isif_video_queue,
-};
-
-/*
- * V4L2 subdev operations
- */
-
-/* Parameter operations */
-static int isif_get_params(struct v4l2_subdev *sd, void *params)
-{
-	struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
-
-	/* only raw module parameters can be set through the IOCTL */
-	if (isif->formats[ISIF_PAD_SINK].code != MEDIA_BUS_FMT_SGRBG12_1X12)
-		return -EINVAL;
-	memcpy(params, &isif->isif_cfg.bayer.config_params,
-			sizeof(isif->isif_cfg.bayer.config_params));
-	return 0;
-}
-
-static int isif_validate_df_csc_params(const struct vpfe_isif_df_csc *df_csc)
-{
-	const struct vpfe_isif_color_space_conv *csc;
-	int err = -EINVAL;
-	int i;
-
-	if (!df_csc->df_or_csc) {
-		/* csc configuration */
-		csc = &df_csc->csc;
-		if (csc->en) {
-			for (i = 0; i < VPFE_ISIF_CSC_NUM_COEFF; i++)
-				if (csc->coeff[i].integer >
-				    ISIF_CSC_COEF_INTEG_MASK ||
-				    csc->coeff[i].decimal >
-				    ISIF_CSC_COEF_DECIMAL_MASK) {
-					pr_err("Invalid CSC coefficients\n");
-					return err;
-				}
-		}
-	}
-	if (df_csc->start_pix > ISIF_DF_CSC_SPH_MASK) {
-		pr_err("Invalid df_csc start pix value\n");
-		return err;
-	}
-
-	if (df_csc->num_pixels > ISIF_DF_NUMPIX) {
-		pr_err("Invalid df_csc num pixels value\n");
-		return err;
-	}
-
-	if (df_csc->start_line > ISIF_DF_CSC_LNH_MASK) {
-		pr_err("Invalid df_csc start_line value\n");
-		return err;
-	}
-
-	if (df_csc->num_lines > ISIF_DF_NUMLINES) {
-		pr_err("Invalid df_csc num_lines value\n");
-		return err;
-	}
-
-	return 0;
-}
-
-#define DM365_ISIF_MAX_VDFLSFT		4
-#define DM365_ISIF_MAX_VDFSLV		4095
-#define DM365_ISIF_MAX_DFCMEM0		0x1fff
-#define DM365_ISIF_MAX_DFCMEM1		0x1fff
-
-static int isif_validate_dfc_params(const struct vpfe_isif_dfc *dfc)
-{
-	int err = -EINVAL;
-	int i;
-
-	if (!dfc->en)
-		return 0;
-
-	if (dfc->corr_whole_line > 1) {
-		pr_err("Invalid corr_whole_line value\n");
-		return err;
-	}
-
-	if (dfc->def_level_shift > DM365_ISIF_MAX_VDFLSFT) {
-		pr_err("Invalid def_level_shift value\n");
-		return err;
-	}
-
-	if (dfc->def_sat_level > DM365_ISIF_MAX_VDFSLV) {
-		pr_err("Invalid def_sat_level value\n");
-		return err;
-	}
-
-	if (!dfc->num_vdefects ||
-	    dfc->num_vdefects > VPFE_ISIF_VDFC_TABLE_SIZE) {
-		pr_err("Invalid num_vdefects value\n");
-		return err;
-	}
-
-	for (i = 0; i < VPFE_ISIF_VDFC_TABLE_SIZE; i++) {
-		if (dfc->table[i].pos_vert > DM365_ISIF_MAX_DFCMEM0) {
-			pr_err("Invalid pos_vert value\n");
-			return err;
-		}
-		if (dfc->table[i].pos_horz > DM365_ISIF_MAX_DFCMEM1) {
-			pr_err("Invalid pos_horz value\n");
-			return err;
-		}
-	}
-
-	return 0;
-}
-
-#define DM365_ISIF_MAX_CLVRV			0xfff
-#define DM365_ISIF_MAX_CLDC			0x1fff
-#define DM365_ISIF_MAX_CLHSH			0x1fff
-#define DM365_ISIF_MAX_CLHSV			0x1fff
-#define DM365_ISIF_MAX_CLVSH			0x1fff
-#define DM365_ISIF_MAX_CLVSV			0x1fff
-#define DM365_ISIF_MAX_HEIGHT_BLACK_REGION	0x1fff
-
-static int isif_validate_bclamp_params(const struct vpfe_isif_black_clamp *bclamp)
-{
-	int err = -EINVAL;
-
-	if (bclamp->dc_offset > DM365_ISIF_MAX_CLDC) {
-		pr_err("Invalid bclamp dc_offset value\n");
-		return err;
-	}
-	if (!bclamp->en)
-		return 0;
-	if (bclamp->horz.clamp_pix_limit > 1) {
-		pr_err("Invalid bclamp horz clamp_pix_limit value\n");
-		return err;
-	}
-	if (bclamp->horz.win_count_calc < 1 ||
-			bclamp->horz.win_count_calc > 32) {
-		pr_err("Invalid bclamp horz win_count_calc value\n");
-		return err;
-	}
-	if (bclamp->horz.win_start_h_calc > DM365_ISIF_MAX_CLHSH) {
-		pr_err("Invalid bclamp win_start_v_calc value\n");
-		return err;
-	}
-
-	if (bclamp->horz.win_start_v_calc > DM365_ISIF_MAX_CLHSV) {
-		pr_err("Invalid bclamp win_start_v_calc value\n");
-		return err;
-	}
-	if (bclamp->vert.reset_clamp_val > DM365_ISIF_MAX_CLVRV) {
-		pr_err("Invalid bclamp reset_clamp_val value\n");
-		return err;
-	}
-	if (bclamp->vert.ob_v_sz_calc > DM365_ISIF_MAX_HEIGHT_BLACK_REGION) {
-		pr_err("Invalid bclamp ob_v_sz_calc value\n");
-		return err;
-	}
-	if (bclamp->vert.ob_start_h > DM365_ISIF_MAX_CLVSH) {
-		pr_err("Invalid bclamp ob_start_h value\n");
-		return err;
-	}
-	if (bclamp->vert.ob_start_v > DM365_ISIF_MAX_CLVSV) {
-		pr_err("Invalid bclamp ob_start_h value\n");
-		return err;
-	}
-	return 0;
-}
-
-static int
-isif_validate_raw_params(const struct vpfe_isif_raw_config *params)
-{
-	int ret;
-
-	ret = isif_validate_df_csc_params(&params->df_csc);
-	if (ret)
-		return ret;
-	ret = isif_validate_dfc_params(&params->dfc);
-	if (ret)
-		return ret;
-	return isif_validate_bclamp_params(&params->bclamp);
-}
-
-static int isif_set_params(struct v4l2_subdev *sd, const struct vpfe_isif_raw_config *params)
-{
-	struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
-	int ret = -EINVAL;
-
-	/* only raw module parameters can be set through the IOCTL */
-	if (isif->formats[ISIF_PAD_SINK].code != MEDIA_BUS_FMT_SGRBG12_1X12)
-		return ret;
-
-	if (!isif_validate_raw_params(params)) {
-		memcpy(&isif->isif_cfg.bayer.config_params, params,
-			sizeof(*params));
-		ret = 0;
-	}
-	return ret;
-}
-/*
- * isif_ioctl() - isif module private ioctl's
- * @sd: VPFE isif V4L2 subdevice
- * @cmd: ioctl command
- * @arg: ioctl argument
- *
- * Return 0 on success or a negative error code otherwise.
- */
-static long isif_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	switch (cmd) {
-	case VIDIOC_VPFE_ISIF_S_RAW_PARAMS:
-		return isif_set_params(sd, arg);
-
-	case VIDIOC_VPFE_ISIF_G_RAW_PARAMS:
-		return isif_get_params(sd, arg);
-
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-static void isif_config_gain_offset(struct vpfe_isif_device *isif)
-{
-	struct vpfe_isif_gain_offsets_adj *gain_off_ptr =
-		&isif->isif_cfg.bayer.config_params.gain_offset;
-	void __iomem *base = isif->isif_cfg.base_addr;
-	u32 val;
-
-	val = ((gain_off_ptr->gain_sdram_en & 1) << GAIN_SDRAM_EN_SHIFT) |
-	      ((gain_off_ptr->gain_ipipe_en & 1) << GAIN_IPIPE_EN_SHIFT) |
-	      ((gain_off_ptr->gain_h3a_en & 1) << GAIN_H3A_EN_SHIFT) |
-	      ((gain_off_ptr->offset_sdram_en & 1) << OFST_SDRAM_EN_SHIFT) |
-	      ((gain_off_ptr->offset_ipipe_en & 1) << OFST_IPIPE_EN_SHIFT) |
-	      ((gain_off_ptr->offset_h3a_en & 1) << OFST_H3A_EN_SHIFT);
-	isif_merge(base, GAIN_OFFSET_EN_MASK, val, CGAMMAWD);
-
-	isif_write(base, isif->isif_cfg.isif_gain_params.cr_gain, CRGAIN);
-	isif_write(base, isif->isif_cfg.isif_gain_params.cgr_gain, CGRGAIN);
-	isif_write(base, isif->isif_cfg.isif_gain_params.cgb_gain, CGBGAIN);
-	isif_write(base, isif->isif_cfg.isif_gain_params.cb_gain, CBGAIN);
-	isif_write(base, isif->isif_cfg.isif_gain_params.offset & OFFSET_MASK,
-		   COFSTA);
-
-}
-
-static void isif_config_bclamp(struct vpfe_isif_device *isif,
-		   struct vpfe_isif_black_clamp *bc)
-{
-	u32 val;
-
-	/**
-	 * DC Offset is always added to image data irrespective of bc enable
-	 * status
-	 */
-	val = bc->dc_offset & ISIF_BC_DCOFFSET_MASK;
-	isif_write(isif->isif_cfg.base_addr, val, CLDCOFST);
-
-	if (!bc->en)
-		return;
-
-	val = (bc->bc_mode_color & ISIF_BC_MODE_COLOR_MASK) <<
-		ISIF_BC_MODE_COLOR_SHIFT;
-
-	/* Enable BC and horizontal clamp calculation parameters */
-	val = val | 1 | ((bc->horz.mode & ISIF_HORZ_BC_MODE_MASK) <<
-	      ISIF_HORZ_BC_MODE_SHIFT);
-
-	isif_write(isif->isif_cfg.base_addr, val, CLAMPCFG);
-
-	if (bc->horz.mode != VPFE_ISIF_HORZ_BC_DISABLE) {
-		/*
-		 * Window count for calculation
-		 * Base window selection
-		 * pixel limit
-		 * Horizontal size of window
-		 * vertical size of the window
-		 * Horizontal start position of the window
-		 * Vertical start position of the window
-		 */
-		val = (bc->horz.win_count_calc & ISIF_HORZ_BC_WIN_COUNT_MASK) |
-		      ((bc->horz.base_win_sel_calc & 1) <<
-		      ISIF_HORZ_BC_WIN_SEL_SHIFT) |
-		      ((bc->horz.clamp_pix_limit & 1) <<
-		      ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
-		      ((bc->horz.win_h_sz_calc &
-		      ISIF_HORZ_BC_WIN_H_SIZE_MASK) <<
-		      ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
-		      ((bc->horz.win_v_sz_calc &
-		      ISIF_HORZ_BC_WIN_V_SIZE_MASK) <<
-		      ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
-
-		isif_write(isif->isif_cfg.base_addr, val, CLHWIN0);
-
-		val = bc->horz.win_start_h_calc & ISIF_HORZ_BC_WIN_START_H_MASK;
-		isif_write(isif->isif_cfg.base_addr, val, CLHWIN1);
-
-		val = bc->horz.win_start_v_calc & ISIF_HORZ_BC_WIN_START_V_MASK;
-		isif_write(isif->isif_cfg.base_addr, val, CLHWIN2);
-	}
-
-	/* vertical clamp calculation parameters */
-	/* OB H Valid */
-	val = bc->vert.ob_h_sz_calc & ISIF_VERT_BC_OB_H_SZ_MASK;
-
-	/* Reset clamp value sel for previous line */
-	val |= (bc->vert.reset_val_sel & ISIF_VERT_BC_RST_VAL_SEL_MASK) <<
-				ISIF_VERT_BC_RST_VAL_SEL_SHIFT;
-
-	/* Line average coefficient */
-	val |= bc->vert.line_ave_coef << ISIF_VERT_BC_LINE_AVE_COEF_SHIFT;
-	isif_write(isif->isif_cfg.base_addr, val, CLVWIN0);
-
-	/* Configured reset value */
-	if (bc->vert.reset_val_sel == VPFE_ISIF_VERT_BC_USE_CONFIG_CLAMP_VAL) {
-		val = bc->vert.reset_clamp_val & ISIF_VERT_BC_RST_VAL_MASK;
-		isif_write(isif->isif_cfg.base_addr, val, CLVRV);
-	}
-
-	/* Optical Black horizontal start position */
-	val = bc->vert.ob_start_h & ISIF_VERT_BC_OB_START_HORZ_MASK;
-	isif_write(isif->isif_cfg.base_addr, val, CLVWIN1);
-
-	/* Optical Black vertical start position */
-	val = bc->vert.ob_start_v & ISIF_VERT_BC_OB_START_VERT_MASK;
-	isif_write(isif->isif_cfg.base_addr, val, CLVWIN2);
-
-	val = bc->vert.ob_v_sz_calc & ISIF_VERT_BC_OB_VERT_SZ_MASK;
-	isif_write(isif->isif_cfg.base_addr, val, CLVWIN3);
-
-	/* Vertical start position for BC subtraction */
-	val = bc->vert_start_sub & ISIF_BC_VERT_START_SUB_V_MASK;
-	isif_write(isif->isif_cfg.base_addr, val, CLSV);
-}
-
-/* This function will configure the window size to be capture in ISIF reg */
-static void
-isif_setwin(struct vpfe_isif_device *isif, struct v4l2_rect *image_win,
-	    enum isif_frmfmt frm_fmt, int ppc, int mode)
-{
-	int horz_nr_pixels;
-	int vert_nr_lines;
-	int horz_start;
-	int vert_start;
-	int mid_img;
-
-	/*
-	 * ppc - per pixel count. indicates how many pixels per cell
-	 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
-	 * raw capture this is 1
-	 */
-	horz_start = image_win->left << (ppc - 1);
-	horz_nr_pixels = (image_win->width << (ppc - 1)) - 1;
-
-	/* Writing the horizontal info into the registers */
-	isif_write(isif->isif_cfg.base_addr,
-		   horz_start & START_PX_HOR_MASK, SPH);
-	isif_write(isif->isif_cfg.base_addr,
-		   horz_nr_pixels & NUM_PX_HOR_MASK, LNH);
-	vert_start = image_win->top;
-
-	if (frm_fmt == ISIF_FRMFMT_INTERLACED) {
-		vert_nr_lines = (image_win->height >> 1) - 1;
-		vert_start >>= 1;
-		/* To account for VD since line 0 doesn't have any data */
-		vert_start += 1;
-	} else {
-		/* To account for VD since line 0 doesn't have any data */
-		vert_start += 1;
-		vert_nr_lines = image_win->height - 1;
-		/* configure VDINT0 and VDINT1 */
-		mid_img = vert_start + (image_win->height / 2);
-		isif_write(isif->isif_cfg.base_addr, mid_img, VDINT1);
-	}
-
-	if (!mode)
-		isif_write(isif->isif_cfg.base_addr, 0, VDINT0);
-	else
-		isif_write(isif->isif_cfg.base_addr, vert_nr_lines, VDINT0);
-	isif_write(isif->isif_cfg.base_addr,
-		   vert_start & START_VER_ONE_MASK, SLV0);
-	isif_write(isif->isif_cfg.base_addr,
-		   vert_start & START_VER_TWO_MASK, SLV1);
-	isif_write(isif->isif_cfg.base_addr,
-		   vert_nr_lines & NUM_LINES_VER, LNV);
-}
-
-#define DM365_ISIF_DFCMWR_MEMORY_WRITE		1
-#define DM365_ISIF_DFCMRD_MEMORY_READ		0x2
-
-static void
-isif_config_dfc(struct vpfe_isif_device *isif, struct vpfe_isif_dfc *vdfc)
-{
-#define DFC_WRITE_WAIT_COUNT	1000
-	u32 count = DFC_WRITE_WAIT_COUNT;
-	u32 val;
-	int i;
-
-	if (!vdfc->en)
-		return;
-
-	/* Correction mode */
-	val = (vdfc->corr_mode & ISIF_VDFC_CORR_MOD_MASK) <<
-	       ISIF_VDFC_CORR_MOD_SHIFT;
-
-	/* Correct whole line or partial */
-	if (vdfc->corr_whole_line)
-		val |= BIT(ISIF_VDFC_CORR_WHOLE_LN_SHIFT);
-
-	/* level shift value */
-	val |= (vdfc->def_level_shift & ISIF_VDFC_LEVEL_SHFT_MASK) <<
-		ISIF_VDFC_LEVEL_SHFT_SHIFT;
-
-	isif_write(isif->isif_cfg.base_addr, val, DFCCTL);
-
-	/* Defect saturation level */
-	val = vdfc->def_sat_level & ISIF_VDFC_SAT_LEVEL_MASK;
-	isif_write(isif->isif_cfg.base_addr, val, VDFSATLV);
-
-	isif_write(isif->isif_cfg.base_addr, vdfc->table[0].pos_vert &
-		   ISIF_VDFC_POS_MASK, DFCMEM0);
-	isif_write(isif->isif_cfg.base_addr, vdfc->table[0].pos_horz &
-		   ISIF_VDFC_POS_MASK, DFCMEM1);
-	if (vdfc->corr_mode == VPFE_ISIF_VDFC_NORMAL ||
-	    vdfc->corr_mode == VPFE_ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
-		isif_write(isif->isif_cfg.base_addr,
-			   vdfc->table[0].level_at_pos, DFCMEM2);
-		isif_write(isif->isif_cfg.base_addr,
-			   vdfc->table[0].level_up_pixels, DFCMEM3);
-		isif_write(isif->isif_cfg.base_addr,
-			   vdfc->table[0].level_low_pixels, DFCMEM4);
-	}
-
-	val = isif_read(isif->isif_cfg.base_addr, DFCMEMCTL);
-	/* set DFCMARST and set DFCMWR */
-	val |= BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
-	val |= 1;
-	isif_write(isif->isif_cfg.base_addr, val, DFCMEMCTL);
-
-	while (count && (isif_read(isif->isif_cfg.base_addr, DFCMEMCTL) & 0x01))
-		count--;
-
-	val = isif_read(isif->isif_cfg.base_addr, DFCMEMCTL);
-	if (!count) {
-		pr_debug("defect table write timeout !!\n");
-		return;
-	}
-
-	for (i = 1; i < vdfc->num_vdefects; i++) {
-		isif_write(isif->isif_cfg.base_addr, vdfc->table[i].pos_vert &
-			ISIF_VDFC_POS_MASK, DFCMEM0);
-
-		isif_write(isif->isif_cfg.base_addr, vdfc->table[i].pos_horz &
-			ISIF_VDFC_POS_MASK, DFCMEM1);
-
-		if (vdfc->corr_mode == VPFE_ISIF_VDFC_NORMAL ||
-		    vdfc->corr_mode == VPFE_ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
-			isif_write(isif->isif_cfg.base_addr,
-				   vdfc->table[i].level_at_pos, DFCMEM2);
-			isif_write(isif->isif_cfg.base_addr,
-				   vdfc->table[i].level_up_pixels, DFCMEM3);
-			isif_write(isif->isif_cfg.base_addr,
-				   vdfc->table[i].level_low_pixels, DFCMEM4);
-		}
-		val = isif_read(isif->isif_cfg.base_addr, DFCMEMCTL);
-		/* clear DFCMARST and set DFCMWR */
-		val &= ~BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
-		val |= 1;
-		isif_write(isif->isif_cfg.base_addr, val, DFCMEMCTL);
-
-		count = DFC_WRITE_WAIT_COUNT;
-		while (count && (isif_read(isif->isif_cfg.base_addr,
-			DFCMEMCTL) & 0x01))
-			count--;
-
-		val = isif_read(isif->isif_cfg.base_addr, DFCMEMCTL);
-		if (!count) {
-			pr_debug("defect table write timeout !!\n");
-			return;
-		}
-	}
-	if (vdfc->num_vdefects < VPFE_ISIF_VDFC_TABLE_SIZE) {
-		/* Extra cycle needed */
-		isif_write(isif->isif_cfg.base_addr, 0, DFCMEM0);
-		isif_write(isif->isif_cfg.base_addr,
-			   DM365_ISIF_MAX_DFCMEM1, DFCMEM1);
-		isif_write(isif->isif_cfg.base_addr,
-			   DM365_ISIF_DFCMWR_MEMORY_WRITE, DFCMEMCTL);
-	}
-	/* enable VDFC */
-	isif_merge(isif->isif_cfg.base_addr, (1 << ISIF_VDFC_EN_SHIFT),
-		   (1 << ISIF_VDFC_EN_SHIFT), DFCCTL);
-
-	isif_merge(isif->isif_cfg.base_addr, (1 << ISIF_VDFC_EN_SHIFT),
-		   (0 << ISIF_VDFC_EN_SHIFT), DFCCTL);
-
-	isif_write(isif->isif_cfg.base_addr, 0x6, DFCMEMCTL);
-	for (i = 0; i < vdfc->num_vdefects; i++) {
-		count = DFC_WRITE_WAIT_COUNT;
-		while (count &&
-			(isif_read(isif->isif_cfg.base_addr, DFCMEMCTL) & 0x2))
-			count--;
-		val = isif_read(isif->isif_cfg.base_addr, DFCMEMCTL);
-		if (!count) {
-			pr_debug("defect table write timeout !!\n");
-			return;
-		}
-		isif_write(isif->isif_cfg.base_addr,
-			   DM365_ISIF_DFCMRD_MEMORY_READ, DFCMEMCTL);
-	}
-}
-
-static void
-isif_config_csc(struct vpfe_isif_device *isif, struct vpfe_isif_df_csc *df_csc)
-{
-	u32 val1;
-	u32 val2;
-	u32 i;
-
-	if (!df_csc->csc.en) {
-		isif_write(isif->isif_cfg.base_addr, 0, CSCCTL);
-		return;
-	}
-	/* initialize all bits to 0 */
-	val1 = 0;
-	for (i = 0; i < VPFE_ISIF_CSC_NUM_COEFF; i++) {
-		if ((i % 2) == 0) {
-			/* CSCM - LSB */
-			val1 = ((df_csc->csc.coeff[i].integer &
-				ISIF_CSC_COEF_INTEG_MASK) <<
-				ISIF_CSC_COEF_INTEG_SHIFT) |
-				((df_csc->csc.coeff[i].decimal &
-				ISIF_CSC_COEF_DECIMAL_MASK));
-		} else {
-
-			/* CSCM - MSB */
-			val2 = ((df_csc->csc.coeff[i].integer &
-				ISIF_CSC_COEF_INTEG_MASK) <<
-				ISIF_CSC_COEF_INTEG_SHIFT) |
-				((df_csc->csc.coeff[i].decimal &
-				ISIF_CSC_COEF_DECIMAL_MASK));
-			val2 <<= ISIF_CSCM_MSB_SHIFT;
-			val2 |= val1;
-			isif_write(isif->isif_cfg.base_addr, val2,
-				   (CSCM0 + ((i-1) << 1)));
-		}
-	}
-	/* program the active area */
-	isif_write(isif->isif_cfg.base_addr, df_csc->start_pix &
-		ISIF_DF_CSC_SPH_MASK, FMTSPH);
-	/*
-	 * one extra pixel as required for CSC. Actually number of
-	 * pixel - 1 should be configured in this register. So we
-	 * need to subtract 1 before writing to FMTSPH, but we will
-	 * not do this since csc requires one extra pixel
-	 */
-	isif_write(isif->isif_cfg.base_addr, df_csc->num_pixels &
-		ISIF_DF_CSC_SPH_MASK, FMTLNH);
-	isif_write(isif->isif_cfg.base_addr, df_csc->start_line &
-		ISIF_DF_CSC_SPH_MASK, FMTSLV);
-	/*
-	 * one extra line as required for CSC. See reason documented for
-	 * num_pixels
-	 */
-	isif_write(isif->isif_cfg.base_addr, df_csc->num_lines &
-		ISIF_DF_CSC_SPH_MASK, FMTLNV);
-	/* Enable CSC */
-	isif_write(isif->isif_cfg.base_addr, 1, CSCCTL);
-}
-
-static void
-isif_config_linearization(struct vpfe_isif_device *isif,
-			  struct vpfe_isif_linearize *linearize)
-{
-	u32 val;
-	u32 i;
-
-	if (!linearize->en) {
-		isif_write(isif->isif_cfg.base_addr, 0, LINCFG0);
-		return;
-	}
-	/* shift value for correction */
-	val = (linearize->corr_shft & ISIF_LIN_CORRSFT_MASK) <<
-	      ISIF_LIN_CORRSFT_SHIFT;
-	/* enable */
-	val |= 1;
-	isif_write(isif->isif_cfg.base_addr, val, LINCFG0);
-	/* Scale factor */
-	val = (linearize->scale_fact.integer & 1) <<
-	      ISIF_LIN_SCALE_FACT_INTEG_SHIFT;
-	val |= linearize->scale_fact.decimal & ISIF_LIN_SCALE_FACT_DECIMAL_MASK;
-	isif_write(isif->isif_cfg.base_addr, val, LINCFG1);
-
-	for (i = 0; i < VPFE_ISIF_LINEAR_TAB_SIZE; i++) {
-		val = linearize->table[i] & ISIF_LIN_ENTRY_MASK;
-		if (i%2)
-			isif_regw_lin_tbl(isif, val, ((i >> 1) << 2), 1);
-		else
-			isif_regw_lin_tbl(isif, val, ((i >> 1) << 2), 0);
-	}
-}
-
-static void
-isif_config_culling(struct vpfe_isif_device *isif, struct vpfe_isif_cul *cul)
-{
-	u32 val;
-
-	/* Horizontal pattern */
-	val = cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT;
-	val |= cul->hcpat_odd;
-	isif_write(isif->isif_cfg.base_addr, val, CULH);
-	/* vertical pattern */
-	isif_write(isif->isif_cfg.base_addr, cul->vcpat, CULV);
-	/* LPF */
-	isif_merge(isif->isif_cfg.base_addr, ISIF_LPF_MASK << ISIF_LPF_SHIFT,
-		   cul->en_lpf << ISIF_LPF_SHIFT, MODESET);
-}
-
-static int isif_get_pix_fmt(u32 mbus_code)
-{
-	switch (mbus_code) {
-	case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
-	case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
-	case MEDIA_BUS_FMT_SGRBG12_1X12:
-		return ISIF_PIXFMT_RAW;
-
-	case MEDIA_BUS_FMT_YUYV8_2X8:
-	case MEDIA_BUS_FMT_UYVY8_2X8:
-	case MEDIA_BUS_FMT_YUYV10_2X10:
-	case MEDIA_BUS_FMT_Y8_1X8:
-		return ISIF_PIXFMT_YCBCR_8BIT;
-
-	case MEDIA_BUS_FMT_YUYV8_1X16:
-	case MEDIA_BUS_FMT_YUYV10_1X20:
-		return ISIF_PIXFMT_YCBCR_16BIT;
-
-	default:
-		break;
-	}
-	return -EINVAL;
-}
-
-#define ISIF_INTERLACE_INVERSE_MODE		0x4b6d
-#define ISIF_INTERLACE_NON_INVERSE_MODE		0x0b6d
-#define ISIF_PROGRESSIVE_INVERSE_MODE		0x4000
-#define ISIF_PROGRESSIVE_NON_INVERSE_MODE	0x0000
-
-static int isif_config_raw(struct v4l2_subdev *sd, int mode)
-{
-	struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
-	struct isif_params_raw *params = &isif->isif_cfg.bayer;
-	struct vpfe_isif_raw_config *module_params =
-				&isif->isif_cfg.bayer.config_params;
-	struct v4l2_mbus_framefmt *format;
-	int pix_fmt;
-	u32 val;
-
-	format = &isif->formats[ISIF_PAD_SINK];
-
-	/* In case of user has set BT656IF earlier, it should be reset
-	 * when configuring for raw input.
-	 */
-	isif_write(isif->isif_cfg.base_addr, 0, REC656IF);
-	/* Configure CCDCFG register
-	 * Set CCD Not to swap input since input is RAW data
-	 * Set FID detection function to Latch at V-Sync
-	 * Set WENLOG - isif valid area
-	 * Set TRGSEL
-	 * Set EXTRG
-	 * Packed to 8 or 16 bits
-	 */
-	val = ISIF_YCINSWP_RAW | ISIF_CCDCFG_FIDMD_LATCH_VSYNC |
-	      ISIF_CCDCFG_WENLOG_AND | ISIF_CCDCFG_TRGSEL_WEN |
-	      ISIF_CCDCFG_EXTRG_DISABLE | (isif->isif_cfg.data_pack &
-	      ISIF_DATA_PACK_MASK);
-	isif_write(isif->isif_cfg.base_addr, val, CCDCFG);
-
-	pix_fmt = isif_get_pix_fmt(format->code);
-	if (pix_fmt < 0) {
-		pr_debug("Invalid pix_fmt(input mode)\n");
-		return -EINVAL;
-	}
-	/*
-	 * Configure the vertical sync polarity(MODESET.VDPOL)
-	 * Configure the horizontal sync polarity (MODESET.HDPOL)
-	 * Configure frame id polarity (MODESET.FLDPOL)
-	 * Configure data polarity
-	 * Configure External WEN Selection
-	 * Configure frame format(progressive or interlace)
-	 * Configure pixel format (Input mode)
-	 * Configure the data shift
-	 */
-	val = ISIF_VDHDOUT_INPUT | ((params->vd_pol & ISIF_VD_POL_MASK) <<
-	      ISIF_VD_POL_SHIFT) | ((params->hd_pol & ISIF_HD_POL_MASK) <<
-	      ISIF_HD_POL_SHIFT) | ((params->fid_pol & ISIF_FID_POL_MASK) <<
-	      ISIF_FID_POL_SHIFT) | ((ISIF_DATAPOL_NORMAL &
-	      ISIF_DATAPOL_MASK) << ISIF_DATAPOL_SHIFT) | ((ISIF_EXWEN_DISABLE &
-	      ISIF_EXWEN_MASK) << ISIF_EXWEN_SHIFT) | ((params->frm_fmt &
-	      ISIF_FRM_FMT_MASK) << ISIF_FRM_FMT_SHIFT) | ((pix_fmt &
-	      ISIF_INPUT_MASK) << ISIF_INPUT_SHIFT);
-
-	/* currently only MEDIA_BUS_FMT_SGRBG12_1X12 is
-	 * supported. shift appropriately depending on
-	 * different MBUS fmt's added
-	 */
-	if (format->code == MEDIA_BUS_FMT_SGRBG12_1X12)
-		val |= ((VPFE_ISIF_NO_SHIFT &
-			ISIF_DATASFT_MASK) << ISIF_DATASFT_SHIFT);
-
-	isif_write(isif->isif_cfg.base_addr, val, MODESET);
-	/*
-	 * Configure GAMMAWD register
-	 * CFA pattern setting
-	 */
-	val = (params->cfa_pat & ISIF_GAMMAWD_CFA_MASK) <<
-		ISIF_GAMMAWD_CFA_SHIFT;
-	/* Gamma msb */
-	if (params->v4l2_pix_fmt == V4L2_PIX_FMT_SGRBG10ALAW8)
-		val = val | ISIF_ALAW_ENABLE;
-
-	val = val | ((params->data_msb & ISIF_ALAW_GAMA_WD_MASK) <<
-			ISIF_ALAW_GAMA_WD_SHIFT);
-
-	isif_write(isif->isif_cfg.base_addr, val, CGAMMAWD);
-	/* Configure DPCM compression settings */
-	if (params->v4l2_pix_fmt == V4L2_PIX_FMT_SGRBG10DPCM8) {
-		val =  BIT(ISIF_DPCM_EN_SHIFT);
-		val |= (params->dpcm_predictor &
-			ISIF_DPCM_PREDICTOR_MASK) << ISIF_DPCM_PREDICTOR_SHIFT;
-	}
-	isif_write(isif->isif_cfg.base_addr, val, MISC);
-	/* Configure Gain & Offset */
-	isif_config_gain_offset(isif);
-	/* Configure Color pattern */
-	if (format->code == MEDIA_BUS_FMT_SGRBG12_1X12)
-		val = isif_sgrbg_pattern;
-	else
-		/* default set to rggb */
-		val = isif_srggb_pattern;
-
-	isif_write(isif->isif_cfg.base_addr, val, CCOLP);
-
-	/* Configure HSIZE register  */
-	val = (params->horz_flip_en & ISIF_HSIZE_FLIP_MASK) <<
-	      ISIF_HSIZE_FLIP_SHIFT;
-
-	/* calculate line offset in 32 bytes based on pack value */
-	if (isif->isif_cfg.data_pack == ISIF_PACK_8BIT)
-		val |= ((params->win.width + 31) >> 5) & ISIF_LINEOFST_MASK;
-	else if (isif->isif_cfg.data_pack == ISIF_PACK_12BIT)
-		val |= ((((params->win.width + (params->win.width >> 2)) +
-			31) >> 5) & ISIF_LINEOFST_MASK);
-	else
-		val |= (((params->win.width * 2) + 31) >> 5) &
-			ISIF_LINEOFST_MASK;
-	isif_write(isif->isif_cfg.base_addr, val, HSIZE);
-	/* Configure SDOFST register  */
-	if (params->frm_fmt == ISIF_FRMFMT_INTERLACED) {
-		if (params->image_invert_en)
-			/* For interlace inverse mode */
-			isif_write(isif->isif_cfg.base_addr,
-				   ISIF_INTERLACE_INVERSE_MODE, SDOFST);
-		else
-			/* For interlace non inverse mode */
-			isif_write(isif->isif_cfg.base_addr,
-				   ISIF_INTERLACE_NON_INVERSE_MODE, SDOFST);
-	} else if (params->frm_fmt == ISIF_FRMFMT_PROGRESSIVE) {
-		if (params->image_invert_en)
-			isif_write(isif->isif_cfg.base_addr,
-				   ISIF_PROGRESSIVE_INVERSE_MODE, SDOFST);
-		else
-			/* For progessive non inverse mode */
-			isif_write(isif->isif_cfg.base_addr,
-				   ISIF_PROGRESSIVE_NON_INVERSE_MODE, SDOFST);
-	}
-	/* Configure video window */
-	isif_setwin(isif, &params->win, params->frm_fmt, 1, mode);
-	/* Configure Black Clamp */
-	isif_config_bclamp(isif, &module_params->bclamp);
-	/* Configure Vertical Defection Pixel Correction */
-	isif_config_dfc(isif, &module_params->dfc);
-	if (!module_params->df_csc.df_or_csc)
-		/* Configure Color Space Conversion */
-		isif_config_csc(isif, &module_params->df_csc);
-
-	isif_config_linearization(isif, &module_params->linearize);
-	/* Configure Culling */
-	isif_config_culling(isif, &module_params->culling);
-	/* Configure Horizontal and vertical offsets(DFC,LSC,Gain) */
-	val = module_params->horz_offset & ISIF_DATA_H_OFFSET_MASK;
-	isif_write(isif->isif_cfg.base_addr, val, DATAHOFST);
-
-	val = module_params->vert_offset & ISIF_DATA_V_OFFSET_MASK;
-	isif_write(isif->isif_cfg.base_addr, val, DATAVOFST);
-
-	return 0;
-}
-
-#define DM365_ISIF_HSIZE_MASK		0xffffffe0
-#define DM365_ISIF_SDOFST_2_LINES	0x00000249
-
-/* This function will configure ISIF for YCbCr parameters. */
-static int isif_config_ycbcr(struct v4l2_subdev *sd, int mode)
-{
-	struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
-	struct isif_ycbcr_config *params = &isif->isif_cfg.ycbcr;
-	struct v4l2_mbus_framefmt *format;
-	int pix_fmt;
-	u32 modeset;
-	u32 ccdcfg;
-
-	format = &isif->formats[ISIF_PAD_SINK];
-	/*
-	 * first reset the ISIF
-	 * all registers have default values after reset
-	 * This is important since we assume default values to be set in
-	 * a lot of registers that we didn't touch
-	 */
-	/* start with all bits zero */
-	ccdcfg = 0;
-	modeset = 0;
-	pix_fmt = isif_get_pix_fmt(format->code);
-	if (pix_fmt < 0) {
-		pr_debug("Invalid pix_fmt(input mode)\n");
-		return -EINVAL;
-	}
-	/* configure pixel format or input mode */
-	modeset = modeset | ((pix_fmt & ISIF_INPUT_MASK) <<
-		  ISIF_INPUT_SHIFT) | ((params->frm_fmt & ISIF_FRM_FMT_MASK) <<
-		  ISIF_FRM_FMT_SHIFT) | (((params->fid_pol &
-		  ISIF_FID_POL_MASK) << ISIF_FID_POL_SHIFT)) |
-		  (((params->hd_pol & ISIF_HD_POL_MASK) << ISIF_HD_POL_SHIFT)) |
-		  (((params->vd_pol & ISIF_VD_POL_MASK) << ISIF_VD_POL_SHIFT));
-	/* pack the data to 8-bit CCDCCFG */
-	switch (format->code) {
-	case MEDIA_BUS_FMT_YUYV8_2X8:
-	case MEDIA_BUS_FMT_UYVY8_2X8:
-		if (pix_fmt != ISIF_PIXFMT_YCBCR_8BIT) {
-			pr_debug("Invalid pix_fmt(input mode)\n");
-			return -EINVAL;
-		}
-		modeset |= ((VPFE_PINPOL_NEGATIVE & ISIF_VD_POL_MASK) <<
-				ISIF_VD_POL_SHIFT);
-		isif_write(isif->isif_cfg.base_addr, 3, REC656IF);
-		ccdcfg = ccdcfg | ISIF_PACK_8BIT | ISIF_YCINSWP_YCBCR;
-		break;
-
-	case MEDIA_BUS_FMT_YUYV10_2X10:
-		if (pix_fmt != ISIF_PIXFMT_YCBCR_8BIT) {
-			pr_debug("Invalid pix_fmt(input mode)\n");
-			return -EINVAL;
-		}
-		/* setup BT.656, embedded sync  */
-		isif_write(isif->isif_cfg.base_addr, 3, REC656IF);
-		/* enable 10 bit mode in ccdcfg */
-		ccdcfg = ccdcfg | ISIF_PACK_8BIT | ISIF_YCINSWP_YCBCR |
-			ISIF_BW656_ENABLE;
-		break;
-
-	case MEDIA_BUS_FMT_YUYV10_1X20:
-		if (pix_fmt != ISIF_PIXFMT_YCBCR_16BIT) {
-			pr_debug("Invalid pix_fmt(input mode)\n");
-			return -EINVAL;
-		}
-		isif_write(isif->isif_cfg.base_addr, 3, REC656IF);
-		break;
-
-	case MEDIA_BUS_FMT_Y8_1X8:
-		ccdcfg |= ISIF_PACK_8BIT;
-		ccdcfg |= ISIF_YCINSWP_YCBCR;
-		if (pix_fmt != ISIF_PIXFMT_YCBCR_8BIT) {
-			pr_debug("Invalid pix_fmt(input mode)\n");
-			return -EINVAL;
-		}
-		break;
-
-	case MEDIA_BUS_FMT_YUYV8_1X16:
-		if (pix_fmt != ISIF_PIXFMT_YCBCR_16BIT) {
-			pr_debug("Invalid pix_fmt(input mode)\n");
-			return -EINVAL;
-		}
-		break;
-
-	default:
-		/* should never come here */
-		pr_debug("Invalid interface type\n");
-		return -EINVAL;
-	}
-	isif_write(isif->isif_cfg.base_addr, modeset, MODESET);
-	/* Set up pix order */
-	ccdcfg |= (params->pix_order & ISIF_PIX_ORDER_MASK) <<
-		ISIF_PIX_ORDER_SHIFT;
-	isif_write(isif->isif_cfg.base_addr, ccdcfg, CCDCFG);
-	/* configure video window */
-	if (format->code == MEDIA_BUS_FMT_YUYV10_1X20 ||
-			format->code == MEDIA_BUS_FMT_YUYV8_1X16)
-		isif_setwin(isif, &params->win, params->frm_fmt, 1, mode);
-	else
-		isif_setwin(isif, &params->win, params->frm_fmt, 2, mode);
-
-	/*
-	 * configure the horizontal line offset
-	 * this is done by rounding up width to a multiple of 16 pixels
-	 * and multiply by two to account for y:cb:cr 4:2:2 data
-	 */
-	isif_write(isif->isif_cfg.base_addr,
-		   ((((params->win.width * 2) + 31) &
-		   DM365_ISIF_HSIZE_MASK) >> 5), HSIZE);
-
-	/* configure the memory line offset */
-	if (params->frm_fmt == ISIF_FRMFMT_INTERLACED &&
-	    params->buf_type == ISIF_BUFTYPE_FLD_INTERLEAVED)
-		/* two fields are interleaved in memory */
-		isif_write(isif->isif_cfg.base_addr,
-			   DM365_ISIF_SDOFST_2_LINES, SDOFST);
-	return 0;
-}
-
-static int isif_configure(struct v4l2_subdev *sd, int mode)
-{
-	struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *format;
-
-	format = &isif->formats[ISIF_PAD_SINK];
-
-	switch (format->code) {
-	case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
-	case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
-	case MEDIA_BUS_FMT_SGRBG12_1X12:
-		return isif_config_raw(sd, mode);
-
-	case MEDIA_BUS_FMT_YUYV8_2X8:
-	case MEDIA_BUS_FMT_UYVY8_2X8:
-	case MEDIA_BUS_FMT_YUYV10_2X10:
-	case MEDIA_BUS_FMT_Y8_1X8:
-	case MEDIA_BUS_FMT_YUYV8_1X16:
-	case MEDIA_BUS_FMT_YUYV10_1X20:
-		return isif_config_ycbcr(sd, mode);
-
-	default:
-		break;
-	}
-	return -EINVAL;
-}
-
-/*
- * isif_set_stream() - Enable/Disable streaming on the ISIF module
- * @sd: VPFE ISIF V4L2 subdevice
- * @enable: Enable/disable stream
- */
-static int isif_set_stream(struct v4l2_subdev *sd, int enable)
-{
-	struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
-	int ret;
-
-	if (enable) {
-		ret = isif_configure(sd,
-			(isif->output == ISIF_OUTPUT_MEMORY) ? 0 : 1);
-		if (ret)
-			return ret;
-		if (isif->output == ISIF_OUTPUT_MEMORY)
-			isif_enable_output_to_sdram(isif, 1);
-		isif_enable(isif, 1);
-	} else {
-		isif_enable(isif, 0);
-		isif_enable_output_to_sdram(isif, 0);
-	}
-
-	return 0;
-}
-
-/*
- * __isif_get_format() - helper function for getting isif format
- * @isif: pointer to isif private structure.
- * @pad: pad number.
- * @cfg: V4L2 subdev pad config
- * @which: wanted subdev format.
- */
-static struct v4l2_mbus_framefmt *
-__isif_get_format(struct vpfe_isif_device *isif,
-		  struct v4l2_subdev_pad_config *cfg, unsigned int pad,
-		  enum v4l2_subdev_format_whence which)
-{
-	if (which == V4L2_SUBDEV_FORMAT_TRY)
-		return v4l2_subdev_get_try_format(&isif->subdev, cfg, pad);
-
-	return &isif->formats[pad];
-}
-
-/*
- * isif_set_format() - set format on pad
- * @sd    : VPFE ISIF device
- * @cfg   : V4L2 subdev pad config
- * @fmt   : pointer to v4l2 subdev format structure
- *
- * Return 0 on success or -EINVAL if format or pad is invalid
- */
-static int
-isif_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-		struct v4l2_subdev_format *fmt)
-{
-	struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
-	struct vpfe_device *vpfe_dev = to_vpfe_device(isif);
-	struct v4l2_mbus_framefmt *format;
-
-	format = __isif_get_format(isif, cfg, fmt->pad, fmt->which);
-	if (format == NULL)
-		return -EINVAL;
-
-	isif_try_format(isif, cfg, fmt);
-	memcpy(format, &fmt->format, sizeof(*format));
-
-	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
-		return 0;
-
-	if (fmt->pad == ISIF_PAD_SOURCE)
-		return isif_config_format(vpfe_dev, fmt->pad);
-
-	return 0;
-}
-
-/*
- * isif_get_format() - Retrieve the video format on a pad
- * @sd: VPFE ISIF V4L2 subdevice
- * @cfg: V4L2 subdev pad config
- * @fmt: pointer to v4l2 subdev format structure
- *
- * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
- * to the format type.
- */
-static int
-isif_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-		struct v4l2_subdev_format *fmt)
-{
-	struct vpfe_isif_device *vpfe_isif = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *format;
-
-	format = __isif_get_format(vpfe_isif, cfg, fmt->pad, fmt->which);
-	if (format == NULL)
-		return -EINVAL;
-
-	memcpy(&fmt->format, format, sizeof(fmt->format));
-
-	return 0;
-}
-
-/*
- * isif_enum_frame_size() - enum frame sizes on pads
- * @sd: VPFE isif V4L2 subdevice
- * @cfg: V4L2 subdev pad config
- * @code: pointer to v4l2_subdev_frame_size_enum structure
- */
-static int
-isif_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-		     struct v4l2_subdev_frame_size_enum *fse)
-{
-	struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
-	struct v4l2_subdev_format format;
-
-	if (fse->index != 0)
-		return -EINVAL;
-
-	format.pad = fse->pad;
-	format.format.code = fse->code;
-	format.format.width = 1;
-	format.format.height = 1;
-	format.which = fse->which;
-	isif_try_format(isif, cfg, &format);
-	fse->min_width = format.format.width;
-	fse->min_height = format.format.height;
-
-	if (format.format.code != fse->code)
-		return -EINVAL;
-
-	format.pad = fse->pad;
-	format.format.code = fse->code;
-	format.format.width = -1;
-	format.format.height = -1;
-	format.which = fse->which;
-	isif_try_format(isif, cfg, &format);
-	fse->max_width = format.format.width;
-	fse->max_height = format.format.height;
-
-	return 0;
-}
-
-/*
- * isif_enum_mbus_code() - enum mbus codes for pads
- * @sd: VPFE isif V4L2 subdevice
- * @cfg: V4L2 subdev pad config
- * @code: pointer to v4l2_subdev_mbus_code_enum structure
- */
-static int
-isif_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-		    struct v4l2_subdev_mbus_code_enum *code)
-{
-	switch (code->pad) {
-	case ISIF_PAD_SINK:
-	case ISIF_PAD_SOURCE:
-		if (code->index >= ARRAY_SIZE(isif_fmts))
-			return -EINVAL;
-		code->code = isif_fmts[code->index];
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * isif_pad_set_selection() - set crop rectangle on pad
- * @sd: VPFE isif V4L2 subdevice
- * @cfg: V4L2 subdev pad config
- * @code: pointer to v4l2_subdev_mbus_code_enum structure
- *
- * Return 0 on success, -EINVAL if pad is invalid
- */
-static int
-isif_pad_set_selection(struct v4l2_subdev *sd,
-		       struct v4l2_subdev_pad_config *cfg,
-		       struct v4l2_subdev_selection *sel)
-{
-	struct vpfe_isif_device *vpfe_isif = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *format;
-
-	/* check whether it's a valid pad and target */
-	if (sel->pad != ISIF_PAD_SINK || sel->target != V4L2_SEL_TGT_CROP)
-		return -EINVAL;
-
-	format = __isif_get_format(vpfe_isif, cfg, sel->pad, sel->which);
-	if (format == NULL)
-		return -EINVAL;
-
-	/* check wether crop rect is within limits */
-	if (sel->r.top < 0 || sel->r.left < 0 ||
-		(sel->r.left + sel->r.width >
-		vpfe_isif->formats[ISIF_PAD_SINK].width) ||
-		(sel->r.top + sel->r.height >
-			vpfe_isif->formats[ISIF_PAD_SINK].height)) {
-		sel->r.left = 0;
-		sel->r.top = 0;
-		sel->r.width = format->width;
-		sel->r.height = format->height;
-	}
-	/* adjust the width to 16 pixel boundary */
-	sel->r.width = (sel->r.width + 15) & ~0xf;
-	vpfe_isif->crop = sel->r;
-	if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
-		isif_set_image_window(vpfe_isif);
-	} else {
-		struct v4l2_rect *rect;
-
-		rect = v4l2_subdev_get_try_crop(sd, cfg, ISIF_PAD_SINK);
-		memcpy(rect, &vpfe_isif->crop, sizeof(*rect));
-	}
-	return 0;
-}
-
-/*
- * isif_pad_get_selection() - get crop rectangle on pad
- * @sd: VPFE isif V4L2 subdevice
- * @cfg: V4L2 subdev pad config
- * @code: pointer to v4l2_subdev_mbus_code_enum structure
- *
- * Return 0 on success, -EINVAL if pad is invalid
- */
-static int
-isif_pad_get_selection(struct v4l2_subdev *sd,
-		       struct v4l2_subdev_pad_config *cfg,
-		       struct v4l2_subdev_selection *sel)
-{
-	struct vpfe_isif_device *vpfe_isif = v4l2_get_subdevdata(sd);
-
-	/* check whether it's a valid pad and target */
-	if (sel->pad != ISIF_PAD_SINK || sel->target != V4L2_SEL_TGT_CROP)
-		return -EINVAL;
-
-	if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
-		struct v4l2_rect *rect;
-
-		rect = v4l2_subdev_get_try_crop(sd, cfg, ISIF_PAD_SINK);
-		memcpy(&sel->r, rect, sizeof(*rect));
-	} else {
-		sel->r = vpfe_isif->crop;
-	}
-
-	return 0;
-}
-
-/*
- * isif_init_formats() - Initialize formats on all pads
- * @sd: VPFE isif V4L2 subdevice
- * @fh: V4L2 subdev file handle
- *
- * Initialize all pad formats with default values. Try formats are initialized
- * on the file handle.
- */
-static int
-isif_init_formats(struct v4l2_subdev *sd,
-		  struct v4l2_subdev_fh *fh)
-{
-	struct v4l2_subdev_format format;
-	struct v4l2_subdev_selection sel;
-
-	memset(&format, 0, sizeof(format));
-	format.pad = ISIF_PAD_SINK;
-	format.which = V4L2_SUBDEV_FORMAT_TRY;
-	format.format.code = MEDIA_BUS_FMT_SGRBG12_1X12;
-	format.format.width = MAX_WIDTH;
-	format.format.height = MAX_HEIGHT;
-	isif_set_format(sd, fh->pad, &format);
-
-	memset(&format, 0, sizeof(format));
-	format.pad = ISIF_PAD_SOURCE;
-	format.which = V4L2_SUBDEV_FORMAT_TRY;
-	format.format.code = MEDIA_BUS_FMT_SGRBG12_1X12;
-	format.format.width = MAX_WIDTH;
-	format.format.height = MAX_HEIGHT;
-	isif_set_format(sd, fh->pad, &format);
-
-	memset(&sel, 0, sizeof(sel));
-	sel.pad = ISIF_PAD_SINK;
-	sel.which = V4L2_SUBDEV_FORMAT_TRY;
-	sel.target = V4L2_SEL_TGT_CROP;
-	sel.r.width = MAX_WIDTH;
-	sel.r.height = MAX_HEIGHT;
-	isif_pad_set_selection(sd, fh->pad, &sel);
-
-	return 0;
-}
-
-/* subdev core operations */
-static const struct v4l2_subdev_core_ops isif_v4l2_core_ops = {
-	.ioctl = isif_ioctl,
-};
-
-/* subdev file operations */
-static const struct v4l2_subdev_internal_ops isif_v4l2_internal_ops = {
-	.open = isif_init_formats,
-};
-
-/* subdev video operations */
-static const struct v4l2_subdev_video_ops isif_v4l2_video_ops = {
-	.s_stream = isif_set_stream,
-};
-
-/* subdev pad operations */
-static const struct v4l2_subdev_pad_ops isif_v4l2_pad_ops = {
-	.enum_mbus_code = isif_enum_mbus_code,
-	.enum_frame_size = isif_enum_frame_size,
-	.get_fmt = isif_get_format,
-	.set_fmt = isif_set_format,
-	.set_selection = isif_pad_set_selection,
-	.get_selection = isif_pad_get_selection,
-};
-
-/* subdev operations */
-static const struct v4l2_subdev_ops isif_v4l2_ops = {
-	.core = &isif_v4l2_core_ops,
-	.video = &isif_v4l2_video_ops,
-	.pad = &isif_v4l2_pad_ops,
-};
-
-/*
- * Media entity operations
- */
-
-/*
- * isif_link_setup() - Setup isif connections
- * @entity: isif media entity
- * @local: Pad at the local end of the link
- * @remote: Pad at the remote end of the link
- * @flags: Link flags
- *
- * return -EINVAL or zero on success
- */
-static int
-isif_link_setup(struct media_entity *entity, const struct media_pad *local,
-		const struct media_pad *remote, u32 flags)
-{
-	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
-	struct vpfe_isif_device *isif = v4l2_get_subdevdata(sd);
-	unsigned int index = local->index;
-
-	/* FIXME: this is actually a hack! */
-	if (is_media_entity_v4l2_subdev(remote->entity))
-		index |= 2 << 16;
-
-	switch (index) {
-	case ISIF_PAD_SINK | 2 << 16:
-		/* read from decoder/sensor */
-		if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-			isif->input = ISIF_INPUT_NONE;
-			break;
-		}
-		if (isif->input != ISIF_INPUT_NONE)
-			return -EBUSY;
-		isif->input = ISIF_INPUT_PARALLEL;
-		break;
-
-	case ISIF_PAD_SOURCE:
-		/* write to memory */
-		if (flags & MEDIA_LNK_FL_ENABLED)
-			isif->output = ISIF_OUTPUT_MEMORY;
-		else
-			isif->output = ISIF_OUTPUT_NONE;
-		break;
-
-	case ISIF_PAD_SOURCE | 2 << 16:
-		if (flags & MEDIA_LNK_FL_ENABLED)
-			isif->output = ISIF_OUTPUT_IPIPEIF;
-		else
-			isif->output = ISIF_OUTPUT_NONE;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-static const struct media_entity_operations isif_media_ops = {
-	.link_setup = isif_link_setup,
-};
-
-/*
- * vpfe_isif_unregister_entities() - isif unregister entity
- * @isif - pointer to isif subdevice structure.
- */
-void vpfe_isif_unregister_entities(struct vpfe_isif_device *isif)
-{
-	vpfe_video_unregister(&isif->video_out);
-	/* 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)
-{
-	enum vpss_ccdc_source_sel source = VPSS_CCDCIN;
-	int i;
-
-	memset(&isif->isif_cfg.bayer.config_params, 0,
-	       sizeof(struct vpfe_isif_raw_config));
-
-	isif->isif_cfg.bayer.config_params.linearize.corr_shft =
-					VPFE_ISIF_NO_SHIFT;
-	isif->isif_cfg.bayer.config_params.linearize.scale_fact.integer = 1;
-	isif->isif_cfg.bayer.config_params.culling.hcpat_odd =
-			ISIF_CULLING_HCAPT_ODD;
-	isif->isif_cfg.bayer.config_params.culling.hcpat_even =
-			ISIF_CULLING_HCAPT_EVEN;
-	isif->isif_cfg.bayer.config_params.culling.vcpat = ISIF_CULLING_VCAPT;
-	/* Enable clock to ISIF, IPIPEIF and BL */
-	vpss_enable_clock(VPSS_CCDC_CLOCK, 1);
-	vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
-	vpss_enable_clock(VPSS_BL_CLOCK, 1);
-
-	/* set all registers to default value */
-	for (i = 0; i <= 0x1f8; i += 4)
-		isif_write(isif->isif_cfg.base_addr, 0, i);
-	/* no culling support */
-	isif_write(isif->isif_cfg.base_addr, 0xffff, CULH);
-	isif_write(isif->isif_cfg.base_addr, 0xff, CULV);
-
-	/* Set default offset and gain */
-	isif_config_gain_offset(isif);
-	vpss_select_ccdc_source(source);
-}
-
-/*
- * vpfe_isif_register_entities() - isif register entity
- * @isif - pointer to isif subdevice structure.
- * @vdev: pointer to v4l2 device structure.
- */
-int vpfe_isif_register_entities(struct vpfe_isif_device *isif,
-			    struct v4l2_device *vdev)
-{
-	struct vpfe_device *vpfe_dev = to_vpfe_device(isif);
-	unsigned int flags;
-	int ret;
-
-	/* Register the subdev */
-	ret = v4l2_device_register_subdev(vdev, &isif->subdev);
-	if (ret < 0)
-		return ret;
-
-	isif_restore_defaults(isif);
-	ret = vpfe_video_register(&isif->video_out, vdev);
-	if (ret) {
-		pr_err("Failed to register isif video out device\n");
-		goto out_video_register;
-	}
-	isif->video_out.vpfe_dev = vpfe_dev;
-	flags = 0;
-	/* connect isif to video node */
-	ret = media_create_pad_link(&isif->subdev.entity, 1,
-				       &isif->video_out.video_dev.entity,
-				       0, flags);
-	if (ret < 0)
-		goto out_create_link;
-	return 0;
-out_create_link:
-	vpfe_video_unregister(&isif->video_out);
-out_video_register:
-	v4l2_device_unregister_subdev(&isif->subdev);
-	return ret;
-}
-
-/* -------------------------------------------------------------------
- * V4L2 subdev control operations
- */
-
-static int vpfe_isif_s_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct vpfe_isif_device *isif =
-	     container_of(ctrl->handler, struct vpfe_isif_device, ctrls);
-	struct isif_oper_config *config = &isif->isif_cfg;
-
-	switch (ctrl->id) {
-	case VPFE_CID_DPCM_PREDICTOR:
-		config->bayer.dpcm_predictor = ctrl->val;
-		break;
-
-	case VPFE_ISIF_CID_CRGAIN:
-		config->isif_gain_params.cr_gain = ctrl->val;
-		break;
-
-	case VPFE_ISIF_CID_CGRGAIN:
-		config->isif_gain_params.cgr_gain = ctrl->val;
-		break;
-
-	case VPFE_ISIF_CID_CGBGAIN:
-		config->isif_gain_params.cgb_gain = ctrl->val;
-		break;
-
-	case VPFE_ISIF_CID_CBGAIN:
-		config->isif_gain_params.cb_gain = ctrl->val;
-		break;
-
-	case VPFE_ISIF_CID_GAIN_OFFSET:
-		config->isif_gain_params.offset = ctrl->val;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops vpfe_isif_ctrl_ops = {
-	.s_ctrl = vpfe_isif_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config vpfe_isif_dpcm_pred = {
-	.ops = &vpfe_isif_ctrl_ops,
-	.id = VPFE_CID_DPCM_PREDICTOR,
-	.name = "DPCM Predictor",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 0,
-	.max = 1,
-	.step = 1,
-	.def = 0,
-};
-
-static const struct v4l2_ctrl_config vpfe_isif_crgain = {
-	.ops = &vpfe_isif_ctrl_ops,
-	.id = VPFE_ISIF_CID_CRGAIN,
-	.name = "CRGAIN",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 0,
-	.max = (1 << 12) - 1,
-	.step = 1,
-	.def = 0,
-};
-
-static const struct v4l2_ctrl_config vpfe_isif_cgrgain = {
-	.ops = &vpfe_isif_ctrl_ops,
-	.id = VPFE_ISIF_CID_CGRGAIN,
-	.name = "CGRGAIN",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 0,
-	.max = (1 << 12) - 1,
-	.step = 1,
-	.def = 0,
-};
-
-static const struct v4l2_ctrl_config vpfe_isif_cgbgain = {
-	.ops = &vpfe_isif_ctrl_ops,
-	.id = VPFE_ISIF_CID_CGBGAIN,
-	.name = "CGBGAIN",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 0,
-	.max = (1 << 12) - 1,
-	.step = 1,
-	.def = 0,
-};
-
-static const struct v4l2_ctrl_config vpfe_isif_cbgain = {
-	.ops = &vpfe_isif_ctrl_ops,
-	.id = VPFE_ISIF_CID_CBGAIN,
-	.name = "CBGAIN",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 0,
-	.max = (1 << 12) - 1,
-	.step = 1,
-	.def = 0,
-};
-
-static const struct v4l2_ctrl_config vpfe_isif_gain_offset = {
-	.ops = &vpfe_isif_ctrl_ops,
-	.id = VPFE_ISIF_CID_GAIN_OFFSET,
-	.name = "Gain Offset",
-	.type = V4L2_CTRL_TYPE_INTEGER,
-	.min = 0,
-	.max = (1 << 12) - 1,
-	.step = 1,
-	.def = 0,
-};
-
-static void isif_remove(struct vpfe_isif_device *isif,
-			struct platform_device *pdev)
-{
-	struct resource *res;
-	int i = 0;
-
-	iounmap(isif->isif_cfg.base_addr);
-	iounmap(isif->isif_cfg.linear_tbl0_addr);
-	iounmap(isif->isif_cfg.linear_tbl1_addr);
-
-	while (i < 3) {
-		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
-		if (res)
-			release_mem_region(res->start,
-					   resource_size(res));
-		i++;
-	}
-}
-
-static void isif_config_defaults(struct vpfe_isif_device *isif)
-{
-	isif->isif_cfg.ycbcr.v4l2_pix_fmt = V4L2_PIX_FMT_UYVY;
-	isif->isif_cfg.ycbcr.pix_fmt = ISIF_PIXFMT_YCBCR_8BIT;
-	isif->isif_cfg.ycbcr.frm_fmt = ISIF_FRMFMT_INTERLACED;
-	isif->isif_cfg.ycbcr.fid_pol = VPFE_PINPOL_POSITIVE;
-	isif->isif_cfg.ycbcr.vd_pol = VPFE_PINPOL_POSITIVE;
-	isif->isif_cfg.ycbcr.hd_pol = VPFE_PINPOL_POSITIVE;
-	isif->isif_cfg.ycbcr.pix_order = ISIF_PIXORDER_CBYCRY;
-	isif->isif_cfg.ycbcr.buf_type = ISIF_BUFTYPE_FLD_INTERLEAVED;
-
-	isif->isif_cfg.bayer.v4l2_pix_fmt = V4L2_PIX_FMT_SGRBG10ALAW8;
-	isif->isif_cfg.bayer.pix_fmt = ISIF_PIXFMT_RAW;
-	isif->isif_cfg.bayer.frm_fmt = ISIF_FRMFMT_PROGRESSIVE;
-	isif->isif_cfg.bayer.fid_pol = VPFE_PINPOL_POSITIVE;
-	isif->isif_cfg.bayer.vd_pol = VPFE_PINPOL_POSITIVE;
-	isif->isif_cfg.bayer.hd_pol = VPFE_PINPOL_POSITIVE;
-	isif->isif_cfg.bayer.cfa_pat = ISIF_CFA_PAT_MOSAIC;
-	isif->isif_cfg.bayer.data_msb = ISIF_BIT_MSB_11;
-	isif->isif_cfg.data_pack = ISIF_PACK_8BIT;
-}
-/*
- * vpfe_isif_init() - Initialize V4L2 subdev and media entity
- * @isif: VPFE isif module
- * @pdev: Pointer to platform device structure.
- * Return 0 on success and a negative error code on failure.
- */
-int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev)
-{
-	struct v4l2_subdev *sd = &isif->subdev;
-	struct media_pad *pads = &isif->pads[0];
-	struct media_entity *me = &sd->entity;
-	static resource_size_t res_len;
-	struct resource *res;
-	void __iomem *addr;
-	int status;
-	int i = 0;
-
-	/* Get the ISIF base address, linearization table0 and table1 addr. */
-	while (i < 3) {
-		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
-		if (!res) {
-			status = -ENOENT;
-			goto fail_nobase_res;
-		}
-		res_len = resource_size(res);
-		res = request_mem_region(res->start, res_len, res->name);
-		if (!res) {
-			status = -EBUSY;
-			goto fail_nobase_res;
-		}
-		addr = ioremap_nocache(res->start, res_len);
-		if (!addr) {
-			status = -EBUSY;
-			goto fail_base_iomap;
-		}
-		switch (i) {
-		case 0:
-			/* ISIF base address */
-			isif->isif_cfg.base_addr = addr;
-			break;
-		case 1:
-			/* ISIF linear tbl0 address */
-			isif->isif_cfg.linear_tbl0_addr = addr;
-			break;
-		default:
-			/* ISIF linear tbl0 address */
-			isif->isif_cfg.linear_tbl1_addr = addr;
-			break;
-		}
-		i++;
-	}
-	davinci_cfg_reg(DM365_VIN_CAM_WEN);
-	davinci_cfg_reg(DM365_VIN_CAM_VD);
-	davinci_cfg_reg(DM365_VIN_CAM_HD);
-	davinci_cfg_reg(DM365_VIN_YIN4_7_EN);
-	davinci_cfg_reg(DM365_VIN_YIN0_3_EN);
-
-	/* queue ops */
-	isif->video_out.ops = &isif_video_ops;
-	v4l2_subdev_init(sd, &isif_v4l2_ops);
-	sd->internal_ops = &isif_v4l2_internal_ops;
-	strscpy(sd->name, "DAVINCI ISIF", sizeof(sd->name));
-	sd->grp_id = 1 << 16;	/* group ID for davinci subdevs */
-	v4l2_set_subdevdata(sd, isif);
-	sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
-	pads[ISIF_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-	pads[ISIF_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-
-	isif->input = ISIF_INPUT_NONE;
-	isif->output = ISIF_OUTPUT_NONE;
-	me->ops = &isif_media_ops;
-	status = media_entity_pads_init(me, ISIF_PADS_NUM, pads);
-	if (status)
-		goto isif_fail;
-	isif->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	status = vpfe_video_init(&isif->video_out, "ISIF");
-	if (status) {
-		pr_err("Failed to init isif-out video device\n");
-		goto isif_fail;
-	}
-	v4l2_ctrl_handler_init(&isif->ctrls, 6);
-	v4l2_ctrl_new_custom(&isif->ctrls, &vpfe_isif_crgain, NULL);
-	v4l2_ctrl_new_custom(&isif->ctrls, &vpfe_isif_cgrgain, NULL);
-	v4l2_ctrl_new_custom(&isif->ctrls, &vpfe_isif_cgbgain, NULL);
-	v4l2_ctrl_new_custom(&isif->ctrls, &vpfe_isif_cbgain, NULL);
-	v4l2_ctrl_new_custom(&isif->ctrls, &vpfe_isif_gain_offset, NULL);
-	v4l2_ctrl_new_custom(&isif->ctrls, &vpfe_isif_dpcm_pred, NULL);
-
-	v4l2_ctrl_handler_setup(&isif->ctrls);
-	sd->ctrl_handler = &isif->ctrls;
-	isif_config_defaults(isif);
-	return 0;
-fail_base_iomap:
-	release_mem_region(res->start, res_len);
-	i--;
-fail_nobase_res:
-	if (isif->isif_cfg.base_addr)
-		iounmap(isif->isif_cfg.base_addr);
-	if (isif->isif_cfg.linear_tbl0_addr)
-		iounmap(isif->isif_cfg.linear_tbl0_addr);
-
-	while (i >= 0) {
-		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
-		release_mem_region(res->start, res_len);
-		i--;
-	}
-	return status;
-isif_fail:
-	v4l2_ctrl_handler_free(&isif->ctrls);
-	isif_remove(isif, pdev);
-	return status;
-}
-
-/*
- * vpfe_isif_cleanup - isif module cleanup
- * @isif: pointer to isif subdevice
- * @dev: pointer to platform device structure
- */
-void
-vpfe_isif_cleanup(struct vpfe_isif_device *isif, struct platform_device *pdev)
-{
-	isif_remove(isif, pdev);
-}
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.h b/drivers/staging/media/davinci_vpfe/dm365_isif.h
deleted file mode 100644
index 0e1fe47..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _DAVINCI_VPFE_DM365_ISIF_H
-#define _DAVINCI_VPFE_DM365_ISIF_H
-
-#include <linux/platform_device.h>
-
-#include <mach/mux.h>
-
-#include <media/davinci/vpfe_types.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-
-#include "davinci_vpfe_user.h"
-#include "dm365_isif_regs.h"
-#include "vpfe_video.h"
-
-#define ISIF_CULLING_HCAPT_ODD		0xff
-#define ISIF_CULLING_HCAPT_EVEN		0xff
-#define ISIF_CULLING_VCAPT		0xff
-
-#define ISIF_CADU_BITS			0x07ff
-#define ISIF_CADL_BITS			0x0ffff
-
-enum isif_pixfmt {
-	ISIF_PIXFMT_RAW = 0,
-	ISIF_PIXFMT_YCBCR_16BIT = 1,
-	ISIF_PIXFMT_YCBCR_8BIT = 2,
-};
-
-enum isif_frmfmt {
-	ISIF_FRMFMT_PROGRESSIVE = 0,
-	ISIF_FRMFMT_INTERLACED = 1,
-};
-
-/* PIXEL ORDER IN MEMORY from LSB to MSB */
-/* only applicable for 8-bit input mode  */
-enum isif_pixorder {
-	ISIF_PIXORDER_YCBYCR = 0,
-	ISIF_PIXORDER_CBYCRY = 1,
-};
-
-enum isif_buftype {
-	ISIF_BUFTYPE_FLD_INTERLEAVED = 0,
-	ISIF_BUFTYPE_FLD_SEPARATED = 1,
-};
-
-struct isif_ycbcr_config {
-	/* v4l2 pixel format */
-	unsigned long v4l2_pix_fmt;
-	/* isif pixel format */
-	enum isif_pixfmt pix_fmt;
-	/* isif frame format */
-	enum isif_frmfmt frm_fmt;
-	/* isif crop window */
-	struct v4l2_rect win;
-	/* field polarity */
-	enum vpfe_pin_pol fid_pol;
-	/* interface VD polarity */
-	enum vpfe_pin_pol vd_pol;
-	/* interface HD polarity */
-	enum vpfe_pin_pol hd_pol;
-	/* isif pix order. Only used for ycbcr capture */
-	enum isif_pixorder pix_order;
-	/* isif buffer type. Only used for ycbcr capture */
-	enum isif_buftype buf_type;
-};
-
-enum isif_cfa_pattern {
-	ISIF_CFA_PAT_MOSAIC = 0,
-	ISIF_CFA_PAT_STRIPE = 1,
-};
-
-enum isif_data_msb {
-	/* MSB b15 */
-	ISIF_BIT_MSB_15 = 0,
-	/* MSB b14 */
-	ISIF_BIT_MSB_14 = 1,
-	/* MSB b13 */
-	ISIF_BIT_MSB_13 = 2,
-	/* MSB b12 */
-	ISIF_BIT_MSB_12 = 3,
-	/* MSB b11 */
-	ISIF_BIT_MSB_11 = 4,
-	/* MSB b10 */
-	ISIF_BIT_MSB_10 = 5,
-	/* MSB b9 */
-	ISIF_BIT_MSB_9 = 6,
-	/* MSB b8 */
-	ISIF_BIT_MSB_8 = 7,
-	/* MSB b7 */
-	ISIF_BIT_MSB_7 = 8,
-};
-
-struct isif_params_raw {
-	/* v4l2 pixel format */
-	unsigned long v4l2_pix_fmt;
-	/* isif pixel format */
-	enum isif_pixfmt pix_fmt;
-	/* isif frame format */
-	enum isif_frmfmt frm_fmt;
-	/* video window */
-	struct v4l2_rect win;
-	/* field polarity */
-	enum vpfe_pin_pol fid_pol;
-	/* interface VD polarity */
-	enum vpfe_pin_pol vd_pol;
-	/* interface HD polarity */
-	enum vpfe_pin_pol hd_pol;
-	/* buffer type. Applicable for interlaced mode */
-	enum isif_buftype buf_type;
-	/* cfa pattern */
-	enum isif_cfa_pattern cfa_pat;
-	/* Data MSB position */
-	enum isif_data_msb data_msb;
-	/* Enable horizontal flip */
-	unsigned char horz_flip_en;
-	/* Enable image invert vertically */
-	unsigned char image_invert_en;
-	unsigned char dpcm_predictor;
-	struct vpfe_isif_raw_config config_params;
-};
-
-enum isif_data_pack {
-	ISIF_PACK_16BIT = 0,
-	ISIF_PACK_12BIT = 1,
-	ISIF_PACK_8BIT = 2,
-};
-
-struct isif_gain_values {
-	unsigned int cr_gain;
-	unsigned int cgr_gain;
-	unsigned int cgb_gain;
-	unsigned int cb_gain;
-	unsigned int offset;
-};
-
-struct isif_oper_config {
-	struct isif_ycbcr_config ycbcr;
-	struct isif_params_raw bayer;
-	enum isif_data_pack data_pack;
-	struct isif_gain_values isif_gain_params;
-	void __iomem *base_addr;
-	void __iomem *linear_tbl0_addr;
-	void __iomem *linear_tbl1_addr;
-};
-
-#define ISIF_PAD_SINK      0
-#define ISIF_PAD_SOURCE    1
-
-#define ISIF_PADS_NUM      2
-
-enum isif_input_entity {
-	ISIF_INPUT_NONE = 0,
-	ISIF_INPUT_PARALLEL = 1,
-};
-
-#define ISIF_OUTPUT_NONE	(0)
-#define ISIF_OUTPUT_MEMORY	(1 << 0)
-#define ISIF_OUTPUT_IPIPEIF	(1 << 1)
-
-struct vpfe_isif_device {
-	struct v4l2_subdev		subdev;
-	struct media_pad		pads[ISIF_PADS_NUM];
-	struct v4l2_mbus_framefmt	formats[ISIF_PADS_NUM];
-	enum isif_input_entity		input;
-	unsigned int			output;
-	struct v4l2_ctrl_handler        ctrls;
-	struct v4l2_rect		crop;
-	struct isif_oper_config		isif_cfg;
-	struct vpfe_video_device	video_out;
-};
-
-enum v4l2_field vpfe_isif_get_fid(struct vpfe_device *vpfe_dev);
-void vpfe_isif_unregister_entities(struct vpfe_isif_device *isif);
-int vpfe_isif_register_entities(struct vpfe_isif_device *isif,
-				struct v4l2_device *dev);
-int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev);
-void vpfe_isif_cleanup(struct vpfe_isif_device *vpfe_isif,
-		       struct platform_device *pdev);
-void vpfe_isif_vidint1_isr(struct vpfe_isif_device *isif);
-void vpfe_isif_buffer_isr(struct vpfe_isif_device *isif);
-
-#endif		/* _DAVINCI_VPFE_DM365_ISIF_H */
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif_regs.h b/drivers/staging/media/davinci_vpfe/dm365_isif_regs.h
deleted file mode 100644
index 6695680..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_isif_regs.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _DAVINCI_VPFE_DM365_ISIF_REGS_H
-#define _DAVINCI_VPFE_DM365_ISIF_REGS_H
-
-/* ISIF registers relative offsets */
-#define SYNCEN					0x00
-#define MODESET					0x04
-#define HDW					0x08
-#define VDW					0x0c
-#define PPLN					0x10
-#define LPFR					0x14
-#define SPH					0x18
-#define LNH					0x1c
-#define SLV0					0x20
-#define SLV1					0x24
-#define LNV					0x28
-#define CULH					0x2c
-#define CULV					0x30
-#define HSIZE					0x34
-#define SDOFST					0x38
-#define CADU					0x3c
-#define CADL					0x40
-#define LINCFG0					0x44
-#define LINCFG1					0x48
-#define CCOLP					0x4c
-#define CRGAIN					0x50
-#define CGRGAIN					0x54
-#define CGBGAIN					0x58
-#define CBGAIN					0x5c
-#define COFSTA					0x60
-#define FLSHCFG0				0x64
-#define FLSHCFG1				0x68
-#define FLSHCFG2				0x6c
-#define VDINT0					0x70
-#define VDINT1					0x74
-#define VDINT2					0x78
-#define MISC					0x7c
-#define CGAMMAWD				0x80
-#define REC656IF				0x84
-#define CCDCFG					0x88
-/*****************************************************
- * Defect Correction registers
- *****************************************************/
-#define DFCCTL					0x8c
-#define VDFSATLV				0x90
-#define DFCMEMCTL				0x94
-#define DFCMEM0					0x98
-#define DFCMEM1					0x9c
-#define DFCMEM2					0xa0
-#define DFCMEM3					0xa4
-#define DFCMEM4					0xa8
-/****************************************************
- * Black Clamp registers
- ****************************************************/
-#define CLAMPCFG				0xac
-#define CLDCOFST				0xb0
-#define CLSV					0xb4
-#define CLHWIN0					0xb8
-#define CLHWIN1					0xbc
-#define CLHWIN2					0xc0
-#define CLVRV					0xc4
-#define CLVWIN0					0xc8
-#define CLVWIN1					0xcc
-#define CLVWIN2					0xd0
-#define CLVWIN3					0xd4
-/****************************************************
- * Lense Shading Correction
- ****************************************************/
-#define DATAHOFST				0xd8
-#define DATAVOFST				0xdc
-#define LSCHVAL					0xe0
-#define LSCVVAL					0xe4
-#define TWODLSCCFG				0xe8
-#define TWODLSCOFST				0xec
-#define TWODLSCINI				0xf0
-#define TWODLSCGRBU				0xf4
-#define TWODLSCGRBL				0xf8
-#define TWODLSCGROF				0xfc
-#define TWODLSCORBU				0x100
-#define TWODLSCORBL				0x104
-#define TWODLSCOROF				0x108
-#define TWODLSCIRQEN				0x10c
-#define TWODLSCIRQST				0x110
-/****************************************************
- * Data formatter
- ****************************************************/
-#define FMTCFG					0x114
-#define FMTPLEN					0x118
-#define FMTSPH					0x11c
-#define FMTLNH					0x120
-#define FMTSLV					0x124
-#define FMTLNV					0x128
-#define FMTRLEN					0x12c
-#define FMTHCNT					0x130
-#define FMTAPTR_BASE				0x134
-/* Below macro for addresses FMTAPTR0 - FMTAPTR15 */
-#define FMTAPTR(i)			(FMTAPTR_BASE + (i * 4))
-#define FMTPGMVF0				0x174
-#define FMTPGMVF1				0x178
-#define FMTPGMAPU0				0x17c
-#define FMTPGMAPU1				0x180
-#define FMTPGMAPS0				0x184
-#define FMTPGMAPS1				0x188
-#define FMTPGMAPS2				0x18c
-#define FMTPGMAPS3				0x190
-#define FMTPGMAPS4				0x194
-#define FMTPGMAPS5				0x198
-#define FMTPGMAPS6				0x19c
-#define FMTPGMAPS7				0x1a0
-/************************************************
- * Color Space Converter
- ************************************************/
-#define CSCCTL					0x1a4
-#define CSCM0					0x1a8
-#define CSCM1					0x1ac
-#define CSCM2					0x1b0
-#define CSCM3					0x1b4
-#define CSCM4					0x1b8
-#define CSCM5					0x1bc
-#define CSCM6					0x1c0
-#define CSCM7					0x1c4
-#define OBWIN0					0x1c8
-#define OBWIN1					0x1cc
-#define OBWIN2					0x1d0
-#define OBWIN3					0x1d4
-#define OBVAL0					0x1d8
-#define OBVAL1					0x1dc
-#define OBVAL2					0x1e0
-#define OBVAL3					0x1e4
-#define OBVAL4					0x1e8
-#define OBVAL5					0x1ec
-#define OBVAL6					0x1f0
-#define OBVAL7					0x1f4
-#define CLKCTL					0x1f8
-
-/* Masks & Shifts below */
-#define START_PX_HOR_MASK			0x7fff
-#define NUM_PX_HOR_MASK				0x7fff
-#define START_VER_ONE_MASK			0x7fff
-#define START_VER_TWO_MASK			0x7fff
-#define NUM_LINES_VER				0x7fff
-
-/* gain - offset masks */
-#define OFFSET_MASK				0xfff
-#define GAIN_SDRAM_EN_SHIFT			12
-#define GAIN_IPIPE_EN_SHIFT			13
-#define GAIN_H3A_EN_SHIFT			14
-#define OFST_SDRAM_EN_SHIFT			8
-#define OFST_IPIPE_EN_SHIFT			9
-#define OFST_H3A_EN_SHIFT			10
-#define GAIN_OFFSET_EN_MASK			0x7700
-
-/* Culling */
-#define CULL_PAT_EVEN_LINE_SHIFT		8
-
-/* CCDCFG register */
-#define ISIF_YCINSWP_RAW			(0x00 << 4)
-#define ISIF_YCINSWP_YCBCR			(0x01 << 4)
-#define ISIF_CCDCFG_FIDMD_LATCH_VSYNC		(0x00 << 6)
-#define ISIF_CCDCFG_WENLOG_AND			(0x00 << 8)
-#define ISIF_CCDCFG_TRGSEL_WEN			(0x00 << 9)
-#define ISIF_CCDCFG_EXTRG_DISABLE		(0x00 << 10)
-#define ISIF_LATCH_ON_VSYNC_DISABLE		(0x01 << 15)
-#define ISIF_LATCH_ON_VSYNC_ENABLE		(0x00 << 15)
-#define ISIF_DATA_PACK_MASK			0x03
-#define ISIF_PIX_ORDER_SHIFT			11
-#define ISIF_PIX_ORDER_MASK			0x01
-#define ISIF_BW656_ENABLE			(0x01 << 5)
-
-/* MODESET registers */
-#define ISIF_VDHDOUT_INPUT			(0x00 << 0)
-#define ISIF_INPUT_MASK				0x03
-#define ISIF_INPUT_SHIFT			12
-#define ISIF_FID_POL_MASK			0x01
-#define ISIF_FID_POL_SHIFT			4
-#define ISIF_HD_POL_MASK			0x01
-#define ISIF_HD_POL_SHIFT			3
-#define ISIF_VD_POL_MASK			0x01
-#define ISIF_VD_POL_SHIFT			2
-#define ISIF_DATAPOL_NORMAL			0x00
-#define ISIF_DATAPOL_MASK			0x01
-#define ISIF_DATAPOL_SHIFT			6
-#define ISIF_EXWEN_DISABLE			0x00
-#define ISIF_EXWEN_MASK				0x01
-#define ISIF_EXWEN_SHIFT			5
-#define ISIF_FRM_FMT_MASK			0x01
-#define ISIF_FRM_FMT_SHIFT			7
-#define ISIF_DATASFT_MASK			0x07
-#define ISIF_DATASFT_SHIFT			8
-#define ISIF_LPF_SHIFT				14
-#define ISIF_LPF_MASK				0x1
-
-/* GAMMAWD registers */
-#define ISIF_ALAW_GAMA_WD_MASK			0xf
-#define ISIF_ALAW_GAMA_WD_SHIFT			1
-#define ISIF_ALAW_ENABLE			0x01
-#define ISIF_GAMMAWD_CFA_MASK			0x01
-#define ISIF_GAMMAWD_CFA_SHIFT			5
-
-/* HSIZE registers */
-#define ISIF_HSIZE_FLIP_MASK			0x01
-#define ISIF_HSIZE_FLIP_SHIFT			12
-#define ISIF_LINEOFST_MASK			0xfff
-
-/* MISC registers */
-#define ISIF_DPCM_EN_SHIFT			12
-#define ISIF_DPCM_PREDICTOR_SHIFT		13
-#define ISIF_DPCM_PREDICTOR_MASK		1
-
-/* Black clamp related */
-#define ISIF_BC_DCOFFSET_MASK			0x1fff
-#define ISIF_BC_MODE_COLOR_MASK			1
-#define ISIF_BC_MODE_COLOR_SHIFT		4
-#define ISIF_HORZ_BC_MODE_MASK			3
-#define ISIF_HORZ_BC_MODE_SHIFT			1
-#define ISIF_HORZ_BC_WIN_COUNT_MASK		0x1f
-#define ISIF_HORZ_BC_WIN_SEL_SHIFT		5
-#define ISIF_HORZ_BC_PIX_LIMIT_SHIFT		6
-#define ISIF_HORZ_BC_WIN_H_SIZE_MASK		3
-#define ISIF_HORZ_BC_WIN_H_SIZE_SHIFT		8
-#define ISIF_HORZ_BC_WIN_V_SIZE_MASK		3
-#define ISIF_HORZ_BC_WIN_V_SIZE_SHIFT		12
-#define ISIF_HORZ_BC_WIN_START_H_MASK		0x1fff
-#define ISIF_HORZ_BC_WIN_START_V_MASK		0x1fff
-#define ISIF_VERT_BC_OB_H_SZ_MASK		7
-#define ISIF_VERT_BC_RST_VAL_SEL_MASK		3
-#define ISIF_VERT_BC_RST_VAL_SEL_SHIFT		4
-#define ISIF_VERT_BC_LINE_AVE_COEF_SHIFT	8
-#define ISIF_VERT_BC_OB_START_HORZ_MASK		0x1fff
-#define ISIF_VERT_BC_OB_START_VERT_MASK		0x1fff
-#define ISIF_VERT_BC_OB_VERT_SZ_MASK		0x1fff
-#define ISIF_VERT_BC_RST_VAL_MASK		0xfff
-#define ISIF_BC_VERT_START_SUB_V_MASK		0x1fff
-
-/* VDFC registers */
-#define ISIF_VDFC_EN_SHIFT			4
-#define ISIF_VDFC_CORR_MOD_MASK			3
-#define ISIF_VDFC_CORR_MOD_SHIFT		5
-#define ISIF_VDFC_CORR_WHOLE_LN_SHIFT		7
-#define ISIF_VDFC_LEVEL_SHFT_MASK		7
-#define ISIF_VDFC_LEVEL_SHFT_SHIFT		8
-#define ISIF_VDFC_SAT_LEVEL_MASK		0xfff
-#define ISIF_VDFC_POS_MASK			0x1fff
-#define ISIF_DFCMEMCTL_DFCMARST_SHIFT		2
-
-/* CSC registers */
-#define ISIF_CSC_COEF_INTEG_MASK		7
-#define ISIF_CSC_COEF_DECIMAL_MASK		0x1f
-#define ISIF_CSC_COEF_INTEG_SHIFT		5
-#define ISIF_CSCM_MSB_SHIFT			8
-#define ISIF_DF_CSC_SPH_MASK			0x1fff
-#define ISIF_DF_CSC_LNH_MASK			0x1fff
-#define ISIF_DF_CSC_SLV_MASK			0x1fff
-#define ISIF_DF_CSC_LNV_MASK			0x1fff
-#define ISIF_DF_NUMLINES			0x7fff
-#define ISIF_DF_NUMPIX				0x1fff
-
-/* Offsets for LSC/DFC/Gain */
-#define ISIF_DATA_H_OFFSET_MASK			0x1fff
-#define ISIF_DATA_V_OFFSET_MASK			0x1fff
-
-/* Linearization */
-#define ISIF_LIN_CORRSFT_MASK			7
-#define ISIF_LIN_CORRSFT_SHIFT			4
-#define ISIF_LIN_SCALE_FACT_INTEG_SHIFT		10
-#define ISIF_LIN_SCALE_FACT_DECIMAL_MASK	0x3ff
-#define ISIF_LIN_ENTRY_MASK			0x3ff
-
-/* masks and shifts*/
-#define ISIF_SYNCEN_VDHDEN_MASK			(1 << 0)
-#define ISIF_SYNCEN_WEN_MASK			(1 << 1)
-#define ISIF_SYNCEN_WEN_SHIFT			1
-
-#endif		/* _DAVINCI_VPFE_DM365_ISIF_REGS_H */
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
deleted file mode 100644
index 7adf1fa..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ /dev/null
@@ -1,1995 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- *
- *
- * Resizer allows upscaling or downscaling a image to a desired
- * resolution. There are 2 resizer modules. both operating on the
- * same input image, but can have different output resolution.
- */
-
-#include "dm365_ipipe_hw.h"
-#include "dm365_resizer.h"
-
-#define MIN_IN_WIDTH		32
-#define MIN_IN_HEIGHT		32
-#define MAX_IN_WIDTH		4095
-#define MAX_IN_HEIGHT		4095
-#define MIN_OUT_WIDTH		16
-#define MIN_OUT_HEIGHT		2
-
-static const unsigned int resizer_input_formats[] = {
-	MEDIA_BUS_FMT_UYVY8_2X8,
-	MEDIA_BUS_FMT_Y8_1X8,
-	MEDIA_BUS_FMT_UV8_1X8,
-	MEDIA_BUS_FMT_SGRBG12_1X12,
-};
-
-static const unsigned int resizer_output_formats[] = {
-	MEDIA_BUS_FMT_UYVY8_2X8,
-	MEDIA_BUS_FMT_Y8_1X8,
-	MEDIA_BUS_FMT_UV8_1X8,
-	MEDIA_BUS_FMT_YDYUYDYV8_1X16,
-	MEDIA_BUS_FMT_SGRBG12_1X12,
-};
-
-/* resizer_calculate_line_length() - This function calculates the line length of
- *				     various image planes at the input and
- *				     output.
- */
-static void
-resizer_calculate_line_length(u32 pix, int width, int height,
-			      int *line_len, int *line_len_c)
-{
-	*line_len = 0;
-	*line_len_c = 0;
-
-	if (pix == MEDIA_BUS_FMT_UYVY8_2X8 ||
-	    pix == MEDIA_BUS_FMT_SGRBG12_1X12) {
-		*line_len = width << 1;
-	} else {
-		*line_len = width;
-		*line_len_c = width;
-	}
-
-	/* adjust the line len to be a multiple of 32 */
-	*line_len += 31;
-	*line_len &= ~0x1f;
-	*line_len_c += 31;
-	*line_len_c &= ~0x1f;
-}
-
-static inline int
-resizer_validate_output_image_format(struct device *dev,
-				     struct v4l2_mbus_framefmt *format,
-				     int *in_line_len, int *in_line_len_c)
-{
-	if (format->code != MEDIA_BUS_FMT_UYVY8_2X8 &&
-	    format->code != MEDIA_BUS_FMT_Y8_1X8 &&
-	    format->code != MEDIA_BUS_FMT_UV8_1X8 &&
-	    format->code != MEDIA_BUS_FMT_YDYUYDYV8_1X16 &&
-	    format->code != MEDIA_BUS_FMT_SGRBG12_1X12) {
-		dev_err(dev, "Invalid Mbus format, %d\n", format->code);
-		return -EINVAL;
-	}
-	if (!format->width || !format->height) {
-		dev_err(dev, "invalid width or height\n");
-		return -EINVAL;
-	}
-	resizer_calculate_line_length(format->code, format->width,
-		format->height, in_line_len, in_line_len_c);
-	return 0;
-}
-
-static void
-resizer_configure_passthru(struct vpfe_resizer_device *resizer, int bypass)
-{
-	struct resizer_params *param = &resizer->config;
-
-	param->rsz_rsc_param[RSZ_A].cen = DISABLE;
-	param->rsz_rsc_param[RSZ_A].yen = DISABLE;
-	param->rsz_rsc_param[RSZ_A].v_phs_y = 0;
-	param->rsz_rsc_param[RSZ_A].v_phs_c = 0;
-	param->rsz_rsc_param[RSZ_A].v_dif = 256;
-	param->rsz_rsc_param[RSZ_A].v_lpf_int_y = 0;
-	param->rsz_rsc_param[RSZ_A].v_lpf_int_c = 0;
-	param->rsz_rsc_param[RSZ_A].h_phs = 0;
-	param->rsz_rsc_param[RSZ_A].h_dif = 256;
-	param->rsz_rsc_param[RSZ_A].h_lpf_int_y = 0;
-	param->rsz_rsc_param[RSZ_A].h_lpf_int_c = 0;
-	param->rsz_rsc_param[RSZ_A].dscale_en = DISABLE;
-	param->rsz2rgb[RSZ_A].rgb_en = DISABLE;
-	param->rsz_en[RSZ_A] = ENABLE;
-	param->rsz_en[RSZ_B] = DISABLE;
-	if (bypass) {
-		param->rsz_rsc_param[RSZ_A].i_vps = 0;
-		param->rsz_rsc_param[RSZ_A].i_hps = 0;
-		/* Raw Bypass */
-		param->rsz_common.passthrough = BYPASS_ON;
-	}
-}
-
-static void
-configure_resizer_out_params(struct vpfe_resizer_device *resizer, int index,
-			     void *output_spec, unsigned char partial,
-			     unsigned int flag)
-{
-	struct resizer_params *param = &resizer->config;
-	struct v4l2_mbus_framefmt *outformat;
-	struct vpfe_rsz_output_spec *output;
-
-	if (index == RSZ_A &&
-	    resizer->resizer_a.output == RESIZER_OUTPUT_NONE) {
-		param->rsz_en[index] = DISABLE;
-		return;
-	}
-	if (index == RSZ_B &&
-	    resizer->resizer_b.output == RESIZER_OUTPUT_NONE) {
-		param->rsz_en[index] = DISABLE;
-		return;
-	}
-	output = output_spec;
-	param->rsz_en[index] = ENABLE;
-	if (partial) {
-		param->rsz_rsc_param[index].h_flip = output->h_flip;
-		param->rsz_rsc_param[index].v_flip = output->v_flip;
-		param->rsz_rsc_param[index].v_typ_y = output->v_typ_y;
-		param->rsz_rsc_param[index].v_typ_c = output->v_typ_c;
-		param->rsz_rsc_param[index].v_lpf_int_y =
-						output->v_lpf_int_y;
-		param->rsz_rsc_param[index].v_lpf_int_c =
-						output->v_lpf_int_c;
-		param->rsz_rsc_param[index].h_typ_y = output->h_typ_y;
-		param->rsz_rsc_param[index].h_typ_c = output->h_typ_c;
-		param->rsz_rsc_param[index].h_lpf_int_y =
-						output->h_lpf_int_y;
-		param->rsz_rsc_param[index].h_lpf_int_c =
-						output->h_lpf_int_c;
-		param->rsz_rsc_param[index].dscale_en =
-						output->en_down_scale;
-		param->rsz_rsc_param[index].h_dscale_ave_sz =
-						output->h_dscale_ave_sz;
-		param->rsz_rsc_param[index].v_dscale_ave_sz =
-						output->v_dscale_ave_sz;
-		param->ext_mem_param[index].user_y_ofst =
-				    (output->user_y_ofst + 31) & ~0x1f;
-		param->ext_mem_param[index].user_c_ofst =
-				    (output->user_c_ofst + 31) & ~0x1f;
-		return;
-	}
-
-	if (index == RSZ_A)
-		outformat = &resizer->resizer_a.formats[RESIZER_PAD_SOURCE];
-	else
-		outformat = &resizer->resizer_b.formats[RESIZER_PAD_SOURCE];
-	param->rsz_rsc_param[index].o_vsz = outformat->height - 1;
-	param->rsz_rsc_param[index].o_hsz = outformat->width - 1;
-	param->ext_mem_param[index].rsz_sdr_ptr_s_y = output->vst_y;
-	param->ext_mem_param[index].rsz_sdr_ptr_e_y = outformat->height;
-	param->ext_mem_param[index].rsz_sdr_ptr_s_c = output->vst_c;
-	param->ext_mem_param[index].rsz_sdr_ptr_e_c = outformat->height;
-
-	if (!flag)
-		return;
-	/* update common parameters */
-	param->rsz_rsc_param[index].h_flip = output->h_flip;
-	param->rsz_rsc_param[index].v_flip = output->v_flip;
-	param->rsz_rsc_param[index].v_typ_y = output->v_typ_y;
-	param->rsz_rsc_param[index].v_typ_c = output->v_typ_c;
-	param->rsz_rsc_param[index].v_lpf_int_y = output->v_lpf_int_y;
-	param->rsz_rsc_param[index].v_lpf_int_c = output->v_lpf_int_c;
-	param->rsz_rsc_param[index].h_typ_y = output->h_typ_y;
-	param->rsz_rsc_param[index].h_typ_c = output->h_typ_c;
-	param->rsz_rsc_param[index].h_lpf_int_y = output->h_lpf_int_y;
-	param->rsz_rsc_param[index].h_lpf_int_c = output->h_lpf_int_c;
-	param->rsz_rsc_param[index].dscale_en = output->en_down_scale;
-	param->rsz_rsc_param[index].h_dscale_ave_sz = output->h_dscale_ave_sz;
-	param->rsz_rsc_param[index].v_dscale_ave_sz = output->h_dscale_ave_sz;
-	param->ext_mem_param[index].user_y_ofst =
-					(output->user_y_ofst + 31) & ~0x1f;
-	param->ext_mem_param[index].user_c_ofst =
-					(output->user_c_ofst + 31) & ~0x1f;
-}
-
-/*
- * resizer_calculate_resize_ratios() - Calculates resize ratio for resizer
- *				      A or B. This is called after setting
- *				     the input size or output size.
- * @resizer: Pointer to VPFE resizer subdevice.
- * @index: index RSZ_A-resizer-A RSZ_B-resizer-B.
- */
-static void
-resizer_calculate_resize_ratios(struct vpfe_resizer_device *resizer, int index)
-{
-	struct resizer_params *param = &resizer->config;
-	struct v4l2_mbus_framefmt *informat, *outformat;
-
-	informat = &resizer->crop_resizer.formats[RESIZER_CROP_PAD_SINK];
-
-	if (index == RSZ_A)
-		outformat = &resizer->resizer_a.formats[RESIZER_PAD_SOURCE];
-	else
-		outformat = &resizer->resizer_b.formats[RESIZER_PAD_SOURCE];
-
-	if (outformat->field != V4L2_FIELD_INTERLACED)
-		param->rsz_rsc_param[index].v_dif =
-			((informat->height) * 256) / (outformat->height);
-	else
-		param->rsz_rsc_param[index].v_dif =
-			((informat->height >> 1) * 256) / (outformat->height);
-	param->rsz_rsc_param[index].h_dif =
-			((informat->width) * 256) / (outformat->width);
-}
-
-static void resizer_enable_422_420_conversion(struct resizer_params *param,
-					      int index, bool en)
-{
-	param->rsz_rsc_param[index].cen = en;
-	param->rsz_rsc_param[index].yen = en;
-}
-
-/* resizer_calculate_sdram_offsets() - This function calculates the offsets from
- *				       start of buffer for the C plane when
- *				       output format is YUV420SP. It also
- *				       calculates the offsets from the start of
- *				       the buffer when the image is flipped
- *				       vertically or horizontally for ycbcr/y/c
- *				       planes.
- * @resizer: Pointer to resizer subdevice.
- * @index: index RSZ_A-resizer-A RSZ_B-resizer-B.
- */
-static int
-resizer_calculate_sdram_offsets(struct vpfe_resizer_device *resizer, int index)
-{
-	struct resizer_params *param = &resizer->config;
-	struct v4l2_mbus_framefmt *outformat;
-	int bytesperpixel = 2;
-	int image_height;
-	int image_width;
-	int yuv_420 = 0;
-	int offset = 0;
-
-	if (index == RSZ_A)
-		outformat = &resizer->resizer_a.formats[RESIZER_PAD_SOURCE];
-	else
-		outformat = &resizer->resizer_b.formats[RESIZER_PAD_SOURCE];
-
-	image_height = outformat->height + 1;
-	image_width = outformat->width + 1;
-	param->ext_mem_param[index].c_offset = 0;
-	param->ext_mem_param[index].flip_ofst_y = 0;
-	param->ext_mem_param[index].flip_ofst_c = 0;
-	if (outformat->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16) {
-		/* YUV 420 */
-		yuv_420 = 1;
-		bytesperpixel = 1;
-	}
-
-	if (param->rsz_rsc_param[index].h_flip)
-		/* width * bytesperpixel - 1 */
-		offset = (image_width * bytesperpixel) - 1;
-	if (param->rsz_rsc_param[index].v_flip)
-		offset += (image_height - 1) *
-			param->ext_mem_param[index].rsz_sdr_oft_y;
-	param->ext_mem_param[index].flip_ofst_y = offset;
-	if (!yuv_420)
-		return 0;
-	offset = 0;
-	/* half height for c-plane */
-	if (param->rsz_rsc_param[index].h_flip)
-		/* width * bytesperpixel - 1 */
-		offset = image_width - 1;
-	if (param->rsz_rsc_param[index].v_flip)
-		offset += (((image_height >> 1) - 1) *
-			   param->ext_mem_param[index].rsz_sdr_oft_c);
-	param->ext_mem_param[index].flip_ofst_c = offset;
-	param->ext_mem_param[index].c_offset =
-		      param->ext_mem_param[index].rsz_sdr_oft_y * image_height;
-	return 0;
-}
-
-static int resizer_configure_output_win(struct vpfe_resizer_device *resizer)
-{
-	struct resizer_params *param = &resizer->config;
-	struct vpfe_rsz_output_spec output_specs;
-	struct v4l2_mbus_framefmt *outformat;
-	int line_len_c;
-	int line_len;
-	int ret;
-
-	outformat = &resizer->resizer_a.formats[RESIZER_PAD_SOURCE];
-
-	memset(&output_specs, 0x0, sizeof(struct vpfe_rsz_output_spec));
-	output_specs.vst_y = param->user_config.vst;
-	if (outformat->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16)
-		output_specs.vst_c = param->user_config.vst;
-
-	configure_resizer_out_params(resizer, RSZ_A, &output_specs, 0, 0);
-	resizer_calculate_line_length(outformat->code,
-				      param->rsz_rsc_param[0].o_hsz + 1,
-				      param->rsz_rsc_param[0].o_vsz + 1,
-				      &line_len, &line_len_c);
-	param->ext_mem_param[0].rsz_sdr_oft_y = line_len;
-	param->ext_mem_param[0].rsz_sdr_oft_c = line_len_c;
-	resizer_calculate_resize_ratios(resizer, RSZ_A);
-	if (param->rsz_en[RSZ_B])
-		resizer_calculate_resize_ratios(resizer, RSZ_B);
-
-	if (outformat->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16)
-		resizer_enable_422_420_conversion(param, RSZ_A, ENABLE);
-	else
-		resizer_enable_422_420_conversion(param, RSZ_A, DISABLE);
-
-	ret = resizer_calculate_sdram_offsets(resizer, RSZ_A);
-	if (!ret && param->rsz_en[RSZ_B])
-		ret = resizer_calculate_sdram_offsets(resizer, RSZ_B);
-
-	if (ret)
-		pr_err("Error in calculating sdram offsets\n");
-	return ret;
-}
-
-static int
-resizer_calculate_down_scale_f_div_param(struct device *dev,
-					 int input_width, int output_width,
-					 struct resizer_scale_param *param)
-{
-	/* rsz = R, input_width = H, output width = h in the equation */
-	unsigned int two_power;
-	unsigned int upper_h1;
-	unsigned int upper_h2;
-	unsigned int val1;
-	unsigned int val;
-	unsigned int rsz;
-	unsigned int h1;
-	unsigned int h2;
-	unsigned int o;
-	unsigned int n;
-
-	upper_h1 = input_width >> 1;
-	n = param->h_dscale_ave_sz;
-	/* 2 ^ (scale+1) */
-	two_power = 1 << (n + 1);
-	upper_h1 = (upper_h1 >> (n + 1)) << (n + 1);
-	upper_h2 = input_width - upper_h1;
-	if (upper_h2 % two_power) {
-		dev_err(dev, "frame halves to be a multiple of 2 power n+1\n");
-		return -EINVAL;
-	}
-	two_power = 1 << n;
-	rsz = (input_width << 8) / output_width;
-	val = rsz * two_power;
-	val = ((upper_h1 << 8) / val) + 1;
-	if (!(val % 2)) {
-		h1 = val;
-	} else {
-		val = upper_h1 << 8;
-		val >>= n + 1;
-		val -= rsz >> 1;
-		val /= rsz << 1;
-		val <<= 1;
-		val += 2;
-		h1 = val;
-	}
-	o = 10 + (two_power << 2);
-	if (((input_width << 7) / rsz) % 2)
-		o += ((DIV_ROUND_UP(rsz, 1024) << 1) << n);
-	h2 = output_width - h1;
-	/* phi */
-	val = (h1 * rsz) - (((upper_h1 - (o - 10)) / two_power) << 8);
-	/* skip */
-	val1 = ((val - 1024) >> 9) << 1;
-	param->f_div.num_passes = MAX_PASSES;
-	param->f_div.pass[0].o_hsz = h1 - 1;
-	param->f_div.pass[0].i_hps = 0;
-	param->f_div.pass[0].h_phs = 0;
-	param->f_div.pass[0].src_hps = 0;
-	param->f_div.pass[0].src_hsz = upper_h1 + o;
-	param->f_div.pass[1].o_hsz = h2 - 1;
-	param->f_div.pass[1].i_hps = 10 + (val1 * two_power);
-	param->f_div.pass[1].h_phs = val - (val1 << 8);
-	param->f_div.pass[1].src_hps = upper_h1 - o;
-	param->f_div.pass[1].src_hsz = upper_h2 + o;
-
-	return 0;
-}
-
-static int
-resizer_configure_common_in_params(struct vpfe_resizer_device *resizer)
-{
-	struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
-	struct resizer_params *param = &resizer->config;
-	struct vpfe_rsz_config_params *user_config;
-	struct v4l2_mbus_framefmt *informat;
-
-	informat = &resizer->crop_resizer.formats[RESIZER_CROP_PAD_SINK];
-	user_config = &resizer->config.user_config;
-	param->rsz_common.vps = param->user_config.vst;
-	param->rsz_common.hps = param->user_config.hst;
-
-	if (vpfe_ipipeif_decimation_enabled(vpfe_dev))
-		param->rsz_common.hsz = ((informat->width - 1) *
-			IPIPEIF_RSZ_CONST) / vpfe_ipipeif_get_rsz(vpfe_dev);
-	else
-		param->rsz_common.hsz = informat->width - 1;
-
-	if (informat->field == V4L2_FIELD_INTERLACED)
-		param->rsz_common.vsz  = (informat->height - 1) >> 1;
-	else
-		param->rsz_common.vsz  = informat->height - 1;
-
-	param->rsz_common.raw_flip = 0;
-
-	if (resizer->crop_resizer.input == RESIZER_CROP_INPUT_IPIPEIF)
-		param->rsz_common.source = IPIPEIF_DATA;
-	else
-		param->rsz_common.source = IPIPE_DATA;
-
-	switch (informat->code) {
-	case MEDIA_BUS_FMT_UYVY8_2X8:
-		param->rsz_common.src_img_fmt = RSZ_IMG_422;
-		param->rsz_common.raw_flip = 0;
-		break;
-
-	case MEDIA_BUS_FMT_Y8_1X8:
-		param->rsz_common.src_img_fmt = RSZ_IMG_420;
-		/* Select y */
-		param->rsz_common.y_c = 0;
-		param->rsz_common.raw_flip = 0;
-		break;
-
-	case MEDIA_BUS_FMT_UV8_1X8:
-		param->rsz_common.src_img_fmt = RSZ_IMG_420;
-		/* Select y */
-		param->rsz_common.y_c = 1;
-		param->rsz_common.raw_flip = 0;
-		break;
-
-	case MEDIA_BUS_FMT_SGRBG12_1X12:
-		param->rsz_common.raw_flip = 1;
-		break;
-
-	default:
-		param->rsz_common.src_img_fmt = RSZ_IMG_422;
-		param->rsz_common.source = IPIPE_DATA;
-	}
-
-	param->rsz_common.yuv_y_min = user_config->yuv_y_min;
-	param->rsz_common.yuv_y_max = user_config->yuv_y_max;
-	param->rsz_common.yuv_c_min = user_config->yuv_c_min;
-	param->rsz_common.yuv_c_max = user_config->yuv_c_max;
-	param->rsz_common.out_chr_pos = user_config->out_chr_pos;
-	param->rsz_common.rsz_seq_crv = user_config->chroma_sample_even;
-
-	return 0;
-}
-static int
-resizer_configure_in_continuous_mode(struct vpfe_resizer_device *resizer)
-{
-	struct device *dev = resizer->crop_resizer.subdev.v4l2_dev->dev;
-	struct resizer_params *param = &resizer->config;
-	struct vpfe_rsz_config_params *cont_config;
-	int line_len_c;
-	int line_len;
-	int ret;
-
-	if (resizer->resizer_a.output != RESIZER_OUTPUT_MEMORY) {
-		dev_err(dev, "enable resizer - Resizer-A\n");
-		return -EINVAL;
-	}
-
-	cont_config = &resizer->config.user_config;
-	param->rsz_en[RSZ_A] = ENABLE;
-	configure_resizer_out_params(resizer, RSZ_A,
-				     &cont_config->output1, 1, 0);
-	param->rsz_en[RSZ_B] = DISABLE;
-	param->oper_mode = RESIZER_MODE_CONTINUOUS;
-
-	if (resizer->resizer_b.output == RESIZER_OUTPUT_MEMORY) {
-		struct v4l2_mbus_framefmt *outformat2;
-
-		param->rsz_en[RSZ_B] = ENABLE;
-		outformat2 = &resizer->resizer_b.formats[RESIZER_PAD_SOURCE];
-		ret = resizer_validate_output_image_format(dev, outformat2,
-				&line_len, &line_len_c);
-		if (ret)
-			return ret;
-		param->ext_mem_param[RSZ_B].rsz_sdr_oft_y = line_len;
-		param->ext_mem_param[RSZ_B].rsz_sdr_oft_c = line_len_c;
-		configure_resizer_out_params(resizer, RSZ_B,
-						&cont_config->output2, 0, 1);
-		if (outformat2->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16)
-			resizer_enable_422_420_conversion(param,
-							  RSZ_B, ENABLE);
-		else
-			resizer_enable_422_420_conversion(param,
-							  RSZ_B, DISABLE);
-	}
-	resizer_configure_common_in_params(resizer);
-	ret = resizer_configure_output_win(resizer);
-	if (ret)
-		return ret;
-
-	param->rsz_common.passthrough = cont_config->bypass;
-	if (cont_config->bypass)
-		resizer_configure_passthru(resizer, 1);
-
-	return 0;
-}
-
-static inline int
-resizer_validate_input_image_format(struct device *dev,
-				    u32 pix,
-				    int width, int height, int *line_len)
-{
-	int val;
-
-	if (pix != MEDIA_BUS_FMT_UYVY8_2X8 &&
-	    pix != MEDIA_BUS_FMT_Y8_1X8 &&
-	    pix != MEDIA_BUS_FMT_UV8_1X8 &&
-	    pix != MEDIA_BUS_FMT_SGRBG12_1X12) {
-		dev_err(dev,
-		"resizer validate output: pix format not supported, %d\n", pix);
-		return -EINVAL;
-	}
-
-	if (!width || !height) {
-		dev_err(dev,
-			"resizer validate input: invalid width or height\n");
-		return -EINVAL;
-	}
-
-	if (pix == MEDIA_BUS_FMT_UV8_1X8)
-		resizer_calculate_line_length(pix, width,
-					      height, &val, line_len);
-	else
-		resizer_calculate_line_length(pix, width,
-					      height, line_len, &val);
-
-	return 0;
-}
-
-static int
-resizer_validate_decimation(struct device *dev, enum ipipeif_decimation dec_en,
-			    unsigned char rsz, unsigned char frame_div_mode_en,
-			    int width)
-{
-	if (dec_en && frame_div_mode_en) {
-		dev_err(dev,
-		 "dec_en & frame_div_mode_en can not enabled simultaneously\n");
-		return -EINVAL;
-	}
-
-	if (frame_div_mode_en) {
-		dev_err(dev, "frame_div_mode mode not supported\n");
-		return -EINVAL;
-	}
-
-	if (!dec_en)
-		return 0;
-
-	if (width <= VPFE_IPIPE_MAX_INPUT_WIDTH) {
-		dev_err(dev,
-			"image width to be more than %d for decimation\n",
-			VPFE_IPIPE_MAX_INPUT_WIDTH);
-		return -EINVAL;
-	}
-
-	if (rsz < IPIPEIF_RSZ_MIN || rsz > IPIPEIF_RSZ_MAX) {
-		dev_err(dev, "rsz range is %d to %d\n",
-			IPIPEIF_RSZ_MIN, IPIPEIF_RSZ_MAX);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/* resizer_calculate_normal_f_div_param() - Algorithm to calculate the frame
- *					    division parameters for resizer.
- *					    in normal mode.
- */
-static int
-resizer_calculate_normal_f_div_param(struct device *dev, int input_width,
-		int output_width, struct resizer_scale_param *param)
-{
-	/* rsz = R, input_width = H, output width = h in the equation */
-	unsigned int val1;
-	unsigned int rsz;
-	unsigned int val;
-	unsigned int h1;
-	unsigned int h2;
-	unsigned int o;
-
-	if (output_width > input_width) {
-		dev_err(dev, "frame div mode is used for scale down only\n");
-		return -EINVAL;
-	}
-
-	rsz = (input_width << 8) / output_width;
-	val = rsz << 1;
-	val = ((input_width << 8) / val) + 1;
-	o = 14;
-	if (!(val % 2)) {
-		h1 = val;
-	} else {
-		val = input_width << 7;
-		val -= rsz >> 1;
-		val /= rsz << 1;
-		val <<= 1;
-		val += 2;
-		o += (DIV_ROUND_UP(rsz, 1024) << 1);
-		h1 = val;
-	}
-	h2 = output_width - h1;
-	/* phi */
-	val = (h1 * rsz) - (((input_width >> 1) - o) << 8);
-	/* skip */
-	val1 = ((val - 1024) >> 9) << 1;
-	param->f_div.num_passes = MAX_PASSES;
-	param->f_div.pass[0].o_hsz = h1 - 1;
-	param->f_div.pass[0].i_hps = 0;
-	param->f_div.pass[0].h_phs = 0;
-	param->f_div.pass[0].src_hps = 0;
-	param->f_div.pass[0].src_hsz = (input_width >> 2) + o;
-	param->f_div.pass[1].o_hsz = h2 - 1;
-	param->f_div.pass[1].i_hps = val1;
-	param->f_div.pass[1].h_phs = val - (val1 << 8);
-	param->f_div.pass[1].src_hps = (input_width >> 2) - o;
-	param->f_div.pass[1].src_hsz = (input_width >> 2) + o;
-
-	return 0;
-}
-
-static int
-resizer_configure_in_single_shot_mode(struct vpfe_resizer_device *resizer)
-{
-	struct vpfe_rsz_config_params *config = &resizer->config.user_config;
-	struct device *dev = resizer->crop_resizer.subdev.v4l2_dev->dev;
-	struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
-	struct v4l2_mbus_framefmt *outformat1, *outformat2;
-	struct resizer_params *param = &resizer->config;
-	struct v4l2_mbus_framefmt *informat;
-	int decimation;
-	int line_len_c;
-	int line_len;
-	int rsz;
-	int ret;
-
-	informat = &resizer->crop_resizer.formats[RESIZER_CROP_PAD_SINK];
-	outformat1 = &resizer->resizer_a.formats[RESIZER_PAD_SOURCE];
-	outformat2 = &resizer->resizer_b.formats[RESIZER_PAD_SOURCE];
-
-	decimation = vpfe_ipipeif_decimation_enabled(vpfe_dev);
-	rsz = vpfe_ipipeif_get_rsz(vpfe_dev);
-	if (decimation && param->user_config.frame_div_mode_en) {
-		dev_err(dev,
-		"dec_en & frame_div_mode_en cannot enabled simultaneously\n");
-		return -EINVAL;
-	}
-
-	ret = resizer_validate_decimation(dev, decimation, rsz,
-	      param->user_config.frame_div_mode_en, informat->width);
-	if (ret)
-		return -EINVAL;
-
-	ret = resizer_validate_input_image_format(dev, informat->code,
-		informat->width, informat->height, &line_len);
-	if (ret)
-		return -EINVAL;
-
-	if (resizer->resizer_a.output != RESIZER_OUTPUT_NONE) {
-		param->rsz_en[RSZ_A] = ENABLE;
-		ret = resizer_validate_output_image_format(dev, outformat1,
-					&line_len, &line_len_c);
-		if (ret)
-			return ret;
-		param->ext_mem_param[RSZ_A].rsz_sdr_oft_y = line_len;
-		param->ext_mem_param[RSZ_A].rsz_sdr_oft_c = line_len_c;
-		configure_resizer_out_params(resizer, RSZ_A,
-					&param->user_config.output1, 0, 1);
-
-		if (outformat1->code == MEDIA_BUS_FMT_SGRBG12_1X12)
-			param->rsz_common.raw_flip = 1;
-		else
-			param->rsz_common.raw_flip = 0;
-
-		if (outformat1->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16)
-			resizer_enable_422_420_conversion(param,
-							  RSZ_A, ENABLE);
-		else
-			resizer_enable_422_420_conversion(param,
-							  RSZ_A, DISABLE);
-	}
-
-	if (resizer->resizer_b.output != RESIZER_OUTPUT_NONE) {
-		param->rsz_en[RSZ_B] = ENABLE;
-		ret = resizer_validate_output_image_format(dev, outformat2,
-				&line_len, &line_len_c);
-		if (ret)
-			return ret;
-		param->ext_mem_param[RSZ_B].rsz_sdr_oft_y = line_len;
-		param->ext_mem_param[RSZ_B].rsz_sdr_oft_c = line_len_c;
-		configure_resizer_out_params(resizer, RSZ_B,
-					&param->user_config.output2, 0, 1);
-		if (outformat2->code == MEDIA_BUS_FMT_YDYUYDYV8_1X16)
-			resizer_enable_422_420_conversion(param,
-							  RSZ_B, ENABLE);
-		else
-			resizer_enable_422_420_conversion(param,
-							  RSZ_B, DISABLE);
-	}
-
-	resizer_configure_common_in_params(resizer);
-	if (resizer->resizer_a.output != RESIZER_OUTPUT_NONE) {
-		resizer_calculate_resize_ratios(resizer, RSZ_A);
-		resizer_calculate_sdram_offsets(resizer, RSZ_A);
-		/* Overriding resize ratio calculation */
-		if (informat->code == MEDIA_BUS_FMT_UV8_1X8) {
-			param->rsz_rsc_param[RSZ_A].v_dif =
-				(((informat->height + 1) * 2) * 256) /
-				(param->rsz_rsc_param[RSZ_A].o_vsz + 1);
-		}
-	}
-
-	if (resizer->resizer_b.output != RESIZER_OUTPUT_NONE) {
-		resizer_calculate_resize_ratios(resizer, RSZ_B);
-		resizer_calculate_sdram_offsets(resizer, RSZ_B);
-		/* Overriding resize ratio calculation */
-		if (informat->code == MEDIA_BUS_FMT_UV8_1X8) {
-			param->rsz_rsc_param[RSZ_B].v_dif =
-				(((informat->height + 1) * 2) * 256) /
-				(param->rsz_rsc_param[RSZ_B].o_vsz + 1);
-		}
-	}
-	if (param->user_config.frame_div_mode_en &&
-		param->rsz_en[RSZ_A]) {
-		if (!param->rsz_rsc_param[RSZ_A].dscale_en)
-			ret = resizer_calculate_normal_f_div_param(dev,
-			      informat->width,
-			      param->rsz_rsc_param[RSZ_A].o_vsz + 1,
-			      &param->rsz_rsc_param[RSZ_A]);
-		else
-			ret = resizer_calculate_down_scale_f_div_param(dev,
-			      informat->width,
-			      param->rsz_rsc_param[RSZ_A].o_vsz + 1,
-			      &param->rsz_rsc_param[RSZ_A]);
-		if (ret)
-			return -EINVAL;
-	}
-	if (param->user_config.frame_div_mode_en &&
-		param->rsz_en[RSZ_B]) {
-		if (!param->rsz_rsc_param[RSZ_B].dscale_en)
-			ret = resizer_calculate_normal_f_div_param(dev,
-			      informat->width,
-			      param->rsz_rsc_param[RSZ_B].o_vsz + 1,
-			      &param->rsz_rsc_param[RSZ_B]);
-		else
-			ret = resizer_calculate_down_scale_f_div_param(dev,
-			      informat->width,
-			      param->rsz_rsc_param[RSZ_B].o_vsz + 1,
-			      &param->rsz_rsc_param[RSZ_B]);
-		if (ret)
-			return -EINVAL;
-	}
-	param->rsz_common.passthrough = config->bypass;
-	if (config->bypass)
-		resizer_configure_passthru(resizer, 1);
-	return 0;
-}
-
-static void
-resizer_set_default_configuration(struct vpfe_resizer_device *resizer)
-{
-#define  WIDTH_I 640
-#define  HEIGHT_I 480
-#define  WIDTH_O 640
-#define  HEIGHT_O 480
-	const struct resizer_params rsz_default_config = {
-		.oper_mode = RESIZER_MODE_ONE_SHOT,
-		.rsz_common = {
-			.vsz = HEIGHT_I - 1,
-			.hsz = WIDTH_I - 1,
-			.src_img_fmt = RSZ_IMG_422,
-			.raw_flip = 1,	/* flip preserve Raw format */
-			.source = IPIPE_DATA,
-			.passthrough = BYPASS_OFF,
-			.yuv_y_max = 255,
-			.yuv_c_max = 255,
-			.rsz_seq_crv = DISABLE,
-			.out_chr_pos = VPFE_IPIPE_YUV422_CHR_POS_COSITE,
-		},
-		.rsz_rsc_param = {
-			{
-				.h_flip = DISABLE,
-				.v_flip = DISABLE,
-				.cen = DISABLE,
-				.yen = DISABLE,
-				.o_vsz = HEIGHT_O - 1,
-				.o_hsz = WIDTH_O - 1,
-				.v_dif = 256,
-				.v_typ_y = VPFE_RSZ_INTP_CUBIC,
-				.v_typ_c = VPFE_RSZ_INTP_CUBIC,
-				.h_dif = 256,
-				.h_typ_y = VPFE_RSZ_INTP_CUBIC,
-				.h_typ_c = VPFE_RSZ_INTP_CUBIC,
-				.h_dscale_ave_sz =
-					VPFE_IPIPE_DWN_SCALE_1_OVER_2,
-				.v_dscale_ave_sz =
-					VPFE_IPIPE_DWN_SCALE_1_OVER_2,
-			},
-			{
-				.h_flip = DISABLE,
-				.v_flip = DISABLE,
-				.cen = DISABLE,
-				.yen = DISABLE,
-				.o_vsz = HEIGHT_O - 1,
-				.o_hsz = WIDTH_O - 1,
-				.v_dif = 256,
-				.v_typ_y = VPFE_RSZ_INTP_CUBIC,
-				.v_typ_c = VPFE_RSZ_INTP_CUBIC,
-				.h_dif = 256,
-				.h_typ_y = VPFE_RSZ_INTP_CUBIC,
-				.h_typ_c = VPFE_RSZ_INTP_CUBIC,
-				.h_dscale_ave_sz =
-					VPFE_IPIPE_DWN_SCALE_1_OVER_2,
-				.v_dscale_ave_sz =
-					VPFE_IPIPE_DWN_SCALE_1_OVER_2,
-			},
-		},
-		.rsz2rgb = {
-			{
-				.rgb_en = DISABLE
-			},
-			{
-				.rgb_en = DISABLE
-			}
-		},
-		.ext_mem_param = {
-			{
-				.rsz_sdr_oft_y = WIDTH_O << 1,
-				.rsz_sdr_ptr_e_y = HEIGHT_O,
-				.rsz_sdr_oft_c = WIDTH_O,
-				.rsz_sdr_ptr_e_c = HEIGHT_O >> 1,
-			},
-			{
-				.rsz_sdr_oft_y = WIDTH_O << 1,
-				.rsz_sdr_ptr_e_y = HEIGHT_O,
-				.rsz_sdr_oft_c = WIDTH_O,
-				.rsz_sdr_ptr_e_c = HEIGHT_O,
-			},
-		},
-		.rsz_en[0] = ENABLE,
-		.rsz_en[1] = DISABLE,
-		.user_config = {
-			.output1 = {
-				.v_typ_y = VPFE_RSZ_INTP_CUBIC,
-				.v_typ_c = VPFE_RSZ_INTP_CUBIC,
-				.h_typ_y = VPFE_RSZ_INTP_CUBIC,
-				.h_typ_c = VPFE_RSZ_INTP_CUBIC,
-				.h_dscale_ave_sz =
-					VPFE_IPIPE_DWN_SCALE_1_OVER_2,
-				.v_dscale_ave_sz =
-					VPFE_IPIPE_DWN_SCALE_1_OVER_2,
-			},
-			.output2 = {
-				.v_typ_y = VPFE_RSZ_INTP_CUBIC,
-				.v_typ_c = VPFE_RSZ_INTP_CUBIC,
-				.h_typ_y = VPFE_RSZ_INTP_CUBIC,
-				.h_typ_c = VPFE_RSZ_INTP_CUBIC,
-				.h_dscale_ave_sz =
-					VPFE_IPIPE_DWN_SCALE_1_OVER_2,
-				.v_dscale_ave_sz =
-					VPFE_IPIPE_DWN_SCALE_1_OVER_2,
-			},
-			.yuv_y_max = 255,
-			.yuv_c_max = 255,
-			.out_chr_pos = VPFE_IPIPE_YUV422_CHR_POS_COSITE,
-		},
-	};
-	memcpy(&resizer->config, &rsz_default_config,
-	       sizeof(struct resizer_params));
-}
-
-/*
- * resizer_set_configuration() - set resizer config
- * @resizer: vpfe resizer device pointer.
- * @chan_config: resizer channel configuration.
- */
-static int
-resizer_set_configuration(struct vpfe_resizer_device *resizer,
-			  struct vpfe_rsz_config *chan_config)
-{
-	if (!chan_config->config)
-		resizer_set_default_configuration(resizer);
-	else
-		if (copy_from_user(&resizer->config.user_config,
-				   (void __user *)chan_config->config,
-				   sizeof(struct vpfe_rsz_config_params)))
-			return -EFAULT;
-
-	return 0;
-}
-
-/*
- * resizer_get_configuration() - get resizer config
- * @resizer: vpfe resizer device pointer.
- * @channel: image processor logical channel.
- * @chan_config: resizer channel configuration.
- */
-static int
-resizer_get_configuration(struct vpfe_resizer_device *resizer,
-		   struct vpfe_rsz_config *chan_config)
-{
-	struct device *dev = resizer->crop_resizer.subdev.v4l2_dev->dev;
-
-	if (!chan_config->config) {
-		dev_err(dev, "Resizer channel invalid pointer\n");
-		return -EINVAL;
-	}
-
-	if (copy_to_user((void __user *)chan_config->config,
-			 (void *)&resizer->config.user_config,
-			 sizeof(struct vpfe_rsz_config_params))) {
-		dev_err(dev, "resizer_get_configuration: Error in copy to user\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-/*
- * VPFE video operations
- */
-
-/*
- * resizer_a_video_out_queue() - RESIZER-A video out queue
- * @vpfe_dev: vpfe device pointer.
- * @addr: buffer address.
- */
-static int resizer_a_video_out_queue(struct vpfe_device *vpfe_dev,
-				     unsigned long addr)
-{
-	struct vpfe_resizer_device *resizer = &vpfe_dev->vpfe_resizer;
-
-	return resizer_set_outaddr(resizer->base_addr,
-				      &resizer->config, RSZ_A, addr);
-}
-
-/*
- * resizer_b_video_out_queue() - RESIZER-B video out queue
- * @vpfe_dev: vpfe device pointer.
- * @addr: buffer address.
- */
-static int resizer_b_video_out_queue(struct vpfe_device *vpfe_dev,
-				     unsigned long addr)
-{
-	struct vpfe_resizer_device *resizer = &vpfe_dev->vpfe_resizer;
-
-	return resizer_set_outaddr(resizer->base_addr,
-				   &resizer->config, RSZ_B, addr);
-}
-
-static const struct vpfe_video_operations resizer_a_video_ops = {
-	.queue = resizer_a_video_out_queue,
-};
-
-static const struct vpfe_video_operations resizer_b_video_ops = {
-	.queue = resizer_b_video_out_queue,
-};
-
-static void resizer_enable(struct vpfe_resizer_device *resizer, int en)
-{
-	struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
-	u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input;
-	unsigned char val;
-
-	if (resizer->crop_resizer.input == RESIZER_CROP_INPUT_NONE)
-		return;
-
-	if (resizer->crop_resizer.input == RESIZER_CROP_INPUT_IPIPEIF &&
-	   ipipeif_sink == IPIPEIF_INPUT_MEMORY) {
-		do {
-			val = regr_rsz(resizer->base_addr, RSZ_SRC_EN);
-		} while (val);
-
-		if (resizer->resizer_a.output != RESIZER_OUTPUT_NONE) {
-			do {
-				val = regr_rsz(resizer->base_addr, RSZ_A);
-			} while (val);
-		}
-		if (resizer->resizer_b.output != RESIZER_OUTPUT_NONE) {
-			do {
-				val = regr_rsz(resizer->base_addr, RSZ_B);
-			} while (val);
-		}
-	}
-	if (resizer->resizer_a.output != RESIZER_OUTPUT_NONE)
-		rsz_enable(resizer->base_addr, RSZ_A, en);
-
-	if (resizer->resizer_b.output != RESIZER_OUTPUT_NONE)
-		rsz_enable(resizer->base_addr, RSZ_B, en);
-}
-
-
-/*
- * resizer_ss_isr() - resizer module single-shot buffer scheduling isr
- * @resizer: vpfe resizer device pointer.
- */
-static void resizer_ss_isr(struct vpfe_resizer_device *resizer)
-{
-	struct vpfe_video_device *video_out = &resizer->resizer_a.video_out;
-	struct vpfe_video_device *video_out2 = &resizer->resizer_b.video_out;
-	struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
-	struct vpfe_pipeline *pipe = &video_out->pipe;
-	u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input;
-	u32 val;
-
-	if (ipipeif_sink != IPIPEIF_INPUT_MEMORY)
-		return;
-
-	if (resizer->resizer_a.output == RESIZER_OUTPUT_MEMORY) {
-		val = vpss_dma_complete_interrupt();
-		if (val != 0 && val != 2)
-			return;
-	}
-
-	if (resizer->resizer_a.output == RESIZER_OUTPUT_MEMORY) {
-		spin_lock(&video_out->dma_queue_lock);
-		vpfe_video_process_buffer_complete(video_out);
-		video_out->state = VPFE_VIDEO_BUFFER_NOT_QUEUED;
-		vpfe_video_schedule_next_buffer(video_out);
-		spin_unlock(&video_out->dma_queue_lock);
-	}
-
-	/* If resizer B is enabled */
-	if (pipe->output_num > 1 && resizer->resizer_b.output ==
-	    RESIZER_OUTPUT_MEMORY) {
-		spin_lock(&video_out2->dma_queue_lock);
-		vpfe_video_process_buffer_complete(video_out2);
-		video_out2->state = VPFE_VIDEO_BUFFER_NOT_QUEUED;
-		vpfe_video_schedule_next_buffer(video_out2);
-		spin_unlock(&video_out2->dma_queue_lock);
-	}
-
-	/* start HW if buffers are queued */
-	if (vpfe_video_is_pipe_ready(pipe) &&
-	    resizer->resizer_a.output == RESIZER_OUTPUT_MEMORY) {
-		resizer_enable(resizer, 1);
-		vpfe_ipipe_enable(vpfe_dev, 1);
-		vpfe_ipipeif_enable(vpfe_dev);
-	}
-}
-
-/*
- * vpfe_resizer_buffer_isr() - resizer module buffer scheduling isr
- * @resizer: vpfe resizer device pointer.
- */
-void vpfe_resizer_buffer_isr(struct vpfe_resizer_device *resizer)
-{
-	struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
-	struct vpfe_video_device *video_out = &resizer->resizer_a.video_out;
-	struct vpfe_video_device *video_out2 = &resizer->resizer_b.video_out;
-	struct vpfe_pipeline *pipe = &resizer->resizer_a.video_out.pipe;
-	enum v4l2_field field;
-	int fid;
-
-	if (!video_out->started)
-		return;
-
-	if (resizer->crop_resizer.input == RESIZER_CROP_INPUT_NONE)
-		return;
-
-	field = video_out->fmt.fmt.pix.field;
-	if (field == V4L2_FIELD_NONE) {
-		/* handle progressive frame capture */
-		if (video_out->cur_frm != video_out->next_frm) {
-			vpfe_video_process_buffer_complete(video_out);
-			if (pipe->output_num > 1)
-				vpfe_video_process_buffer_complete(video_out2);
-		}
-
-		video_out->skip_frame_count--;
-		if (!video_out->skip_frame_count) {
-			video_out->skip_frame_count =
-				video_out->skip_frame_count_init;
-			rsz_src_enable(resizer->base_addr, 1);
-		} else {
-			rsz_src_enable(resizer->base_addr, 0);
-		}
-		return;
-	}
-
-	/* handle interlaced frame capture */
-	fid = vpfe_isif_get_fid(vpfe_dev);
-
-	/* switch the software maintained field id */
-	video_out->field_id ^= 1;
-	if (fid == video_out->field_id) {
-		/*
-		 * we are in-sync here,continue.
-		 * One frame is just being captured. If the
-		 * next frame is available, release the current
-		 * frame and move on
-		 */
-		if (fid == 0 && video_out->cur_frm != video_out->next_frm) {
-			vpfe_video_process_buffer_complete(video_out);
-			if (pipe->output_num > 1)
-				vpfe_video_process_buffer_complete(video_out2);
-		}
-	} else if (fid == 0) {
-		/*
-		 * out of sync. Recover from any hardware out-of-sync.
-		 * May loose one frame
-		 */
-		video_out->field_id = fid;
-	}
-}
-
-/*
- * vpfe_resizer_dma_isr() - resizer module dma isr
- * @resizer: vpfe resizer device pointer.
- */
-void vpfe_resizer_dma_isr(struct vpfe_resizer_device *resizer)
-{
-	struct vpfe_video_device *video_out2 = &resizer->resizer_b.video_out;
-	struct vpfe_video_device *video_out = &resizer->resizer_a.video_out;
-	struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
-	struct vpfe_pipeline *pipe = &video_out->pipe;
-	int schedule_capture = 0;
-	enum v4l2_field field;
-	int fid;
-
-	if (!video_out->started)
-		return;
-
-	if (pipe->state == VPFE_PIPELINE_STREAM_SINGLESHOT) {
-		resizer_ss_isr(resizer);
-		return;
-	}
-
-	field = video_out->fmt.fmt.pix.field;
-	if (field == V4L2_FIELD_NONE) {
-		if (!list_empty(&video_out->dma_queue) &&
-			video_out->cur_frm == video_out->next_frm)
-			schedule_capture = 1;
-	} else {
-		fid = vpfe_isif_get_fid(vpfe_dev);
-		if (fid == video_out->field_id) {
-			/* we are in-sync here,continue */
-			if (fid == 1 && !list_empty(&video_out->dma_queue) &&
-			    video_out->cur_frm == video_out->next_frm)
-				schedule_capture = 1;
-		}
-	}
-
-	if (!schedule_capture)
-		return;
-
-	spin_lock(&video_out->dma_queue_lock);
-	vpfe_video_schedule_next_buffer(video_out);
-	spin_unlock(&video_out->dma_queue_lock);
-	if (pipe->output_num > 1) {
-		spin_lock(&video_out2->dma_queue_lock);
-		vpfe_video_schedule_next_buffer(video_out2);
-		spin_unlock(&video_out2->dma_queue_lock);
-	}
-}
-
-/*
- * V4L2 subdev operations
- */
-
-/*
- * resizer_ioctl() - Handle resizer module private ioctl's
- * @sd: pointer to v4l2 subdev structure
- * @cmd: configuration command
- * @arg: configuration argument
- */
-static long resizer_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
-	struct vpfe_resizer_device *resizer = v4l2_get_subdevdata(sd);
-	struct device *dev = resizer->crop_resizer.subdev.v4l2_dev->dev;
-	struct vpfe_rsz_config *user_config;
-	int ret = -ENOIOCTLCMD;
-
-	if (&resizer->crop_resizer.subdev != sd)
-		return ret;
-
-	switch (cmd) {
-	case VIDIOC_VPFE_RSZ_S_CONFIG:
-		user_config = arg;
-		ret = resizer_set_configuration(resizer, user_config);
-		break;
-
-	case VIDIOC_VPFE_RSZ_G_CONFIG:
-		user_config = arg;
-		if (!user_config->config) {
-			dev_err(dev, "error in VIDIOC_VPFE_RSZ_G_CONFIG\n");
-			return -EINVAL;
-		}
-		ret = resizer_get_configuration(resizer, user_config);
-		break;
-	}
-	return ret;
-}
-
-static int resizer_do_hw_setup(struct vpfe_resizer_device *resizer)
-{
-	struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
-	u16 ipipeif_sink = vpfe_dev->vpfe_ipipeif.input;
-	u16 ipipeif_source = vpfe_dev->vpfe_ipipeif.output;
-	struct resizer_params *param = &resizer->config;
-	int ret = 0;
-
-	if (resizer->resizer_a.output == RESIZER_OUTPUT_MEMORY ||
-	    resizer->resizer_b.output == RESIZER_OUTPUT_MEMORY) {
-		if (ipipeif_sink == IPIPEIF_INPUT_MEMORY &&
-		    ipipeif_source == IPIPEIF_OUTPUT_RESIZER)
-			ret = resizer_configure_in_single_shot_mode(resizer);
-		else
-			ret =  resizer_configure_in_continuous_mode(resizer);
-		if (ret)
-			return ret;
-		ret = config_rsz_hw(resizer, param);
-	}
-	return ret;
-}
-
-/*
- * resizer_set_stream() - Enable/Disable streaming on resizer subdev
- * @sd: pointer to v4l2 subdev structure
- * @enable: 1 == Enable, 0 == Disable
- */
-static int resizer_set_stream(struct v4l2_subdev *sd, int enable)
-{
-	struct vpfe_resizer_device *resizer = v4l2_get_subdevdata(sd);
-
-	if (&resizer->crop_resizer.subdev != sd)
-		return 0;
-
-	if (resizer->resizer_a.output != RESIZER_OUTPUT_MEMORY)
-		return 0;
-
-	switch (enable) {
-	case 1:
-		if (resizer_do_hw_setup(resizer) < 0)
-			return -EINVAL;
-		resizer_enable(resizer, enable);
-		break;
-
-	case 0:
-		resizer_enable(resizer, enable);
-		break;
-	}
-
-	return 0;
-}
-
-/*
- * __resizer_get_format() - helper function for getting resizer format
- * @sd: pointer to subdev.
- * @cfg: V4L2 subdev pad config
- * @pad: pad number.
- * @which: wanted subdev format.
- * Return wanted mbus frame format.
- */
-static struct v4l2_mbus_framefmt *
-__resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-		     unsigned int pad, enum v4l2_subdev_format_whence which)
-{
-	struct vpfe_resizer_device *resizer = v4l2_get_subdevdata(sd);
-
-	if (which == V4L2_SUBDEV_FORMAT_TRY)
-		return v4l2_subdev_get_try_format(sd, cfg, pad);
-	if (&resizer->crop_resizer.subdev == sd)
-		return &resizer->crop_resizer.formats[pad];
-	if (&resizer->resizer_a.subdev == sd)
-		return &resizer->resizer_a.formats[pad];
-	if (&resizer->resizer_b.subdev == sd)
-		return &resizer->resizer_b.formats[pad];
-	return NULL;
-}
-
-/*
- * resizer_try_format() - Handle try format by pad subdev method
- * @sd: pointer to subdev.
- * @cfg: V4L2 subdev pad config
- * @pad: pad num.
- * @fmt: pointer to v4l2 format structure.
- * @which: wanted subdev format.
- */
-static void
-resizer_try_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
-	unsigned int pad, struct v4l2_mbus_framefmt *fmt,
-	enum v4l2_subdev_format_whence which)
-{
-	struct vpfe_resizer_device *resizer = v4l2_get_subdevdata(sd);
-	unsigned int max_out_height;
-	unsigned int max_out_width;
-	unsigned int i;
-
-	if ((&resizer->resizer_a.subdev == sd && pad == RESIZER_PAD_SINK) ||
-	    (&resizer->resizer_b.subdev == sd && pad == RESIZER_PAD_SINK) ||
-	    (&resizer->crop_resizer.subdev == sd &&
-	    (pad == RESIZER_CROP_PAD_SOURCE ||
-	    pad == RESIZER_CROP_PAD_SOURCE2 || pad == RESIZER_CROP_PAD_SINK))) {
-		for (i = 0; i < ARRAY_SIZE(resizer_input_formats); i++) {
-			if (fmt->code == resizer_input_formats[i])
-				break;
-		}
-		/* If not found, use UYVY as default */
-		if (i >= ARRAY_SIZE(resizer_input_formats))
-			fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
-
-		fmt->width = clamp_t(u32, fmt->width, MIN_IN_WIDTH,
-					MAX_IN_WIDTH);
-		fmt->height = clamp_t(u32, fmt->height, MIN_IN_HEIGHT,
-				MAX_IN_HEIGHT);
-	} else if (&resizer->resizer_a.subdev == sd &&
-		   pad == RESIZER_PAD_SOURCE) {
-		max_out_width = IPIPE_MAX_OUTPUT_WIDTH_A;
-		max_out_height = IPIPE_MAX_OUTPUT_HEIGHT_A;
-
-		for (i = 0; i < ARRAY_SIZE(resizer_output_formats); i++) {
-			if (fmt->code == resizer_output_formats[i])
-				break;
-		}
-		/* If not found, use UYVY as default */
-		if (i >= ARRAY_SIZE(resizer_output_formats))
-			fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
-
-		fmt->width = clamp_t(u32, fmt->width, MIN_OUT_WIDTH,
-					max_out_width);
-		fmt->width &= ~15;
-		fmt->height = clamp_t(u32, fmt->height, MIN_OUT_HEIGHT,
-				max_out_height);
-	} else if (&resizer->resizer_b.subdev == sd &&
-		   pad == RESIZER_PAD_SOURCE) {
-		max_out_width = IPIPE_MAX_OUTPUT_WIDTH_B;
-		max_out_height = IPIPE_MAX_OUTPUT_HEIGHT_B;
-
-		for (i = 0; i < ARRAY_SIZE(resizer_output_formats); i++) {
-			if (fmt->code == resizer_output_formats[i])
-				break;
-		}
-		/* If not found, use UYVY as default */
-		if (i >= ARRAY_SIZE(resizer_output_formats))
-			fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
-
-		fmt->width = clamp_t(u32, fmt->width, MIN_OUT_WIDTH,
-					max_out_width);
-		fmt->width &= ~15;
-		fmt->height = clamp_t(u32, fmt->height, MIN_OUT_HEIGHT,
-				max_out_height);
-	}
-}
-
-/*
- * resizer_set_format() - Handle set format by pads subdev method
- * @sd: pointer to v4l2 subdev structure
- * @cfg: V4L2 subdev pad config
- * @fmt: pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int resizer_set_format(struct v4l2_subdev *sd,
-			      struct v4l2_subdev_pad_config *cfg,
-			      struct v4l2_subdev_format *fmt)
-{
-	struct vpfe_resizer_device *resizer = v4l2_get_subdevdata(sd);
-	struct v4l2_mbus_framefmt *format;
-
-	format = __resizer_get_format(sd, cfg, fmt->pad, fmt->which);
-	if (format == NULL)
-		return -EINVAL;
-
-	resizer_try_format(sd, cfg, fmt->pad, &fmt->format, fmt->which);
-	*format = fmt->format;
-
-	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
-		return 0;
-
-	if (&resizer->crop_resizer.subdev == sd) {
-		if (fmt->pad == RESIZER_CROP_PAD_SINK) {
-			resizer->crop_resizer.formats[fmt->pad] = fmt->format;
-		} else if (fmt->pad == RESIZER_CROP_PAD_SOURCE &&
-				resizer->crop_resizer.output == RESIZER_A) {
-			resizer->crop_resizer.formats[fmt->pad] = fmt->format;
-			resizer->crop_resizer.
-			formats[RESIZER_CROP_PAD_SOURCE2] = fmt->format;
-		} else if (fmt->pad == RESIZER_CROP_PAD_SOURCE2 &&
-			resizer->crop_resizer.output2 == RESIZER_B) {
-			resizer->crop_resizer.formats[fmt->pad] = fmt->format;
-			resizer->crop_resizer.
-			formats[RESIZER_CROP_PAD_SOURCE] = fmt->format;
-		} else {
-			return -EINVAL;
-		}
-	} else if (&resizer->resizer_a.subdev == sd) {
-		if (fmt->pad == RESIZER_PAD_SINK)
-			resizer->resizer_a.formats[fmt->pad] = fmt->format;
-		else if (fmt->pad == RESIZER_PAD_SOURCE)
-			resizer->resizer_a.formats[fmt->pad] = fmt->format;
-		else
-			return -EINVAL;
-	} else if (&resizer->resizer_b.subdev == sd) {
-		if (fmt->pad == RESIZER_PAD_SINK)
-			resizer->resizer_b.formats[fmt->pad] = fmt->format;
-		else if (fmt->pad == RESIZER_PAD_SOURCE)
-			resizer->resizer_b.formats[fmt->pad] = fmt->format;
-		else
-			return -EINVAL;
-	} else {
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*
- * resizer_get_format() - Retrieve the video format on a pad
- * @sd: pointer to v4l2 subdev structure.
- * @cfg: V4L2 subdev pad config
- * @fmt: pointer to v4l2 subdev format structure
- * return -EINVAL or zero on success
- */
-static int resizer_get_format(struct v4l2_subdev *sd,
-			      struct v4l2_subdev_pad_config *cfg,
-			      struct v4l2_subdev_format *fmt)
-{
-	struct v4l2_mbus_framefmt *format;
-
-	format = __resizer_get_format(sd, cfg, fmt->pad, fmt->which);
-	if (format == NULL)
-		return -EINVAL;
-
-	fmt->format = *format;
-
-	return 0;
-}
-
-/*
- * resizer_enum_frame_size() - enum frame sizes on pads
- * @sd: Pointer to subdevice.
- * @cfg: V4L2 subdev pad config
- * @code: pointer to v4l2_subdev_frame_size_enum structure.
- */
-static int resizer_enum_frame_size(struct v4l2_subdev *sd,
-				   struct v4l2_subdev_pad_config *cfg,
-				   struct v4l2_subdev_frame_size_enum *fse)
-{
-	struct v4l2_mbus_framefmt format;
-
-	if (fse->index != 0)
-		return -EINVAL;
-
-	format.code = fse->code;
-	format.width = 1;
-	format.height = 1;
-	resizer_try_format(sd, cfg, fse->pad, &format, fse->which);
-	fse->min_width = format.width;
-	fse->min_height = format.height;
-
-	if (format.code != fse->code)
-		return -EINVAL;
-
-	format.code = fse->code;
-	format.width = -1;
-	format.height = -1;
-	resizer_try_format(sd, cfg, fse->pad, &format, fse->which);
-	fse->max_width = format.width;
-	fse->max_height = format.height;
-
-	return 0;
-}
-
-/*
- * resizer_enum_mbus_code() - enum mbus codes for pads
- * @sd: Pointer to subdevice.
- * @cfg: V4L2 subdev pad config
- * @code: pointer to v4l2_subdev_mbus_code_enum structure
- */
-static int resizer_enum_mbus_code(struct v4l2_subdev *sd,
-				  struct v4l2_subdev_pad_config *cfg,
-				  struct v4l2_subdev_mbus_code_enum *code)
-{
-	if (code->pad == RESIZER_PAD_SINK) {
-		if (code->index >= ARRAY_SIZE(resizer_input_formats))
-			return -EINVAL;
-
-		code->code = resizer_input_formats[code->index];
-	} else if (code->pad == RESIZER_PAD_SOURCE) {
-		if (code->index >= ARRAY_SIZE(resizer_output_formats))
-			return -EINVAL;
-
-		code->code = resizer_output_formats[code->index];
-	}
-
-	return 0;
-}
-
-/*
- * resizer_init_formats() - Initialize formats on all pads
- * @sd: Pointer to subdevice.
- * @fh: V4L2 subdev file handle.
- *
- * Initialize all pad formats with default values. Try formats are
- * initialized on the file handle.
- */
-static int resizer_init_formats(struct v4l2_subdev *sd,
-				struct v4l2_subdev_fh *fh)
-{
-	__u32 which = V4L2_SUBDEV_FORMAT_TRY;
-	struct vpfe_resizer_device *resizer = v4l2_get_subdevdata(sd);
-	struct v4l2_subdev_format format;
-
-	if (&resizer->crop_resizer.subdev == sd) {
-		memset(&format, 0, sizeof(format));
-		format.pad = RESIZER_CROP_PAD_SINK;
-		format.which = which;
-		format.format.code = MEDIA_BUS_FMT_YUYV8_2X8;
-		format.format.width = MAX_IN_WIDTH;
-		format.format.height = MAX_IN_HEIGHT;
-		resizer_set_format(sd, fh->pad, &format);
-
-		memset(&format, 0, sizeof(format));
-		format.pad = RESIZER_CROP_PAD_SOURCE;
-		format.which = which;
-		format.format.code = MEDIA_BUS_FMT_UYVY8_2X8;
-		format.format.width = MAX_IN_WIDTH;
-		format.format.height = MAX_IN_WIDTH;
-		resizer_set_format(sd, fh->pad, &format);
-
-		memset(&format, 0, sizeof(format));
-		format.pad = RESIZER_CROP_PAD_SOURCE2;
-		format.which = which;
-		format.format.code = MEDIA_BUS_FMT_UYVY8_2X8;
-		format.format.width = MAX_IN_WIDTH;
-		format.format.height = MAX_IN_WIDTH;
-		resizer_set_format(sd, fh->pad, &format);
-	} else if (&resizer->resizer_a.subdev == sd) {
-		memset(&format, 0, sizeof(format));
-		format.pad = RESIZER_PAD_SINK;
-		format.which = which;
-		format.format.code = MEDIA_BUS_FMT_YUYV8_2X8;
-		format.format.width = MAX_IN_WIDTH;
-		format.format.height = MAX_IN_HEIGHT;
-		resizer_set_format(sd, fh->pad, &format);
-
-		memset(&format, 0, sizeof(format));
-		format.pad = RESIZER_PAD_SOURCE;
-		format.which = which;
-		format.format.code = MEDIA_BUS_FMT_UYVY8_2X8;
-		format.format.width = IPIPE_MAX_OUTPUT_WIDTH_A;
-		format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_A;
-		resizer_set_format(sd, fh->pad, &format);
-	} else if (&resizer->resizer_b.subdev == sd) {
-		memset(&format, 0, sizeof(format));
-		format.pad = RESIZER_PAD_SINK;
-		format.which = which;
-		format.format.code = MEDIA_BUS_FMT_YUYV8_2X8;
-		format.format.width = MAX_IN_WIDTH;
-		format.format.height = MAX_IN_HEIGHT;
-		resizer_set_format(sd, fh->pad, &format);
-
-		memset(&format, 0, sizeof(format));
-		format.pad = RESIZER_PAD_SOURCE;
-		format.which = which;
-		format.format.code = MEDIA_BUS_FMT_UYVY8_2X8;
-		format.format.width = IPIPE_MAX_OUTPUT_WIDTH_B;
-		format.format.height = IPIPE_MAX_OUTPUT_HEIGHT_B;
-		resizer_set_format(sd, fh->pad, &format);
-	}
-
-	return 0;
-}
-
-/* subdev core operations */
-static const struct v4l2_subdev_core_ops resizer_v4l2_core_ops = {
-	.ioctl = resizer_ioctl,
-};
-
-/* subdev internal operations */
-static const struct v4l2_subdev_internal_ops resizer_v4l2_internal_ops = {
-	.open = resizer_init_formats,
-};
-
-/* subdev video operations */
-static const struct v4l2_subdev_video_ops resizer_v4l2_video_ops = {
-	.s_stream = resizer_set_stream,
-};
-
-/* subdev pad operations */
-static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = {
-	.enum_mbus_code = resizer_enum_mbus_code,
-	.enum_frame_size = resizer_enum_frame_size,
-	.get_fmt = resizer_get_format,
-	.set_fmt = resizer_set_format,
-};
-
-/* subdev operations */
-static const struct v4l2_subdev_ops resizer_v4l2_ops = {
-	.core = &resizer_v4l2_core_ops,
-	.video = &resizer_v4l2_video_ops,
-	.pad = &resizer_v4l2_pad_ops,
-};
-
-/*
- * Media entity operations
- */
-
-/*
- * resizer_link_setup() - Setup resizer connections
- * @entity: Pointer to media entity structure
- * @local: Pointer to local pad array
- * @remote: Pointer to remote pad array
- * @flags: Link flags
- * return -EINVAL or zero on success
- */
-static int resizer_link_setup(struct media_entity *entity,
-			   const struct media_pad *local,
-			   const struct media_pad *remote, u32 flags)
-{
-	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
-	struct vpfe_resizer_device *resizer = v4l2_get_subdevdata(sd);
-	struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
-	u16 ipipeif_source = vpfe_dev->vpfe_ipipeif.output;
-	u16 ipipe_source = vpfe_dev->vpfe_ipipe.output;
-	unsigned int index = local->index;
-
-	/* FIXME: this is actually a hack! */
-	if (is_media_entity_v4l2_subdev(remote->entity))
-		index |= 2 << 16;
-
-	if (&resizer->crop_resizer.subdev == sd) {
-		switch (index) {
-		case RESIZER_CROP_PAD_SINK | 2 << 16:
-			if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-				resizer->crop_resizer.input =
-					RESIZER_CROP_INPUT_NONE;
-				break;
-			}
-
-			if (resizer->crop_resizer.input !=
-			   RESIZER_CROP_INPUT_NONE)
-				return -EBUSY;
-			if (ipipeif_source == IPIPEIF_OUTPUT_RESIZER)
-				resizer->crop_resizer.input =
-						RESIZER_CROP_INPUT_IPIPEIF;
-			else if (ipipe_source == IPIPE_OUTPUT_RESIZER)
-				resizer->crop_resizer.input =
-						RESIZER_CROP_INPUT_IPIPE;
-			else
-				return -EINVAL;
-			break;
-
-		case RESIZER_CROP_PAD_SOURCE | 2 << 16:
-			if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-				resizer->crop_resizer.output =
-				RESIZER_CROP_OUTPUT_NONE;
-				break;
-			}
-			if (resizer->crop_resizer.output !=
-			    RESIZER_CROP_OUTPUT_NONE)
-				return -EBUSY;
-			resizer->crop_resizer.output = RESIZER_A;
-			break;
-
-		case RESIZER_CROP_PAD_SOURCE2 | 2 << 16:
-			if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-				resizer->crop_resizer.output2 =
-					RESIZER_CROP_OUTPUT_NONE;
-				break;
-			}
-			if (resizer->crop_resizer.output2 !=
-			    RESIZER_CROP_OUTPUT_NONE)
-				return -EBUSY;
-			resizer->crop_resizer.output2 = RESIZER_B;
-			break;
-
-		default:
-			return -EINVAL;
-		}
-	} else if (&resizer->resizer_a.subdev == sd) {
-		switch (index) {
-		case RESIZER_PAD_SINK | 2 << 16:
-			if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-				resizer->resizer_a.input = RESIZER_INPUT_NONE;
-				break;
-			}
-			if (resizer->resizer_a.input != RESIZER_INPUT_NONE)
-				return -EBUSY;
-			resizer->resizer_a.input = RESIZER_INPUT_CROP_RESIZER;
-			break;
-
-		case RESIZER_PAD_SOURCE:
-			if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-				resizer->resizer_a.output = RESIZER_OUTPUT_NONE;
-				break;
-			}
-			if (resizer->resizer_a.output != RESIZER_OUTPUT_NONE)
-				return -EBUSY;
-			resizer->resizer_a.output = RESIZER_OUTPUT_MEMORY;
-			break;
-
-		default:
-			return -EINVAL;
-		}
-	} else if (&resizer->resizer_b.subdev == sd) {
-		switch (index) {
-		case RESIZER_PAD_SINK | 2 << 16:
-			if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-				resizer->resizer_b.input = RESIZER_INPUT_NONE;
-				break;
-			}
-			if (resizer->resizer_b.input != RESIZER_INPUT_NONE)
-				return -EBUSY;
-			resizer->resizer_b.input = RESIZER_INPUT_CROP_RESIZER;
-			break;
-
-		case RESIZER_PAD_SOURCE:
-			if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-				resizer->resizer_b.output = RESIZER_OUTPUT_NONE;
-				break;
-			}
-			if (resizer->resizer_b.output != RESIZER_OUTPUT_NONE)
-				return -EBUSY;
-			resizer->resizer_b.output = RESIZER_OUTPUT_MEMORY;
-			break;
-
-		default:
-			return -EINVAL;
-		}
-	} else {
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static const struct media_entity_operations resizer_media_ops = {
-	.link_setup = resizer_link_setup,
-};
-
-/*
- * vpfe_resizer_unregister_entities() - Unregister entity
- * @vpfe_rsz - pointer to resizer subdevice structure.
- */
-void vpfe_resizer_unregister_entities(struct vpfe_resizer_device *vpfe_rsz)
-{
-	/* unregister video devices */
-	vpfe_video_unregister(&vpfe_rsz->resizer_a.video_out);
-	vpfe_video_unregister(&vpfe_rsz->resizer_b.video_out);
-
-	/* 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);
-}
-
-/*
- * vpfe_resizer_register_entities() - Register entity
- * @resizer - pointer to resizer device.
- * @vdev: pointer to v4l2 device structure.
- */
-int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer,
-				   struct v4l2_device *vdev)
-{
-	struct vpfe_device *vpfe_dev = to_vpfe_device(resizer);
-	unsigned int flags = 0;
-	int ret;
-
-	/* Register the crop resizer subdev */
-	ret = v4l2_device_register_subdev(vdev, &resizer->crop_resizer.subdev);
-	if (ret < 0) {
-		pr_err("Failed to register crop resizer as v4l2-subdev\n");
-		return ret;
-	}
-	/* Register Resizer-A subdev */
-	ret = v4l2_device_register_subdev(vdev, &resizer->resizer_a.subdev);
-	if (ret < 0) {
-		pr_err("Failed to register resizer-a as v4l2-subdev\n");
-		return ret;
-	}
-	/* Register Resizer-B subdev */
-	ret = v4l2_device_register_subdev(vdev, &resizer->resizer_b.subdev);
-	if (ret < 0) {
-		pr_err("Failed to register resizer-b as v4l2-subdev\n");
-		return ret;
-	}
-	/* Register video-out device for resizer-a */
-	ret = vpfe_video_register(&resizer->resizer_a.video_out, vdev);
-	if (ret) {
-		pr_err("Failed to register RSZ-A video-out device\n");
-		goto out_video_out2_register;
-	}
-	resizer->resizer_a.video_out.vpfe_dev = vpfe_dev;
-
-	/* Register video-out device for resizer-b */
-	ret = vpfe_video_register(&resizer->resizer_b.video_out, vdev);
-	if (ret) {
-		pr_err("Failed to register RSZ-B video-out device\n");
-		goto out_video_out2_register;
-	}
-	resizer->resizer_b.video_out.vpfe_dev = vpfe_dev;
-
-	/* create link between Resizer Crop----> Resizer A*/
-	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1,
-				&resizer->resizer_a.subdev.entity,
-				0, flags);
-	if (ret < 0)
-		goto out_create_link;
-
-	/* create link between Resizer Crop----> Resizer B*/
-	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2,
-				&resizer->resizer_b.subdev.entity,
-				0, flags);
-	if (ret < 0)
-		goto out_create_link;
-
-	/* create link between Resizer A ----> video out */
-	ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1,
-		&resizer->resizer_a.video_out.video_dev.entity, 0, flags);
-	if (ret < 0)
-		goto out_create_link;
-
-	/* create link between Resizer B ----> video out */
-	ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1,
-		&resizer->resizer_b.video_out.video_dev.entity, 0, flags);
-	if (ret < 0)
-		goto out_create_link;
-
-	return 0;
-
-out_create_link:
-	vpfe_video_unregister(&resizer->resizer_b.video_out);
-out_video_out2_register:
-	vpfe_video_unregister(&resizer->resizer_a.video_out);
-	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;
-}
-
-/*
- * vpfe_resizer_init() - resizer device initialization.
- * @vpfe_rsz - pointer to resizer device
- * @pdev: platform device pointer.
- */
-int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
-		      struct platform_device *pdev)
-{
-	struct v4l2_subdev *sd = &vpfe_rsz->crop_resizer.subdev;
-	struct media_pad *pads = &vpfe_rsz->crop_resizer.pads[0];
-	struct media_entity *me = &sd->entity;
-	resource_size_t res_len;
-	struct resource *res;
-	int ret;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 5);
-	if (!res)
-		return -ENOENT;
-
-	res_len = resource_size(res);
-	res = request_mem_region(res->start, res_len, res->name);
-	if (!res)
-		return -EBUSY;
-
-	vpfe_rsz->base_addr = ioremap_nocache(res->start, res_len);
-	if (!vpfe_rsz->base_addr)
-		return -EBUSY;
-
-	v4l2_subdev_init(sd, &resizer_v4l2_ops);
-	sd->internal_ops = &resizer_v4l2_internal_ops;
-	strscpy(sd->name, "DAVINCI RESIZER CROP", sizeof(sd->name));
-	sd->grp_id = 1 << 16;	/* group ID for davinci subdevs */
-	v4l2_set_subdevdata(sd, vpfe_rsz);
-	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
-	pads[RESIZER_CROP_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-	pads[RESIZER_CROP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-	pads[RESIZER_CROP_PAD_SOURCE2].flags = MEDIA_PAD_FL_SOURCE;
-
-	vpfe_rsz->crop_resizer.input = RESIZER_CROP_INPUT_NONE;
-	vpfe_rsz->crop_resizer.output = RESIZER_CROP_OUTPUT_NONE;
-	vpfe_rsz->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE;
-	vpfe_rsz->crop_resizer.rsz_device = vpfe_rsz;
-	me->ops = &resizer_media_ops;
-	ret = media_entity_pads_init(me, RESIZER_CROP_PADS_NUM, pads);
-	if (ret)
-		return ret;
-
-	sd = &vpfe_rsz->resizer_a.subdev;
-	pads = &vpfe_rsz->resizer_a.pads[0];
-	me = &sd->entity;
-
-	v4l2_subdev_init(sd, &resizer_v4l2_ops);
-	sd->internal_ops = &resizer_v4l2_internal_ops;
-	strscpy(sd->name, "DAVINCI RESIZER A", sizeof(sd->name));
-	sd->grp_id = 1 << 16;	/* group ID for davinci subdevs */
-	v4l2_set_subdevdata(sd, vpfe_rsz);
-	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
-	pads[RESIZER_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-	pads[RESIZER_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-
-	vpfe_rsz->resizer_a.input = RESIZER_INPUT_NONE;
-	vpfe_rsz->resizer_a.output = RESIZER_OUTPUT_NONE;
-	vpfe_rsz->resizer_a.rsz_device = vpfe_rsz;
-	me->ops = &resizer_media_ops;
-	ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads);
-	if (ret)
-		return ret;
-
-	sd = &vpfe_rsz->resizer_b.subdev;
-	pads = &vpfe_rsz->resizer_b.pads[0];
-	me = &sd->entity;
-
-	v4l2_subdev_init(sd, &resizer_v4l2_ops);
-	sd->internal_ops = &resizer_v4l2_internal_ops;
-	strscpy(sd->name, "DAVINCI RESIZER B", sizeof(sd->name));
-	sd->grp_id = 1 << 16;	/* group ID for davinci subdevs */
-	v4l2_set_subdevdata(sd, vpfe_rsz);
-	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
-	pads[RESIZER_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
-	pads[RESIZER_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
-
-	vpfe_rsz->resizer_b.input = RESIZER_INPUT_NONE;
-	vpfe_rsz->resizer_b.output = RESIZER_OUTPUT_NONE;
-	vpfe_rsz->resizer_b.rsz_device = vpfe_rsz;
-	me->ops = &resizer_media_ops;
-	ret = media_entity_pads_init(me, RESIZER_PADS_NUM, pads);
-	if (ret)
-		return ret;
-
-	vpfe_rsz->resizer_a.video_out.ops = &resizer_a_video_ops;
-	vpfe_rsz->resizer_a.video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	ret = vpfe_video_init(&vpfe_rsz->resizer_a.video_out, "RSZ-A");
-	if (ret) {
-		pr_err("Failed to init RSZ video-out device\n");
-		return ret;
-	}
-	vpfe_rsz->resizer_b.video_out.ops = &resizer_b_video_ops;
-	vpfe_rsz->resizer_b.video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	ret = vpfe_video_init(&vpfe_rsz->resizer_b.video_out, "RSZ-B");
-	if (ret) {
-		pr_err("Failed to init RSZ video-out2 device\n");
-		return ret;
-	}
-	memset(&vpfe_rsz->config, 0, sizeof(struct resizer_params));
-
-	return 0;
-}
-
-void
-vpfe_resizer_cleanup(struct vpfe_resizer_device *vpfe_rsz,
-		     struct platform_device *pdev)
-{
-	struct resource *res;
-
-	iounmap(vpfe_rsz->base_addr);
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 5);
-	if (res)
-		release_mem_region(res->start,
-					resource_size(res));
-}
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.h b/drivers/staging/media/davinci_vpfe/dm365_resizer.h
deleted file mode 100644
index 5e31de9..0000000
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _DAVINCI_VPFE_DM365_RESIZER_H
-#define _DAVINCI_VPFE_DM365_RESIZER_H
-
-enum resizer_oper_mode {
-	RESIZER_MODE_CONTINUOUS = 0,
-	RESIZER_MODE_ONE_SHOT = 1,
-};
-
-struct f_div_pass {
-	unsigned int o_hsz;
-	unsigned int i_hps;
-	unsigned int h_phs;
-	unsigned int src_hps;
-	unsigned int src_hsz;
-};
-
-#define MAX_PASSES		2
-
-struct f_div_param {
-	unsigned char en;
-	unsigned int num_passes;
-	struct f_div_pass pass[MAX_PASSES];
-};
-
-/* Resizer Rescale Parameters*/
-struct resizer_scale_param {
-	bool h_flip;
-	bool v_flip;
-	bool cen;
-	bool yen;
-	unsigned short i_vps;
-	unsigned short i_hps;
-	unsigned short o_vsz;
-	unsigned short o_hsz;
-	unsigned short v_phs_y;
-	unsigned short v_phs_c;
-	unsigned short v_dif;
-	/* resize method - Luminance */
-	enum vpfe_rsz_intp_t v_typ_y;
-	/* resize method - Chrominance */
-	enum vpfe_rsz_intp_t v_typ_c;
-	/* vertical lpf intensity - Luminance */
-	unsigned char v_lpf_int_y;
-	/* vertical lpf intensity - Chrominance */
-	unsigned char v_lpf_int_c;
-	unsigned short h_phs;
-	unsigned short h_dif;
-	/* resize method - Luminance */
-	enum vpfe_rsz_intp_t h_typ_y;
-	/* resize method - Chrominance */
-	enum vpfe_rsz_intp_t h_typ_c;
-	/* horizontal lpf intensity - Luminance */
-	unsigned char h_lpf_int_y;
-	/* horizontal lpf intensity - Chrominance */
-	unsigned char h_lpf_int_c;
-	bool dscale_en;
-	enum vpfe_rsz_down_scale_ave_sz h_dscale_ave_sz;
-	enum vpfe_rsz_down_scale_ave_sz v_dscale_ave_sz;
-	/* store the calculated frame division parameter */
-	struct f_div_param f_div;
-};
-
-enum resizer_rgb_t {
-	OUTPUT_32BIT,
-	OUTPUT_16BIT
-};
-
-enum resizer_rgb_msk_t {
-	NOMASK = 0,
-	MASKLAST2 = 1,
-};
-
-/* Resizer RGB Conversion Parameters */
-struct resizer_rgb {
-	bool rgb_en;
-	enum resizer_rgb_t rgb_typ;
-	enum resizer_rgb_msk_t rgb_msk0;
-	enum resizer_rgb_msk_t rgb_msk1;
-	unsigned int rgb_alpha_val;
-};
-
-/* Resizer External Memory Parameters */
-struct rsz_ext_mem_param {
-	unsigned int rsz_sdr_oft_y;
-	unsigned int rsz_sdr_ptr_s_y;
-	unsigned int rsz_sdr_ptr_e_y;
-	unsigned int rsz_sdr_oft_c;
-	unsigned int rsz_sdr_ptr_s_c;
-	unsigned int rsz_sdr_ptr_e_c;
-	/* offset to be added to buffer start when flipping for y/ycbcr */
-	unsigned int flip_ofst_y;
-	/* offset to be added to buffer start when flipping for c */
-	unsigned int flip_ofst_c;
-	/* c offset for YUV 420SP */
-	unsigned int c_offset;
-	/* User Defined Y offset for YUV 420SP or YUV420ILE data */
-	unsigned int user_y_ofst;
-	/* User Defined C offset for YUV 420SP data */
-	unsigned int user_c_ofst;
-};
-
-enum rsz_data_source {
-	IPIPE_DATA,
-	IPIPEIF_DATA
-};
-
-enum rsz_src_img_fmt {
-	RSZ_IMG_422,
-	RSZ_IMG_420
-};
-
-enum rsz_dpaths_bypass_t {
-	BYPASS_OFF = 0,
-	BYPASS_ON = 1,
-};
-
-struct rsz_common_params {
-	unsigned int vps;
-	unsigned int vsz;
-	unsigned int hps;
-	unsigned int hsz;
-	/* 420 or 422 */
-	enum rsz_src_img_fmt src_img_fmt;
-	/* Y or C when src_fmt is 420, 0 - y, 1 - c */
-	unsigned char y_c;
-	/* flip raw or ycbcr */
-	unsigned char raw_flip;
-	/* IPIPE or IPIPEIF data */
-	enum rsz_data_source source;
-	enum rsz_dpaths_bypass_t passthrough;
-	unsigned char yuv_y_min;
-	unsigned char yuv_y_max;
-	unsigned char yuv_c_min;
-	unsigned char yuv_c_max;
-	bool rsz_seq_crv;
-	enum vpfe_chr_pos out_chr_pos;
-};
-
-struct resizer_params {
-	enum resizer_oper_mode oper_mode;
-	struct rsz_common_params rsz_common;
-	struct resizer_scale_param rsz_rsc_param[2];
-	struct resizer_rgb rsz2rgb[2];
-	struct rsz_ext_mem_param ext_mem_param[2];
-	bool rsz_en[2];
-	struct vpfe_rsz_config_params user_config;
-};
-
-#define ENABLE			1
-#define DISABLE			(!ENABLE)
-
-#define RESIZER_CROP_PAD_SINK		0
-#define RESIZER_CROP_PAD_SOURCE		1
-#define RESIZER_CROP_PAD_SOURCE2	2
-
-#define RESIZER_CROP_PADS_NUM		3
-
-enum resizer_crop_input_entity {
-	RESIZER_CROP_INPUT_NONE = 0,
-	RESIZER_CROP_INPUT_IPIPEIF = 1,
-	RESIZER_CROP_INPUT_IPIPE = 2,
-};
-
-enum resizer_crop_output_entity {
-	RESIZER_CROP_OUTPUT_NONE,
-	RESIZER_A,
-	RESIZER_B,
-};
-
-struct dm365_crop_resizer_device {
-	struct v4l2_subdev			subdev;
-	struct media_pad			pads[RESIZER_CROP_PADS_NUM];
-	struct v4l2_mbus_framefmt		formats[RESIZER_CROP_PADS_NUM];
-	enum resizer_crop_input_entity		input;
-	enum resizer_crop_output_entity		output;
-	enum resizer_crop_output_entity		output2;
-	struct vpfe_resizer_device		*rsz_device;
-};
-
-#define RESIZER_PAD_SINK		0
-#define RESIZER_PAD_SOURCE		1
-
-#define RESIZER_PADS_NUM		2
-
-enum resizer_input_entity {
-	RESIZER_INPUT_NONE = 0,
-	RESIZER_INPUT_CROP_RESIZER = 1,
-};
-
-enum resizer_output_entity {
-	RESIZER_OUTPUT_NONE = 0,
-	RESIZER_OUTPUT_MEMORY = 1,
-};
-
-struct dm365_resizer_device {
-	struct v4l2_subdev		subdev;
-	struct media_pad		pads[RESIZER_PADS_NUM];
-	struct v4l2_mbus_framefmt	formats[RESIZER_PADS_NUM];
-	enum resizer_input_entity	input;
-	enum resizer_output_entity	output;
-	struct vpfe_video_device	video_out;
-	struct vpfe_resizer_device	*rsz_device;
-};
-
-struct vpfe_resizer_device {
-	struct dm365_crop_resizer_device	crop_resizer;
-	struct dm365_resizer_device		resizer_a;
-	struct dm365_resizer_device		resizer_b;
-	struct resizer_params			config;
-	void __iomem *base_addr;
-};
-
-int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
-		      struct platform_device *pdev);
-int vpfe_resizer_register_entities(struct vpfe_resizer_device *vpfe_rsz,
-				   struct v4l2_device *v4l2_dev);
-void vpfe_resizer_unregister_entities(struct vpfe_resizer_device *vpfe_rsz);
-void vpfe_resizer_cleanup(struct vpfe_resizer_device *vpfe_rsz,
-			  struct platform_device *pdev);
-void vpfe_resizer_buffer_isr(struct vpfe_resizer_device *resizer);
-void vpfe_resizer_dma_isr(struct vpfe_resizer_device *resizer);
-
-#endif		/* _DAVINCI_VPFE_DM365_RESIZER_H */
diff --git a/drivers/staging/media/davinci_vpfe/vpfe.h b/drivers/staging/media/davinci_vpfe/vpfe.h
deleted file mode 100644
index 1f8e011..0000000
--- a/drivers/staging/media/davinci_vpfe/vpfe.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _VPFE_H
-#define _VPFE_H
-
-#ifdef __KERNEL__
-#include <linux/v4l2-subdev.h>
-#include <linux/clk.h>
-#include <linux/i2c.h>
-
-#include <media/davinci/vpfe_types.h>
-
-#define CAPTURE_DRV_NAME	"vpfe-capture"
-
-struct vpfe_route {
-	__u32 input;
-	__u32 output;
-};
-
-enum vpfe_subdev_id {
-	VPFE_SUBDEV_TVP5146 = 1,
-	VPFE_SUBDEV_MT9T031 = 2,
-	VPFE_SUBDEV_TVP7002 = 3,
-	VPFE_SUBDEV_MT9P031 = 4,
-};
-
-struct vpfe_ext_subdev_info {
-	/* v4l2 subdev */
-	struct v4l2_subdev *subdev;
-	/* Sub device module name */
-	char module_name[32];
-	/* Sub device group id */
-	int grp_id;
-	/* Number of inputs supported */
-	int num_inputs;
-	/* inputs available at the sub device */
-	struct v4l2_input *inputs;
-	/* Sub dev routing information for each input */
-	struct vpfe_route *routes;
-	/* ccdc bus/interface configuration */
-	struct vpfe_hw_if_param ccdc_if_params;
-	/* i2c subdevice board info */
-	struct i2c_board_info board_info;
-	/* Is this a camera sub device ? */
-	unsigned is_camera:1;
-	/* check if sub dev supports routing */
-	unsigned can_route:1;
-	/* registered ? */
-	unsigned registered:1;
-};
-
-struct vpfe_config {
-	/* Number of sub devices connected to vpfe */
-	int num_subdevs;
-	/* information about each subdev */
-	struct vpfe_ext_subdev_info *sub_devs;
-	/* evm card info */
-	char *card_name;
-	/* setup function for the input path */
-	int (*setup_input)(enum vpfe_subdev_id id);
-	/* number of clocks */
-	int num_clocks;
-	/* clocks used for vpfe capture */
-	char *clocks[];
-};
-#endif
-#endif
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
deleted file mode 100644
index 9dc28ff..0000000
--- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
+++ /dev/null
@@ -1,716 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- *
- *
- * Driver name : VPFE Capture driver
- *    VPFE Capture driver allows applications to capture and stream video
- *    frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
- *    TVP5146 or  Raw Bayer RGB image data from an image sensor
- *    such as Microns' MT9T001, MT9T031 etc.
- *
- *    These SoCs have, in common, a Video Processing Subsystem (VPSS) that
- *    consists of a Video Processing Front End (VPFE) for capturing
- *    video/raw image data and Video Processing Back End (VPBE) for displaying
- *    YUV data through an in-built analog encoder or Digital LCD port. This
- *    driver is for capture through VPFE. A typical EVM using these SoCs have
- *    following high level configuration.
- *
- *    decoder(TVP5146/		YUV/
- *	MT9T001)   -->  Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
- *			data input              |      |
- *							V      |
- *						      SDRAM    |
- *							       V
- *							   Image Processor
- *							       |
- *							       V
- *							     SDRAM
- *    The data flow happens from a decoder connected to the VPFE over a
- *    YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
- *    and to the input of VPFE through an optional MUX (if more inputs are
- *    to be interfaced on the EVM). The input data is first passed through
- *    CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
- *    does very little or no processing on YUV data and does pre-process Raw
- *    Bayer RGB data through modules such as Defect Pixel Correction (DFC)
- *    Color Space Conversion (CSC), data gain/offset etc. After this, data
- *    can be written to SDRAM or can be connected to the image processing
- *    block such as IPIPE (on DM355/DM365 only).
- *
- *    Features supported
- *		- MMAP IO
- *		- USERPTR IO
- *		- Capture using TVP5146 over BT.656
- *		- Support for interfacing decoders using sub device model
- *		- Work with DM365 or DM355 or DM6446 CCDC to do Raw Bayer
- *		  RGB/YUV data capture to SDRAM.
- *		- Chaining of Image Processor
- *		- SINGLE-SHOT mode
- */
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "vpfe.h"
-#include "vpfe_mc_capture.h"
-
-static bool debug;
-static bool interface;
-
-module_param(interface, bool, 0444);
-module_param(debug, bool, 0644);
-
-/*
- * VPFE capture can be used for capturing video such as from TVP5146 or TVP7002
- * and for capture raw bayer data from camera sensors such as mt9p031. At this
- * point there is problem in co-existence of mt9p031 and tvp5146 due to i2c
- * address collision. So set the variable below from bootargs to do either video
- * capture or camera capture.
- * interface = 0 - video capture (from TVP514x or such),
- * interface = 1 - Camera capture (from mt9p031 or such)
- * Re-visit this when we fix the co-existence issue
- */
-MODULE_PARM_DESC(interface, "interface 0-1 (default:0)");
-MODULE_PARM_DESC(debug, "Debug level 0-1");
-
-MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Texas Instruments");
-
-/* map mbus_fmt to pixelformat */
-void mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
-			   struct v4l2_pix_format *pix)
-{
-	switch (mbus->code) {
-	case MEDIA_BUS_FMT_UYVY8_2X8:
-		pix->pixelformat = V4L2_PIX_FMT_UYVY;
-		pix->bytesperline = pix->width * 2;
-		break;
-
-	case MEDIA_BUS_FMT_YUYV8_2X8:
-		pix->pixelformat = V4L2_PIX_FMT_YUYV;
-		pix->bytesperline = pix->width * 2;
-		break;
-
-	case MEDIA_BUS_FMT_YUYV10_1X20:
-		pix->pixelformat = V4L2_PIX_FMT_UYVY;
-		pix->bytesperline = pix->width * 2;
-		break;
-
-	case MEDIA_BUS_FMT_SGRBG12_1X12:
-		pix->pixelformat = V4L2_PIX_FMT_SBGGR16;
-		pix->bytesperline = pix->width * 2;
-		break;
-
-	case MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8:
-		pix->pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8;
-		pix->bytesperline = pix->width;
-		break;
-
-	case MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8:
-		pix->pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8;
-		pix->bytesperline = pix->width;
-		break;
-
-	case MEDIA_BUS_FMT_YDYUYDYV8_1X16:
-		pix->pixelformat = V4L2_PIX_FMT_NV12;
-		pix->bytesperline = pix->width;
-		break;
-
-	case MEDIA_BUS_FMT_Y8_1X8:
-		pix->pixelformat = V4L2_PIX_FMT_GREY;
-		pix->bytesperline = pix->width;
-		break;
-
-	case MEDIA_BUS_FMT_UV8_1X8:
-		pix->pixelformat = V4L2_PIX_FMT_UV8;
-		pix->bytesperline = pix->width;
-		break;
-
-	default:
-		pr_err("Invalid mbus code set\n");
-	}
-	/* pitch should be 32 bytes aligned */
-	pix->bytesperline = ALIGN(pix->bytesperline, 32);
-	if (pix->pixelformat == V4L2_PIX_FMT_NV12)
-		pix->sizeimage = pix->bytesperline * pix->height +
-				((pix->bytesperline * pix->height) >> 1);
-	else
-		pix->sizeimage = pix->bytesperline * pix->height;
-}
-
-/* ISR for VINT0*/
-static irqreturn_t vpfe_isr(int irq, void *dev_id)
-{
-	struct vpfe_device *vpfe_dev = dev_id;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "%s\n", __func__);
-	vpfe_isif_buffer_isr(&vpfe_dev->vpfe_isif);
-	vpfe_resizer_buffer_isr(&vpfe_dev->vpfe_resizer);
-	return IRQ_HANDLED;
-}
-
-/* vpfe_vdint1_isr() - isr handler for VINT1 interrupt */
-static irqreturn_t vpfe_vdint1_isr(int irq, void *dev_id)
-{
-	struct vpfe_device *vpfe_dev = dev_id;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "%s\n", __func__);
-	vpfe_isif_vidint1_isr(&vpfe_dev->vpfe_isif);
-	return IRQ_HANDLED;
-}
-
-/* vpfe_imp_dma_isr() - ISR for ipipe dma completion */
-static irqreturn_t vpfe_imp_dma_isr(int irq, void *dev_id)
-{
-	struct vpfe_device *vpfe_dev = dev_id;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "%s\n", __func__);
-	vpfe_ipipeif_ss_buffer_isr(&vpfe_dev->vpfe_ipipeif);
-	vpfe_resizer_dma_isr(&vpfe_dev->vpfe_resizer);
-	return IRQ_HANDLED;
-}
-
-/*
- * vpfe_disable_clock() - Disable clocks for vpfe capture driver
- * @vpfe_dev - ptr to vpfe capture device
- *
- * Disables clocks defined in vpfe configuration. The function
- * assumes that at least one clock is to be defined which is
- * true as of now.
- */
-static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
-{
-	struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
-	int i;
-
-	for (i = 0; i < vpfe_cfg->num_clocks; i++) {
-		clk_disable_unprepare(vpfe_dev->clks[i]);
-		clk_put(vpfe_dev->clks[i]);
-	}
-	kzfree(vpfe_dev->clks);
-	v4l2_info(vpfe_dev->pdev->driver, "vpfe capture clocks disabled\n");
-}
-
-/*
- * vpfe_enable_clock() - Enable clocks for vpfe capture driver
- * @vpfe_dev - ptr to vpfe capture device
- *
- * Enables clocks defined in vpfe configuration. The function
- * assumes that at least one clock is to be defined which is
- * true as of now.
- */
-static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
-{
-	struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
-	int ret = -EFAULT;
-	int i;
-
-	if (!vpfe_cfg->num_clocks)
-		return 0;
-
-	vpfe_dev->clks = kcalloc(vpfe_cfg->num_clocks,
-				 sizeof(*vpfe_dev->clks), GFP_KERNEL);
-	if (!vpfe_dev->clks)
-		return -ENOMEM;
-
-	for (i = 0; i < vpfe_cfg->num_clocks; i++) {
-		if (vpfe_cfg->clocks[i] == NULL) {
-			v4l2_err(vpfe_dev->pdev->driver,
-				"clock %s is not defined in vpfe config\n",
-				vpfe_cfg->clocks[i]);
-			goto out;
-		}
-
-		vpfe_dev->clks[i] =
-				clk_get(vpfe_dev->pdev, vpfe_cfg->clocks[i]);
-		if (IS_ERR(vpfe_dev->clks[i])) {
-			v4l2_err(vpfe_dev->pdev->driver,
-				"Failed to get clock %s\n",
-				vpfe_cfg->clocks[i]);
-			goto out;
-		}
-
-		if (clk_prepare_enable(vpfe_dev->clks[i])) {
-			v4l2_err(vpfe_dev->pdev->driver,
-				"vpfe clock %s not enabled\n",
-				vpfe_cfg->clocks[i]);
-			goto out;
-		}
-
-		v4l2_info(vpfe_dev->pdev->driver, "vpss clock %s enabled",
-			  vpfe_cfg->clocks[i]);
-	}
-
-	return 0;
-out:
-	for (i = 0; i < vpfe_cfg->num_clocks; i++)
-		if (!IS_ERR(vpfe_dev->clks[i])) {
-			clk_disable_unprepare(vpfe_dev->clks[i]);
-			clk_put(vpfe_dev->clks[i]);
-		}
-
-	v4l2_err(vpfe_dev->pdev->driver, "Failed to enable clocks\n");
-	kzfree(vpfe_dev->clks);
-
-	return ret;
-}
-
-/*
- * vpfe_detach_irq() - Detach IRQs for vpfe capture driver
- * @vpfe_dev - ptr to vpfe capture device
- *
- * Detach all IRQs defined in vpfe configuration.
- */
-static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
-{
-	free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
-	free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
-	free_irq(vpfe_dev->imp_dma_irq, vpfe_dev);
-}
-
-/*
- * vpfe_attach_irq() - Attach IRQs for vpfe capture driver
- * @vpfe_dev - ptr to vpfe capture device
- *
- * Attach all IRQs defined in vpfe configuration.
- */
-static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
-{
-	int ret;
-
-	ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, 0,
-			  "vpfe_capture0", vpfe_dev);
-	if (ret < 0) {
-		v4l2_err(&vpfe_dev->v4l2_dev,
-			"Error: requesting VINT0 interrupt\n");
-		return ret;
-	}
-
-	ret = request_irq(vpfe_dev->ccdc_irq1, vpfe_vdint1_isr, 0,
-			  "vpfe_capture1", vpfe_dev);
-	if (ret < 0) {
-		v4l2_err(&vpfe_dev->v4l2_dev,
-			"Error: requesting VINT1 interrupt\n");
-		free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
-		return ret;
-	}
-
-	ret = request_irq(vpfe_dev->imp_dma_irq, vpfe_imp_dma_isr,
-			  0, "Imp_Sdram_Irq", vpfe_dev);
-	if (ret < 0) {
-		v4l2_err(&vpfe_dev->v4l2_dev,
-			 "Error: requesting IMP IRQ interrupt\n");
-		free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
-		free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
-		return ret;
-	}
-
-	return 0;
-}
-
-/*
- * register_i2c_devices() - register all i2c v4l2 subdevs
- * @vpfe_dev - ptr to vpfe capture device
- *
- * register all i2c v4l2 subdevs
- */
-static int register_i2c_devices(struct vpfe_device *vpfe_dev)
-{
-	struct vpfe_ext_subdev_info *sdinfo;
-	struct vpfe_config *vpfe_cfg;
-	struct i2c_adapter *i2c_adap;
-	unsigned int num_subdevs;
-	int ret;
-	int i;
-	int k;
-
-	vpfe_cfg = vpfe_dev->cfg;
-	i2c_adap = i2c_get_adapter(1);
-	num_subdevs = vpfe_cfg->num_subdevs;
-	vpfe_dev->sd =
-		  kcalloc(num_subdevs, sizeof(struct v4l2_subdev *),
-			  GFP_KERNEL);
-	if (!vpfe_dev->sd)
-		return -ENOMEM;
-
-	for (i = 0, k = 0; i < num_subdevs; i++) {
-		sdinfo = &vpfe_cfg->sub_devs[i];
-		/*
-		 * register subdevices based on interface setting. Currently
-		 * tvp5146 and mt9p031 cannot co-exists due to i2c address
-		 * conflicts. So only one of them is registered. Re-visit this
-		 * once we have support for i2c switch handling in i2c driver
-		 * framework
-		 */
-		if (interface == sdinfo->is_camera) {
-			/* setup input path */
-			if (vpfe_cfg->setup_input &&
-				vpfe_cfg->setup_input(sdinfo->grp_id) < 0) {
-				ret = -EFAULT;
-				v4l2_info(&vpfe_dev->v4l2_dev,
-					  "could not setup input for %s\n",
-						sdinfo->module_name);
-				goto probe_sd_out;
-			}
-			/* Load up the subdevice */
-			vpfe_dev->sd[k] =
-				v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
-						  i2c_adap, &sdinfo->board_info,
-						  NULL);
-			if (vpfe_dev->sd[k]) {
-				v4l2_info(&vpfe_dev->v4l2_dev,
-						"v4l2 sub device %s registered\n",
-						sdinfo->module_name);
-
-				vpfe_dev->sd[k]->grp_id = sdinfo->grp_id;
-				k++;
-
-				sdinfo->registered = 1;
-			}
-		} else {
-			v4l2_info(&vpfe_dev->v4l2_dev,
-				  "v4l2 sub device %s is not registered\n",
-				  sdinfo->module_name);
-		}
-	}
-	vpfe_dev->num_ext_subdevs = k;
-
-	return 0;
-
-probe_sd_out:
-	kzfree(vpfe_dev->sd);
-
-	return ret;
-}
-
-/*
- * vpfe_register_entities() - register all v4l2 subdevs and media entities
- * @vpfe_dev - ptr to vpfe capture device
- *
- * register all v4l2 subdevs, media entities, and creates links
- * between entities
- */
-static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
-{
-	unsigned int flags = 0;
-	int ret;
-	int i;
-
-	/* register i2c devices first */
-	ret = register_i2c_devices(vpfe_dev);
-	if (ret)
-		return ret;
-
-	/* register rest of the sub-devs */
-	ret = vpfe_isif_register_entities(&vpfe_dev->vpfe_isif,
-					  &vpfe_dev->v4l2_dev);
-	if (ret)
-		return ret;
-
-	ret = vpfe_ipipeif_register_entities(&vpfe_dev->vpfe_ipipeif,
-					     &vpfe_dev->v4l2_dev);
-	if (ret)
-		goto out_isif_register;
-
-	ret = vpfe_ipipe_register_entities(&vpfe_dev->vpfe_ipipe,
-					   &vpfe_dev->v4l2_dev);
-	if (ret)
-		goto out_ipipeif_register;
-
-	ret = vpfe_resizer_register_entities(&vpfe_dev->vpfe_resizer,
-					     &vpfe_dev->v4l2_dev);
-	if (ret)
-		goto out_ipipe_register;
-
-	/* create links now, starting with external(i2c) entities */
-	for (i = 0; i < vpfe_dev->num_ext_subdevs; i++)
-		/*
-		 * if entity has no pads (ex: amplifier),
-		 * can't establish link
-		 */
-		if (vpfe_dev->sd[i]->entity.num_pads) {
-			ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
-				0, &vpfe_dev->vpfe_isif.subdev.entity,
-				0, flags);
-			if (ret < 0)
-				goto out_resizer_register;
-		}
-
-	ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
-				       &vpfe_dev->vpfe_ipipeif.subdev.entity,
-				       0, flags);
-	if (ret < 0)
-		goto out_resizer_register;
-
-	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
-				       &vpfe_dev->vpfe_ipipe.subdev.entity,
-				       0, flags);
-	if (ret < 0)
-		goto out_resizer_register;
-
-	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
-			1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
-			0, flags);
-	if (ret < 0)
-		goto out_resizer_register;
-
-	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
-			&vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
-			0, flags);
-	if (ret < 0)
-		goto out_resizer_register;
-
-	ret = v4l2_device_register_subdev_nodes(&vpfe_dev->v4l2_dev);
-	if (ret < 0)
-		goto out_resizer_register;
-
-	return 0;
-
-out_resizer_register:
-	vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
-out_ipipe_register:
-	vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
-out_ipipeif_register:
-	vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
-out_isif_register:
-	vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
-
-	return ret;
-}
-
-/*
- * vpfe_unregister_entities() - unregister all v4l2 subdevs and media entities
- * @vpfe_dev - ptr to vpfe capture device
- *
- * unregister all v4l2 subdevs and media entities
- */
-static void vpfe_unregister_entities(struct vpfe_device *vpfe_dev)
-{
-	vpfe_isif_unregister_entities(&vpfe_dev->vpfe_isif);
-	vpfe_ipipeif_unregister_entities(&vpfe_dev->vpfe_ipipeif);
-	vpfe_ipipe_unregister_entities(&vpfe_dev->vpfe_ipipe);
-	vpfe_resizer_unregister_entities(&vpfe_dev->vpfe_resizer);
-}
-
-/*
- * vpfe_cleanup_modules() - cleanup all non-i2c v4l2 subdevs
- * @vpfe_dev - ptr to vpfe capture device
- * @pdev - pointer to platform device
- *
- * cleanup all v4l2 subdevs
- */
-static void vpfe_cleanup_modules(struct vpfe_device *vpfe_dev,
-				 struct platform_device *pdev)
-{
-	vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
-	vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
-	vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
-	vpfe_resizer_cleanup(&vpfe_dev->vpfe_resizer, pdev);
-}
-
-/*
- * vpfe_initialize_modules() - initialize all non-i2c v4l2 subdevs
- * @vpfe_dev - ptr to vpfe capture device
- * @pdev - pointer to platform device
- *
- * initialize all v4l2 subdevs and media entities
- */
-static int vpfe_initialize_modules(struct vpfe_device *vpfe_dev,
-				   struct platform_device *pdev)
-{
-	int ret;
-
-	ret = vpfe_isif_init(&vpfe_dev->vpfe_isif, pdev);
-	if (ret)
-		return ret;
-
-	ret = vpfe_ipipeif_init(&vpfe_dev->vpfe_ipipeif, pdev);
-	if (ret)
-		goto out_isif_init;
-
-	ret = vpfe_ipipe_init(&vpfe_dev->vpfe_ipipe, pdev);
-	if (ret)
-		goto out_ipipeif_init;
-
-	ret = vpfe_resizer_init(&vpfe_dev->vpfe_resizer, pdev);
-	if (ret)
-		goto out_ipipe_init;
-
-	return 0;
-
-out_ipipe_init:
-	vpfe_ipipe_cleanup(&vpfe_dev->vpfe_ipipe, pdev);
-out_ipipeif_init:
-	vpfe_ipipeif_cleanup(&vpfe_dev->vpfe_ipipeif, pdev);
-out_isif_init:
-	vpfe_isif_cleanup(&vpfe_dev->vpfe_isif, pdev);
-
-	return ret;
-}
-
-/*
- * vpfe_probe() : vpfe probe function
- * @pdev: platform device pointer
- *
- * This function creates device entries by register itself to the V4L2 driver
- * and initializes fields of each device objects
- */
-static int vpfe_probe(struct platform_device *pdev)
-{
-	struct vpfe_device *vpfe_dev;
-	struct resource *res1;
-	int ret = -ENOMEM;
-
-	vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
-	if (!vpfe_dev)
-		return ret;
-
-	if (pdev->dev.platform_data == NULL) {
-		v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
-		ret = -ENOENT;
-		goto probe_free_dev_mem;
-	}
-
-	vpfe_dev->cfg = pdev->dev.platform_data;
-	if (vpfe_dev->cfg->card_name == NULL ||
-			vpfe_dev->cfg->sub_devs == NULL) {
-		v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
-		ret = -ENOENT;
-		goto probe_free_dev_mem;
-	}
-
-	/* Get VINT0 irq resource */
-	res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res1) {
-		v4l2_err(pdev->dev.driver,
-			 "Unable to get interrupt for VINT0\n");
-		ret = -ENOENT;
-		goto probe_free_dev_mem;
-	}
-	vpfe_dev->ccdc_irq0 = res1->start;
-
-	/* Get VINT1 irq resource */
-	res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
-	if (!res1) {
-		v4l2_err(pdev->dev.driver,
-			 "Unable to get interrupt for VINT1\n");
-		ret = -ENOENT;
-		goto probe_free_dev_mem;
-	}
-	vpfe_dev->ccdc_irq1 = res1->start;
-
-	/* Get DMA irq resource */
-	res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
-	if (!res1) {
-		v4l2_err(pdev->dev.driver,
-			 "Unable to get interrupt for DMA\n");
-		ret = -ENOENT;
-		goto probe_free_dev_mem;
-	}
-	vpfe_dev->imp_dma_irq = res1->start;
-
-	vpfe_dev->pdev = &pdev->dev;
-
-	/* enable vpss clocks */
-	ret = vpfe_enable_clock(vpfe_dev);
-	if (ret)
-		goto probe_free_dev_mem;
-
-	ret = vpfe_initialize_modules(vpfe_dev, pdev);
-	if (ret)
-		goto probe_disable_clock;
-
-	vpfe_dev->media_dev.dev = vpfe_dev->pdev;
-	strscpy((char *)&vpfe_dev->media_dev.model, "davinci-media",
-		sizeof(vpfe_dev->media_dev.model));
-
-	ret = media_device_register(&vpfe_dev->media_dev);
-	if (ret) {
-		v4l2_err(pdev->dev.driver,
-			"Unable to register media device.\n");
-		goto probe_out_entities_cleanup;
-	}
-
-	vpfe_dev->v4l2_dev.mdev = &vpfe_dev->media_dev;
-	ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
-	if (ret) {
-		v4l2_err(pdev->dev.driver, "Unable to register v4l2 device.\n");
-		goto probe_out_media_unregister;
-	}
-
-	v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
-	/* set the driver data in platform device */
-	platform_set_drvdata(pdev, vpfe_dev);
-	/* register subdevs/entities */
-	ret = vpfe_register_entities(vpfe_dev);
-	if (ret)
-		goto probe_out_v4l2_unregister;
-
-	ret = vpfe_attach_irq(vpfe_dev);
-	if (ret)
-		goto probe_out_entities_unregister;
-
-	return 0;
-
-probe_out_entities_unregister:
-	vpfe_unregister_entities(vpfe_dev);
-	kzfree(vpfe_dev->sd);
-probe_out_v4l2_unregister:
-	v4l2_device_unregister(&vpfe_dev->v4l2_dev);
-probe_out_media_unregister:
-	media_device_unregister(&vpfe_dev->media_dev);
-probe_out_entities_cleanup:
-	vpfe_cleanup_modules(vpfe_dev, pdev);
-probe_disable_clock:
-	vpfe_disable_clock(vpfe_dev);
-probe_free_dev_mem:
-	kzfree(vpfe_dev);
-
-	return ret;
-}
-
-/*
- * vpfe_remove : This function un-registers device from V4L2 driver
- */
-static int vpfe_remove(struct platform_device *pdev)
-{
-	struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
-
-	v4l2_info(pdev->dev.driver, "%s\n", __func__);
-
-	kzfree(vpfe_dev->sd);
-	vpfe_detach_irq(vpfe_dev);
-	vpfe_unregister_entities(vpfe_dev);
-	vpfe_cleanup_modules(vpfe_dev, pdev);
-	v4l2_device_unregister(&vpfe_dev->v4l2_dev);
-	media_device_unregister(&vpfe_dev->media_dev);
-	vpfe_disable_clock(vpfe_dev);
-	kzfree(vpfe_dev);
-
-	return 0;
-}
-
-static struct platform_driver vpfe_driver = {
-	.driver = {
-		.name = CAPTURE_DRV_NAME,
-	},
-	.probe = vpfe_probe,
-	.remove = vpfe_remove,
-};
-
-module_platform_driver(vpfe_driver);
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h
deleted file mode 100644
index fe4a421..0000000
--- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _DAVINCI_VPFE_MC_CAPTURE_H
-#define _DAVINCI_VPFE_MC_CAPTURE_H
-
-#include "dm365_ipipe.h"
-#include "dm365_ipipeif.h"
-#include "dm365_isif.h"
-#include "dm365_resizer.h"
-#include "vpfe_video.h"
-
-#define VPFE_MAJOR_RELEASE		0
-#define VPFE_MINOR_RELEASE		0
-#define VPFE_BUILD			1
-#define VPFE_CAPTURE_VERSION_CODE       ((VPFE_MAJOR_RELEASE << 16) | \
-					(VPFE_MINOR_RELEASE << 8)  | \
-					VPFE_BUILD)
-
-/* IPIPE hardware limits */
-#define IPIPE_MAX_OUTPUT_WIDTH_A	2176
-#define IPIPE_MAX_OUTPUT_WIDTH_B	640
-
-/* Based on max resolution supported. QXGA */
-#define IPIPE_MAX_OUTPUT_HEIGHT_A	1536
-/* Based on max resolution supported. VGA */
-#define IPIPE_MAX_OUTPUT_HEIGHT_B	480
-
-#define to_vpfe_device(ptr_module)				\
-	container_of(ptr_module, struct vpfe_device, vpfe_##ptr_module)
-#define to_device(ptr_module)						\
-	(to_vpfe_device(ptr_module)->dev)
-
-struct vpfe_device {
-	/* external registered sub devices */
-	struct v4l2_subdev		**sd;
-	/* number of registered external subdevs */
-	unsigned int			num_ext_subdevs;
-	/* vpfe cfg */
-	struct vpfe_config		*cfg;
-	/* clock ptrs for vpfe capture */
-	struct clk			**clks;
-	/* V4l2 device */
-	struct v4l2_device		v4l2_dev;
-	/* parent device */
-	struct device			*pdev;
-	/* IRQ number for DMA transfer completion at the image processor */
-	unsigned int			imp_dma_irq;
-	/* CCDC IRQs used when CCDC/ISIF output to SDRAM */
-	unsigned int			ccdc_irq0;
-	unsigned int			ccdc_irq1;
-	/* media device */
-	struct media_device		media_dev;
-	/* ccdc subdevice */
-	struct vpfe_isif_device		vpfe_isif;
-	/* ipipeif subdevice */
-	struct vpfe_ipipeif_device	vpfe_ipipeif;
-	/* ipipe subdevice */
-	struct vpfe_ipipe_device	vpfe_ipipe;
-	/* resizer subdevice */
-	struct vpfe_resizer_device	vpfe_resizer;
-};
-
-/* File handle structure */
-struct vpfe_fh {
-	struct v4l2_fh vfh;
-	struct vpfe_video_device *video;
-	/* Indicates whether this file handle is doing IO */
-	u8 io_allowed;
-};
-
-void mbus_to_pix(const struct v4l2_mbus_framefmt *mbus,
-			   struct v4l2_pix_format *pix);
-
-#endif		/* _DAVINCI_VPFE_MC_CAPTURE_H */
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
deleted file mode 100644
index ab6bc45..0000000
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ /dev/null
@@ -1,1646 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <media/v4l2-ioctl.h>
-
-#include "vpfe.h"
-#include "vpfe_mc_capture.h"
-
-static int debug;
-
-/* get v4l2 subdev pointer to external subdev which is active */
-static struct media_entity *vpfe_get_input_entity
-			(struct vpfe_video_device *video)
-{
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct media_pad *remote;
-
-	remote = media_entity_remote_pad(&vpfe_dev->vpfe_isif.pads[0]);
-	if (!remote) {
-		pr_err("Invalid media connection to isif/ccdc\n");
-		return NULL;
-	}
-	return remote->entity;
-}
-
-/* updates external subdev(sensor/decoder) which is active */
-static int vpfe_update_current_ext_subdev(struct vpfe_video_device *video)
-{
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_config *vpfe_cfg;
-	struct v4l2_subdev *subdev;
-	struct media_pad *remote;
-	int i;
-
-	remote = media_entity_remote_pad(&vpfe_dev->vpfe_isif.pads[0]);
-	if (!remote) {
-		pr_err("Invalid media connection to isif/ccdc\n");
-		return -EINVAL;
-	}
-
-	subdev = media_entity_to_v4l2_subdev(remote->entity);
-	vpfe_cfg = vpfe_dev->pdev->platform_data;
-	for (i = 0; i < vpfe_cfg->num_subdevs; i++) {
-		if (!strcmp(vpfe_cfg->sub_devs[i].module_name, subdev->name)) {
-			video->current_ext_subdev = &vpfe_cfg->sub_devs[i];
-			break;
-		}
-	}
-
-	/* if user not linked decoder/sensor to isif/ccdc */
-	if (i == vpfe_cfg->num_subdevs) {
-		pr_err("Invalid media chain connection to isif/ccdc\n");
-		return -EINVAL;
-	}
-	/* find the v4l2 subdev pointer */
-	for (i = 0; i < vpfe_dev->num_ext_subdevs; i++) {
-		if (!strcmp(video->current_ext_subdev->module_name,
-			vpfe_dev->sd[i]->name))
-			video->current_ext_subdev->subdev = vpfe_dev->sd[i];
-	}
-	return 0;
-}
-
-/* get the subdev which is connected to the output video node */
-static struct v4l2_subdev *
-vpfe_video_remote_subdev(struct vpfe_video_device *video, u32 *pad)
-{
-	struct media_pad *remote = media_entity_remote_pad(&video->pad);
-
-	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
-		return NULL;
-	if (pad)
-		*pad = remote->index;
-	return media_entity_to_v4l2_subdev(remote->entity);
-}
-
-/* get the format set at output pad of the adjacent subdev */
-static int
-__vpfe_video_get_format(struct vpfe_video_device *video,
-			struct v4l2_format *format)
-{
-	struct v4l2_subdev_format fmt;
-	struct v4l2_subdev *subdev;
-	struct media_pad *remote;
-	u32 pad;
-	int ret;
-
-	subdev = vpfe_video_remote_subdev(video, &pad);
-	if (!subdev)
-		return -EINVAL;
-
-	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-	remote = media_entity_remote_pad(&video->pad);
-	fmt.pad = remote->index;
-
-	ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
-	if (ret == -ENOIOCTLCMD)
-		return -EINVAL;
-
-	format->type = video->type;
-	/* convert mbus_format to v4l2_format */
-	v4l2_fill_pix_format(&format->fmt.pix, &fmt.format);
-	mbus_to_pix(&fmt.format, &format->fmt.pix);
-
-	return 0;
-}
-
-/* make a note of pipeline details */
-static int vpfe_prepare_pipeline(struct vpfe_video_device *video)
-{
-	struct media_graph graph;
-	struct media_entity *entity = &video->video_dev.entity;
-	struct media_device *mdev = entity->graph_obj.mdev;
-	struct vpfe_pipeline *pipe = &video->pipe;
-	struct vpfe_video_device *far_end = NULL;
-	int ret;
-
-	pipe->input_num = 0;
-	pipe->output_num = 0;
-
-	if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		pipe->inputs[pipe->input_num++] = video;
-	else
-		pipe->outputs[pipe->output_num++] = video;
-
-	mutex_lock(&mdev->graph_mutex);
-	ret = media_graph_walk_init(&graph, mdev);
-	if (ret) {
-		mutex_unlock(&mdev->graph_mutex);
-		return -ENOMEM;
-	}
-	media_graph_walk_start(&graph, entity);
-	while ((entity = media_graph_walk_next(&graph))) {
-		if (entity == &video->video_dev.entity)
-			continue;
-		if (!is_media_entity_v4l2_video_device(entity))
-			continue;
-		far_end = to_vpfe_video(media_entity_to_video_device(entity));
-		if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
-			pipe->inputs[pipe->input_num++] = far_end;
-		else
-			pipe->outputs[pipe->output_num++] = far_end;
-	}
-	media_graph_walk_cleanup(&graph);
-	mutex_unlock(&mdev->graph_mutex);
-
-	return 0;
-}
-
-/* update pipe state selected by user */
-static int vpfe_update_pipe_state(struct vpfe_video_device *video)
-{
-	struct vpfe_pipeline *pipe = &video->pipe;
-	int ret;
-
-	ret = vpfe_prepare_pipeline(video);
-	if (ret)
-		return ret;
-
-	/*
-	 * Find out if there is any input video
-	 * if yes, it is single shot.
-	 */
-	if (pipe->input_num == 0) {
-		pipe->state = VPFE_PIPELINE_STREAM_CONTINUOUS;
-		ret = vpfe_update_current_ext_subdev(video);
-		if (ret) {
-			pr_err("Invalid external subdev\n");
-			return ret;
-		}
-	} else {
-		pipe->state = VPFE_PIPELINE_STREAM_SINGLESHOT;
-	}
-	video->initialized = 1;
-	video->skip_frame_count = 1;
-	video->skip_frame_count_init = 1;
-	return 0;
-}
-
-/* checks whether pipeline is ready for enabling */
-int vpfe_video_is_pipe_ready(struct vpfe_pipeline *pipe)
-{
-	int i;
-
-	for (i = 0; i < pipe->input_num; i++)
-		if (!pipe->inputs[i]->started ||
-			pipe->inputs[i]->state != VPFE_VIDEO_BUFFER_QUEUED)
-			return 0;
-	for (i = 0; i < pipe->output_num; i++)
-		if (!pipe->outputs[i]->started ||
-			pipe->outputs[i]->state != VPFE_VIDEO_BUFFER_QUEUED)
-			return 0;
-	return 1;
-}
-
-/*
- * Validate a pipeline by checking both ends of all links for format
- * discrepancies.
- *
- * Return 0 if all formats match, or -EPIPE if at least one link is found with
- * different formats on its two ends.
- */
-static int vpfe_video_validate_pipeline(struct vpfe_pipeline *pipe)
-{
-	struct v4l2_subdev_format fmt_source;
-	struct v4l2_subdev_format fmt_sink;
-	struct v4l2_subdev *subdev;
-	struct media_pad *pad;
-	int ret;
-
-	/*
-	 * Should not matter if it is output[0] or 1 as
-	 * the general ideas is to traverse backwards and
-	 * the fact that the out video node always has the
-	 * format of the connected pad.
-	 */
-	subdev = vpfe_video_remote_subdev(pipe->outputs[0], NULL);
-	if (!subdev)
-		return -EPIPE;
-
-	while (1) {
-		/* Retrieve the sink format */
-		pad = &subdev->entity.pads[0];
-		if (!(pad->flags & MEDIA_PAD_FL_SINK))
-			break;
-
-		fmt_sink.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-		fmt_sink.pad = pad->index;
-		ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL,
-				       &fmt_sink);
-
-		if (ret < 0 && ret != -ENOIOCTLCMD)
-			return -EPIPE;
-
-		/* Retrieve the source format */
-		pad = media_entity_remote_pad(pad);
-		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-			break;
-
-		subdev = media_entity_to_v4l2_subdev(pad->entity);
-
-		fmt_source.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-		fmt_source.pad = pad->index;
-		ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_source);
-		if (ret < 0 && ret != -ENOIOCTLCMD)
-			return -EPIPE;
-
-		/* Check if the two ends match */
-		if (fmt_source.format.code != fmt_sink.format.code ||
-		    fmt_source.format.width != fmt_sink.format.width ||
-		    fmt_source.format.height != fmt_sink.format.height)
-			return -EPIPE;
-	}
-	return 0;
-}
-
-/*
- * vpfe_pipeline_enable() - Enable streaming on a pipeline
- * @vpfe_dev: vpfe device
- * @pipe: vpfe pipeline
- *
- * Walk the entities chain starting at the pipeline output video node and start
- * all modules in the chain in the given mode.
- *
- * Return 0 if successful, or the return value of the failed video::s_stream
- * operation otherwise.
- */
-static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
-{
-	struct media_entity *entity;
-	struct v4l2_subdev *subdev;
-	struct media_device *mdev;
-	int ret;
-
-	if (pipe->state == VPFE_PIPELINE_STREAM_CONTINUOUS)
-		entity = vpfe_get_input_entity(pipe->outputs[0]);
-	else
-		entity = &pipe->inputs[0]->video_dev.entity;
-
-	mdev = entity->graph_obj.mdev;
-	mutex_lock(&mdev->graph_mutex);
-	ret = media_graph_walk_init(&pipe->graph, mdev);
-	if (ret)
-		goto out;
-	media_graph_walk_start(&pipe->graph, entity);
-	while ((entity = media_graph_walk_next(&pipe->graph))) {
-
-		if (!is_media_entity_v4l2_subdev(entity))
-			continue;
-		subdev = media_entity_to_v4l2_subdev(entity);
-		ret = v4l2_subdev_call(subdev, video, s_stream, 1);
-		if (ret < 0 && ret != -ENOIOCTLCMD)
-			break;
-	}
-out:
-	if (ret)
-		media_graph_walk_cleanup(&pipe->graph);
-	mutex_unlock(&mdev->graph_mutex);
-	return ret;
-}
-
-/*
- * vpfe_pipeline_disable() - Disable streaming on a pipeline
- * @vpfe_dev: vpfe device
- * @pipe: VPFE pipeline
- *
- * Walk the entities chain starting at the pipeline output video node and stop
- * all modules in the chain.
- *
- * Return 0 if all modules have been properly stopped, or -ETIMEDOUT if a module
- * can't be stopped.
- */
-static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
-{
-	struct media_entity *entity;
-	struct v4l2_subdev *subdev;
-	struct media_device *mdev;
-	int ret = 0;
-
-	if (pipe->state == VPFE_PIPELINE_STREAM_CONTINUOUS)
-		entity = vpfe_get_input_entity(pipe->outputs[0]);
-	else
-		entity = &pipe->inputs[0]->video_dev.entity;
-
-	mdev = entity->graph_obj.mdev;
-	mutex_lock(&mdev->graph_mutex);
-	media_graph_walk_start(&pipe->graph, entity);
-
-	while ((entity = media_graph_walk_next(&pipe->graph))) {
-
-		if (!is_media_entity_v4l2_subdev(entity))
-			continue;
-		subdev = media_entity_to_v4l2_subdev(entity);
-		ret = v4l2_subdev_call(subdev, video, s_stream, 0);
-		if (ret < 0 && ret != -ENOIOCTLCMD)
-			break;
-	}
-	mutex_unlock(&mdev->graph_mutex);
-
-	media_graph_walk_cleanup(&pipe->graph);
-	return ret ? -ETIMEDOUT : 0;
-}
-
-/*
- * vpfe_pipeline_set_stream() - Enable/disable streaming on a pipeline
- * @vpfe_dev: VPFE device
- * @pipe: VPFE pipeline
- * @state: Stream state (stopped or active)
- *
- * Set the pipeline to the given stream state.
- *
- * Return 0 if successful, or the return value of the failed video::s_stream
- * operation otherwise.
- */
-static int vpfe_pipeline_set_stream(struct vpfe_pipeline *pipe,
-			    enum vpfe_pipeline_stream_state state)
-{
-	if (state == VPFE_PIPELINE_STREAM_STOPPED)
-		return vpfe_pipeline_disable(pipe);
-
-	return vpfe_pipeline_enable(pipe);
-}
-
-static int all_videos_stopped(struct vpfe_video_device *video)
-{
-	struct vpfe_pipeline *pipe = &video->pipe;
-	int i;
-
-	for (i = 0; i < pipe->input_num; i++)
-		if (pipe->inputs[i]->started)
-			return 0;
-	for (i = 0; i < pipe->output_num; i++)
-		if (pipe->outputs[i]->started)
-			return 0;
-	return 1;
-}
-
-/*
- * vpfe_open() - open video device
- * @file: file pointer
- *
- * initialize media pipeline state, allocate memory for file handle
- *
- * Return 0 if successful, or the return -ENODEV otherwise.
- */
-static int vpfe_open(struct file *file)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_fh *handle;
-
-	/* Allocate memory for the file handle object */
-	handle = kzalloc(sizeof(struct vpfe_fh), GFP_KERNEL);
-
-	if (!handle)
-		return -ENOMEM;
-
-	v4l2_fh_init(&handle->vfh, &video->video_dev);
-	v4l2_fh_add(&handle->vfh);
-
-	mutex_lock(&video->lock);
-	/* If decoder is not initialized. initialize it */
-	if (!video->initialized && vpfe_update_pipe_state(video)) {
-		mutex_unlock(&video->lock);
-		v4l2_fh_del(&handle->vfh);
-		v4l2_fh_exit(&handle->vfh);
-		kfree(handle);
-		return -ENODEV;
-	}
-	/* Increment device users counter */
-	video->usrs++;
-	/* Set io_allowed member to false */
-	handle->io_allowed = 0;
-	handle->video = video;
-	file->private_data = &handle->vfh;
-	mutex_unlock(&video->lock);
-
-	return 0;
-}
-
-/* get the next buffer available from dma queue */
-static unsigned long
-vpfe_video_get_next_buffer(struct vpfe_video_device *video)
-{
-	video->cur_frm = video->next_frm =
-		list_entry(video->dma_queue.next,
-			   struct vpfe_cap_buffer, list);
-
-	list_del(&video->next_frm->list);
-	video->next_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
-	return vb2_dma_contig_plane_dma_addr(&video->next_frm->vb.vb2_buf, 0);
-}
-
-/* schedule the next buffer which is available on dma queue */
-void vpfe_video_schedule_next_buffer(struct vpfe_video_device *video)
-{
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	unsigned long addr;
-
-	if (list_empty(&video->dma_queue))
-		return;
-
-	video->next_frm = list_entry(video->dma_queue.next,
-					struct vpfe_cap_buffer, list);
-
-	if (video->pipe.state == VPFE_PIPELINE_STREAM_SINGLESHOT)
-		video->cur_frm = video->next_frm;
-
-	list_del(&video->next_frm->list);
-	video->next_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
-	addr = vb2_dma_contig_plane_dma_addr(&video->next_frm->vb.vb2_buf, 0);
-	video->ops->queue(vpfe_dev, addr);
-	video->state = VPFE_VIDEO_BUFFER_QUEUED;
-}
-
-/* schedule the buffer for capturing bottom field */
-void vpfe_video_schedule_bottom_field(struct vpfe_video_device *video)
-{
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	unsigned long addr;
-
-	addr = vb2_dma_contig_plane_dma_addr(&video->cur_frm->vb.vb2_buf, 0);
-	addr += video->field_off;
-	video->ops->queue(vpfe_dev, addr);
-}
-
-/* make buffer available for dequeue */
-void vpfe_video_process_buffer_complete(struct vpfe_video_device *video)
-{
-	struct vpfe_pipeline *pipe = &video->pipe;
-
-	video->cur_frm->vb.vb2_buf.timestamp = ktime_get_ns();
-	vb2_buffer_done(&video->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
-	if (pipe->state == VPFE_PIPELINE_STREAM_CONTINUOUS)
-		video->cur_frm = video->next_frm;
-}
-
-/* vpfe_stop_capture() - stop streaming */
-static void vpfe_stop_capture(struct vpfe_video_device *video)
-{
-	struct vpfe_pipeline *pipe = &video->pipe;
-
-	video->started = 0;
-
-	if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
-		return;
-	if (all_videos_stopped(video))
-		vpfe_pipeline_set_stream(pipe,
-					 VPFE_PIPELINE_STREAM_STOPPED);
-}
-
-/*
- * vpfe_release() - release video device
- * @file: file pointer
- *
- * deletes buffer queue, frees the buffers and the vpfe file handle
- *
- * Return 0
- */
-static int vpfe_release(struct file *file)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct v4l2_fh *vfh = file->private_data;
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_fh *fh = container_of(vfh, struct vpfe_fh, vfh);
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_release\n");
-
-	/* Get the device lock */
-	mutex_lock(&video->lock);
-	/* if this instance is doing IO */
-	if (fh->io_allowed) {
-		if (video->started) {
-			vpfe_stop_capture(video);
-			/*
-			 * mark pipe state as stopped in vpfe_release(),
-			 * as app might call streamon() after streamoff()
-			 * in which case driver has to start streaming.
-			 */
-			video->pipe.state = VPFE_PIPELINE_STREAM_STOPPED;
-			vb2_streamoff(&video->buffer_queue,
-				      video->buffer_queue.type);
-		}
-		video->io_usrs = 0;
-		/* Free buffers allocated */
-		vb2_queue_release(&video->buffer_queue);
-	}
-	/* Decrement device users counter */
-	video->usrs--;
-	v4l2_fh_del(&fh->vfh);
-	v4l2_fh_exit(&fh->vfh);
-	/* If this is the last file handle */
-	if (!video->usrs)
-		video->initialized = 0;
-	mutex_unlock(&video->lock);
-	file->private_data = NULL;
-	/* Free memory allocated to file handle object */
-	v4l2_fh_del(vfh);
-	kzfree(fh);
-	return 0;
-}
-
-/*
- * vpfe_mmap() - It is used to map kernel space buffers
- * into user spaces
- */
-static int vpfe_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_mmap\n");
-	return vb2_mmap(&video->buffer_queue, vma);
-}
-
-/*
- * vpfe_poll() - It is used for select/poll system call
- */
-static __poll_t vpfe_poll(struct file *file, poll_table *wait)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_poll\n");
-	if (video->started)
-		return vb2_poll(&video->buffer_queue, file, wait);
-	return 0;
-}
-
-/* vpfe capture driver file operations */
-static const struct v4l2_file_operations vpfe_fops = {
-	.owner = THIS_MODULE,
-	.open = vpfe_open,
-	.release = vpfe_release,
-	.unlocked_ioctl = video_ioctl2,
-	.mmap = vpfe_mmap,
-	.poll = vpfe_poll
-};
-
-/*
- * vpfe_querycap() - query capabilities of video device
- * @file: file pointer
- * @priv: void pointer
- * @cap: pointer to v4l2_capability structure
- *
- * fills v4l2 capabilities structure
- *
- * Return 0
- */
-static int vpfe_querycap(struct file *file, void  *priv,
-			       struct v4l2_capability *cap)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n");
-
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
-			    V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS;
-	strscpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
-	strscpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
-	strscpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
-
-	return 0;
-}
-
-/*
- * vpfe_g_fmt() - get the format which is active on video device
- * @file: file pointer
- * @priv: void pointer
- * @fmt: pointer to v4l2_format structure
- *
- * fills v4l2 format structure with active format
- *
- * Return 0
- */
-static int vpfe_g_fmt(struct file *file, void *priv,
-				struct v4l2_format *fmt)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt\n");
-	/* Fill in the information about format */
-	*fmt = video->fmt;
-	return 0;
-}
-
-/*
- * vpfe_enum_fmt() - enum formats supported on media chain
- * @file: file pointer
- * @priv: void pointer
- * @fmt: pointer to v4l2_fmtdesc structure
- *
- * fills v4l2_fmtdesc structure with output format set on adjacent subdev,
- * only one format is enumearted as subdevs are already configured
- *
- * Return 0 if successful, error code otherwise
- */
-static int vpfe_enum_fmt(struct file *file, void  *priv,
-				   struct v4l2_fmtdesc *fmt)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct v4l2_subdev_format sd_fmt;
-	struct v4l2_mbus_framefmt mbus;
-	struct v4l2_subdev *subdev;
-	struct v4l2_format format;
-	struct media_pad *remote;
-	int ret;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt\n");
-
-	/*
-	 * since already subdev pad format is set,
-	 * only one pixel format is available
-	 */
-	if (fmt->index > 0) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid index\n");
-		return -EINVAL;
-	}
-	/* get the remote pad */
-	remote = media_entity_remote_pad(&video->pad);
-	if (!remote) {
-		v4l2_err(&vpfe_dev->v4l2_dev,
-			 "invalid remote pad for video node\n");
-		return -EINVAL;
-	}
-	/* get the remote subdev */
-	subdev = vpfe_video_remote_subdev(video, NULL);
-	if (!subdev) {
-		v4l2_err(&vpfe_dev->v4l2_dev,
-			 "invalid remote subdev for video node\n");
-		return -EINVAL;
-	}
-	sd_fmt.pad = remote->index;
-	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-	/* get output format of remote subdev */
-	ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &sd_fmt);
-	if (ret) {
-		v4l2_err(&vpfe_dev->v4l2_dev,
-			 "invalid remote subdev for video node\n");
-		return ret;
-	}
-	/* convert to pix format */
-	mbus.code = sd_fmt.format.code;
-	mbus_to_pix(&mbus, &format.fmt.pix);
-	/* copy the result */
-	fmt->pixelformat = format.fmt.pix.pixelformat;
-
-	return 0;
-}
-
-/*
- * vpfe_s_fmt() - set the format on video device
- * @file: file pointer
- * @priv: void pointer
- * @fmt: pointer to v4l2_format structure
- *
- * validate and set the format on video device
- *
- * Return 0 on success, error code otherwise
- */
-static int vpfe_s_fmt(struct file *file, void *priv,
-				struct v4l2_format *fmt)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct v4l2_format format;
-	int ret;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt\n");
-	/* If streaming is started, return error */
-	if (video->started) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is started\n");
-		return -EBUSY;
-	}
-	/* get adjacent subdev's output pad format */
-	ret = __vpfe_video_get_format(video, &format);
-	if (ret)
-		return ret;
-	*fmt = format;
-	video->fmt = *fmt;
-	return 0;
-}
-
-/*
- * vpfe_try_fmt() - try the format on video device
- * @file: file pointer
- * @priv: void pointer
- * @fmt: pointer to v4l2_format structure
- *
- * validate the format, update with correct format
- * based on output format set on adjacent subdev
- *
- * Return 0 on success, error code otherwise
- */
-static int vpfe_try_fmt(struct file *file, void *priv,
-				  struct v4l2_format *fmt)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct v4l2_format format;
-	int ret;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt\n");
-	/* get adjacent subdev's output pad format */
-	ret = __vpfe_video_get_format(video, &format);
-	if (ret)
-		return ret;
-
-	*fmt = format;
-	return 0;
-}
-
-/*
- * vpfe_enum_input() - enum inputs supported on media chain
- * @file: file pointer
- * @priv: void pointer
- * @fmt: pointer to v4l2_fmtdesc structure
- *
- * fills v4l2_input structure with input available on media chain,
- * only one input is enumearted as media chain is setup by this time
- *
- * Return 0 if successful, -EINVAL is media chain is invalid
- */
-static int vpfe_enum_input(struct file *file, void *priv,
-				 struct v4l2_input *inp)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_ext_subdev_info *sdinfo = video->current_ext_subdev;
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_input\n");
-	/* enumerate from the subdev user has chosen through mc */
-	if (inp->index < sdinfo->num_inputs) {
-		memcpy(inp, &sdinfo->inputs[inp->index],
-		       sizeof(struct v4l2_input));
-		return 0;
-	}
-	return -EINVAL;
-}
-
-/*
- * vpfe_g_input() - get index of the input which is active
- * @file: file pointer
- * @priv: void pointer
- * @index: pointer to unsigned int
- *
- * set index with input index which is active
- */
-static int vpfe_g_input(struct file *file, void *priv, unsigned int *index)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_input\n");
-
-	*index = video->current_input;
-	return 0;
-}
-
-/*
- * vpfe_s_input() - set input which is pointed by input index
- * @file: file pointer
- * @priv: void pointer
- * @index: pointer to unsigned int
- *
- * set input on external subdev
- *
- * Return 0 on success, error code otherwise
- */
-static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_ext_subdev_info *sdinfo;
-	struct vpfe_route *route;
-	struct v4l2_input *inps;
-	u32 output;
-	u32 input;
-	int ret;
-	int i;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n");
-
-	ret = mutex_lock_interruptible(&video->lock);
-	if (ret)
-		return ret;
-	/*
-	 * If streaming is started return device busy
-	 * error
-	 */
-	if (video->started) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is on\n");
-		ret = -EBUSY;
-		goto unlock_out;
-	}
-
-	sdinfo = video->current_ext_subdev;
-	if (!sdinfo->registered) {
-		ret = -EINVAL;
-		goto unlock_out;
-	}
-	if (vpfe_dev->cfg->setup_input &&
-		vpfe_dev->cfg->setup_input(sdinfo->grp_id) < 0) {
-		ret = -EFAULT;
-		v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
-			  "couldn't setup input for %s\n",
-			  sdinfo->module_name);
-		goto unlock_out;
-	}
-	route = &sdinfo->routes[index];
-	if (route && sdinfo->can_route) {
-		input = route->input;
-		output = route->output;
-		ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
-						 sdinfo->grp_id, video,
-						 s_routing, input, output, 0);
-		if (ret) {
-			v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
-				"s_input:error in setting input in decoder\n");
-			ret = -EINVAL;
-			goto unlock_out;
-		}
-	}
-	/* set standards set by subdev in video device */
-	for (i = 0; i < sdinfo->num_inputs; i++) {
-		inps = &sdinfo->inputs[i];
-		video->video_dev.tvnorms |= inps->std;
-	}
-	video->current_input = index;
-unlock_out:
-	mutex_unlock(&video->lock);
-	return ret;
-}
-
-/*
- * vpfe_querystd() - query std which is being input on external subdev
- * @file: file pointer
- * @priv: void pointer
- * @std_id: pointer to v4l2_std_id structure
- *
- * call external subdev through v4l2_device_call_until_err to
- * get the std that is being active.
- *
- * Return 0 on success, error code otherwise
- */
-static int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_ext_subdev_info *sdinfo;
-	int ret;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n");
-
-	ret = mutex_lock_interruptible(&video->lock);
-	sdinfo = video->current_ext_subdev;
-	if (ret)
-		return ret;
-	/* Call querystd function of decoder device */
-	ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-					 video, querystd, std_id);
-	mutex_unlock(&video->lock);
-	return ret;
-}
-
-/*
- * vpfe_s_std() - set std on external subdev
- * @file: file pointer
- * @priv: void pointer
- * @std_id: pointer to v4l2_std_id structure
- *
- * set std pointed by std_id on external subdev by calling it using
- * v4l2_device_call_until_err
- *
- * Return 0 on success, error code otherwise
- */
-static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id std_id)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_ext_subdev_info *sdinfo;
-	int ret;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n");
-
-	/* Call decoder driver function to set the standard */
-	ret = mutex_lock_interruptible(&video->lock);
-	if (ret)
-		return ret;
-	sdinfo = video->current_ext_subdev;
-	/* If streaming is started, return device busy error */
-	if (video->started) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "streaming is started\n");
-		ret = -EBUSY;
-		goto unlock_out;
-	}
-	ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
-					 video, s_std, std_id);
-	if (ret < 0) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
-		video->stdid = V4L2_STD_UNKNOWN;
-		goto unlock_out;
-	}
-	video->stdid = std_id;
-unlock_out:
-	mutex_unlock(&video->lock);
-	return ret;
-}
-
-static int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_std\n");
-	*tvnorm = video->stdid;
-	return 0;
-}
-
-/*
- * vpfe_enum_dv_timings() - enumerate dv_timings which are supported by
- *			to external subdev
- * @file: file pointer
- * @priv: void pointer
- * @timings: pointer to v4l2_enum_dv_timings structure
- *
- * enum dv_timings's which are supported by external subdev through
- * v4l2_subdev_call
- *
- * Return 0 on success, error code otherwise
- */
-static int
-vpfe_enum_dv_timings(struct file *file, void *fh,
-		  struct v4l2_enum_dv_timings *timings)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct v4l2_subdev *subdev = video->current_ext_subdev->subdev;
-
-	timings->pad = 0;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_dv_timings\n");
-	return v4l2_subdev_call(subdev, pad, enum_dv_timings, timings);
-}
-
-/*
- * vpfe_query_dv_timings() - query the dv_timings which is being input
- *			to external subdev
- * @file: file pointer
- * @priv: void pointer
- * @timings: pointer to v4l2_dv_timings structure
- *
- * get dv_timings which is being input on external subdev through
- * v4l2_subdev_call
- *
- * Return 0 on success, error code otherwise
- */
-static int
-vpfe_query_dv_timings(struct file *file, void *fh,
-		   struct v4l2_dv_timings *timings)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct v4l2_subdev *subdev = video->current_ext_subdev->subdev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_query_dv_timings\n");
-	return v4l2_subdev_call(subdev, video, query_dv_timings, timings);
-}
-
-/*
- * vpfe_s_dv_timings() - set dv_timings on external subdev
- * @file: file pointer
- * @priv: void pointer
- * @timings: pointer to v4l2_dv_timings structure
- *
- * set dv_timings pointed by timings on external subdev through
- * v4l2_device_call_until_err, this configures amplifier also
- *
- * Return 0 on success, error code otherwise
- */
-static int
-vpfe_s_dv_timings(struct file *file, void *fh,
-		  struct v4l2_dv_timings *timings)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_dv_timings\n");
-
-	video->stdid = V4L2_STD_UNKNOWN;
-	return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
-					  video->current_ext_subdev->grp_id,
-					  video, s_dv_timings, timings);
-}
-
-/*
- * vpfe_g_dv_timings() - get dv_timings which is set on external subdev
- * @file: file pointer
- * @priv: void pointer
- * @timings: pointer to v4l2_dv_timings structure
- *
- * get dv_timings which is set on external subdev through
- * v4l2_subdev_call
- *
- * Return 0 on success, error code otherwise
- */
-static int
-vpfe_g_dv_timings(struct file *file, void *fh,
-	      struct v4l2_dv_timings *timings)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct v4l2_subdev *subdev = video->current_ext_subdev->subdev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_dv_timings\n");
-	return v4l2_subdev_call(subdev, video, g_dv_timings, timings);
-}
-
-/*
- *  Videobuf operations
- */
-/*
- * vpfe_buffer_queue_setup : Callback function for buffer setup.
- * @vq: vb2_queue ptr
- * @fmt: v4l2 format
- * @nbuffers: ptr to number of buffers requested by application
- * @nplanes:: contains number of distinct video planes needed to hold a frame
- * @sizes[]: contains the size (in bytes) of each plane.
- * @alloc_devs: ptr to allocation context
- *
- * This callback function is called when reqbuf() is called to adjust
- * the buffer nbuffers and buffer size
- */
-static int
-vpfe_buffer_queue_setup(struct vb2_queue *vq,
-			unsigned int *nbuffers, unsigned int *nplanes,
-			unsigned int sizes[], struct device *alloc_devs[])
-{
-	struct vpfe_fh *fh = vb2_get_drv_priv(vq);
-	struct vpfe_video_device *video = fh->video;
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	unsigned long size;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue_setup\n");
-	size = video->fmt.fmt.pix.sizeimage;
-
-	if (vq->num_buffers + *nbuffers < 3)
-		*nbuffers = 3 - vq->num_buffers;
-
-	*nplanes = 1;
-	sizes[0] = size;
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
-		 "nbuffers=%d, size=%lu\n", *nbuffers, size);
-	return 0;
-}
-
-/*
- * vpfe_buffer_prepare : callback function for buffer prepare
- * @vb: ptr to vb2_buffer
- *
- * This is the callback function for buffer prepare when vb2_qbuf()
- * function is called. The buffer is prepared and user space virtual address
- * or user address is converted into  physical address
- */
-static int vpfe_buffer_prepare(struct vb2_buffer *vb)
-{
-	struct vpfe_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
-	struct vpfe_video_device *video = fh->video;
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	unsigned long addr;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
-
-	/* Initialize buffer */
-	vb2_set_plane_payload(vb, 0, video->fmt.fmt.pix.sizeimage);
-	if (vb2_plane_vaddr(vb, 0) &&
-	    vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
-		return -EINVAL;
-
-	addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-	/* Make sure user addresses are aligned to 32 bytes */
-	if (!ALIGN(addr, 32))
-		return -EINVAL;
-
-	return 0;
-}
-
-static void vpfe_buffer_queue(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	/* Get the file handle object and device object */
-	struct vpfe_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
-	struct vpfe_video_device *video = fh->video;
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_pipeline *pipe = &video->pipe;
-	struct vpfe_cap_buffer *buf = container_of(vbuf,
-				struct vpfe_cap_buffer, vb);
-	unsigned long flags;
-	unsigned long empty;
-	unsigned long addr;
-
-	spin_lock_irqsave(&video->dma_queue_lock, flags);
-	empty = list_empty(&video->dma_queue);
-	/* add the buffer to the DMA queue */
-	list_add_tail(&buf->list, &video->dma_queue);
-	spin_unlock_irqrestore(&video->dma_queue_lock, flags);
-	/* this case happens in case of single shot */
-	if (empty && video->started && pipe->state ==
-		VPFE_PIPELINE_STREAM_SINGLESHOT &&
-		video->state == VPFE_VIDEO_BUFFER_NOT_QUEUED) {
-		spin_lock(&video->dma_queue_lock);
-		addr = vpfe_video_get_next_buffer(video);
-		video->ops->queue(vpfe_dev, addr);
-
-		video->state = VPFE_VIDEO_BUFFER_QUEUED;
-		spin_unlock(&video->dma_queue_lock);
-
-		/* enable h/w each time in single shot */
-		if (vpfe_video_is_pipe_ready(pipe))
-			vpfe_pipeline_set_stream(pipe,
-					VPFE_PIPELINE_STREAM_SINGLESHOT);
-	}
-}
-
-/* vpfe_start_capture() - start streaming on all the subdevs */
-static int vpfe_start_capture(struct vpfe_video_device *video)
-{
-	struct vpfe_pipeline *pipe = &video->pipe;
-	int ret = 0;
-
-	video->started = 1;
-	if (vpfe_video_is_pipe_ready(pipe))
-		ret = vpfe_pipeline_set_stream(pipe, pipe->state);
-
-	return ret;
-}
-
-static int vpfe_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
-	struct vpfe_fh *fh = vb2_get_drv_priv(vq);
-	struct vpfe_video_device *video = fh->video;
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	unsigned long addr;
-	int ret;
-
-	ret = mutex_lock_interruptible(&video->lock);
-	if (ret)
-		goto streamoff;
-
-	/* Get the next frame from the buffer queue */
-	video->cur_frm = video->next_frm =
-		list_entry(video->dma_queue.next, struct vpfe_cap_buffer, list);
-	/* Remove buffer from the buffer queue */
-	list_del(&video->cur_frm->list);
-	/* Mark state of the current frame to active */
-	video->cur_frm->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
-	/* Initialize field_id and started member */
-	video->field_id = 0;
-	addr = vb2_dma_contig_plane_dma_addr(&video->cur_frm->vb.vb2_buf, 0);
-	video->ops->queue(vpfe_dev, addr);
-	video->state = VPFE_VIDEO_BUFFER_QUEUED;
-
-	ret = vpfe_start_capture(video);
-	if (ret) {
-		struct vpfe_cap_buffer *buf, *tmp;
-
-		vb2_buffer_done(&video->cur_frm->vb.vb2_buf,
-				VB2_BUF_STATE_QUEUED);
-		list_for_each_entry_safe(buf, tmp, &video->dma_queue, list) {
-			list_del(&buf->list);
-			vb2_buffer_done(&buf->vb.vb2_buf,
-					VB2_BUF_STATE_QUEUED);
-		}
-		goto unlock_out;
-	}
-
-	mutex_unlock(&video->lock);
-
-	return ret;
-unlock_out:
-	mutex_unlock(&video->lock);
-streamoff:
-	ret = vb2_streamoff(&video->buffer_queue, video->buffer_queue.type);
-	return 0;
-}
-
-static int vpfe_buffer_init(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vpfe_cap_buffer *buf = container_of(vbuf,
-						   struct vpfe_cap_buffer, vb);
-
-	INIT_LIST_HEAD(&buf->list);
-	return 0;
-}
-
-/* abort streaming and wait for last buffer */
-static void vpfe_stop_streaming(struct vb2_queue *vq)
-{
-	struct vpfe_fh *fh = vb2_get_drv_priv(vq);
-	struct vpfe_video_device *video = fh->video;
-
-	/* release all active buffers */
-	if (video->cur_frm == video->next_frm) {
-		vb2_buffer_done(&video->cur_frm->vb.vb2_buf,
-				VB2_BUF_STATE_ERROR);
-	} else {
-		if (video->cur_frm != NULL)
-			vb2_buffer_done(&video->cur_frm->vb.vb2_buf,
-					VB2_BUF_STATE_ERROR);
-		if (video->next_frm != NULL)
-			vb2_buffer_done(&video->next_frm->vb.vb2_buf,
-					VB2_BUF_STATE_ERROR);
-	}
-
-	while (!list_empty(&video->dma_queue)) {
-		video->next_frm = list_entry(video->dma_queue.next,
-						struct vpfe_cap_buffer, list);
-		list_del(&video->next_frm->list);
-		vb2_buffer_done(&video->next_frm->vb.vb2_buf,
-				VB2_BUF_STATE_ERROR);
-	}
-}
-
-static void vpfe_buf_cleanup(struct vb2_buffer *vb)
-{
-	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
-	struct vpfe_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
-	struct vpfe_video_device *video = fh->video;
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_cap_buffer *buf = container_of(vbuf,
-					struct vpfe_cap_buffer, vb);
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buf_cleanup\n");
-	if (vb->state == VB2_BUF_STATE_ACTIVE)
-		list_del_init(&buf->list);
-}
-
-static const struct vb2_ops video_qops = {
-	.queue_setup		= vpfe_buffer_queue_setup,
-	.buf_init		= vpfe_buffer_init,
-	.buf_prepare		= vpfe_buffer_prepare,
-	.start_streaming	= vpfe_start_streaming,
-	.stop_streaming		= vpfe_stop_streaming,
-	.buf_cleanup		= vpfe_buf_cleanup,
-	.buf_queue		= vpfe_buffer_queue,
-	.wait_prepare		= vb2_ops_wait_prepare,
-	.wait_finish		= vb2_ops_wait_finish,
-};
-
-/*
- * vpfe_reqbufs() - supported REQBUF only once opening
- * the device.
- */
-static int vpfe_reqbufs(struct file *file, void *priv,
-			struct v4l2_requestbuffers *req_buf)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_fh *fh = file->private_data;
-	struct vb2_queue *q;
-	int ret;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n");
-
-	if (req_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-	    req_buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT){
-		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buffer type\n");
-		return -EINVAL;
-	}
-
-	ret = mutex_lock_interruptible(&video->lock);
-	if (ret)
-		return ret;
-
-	if (video->io_usrs != 0) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n");
-		ret = -EBUSY;
-		goto unlock_out;
-	}
-	video->memory = req_buf->memory;
-
-	/* Initialize videobuf2 queue as per the buffer type */
-	q = &video->buffer_queue;
-	q->type = req_buf->type;
-	q->io_modes = VB2_MMAP | VB2_USERPTR;
-	q->drv_priv = fh;
-	q->min_buffers_needed = 1;
-	q->ops = &video_qops;
-	q->mem_ops = &vb2_dma_contig_memops;
-	q->buf_struct_size = sizeof(struct vpfe_cap_buffer);
-	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
-	q->dev = vpfe_dev->pdev;
-	q->lock = &video->lock;
-
-	ret = vb2_queue_init(q);
-	if (ret) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "vb2_queue_init() failed\n");
-		goto unlock_out;
-	}
-
-	fh->io_allowed = 1;
-	video->io_usrs = 1;
-	INIT_LIST_HEAD(&video->dma_queue);
-	ret = vb2_reqbufs(&video->buffer_queue, req_buf);
-
-unlock_out:
-	mutex_unlock(&video->lock);
-	return ret;
-}
-
-/*
- * vpfe_querybuf() - query buffers for exchange
- */
-static int vpfe_querybuf(struct file *file, void *priv,
-			 struct v4l2_buffer *buf)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querybuf\n");
-
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-	    buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
-		return  -EINVAL;
-	}
-
-	if (video->memory != V4L2_MEMORY_MMAP) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid memory\n");
-		return -EINVAL;
-	}
-
-	/* Call vb2_querybuf to get information */
-	return vb2_querybuf(&video->buffer_queue, buf);
-}
-
-/*
- * vpfe_qbuf() - queue buffers for capture or processing
- */
-static int vpfe_qbuf(struct file *file, void *priv,
-		     struct v4l2_buffer *p)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_fh *fh = file->private_data;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_qbuf\n");
-
-	if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-	    p->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
-		return -EINVAL;
-	}
-	/*
-	 * If this file handle is not allowed to do IO,
-	 * return error
-	 */
-	if (!fh->io_allowed) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
-		return -EACCES;
-	}
-
-	return vb2_qbuf(&video->buffer_queue,
-			video->video_dev.v4l2_dev->mdev, p);
-}
-
-/*
- * vpfe_dqbuf() - deque buffer which is done with processing
- */
-static int vpfe_dqbuf(struct file *file, void *priv,
-		      struct v4l2_buffer *buf)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_dqbuf\n");
-
-	if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-	    buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
-		return -EINVAL;
-	}
-
-	return vb2_dqbuf(&video->buffer_queue,
-			 buf, (file->f_flags & O_NONBLOCK));
-}
-
-/*
- * vpfe_streamon() - start streaming
- * @file: file pointer
- * @priv: void pointer
- * @buf_type: enum v4l2_buf_type
- *
- * queue buffer onto hardware for capture/processing and
- * start all the subdevs which are in media chain
- *
- * Return 0 on success, error code otherwise
- */
-static int vpfe_streamon(struct file *file, void *priv,
-			 enum v4l2_buf_type buf_type)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_pipeline *pipe = &video->pipe;
-	struct vpfe_fh *fh = file->private_data;
-	int ret = -EINVAL;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n");
-
-	if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-	    buf_type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
-		return ret;
-	}
-	/* If file handle is not allowed IO, return error */
-	if (!fh->io_allowed) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
-		return -EACCES;
-	}
-	/* If buffer queue is empty, return error */
-	if (list_empty(&video->buffer_queue.queued_list)) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "buffer queue is empty\n");
-		return -EIO;
-	}
-	/* Validate the pipeline */
-	if (buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		ret = vpfe_video_validate_pipeline(pipe);
-		if (ret < 0)
-			return ret;
-	}
-	/* Call vb2_streamon to start streaming */
-	return vb2_streamon(&video->buffer_queue, buf_type);
-}
-
-/*
- * vpfe_streamoff() - stop streaming
- * @file: file pointer
- * @priv: void pointer
- * @buf_type: enum v4l2_buf_type
- *
- * stop all the subdevs which are in media chain
- *
- * Return 0 on success, error code otherwise
- */
-static int vpfe_streamoff(struct file *file, void *priv,
-			  enum v4l2_buf_type buf_type)
-{
-	struct vpfe_video_device *video = video_drvdata(file);
-	struct vpfe_device *vpfe_dev = video->vpfe_dev;
-	struct vpfe_fh *fh = file->private_data;
-	int ret = 0;
-
-	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n");
-
-	if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
-	    buf_type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-		v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "Invalid buf type\n");
-		return -EINVAL;
-	}
-
-	/* If io is allowed for this file handle, return error */
-	if (!fh->io_allowed) {
-		v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "fh->io_allowed\n");
-		return -EACCES;
-	}
-
-	/* If streaming is not started, return error */
-	if (!video->started) {
-		v4l2_err(&vpfe_dev->v4l2_dev, "device is not started\n");
-		return -EINVAL;
-	}
-
-	ret = mutex_lock_interruptible(&video->lock);
-	if (ret)
-		return ret;
-
-	vpfe_stop_capture(video);
-	ret = vb2_streamoff(&video->buffer_queue, buf_type);
-	mutex_unlock(&video->lock);
-
-	return ret;
-}
-
-/* vpfe capture ioctl operations */
-static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
-	.vidioc_querycap	 = vpfe_querycap,
-	.vidioc_g_fmt_vid_cap    = vpfe_g_fmt,
-	.vidioc_s_fmt_vid_cap    = vpfe_s_fmt,
-	.vidioc_try_fmt_vid_cap  = vpfe_try_fmt,
-	.vidioc_enum_fmt_vid_cap = vpfe_enum_fmt,
-	.vidioc_g_fmt_vid_out    = vpfe_g_fmt,
-	.vidioc_s_fmt_vid_out    = vpfe_s_fmt,
-	.vidioc_try_fmt_vid_out  = vpfe_try_fmt,
-	.vidioc_enum_fmt_vid_out = vpfe_enum_fmt,
-	.vidioc_enum_input	 = vpfe_enum_input,
-	.vidioc_g_input		 = vpfe_g_input,
-	.vidioc_s_input		 = vpfe_s_input,
-	.vidioc_querystd	 = vpfe_querystd,
-	.vidioc_s_std		 = vpfe_s_std,
-	.vidioc_g_std		 = vpfe_g_std,
-	.vidioc_enum_dv_timings	 = vpfe_enum_dv_timings,
-	.vidioc_query_dv_timings = vpfe_query_dv_timings,
-	.vidioc_s_dv_timings	 = vpfe_s_dv_timings,
-	.vidioc_g_dv_timings	 = vpfe_g_dv_timings,
-	.vidioc_reqbufs		 = vpfe_reqbufs,
-	.vidioc_querybuf	 = vpfe_querybuf,
-	.vidioc_qbuf		 = vpfe_qbuf,
-	.vidioc_dqbuf		 = vpfe_dqbuf,
-	.vidioc_streamon	 = vpfe_streamon,
-	.vidioc_streamoff	 = vpfe_streamoff,
-};
-
-/* VPFE video init function */
-int vpfe_video_init(struct vpfe_video_device *video, const char *name)
-{
-	const char *direction;
-	int ret;
-
-	switch (video->type) {
-	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		direction = "output";
-		video->pad.flags = MEDIA_PAD_FL_SINK;
-		video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-		break;
-
-	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		direction = "input";
-		video->pad.flags = MEDIA_PAD_FL_SOURCE;
-		video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-	/* Initialize field of video device */
-	mutex_init(&video->lock);
-	video->video_dev.release = video_device_release;
-	video->video_dev.fops = &vpfe_fops;
-	video->video_dev.ioctl_ops = &vpfe_ioctl_ops;
-	video->video_dev.minor = -1;
-	video->video_dev.tvnorms = 0;
-	video->video_dev.lock = &video->lock;
-	snprintf(video->video_dev.name, sizeof(video->video_dev.name),
-		 "DAVINCI VIDEO %s %s", name, direction);
-
-	spin_lock_init(&video->irqlock);
-	spin_lock_init(&video->dma_queue_lock);
-	ret = media_entity_pads_init(&video->video_dev.entity,
-				1, &video->pad);
-	if (ret < 0)
-		return ret;
-
-	video_set_drvdata(&video->video_dev, video);
-
-	return 0;
-}
-
-/* vpfe video device register function */
-int vpfe_video_register(struct vpfe_video_device *video,
-			struct v4l2_device *vdev)
-{
-	int ret;
-
-	video->video_dev.v4l2_dev = vdev;
-
-	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		video->video_dev.device_caps = V4L2_CAP_VIDEO_CAPTURE;
-	else
-		video->video_dev.device_caps = V4L2_CAP_VIDEO_OUTPUT;
-	video->video_dev.device_caps |= V4L2_CAP_STREAMING;
-	ret = video_register_device(&video->video_dev, VFL_TYPE_GRABBER, -1);
-	if (ret < 0)
-		pr_err("%s: could not register video device (%d)\n",
-		       __func__, ret);
-	return ret;
-}
-
-/* vpfe video device unregister function */
-void vpfe_video_unregister(struct vpfe_video_device *video)
-{
-	if (video_is_registered(&video->video_dev)) {
-		video_unregister_device(&video->video_dev);
-		media_entity_cleanup(&video->video_dev.entity);
-	}
-}
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.h b/drivers/staging/media/davinci_vpfe/vpfe_video.h
deleted file mode 100644
index 5d01c48..0000000
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2012 Texas Instruments Inc
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * 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.
- *
- * Contributors:
- *      Manjunath Hadli <manjunath.hadli@ti.com>
- *      Prabhakar Lad <prabhakar.lad@ti.com>
- */
-
-#ifndef _DAVINCI_VPFE_VIDEO_H
-#define _DAVINCI_VPFE_VIDEO_H
-
-#include <media/videobuf2-v4l2.h>
-#include <media/videobuf2-dma-contig.h>
-
-struct vpfe_device;
-
-/*
- * struct vpfe_video_operations - VPFE video operations
- * @queue:	Resume streaming when a buffer is queued. Called on VIDIOC_QBUF
- *		if there was no buffer previously queued.
- */
-struct vpfe_video_operations {
-	int (*queue)(struct vpfe_device *vpfe_dev, unsigned long addr);
-};
-
-enum vpfe_pipeline_stream_state {
-	VPFE_PIPELINE_STREAM_STOPPED = 0,
-	VPFE_PIPELINE_STREAM_CONTINUOUS = 1,
-	VPFE_PIPELINE_STREAM_SINGLESHOT = 2,
-};
-
-enum vpfe_video_state {
-	/* indicates that buffer is not queued */
-	VPFE_VIDEO_BUFFER_NOT_QUEUED = 0,
-	/* indicates that buffer is queued */
-	VPFE_VIDEO_BUFFER_QUEUED = 1,
-};
-
-struct vpfe_pipeline {
-	/* media pipeline */
-	struct media_pipeline		*pipe;
-	struct media_graph	graph;
-	/* state of the pipeline, continuous,
-	 * single-shot or stopped
-	 */
-	enum vpfe_pipeline_stream_state	state;
-	/* number of active input video entities */
-	unsigned int			input_num;
-	/* number of active output video entities */
-	unsigned int			output_num;
-	/* input video nodes in case of single-shot mode */
-	struct vpfe_video_device	*inputs[10];
-	/* capturing video nodes */
-	struct vpfe_video_device	*outputs[10];
-};
-
-#define to_vpfe_pipeline(__e) \
-	container_of((__e)->pipe, struct vpfe_pipeline, pipe)
-
-#define to_vpfe_video(vdev) \
-	container_of(vdev, struct vpfe_video_device, video_dev)
-
-struct vpfe_cap_buffer {
-	struct vb2_v4l2_buffer vb;
-	struct list_head list;
-};
-
-struct vpfe_video_device {
-	/* vpfe device */
-	struct vpfe_device			*vpfe_dev;
-	/* video dev */
-	struct video_device			video_dev;
-	/* media pad of video entity */
-	struct media_pad			pad;
-	/* video operations supported by video device */
-	const struct vpfe_video_operations	*ops;
-	/* type of the video buffers used by user */
-	enum v4l2_buf_type			type;
-	/* Indicates id of the field which is being captured */
-	u32					field_id;
-	/* pipeline for which video device is part of */
-	struct vpfe_pipeline			pipe;
-	/* Indicates whether streaming started */
-	u8					started;
-	/* Indicates state of the stream */
-	unsigned int				state;
-	/* current input at the sub device */
-	int					current_input;
-	/*
-	 * This field keeps track of type of buffer exchange mechanism
-	 * user has selected
-	 */
-	enum v4l2_memory			memory;
-	/* number of open instances of the channel */
-	u32					usrs;
-	/* flag to indicate whether decoder is initialized */
-	u8					initialized;
-	/* skip frame count */
-	u8					skip_frame_count;
-	/* skip frame count init value */
-	u8					skip_frame_count_init;
-	/* time per frame for skipping */
-	struct v4l2_fract			timeperframe;
-	/* ptr to currently selected sub device */
-	struct vpfe_ext_subdev_info		*current_ext_subdev;
-	/* Pointer pointing to current vpfe_cap_buffer */
-	struct vpfe_cap_buffer			*cur_frm;
-	/* Pointer pointing to next vpfe_cap_buffer */
-	struct vpfe_cap_buffer			*next_frm;
-	/* Used to store pixel format */
-	struct v4l2_format			fmt;
-	struct vb2_queue			buffer_queue;
-	/* Queue of filled frames */
-	struct list_head			dma_queue;
-	spinlock_t				irqlock;
-	/* IRQ lock for DMA queue */
-	spinlock_t				dma_queue_lock;
-	/* lock used to serialize all video4linux ioctls */
-	struct mutex				lock;
-	/* number of users performing IO */
-	u32					io_usrs;
-	/* Currently selected or default standard */
-	v4l2_std_id				stdid;
-	/*
-	 * offset where second field starts from the starting of the
-	 * buffer for field separated YCbCr formats
-	 */
-	u32					field_off;
-};
-
-int vpfe_video_is_pipe_ready(struct vpfe_pipeline *pipe);
-void vpfe_video_unregister(struct vpfe_video_device *video);
-int vpfe_video_register(struct vpfe_video_device *video,
-			struct v4l2_device *vdev);
-int vpfe_video_init(struct vpfe_video_device *video, const char *name);
-void vpfe_video_process_buffer_complete(struct vpfe_video_device *video);
-void vpfe_video_schedule_bottom_field(struct vpfe_video_device *video);
-void vpfe_video_schedule_next_buffer(struct vpfe_video_device *video);
-
-#endif		/* _DAVINCI_VPFE_VIDEO_H */
diff --git a/drivers/staging/media/hantro/Kconfig b/drivers/staging/media/hantro/Kconfig
index be133bb..de77fe65 100644
--- a/drivers/staging/media/hantro/Kconfig
+++ b/drivers/staging/media/hantro/Kconfig
@@ -20,4 +20,4 @@
 	depends on ARCH_ROCKCHIP || COMPILE_TEST
 	default y
 	help
-	  Enable support for RK3288 and RK3399 SoCs.
+	  Enable support for RK3288, RK3328, and RK3399 SoCs.
diff --git a/drivers/staging/media/hantro/Makefile b/drivers/staging/media/hantro/Makefile
index 1584acd..5d6b038 100644
--- a/drivers/staging/media/hantro/Makefile
+++ b/drivers/staging/media/hantro/Makefile
@@ -4,11 +4,16 @@
 		hantro_drv.o \
 		hantro_v4l2.o \
 		hantro_h1_jpeg_enc.o \
+		hantro_g1_h264_dec.o \
 		hantro_g1_mpeg2_dec.o \
+		hantro_g1_vp8_dec.o \
 		rk3399_vpu_hw_jpeg_enc.o \
 		rk3399_vpu_hw_mpeg2_dec.o \
+		rk3399_vpu_hw_vp8_dec.o \
 		hantro_jpeg.o \
-		hantro_mpeg2.o
+		hantro_h264.o \
+		hantro_mpeg2.o \
+		hantro_vp8.o
 
 hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \
 		rk3288_vpu_hw.o \
diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h
index 62dcca9..f670bbd 100644
--- a/drivers/staging/media/hantro/hantro.h
+++ b/drivers/staging/media/hantro/hantro.h
@@ -20,11 +20,20 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-dma-contig.h>
 
 #include "hantro_hw.h"
 
+#define VP8_MB_DIM			16
+#define VP8_MB_WIDTH(w)			DIV_ROUND_UP(w, VP8_MB_DIM)
+#define VP8_MB_HEIGHT(h)		DIV_ROUND_UP(h, VP8_MB_DIM)
+
+#define H264_MB_DIM			16
+#define H264_MB_WIDTH(w)		DIV_ROUND_UP(w, H264_MB_DIM)
+#define H264_MB_HEIGHT(h)		DIV_ROUND_UP(h, H264_MB_DIM)
+
 #define MPEG2_MB_DIM			16
 #define MPEG2_MB_WIDTH(w)		DIV_ROUND_UP(w, MPEG2_MB_DIM)
 #define MPEG2_MB_HEIGHT(h)		DIV_ROUND_UP(h, MPEG2_MB_DIM)
@@ -38,8 +47,9 @@
 
 #define HANTRO_JPEG_ENCODER	BIT(0)
 #define HANTRO_ENCODERS		0x0000ffff
-
 #define HANTRO_MPEG2_DECODER	BIT(16)
+#define HANTRO_VP8_DECODER	BIT(17)
+#define HANTRO_H264_DECODER	BIT(18)
 #define HANTRO_DECODERS		0xffff0000
 
 /**
@@ -96,22 +106,24 @@
  * enum hantro_codec_mode - codec operating mode.
  * @HANTRO_MODE_NONE:  No operating mode. Used for RAW video formats.
  * @HANTRO_MODE_JPEG_ENC: JPEG encoder.
+ * @HANTRO_MODE_H264_DEC: H264 decoder.
  * @HANTRO_MODE_MPEG2_DEC: MPEG-2 decoder.
+ * @HANTRO_MODE_VP8_DEC: VP8 decoder.
  */
 enum hantro_codec_mode {
 	HANTRO_MODE_NONE = -1,
 	HANTRO_MODE_JPEG_ENC,
+	HANTRO_MODE_H264_DEC,
 	HANTRO_MODE_MPEG2_DEC,
+	HANTRO_MODE_VP8_DEC,
 };
 
 /*
  * struct hantro_ctrl - helper type to declare supported controls
- * @id:		V4L2 control ID (V4L2_CID_xxx)
  * @codec:	codec id this control belong to (HANTRO_JPEG_ENCODER, etc.)
  * @cfg:	control configuration
  */
 struct hantro_ctrl {
-	unsigned int id;
 	unsigned int codec;
 	struct v4l2_ctrl_config cfg;
 };
@@ -215,6 +227,7 @@
  * @codec_ops:		Set of operations related to codec mode.
  * @jpeg_enc:		JPEG-encoding context.
  * @mpeg2_dec:		MPEG-2-decoding context.
+ * @vp8_dec:		VP8-decoding context.
  */
 struct hantro_ctx {
 	struct hantro_dev *dev;
@@ -239,8 +252,10 @@
 
 	/* Specific for particular codec modes. */
 	union {
+		struct hantro_h264_dec_hw_ctx h264_dec;
 		struct hantro_jpeg_enc_hw_ctx jpeg_enc;
 		struct hantro_mpeg2_dec_hw_ctx mpeg2_dec;
+		struct hantro_vp8_dec_hw_ctx vp8_dec;
 	};
 };
 
@@ -265,6 +280,12 @@
 	struct v4l2_frmsize_stepwise frmsize;
 };
 
+struct hantro_reg {
+	u32 base;
+	u32 shift;
+	u32 mask;
+};
+
 /* Logging helpers */
 
 /**
@@ -343,9 +364,33 @@
 	return val;
 }
 
+static inline void hantro_reg_write(struct hantro_dev *vpu,
+				    const struct hantro_reg *reg,
+				    u32 val)
+{
+	u32 v;
+
+	v = vdpu_read(vpu, reg->base);
+	v &= ~(reg->mask << reg->shift);
+	v |= ((val & reg->mask) << reg->shift);
+	vdpu_write_relaxed(vpu, v, reg->base);
+}
+
 bool hantro_is_encoder_ctx(const struct hantro_ctx *ctx);
 
 void *hantro_get_ctrl(struct hantro_ctx *ctx, u32 id);
 dma_addr_t hantro_get_ref(struct vb2_queue *q, u64 ts);
 
+static inline struct vb2_v4l2_buffer *
+hantro_get_src_buf(struct hantro_ctx *ctx)
+{
+	return v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+}
+
+static inline struct vb2_v4l2_buffer *
+hantro_get_dst_buf(struct hantro_ctx *ctx)
+{
+	return v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+}
+
 #endif /* HANTRO_H_ */
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index c3665f0..d8b6816 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -111,8 +111,6 @@
 	src->sequence = ctx->sequence_out++;
 	dst->sequence = ctx->sequence_cap++;
 
-	v4l2_m2m_buf_copy_metadata(src, dst, true);
-
 	ret = ctx->buf_finish(ctx, &dst->vb2_buf, bytesused);
 	if (ret)
 		result = VB2_BUF_STATE_ERROR;
@@ -153,11 +151,37 @@
 	}
 }
 
+void hantro_prepare_run(struct hantro_ctx *ctx)
+{
+	struct vb2_v4l2_buffer *src_buf;
+
+	src_buf = hantro_get_src_buf(ctx);
+	v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
+				&ctx->ctrl_handler);
+}
+
+void hantro_finish_run(struct hantro_ctx *ctx)
+{
+	struct vb2_v4l2_buffer *src_buf;
+
+	src_buf = hantro_get_src_buf(ctx);
+	v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
+				   &ctx->ctrl_handler);
+
+	/* Kick the watchdog. */
+	schedule_delayed_work(&ctx->dev->watchdog_work,
+			      msecs_to_jiffies(2000));
+}
+
 static void device_run(void *priv)
 {
 	struct hantro_ctx *ctx = priv;
+	struct vb2_v4l2_buffer *src, *dst;
 	int ret;
 
+	src = hantro_get_src_buf(ctx);
+	dst = hantro_get_dst_buf(ctx);
+
 	ret = clk_bulk_enable(ctx->dev->variant->num_clocks, ctx->dev->clocks);
 	if (ret)
 		goto err_cancel_job;
@@ -165,6 +189,8 @@
 	if (ret < 0)
 		goto err_cancel_job;
 
+	v4l2_m2m_buf_copy_metadata(src, dst, true);
+
 	ctx->codec_ops->run(ctx);
 	return;
 
@@ -262,28 +288,74 @@
 	.s_ctrl = hantro_s_ctrl,
 };
 
-static struct hantro_ctrl controls[] = {
+static const struct hantro_ctrl controls[] = {
 	{
-		.id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
 		.codec = HANTRO_JPEG_ENCODER,
 		.cfg = {
+			.id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
 			.min = 5,
 			.max = 100,
 			.step = 1,
 			.def = 50,
+			.ops = &hantro_ctrl_ops,
 		},
 	}, {
-		.id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
 		.codec = HANTRO_MPEG2_DECODER,
 		.cfg = {
-			.elem_size = sizeof(struct v4l2_ctrl_mpeg2_slice_params),
+			.id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
 		},
 	}, {
-		.id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
 		.codec = HANTRO_MPEG2_DECODER,
 		.cfg = {
-			.elem_size = sizeof(struct v4l2_ctrl_mpeg2_quantization),
+			.id = V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
 		},
+	}, {
+		.codec = HANTRO_VP8_DECODER,
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER,
+		},
+	}, {
+		.codec = HANTRO_H264_DECODER,
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
+		},
+	}, {
+		.codec = HANTRO_H264_DECODER,
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
+		},
+	}, {
+		.codec = HANTRO_H264_DECODER,
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_H264_SPS,
+		},
+	}, {
+		.codec = HANTRO_H264_DECODER,
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_H264_PPS,
+		},
+	}, {
+		.codec = HANTRO_H264_DECODER,
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
+		},
+	}, {
+		.codec = HANTRO_H264_DECODER,
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE,
+			.min = V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
+			.def = V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
+			.max = V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
+		},
+	}, {
+		.codec = HANTRO_H264_DECODER,
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_H264_START_CODE,
+			.min = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
+			.def = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
+			.max = V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
+		},
+	}, {
 	},
 };
 
@@ -298,22 +370,12 @@
 	for (i = 0; i < num_ctrls; i++) {
 		if (!(allowed_codecs & controls[i].codec))
 			continue;
-		if (!controls[i].cfg.elem_size) {
-			v4l2_ctrl_new_std(&ctx->ctrl_handler,
-					  &hantro_ctrl_ops,
-					  controls[i].id, controls[i].cfg.min,
-					  controls[i].cfg.max,
-					  controls[i].cfg.step,
-					  controls[i].cfg.def);
-		} else {
-			controls[i].cfg.id = controls[i].id;
-			v4l2_ctrl_new_custom(&ctx->ctrl_handler,
-					     &controls[i].cfg, NULL);
-		}
 
+		v4l2_ctrl_new_custom(&ctx->ctrl_handler,
+				     &controls[i].cfg, NULL);
 		if (ctx->ctrl_handler.error) {
 			vpu_err("Adding control (%d) failed %d\n",
-				controls[i].id,
+				controls[i].cfg.id,
 				ctx->ctrl_handler.error);
 			v4l2_ctrl_handler_free(&ctx->ctrl_handler);
 			return ctx->ctrl_handler.error;
@@ -419,6 +481,7 @@
 static const struct of_device_id of_hantro_match[] = {
 #ifdef CONFIG_VIDEO_HANTRO_ROCKCHIP
 	{ .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, },
+	{ .compatible = "rockchip,rk3328-vpu", .data = &rk3328_vpu_variant, },
 	{ .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, },
 #endif
 	{ /* sentinel */ }
@@ -724,6 +787,7 @@
 		dev_err(vpu->dev, "Could not set DMA coherent mask.\n");
 		return ret;
 	}
+	vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
 
 	for (i = 0; i < vpu->variant->num_irqs; i++) {
 		const char *irq_name = vpu->variant->irqs[i].name;
diff --git a/drivers/staging/media/hantro/hantro_g1_h264_dec.c b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
new file mode 100644
index 0000000..7ab5349
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_g1_h264_dec.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip RK3288 VPU codec driver
+ *
+ * Copyright (c) 2014 Rockchip Electronics Co., Ltd.
+ *	Hertz Wong <hertz.wong@rock-chips.com>
+ *	Herman Chen <herman.chen@rock-chips.com>
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *	Tomasz Figa <tfiga@chromium.org>
+ */
+
+#include <linux/types.h>
+#include <linux/sort.h>
+
+#include <media/v4l2-mem2mem.h>
+
+#include "hantro_g1_regs.h"
+#include "hantro_hw.h"
+#include "hantro_v4l2.h"
+
+static void set_params(struct hantro_ctx *ctx)
+{
+	const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
+	const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode;
+	const struct v4l2_ctrl_h264_slice_params *slices = ctrls->slices;
+	const struct v4l2_ctrl_h264_sps *sps = ctrls->sps;
+	const struct v4l2_ctrl_h264_pps *pps = ctrls->pps;
+	struct vb2_v4l2_buffer *src_buf = hantro_get_src_buf(ctx);
+	struct hantro_dev *vpu = ctx->dev;
+	u32 reg;
+
+	/* Decoder control register 0. */
+	reg = G1_REG_DEC_CTRL0_DEC_AXI_WR_ID(0x0);
+	if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
+		reg |= G1_REG_DEC_CTRL0_SEQ_MBAFF_E;
+	reg |= G1_REG_DEC_CTRL0_PICORD_COUNT_E;
+	if (dec_param->nal_ref_idc)
+		reg |= G1_REG_DEC_CTRL0_WRITE_MVS_E;
+
+	if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) &&
+	    (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD ||
+	     slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC))
+		reg |= G1_REG_DEC_CTRL0_PIC_INTERLACE_E;
+	if (slices[0].flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
+		reg |= G1_REG_DEC_CTRL0_PIC_FIELDMODE_E;
+	if (!(slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD))
+		reg |= G1_REG_DEC_CTRL0_PIC_TOPFIELD_E;
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL0);
+
+	/* Decoder control register 1. */
+	reg = G1_REG_DEC_CTRL1_PIC_MB_WIDTH(sps->pic_width_in_mbs_minus1 + 1) |
+	      G1_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(sps->pic_height_in_map_units_minus1 + 1) |
+	      G1_REG_DEC_CTRL1_REF_FRAMES(sps->max_num_ref_frames);
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL1);
+
+	/* Decoder control register 2. */
+	reg = G1_REG_DEC_CTRL2_CH_QP_OFFSET(pps->chroma_qp_index_offset) |
+	      G1_REG_DEC_CTRL2_CH_QP_OFFSET2(pps->second_chroma_qp_index_offset);
+
+	/* always use the matrix sent from userspace */
+	reg |= G1_REG_DEC_CTRL2_TYPE1_QUANT_E;
+
+	if (slices[0].flags &  V4L2_H264_SLICE_FLAG_FIELD_PIC)
+		reg |= G1_REG_DEC_CTRL2_FIELDPIC_FLAG_E;
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL2);
+
+	/* Decoder control register 3. */
+	reg = G1_REG_DEC_CTRL3_START_CODE_E |
+	      G1_REG_DEC_CTRL3_INIT_QP(pps->pic_init_qp_minus26 + 26) |
+	      G1_REG_DEC_CTRL3_STREAM_LEN(vb2_get_plane_payload(&src_buf->vb2_buf, 0));
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL3);
+
+	/* Decoder control register 4. */
+	reg = G1_REG_DEC_CTRL4_FRAMENUM_LEN(sps->log2_max_frame_num_minus4 + 4) |
+	      G1_REG_DEC_CTRL4_FRAMENUM(slices[0].frame_num) |
+	      G1_REG_DEC_CTRL4_WEIGHT_BIPR_IDC(pps->weighted_bipred_idc);
+	if (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE)
+		reg |= G1_REG_DEC_CTRL4_CABAC_E;
+	if (sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)
+		reg |= G1_REG_DEC_CTRL4_DIR_8X8_INFER_E;
+	if (sps->chroma_format_idc == 0)
+		reg |= G1_REG_DEC_CTRL4_BLACKWHITE_E;
+	if (pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED)
+		reg |= G1_REG_DEC_CTRL4_WEIGHT_PRED_E;
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL4);
+
+	/* Decoder control register 5. */
+	reg = G1_REG_DEC_CTRL5_REFPIC_MK_LEN(slices[0].dec_ref_pic_marking_bit_size) |
+	      G1_REG_DEC_CTRL5_IDR_PIC_ID(slices[0].idr_pic_id);
+	if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED)
+		reg |= G1_REG_DEC_CTRL5_CONST_INTRA_E;
+	if (pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT)
+		reg |= G1_REG_DEC_CTRL5_FILT_CTRL_PRES;
+	if (pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT)
+		reg |= G1_REG_DEC_CTRL5_RDPIC_CNT_PRES;
+	if (pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE)
+		reg |= G1_REG_DEC_CTRL5_8X8TRANS_FLAG_E;
+	if (dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC)
+		reg |= G1_REG_DEC_CTRL5_IDR_PIC_E;
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL5);
+
+	/* Decoder control register 6. */
+	reg = G1_REG_DEC_CTRL6_PPS_ID(slices[0].pic_parameter_set_id) |
+	      G1_REG_DEC_CTRL6_REFIDX0_ACTIVE(pps->num_ref_idx_l0_default_active_minus1 + 1) |
+	      G1_REG_DEC_CTRL6_REFIDX1_ACTIVE(pps->num_ref_idx_l1_default_active_minus1 + 1) |
+	      G1_REG_DEC_CTRL6_POC_LENGTH(slices[0].pic_order_cnt_bit_size);
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL6);
+
+	/* Error concealment register. */
+	vdpu_write_relaxed(vpu, 0, G1_REG_ERR_CONC);
+
+	/* Prediction filter tap register. */
+	vdpu_write_relaxed(vpu,
+			   G1_REG_PRED_FLT_PRED_BC_TAP_0_0(1) |
+			   G1_REG_PRED_FLT_PRED_BC_TAP_0_1(-5 & 0x3ff) |
+			   G1_REG_PRED_FLT_PRED_BC_TAP_0_2(20),
+			   G1_REG_PRED_FLT);
+
+	/* Reference picture buffer control register. */
+	vdpu_write_relaxed(vpu, 0, G1_REG_REF_BUF_CTRL);
+
+	/* Reference picture buffer control register 2. */
+	vdpu_write_relaxed(vpu, G1_REG_REF_BUF_CTRL2_APF_THRESHOLD(8),
+			   G1_REG_REF_BUF_CTRL2);
+}
+
+static void set_ref(struct hantro_ctx *ctx)
+{
+	struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
+	const u8 *b0_reflist, *b1_reflist, *p_reflist;
+	struct hantro_dev *vpu = ctx->dev;
+	u32 dpb_longterm = 0;
+	u32 dpb_valid = 0;
+	int reg_num;
+	u32 reg;
+	int i;
+
+	/*
+	 * Set up bit maps of valid and long term DPBs.
+	 * NOTE: The bits are reversed, i.e. MSb is DPB 0.
+	 */
+	for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) {
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
+			dpb_valid |= BIT(HANTRO_H264_DPB_SIZE - 1 - i);
+
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
+			dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE - 1 - i);
+	}
+	vdpu_write_relaxed(vpu, dpb_valid << 16, G1_REG_VALID_REF);
+	vdpu_write_relaxed(vpu, dpb_longterm << 16, G1_REG_LT_REF);
+
+	/*
+	 * Set up reference frame picture numbers.
+	 *
+	 * Each G1_REG_REF_PIC(x) register contains numbers of two
+	 * subsequential reference pictures.
+	 */
+	for (i = 0; i < HANTRO_H264_DPB_SIZE; i += 2) {
+		reg = 0;
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
+			reg |= G1_REG_REF_PIC_REFER0_NBR(dpb[i].pic_num);
+		else
+			reg |= G1_REG_REF_PIC_REFER0_NBR(dpb[i].frame_num);
+
+		if (dpb[i + 1].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
+			reg |= G1_REG_REF_PIC_REFER1_NBR(dpb[i + 1].pic_num);
+		else
+			reg |= G1_REG_REF_PIC_REFER1_NBR(dpb[i + 1].frame_num);
+
+		vdpu_write_relaxed(vpu, reg, G1_REG_REF_PIC(i / 2));
+	}
+
+	b0_reflist = ctx->h264_dec.reflists.b0;
+	b1_reflist = ctx->h264_dec.reflists.b1;
+	p_reflist = ctx->h264_dec.reflists.p;
+
+	/*
+	 * Each G1_REG_BD_REF_PIC(x) register contains three entries
+	 * of each forward and backward picture list.
+	 */
+	reg_num = 0;
+	for (i = 0; i < 15; i += 3) {
+		reg = G1_REG_BD_REF_PIC_BINIT_RLIST_F0(b0_reflist[i]) |
+		      G1_REG_BD_REF_PIC_BINIT_RLIST_F1(b0_reflist[i + 1]) |
+		      G1_REG_BD_REF_PIC_BINIT_RLIST_F2(b0_reflist[i + 2]) |
+		      G1_REG_BD_REF_PIC_BINIT_RLIST_B0(b1_reflist[i]) |
+		      G1_REG_BD_REF_PIC_BINIT_RLIST_B1(b1_reflist[i + 1]) |
+		      G1_REG_BD_REF_PIC_BINIT_RLIST_B2(b1_reflist[i + 2]);
+		vdpu_write_relaxed(vpu, reg, G1_REG_BD_REF_PIC(reg_num++));
+	}
+
+	/*
+	 * G1_REG_BD_P_REF_PIC register contains last entries (index 15)
+	 * of forward and backward reference picture lists and first 4 entries
+	 * of P forward picture list.
+	 */
+	reg = G1_REG_BD_P_REF_PIC_BINIT_RLIST_F15(b0_reflist[15]) |
+	      G1_REG_BD_P_REF_PIC_BINIT_RLIST_B15(b1_reflist[15]) |
+	      G1_REG_BD_P_REF_PIC_PINIT_RLIST_F0(p_reflist[0]) |
+	      G1_REG_BD_P_REF_PIC_PINIT_RLIST_F1(p_reflist[1]) |
+	      G1_REG_BD_P_REF_PIC_PINIT_RLIST_F2(p_reflist[2]) |
+	      G1_REG_BD_P_REF_PIC_PINIT_RLIST_F3(p_reflist[3]);
+	vdpu_write_relaxed(vpu, reg, G1_REG_BD_P_REF_PIC);
+
+	/*
+	 * Each G1_REG_FWD_PIC(x) register contains six consecutive
+	 * entries of P forward picture list, starting from index 4.
+	 */
+	reg_num = 0;
+	for (i = 4; i < HANTRO_H264_DPB_SIZE; i += 6) {
+		reg = G1_REG_FWD_PIC_PINIT_RLIST_F0(p_reflist[i]) |
+		      G1_REG_FWD_PIC_PINIT_RLIST_F1(p_reflist[i + 1]) |
+		      G1_REG_FWD_PIC_PINIT_RLIST_F2(p_reflist[i + 2]) |
+		      G1_REG_FWD_PIC_PINIT_RLIST_F3(p_reflist[i + 3]) |
+		      G1_REG_FWD_PIC_PINIT_RLIST_F4(p_reflist[i + 4]) |
+		      G1_REG_FWD_PIC_PINIT_RLIST_F5(p_reflist[i + 5]);
+		vdpu_write_relaxed(vpu, reg, G1_REG_FWD_PIC(reg_num++));
+	}
+
+	/* Set up addresses of DPB buffers. */
+	for (i = 0; i < HANTRO_H264_DPB_SIZE; i++) {
+		struct vb2_buffer *buf =  hantro_h264_get_ref_buf(ctx, i);
+
+		vdpu_write_relaxed(vpu, vb2_dma_contig_plane_dma_addr(buf, 0),
+				   G1_REG_ADDR_REF(i));
+	}
+}
+
+static void set_buffers(struct hantro_ctx *ctx)
+{
+	const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
+	struct vb2_v4l2_buffer *src_buf, *dst_buf;
+	struct hantro_dev *vpu = ctx->dev;
+	dma_addr_t src_dma, dst_dma;
+
+	src_buf = hantro_get_src_buf(ctx);
+	dst_buf = hantro_get_dst_buf(ctx);
+
+	/* Source (stream) buffer. */
+	src_dma = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+	vdpu_write_relaxed(vpu, src_dma, G1_REG_ADDR_STR);
+
+	/* Destination (decoded frame) buffer. */
+	dst_dma = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+	vdpu_write_relaxed(vpu, dst_dma, G1_REG_ADDR_DST);
+
+	/* Higher profiles require DMV buffer appended to reference frames. */
+	if (ctrls->sps->profile_idc > 66) {
+		size_t pic_size = ctx->h264_dec.pic_size;
+		size_t mv_offset = round_up(pic_size, 8);
+
+		if (ctrls->slices[0].flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)
+			mv_offset += 32 * H264_MB_WIDTH(ctx->dst_fmt.width);
+
+		vdpu_write_relaxed(vpu, dst_dma + mv_offset,
+				   G1_REG_ADDR_DIR_MV);
+	}
+
+	/* Auxiliary buffer prepared in hantro_g1_h264_dec_prepare_table(). */
+	vdpu_write_relaxed(vpu, ctx->h264_dec.priv.dma, G1_REG_ADDR_QTABLE);
+}
+
+void hantro_g1_h264_dec_run(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+
+	/* Prepare the H264 decoder context. */
+	if (hantro_h264_dec_prepare_run(ctx))
+		return;
+
+	/* Configure hardware registers. */
+	set_params(ctx);
+	set_ref(ctx);
+	set_buffers(ctx);
+
+	hantro_finish_run(ctx);
+
+	/* Start decoding! */
+	vdpu_write_relaxed(vpu,
+			   G1_REG_CONFIG_DEC_AXI_RD_ID(0xffu) |
+			   G1_REG_CONFIG_DEC_TIMEOUT_E |
+			   G1_REG_CONFIG_DEC_OUT_ENDIAN |
+			   G1_REG_CONFIG_DEC_STRENDIAN_E |
+			   G1_REG_CONFIG_DEC_MAX_BURST(16) |
+			   G1_REG_CONFIG_DEC_OUTSWAP32_E |
+			   G1_REG_CONFIG_DEC_INSWAP32_E |
+			   G1_REG_CONFIG_DEC_STRSWAP32_E |
+			   G1_REG_CONFIG_DEC_CLK_GATE_E,
+			   G1_REG_CONFIG);
+	vdpu_write(vpu, G1_REG_INTERRUPT_DEC_E, G1_REG_INTERRUPT);
+}
diff --git a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
index e592c1b..80f0e94 100644
--- a/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/hantro_g1_mpeg2_dec.c
@@ -167,12 +167,11 @@
 	const struct v4l2_mpeg2_picture *picture;
 	u32 reg;
 
-	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
-	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+	src_buf = hantro_get_src_buf(ctx);
+	dst_buf = hantro_get_dst_buf(ctx);
 
 	/* Apply request controls if any */
-	v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
-				&ctx->ctrl_handler);
+	hantro_prepare_run(ctx);
 
 	slice_params = hantro_get_ctrl(ctx,
 				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
@@ -248,12 +247,7 @@
 					&dst_buf->vb2_buf,
 					sequence, picture, slice_params);
 
-	/* Controls no longer in-use, we can complete them */
-	v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
-				   &ctx->ctrl_handler);
-
-	/* Kick the watchdog and start decoding */
-	schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000));
+	hantro_finish_run(ctx);
 
 	reg = G1_REG_DEC_E(1);
 	vdpu_write(vpu, reg, G1_SWREG(1));
diff --git a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
new file mode 100644
index 0000000..6d99c2b
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c
@@ -0,0 +1,503 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hantro VP8 codec driver
+ *
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd.
+ *	ZhiChao Yu <zhichao.yu@rock-chips.com>
+ *
+ * Copyright (C) 2019 Google, Inc.
+ *	Tomasz Figa <tfiga@chromium.org>
+ */
+
+#include <media/v4l2-mem2mem.h>
+#include <media/vp8-ctrls.h>
+
+#include "hantro_hw.h"
+#include "hantro.h"
+#include "hantro_g1_regs.h"
+
+/* DCT partition base address regs */
+static const struct hantro_reg vp8_dec_dct_base[8] = {
+	{ G1_REG_ADDR_STR, 0, 0xffffffff },
+	{ G1_REG_ADDR_REF(8), 0, 0xffffffff },
+	{ G1_REG_ADDR_REF(9), 0, 0xffffffff },
+	{ G1_REG_ADDR_REF(10), 0, 0xffffffff },
+	{ G1_REG_ADDR_REF(11), 0, 0xffffffff },
+	{ G1_REG_ADDR_REF(12), 0, 0xffffffff },
+	{ G1_REG_ADDR_REF(14), 0, 0xffffffff },
+	{ G1_REG_ADDR_REF(15), 0, 0xffffffff },
+};
+
+/* Loop filter level regs */
+static const struct hantro_reg vp8_dec_lf_level[4] = {
+	{ G1_REG_REF_PIC(2), 18, 0x3f },
+	{ G1_REG_REF_PIC(2), 12, 0x3f },
+	{ G1_REG_REF_PIC(2), 6, 0x3f },
+	{ G1_REG_REF_PIC(2), 0, 0x3f },
+};
+
+/* Macroblock loop filter level adjustment regs */
+static const struct hantro_reg vp8_dec_mb_adj[4] = {
+	{ G1_REG_REF_PIC(0), 21, 0x7f },
+	{ G1_REG_REF_PIC(0), 14, 0x7f },
+	{ G1_REG_REF_PIC(0), 7, 0x7f },
+	{ G1_REG_REF_PIC(0), 0, 0x7f },
+};
+
+/* Reference frame adjustment regs */
+static const struct hantro_reg vp8_dec_ref_adj[4] = {
+	{ G1_REG_REF_PIC(1), 21, 0x7f },
+	{ G1_REG_REF_PIC(1), 14, 0x7f },
+	{ G1_REG_REF_PIC(1), 7, 0x7f },
+	{ G1_REG_REF_PIC(1), 0, 0x7f },
+};
+
+/* Quantizer */
+static const struct hantro_reg vp8_dec_quant[4] = {
+	{ G1_REG_REF_PIC(3), 11, 0x7ff },
+	{ G1_REG_REF_PIC(3), 0, 0x7ff },
+	{ G1_REG_BD_REF_PIC(4), 11, 0x7ff },
+	{ G1_REG_BD_REF_PIC(4), 0, 0x7ff },
+};
+
+/* Quantizer delta regs */
+static const struct hantro_reg vp8_dec_quant_delta[5] = {
+	{ G1_REG_REF_PIC(3), 27, 0x1f },
+	{ G1_REG_REF_PIC(3), 22, 0x1f },
+	{ G1_REG_BD_REF_PIC(4), 27, 0x1f },
+	{ G1_REG_BD_REF_PIC(4), 22, 0x1f },
+	{ G1_REG_BD_P_REF_PIC, 27, 0x1f },
+};
+
+/* DCT partition start bits regs */
+static const struct hantro_reg vp8_dec_dct_start_bits[8] = {
+	{ G1_REG_DEC_CTRL2, 26, 0x3f }, { G1_REG_DEC_CTRL4, 26, 0x3f },
+	{ G1_REG_DEC_CTRL4, 20, 0x3f }, { G1_REG_DEC_CTRL7, 24, 0x3f },
+	{ G1_REG_DEC_CTRL7, 18, 0x3f }, { G1_REG_DEC_CTRL7, 12, 0x3f },
+	{ G1_REG_DEC_CTRL7, 6, 0x3f },  { G1_REG_DEC_CTRL7, 0, 0x3f },
+};
+
+/* Precision filter tap regs */
+static const struct hantro_reg vp8_dec_pred_bc_tap[8][4] = {
+	{
+		{ G1_REG_PRED_FLT, 22, 0x3ff },
+		{ G1_REG_PRED_FLT, 12, 0x3ff },
+		{ G1_REG_PRED_FLT, 2, 0x3ff },
+		{ G1_REG_REF_PIC(4), 22, 0x3ff },
+	},
+	{
+		{ G1_REG_REF_PIC(4), 12, 0x3ff },
+		{ G1_REG_REF_PIC(4), 2, 0x3ff },
+		{ G1_REG_REF_PIC(5), 22, 0x3ff },
+		{ G1_REG_REF_PIC(5), 12, 0x3ff },
+	},
+	{
+		{ G1_REG_REF_PIC(5), 2, 0x3ff },
+		{ G1_REG_REF_PIC(6), 22, 0x3ff },
+		{ G1_REG_REF_PIC(6), 12, 0x3ff },
+		{ G1_REG_REF_PIC(6), 2, 0x3ff },
+	},
+	{
+		{ G1_REG_REF_PIC(7), 22, 0x3ff },
+		{ G1_REG_REF_PIC(7), 12, 0x3ff },
+		{ G1_REG_REF_PIC(7), 2, 0x3ff },
+		{ G1_REG_LT_REF, 22, 0x3ff },
+	},
+	{
+		{ G1_REG_LT_REF, 12, 0x3ff },
+		{ G1_REG_LT_REF, 2, 0x3ff },
+		{ G1_REG_VALID_REF, 22, 0x3ff },
+		{ G1_REG_VALID_REF, 12, 0x3ff },
+	},
+	{
+		{ G1_REG_VALID_REF, 2, 0x3ff },
+		{ G1_REG_BD_REF_PIC(0), 22, 0x3ff },
+		{ G1_REG_BD_REF_PIC(0), 12, 0x3ff },
+		{ G1_REG_BD_REF_PIC(0), 2, 0x3ff },
+	},
+	{
+		{ G1_REG_BD_REF_PIC(1), 22, 0x3ff },
+		{ G1_REG_BD_REF_PIC(1), 12, 0x3ff },
+		{ G1_REG_BD_REF_PIC(1), 2, 0x3ff },
+		{ G1_REG_BD_REF_PIC(2), 22, 0x3ff },
+	},
+	{
+		{ G1_REG_BD_REF_PIC(2), 12, 0x3ff },
+		{ G1_REG_BD_REF_PIC(2), 2, 0x3ff },
+		{ G1_REG_BD_REF_PIC(3), 22, 0x3ff },
+		{ G1_REG_BD_REF_PIC(3), 12, 0x3ff },
+	},
+};
+
+/*
+ * Set loop filters
+ */
+static void cfg_lf(struct hantro_ctx *ctx,
+		   const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	const struct v4l2_vp8_segment_header *seg = &hdr->segment_header;
+	const struct v4l2_vp8_loopfilter_header *lf = &hdr->lf_header;
+	struct hantro_dev *vpu = ctx->dev;
+	unsigned int i;
+	u32 reg;
+
+	if (!(seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED)) {
+		hantro_reg_write(vpu, &vp8_dec_lf_level[0], lf->level);
+	} else if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE) {
+		for (i = 0; i < 4; i++) {
+			u32 lf_level = clamp(lf->level + seg->lf_update[i],
+					     0, 63);
+
+			hantro_reg_write(vpu, &vp8_dec_lf_level[i], lf_level);
+		}
+	} else {
+		for (i = 0; i < 4; i++)
+			hantro_reg_write(vpu, &vp8_dec_lf_level[i],
+					 seg->lf_update[i]);
+	}
+
+	reg = G1_REG_REF_PIC_FILT_SHARPNESS(lf->sharpness_level);
+	if (lf->flags & V4L2_VP8_LF_FILTER_TYPE_SIMPLE)
+		reg |= G1_REG_REF_PIC_FILT_TYPE_E;
+	vdpu_write_relaxed(vpu, reg, G1_REG_REF_PIC(0));
+
+	if (lf->flags & V4L2_VP8_LF_HEADER_ADJ_ENABLE) {
+		for (i = 0; i < 4; i++) {
+			hantro_reg_write(vpu, &vp8_dec_mb_adj[i],
+					 lf->mb_mode_delta[i]);
+			hantro_reg_write(vpu, &vp8_dec_ref_adj[i],
+					 lf->ref_frm_delta[i]);
+		}
+	}
+}
+
+/*
+ * Set quantization parameters
+ */
+static void cfg_qp(struct hantro_ctx *ctx,
+		   const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	const struct v4l2_vp8_quantization_header *q = &hdr->quant_header;
+	const struct v4l2_vp8_segment_header *seg = &hdr->segment_header;
+	struct hantro_dev *vpu = ctx->dev;
+	unsigned int i;
+
+	if (!(seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED)) {
+		hantro_reg_write(vpu, &vp8_dec_quant[0], q->y_ac_qi);
+	} else if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE) {
+		for (i = 0; i < 4; i++) {
+			u32 quant = clamp(q->y_ac_qi + seg->quant_update[i],
+					  0, 127);
+
+			hantro_reg_write(vpu, &vp8_dec_quant[i], quant);
+		}
+	} else {
+		for (i = 0; i < 4; i++)
+			hantro_reg_write(vpu, &vp8_dec_quant[i],
+					 seg->quant_update[i]);
+	}
+
+	hantro_reg_write(vpu, &vp8_dec_quant_delta[0], q->y_dc_delta);
+	hantro_reg_write(vpu, &vp8_dec_quant_delta[1], q->y2_dc_delta);
+	hantro_reg_write(vpu, &vp8_dec_quant_delta[2], q->y2_ac_delta);
+	hantro_reg_write(vpu, &vp8_dec_quant_delta[3], q->uv_dc_delta);
+	hantro_reg_write(vpu, &vp8_dec_quant_delta[4], q->uv_ac_delta);
+}
+
+/*
+ * set control partition and DCT partition regs
+ *
+ * VP8 frame stream data layout:
+ *
+ *	                     first_part_size          parttion_sizes[0]
+ *                              ^                     ^
+ * src_dma                      |                     |
+ * ^                   +--------+------+        +-----+-----+
+ * |                   | control part  |        |           |
+ * +--------+----------------+------------------+-----------+-----+-----------+
+ * | tag 3B | extra 7B | hdr | mb_data | DCT sz | DCT part0 | ... | DCT partn |
+ * +--------+-----------------------------------+-----------+-----+-----------+
+ *                           |         |        |                             |
+ *                           v         +----+---+                             v
+ *                           mb_start       |                       src_dma_end
+ *                                          v
+ *                                       DCT size part
+ *                                      (num_dct-1)*3B
+ * Note:
+ *   1. only key-frames have extra 7-bytes
+ *   2. all offsets are base on src_dma
+ *   3. number of DCT parts is 1, 2, 4 or 8
+ *   4. the addresses set to the VPU must be 64-bits aligned
+ */
+static void cfg_parts(struct hantro_ctx *ctx,
+		      const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct vb2_v4l2_buffer *vb2_src;
+	u32 first_part_offset = VP8_FRAME_IS_KEY_FRAME(hdr) ? 10 : 3;
+	u32 mb_size, mb_offset_bytes, mb_offset_bits, mb_start_bits;
+	u32 dct_size_part_size, dct_part_offset;
+	struct hantro_reg reg;
+	dma_addr_t src_dma;
+	u32 dct_part_total_len = 0;
+	u32 count = 0;
+	unsigned int i;
+
+	vb2_src = hantro_get_src_buf(ctx);
+	src_dma = vb2_dma_contig_plane_dma_addr(&vb2_src->vb2_buf, 0);
+
+	/*
+	 * Calculate control partition mb data info
+	 * @first_part_header_bits:	bits offset of mb data from first
+	 *				part start pos
+	 * @mb_offset_bits:		bits offset of mb data from src_dma
+	 *				base addr
+	 * @mb_offset_byte:		bytes offset of mb data from src_dma
+	 *				base addr
+	 * @mb_start_bits:		bits offset of mb data from mb data
+	 *				64bits alignment addr
+	 */
+	mb_offset_bits = first_part_offset * 8 +
+			 hdr->first_part_header_bits + 8;
+	mb_offset_bytes = mb_offset_bits / 8;
+	mb_start_bits = mb_offset_bits -
+			(mb_offset_bytes & (~DEC_8190_ALIGN_MASK)) * 8;
+	mb_size = hdr->first_part_size -
+		  (mb_offset_bytes - first_part_offset) +
+		  (mb_offset_bytes & DEC_8190_ALIGN_MASK);
+
+	/* Macroblock data aligned base addr */
+	vdpu_write_relaxed(vpu, (mb_offset_bytes & (~DEC_8190_ALIGN_MASK))
+				+ src_dma, G1_REG_ADDR_REF(13));
+
+	/* Macroblock data start bits */
+	reg.base = G1_REG_DEC_CTRL2;
+	reg.mask = 0x3f;
+	reg.shift = 18;
+	hantro_reg_write(vpu, &reg, mb_start_bits);
+
+	/* Macroblock aligned data length */
+	reg.base = G1_REG_DEC_CTRL6;
+	reg.mask = 0x3fffff;
+	reg.shift = 0;
+	hantro_reg_write(vpu, &reg, mb_size + 1);
+
+	/*
+	 * Calculate DCT partition info
+	 * @dct_size_part_size: Containing sizes of DCT part, every DCT part
+	 *			has 3 bytes to store its size, except the last
+	 *			DCT part
+	 * @dct_part_offset:	bytes offset of DCT parts from src_dma base addr
+	 * @dct_part_total_len: total size of all DCT parts
+	 */
+	dct_size_part_size = (hdr->num_dct_parts - 1) * 3;
+	dct_part_offset = first_part_offset + hdr->first_part_size;
+	for (i = 0; i < hdr->num_dct_parts; i++)
+		dct_part_total_len += hdr->dct_part_sizes[i];
+	dct_part_total_len += dct_size_part_size;
+	dct_part_total_len += (dct_part_offset & DEC_8190_ALIGN_MASK);
+
+	/* Number of DCT partitions */
+	reg.base = G1_REG_DEC_CTRL6;
+	reg.mask = 0xf;
+	reg.shift = 24;
+	hantro_reg_write(vpu, &reg, hdr->num_dct_parts - 1);
+
+	/* DCT partition length */
+	vdpu_write_relaxed(vpu,
+			   G1_REG_DEC_CTRL3_STREAM_LEN(dct_part_total_len),
+			   G1_REG_DEC_CTRL3);
+
+	/* DCT partitions base address */
+	for (i = 0; i < hdr->num_dct_parts; i++) {
+		u32 byte_offset = dct_part_offset + dct_size_part_size + count;
+		u32 base_addr = byte_offset + src_dma;
+
+		hantro_reg_write(vpu, &vp8_dec_dct_base[i],
+				 base_addr & (~DEC_8190_ALIGN_MASK));
+
+		hantro_reg_write(vpu, &vp8_dec_dct_start_bits[i],
+				 (byte_offset & DEC_8190_ALIGN_MASK) * 8);
+
+		count += hdr->dct_part_sizes[i];
+	}
+}
+
+/*
+ * prediction filter taps
+ * normal 6-tap filters
+ */
+static void cfg_tap(struct hantro_ctx *ctx,
+		    const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct hantro_reg reg;
+	u32 val = 0;
+	int i, j;
+
+	reg.base = G1_REG_BD_REF_PIC(3);
+	reg.mask = 0xf;
+
+	if ((hdr->version & 0x03) != 0)
+		return; /* Tap filter not used. */
+
+	for (i = 0; i < 8; i++) {
+		val = (hantro_vp8_dec_mc_filter[i][0] << 2) |
+		       hantro_vp8_dec_mc_filter[i][5];
+
+		for (j = 0; j < 4; j++)
+			hantro_reg_write(vpu, &vp8_dec_pred_bc_tap[i][j],
+					 hantro_vp8_dec_mc_filter[i][j + 1]);
+
+		switch (i) {
+		case 2:
+			reg.shift = 8;
+			break;
+		case 4:
+			reg.shift = 4;
+			break;
+		case 6:
+			reg.shift = 0;
+			break;
+		default:
+			continue;
+		}
+
+		hantro_reg_write(vpu, &reg, val);
+	}
+}
+
+static void cfg_ref(struct hantro_ctx *ctx,
+		    const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
+	struct hantro_dev *vpu = ctx->dev;
+	struct vb2_v4l2_buffer *vb2_dst;
+	dma_addr_t ref;
+
+	vb2_dst = hantro_get_dst_buf(ctx);
+
+	ref = hantro_get_ref(cap_q, hdr->last_frame_ts);
+	if (!ref)
+		ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
+	vdpu_write_relaxed(vpu, ref, G1_REG_ADDR_REF(0));
+
+	ref = hantro_get_ref(cap_q, hdr->golden_frame_ts);
+	WARN_ON(!ref && hdr->golden_frame_ts);
+	if (!ref)
+		ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
+	if (hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN)
+		ref |= G1_REG_ADDR_REF_TOPC_E;
+	vdpu_write_relaxed(vpu, ref, G1_REG_ADDR_REF(4));
+
+	ref = hantro_get_ref(cap_q, hdr->alt_frame_ts);
+	WARN_ON(!ref && hdr->alt_frame_ts);
+	if (!ref)
+		ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
+	if (hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT)
+		ref |= G1_REG_ADDR_REF_TOPC_E;
+	vdpu_write_relaxed(vpu, ref, G1_REG_ADDR_REF(5));
+}
+
+static void cfg_buffers(struct hantro_ctx *ctx,
+			const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	const struct v4l2_vp8_segment_header *seg = &hdr->segment_header;
+	struct hantro_dev *vpu = ctx->dev;
+	struct vb2_v4l2_buffer *vb2_dst;
+	dma_addr_t dst_dma;
+	u32 reg;
+
+	vb2_dst = hantro_get_dst_buf(ctx);
+
+	/* Set probability table buffer address */
+	vdpu_write_relaxed(vpu, ctx->vp8_dec.prob_tbl.dma,
+			   G1_REG_ADDR_QTABLE);
+
+	/* Set segment map address */
+	reg = G1_REG_FWD_PIC1_SEGMENT_BASE(ctx->vp8_dec.segment_map.dma);
+	if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED) {
+		reg |= G1_REG_FWD_PIC1_SEGMENT_E;
+		if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP)
+			reg |= G1_REG_FWD_PIC1_SEGMENT_UPD_E;
+	}
+	vdpu_write_relaxed(vpu, reg, G1_REG_FWD_PIC(0));
+
+	dst_dma = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
+	vdpu_write_relaxed(vpu, dst_dma, G1_REG_ADDR_DST);
+}
+
+void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx)
+{
+	const struct v4l2_ctrl_vp8_frame_header *hdr;
+	struct hantro_dev *vpu = ctx->dev;
+	size_t height = ctx->dst_fmt.height;
+	size_t width = ctx->dst_fmt.width;
+	u32 mb_width, mb_height;
+	u32 reg;
+
+	hantro_prepare_run(ctx);
+
+	hdr = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER);
+	if (WARN_ON(!hdr))
+		return;
+
+	/* Reset segment_map buffer in keyframe */
+	if (VP8_FRAME_IS_KEY_FRAME(hdr) && ctx->vp8_dec.segment_map.cpu)
+		memset(ctx->vp8_dec.segment_map.cpu, 0,
+		       ctx->vp8_dec.segment_map.size);
+
+	hantro_vp8_prob_update(ctx, hdr);
+
+	reg = G1_REG_CONFIG_DEC_TIMEOUT_E |
+	      G1_REG_CONFIG_DEC_STRENDIAN_E |
+	      G1_REG_CONFIG_DEC_INSWAP32_E |
+	      G1_REG_CONFIG_DEC_STRSWAP32_E |
+	      G1_REG_CONFIG_DEC_OUTSWAP32_E |
+	      G1_REG_CONFIG_DEC_CLK_GATE_E |
+	      G1_REG_CONFIG_DEC_IN_ENDIAN |
+	      G1_REG_CONFIG_DEC_OUT_ENDIAN |
+	      G1_REG_CONFIG_DEC_MAX_BURST(16);
+	vdpu_write_relaxed(vpu, reg, G1_REG_CONFIG);
+
+	reg = G1_REG_DEC_CTRL0_DEC_MODE(10);
+	if (!VP8_FRAME_IS_KEY_FRAME(hdr))
+		reg |= G1_REG_DEC_CTRL0_PIC_INTER_E;
+	if (!(hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF))
+		reg |= G1_REG_DEC_CTRL0_SKIP_MODE;
+	if (hdr->lf_header.level == 0)
+		reg |= G1_REG_DEC_CTRL0_FILTERING_DIS;
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL0);
+
+	/* Frame dimensions */
+	mb_width = VP8_MB_WIDTH(width);
+	mb_height = VP8_MB_HEIGHT(height);
+	reg = G1_REG_DEC_CTRL1_PIC_MB_WIDTH(mb_width) |
+	      G1_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(mb_height) |
+	      G1_REG_DEC_CTRL1_PIC_MB_W_EXT(mb_width >> 9) |
+	      G1_REG_DEC_CTRL1_PIC_MB_H_EXT(mb_height >> 8);
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL1);
+
+	/* Boolean decoder */
+	reg = G1_REG_DEC_CTRL2_BOOLEAN_RANGE(hdr->coder_state.range)
+		| G1_REG_DEC_CTRL2_BOOLEAN_VALUE(hdr->coder_state.value);
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL2);
+
+	reg = 0;
+	if (hdr->version != 3)
+		reg |= G1_REG_DEC_CTRL4_VC1_HEIGHT_EXT;
+	if (hdr->version & 0x3)
+		reg |= G1_REG_DEC_CTRL4_BILIN_MC_E;
+	vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL4);
+
+	cfg_lf(ctx, hdr);
+	cfg_qp(ctx, hdr);
+	cfg_parts(ctx, hdr);
+	cfg_tap(ctx, hdr);
+	cfg_ref(ctx, hdr);
+	cfg_buffers(ctx, hdr);
+
+	hantro_finish_run(ctx);
+
+	vdpu_write(vpu, G1_REG_INTERRUPT_DEC_E, G1_REG_INTERRUPT);
+}
diff --git a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c b/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c
index 0c1e304..ecd34a7 100644
--- a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c
+++ b/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c
@@ -84,8 +84,10 @@
 	struct hantro_jpeg_ctx jpeg_ctx;
 	u32 reg;
 
-	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
-	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+	src_buf = hantro_get_src_buf(ctx);
+	dst_buf = hantro_get_dst_buf(ctx);
+
+	hantro_prepare_run(ctx);
 
 	memset(&jpeg_ctx, 0, sizeof(jpeg_ctx));
 	jpeg_ctx.buffer = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
@@ -119,7 +121,8 @@
 		| H1_REG_ENC_CTRL_ENC_MODE_JPEG
 		| H1_REG_ENC_PIC_INTRA
 		| H1_REG_ENC_CTRL_EN_BIT;
-	/* Kick the watchdog and start encoding */
-	schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000));
+
+	hantro_finish_run(ctx);
+
 	vepu_write(vpu, reg, H1_REG_ENC_CTRL);
 }
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c
new file mode 100644
index 0000000..0d758e0
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_h264.c
@@ -0,0 +1,646 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip RK3288 VPU codec driver
+ *
+ * Copyright (c) 2014 Rockchip Electronics Co., Ltd.
+ *	Hertz Wong <hertz.wong@rock-chips.com>
+ *	Herman Chen <herman.chen@rock-chips.com>
+ *
+ * Copyright (C) 2014 Google, Inc.
+ *	Tomasz Figa <tfiga@chromium.org>
+ */
+
+#include <linux/types.h>
+#include <linux/sort.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "hantro.h"
+#include "hantro_hw.h"
+
+/* Size with u32 units. */
+#define CABAC_INIT_BUFFER_SIZE		(460 * 2)
+#define POC_BUFFER_SIZE			34
+#define SCALING_LIST_SIZE		(6 * 16 + 6 * 64)
+
+#define POC_CMP(p0, p1) ((p0) < (p1) ? -1 : 1)
+
+/* Data structure describing auxiliary buffer format. */
+struct hantro_h264_dec_priv_tbl {
+	u32 cabac_table[CABAC_INIT_BUFFER_SIZE];
+	u32 poc[POC_BUFFER_SIZE];
+	u8 scaling_list[SCALING_LIST_SIZE];
+};
+
+/*
+ * Constant CABAC table.
+ * From drivers/media/platform/rk3288-vpu/rk3288_vpu_hw_h264d.c
+ * in https://chromium.googlesource.com/chromiumos/third_party/kernel,
+ * chromeos-3.14 branch.
+ */
+static const u32 h264_cabac_table[] = {
+	0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07330000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x000b0137,
+	0x0045ef7f, 0xf3660052, 0xf94aeb6b, 0xe57fe17f, 0xe87fee5f, 0xe57feb72,
+	0xe27fef7b, 0xf473f07a, 0xf573f43f, 0xfe44f154, 0xf368fd46, 0xf85df65a,
+	0xe27fff4a, 0xfa61f95b, 0xec7ffc38, 0xfb52f94c, 0xea7df95d, 0xf557fd4d,
+	0xfb47fc3f, 0xfc44f454, 0xf93ef941, 0x083d0538, 0xfe420140, 0x003dfe4e,
+	0x01320734, 0x0a23002c, 0x0b26012d, 0x002e052c, 0x1f110133, 0x07321c13,
+	0x10210e3e, 0xf36cf164, 0xf365f35b, 0xf45ef658, 0xf054f656, 0xf953f357,
+	0xed5e0146, 0x0048fb4a, 0x123bf866, 0xf164005f, 0xfc4b0248, 0xf54bfd47,
+	0x0f2ef345, 0x003e0041, 0x1525f148, 0x09391036, 0x003e0c48, 0x18000f09,
+	0x08190d12, 0x0f090d13, 0x0a250c12, 0x061d1421, 0x0f1e042d, 0x013a003e,
+	0x073d0c26, 0x0b2d0f27, 0x0b2a0d2c, 0x102d0c29, 0x0a311e22, 0x122a0a37,
+	0x1133112e, 0x00591aed, 0x16ef1aef, 0x1ee71cec, 0x21e925e5, 0x21e928e4,
+	0x26ef21f5, 0x28f129fa, 0x26012911, 0x1efa1b03, 0x1a1625f0, 0x23fc26f8,
+	0x26fd2503, 0x26052a00, 0x23102716, 0x0e301b25, 0x153c0c44, 0x0261fd47,
+	0xfa2afb32, 0xfd36fe3e, 0x003a013f, 0xfe48ff4a, 0xf75bfb43, 0xfb1bfd27,
+	0xfe2c002e, 0xf040f844, 0xf64efa4d, 0xf656f45c, 0xf137f63c, 0xfa3efc41,
+	0xf449f84c, 0xf950f758, 0xef6ef561, 0xec54f54f, 0xfa49fc4a, 0xf356f360,
+	0xf561ed75, 0xf84efb21, 0xfc30fe35, 0xfd3ef347, 0xf64ff456, 0xf35af261,
+	0x0000fa5d, 0xfa54f84f, 0x0042ff47, 0x003efe3c, 0xfe3bfb4b, 0xfd3efc3a,
+	0xf742ff4f, 0x00470344, 0x0a2cf93e, 0x0f240e28, 0x101b0c1d, 0x012c1424,
+	0x1220052a, 0x01300a3e, 0x112e0940, 0xf468f561, 0xf060f958, 0xf855f955,
+	0xf755f358, 0x0442fd4d, 0xfd4cfa4c, 0x0a3aff4c, 0xff53f963, 0xf25f025f,
+	0x004cfb4a, 0x0046f54b, 0x01440041, 0xf249033e, 0x043eff44, 0xf34b0b37,
+	0x05400c46, 0x0f060613, 0x07100c0e, 0x120d0d0b, 0x0d0f0f10, 0x0c170d17,
+	0x0f140e1a, 0x0e2c1128, 0x112f1811, 0x15151916, 0x1f1b161d, 0x13230e32,
+	0x0a39073f, 0xfe4dfc52, 0xfd5e0945, 0xf46d24dd, 0x24de20e6, 0x25e22ce0,
+	0x22ee22f1, 0x28f121f9, 0x23fb2100, 0x2602210d, 0x17230d3a, 0x1dfd1a00,
+	0x161e1ff9, 0x23f122fd, 0x220324ff, 0x2205200b, 0x2305220c, 0x270b1e1d,
+	0x221a1d27, 0x13421f15, 0x1f1f1932, 0xef78ec70, 0xee72f555, 0xf15cf259,
+	0xe647f151, 0xf2500044, 0xf246e838, 0xe944e832, 0xf54a17f3, 0x1af328f1,
+	0x31f22c03, 0x2d062c22, 0x21361352, 0xfd4bff17, 0x0122012b, 0x0036fe37,
+	0x003d0140, 0x0044f75c, 0xf26af361, 0xf15af45a, 0xee58f649, 0xf74ff256,
+	0xf649f646, 0xf645fb42, 0xf740fb3a, 0x023b15f6, 0x18f51cf8, 0x1cff1d03,
+	0x1d092314, 0x1d240e43, 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968,
+	0xfa35ff36, 0x07331721, 0x17021500, 0x01090031, 0xdb760539, 0xf34ef541,
+	0x013e0c31, 0xfc491132, 0x1240092b, 0x1d001a43, 0x105a0968, 0xd27fec68,
+	0x0143f34e, 0xf541013e, 0xfa56ef5f, 0xfa3d092d, 0xfd45fa51, 0xf5600637,
+	0x0743fb56, 0x0258003a, 0xfd4cf65e, 0x05360445, 0xfd510058, 0xf943fb4a,
+	0xfc4afb50, 0xf948013a, 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948,
+	0x0d29033e, 0x002dfc4e, 0xfd60e57e, 0xe462e765, 0xe943e452, 0xec5ef053,
+	0xea6eeb5b, 0xee66f35d, 0xe37ff95c, 0xfb59f960, 0xf36cfd2e, 0xff41ff39,
+	0xf75dfd4a, 0xf75cf857, 0xe97e0536, 0x063c063b, 0x0645ff30, 0x0044fc45,
+	0xf858fe55, 0xfa4eff4b, 0xf94d0236, 0x0532fd44, 0x0132062a, 0xfc51013f,
+	0xfc460043, 0x0239fe4c, 0x0b230440, 0x013d0b23, 0x12190c18, 0x0d1d0d24,
+	0xf65df949, 0xfe490d2e, 0x0931f964, 0x09350235, 0x0535fe3d, 0x00380038,
+	0xf33ffb3c, 0xff3e0439, 0xfa450439, 0x0e270433, 0x0d440340, 0x013d093f,
+	0x07321027, 0x052c0434, 0x0b30fb3c, 0xff3b003b, 0x1621052c, 0x0e2bff4e,
+	0x003c0945, 0x0b1c0228, 0x032c0031, 0x002e022c, 0x0233002f, 0x0427023e,
+	0x062e0036, 0x0336023a, 0x043f0633, 0x06390735, 0x06340637, 0x0b2d0e24,
+	0x0835ff52, 0x0737fd4e, 0x0f2e161f, 0xff541907, 0x1ef91c03, 0x1c042000,
+	0x22ff1e06, 0x1e062009, 0x1f131a1b, 0x1a1e2514, 0x1c221146, 0x0143053b,
+	0x0943101e, 0x12201223, 0x161d181f, 0x1726122b, 0x14290b3f, 0x093b0940,
+	0xff5efe59, 0xf76cfa4c, 0xfe2c002d, 0x0034fd40, 0xfe3bfc46, 0xfc4bf852,
+	0xef66f74d, 0x0318002a, 0x00300037, 0xfa3bf947, 0xf453f557, 0xe277013a,
+	0xfd1dff24, 0x0126022b, 0xfa37003a, 0x0040fd4a, 0xf65a0046, 0xfc1d051f,
+	0x072a013b, 0xfe3afd48, 0xfd51f561, 0x003a0805, 0x0a0e0e12, 0x0d1b0228,
+	0x003afd46, 0xfa4ff855, 0x0000f36a, 0xf06af657, 0xeb72ee6e, 0xf262ea6e,
+	0xeb6aee67, 0xeb6be96c, 0xe670f660, 0xf45ffb5b, 0xf75dea5e, 0xfb560943,
+	0xfc50f655, 0xff46073c, 0x093a053d, 0x0c320f32, 0x12311136, 0x0a29072e,
+	0xff330731, 0x08340929, 0x062f0237, 0x0d290a2c, 0x06320535, 0x0d31043f,
+	0x0640fe45, 0xfe3b0646, 0x0a2c091f, 0x0c2b0335, 0x0e220a26, 0xfd340d28,
+	0x1120072c, 0x07260d32, 0x0a391a2b, 0x0e0b0b0e, 0x090b120b, 0x150917fe,
+	0x20f120f1, 0x22eb27e9, 0x2adf29e1, 0x2ee426f4, 0x151d2de8, 0x35d330e6,
+	0x41d52bed, 0x27f61e09, 0x121a141b, 0x0039f252, 0xfb4bed61, 0xdd7d1b00,
+	0x1c001ffc, 0x1b062208, 0x1e0a1816, 0x21131620, 0x1a1f1529, 0x1a2c172f,
+	0x10410e47, 0x083c063f, 0x11411518, 0x17141a17, 0x1b201c17, 0x1c181728,
+	0x18201c1d, 0x172a1339, 0x1635163d, 0x0b560c28, 0x0b330e3b, 0xfc4ff947,
+	0xfb45f746, 0xf842f644, 0xed49f445, 0xf046f143, 0xec3eed46, 0xf042ea41,
+	0xec3f09fe, 0x1af721f7, 0x27f929fe, 0x2d033109, 0x2d1b243b, 0xfa42f923,
+	0xf92af82d, 0xfb30f438, 0xfa3cfb3e, 0xf842f84c, 0xfb55fa51, 0xf64df951,
+	0xef50ee49, 0xfc4af653, 0xf747f743, 0xff3df842, 0xf242003b, 0x023b15f3,
+	0x21f227f9, 0x2efe3302, 0x3c063d11, 0x37222a3e, 0x14f10236, 0x034a14f1,
+	0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331619, 0x22001000, 0xfe090429,
+	0xe3760241, 0xfa47f34f, 0x05340932, 0xfd460a36, 0x1a221316, 0x28003902,
+	0x29241a45, 0xd37ff165, 0xfc4cfa47, 0xf34f0534, 0x0645f35a, 0x0034082b,
+	0xfe45fb52, 0xf660023b, 0x024bfd57, 0xfd640138, 0xfd4afa55, 0x003bfd51,
+	0xf956fb5f, 0xff42ff4d, 0x0146fe56, 0xfb48003d, 0x0029003f, 0x003f003f,
+	0xf7530456, 0x0061f948, 0x0d29033e, 0x0d0f0733, 0x0250d97f, 0xee5bef60,
+	0xe651dd62, 0xe866e961, 0xe577e863, 0xeb6eee66, 0xdc7f0050, 0xfb59f95e,
+	0xfc5c0027, 0x0041f154, 0xdd7ffe49, 0xf468f75b, 0xe17f0337, 0x07380737,
+	0x083dfd35, 0x0044f94a, 0xf758f367, 0xf35bf759, 0xf25cf84c, 0xf457e96e,
+	0xe869f64e, 0xec70ef63, 0xb27fba7f, 0xce7fd27f, 0xfc42fb4e, 0xfc47f848,
+	0x023bff37, 0xf946fa4b, 0xf859de77, 0xfd4b2014, 0x1e16d47f, 0x0036fb3d,
+	0x003aff3c, 0xfd3df843, 0xe754f24a, 0xfb410534, 0x0239003d, 0xf745f546,
+	0x1237fc47, 0x003a073d, 0x09291219, 0x0920052b, 0x092f002c, 0x0033022e,
+	0x1326fc42, 0x0f260c2a, 0x09220059, 0x042d0a1c, 0x0a1f21f5, 0x34d5120f,
+	0x1c0023ea, 0x26e72200, 0x27ee20f4, 0x66a20000, 0x38f121fc, 0x1d0a25fb,
+	0x33e327f7, 0x34de45c6, 0x43c12cfb, 0x200737e3, 0x20010000, 0x1b2421e7,
+	0x22e224e4, 0x26e426e5, 0x22ee23f0, 0x22f220f8, 0x25fa2300, 0x1e0a1c12,
+	0x1a191d29, 0x004b0248, 0x084d0e23, 0x121f1123, 0x151e112d, 0x142a122d,
+	0x1b1a1036, 0x07421038, 0x0b490a43, 0xf674e970, 0xf147f93d, 0x0035fb42,
+	0xf54df750, 0xf754f657, 0xde7feb65, 0xfd27fb35, 0xf93df54b, 0xf14def5b,
+	0xe76be76f, 0xe47af54c, 0xf62cf634, 0xf639f73a, 0xf048f945, 0xfc45fb4a,
+	0xf7560242, 0xf7220120, 0x0b1f0534, 0xfe37fe43, 0x0049f859, 0x03340704,
+	0x0a081108, 0x10130325, 0xff3dfb49, 0xff46fc4e, 0x0000eb7e, 0xe97cec6e,
+	0xe67ee77c, 0xef69e579, 0xe575ef66, 0xe675e574, 0xdf7af65f, 0xf264f85f,
+	0xef6fe472, 0xfa59fe50, 0xfc52f755, 0xf851ff48, 0x05400143, 0x09380045,
+	0x01450745, 0xf945fa43, 0xf04dfe40, 0x023dfa43, 0xfd400239, 0xfd41fd42,
+	0x003e0933, 0xff42fe47, 0xfe4bff46, 0xf7480e3c, 0x1025002f, 0x12230b25,
+	0x0c290a29, 0x02300c29, 0x0d29003b, 0x03321328, 0x03421232, 0x13fa12fa,
+	0x0e001af4, 0x1ff021e7, 0x21ea25e4, 0x27e22ae2, 0x2fd62ddc, 0x31de29ef,
+	0x200945b9, 0x3fc142c0, 0x4db636d9, 0x34dd29f6, 0x240028ff, 0x1e0e1c1a,
+	0x17250c37, 0x0b4125df, 0x27dc28db, 0x26e22edf, 0x2ae228e8, 0x31e326f4,
+	0x28f626fd, 0x2efb1f14, 0x1d1e192c, 0x0c300b31, 0x1a2d1616, 0x17161b15,
+	0x21141a1c, 0x1e181b22, 0x122a1927, 0x12320c46, 0x15360e47, 0x0b531920,
+	0x15311536, 0xfb55fa51, 0xf64df951, 0xef50ee49, 0xfc4af653, 0xf747f743,
+	0xff3df842, 0xf242003b, 0x023b11f6, 0x20f32af7, 0x31fb3500, 0x4003440a,
+	0x421b2f39, 0xfb470018, 0xff24fe2a, 0xfe34f739, 0xfa3ffc41, 0xfc43f952,
+	0xfd51fd4c, 0xf948fa4e, 0xf448f244, 0xfd46fa4c, 0xfb42fb3e, 0x0039fc3d,
+	0xf73c0136, 0x023a11f6, 0x20f32af7, 0x31fb3500, 0x4003440a, 0x421b2f39,
+	0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331d10,
+	0x19000e00, 0xf633fd3e, 0xe5631a10, 0xfc55e866, 0x05390639, 0xef490e39,
+	0x1428140a, 0x1d003600, 0x252a0c61, 0xe07fea75, 0xfe4afc55, 0xe8660539,
+	0xfa5df258, 0xfa2c0437, 0xf559f167, 0xeb741339, 0x143a0454, 0x0660013f,
+	0xfb55f36a, 0x053f064b, 0xfd5aff65, 0x0337fc4f, 0xfe4bf461, 0xf932013c,
+	0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x0722f758,
+	0xec7fdc7f, 0xef5bf25f, 0xe754e756, 0xf459ef5b, 0xe17ff24c, 0xee67f35a,
+	0xdb7f0b50, 0x054c0254, 0x054efa37, 0x043df253, 0xdb7ffb4f, 0xf568f55b,
+	0xe27f0041, 0xfe4f0048, 0xfc5cfa38, 0x0344f847, 0xf362fc56, 0xf458fb52,
+	0xfd48fc43, 0xf848f059, 0xf745ff3b, 0x05420439, 0xfc47fe47, 0x023aff4a,
+	0xfc2cff45, 0x003ef933, 0xfc2ffa2a, 0xfd29fa35, 0x084cf74e, 0xf5530934,
+	0x0043fb5a, 0x0143f148, 0xfb4bf850, 0xeb53eb40, 0xf31fe740, 0xe35e094b,
+	0x113ff84a, 0xfb23fe1b, 0x0d5b0341, 0xf945084d, 0xf642033e, 0xfd44ec51,
+	0x001e0107, 0xfd17eb4a, 0x1042e97c, 0x11252cee, 0x32deea7f, 0x0427002a,
+	0x07220b1d, 0x081f0625, 0x072a0328, 0x08210d2b, 0x0d24042f, 0x0337023a,
+	0x063c082c, 0x0b2c0e2a, 0x07300438, 0x04340d25, 0x0931133a, 0x0a300c2d,
+	0x00451421, 0x083f23ee, 0x21e71cfd, 0x180a1b00, 0x22f234d4, 0x27e81311,
+	0x1f19241d, 0x1821220f, 0x1e141649, 0x1422131f, 0x1b2c1310, 0x0f240f24,
+	0x151c1915, 0x1e141f0c, 0x1b10182a, 0x005d0e38, 0x0f391a26, 0xe87fe873,
+	0xea52f73e, 0x0035003b, 0xf255f359, 0xf35ef55c, 0xe37feb64, 0xf239f443,
+	0xf547f64d, 0xeb55f058, 0xe968f162, 0xdb7ff652, 0xf830f83d, 0xf842f946,
+	0xf24bf64f, 0xf753f45c, 0xee6cfc4f, 0xea45f04b, 0xfe3a013a, 0xf34ef753,
+	0xfc51f363, 0xf351fa26, 0xf33efa3a, 0xfe3bf049, 0xf64cf356, 0xf753f657,
+	0x0000ea7f, 0xe77fe778, 0xe57fed72, 0xe975e776, 0xe675e871, 0xe476e178,
+	0xdb7cf65e, 0xf166f663, 0xf36ace7f, 0xfb5c1139, 0xfb56f35e, 0xf45bfe4d,
+	0x0047ff49, 0x0440f951, 0x05400f39, 0x01430044, 0xf6430144, 0x004d0240,
+	0x0044fb4e, 0x0737053b, 0x02410e36, 0x0f2c053c, 0x0246fe4c, 0xee560c46,
+	0x0540f446, 0x0b370538, 0x00450241, 0xfa4a0536, 0x0736fa4c, 0xf552fe4d,
+	0xfe4d192a, 0x11f310f7, 0x11f41beb, 0x25e229d8, 0x2ad730d1, 0x27e02ed8,
+	0x34cd2ed7, 0x34d92bed, 0x200b3dc9, 0x38d23ece, 0x51bd2dec, 0x23fe1c0f,
+	0x22012701, 0x1e111426, 0x122d0f36, 0x004f24f0, 0x25f225ef, 0x2001220f,
+	0x1d0f1819, 0x22161f10, 0x23121f1c, 0x2129241c, 0x1b2f153e, 0x121f131a,
+	0x24181817, 0x1b10181e, 0x1f1d1629, 0x162a103c, 0x0f340e3c, 0x034ef07b,
+	0x15351638, 0x193d1521, 0x1332113d, 0xfd4ef84a, 0xf748f648, 0xee4bf447,
+	0xf53ffb46, 0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc,
+	0x21ff2107, 0x1f0c2517, 0x1f261440, 0xf747f925, 0xf82cf531, 0xf638f43b,
+	0xf83ff743, 0xfa44f64f, 0xfd4ef84a, 0xf748f648, 0xee4bf447, 0xf53ffb46,
+	0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc, 0x21ff2107,
+	0x1f0c2517, 0x1f261440
+};
+
+/*
+ * NOTE: The scaling lists are in zig-zag order, apply inverse scanning process
+ * to get the values in matrix order. In addition, the hardware requires bytes
+ * swapped within each subsequent 4 bytes. Both arrays below include both
+ * transformations.
+ */
+static const u32 zig_zag_4x4[] = {
+	3, 2, 7, 11, 6, 1, 0, 5, 10, 15, 14, 9, 4, 8, 13, 12
+};
+
+static const u32 zig_zag_8x8[] = {
+	3, 2, 11, 19, 10, 1, 0, 9, 18, 27, 35, 26, 17, 8, 7, 6,
+	15, 16, 25, 34, 43, 51, 42, 33, 24, 23, 14, 5, 4, 13, 22, 31,
+	32, 41, 50, 59, 58, 49, 40, 39, 30, 21, 12, 20, 29, 38, 47, 48,
+	57, 56, 55, 46, 37, 28, 36, 45, 54, 63, 62, 53, 44, 52, 61, 60
+};
+
+static void
+reorder_scaling_list(struct hantro_ctx *ctx)
+{
+	const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
+	const struct v4l2_ctrl_h264_scaling_matrix *scaling = ctrls->scaling;
+	const size_t num_list_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4);
+	const size_t list_len_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4[0]);
+	const size_t num_list_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8);
+	const size_t list_len_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8[0]);
+	struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu;
+	u8 *dst = tbl->scaling_list;
+	const u8 *src;
+	int i, j;
+
+	BUILD_BUG_ON(ARRAY_SIZE(zig_zag_4x4) != list_len_4x4);
+	BUILD_BUG_ON(ARRAY_SIZE(zig_zag_8x8) != list_len_8x8);
+	BUILD_BUG_ON(ARRAY_SIZE(tbl->scaling_list) !=
+		     num_list_4x4 * list_len_4x4 +
+		     num_list_8x8 * list_len_8x8);
+
+	src = &scaling->scaling_list_4x4[0][0];
+	for (i = 0; i < num_list_4x4; ++i) {
+		for (j = 0; j < list_len_4x4; ++j)
+			dst[zig_zag_4x4[j]] = src[j];
+		src += list_len_4x4;
+		dst += list_len_4x4;
+	}
+
+	src = &scaling->scaling_list_8x8[0][0];
+	for (i = 0; i < num_list_8x8; ++i) {
+		for (j = 0; j < list_len_8x8; ++j)
+			dst[zig_zag_8x8[j]] = src[j];
+		src += list_len_8x8;
+		dst += list_len_8x8;
+	}
+}
+
+static void prepare_table(struct hantro_ctx *ctx)
+{
+	const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
+	const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode;
+	struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu;
+	const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
+	int i;
+
+	for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) {
+		tbl->poc[i * 2] = dpb[i].top_field_order_cnt;
+		tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt;
+	}
+
+	tbl->poc[32] = dec_param->top_field_order_cnt;
+	tbl->poc[33] = dec_param->bottom_field_order_cnt;
+
+	reorder_scaling_list(ctx);
+}
+
+struct hantro_h264_reflist_builder {
+	const struct v4l2_h264_dpb_entry *dpb;
+	s32 pocs[HANTRO_H264_DPB_SIZE];
+	u8 unordered_reflist[HANTRO_H264_DPB_SIZE];
+	s32 curpoc;
+	u8 num_valid;
+};
+
+static s32 get_poc(enum v4l2_field field, s32 top_field_order_cnt,
+		   s32 bottom_field_order_cnt)
+{
+	switch (field) {
+	case V4L2_FIELD_TOP:
+		return top_field_order_cnt;
+	case V4L2_FIELD_BOTTOM:
+		return bottom_field_order_cnt;
+	default:
+		break;
+	}
+
+	return min(top_field_order_cnt, bottom_field_order_cnt);
+}
+
+static void
+init_reflist_builder(struct hantro_ctx *ctx,
+		     struct hantro_h264_reflist_builder *b)
+{
+	const struct v4l2_ctrl_h264_decode_params *dec_param;
+	struct vb2_v4l2_buffer *buf = hantro_get_dst_buf(ctx);
+	const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
+	struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
+	unsigned int i;
+
+	dec_param = ctx->h264_dec.ctrls.decode;
+
+	memset(b, 0, sizeof(*b));
+	b->dpb = dpb;
+	b->curpoc = get_poc(buf->field, dec_param->top_field_order_cnt,
+			    dec_param->bottom_field_order_cnt);
+
+	for (i = 0; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++) {
+		int buf_idx;
+
+		if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+			continue;
+
+		buf_idx = vb2_find_timestamp(cap_q, dpb[i].reference_ts, 0);
+		if (buf_idx < 0)
+			continue;
+
+		buf = to_vb2_v4l2_buffer(vb2_get_buffer(cap_q, buf_idx));
+		b->pocs[i] = get_poc(buf->field, dpb[i].top_field_order_cnt,
+				     dpb[i].bottom_field_order_cnt);
+		b->unordered_reflist[b->num_valid] = i;
+		b->num_valid++;
+	}
+
+	for (i = b->num_valid; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++)
+		b->unordered_reflist[i] = i;
+}
+
+static int p_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
+{
+	const struct hantro_h264_reflist_builder *builder = data;
+	const struct v4l2_h264_dpb_entry *a, *b;
+	u8 idxa, idxb;
+
+	idxa = *((u8 *)ptra);
+	idxb = *((u8 *)ptrb);
+	a = &builder->dpb[idxa];
+	b = &builder->dpb[idxb];
+
+	if ((a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) !=
+	    (b->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) {
+		/* Short term pics firt. */
+		if (!(a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
+			return -1;
+		else
+			return 1;
+	}
+
+	/*
+	 * Short term pics in descending pic num order, long term ones in
+	 * ascending order.
+	 */
+	if (!(a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
+		return b->frame_num - a->frame_num;
+
+	return a->pic_num - b->pic_num;
+}
+
+static int b0_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
+{
+	const struct hantro_h264_reflist_builder *builder = data;
+	const struct v4l2_h264_dpb_entry *a, *b;
+	s32 poca, pocb;
+	u8 idxa, idxb;
+
+	idxa = *((u8 *)ptra);
+	idxb = *((u8 *)ptrb);
+	a = &builder->dpb[idxa];
+	b = &builder->dpb[idxb];
+
+	if ((a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) !=
+	    (b->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) {
+		/* Short term pics firt. */
+		if (!(a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
+			return -1;
+		else
+			return 1;
+	}
+
+	/* Long term pics in ascending pic num order. */
+	if (a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
+		return a->pic_num - b->pic_num;
+
+	poca = builder->pocs[idxa];
+	pocb = builder->pocs[idxb];
+
+	/*
+	 * Short term pics with POC < cur POC first in POC descending order
+	 * followed by short term pics with POC > cur POC in POC ascending
+	 * order.
+	 */
+	if ((poca < builder->curpoc) != (pocb < builder->curpoc))
+		return POC_CMP(poca, pocb);
+	else if (poca < builder->curpoc)
+		return POC_CMP(pocb, poca);
+
+	return POC_CMP(poca, pocb);
+}
+
+static int b1_ref_list_cmp(const void *ptra, const void *ptrb, const void *data)
+{
+	const struct hantro_h264_reflist_builder *builder = data;
+	const struct v4l2_h264_dpb_entry *a, *b;
+	s32 poca, pocb;
+	u8 idxa, idxb;
+
+	idxa = *((u8 *)ptra);
+	idxb = *((u8 *)ptrb);
+	a = &builder->dpb[idxa];
+	b = &builder->dpb[idxb];
+
+	if ((a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) !=
+	    (b->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)) {
+		/* Short term pics firt. */
+		if (!(a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
+			return -1;
+		else
+			return 1;
+	}
+
+	/* Long term pics in ascending pic num order. */
+	if (a->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
+		return a->pic_num - b->pic_num;
+
+	poca = builder->pocs[idxa];
+	pocb = builder->pocs[idxb];
+
+	/*
+	 * Short term pics with POC > cur POC first in POC ascending order
+	 * followed by short term pics with POC > cur POC in POC descending
+	 * order.
+	 */
+	if ((poca < builder->curpoc) != (pocb < builder->curpoc))
+		return POC_CMP(pocb, poca);
+	else if (poca < builder->curpoc)
+		return POC_CMP(pocb, poca);
+
+	return POC_CMP(poca, pocb);
+}
+
+static void
+build_p_ref_list(const struct hantro_h264_reflist_builder *builder,
+		 u8 *reflist)
+{
+	memcpy(reflist, builder->unordered_reflist,
+	       sizeof(builder->unordered_reflist));
+	sort_r(reflist, builder->num_valid, sizeof(*reflist),
+	       p_ref_list_cmp, NULL, builder);
+}
+
+static void
+build_b_ref_lists(const struct hantro_h264_reflist_builder *builder,
+		  u8 *b0_reflist, u8 *b1_reflist)
+{
+	memcpy(b0_reflist, builder->unordered_reflist,
+	       sizeof(builder->unordered_reflist));
+	sort_r(b0_reflist, builder->num_valid, sizeof(*b0_reflist),
+	       b0_ref_list_cmp, NULL, builder);
+
+	memcpy(b1_reflist, builder->unordered_reflist,
+	       sizeof(builder->unordered_reflist));
+	sort_r(b1_reflist, builder->num_valid, sizeof(*b1_reflist),
+	       b1_ref_list_cmp, NULL, builder);
+
+	if (builder->num_valid > 1 &&
+	    !memcmp(b1_reflist, b0_reflist, builder->num_valid))
+		swap(b1_reflist[0], b1_reflist[1]);
+}
+
+static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
+			    const struct v4l2_h264_dpb_entry *b)
+{
+	return a->top_field_order_cnt == b->top_field_order_cnt &&
+	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
+}
+
+static void update_dpb(struct hantro_ctx *ctx)
+{
+	const struct v4l2_ctrl_h264_decode_params *dec_param;
+	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	unsigned int i, j;
+
+	dec_param = ctx->h264_dec.ctrls.decode;
+
+	/* Disable all entries by default. */
+	for (i = 0; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++)
+		ctx->h264_dec.dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
+
+	/* Try to match new DPB entries with existing ones by their POCs. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+
+		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+			continue;
+
+		/*
+		 * To cut off some comparisons, iterate only on target DPB
+		 * entries which are not used yet.
+		 */
+		for_each_clear_bit(j, used, ARRAY_SIZE(ctx->h264_dec.dpb)) {
+			struct v4l2_h264_dpb_entry *cdpb;
+
+			cdpb = &ctx->h264_dec.dpb[j];
+			if (cdpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE ||
+			    !dpb_entry_match(cdpb, ndpb))
+				continue;
+
+			*cdpb = *ndpb;
+			set_bit(j, used);
+			break;
+		}
+
+		if (j == ARRAY_SIZE(ctx->h264_dec.dpb))
+			set_bit(i, new);
+	}
+
+	/* For entries that could not be matched, use remaining free slots. */
+	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+		struct v4l2_h264_dpb_entry *cdpb;
+
+		/*
+		 * Both arrays are of the same sizes, so there is no way
+		 * we can end up with no space in target array, unless
+		 * something is buggy.
+		 */
+		j = find_first_zero_bit(used, ARRAY_SIZE(ctx->h264_dec.dpb));
+		if (WARN_ON(j >= ARRAY_SIZE(ctx->h264_dec.dpb)))
+			return;
+
+		cdpb = &ctx->h264_dec.dpb[j];
+		*cdpb = *ndpb;
+		set_bit(j, used);
+	}
+}
+
+struct vb2_buffer *hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
+					   unsigned int dpb_idx)
+{
+	struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
+	struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
+	struct vb2_buffer *buf;
+	int buf_idx = -1;
+
+	if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
+		buf_idx = vb2_find_timestamp(cap_q,
+					     dpb[dpb_idx].reference_ts, 0);
+
+	if (buf_idx >= 0) {
+		buf = vb2_get_buffer(cap_q, buf_idx);
+	} else {
+		struct vb2_v4l2_buffer *dst_buf;
+
+		/*
+		 * If a DPB entry is unused or invalid, address of current
+		 * destination buffer is returned.
+		 */
+		dst_buf = hantro_get_dst_buf(ctx);
+		buf = &dst_buf->vb2_buf;
+	}
+
+	return buf;
+}
+
+int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx)
+{
+	struct hantro_h264_dec_hw_ctx *h264_ctx = &ctx->h264_dec;
+	struct hantro_h264_dec_ctrls *ctrls = &h264_ctx->ctrls;
+	struct hantro_h264_reflist_builder reflist_builder;
+
+	hantro_prepare_run(ctx);
+
+	ctrls->scaling =
+		hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX);
+	if (WARN_ON(!ctrls->scaling))
+		return -EINVAL;
+
+	ctrls->decode =
+		hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
+	if (WARN_ON(!ctrls->decode))
+		return -EINVAL;
+
+	ctrls->slices =
+		hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
+	if (WARN_ON(!ctrls->slices))
+		return -EINVAL;
+
+	ctrls->sps =
+		hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_SPS);
+	if (WARN_ON(!ctrls->sps))
+		return -EINVAL;
+
+	ctrls->pps =
+		hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_PPS);
+	if (WARN_ON(!ctrls->pps))
+		return -EINVAL;
+
+	/* Update the DPB with new refs. */
+	update_dpb(ctx);
+
+	/* Prepare data in memory. */
+	prepare_table(ctx);
+
+	/* Build the P/B{0,1} ref lists. */
+	init_reflist_builder(ctx, &reflist_builder);
+	build_p_ref_list(&reflist_builder, h264_ctx->reflists.p);
+	build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
+			  h264_ctx->reflists.b1);
+	return 0;
+}
+
+void hantro_h264_dec_exit(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct hantro_h264_dec_hw_ctx *h264_dec = &ctx->h264_dec;
+	struct hantro_aux_buf *priv = &h264_dec->priv;
+
+	dma_free_coherent(vpu->dev, priv->size, priv->cpu, priv->dma);
+}
+
+int hantro_h264_dec_init(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct hantro_h264_dec_hw_ctx *h264_dec = &ctx->h264_dec;
+	struct hantro_aux_buf *priv = &h264_dec->priv;
+	struct hantro_h264_dec_priv_tbl *tbl;
+	struct v4l2_pix_format_mplane pix_mp;
+
+	priv->cpu = dma_alloc_coherent(vpu->dev, sizeof(*tbl), &priv->dma,
+				       GFP_KERNEL);
+	if (!priv->cpu)
+		return -ENOMEM;
+
+	priv->size = sizeof(*tbl);
+	tbl = priv->cpu;
+	memcpy(tbl->cabac_table, h264_cabac_table, sizeof(tbl->cabac_table));
+
+	v4l2_fill_pixfmt_mp(&pix_mp, ctx->dst_fmt.pixelformat,
+			    ctx->dst_fmt.width, ctx->dst_fmt.height);
+	h264_dec->pic_size = pix_mp.plane_fmt[0].sizeimage;
+
+	return 0;
+}
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index 3c361c2..2fab655 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -11,9 +11,13 @@
 
 #include <linux/interrupt.h>
 #include <linux/v4l2-controls.h>
+#include <media/h264-ctrls.h>
 #include <media/mpeg2-ctrls.h>
+#include <media/vp8-ctrls.h>
 #include <media/videobuf2-core.h>
 
+#define DEC_8190_ALIGN_MASK	0x07U
+
 struct hantro_dev;
 struct hantro_ctx;
 struct hantro_buf;
@@ -39,6 +43,54 @@
 	struct hantro_aux_buf bounce_buffer;
 };
 
+/* Max. number of entries in the DPB (HW limitation). */
+#define HANTRO_H264_DPB_SIZE		16
+
+/**
+ * struct hantro_h264_dec_ctrls
+ * @decode:	Decode params
+ * @scaling:	Scaling info
+ * @slice:	Slice params
+ * @sps:	SPS info
+ * @pps:	PPS info
+ */
+struct hantro_h264_dec_ctrls {
+	const struct v4l2_ctrl_h264_decode_params *decode;
+	const struct v4l2_ctrl_h264_scaling_matrix *scaling;
+	const struct v4l2_ctrl_h264_slice_params *slices;
+	const struct v4l2_ctrl_h264_sps *sps;
+	const struct v4l2_ctrl_h264_pps *pps;
+};
+
+/**
+ * struct hantro_h264_dec_reflists
+ * @p:		P reflist
+ * @b0:		B0 reflist
+ * @b1:		B1 reflist
+ */
+struct hantro_h264_dec_reflists {
+	u8 p[HANTRO_H264_DPB_SIZE];
+	u8 b0[HANTRO_H264_DPB_SIZE];
+	u8 b1[HANTRO_H264_DPB_SIZE];
+};
+
+/**
+ * struct hantro_h264_dec_hw_ctx
+ * @priv:	Private auxiliary buffer for hardware.
+ * @dpb:	DPB
+ * @reflists:	P/B0/B1 reflists
+ * @ctrls:	V4L2 controls attached to a run
+ * @pic_size:	Size in bytes of decoded picture, this is needed
+ *		to pass the location of motion vectors.
+ */
+struct hantro_h264_dec_hw_ctx {
+	struct hantro_aux_buf priv;
+	struct v4l2_h264_dpb_entry dpb[HANTRO_H264_DPB_SIZE];
+	struct hantro_h264_dec_reflists reflists;
+	struct hantro_h264_dec_ctrls ctrls;
+	size_t pic_size;
+};
+
 /**
  * struct hantro_mpeg2_dec_hw_ctx
  * @qtable:		Quantization table
@@ -48,6 +100,16 @@
 };
 
 /**
+ * struct hantro_vp8d_hw_ctx
+ * @segment_map:	Segment map buffer.
+ * @prob_tbl:		Probability table buffer.
+ */
+struct hantro_vp8_dec_hw_ctx {
+	struct hantro_aux_buf segment_map;
+	struct hantro_aux_buf prob_tbl;
+};
+
+/**
  * struct hantro_codec_ops - codec mode specific operations
  *
  * @init:	If needed, can be used for initialization.
@@ -82,16 +144,27 @@
 extern const struct hantro_variant rk3328_vpu_variant;
 extern const struct hantro_variant rk3288_vpu_variant;
 
+extern const u32 hantro_vp8_dec_mc_filter[8][6];
+
 void hantro_watchdog(struct work_struct *work);
 void hantro_run(struct hantro_ctx *ctx);
 void hantro_irq_done(struct hantro_dev *vpu, unsigned int bytesused,
 		     enum vb2_buffer_state result);
+void hantro_prepare_run(struct hantro_ctx *ctx);
+void hantro_finish_run(struct hantro_ctx *ctx);
 
 void hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx);
 void rk3399_vpu_jpeg_enc_run(struct hantro_ctx *ctx);
 int hantro_jpeg_enc_init(struct hantro_ctx *ctx);
 void hantro_jpeg_enc_exit(struct hantro_ctx *ctx);
 
+struct vb2_buffer *hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
+					   unsigned int dpb_idx);
+int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx);
+void hantro_g1_h264_dec_run(struct hantro_ctx *ctx);
+int hantro_h264_dec_init(struct hantro_ctx *ctx);
+void hantro_h264_dec_exit(struct hantro_ctx *ctx);
+
 void hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx);
 void rk3399_vpu_mpeg2_dec_run(struct hantro_ctx *ctx);
 void hantro_mpeg2_dec_copy_qtable(u8 *qtable,
@@ -99,4 +172,11 @@
 int hantro_mpeg2_dec_init(struct hantro_ctx *ctx);
 void hantro_mpeg2_dec_exit(struct hantro_ctx *ctx);
 
+void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx);
+void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx);
+int hantro_vp8_dec_init(struct hantro_ctx *ctx);
+void hantro_vp8_dec_exit(struct hantro_ctx *ctx);
+void hantro_vp8_prob_update(struct hantro_ctx *ctx,
+			    const struct v4l2_ctrl_vp8_frame_header *hdr);
+
 #endif /* HANTRO_HW_H_ */
diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c
index 68f45ee..3dae52a 100644
--- a/drivers/staging/media/hantro/hantro_v4l2.c
+++ b/drivers/staging/media/hantro/hantro_v4l2.c
@@ -239,6 +239,15 @@
 		/* Fill remaining fields */
 		v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width,
 				    pix_mp->height);
+		/*
+		 * The H264 decoder needs extra space on the output buffers
+		 * to store motion vectors. This is needed for reference
+		 * frames.
+		 */
+		if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
+			pix_mp->plane_fmt[0].sizeimage +=
+				128 * DIV_ROUND_UP(pix_mp->width, 16) *
+				      DIV_ROUND_UP(pix_mp->height, 16);
 	} else if (!pix_mp->plane_fmt[0].sizeimage) {
 		/*
 		 * For coded formats the application can specify
@@ -344,6 +353,8 @@
 		ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = false;
 		break;
 	case V4L2_PIX_FMT_MPEG2_SLICE:
+	case V4L2_PIX_FMT_VP8_FRAME:
+	case V4L2_PIX_FMT_H264_SLICE:
 		ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true;
 		break;
 	default:
diff --git a/drivers/staging/media/hantro/hantro_vp8.c b/drivers/staging/media/hantro/hantro_vp8.c
new file mode 100644
index 0000000..0e02d14
--- /dev/null
+++ b/drivers/staging/media/hantro/hantro_vp8.c
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hantro VPU codec driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include "hantro.h"
+
+/*
+ * probs table with packed
+ */
+struct vp8_prob_tbl_packed {
+	u8 prob_mb_skip_false;
+	u8 prob_intra;
+	u8 prob_ref_last;
+	u8 prob_ref_golden;
+	u8 prob_segment[3];
+	u8 padding0;
+
+	u8 prob_luma_16x16_pred_mode[4];
+	u8 prob_chroma_pred_mode[3];
+	u8 padding1;
+
+	/* mv prob */
+	u8 prob_mv_context[2][19];
+	u8 padding2[2];
+
+	/* coeff probs */
+	u8 prob_coeffs[4][8][3][11];
+	u8 padding3[96];
+};
+
+/*
+ * filter taps taken to 7-bit precision,
+ * reference RFC6386#Page-16, filters[8][6]
+ */
+const u32 hantro_vp8_dec_mc_filter[8][6] = {
+	{ 0, 0, 128, 0, 0, 0 },
+	{ 0, -6, 123, 12, -1, 0 },
+	{ 2, -11, 108, 36, -8, 1 },
+	{ 0, -9, 93, 50, -6, 0 },
+	{ 3, -16, 77, 77, -16, 3 },
+	{ 0, -6, 50, 93, -9, 0 },
+	{ 1, -8, 36, 108, -11, 2 },
+	{ 0, -1, 12, 123, -6, 0 }
+};
+
+void hantro_vp8_prob_update(struct hantro_ctx *ctx,
+			    const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	const struct v4l2_vp8_entropy_header *entropy = &hdr->entropy_header;
+	u32 i, j, k;
+	u8 *dst;
+
+	/* first probs */
+	dst = ctx->vp8_dec.prob_tbl.cpu;
+
+	dst[0] = hdr->prob_skip_false;
+	dst[1] = hdr->prob_intra;
+	dst[2] = hdr->prob_last;
+	dst[3] = hdr->prob_gf;
+	dst[4] = hdr->segment_header.segment_probs[0];
+	dst[5] = hdr->segment_header.segment_probs[1];
+	dst[6] = hdr->segment_header.segment_probs[2];
+	dst[7] = 0;
+
+	dst += 8;
+	dst[0] = entropy->y_mode_probs[0];
+	dst[1] = entropy->y_mode_probs[1];
+	dst[2] = entropy->y_mode_probs[2];
+	dst[3] = entropy->y_mode_probs[3];
+	dst[4] = entropy->uv_mode_probs[0];
+	dst[5] = entropy->uv_mode_probs[1];
+	dst[6] = entropy->uv_mode_probs[2];
+	dst[7] = 0; /*unused */
+
+	/* mv probs */
+	dst += 8;
+	dst[0] = entropy->mv_probs[0][0]; /* is short */
+	dst[1] = entropy->mv_probs[1][0];
+	dst[2] = entropy->mv_probs[0][1]; /* sign */
+	dst[3] = entropy->mv_probs[1][1];
+	dst[4] = entropy->mv_probs[0][8 + 9];
+	dst[5] = entropy->mv_probs[0][9 + 9];
+	dst[6] = entropy->mv_probs[1][8 + 9];
+	dst[7] = entropy->mv_probs[1][9 + 9];
+	dst += 8;
+	for (i = 0; i < 2; ++i) {
+		for (j = 0; j < 8; j += 4) {
+			dst[0] = entropy->mv_probs[i][j + 9 + 0];
+			dst[1] = entropy->mv_probs[i][j + 9 + 1];
+			dst[2] = entropy->mv_probs[i][j + 9 + 2];
+			dst[3] = entropy->mv_probs[i][j + 9 + 3];
+			dst += 4;
+		}
+	}
+	for (i = 0; i < 2; ++i) {
+		dst[0] = entropy->mv_probs[i][0 + 2];
+		dst[1] = entropy->mv_probs[i][1 + 2];
+		dst[2] = entropy->mv_probs[i][2 + 2];
+		dst[3] = entropy->mv_probs[i][3 + 2];
+		dst[4] = entropy->mv_probs[i][4 + 2];
+		dst[5] = entropy->mv_probs[i][5 + 2];
+		dst[6] = entropy->mv_probs[i][6 + 2];
+		dst[7] = 0;	/*unused */
+		dst += 8;
+	}
+
+	/* coeff probs (header part) */
+	dst = ctx->vp8_dec.prob_tbl.cpu;
+	dst += (8 * 7);
+	for (i = 0; i < 4; ++i) {
+		for (j = 0; j < 8; ++j) {
+			for (k = 0; k < 3; ++k) {
+				dst[0] = entropy->coeff_probs[i][j][k][0];
+				dst[1] = entropy->coeff_probs[i][j][k][1];
+				dst[2] = entropy->coeff_probs[i][j][k][2];
+				dst[3] = entropy->coeff_probs[i][j][k][3];
+				dst += 4;
+			}
+		}
+	}
+
+	/* coeff probs (footer part) */
+	dst = ctx->vp8_dec.prob_tbl.cpu;
+	dst += (8 * 55);
+	for (i = 0; i < 4; ++i) {
+		for (j = 0; j < 8; ++j) {
+			for (k = 0; k < 3; ++k) {
+				dst[0] = entropy->coeff_probs[i][j][k][4];
+				dst[1] = entropy->coeff_probs[i][j][k][5];
+				dst[2] = entropy->coeff_probs[i][j][k][6];
+				dst[3] = entropy->coeff_probs[i][j][k][7];
+				dst[4] = entropy->coeff_probs[i][j][k][8];
+				dst[5] = entropy->coeff_probs[i][j][k][9];
+				dst[6] = entropy->coeff_probs[i][j][k][10];
+				dst[7] = 0;	/*unused */
+				dst += 8;
+			}
+		}
+	}
+}
+
+int hantro_vp8_dec_init(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct hantro_aux_buf *aux_buf;
+	unsigned int mb_width, mb_height;
+	size_t segment_map_size;
+	int ret;
+
+	/* segment map table size calculation */
+	mb_width = DIV_ROUND_UP(ctx->dst_fmt.width, 16);
+	mb_height = DIV_ROUND_UP(ctx->dst_fmt.height, 16);
+	segment_map_size = round_up(DIV_ROUND_UP(mb_width * mb_height, 4), 64);
+
+	/*
+	 * In context init the dma buffer for segment map must be allocated.
+	 * And the data in segment map buffer must be set to all zero.
+	 */
+	aux_buf = &ctx->vp8_dec.segment_map;
+	aux_buf->size = segment_map_size;
+	aux_buf->cpu = dma_alloc_coherent(vpu->dev, aux_buf->size,
+					  &aux_buf->dma, GFP_KERNEL);
+	if (!aux_buf->cpu)
+		return -ENOMEM;
+
+	/*
+	 * Allocate probability table buffer,
+	 * total 1208 bytes, 4K page is far enough.
+	 */
+	aux_buf = &ctx->vp8_dec.prob_tbl;
+	aux_buf->size = sizeof(struct vp8_prob_tbl_packed);
+	aux_buf->cpu = dma_alloc_coherent(vpu->dev, aux_buf->size,
+					  &aux_buf->dma, GFP_KERNEL);
+	if (!aux_buf->cpu) {
+		ret = -ENOMEM;
+		goto err_free_seg_map;
+	}
+
+	return 0;
+
+err_free_seg_map:
+	dma_free_coherent(vpu->dev, ctx->vp8_dec.segment_map.size,
+			  ctx->vp8_dec.segment_map.cpu,
+			  ctx->vp8_dec.segment_map.dma);
+
+	return ret;
+}
+
+void hantro_vp8_dec_exit(struct hantro_ctx *ctx)
+{
+	struct hantro_vp8_dec_hw_ctx *vp8_dec = &ctx->vp8_dec;
+	struct hantro_dev *vpu = ctx->dev;
+
+	dma_free_coherent(vpu->dev, vp8_dec->segment_map.size,
+			  vp8_dec->segment_map.cpu, vp8_dec->segment_map.dma);
+	dma_free_coherent(vpu->dev, vp8_dec->prob_tbl.size,
+			  vp8_dec->prob_tbl.cpu, vp8_dec->prob_tbl.dma);
+}
diff --git a/drivers/staging/media/hantro/rk3288_vpu_hw.c b/drivers/staging/media/hantro/rk3288_vpu_hw.c
index bcacc4f..6bfcc47 100644
--- a/drivers/staging/media/hantro/rk3288_vpu_hw.c
+++ b/drivers/staging/media/hantro/rk3288_vpu_hw.c
@@ -62,6 +62,19 @@
 		.codec_mode = HANTRO_MODE_NONE,
 	},
 	{
+		.fourcc = V4L2_PIX_FMT_H264_SLICE,
+		.codec_mode = HANTRO_MODE_H264_DEC,
+		.max_depth = 2,
+		.frmsize = {
+			.min_width = 48,
+			.max_width = 3840,
+			.step_width = H264_MB_DIM,
+			.min_height = 48,
+			.max_height = 2160,
+			.step_height = H264_MB_DIM,
+		},
+	},
+	{
 		.fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
 		.codec_mode = HANTRO_MODE_MPEG2_DEC,
 		.max_depth = 2,
@@ -74,6 +87,19 @@
 			.step_height = MPEG2_MB_DIM,
 		},
 	},
+	{
+		.fourcc = V4L2_PIX_FMT_VP8_FRAME,
+		.codec_mode = HANTRO_MODE_VP8_DEC,
+		.max_depth = 2,
+		.frmsize = {
+			.min_width = 48,
+			.max_width = 3840,
+			.step_width = VP8_MB_DIM,
+			.min_height = 48,
+			.max_height = 2160,
+			.step_height = VP8_MB_DIM,
+		},
+	},
 };
 
 static irqreturn_t rk3288_vepu_irq(int irq, void *dev_id)
@@ -149,12 +175,24 @@
 		.init = hantro_jpeg_enc_init,
 		.exit = hantro_jpeg_enc_exit,
 	},
+	[HANTRO_MODE_H264_DEC] = {
+		.run = hantro_g1_h264_dec_run,
+		.reset = rk3288_vpu_dec_reset,
+		.init = hantro_h264_dec_init,
+		.exit = hantro_h264_dec_exit,
+	},
 	[HANTRO_MODE_MPEG2_DEC] = {
 		.run = hantro_g1_mpeg2_dec_run,
 		.reset = rk3288_vpu_dec_reset,
 		.init = hantro_mpeg2_dec_init,
 		.exit = hantro_mpeg2_dec_exit,
 	},
+	[HANTRO_MODE_VP8_DEC] = {
+		.run = hantro_g1_vp8_dec_run,
+		.reset = rk3288_vpu_dec_reset,
+		.init = hantro_vp8_dec_init,
+		.exit = hantro_vp8_dec_exit,
+	},
 };
 
 /*
@@ -177,7 +215,8 @@
 	.dec_offset = 0x400,
 	.dec_fmts = rk3288_vpu_dec_fmts,
 	.num_dec_fmts = ARRAY_SIZE(rk3288_vpu_dec_fmts),
-	.codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER,
+	.codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
+		 HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
 	.codec_ops = rk3288_vpu_codec_ops,
 	.irqs = rk3288_irqs,
 	.num_irqs = ARRAY_SIZE(rk3288_irqs),
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw.c b/drivers/staging/media/hantro/rk3399_vpu_hw.c
index 5718f80..14d14bc 100644
--- a/drivers/staging/media/hantro/rk3399_vpu_hw.c
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw.c
@@ -73,6 +73,19 @@
 			.step_height = MPEG2_MB_DIM,
 		},
 	},
+	{
+		.fourcc = V4L2_PIX_FMT_VP8_FRAME,
+		.codec_mode = HANTRO_MODE_VP8_DEC,
+		.max_depth = 2,
+		.frmsize = {
+			.min_width = 48,
+			.max_width = 3840,
+			.step_width = VP8_MB_DIM,
+			.min_height = 48,
+			.max_height = 2160,
+			.step_height = VP8_MB_DIM,
+		},
+	},
 };
 
 static irqreturn_t rk3399_vepu_irq(int irq, void *dev_id)
@@ -154,6 +167,12 @@
 		.init = hantro_mpeg2_dec_init,
 		.exit = hantro_mpeg2_dec_exit,
 	},
+	[HANTRO_MODE_VP8_DEC] = {
+		.run = rk3399_vpu_vp8_dec_run,
+		.reset = rk3399_vpu_dec_reset,
+		.init = hantro_vp8_dec_init,
+		.exit = hantro_vp8_dec_exit,
+	},
 };
 
 /*
@@ -176,7 +195,8 @@
 	.dec_offset = 0x400,
 	.dec_fmts = rk3399_vpu_dec_fmts,
 	.num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
-	.codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER,
+	.codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
+		 HANTRO_VP8_DECODER,
 	.codec_ops = rk3399_vpu_codec_ops,
 	.irqs = rk3399_irqs,
 	.num_irqs = ARRAY_SIZE(rk3399_irqs),
@@ -184,3 +204,20 @@
 	.clk_names = rk3399_clk_names,
 	.num_clocks = ARRAY_SIZE(rk3399_clk_names)
 };
+
+static const struct hantro_irq rk3328_irqs[] = {
+	{ "vdpu", rk3399_vdpu_irq },
+};
+
+const struct hantro_variant rk3328_vpu_variant = {
+	.dec_offset = 0x400,
+	.dec_fmts = rk3399_vpu_dec_fmts,
+	.num_dec_fmts = ARRAY_SIZE(rk3399_vpu_dec_fmts),
+	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER,
+	.codec_ops = rk3399_vpu_codec_ops,
+	.irqs = rk3328_irqs,
+	.num_irqs = ARRAY_SIZE(rk3328_irqs),
+	.init = rk3399_vpu_hw_init,
+	.clk_names = rk3399_clk_names,
+	.num_clocks = ARRAY_SIZE(rk3399_clk_names),
+};
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c b/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c
index ae66354..06162f5 100644
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_jpeg_enc.c
@@ -113,14 +113,12 @@
 	struct hantro_dev *vpu = ctx->dev;
 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
 	struct hantro_jpeg_ctx jpeg_ctx;
-	struct media_request *src_req;
 	u32 reg;
 
-	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
-	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+	src_buf = hantro_get_src_buf(ctx);
+	dst_buf = hantro_get_dst_buf(ctx);
 
-	src_req = src_buf->vb2_buf.req_obj.req;
-	v4l2_ctrl_request_setup(src_req, &ctx->ctrl_handler);
+	hantro_prepare_run(ctx);
 
 	memset(&jpeg_ctx, 0, sizeof(jpeg_ctx));
 	jpeg_ctx.buffer = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
@@ -157,9 +155,7 @@
 		| VEPU_REG_ENCODE_FORMAT_JPEG
 		| VEPU_REG_ENCODE_ENABLE;
 
-	v4l2_ctrl_request_complete(src_req, &ctx->ctrl_handler);
-
 	/* Kick the watchdog and start encoding */
-	schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000));
+	hantro_finish_run(ctx);
 	vepu_write(vpu, reg, VEPU_REG_ENCODE_START);
 }
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
index 8685bdd..e7ba5c0 100644
--- a/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_mpeg2_dec.c
@@ -169,12 +169,10 @@
 	const struct v4l2_mpeg2_picture *picture;
 	u32 reg;
 
-	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
-	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+	src_buf = hantro_get_src_buf(ctx);
+	dst_buf = hantro_get_dst_buf(ctx);
 
-	/* Apply request controls if any */
-	v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
-				&ctx->ctrl_handler);
+	hantro_prepare_run(ctx);
 
 	slice_params = hantro_get_ctrl(ctx,
 				       V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS);
@@ -254,12 +252,8 @@
 					 &dst_buf->vb2_buf,
 					 sequence, picture, slice_params);
 
-	/* Controls no longer in-use, we can complete them */
-	v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
-				   &ctx->ctrl_handler);
-
 	/* Kick the watchdog and start decoding */
-	schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000));
+	hantro_finish_run(ctx);
 
 	reg = vdpu_read(vpu, VDPU_SWREG(57)) | VDPU_REG_DEC_E(1);
 	vdpu_write(vpu, reg, VDPU_SWREG(57));
diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c
new file mode 100644
index 0000000..f17e326
--- /dev/null
+++ b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c
@@ -0,0 +1,595 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip VPU codec vp8 decode driver
+ *
+ * Copyright (C) 2014 Rockchip Electronics Co., Ltd.
+ *	ZhiChao Yu <zhichao.yu@rock-chips.com>
+ *
+ * Copyright (C) 2014 Google LLC.
+ *      Tomasz Figa <tfiga@chromium.org>
+ *
+ * Copyright (C) 2015 Rockchip Electronics Co., Ltd.
+ *      Alpha Lin <alpha.lin@rock-chips.com>
+ */
+
+#include <media/v4l2-mem2mem.h>
+#include <media/vp8-ctrls.h>
+
+#include "hantro_hw.h"
+#include "hantro.h"
+#include "hantro_g1_regs.h"
+
+#define VDPU_REG_DEC_CTRL0			0x0c8
+#define VDPU_REG_STREAM_LEN			0x0cc
+#define VDPU_REG_DEC_FORMAT			0x0d4
+#define     VDPU_REG_DEC_CTRL0_DEC_MODE(x)		(((x) & 0xf) << 0)
+#define VDPU_REG_DATA_ENDIAN			0x0d8
+#define     VDPU_REG_CONFIG_DEC_STRENDIAN_E		BIT(5)
+#define     VDPU_REG_CONFIG_DEC_STRSWAP32_E		BIT(4)
+#define     VDPU_REG_CONFIG_DEC_OUTSWAP32_E		BIT(3)
+#define     VDPU_REG_CONFIG_DEC_INSWAP32_E		BIT(2)
+#define     VDPU_REG_CONFIG_DEC_OUT_ENDIAN		BIT(1)
+#define     VDPU_REG_CONFIG_DEC_IN_ENDIAN		BIT(0)
+#define VDPU_REG_AXI_CTRL			0x0e0
+#define     VDPU_REG_CONFIG_DEC_MAX_BURST(x)		(((x) & 0x1f) << 16)
+#define VDPU_REG_EN_FLAGS			0x0e4
+#define     VDPU_REG_DEC_CTRL0_PIC_INTER_E		BIT(14)
+#define     VDPU_REG_CONFIG_DEC_TIMEOUT_E		BIT(5)
+#define     VDPU_REG_CONFIG_DEC_CLK_GATE_E		BIT(4)
+#define VDPU_REG_PRED_FLT			0x0ec
+#define VDPU_REG_ADDR_QTABLE			0x0f4
+#define VDPU_REG_ADDR_DST			0x0fc
+#define VDPU_REG_ADDR_STR			0x100
+#define VDPU_REG_VP8_PIC_MB_SIZE		0x1e0
+#define VDPU_REG_VP8_DCT_START_BIT		0x1e4
+#define     VDPU_REG_DEC_CTRL4_VC1_HEIGHT_EXT		BIT(13)
+#define     VDPU_REG_DEC_CTRL4_BILIN_MC_E		BIT(12)
+#define VDPU_REG_VP8_CTRL0			0x1e8
+#define VDPU_REG_VP8_DATA_VAL			0x1f0
+#define VDPU_REG_PRED_FLT7			0x1f4
+#define VDPU_REG_PRED_FLT8			0x1f8
+#define VDPU_REG_PRED_FLT9			0x1fc
+#define VDPU_REG_PRED_FLT10			0x200
+#define VDPU_REG_FILTER_LEVEL			0x204
+#define VDPU_REG_VP8_QUANTER0			0x208
+#define VDPU_REG_VP8_ADDR_REF0			0x20c
+#define VDPU_REG_FILTER_MB_ADJ			0x210
+#define     VDPU_REG_REF_PIC_FILT_TYPE_E		BIT(31)
+#define     VDPU_REG_REF_PIC_FILT_SHARPNESS(x)		(((x) & 0x7) << 28)
+#define VDPU_REG_FILTER_REF_ADJ			0x214
+#define VDPU_REG_VP8_ADDR_REF2_5(i)		(0x218 + ((i) * 0x4))
+#define     VDPU_REG_VP8_GREF_SIGN_BIAS			BIT(0)
+#define     VDPU_REG_VP8_AREF_SIGN_BIAS			BIT(0)
+#define VDPU_REG_VP8_DCT_BASE(i)		\
+		(0x230 + ((((i) < 5) ? (i) : ((i) + 1)) * 0x4))
+#define VDPU_REG_VP8_ADDR_CTRL_PART		0x244
+#define VDPU_REG_VP8_SEGMENT_VAL		0x254
+#define     VDPU_REG_FWD_PIC1_SEGMENT_BASE(x)		((x) << 0)
+#define     VDPU_REG_FWD_PIC1_SEGMENT_UPD_E		BIT(1)
+#define     VDPU_REG_FWD_PIC1_SEGMENT_E			BIT(0)
+#define VDPU_REG_VP8_DCT_START_BIT2		0x258
+#define VDPU_REG_VP8_QUANTER1			0x25c
+#define VDPU_REG_VP8_QUANTER2			0x260
+#define VDPU_REG_PRED_FLT1			0x264
+#define VDPU_REG_PRED_FLT2			0x268
+#define VDPU_REG_PRED_FLT3			0x26c
+#define VDPU_REG_PRED_FLT4			0x270
+#define VDPU_REG_PRED_FLT5			0x274
+#define VDPU_REG_PRED_FLT6			0x278
+
+static const struct hantro_reg vp8_dec_dct_base[8] = {
+	{ VDPU_REG_ADDR_STR, 0, 0xffffffff },
+	{ VDPU_REG_VP8_DCT_BASE(0), 0, 0xffffffff },
+	{ VDPU_REG_VP8_DCT_BASE(1), 0, 0xffffffff },
+	{ VDPU_REG_VP8_DCT_BASE(2), 0, 0xffffffff },
+	{ VDPU_REG_VP8_DCT_BASE(3), 0, 0xffffffff },
+	{ VDPU_REG_VP8_DCT_BASE(4), 0, 0xffffffff },
+	{ VDPU_REG_VP8_DCT_BASE(5), 0, 0xffffffff },
+	{ VDPU_REG_VP8_DCT_BASE(6), 0, 0xffffffff },
+};
+
+static const struct hantro_reg vp8_dec_lf_level[4] = {
+	{ VDPU_REG_FILTER_LEVEL, 18, 0x3f },
+	{ VDPU_REG_FILTER_LEVEL, 12, 0x3f },
+	{ VDPU_REG_FILTER_LEVEL, 6, 0x3f },
+	{ VDPU_REG_FILTER_LEVEL, 0, 0x3f },
+};
+
+static const struct hantro_reg vp8_dec_mb_adj[4] = {
+	{ VDPU_REG_FILTER_MB_ADJ, 21, 0x7f },
+	{ VDPU_REG_FILTER_MB_ADJ, 14, 0x7f },
+	{ VDPU_REG_FILTER_MB_ADJ, 7, 0x7f },
+	{ VDPU_REG_FILTER_MB_ADJ, 0, 0x7f },
+};
+
+static const struct hantro_reg vp8_dec_ref_adj[4] = {
+	{ VDPU_REG_FILTER_REF_ADJ, 21, 0x7f },
+	{ VDPU_REG_FILTER_REF_ADJ, 14, 0x7f },
+	{ VDPU_REG_FILTER_REF_ADJ, 7, 0x7f },
+	{ VDPU_REG_FILTER_REF_ADJ, 0, 0x7f },
+};
+
+static const struct hantro_reg vp8_dec_quant[4] = {
+	{ VDPU_REG_VP8_QUANTER0, 11, 0x7ff },
+	{ VDPU_REG_VP8_QUANTER0, 0, 0x7ff },
+	{ VDPU_REG_VP8_QUANTER1, 11, 0x7ff },
+	{ VDPU_REG_VP8_QUANTER1, 0, 0x7ff },
+};
+
+static const struct hantro_reg vp8_dec_quant_delta[5] = {
+	{ VDPU_REG_VP8_QUANTER0, 27, 0x1f },
+	{ VDPU_REG_VP8_QUANTER0, 22, 0x1f },
+	{ VDPU_REG_VP8_QUANTER1, 27, 0x1f },
+	{ VDPU_REG_VP8_QUANTER1, 22, 0x1f },
+	{ VDPU_REG_VP8_QUANTER2, 27, 0x1f },
+};
+
+static const struct hantro_reg vp8_dec_dct_start_bits[8] = {
+	{ VDPU_REG_VP8_CTRL0, 26, 0x3f },
+	{ VDPU_REG_VP8_DCT_START_BIT, 26, 0x3f },
+	{ VDPU_REG_VP8_DCT_START_BIT, 20, 0x3f },
+	{ VDPU_REG_VP8_DCT_START_BIT2, 24, 0x3f },
+	{ VDPU_REG_VP8_DCT_START_BIT2, 18, 0x3f },
+	{ VDPU_REG_VP8_DCT_START_BIT2, 12, 0x3f },
+	{ VDPU_REG_VP8_DCT_START_BIT2, 6, 0x3f },
+	{ VDPU_REG_VP8_DCT_START_BIT2, 0, 0x3f },
+};
+
+static const struct hantro_reg vp8_dec_pred_bc_tap[8][6] = {
+	{
+		{ 0, 0, 0},
+		{ VDPU_REG_PRED_FLT, 22, 0x3ff },
+		{ VDPU_REG_PRED_FLT, 12, 0x3ff },
+		{ VDPU_REG_PRED_FLT, 2, 0x3ff },
+		{ VDPU_REG_PRED_FLT1, 22, 0x3ff },
+		{ 0, 0, 0},
+	}, {
+		{ 0, 0, 0},
+		{ VDPU_REG_PRED_FLT1, 12, 0x3ff },
+		{ VDPU_REG_PRED_FLT1, 2, 0x3ff },
+		{ VDPU_REG_PRED_FLT2, 22, 0x3ff },
+		{ VDPU_REG_PRED_FLT2, 12, 0x3ff },
+		{ 0, 0, 0},
+	}, {
+		{ VDPU_REG_PRED_FLT10, 10, 0x3 },
+		{ VDPU_REG_PRED_FLT2, 2, 0x3ff },
+		{ VDPU_REG_PRED_FLT3, 22, 0x3ff },
+		{ VDPU_REG_PRED_FLT3, 12, 0x3ff },
+		{ VDPU_REG_PRED_FLT3, 2, 0x3ff },
+		{ VDPU_REG_PRED_FLT10, 8, 0x3},
+	}, {
+		{ 0, 0, 0},
+		{ VDPU_REG_PRED_FLT4, 22, 0x3ff },
+		{ VDPU_REG_PRED_FLT4, 12, 0x3ff },
+		{ VDPU_REG_PRED_FLT4, 2, 0x3ff },
+		{ VDPU_REG_PRED_FLT5, 22, 0x3ff },
+		{ 0, 0, 0},
+	}, {
+		{ VDPU_REG_PRED_FLT10, 6, 0x3 },
+		{ VDPU_REG_PRED_FLT5, 12, 0x3ff },
+		{ VDPU_REG_PRED_FLT5, 2, 0x3ff },
+		{ VDPU_REG_PRED_FLT6, 22, 0x3ff },
+		{ VDPU_REG_PRED_FLT6, 12, 0x3ff },
+		{ VDPU_REG_PRED_FLT10, 4, 0x3 },
+	}, {
+		{ 0, 0, 0},
+		{ VDPU_REG_PRED_FLT6, 2, 0x3ff },
+		{ VDPU_REG_PRED_FLT7, 22, 0x3ff },
+		{ VDPU_REG_PRED_FLT7, 12, 0x3ff },
+		{ VDPU_REG_PRED_FLT7, 2, 0x3ff },
+		{ 0, 0, 0},
+	}, {
+		{ VDPU_REG_PRED_FLT10, 2, 0x3 },
+		{ VDPU_REG_PRED_FLT8, 22, 0x3ff },
+		{ VDPU_REG_PRED_FLT8, 12, 0x3ff },
+		{ VDPU_REG_PRED_FLT8, 2, 0x3ff },
+		{ VDPU_REG_PRED_FLT9, 22, 0x3ff },
+		{ VDPU_REG_PRED_FLT10, 0, 0x3 },
+	}, {
+		{ 0, 0, 0},
+		{ VDPU_REG_PRED_FLT9, 12, 0x3ff },
+		{ VDPU_REG_PRED_FLT9, 2, 0x3ff },
+		{ VDPU_REG_PRED_FLT10, 22, 0x3ff },
+		{ VDPU_REG_PRED_FLT10, 12, 0x3ff },
+		{ 0, 0, 0},
+	},
+};
+
+static const struct hantro_reg vp8_dec_mb_start_bit = {
+	.base = VDPU_REG_VP8_CTRL0,
+	.shift = 18,
+	.mask = 0x3f
+};
+
+static const struct hantro_reg vp8_dec_mb_aligned_data_len = {
+	.base = VDPU_REG_VP8_DATA_VAL,
+	.shift = 0,
+	.mask = 0x3fffff
+};
+
+static const struct hantro_reg vp8_dec_num_dct_partitions = {
+	.base = VDPU_REG_VP8_DATA_VAL,
+	.shift = 24,
+	.mask = 0xf
+};
+
+static const struct hantro_reg vp8_dec_stream_len = {
+	.base = VDPU_REG_STREAM_LEN,
+	.shift = 0,
+	.mask = 0xffffff
+};
+
+static const struct hantro_reg vp8_dec_mb_width = {
+	.base = VDPU_REG_VP8_PIC_MB_SIZE,
+	.shift = 23,
+	.mask = 0x1ff
+};
+
+static const struct hantro_reg vp8_dec_mb_height = {
+	.base = VDPU_REG_VP8_PIC_MB_SIZE,
+	.shift = 11,
+	.mask = 0xff
+};
+
+static const struct hantro_reg vp8_dec_mb_width_ext = {
+	.base = VDPU_REG_VP8_PIC_MB_SIZE,
+	.shift = 3,
+	.mask = 0x7
+};
+
+static const struct hantro_reg vp8_dec_mb_height_ext = {
+	.base = VDPU_REG_VP8_PIC_MB_SIZE,
+	.shift = 0,
+	.mask = 0x7
+};
+
+static const struct hantro_reg vp8_dec_bool_range = {
+	.base = VDPU_REG_VP8_CTRL0,
+	.shift = 0,
+	.mask = 0xff
+};
+
+static const struct hantro_reg vp8_dec_bool_value = {
+	.base = VDPU_REG_VP8_CTRL0,
+	.shift = 8,
+	.mask = 0xff
+};
+
+static const struct hantro_reg vp8_dec_filter_disable = {
+	.base = VDPU_REG_DEC_CTRL0,
+	.shift = 8,
+	.mask = 1
+};
+
+static const struct hantro_reg vp8_dec_skip_mode = {
+	.base = VDPU_REG_DEC_CTRL0,
+	.shift = 9,
+	.mask = 1
+};
+
+static const struct hantro_reg vp8_dec_start_dec = {
+	.base = VDPU_REG_EN_FLAGS,
+	.shift = 0,
+	.mask = 1
+};
+
+static void cfg_lf(struct hantro_ctx *ctx,
+		   const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	const struct v4l2_vp8_segment_header *seg = &hdr->segment_header;
+	const struct v4l2_vp8_loopfilter_header *lf = &hdr->lf_header;
+	struct hantro_dev *vpu = ctx->dev;
+	unsigned int i;
+	u32 reg;
+
+	if (!(seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED)) {
+		hantro_reg_write(vpu, &vp8_dec_lf_level[0], lf->level);
+	} else if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE) {
+		for (i = 0; i < 4; i++) {
+			u32 lf_level = clamp(lf->level + seg->lf_update[i],
+					     0, 63);
+
+			hantro_reg_write(vpu, &vp8_dec_lf_level[i], lf_level);
+		}
+	} else {
+		for (i = 0; i < 4; i++)
+			hantro_reg_write(vpu, &vp8_dec_lf_level[i],
+					 seg->lf_update[i]);
+	}
+
+	reg = VDPU_REG_REF_PIC_FILT_SHARPNESS(lf->sharpness_level);
+	if (lf->flags & V4L2_VP8_LF_FILTER_TYPE_SIMPLE)
+		reg |= VDPU_REG_REF_PIC_FILT_TYPE_E;
+	vdpu_write_relaxed(vpu, reg, VDPU_REG_FILTER_MB_ADJ);
+
+	if (lf->flags & V4L2_VP8_LF_HEADER_ADJ_ENABLE) {
+		for (i = 0; i < 4; i++) {
+			hantro_reg_write(vpu, &vp8_dec_mb_adj[i],
+					 lf->mb_mode_delta[i]);
+			hantro_reg_write(vpu, &vp8_dec_ref_adj[i],
+					 lf->ref_frm_delta[i]);
+		}
+	}
+}
+
+static void cfg_qp(struct hantro_ctx *ctx,
+		   const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	const struct v4l2_vp8_quantization_header *q = &hdr->quant_header;
+	const struct v4l2_vp8_segment_header *seg = &hdr->segment_header;
+	struct hantro_dev *vpu = ctx->dev;
+	unsigned int i;
+
+	if (!(seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED)) {
+		hantro_reg_write(vpu, &vp8_dec_quant[0], q->y_ac_qi);
+	} else if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE) {
+		for (i = 0; i < 4; i++) {
+			u32 quant = clamp(q->y_ac_qi + seg->quant_update[i],
+					  0, 127);
+
+			hantro_reg_write(vpu, &vp8_dec_quant[i], quant);
+		}
+	} else {
+		for (i = 0; i < 4; i++)
+			hantro_reg_write(vpu, &vp8_dec_quant[i],
+					 seg->quant_update[i]);
+	}
+
+	hantro_reg_write(vpu, &vp8_dec_quant_delta[0], q->y_dc_delta);
+	hantro_reg_write(vpu, &vp8_dec_quant_delta[1], q->y2_dc_delta);
+	hantro_reg_write(vpu, &vp8_dec_quant_delta[2], q->y2_ac_delta);
+	hantro_reg_write(vpu, &vp8_dec_quant_delta[3], q->uv_dc_delta);
+	hantro_reg_write(vpu, &vp8_dec_quant_delta[4], q->uv_ac_delta);
+}
+
+static void cfg_parts(struct hantro_ctx *ctx,
+		      const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct vb2_v4l2_buffer *vb2_src;
+	u32 first_part_offset = VP8_FRAME_IS_KEY_FRAME(hdr) ? 10 : 3;
+	u32 mb_size, mb_offset_bytes, mb_offset_bits, mb_start_bits;
+	u32 dct_size_part_size, dct_part_offset;
+	dma_addr_t src_dma;
+	u32 dct_part_total_len = 0;
+	u32 count = 0;
+	unsigned int i;
+
+	vb2_src = hantro_get_src_buf(ctx);
+	src_dma = vb2_dma_contig_plane_dma_addr(&vb2_src->vb2_buf, 0);
+
+	/*
+	 * Calculate control partition mb data info
+	 * @first_part_header_bits:	bits offset of mb data from first
+	 *				part start pos
+	 * @mb_offset_bits:		bits offset of mb data from src_dma
+	 *				base addr
+	 * @mb_offset_byte:		bytes offset of mb data from src_dma
+	 *				base addr
+	 * @mb_start_bits:		bits offset of mb data from mb data
+	 *				64bits alignment addr
+	 */
+	mb_offset_bits = first_part_offset * 8 +
+			 hdr->first_part_header_bits + 8;
+	mb_offset_bytes = mb_offset_bits / 8;
+	mb_start_bits = mb_offset_bits -
+			(mb_offset_bytes & (~DEC_8190_ALIGN_MASK)) * 8;
+	mb_size = hdr->first_part_size -
+		  (mb_offset_bytes - first_part_offset) +
+		  (mb_offset_bytes & DEC_8190_ALIGN_MASK);
+
+	/* Macroblock data aligned base addr */
+	vdpu_write_relaxed(vpu, (mb_offset_bytes & (~DEC_8190_ALIGN_MASK)) +
+			   src_dma, VDPU_REG_VP8_ADDR_CTRL_PART);
+	hantro_reg_write(vpu, &vp8_dec_mb_start_bit, mb_start_bits);
+	hantro_reg_write(vpu, &vp8_dec_mb_aligned_data_len, mb_size);
+
+	/*
+	 * Calculate DCT partition info
+	 * @dct_size_part_size: Containing sizes of DCT part, every DCT part
+	 *			has 3 bytes to store its size, except the last
+	 *			DCT part
+	 * @dct_part_offset:	bytes offset of DCT parts from src_dma base addr
+	 * @dct_part_total_len: total size of all DCT parts
+	 */
+	dct_size_part_size = (hdr->num_dct_parts - 1) * 3;
+	dct_part_offset = first_part_offset + hdr->first_part_size;
+	for (i = 0; i < hdr->num_dct_parts; i++)
+		dct_part_total_len += hdr->dct_part_sizes[i];
+	dct_part_total_len += dct_size_part_size;
+	dct_part_total_len += (dct_part_offset & DEC_8190_ALIGN_MASK);
+
+	/* Number of DCT partitions */
+	hantro_reg_write(vpu, &vp8_dec_num_dct_partitions,
+			 hdr->num_dct_parts - 1);
+
+	/* DCT partition length */
+	hantro_reg_write(vpu, &vp8_dec_stream_len, dct_part_total_len);
+
+	/* DCT partitions base address */
+	for (i = 0; i < hdr->num_dct_parts; i++) {
+		u32 byte_offset = dct_part_offset + dct_size_part_size + count;
+		u32 base_addr = byte_offset + src_dma;
+
+		hantro_reg_write(vpu, &vp8_dec_dct_base[i],
+				 base_addr & (~DEC_8190_ALIGN_MASK));
+
+		hantro_reg_write(vpu, &vp8_dec_dct_start_bits[i],
+				 (byte_offset & DEC_8190_ALIGN_MASK) * 8);
+
+		count += hdr->dct_part_sizes[i];
+	}
+}
+
+/*
+ * prediction filter taps
+ * normal 6-tap filters
+ */
+static void cfg_tap(struct hantro_ctx *ctx,
+		    const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	int i, j;
+
+	if ((hdr->version & 0x03) != 0)
+		return; /* Tap filter not used. */
+
+	for (i = 0; i < 8; i++) {
+		for (j = 0; j < 6; j++) {
+			if (vp8_dec_pred_bc_tap[i][j].base != 0)
+				hantro_reg_write(vpu,
+						 &vp8_dec_pred_bc_tap[i][j],
+						 hantro_vp8_dec_mc_filter[i][j]);
+		}
+	}
+}
+
+static void cfg_ref(struct hantro_ctx *ctx,
+		    const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct vb2_v4l2_buffer *vb2_dst;
+	struct vb2_queue *cap_q;
+	dma_addr_t ref;
+
+	cap_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	vb2_dst = hantro_get_dst_buf(ctx);
+
+	ref = hantro_get_ref(cap_q, hdr->last_frame_ts);
+	if (!ref)
+		ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
+	vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF0);
+
+	ref = hantro_get_ref(cap_q, hdr->golden_frame_ts);
+	WARN_ON(!ref && hdr->golden_frame_ts);
+	if (!ref)
+		ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
+	if (hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN)
+		ref |= VDPU_REG_VP8_GREF_SIGN_BIAS;
+	vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF2_5(2));
+
+	ref = hantro_get_ref(cap_q, hdr->alt_frame_ts);
+	WARN_ON(!ref && hdr->alt_frame_ts);
+	if (!ref)
+		ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
+	if (hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT)
+		ref |= VDPU_REG_VP8_AREF_SIGN_BIAS;
+	vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF2_5(3));
+}
+
+static void cfg_buffers(struct hantro_ctx *ctx,
+			const struct v4l2_ctrl_vp8_frame_header *hdr)
+{
+	const struct v4l2_vp8_segment_header *seg = &hdr->segment_header;
+	struct hantro_dev *vpu = ctx->dev;
+	struct vb2_v4l2_buffer *vb2_dst;
+	dma_addr_t dst_dma;
+	u32 reg;
+
+	vb2_dst = hantro_get_dst_buf(ctx);
+
+	/* Set probability table buffer address */
+	vdpu_write_relaxed(vpu, ctx->vp8_dec.prob_tbl.dma,
+			   VDPU_REG_ADDR_QTABLE);
+
+	/* Set segment map address */
+	reg = VDPU_REG_FWD_PIC1_SEGMENT_BASE(ctx->vp8_dec.segment_map.dma);
+	if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED) {
+		reg |= VDPU_REG_FWD_PIC1_SEGMENT_E;
+		if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP)
+			reg |= VDPU_REG_FWD_PIC1_SEGMENT_UPD_E;
+	}
+	vdpu_write_relaxed(vpu, reg, VDPU_REG_VP8_SEGMENT_VAL);
+
+	/* set output frame buffer address */
+	dst_dma = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0);
+	vdpu_write_relaxed(vpu, dst_dma, VDPU_REG_ADDR_DST);
+}
+
+void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx)
+{
+	const struct v4l2_ctrl_vp8_frame_header *hdr;
+	struct hantro_dev *vpu = ctx->dev;
+	size_t height = ctx->dst_fmt.height;
+	size_t width = ctx->dst_fmt.width;
+	u32 mb_width, mb_height;
+	u32 reg;
+
+	hantro_prepare_run(ctx);
+
+	hdr = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER);
+	if (WARN_ON(!hdr))
+		return;
+
+	/* Reset segment_map buffer in keyframe */
+	if (VP8_FRAME_IS_KEY_FRAME(hdr) && ctx->vp8_dec.segment_map.cpu)
+		memset(ctx->vp8_dec.segment_map.cpu, 0,
+		       ctx->vp8_dec.segment_map.size);
+
+	hantro_vp8_prob_update(ctx, hdr);
+
+	/*
+	 * Extensive testing shows that the hardware does not properly
+	 * clear the internal state from previous a decoding run. This
+	 * causes corruption in decoded frames for multi-instance use cases.
+	 * A soft reset before programming the registers has been found
+	 * to resolve those problems.
+	 */
+	ctx->codec_ops->reset(ctx);
+
+	reg = VDPU_REG_CONFIG_DEC_TIMEOUT_E
+		| VDPU_REG_CONFIG_DEC_CLK_GATE_E;
+	if (!VP8_FRAME_IS_KEY_FRAME(hdr))
+		reg |= VDPU_REG_DEC_CTRL0_PIC_INTER_E;
+	vdpu_write_relaxed(vpu, reg, VDPU_REG_EN_FLAGS);
+
+	reg = VDPU_REG_CONFIG_DEC_STRENDIAN_E
+		| VDPU_REG_CONFIG_DEC_INSWAP32_E
+		| VDPU_REG_CONFIG_DEC_STRSWAP32_E
+		| VDPU_REG_CONFIG_DEC_OUTSWAP32_E
+		| VDPU_REG_CONFIG_DEC_IN_ENDIAN
+		| VDPU_REG_CONFIG_DEC_OUT_ENDIAN;
+	vdpu_write_relaxed(vpu, reg, VDPU_REG_DATA_ENDIAN);
+
+	reg = VDPU_REG_CONFIG_DEC_MAX_BURST(16);
+	vdpu_write_relaxed(vpu, reg, VDPU_REG_AXI_CTRL);
+
+	reg = VDPU_REG_DEC_CTRL0_DEC_MODE(10);
+	vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_FORMAT);
+
+	if (!(hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF))
+		hantro_reg_write(vpu, &vp8_dec_skip_mode, 1);
+	if (hdr->lf_header.level == 0)
+		hantro_reg_write(vpu, &vp8_dec_filter_disable, 1);
+
+	/* Frame dimensions */
+	mb_width = VP8_MB_WIDTH(width);
+	mb_height = VP8_MB_HEIGHT(height);
+
+	hantro_reg_write(vpu, &vp8_dec_mb_width, mb_width);
+	hantro_reg_write(vpu, &vp8_dec_mb_height, mb_height);
+	hantro_reg_write(vpu, &vp8_dec_mb_width_ext, mb_width >> 9);
+	hantro_reg_write(vpu, &vp8_dec_mb_height_ext, mb_height >> 8);
+
+	/* Boolean decoder */
+	hantro_reg_write(vpu, &vp8_dec_bool_range, hdr->coder_state.range);
+	hantro_reg_write(vpu, &vp8_dec_bool_value, hdr->coder_state.value);
+
+	reg = vdpu_read(vpu, VDPU_REG_VP8_DCT_START_BIT);
+	if (hdr->version != 3)
+		reg |= VDPU_REG_DEC_CTRL4_VC1_HEIGHT_EXT;
+	if (hdr->version & 0x3)
+		reg |= VDPU_REG_DEC_CTRL4_BILIN_MC_E;
+	vdpu_write_relaxed(vpu, reg, VDPU_REG_VP8_DCT_START_BIT);
+
+	cfg_lf(ctx, hdr);
+	cfg_qp(ctx, hdr);
+	cfg_parts(ctx, hdr);
+	cfg_tap(ctx, hdr);
+	cfg_ref(ctx, hdr);
+	cfg_buffers(ctx, hdr);
+
+	hantro_finish_run(ctx);
+
+	hantro_reg_write(vpu, &vp8_dec_start_dec, 1);
+}
diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig
index 4c72634..8f1ae50 100644
--- a/drivers/staging/media/imx/Kconfig
+++ b/drivers/staging/media/imx/Kconfig
@@ -7,6 +7,7 @@
 	depends on HAS_DMA
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_FWNODE
+	select V4L2_MEM2MEM_DEV
 	help
 	  Say yes here to enable support for video4linux media controller
 	  driver for the i.MX5/6 SOC.
@@ -22,11 +23,11 @@
 	  A video4linux camera sensor interface driver for i.MX5/6.
 
 config VIDEO_IMX7_CSI
-	tristate "i.MX7 Camera Sensor Interface driver"
+	tristate "i.MX6UL/L / i.MX7 Camera Sensor Interface driver"
 	depends on VIDEO_IMX_MEDIA && VIDEO_DEV && I2C
 	default y
 	help
 	  Enable support for video4linux camera sensor interface driver for
-	  i.MX7.
+	  i.MX6UL/L or i.MX7.
 endmenu
 endif
diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile
index aa6c4b4..9bd9e87 100644
--- a/drivers/staging/media/imx/Makefile
+++ b/drivers/staging/media/imx/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 imx6-media-objs := imx-media-dev.o imx-media-internal-sd.o \
-	imx-ic-common.o imx-ic-prp.o imx-ic-prpencvf.o imx-media-vdic.o
+	imx-ic-common.o imx-ic-prp.o imx-ic-prpencvf.o imx-media-vdic.o \
+	imx-media-csc-scaler.o
 
 imx-media-common-objs := imx-media-capture.o imx-media-dev-common.o \
 	imx-media-of.o imx-media-utils.o
diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c
new file mode 100644
index 0000000..2b635eb
--- /dev/null
+++ b/drivers/staging/media/imx/imx-media-csc-scaler.c
@@ -0,0 +1,925 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * i.MX IPUv3 IC PP mem2mem CSC/Scaler driver
+ *
+ * Copyright (C) 2011 Pengutronix, Sascha Hauer
+ * Copyright (C) 2018 Pengutronix, Philipp Zabel
+ */
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <video/imx-ipu-v3.h>
+#include <video/imx-ipu-image-convert.h>
+
+#include <media/media-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "imx-media.h"
+
+#define fh_to_ctx(__fh)	container_of(__fh, struct ipu_csc_scaler_ctx, fh)
+
+enum {
+	V4L2_M2M_SRC = 0,
+	V4L2_M2M_DST = 1,
+};
+
+struct ipu_csc_scaler_priv {
+	struct imx_media_video_dev	vdev;
+
+	struct v4l2_m2m_dev		*m2m_dev;
+	struct device			*dev;
+
+	struct imx_media_dev		*md;
+
+	struct mutex			mutex;	/* mem2mem device mutex */
+};
+
+#define vdev_to_priv(v) container_of(v, struct ipu_csc_scaler_priv, vdev)
+
+/* Per-queue, driver-specific private data */
+struct ipu_csc_scaler_q_data {
+	struct v4l2_pix_format		cur_fmt;
+	struct v4l2_rect		rect;
+};
+
+struct ipu_csc_scaler_ctx {
+	struct ipu_csc_scaler_priv	*priv;
+
+	struct v4l2_fh			fh;
+	struct ipu_csc_scaler_q_data	q_data[2];
+	struct ipu_image_convert_ctx	*icc;
+
+	struct v4l2_ctrl_handler	ctrl_hdlr;
+	int				rotate;
+	bool				hflip;
+	bool				vflip;
+	enum ipu_rotate_mode		rot_mode;
+	unsigned int			sequence;
+};
+
+static struct ipu_csc_scaler_q_data *get_q_data(struct ipu_csc_scaler_ctx *ctx,
+						enum v4l2_buf_type type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return &ctx->q_data[V4L2_M2M_SRC];
+	else
+		return &ctx->q_data[V4L2_M2M_DST];
+}
+
+/*
+ * mem2mem callbacks
+ */
+
+static void job_abort(void *_ctx)
+{
+	struct ipu_csc_scaler_ctx *ctx = _ctx;
+
+	if (ctx->icc)
+		ipu_image_convert_abort(ctx->icc);
+}
+
+static void ipu_ic_pp_complete(struct ipu_image_convert_run *run, void *_ctx)
+{
+	struct ipu_csc_scaler_ctx *ctx = _ctx;
+	struct ipu_csc_scaler_priv *priv = ctx->priv;
+	struct vb2_v4l2_buffer *src_buf, *dst_buf;
+
+	src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+	dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+
+	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);
+
+	src_buf->sequence = ctx->sequence++;
+	dst_buf->sequence = src_buf->sequence;
+
+	v4l2_m2m_buf_done(src_buf, run->status ? VB2_BUF_STATE_ERROR :
+						 VB2_BUF_STATE_DONE);
+	v4l2_m2m_buf_done(dst_buf, run->status ? VB2_BUF_STATE_ERROR :
+						 VB2_BUF_STATE_DONE);
+
+	v4l2_m2m_job_finish(priv->m2m_dev, ctx->fh.m2m_ctx);
+	kfree(run);
+}
+
+static void device_run(void *_ctx)
+{
+	struct ipu_csc_scaler_ctx *ctx = _ctx;
+	struct ipu_csc_scaler_priv *priv = ctx->priv;
+	struct vb2_v4l2_buffer *src_buf, *dst_buf;
+	struct ipu_image_convert_run *run;
+	int ret;
+
+	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
+	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
+
+	run = kzalloc(sizeof(*run), GFP_KERNEL);
+	if (!run)
+		goto err;
+
+	run->ctx = ctx->icc;
+	run->in_phys = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
+	run->out_phys = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
+
+	ret = ipu_image_convert_queue(run);
+	if (ret < 0) {
+		v4l2_err(ctx->priv->vdev.vfd->v4l2_dev,
+			 "%s: failed to queue: %d\n", __func__, ret);
+		goto err;
+	}
+
+	return;
+
+err:
+	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
+	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
+	v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
+	v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
+	v4l2_m2m_job_finish(priv->m2m_dev, ctx->fh.m2m_ctx);
+}
+
+/*
+ * Video ioctls
+ */
+static int ipu_csc_scaler_querycap(struct file *file, void *priv,
+				   struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, "imx-media-csc-scaler", sizeof(cap->driver));
+	strscpy(cap->card, "imx-media-csc-scaler", sizeof(cap->card));
+	strscpy(cap->bus_info, "platform:imx-media-csc-scaler",
+		sizeof(cap->bus_info));
+
+	return 0;
+}
+
+static int ipu_csc_scaler_enum_fmt(struct file *file, void *fh,
+				   struct v4l2_fmtdesc *f)
+{
+	u32 fourcc;
+	int ret;
+
+	ret = imx_media_enum_format(&fourcc, f->index, CS_SEL_ANY);
+	if (ret)
+		return ret;
+
+	f->pixelformat = fourcc;
+
+	return 0;
+}
+
+static int ipu_csc_scaler_g_fmt(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct ipu_csc_scaler_ctx *ctx = fh_to_ctx(priv);
+	struct ipu_csc_scaler_q_data *q_data;
+
+	q_data = get_q_data(ctx, f->type);
+
+	f->fmt.pix = q_data->cur_fmt;
+
+	return 0;
+}
+
+static int ipu_csc_scaler_try_fmt(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct ipu_csc_scaler_ctx *ctx = fh_to_ctx(priv);
+	struct ipu_csc_scaler_q_data *q_data = get_q_data(ctx, f->type);
+	struct ipu_image test_in, test_out;
+	enum v4l2_field field;
+
+	field = f->fmt.pix.field;
+	if (field == V4L2_FIELD_ANY)
+		field = V4L2_FIELD_NONE;
+	else if (field != V4L2_FIELD_NONE)
+		return -EINVAL;
+
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		struct ipu_csc_scaler_q_data *q_data_in =
+			get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+
+		test_out.pix = f->fmt.pix;
+		test_in.pix = q_data_in->cur_fmt;
+	} else {
+		struct ipu_csc_scaler_q_data *q_data_out =
+			get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+
+		test_in.pix = f->fmt.pix;
+		test_out.pix = q_data_out->cur_fmt;
+	}
+
+	ipu_image_convert_adjust(&test_in, &test_out, ctx->rot_mode);
+
+	f->fmt.pix = (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
+		test_out.pix : test_in.pix;
+
+	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		f->fmt.pix.colorspace = q_data->cur_fmt.colorspace;
+		f->fmt.pix.ycbcr_enc = q_data->cur_fmt.ycbcr_enc;
+		f->fmt.pix.xfer_func = q_data->cur_fmt.xfer_func;
+		f->fmt.pix.quantization = q_data->cur_fmt.quantization;
+	} else if (f->fmt.pix.colorspace == V4L2_COLORSPACE_DEFAULT) {
+		f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
+		f->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+		f->fmt.pix.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+		f->fmt.pix.quantization = V4L2_QUANTIZATION_DEFAULT;
+	}
+
+	return 0;
+}
+
+static int ipu_csc_scaler_s_fmt(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct ipu_csc_scaler_q_data *q_data;
+	struct ipu_csc_scaler_ctx *ctx = fh_to_ctx(priv);
+	struct vb2_queue *vq;
+	int ret;
+
+	vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
+	if (vb2_is_busy(vq)) {
+		v4l2_err(ctx->priv->vdev.vfd->v4l2_dev, "%s: queue busy\n",
+			 __func__);
+		return -EBUSY;
+	}
+
+	q_data = get_q_data(ctx, f->type);
+
+	ret = ipu_csc_scaler_try_fmt(file, priv, f);
+	if (ret < 0)
+		return ret;
+
+	q_data->cur_fmt.width = f->fmt.pix.width;
+	q_data->cur_fmt.height = f->fmt.pix.height;
+	q_data->cur_fmt.pixelformat = f->fmt.pix.pixelformat;
+	q_data->cur_fmt.field = f->fmt.pix.field;
+	q_data->cur_fmt.bytesperline = f->fmt.pix.bytesperline;
+	q_data->cur_fmt.sizeimage = f->fmt.pix.sizeimage;
+
+	/* Reset cropping/composing rectangle */
+	q_data->rect.left = 0;
+	q_data->rect.top = 0;
+	q_data->rect.width = q_data->cur_fmt.width;
+	q_data->rect.height = q_data->cur_fmt.height;
+
+	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+		/* Set colorimetry on the output queue */
+		q_data->cur_fmt.colorspace = f->fmt.pix.colorspace;
+		q_data->cur_fmt.ycbcr_enc = f->fmt.pix.ycbcr_enc;
+		q_data->cur_fmt.xfer_func = f->fmt.pix.xfer_func;
+		q_data->cur_fmt.quantization = f->fmt.pix.quantization;
+		/* Propagate colorimetry to the capture queue */
+		q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		q_data->cur_fmt.colorspace = f->fmt.pix.colorspace;
+		q_data->cur_fmt.ycbcr_enc = f->fmt.pix.ycbcr_enc;
+		q_data->cur_fmt.xfer_func = f->fmt.pix.xfer_func;
+		q_data->cur_fmt.quantization = f->fmt.pix.quantization;
+	}
+
+	/*
+	 * TODO: Setting colorimetry on the capture queue is currently not
+	 * supported by the V4L2 API
+	 */
+
+	return 0;
+}
+
+static int ipu_csc_scaler_g_selection(struct file *file, void *priv,
+				      struct v4l2_selection *s)
+{
+	struct ipu_csc_scaler_ctx *ctx = fh_to_ctx(priv);
+	struct ipu_csc_scaler_q_data *q_data;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_CROP:
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+			return -EINVAL;
+		q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+		break;
+	case V4L2_SEL_TGT_COMPOSE:
+	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+		if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+			return -EINVAL;
+		q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (s->target == V4L2_SEL_TGT_CROP ||
+	    s->target == V4L2_SEL_TGT_COMPOSE) {
+		s->r = q_data->rect;
+	} else {
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = q_data->cur_fmt.width;
+		s->r.height = q_data->cur_fmt.height;
+	}
+
+	return 0;
+}
+
+static int ipu_csc_scaler_s_selection(struct file *file, void *priv,
+				      struct v4l2_selection *s)
+{
+	struct ipu_csc_scaler_ctx *ctx = fh_to_ctx(priv);
+	struct ipu_csc_scaler_q_data *q_data;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_CROP:
+		if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+			return -EINVAL;
+		break;
+	case V4L2_SEL_TGT_COMPOSE:
+		if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+	    s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		return -EINVAL;
+
+	q_data = get_q_data(ctx, s->type);
+
+	/* The input's frame width to the IC must be a multiple of 8 pixels
+	 * When performing resizing the frame width must be multiple of burst
+	 * size - 8 or 16 pixels as defined by CB#_BURST_16 parameter.
+	 */
+	if (s->flags & V4L2_SEL_FLAG_GE)
+		s->r.width = round_up(s->r.width, 8);
+	if (s->flags & V4L2_SEL_FLAG_LE)
+		s->r.width = round_down(s->r.width, 8);
+	s->r.width = clamp_t(unsigned int, s->r.width, 8,
+			     round_down(q_data->cur_fmt.width, 8));
+	s->r.height = clamp_t(unsigned int, s->r.height, 1,
+			      q_data->cur_fmt.height);
+	s->r.left = clamp_t(unsigned int, s->r.left, 0,
+			    q_data->cur_fmt.width - s->r.width);
+	s->r.top = clamp_t(unsigned int, s->r.top, 0,
+			   q_data->cur_fmt.height - s->r.height);
+
+	/* V4L2_SEL_FLAG_KEEP_CONFIG is only valid for subdevices */
+	q_data->rect = s->r;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops ipu_csc_scaler_ioctl_ops = {
+	.vidioc_querycap		= ipu_csc_scaler_querycap,
+
+	.vidioc_enum_fmt_vid_cap	= ipu_csc_scaler_enum_fmt,
+	.vidioc_g_fmt_vid_cap		= ipu_csc_scaler_g_fmt,
+	.vidioc_try_fmt_vid_cap		= ipu_csc_scaler_try_fmt,
+	.vidioc_s_fmt_vid_cap		= ipu_csc_scaler_s_fmt,
+
+	.vidioc_enum_fmt_vid_out	= ipu_csc_scaler_enum_fmt,
+	.vidioc_g_fmt_vid_out		= ipu_csc_scaler_g_fmt,
+	.vidioc_try_fmt_vid_out		= ipu_csc_scaler_try_fmt,
+	.vidioc_s_fmt_vid_out		= ipu_csc_scaler_s_fmt,
+
+	.vidioc_g_selection		= ipu_csc_scaler_g_selection,
+	.vidioc_s_selection		= ipu_csc_scaler_s_selection,
+
+	.vidioc_reqbufs			= v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querybuf		= v4l2_m2m_ioctl_querybuf,
+
+	.vidioc_qbuf			= v4l2_m2m_ioctl_qbuf,
+	.vidioc_expbuf			= v4l2_m2m_ioctl_expbuf,
+	.vidioc_dqbuf			= v4l2_m2m_ioctl_dqbuf,
+	.vidioc_create_bufs		= v4l2_m2m_ioctl_create_bufs,
+	.vidioc_prepare_buf		= v4l2_m2m_ioctl_prepare_buf,
+
+	.vidioc_streamon		= v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff		= v4l2_m2m_ioctl_streamoff,
+
+	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
+	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
+};
+
+/*
+ * Queue operations
+ */
+
+static int ipu_csc_scaler_queue_setup(struct vb2_queue *vq,
+				      unsigned int *nbuffers,
+				      unsigned int *nplanes,
+				      unsigned int sizes[],
+				      struct device *alloc_devs[])
+{
+	struct ipu_csc_scaler_ctx *ctx = vb2_get_drv_priv(vq);
+	struct ipu_csc_scaler_q_data *q_data;
+	unsigned int size, count = *nbuffers;
+
+	q_data = get_q_data(ctx, vq->type);
+
+	size = q_data->cur_fmt.sizeimage;
+
+	*nbuffers = count;
+
+	if (*nplanes)
+		return sizes[0] < size ? -EINVAL : 0;
+
+	*nplanes = 1;
+	sizes[0] = size;
+
+	dev_dbg(ctx->priv->dev, "get %d buffer(s) of size %d each.\n",
+		count, size);
+
+	return 0;
+}
+
+static int ipu_csc_scaler_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vb2_queue *vq = vb->vb2_queue;
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct ipu_csc_scaler_ctx *ctx = vb2_get_drv_priv(vq);
+	struct ipu_csc_scaler_q_data *q_data;
+	unsigned long size;
+
+	dev_dbg(ctx->priv->dev, "type: %d\n", vq->type);
+
+	if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
+		if (vbuf->field == V4L2_FIELD_ANY)
+			vbuf->field = V4L2_FIELD_NONE;
+		if (vbuf->field != V4L2_FIELD_NONE) {
+			dev_dbg(ctx->priv->dev, "%s: field isn't supported\n",
+				__func__);
+			return -EINVAL;
+		}
+	}
+
+	q_data = get_q_data(ctx, vq->type);
+	size = q_data->cur_fmt.sizeimage;
+
+	if (vb2_plane_size(vb, 0) < size) {
+		dev_dbg(ctx->priv->dev,
+			"%s: data will not fit into plane (%lu < %lu)\n",
+			__func__, vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+
+	vb2_set_plane_payload(vb, 0, size);
+
+	return 0;
+}
+
+static void ipu_csc_scaler_buf_queue(struct vb2_buffer *vb)
+{
+	struct ipu_csc_scaler_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb));
+}
+
+static void ipu_image_from_q_data(struct ipu_image *im,
+				  struct ipu_csc_scaler_q_data *q_data)
+{
+	struct v4l2_pix_format *fmt = &q_data->cur_fmt;
+
+	im->pix = *fmt;
+	if (fmt->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
+		im->pix.ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
+	if (fmt->quantization == V4L2_QUANTIZATION_DEFAULT)
+		im->pix.ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
+	im->rect = q_data->rect;
+}
+
+static int ipu_csc_scaler_start_streaming(struct vb2_queue *q,
+					  unsigned int count)
+{
+	const enum ipu_ic_task ic_task = IC_TASK_POST_PROCESSOR;
+	struct ipu_csc_scaler_ctx *ctx = vb2_get_drv_priv(q);
+	struct ipu_csc_scaler_priv *priv = ctx->priv;
+	struct ipu_soc *ipu = priv->md->ipu[0];
+	struct ipu_csc_scaler_q_data *q_data;
+	struct vb2_queue *other_q;
+	struct ipu_image in, out;
+
+	other_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+				  (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
+				  V4L2_BUF_TYPE_VIDEO_OUTPUT :
+				  V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	if (!vb2_is_streaming(other_q))
+		return 0;
+
+	if (ctx->icc) {
+		v4l2_warn(ctx->priv->vdev.vfd->v4l2_dev, "removing old ICC\n");
+		ipu_image_convert_unprepare(ctx->icc);
+	}
+
+	q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+	ipu_image_from_q_data(&in, q_data);
+
+	q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	ipu_image_from_q_data(&out, q_data);
+
+	ctx->icc = ipu_image_convert_prepare(ipu, ic_task, &in, &out,
+					     ctx->rot_mode,
+					     ipu_ic_pp_complete, ctx);
+	if (IS_ERR(ctx->icc)) {
+		struct vb2_v4l2_buffer *buf;
+		int ret = PTR_ERR(ctx->icc);
+
+		ctx->icc = NULL;
+		v4l2_err(ctx->priv->vdev.vfd->v4l2_dev, "%s: error %d\n",
+			 __func__, ret);
+		while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx)))
+			v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
+		while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx)))
+			v4l2_m2m_buf_done(buf, VB2_BUF_STATE_QUEUED);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void ipu_csc_scaler_stop_streaming(struct vb2_queue *q)
+{
+	struct ipu_csc_scaler_ctx *ctx = vb2_get_drv_priv(q);
+	struct vb2_v4l2_buffer *buf;
+
+	if (ctx->icc) {
+		ipu_image_convert_unprepare(ctx->icc);
+		ctx->icc = NULL;
+	}
+
+	ctx->sequence = 0;
+
+	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+		while ((buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx)))
+			v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR);
+	} else {
+		while ((buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx)))
+			v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR);
+	}
+}
+
+static const struct vb2_ops ipu_csc_scaler_qops = {
+	.queue_setup		= ipu_csc_scaler_queue_setup,
+	.buf_prepare		= ipu_csc_scaler_buf_prepare,
+	.buf_queue		= ipu_csc_scaler_buf_queue,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+	.start_streaming	= ipu_csc_scaler_start_streaming,
+	.stop_streaming		= ipu_csc_scaler_stop_streaming,
+};
+
+static int ipu_csc_scaler_queue_init(void *priv, struct vb2_queue *src_vq,
+				     struct vb2_queue *dst_vq)
+{
+	struct ipu_csc_scaler_ctx *ctx = priv;
+	int ret;
+
+	memset(src_vq, 0, sizeof(*src_vq));
+	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+	src_vq->drv_priv = ctx;
+	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+	src_vq->ops = &ipu_csc_scaler_qops;
+	src_vq->mem_ops = &vb2_dma_contig_memops;
+	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	src_vq->lock = &ctx->priv->mutex;
+	src_vq->dev = ctx->priv->dev;
+
+	ret = vb2_queue_init(src_vq);
+	if (ret)
+		return ret;
+
+	memset(dst_vq, 0, sizeof(*dst_vq));
+	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+	dst_vq->drv_priv = ctx;
+	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
+	dst_vq->ops = &ipu_csc_scaler_qops;
+	dst_vq->mem_ops = &vb2_dma_contig_memops;
+	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	dst_vq->lock = &ctx->priv->mutex;
+	dst_vq->dev = ctx->priv->dev;
+
+	return vb2_queue_init(dst_vq);
+}
+
+static int ipu_csc_scaler_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ipu_csc_scaler_ctx *ctx = container_of(ctrl->handler,
+						      struct ipu_csc_scaler_ctx,
+						      ctrl_hdlr);
+	enum ipu_rotate_mode rot_mode;
+	int rotate;
+	bool hflip, vflip;
+	int ret = 0;
+
+	rotate = ctx->rotate;
+	hflip = ctx->hflip;
+	vflip = ctx->vflip;
+
+	switch (ctrl->id) {
+	case V4L2_CID_HFLIP:
+		hflip = ctrl->val;
+		break;
+	case V4L2_CID_VFLIP:
+		vflip = ctrl->val;
+		break;
+	case V4L2_CID_ROTATE:
+		rotate = ctrl->val;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = ipu_degrees_to_rot_mode(&rot_mode, rotate, hflip, vflip);
+	if (ret)
+		return ret;
+
+	if (rot_mode != ctx->rot_mode) {
+		struct v4l2_pix_format *in_fmt, *out_fmt;
+		struct ipu_image test_in, test_out;
+
+		in_fmt = &ctx->q_data[V4L2_M2M_SRC].cur_fmt;
+		out_fmt = &ctx->q_data[V4L2_M2M_DST].cur_fmt;
+
+		test_in.pix = *in_fmt;
+		test_out.pix = *out_fmt;
+
+		if (ipu_rot_mode_is_irt(rot_mode) !=
+		    ipu_rot_mode_is_irt(ctx->rot_mode)) {
+			/* Switch width & height to keep aspect ratio intact */
+			test_out.pix.width = out_fmt->height;
+			test_out.pix.height = out_fmt->width;
+		}
+
+		ipu_image_convert_adjust(&test_in, &test_out, ctx->rot_mode);
+
+		/* Check if output format needs to be changed */
+		if (test_in.pix.width != in_fmt->width ||
+		    test_in.pix.height != in_fmt->height ||
+		    test_in.pix.bytesperline != in_fmt->bytesperline ||
+		    test_in.pix.sizeimage != in_fmt->sizeimage) {
+			struct vb2_queue *out_q;
+
+			out_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+						V4L2_BUF_TYPE_VIDEO_OUTPUT);
+			if (vb2_is_busy(out_q))
+				return -EBUSY;
+		}
+
+		/* Check if capture format needs to be changed */
+		if (test_out.pix.width != out_fmt->width ||
+		    test_out.pix.height != out_fmt->height ||
+		    test_out.pix.bytesperline != out_fmt->bytesperline ||
+		    test_out.pix.sizeimage != out_fmt->sizeimage) {
+			struct vb2_queue *cap_q;
+
+			cap_q = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
+						V4L2_BUF_TYPE_VIDEO_CAPTURE);
+			if (vb2_is_busy(cap_q))
+				return -EBUSY;
+		}
+
+		*in_fmt = test_in.pix;
+		*out_fmt = test_out.pix;
+
+		ctx->rot_mode = rot_mode;
+		ctx->rotate = rotate;
+		ctx->hflip = hflip;
+		ctx->vflip = vflip;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops ipu_csc_scaler_ctrl_ops = {
+	.s_ctrl = ipu_csc_scaler_s_ctrl,
+};
+
+static int ipu_csc_scaler_init_controls(struct ipu_csc_scaler_ctx *ctx)
+{
+	struct v4l2_ctrl_handler *hdlr = &ctx->ctrl_hdlr;
+
+	v4l2_ctrl_handler_init(hdlr, 3);
+
+	v4l2_ctrl_new_std(hdlr, &ipu_csc_scaler_ctrl_ops, V4L2_CID_HFLIP,
+			  0, 1, 1, 0);
+	v4l2_ctrl_new_std(hdlr, &ipu_csc_scaler_ctrl_ops, V4L2_CID_VFLIP,
+			  0, 1, 1, 0);
+	v4l2_ctrl_new_std(hdlr, &ipu_csc_scaler_ctrl_ops, V4L2_CID_ROTATE,
+			  0, 270, 90, 0);
+
+	if (hdlr->error) {
+		v4l2_ctrl_handler_free(hdlr);
+		return hdlr->error;
+	}
+
+	v4l2_ctrl_handler_setup(hdlr);
+	return 0;
+}
+
+#define DEFAULT_WIDTH	720
+#define DEFAULT_HEIGHT	576
+static const struct ipu_csc_scaler_q_data ipu_csc_scaler_q_data_default = {
+	.cur_fmt = {
+		.width = DEFAULT_WIDTH,
+		.height = DEFAULT_HEIGHT,
+		.pixelformat = V4L2_PIX_FMT_YUV420,
+		.field = V4L2_FIELD_NONE,
+		.bytesperline = DEFAULT_WIDTH,
+		.sizeimage = DEFAULT_WIDTH * DEFAULT_HEIGHT * 3 / 2,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+	},
+	.rect = {
+		.width = DEFAULT_WIDTH,
+		.height = DEFAULT_HEIGHT,
+	},
+};
+
+/*
+ * File operations
+ */
+static int ipu_csc_scaler_open(struct file *file)
+{
+	struct ipu_csc_scaler_priv *priv = video_drvdata(file);
+	struct ipu_csc_scaler_ctx *ctx = NULL;
+	int ret;
+
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->rot_mode = IPU_ROTATE_NONE;
+
+	v4l2_fh_init(&ctx->fh, video_devdata(file));
+	file->private_data = &ctx->fh;
+	v4l2_fh_add(&ctx->fh);
+	ctx->priv = priv;
+
+	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(priv->m2m_dev, ctx,
+					    &ipu_csc_scaler_queue_init);
+	if (IS_ERR(ctx->fh.m2m_ctx)) {
+		ret = PTR_ERR(ctx->fh.m2m_ctx);
+		goto err_ctx;
+	}
+
+	ret = ipu_csc_scaler_init_controls(ctx);
+	if (ret)
+		goto err_ctrls;
+
+	ctx->fh.ctrl_handler = &ctx->ctrl_hdlr;
+
+	ctx->q_data[V4L2_M2M_SRC] = ipu_csc_scaler_q_data_default;
+	ctx->q_data[V4L2_M2M_DST] = ipu_csc_scaler_q_data_default;
+
+	dev_dbg(priv->dev, "Created instance %p, m2m_ctx: %p\n", ctx,
+		ctx->fh.m2m_ctx);
+
+	return 0;
+
+err_ctrls:
+	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+err_ctx:
+	v4l2_fh_del(&ctx->fh);
+	v4l2_fh_exit(&ctx->fh);
+	kfree(ctx);
+	return ret;
+}
+
+static int ipu_csc_scaler_release(struct file *file)
+{
+	struct ipu_csc_scaler_priv *priv = video_drvdata(file);
+	struct ipu_csc_scaler_ctx *ctx = fh_to_ctx(file->private_data);
+
+	dev_dbg(priv->dev, "Releasing instance %p\n", ctx);
+
+	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
+	v4l2_fh_del(&ctx->fh);
+	v4l2_fh_exit(&ctx->fh);
+	kfree(ctx);
+
+	return 0;
+}
+
+static const struct v4l2_file_operations ipu_csc_scaler_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ipu_csc_scaler_open,
+	.release	= ipu_csc_scaler_release,
+	.poll		= v4l2_m2m_fop_poll,
+	.unlocked_ioctl	= video_ioctl2,
+	.mmap		= v4l2_m2m_fop_mmap,
+};
+
+static struct v4l2_m2m_ops m2m_ops = {
+	.device_run	= device_run,
+	.job_abort	= job_abort,
+};
+
+static void ipu_csc_scaler_video_device_release(struct video_device *vdev)
+{
+	struct ipu_csc_scaler_priv *priv = video_get_drvdata(vdev);
+
+	v4l2_m2m_release(priv->m2m_dev);
+	video_device_release(vdev);
+	kfree(priv);
+}
+
+static const struct video_device ipu_csc_scaler_videodev_template = {
+	.name		= "ipu_ic_pp csc/scaler",
+	.fops		= &ipu_csc_scaler_fops,
+	.ioctl_ops	= &ipu_csc_scaler_ioctl_ops,
+	.minor		= -1,
+	.release	= ipu_csc_scaler_video_device_release,
+	.vfl_dir	= VFL_DIR_M2M,
+	.device_caps	= V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
+};
+
+int imx_media_csc_scaler_device_register(struct imx_media_video_dev *vdev)
+{
+	struct ipu_csc_scaler_priv *priv = vdev_to_priv(vdev);
+	struct video_device *vfd = vdev->vfd;
+	int ret;
+
+	vfd->v4l2_dev = &priv->md->v4l2_dev;
+
+	ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
+	if (ret) {
+		v4l2_err(vfd->v4l2_dev, "Failed to register video device\n");
+		return ret;
+	}
+
+	v4l2_info(vfd->v4l2_dev, "Registered %s as /dev/%s\n", vfd->name,
+		  video_device_node_name(vfd));
+
+	return 0;
+}
+
+void imx_media_csc_scaler_device_unregister(struct imx_media_video_dev *vdev)
+{
+	struct ipu_csc_scaler_priv *priv = vdev_to_priv(vdev);
+	struct video_device *vfd = priv->vdev.vfd;
+
+	mutex_lock(&priv->mutex);
+
+	video_unregister_device(vfd);
+
+	mutex_unlock(&priv->mutex);
+}
+
+struct imx_media_video_dev *
+imx_media_csc_scaler_device_init(struct imx_media_dev *md)
+{
+	struct ipu_csc_scaler_priv *priv;
+	struct video_device *vfd;
+	int ret;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return ERR_PTR(-ENOMEM);
+
+	priv->md = md;
+	priv->dev = md->md.dev;
+
+	mutex_init(&priv->mutex);
+
+	vfd = video_device_alloc();
+	if (!vfd) {
+		ret = -ENOMEM;
+		goto err_vfd;
+	}
+
+	*vfd = ipu_csc_scaler_videodev_template;
+	vfd->lock = &priv->mutex;
+	priv->vdev.vfd = vfd;
+
+	INIT_LIST_HEAD(&priv->vdev.list);
+
+	video_set_drvdata(vfd, priv);
+
+	priv->m2m_dev = v4l2_m2m_init(&m2m_ops);
+	if (IS_ERR(priv->m2m_dev)) {
+		ret = PTR_ERR(priv->m2m_dev);
+		v4l2_err(&md->v4l2_dev, "Failed to init mem2mem device: %d\n",
+			 ret);
+		goto err_m2m;
+	}
+
+	return &priv->vdev;
+
+err_m2m:
+	video_set_drvdata(vfd, NULL);
+err_vfd:
+	kfree(priv);
+	return ERR_PTR(ret);
+}
+
+MODULE_DESCRIPTION("i.MX IPUv3 mem2mem scaler/CSC driver");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
index 6ac371f..2c3c2ad 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -38,9 +38,34 @@
 }
 
 /* async subdev complete notifier */
+static int imx6_media_probe_complete(struct v4l2_async_notifier *notifier)
+{
+	struct imx_media_dev *imxmd = notifier2dev(notifier);
+	int ret;
+
+	/* call the imx5/6/7 common probe completion handler */
+	ret = imx_media_probe_complete(notifier);
+	if (ret)
+		return ret;
+
+	mutex_lock(&imxmd->mutex);
+
+	imxmd->m2m_vdev = imx_media_csc_scaler_device_init(imxmd);
+	if (IS_ERR(imxmd->m2m_vdev)) {
+		ret = PTR_ERR(imxmd->m2m_vdev);
+		goto unlock;
+	}
+
+	ret = imx_media_csc_scaler_device_register(imxmd->m2m_vdev);
+unlock:
+	mutex_unlock(&imxmd->mutex);
+	return ret;
+}
+
+/* async subdev complete notifier */
 static const struct v4l2_async_notifier_operations imx_media_notifier_ops = {
 	.bound = imx_media_subdev_bound,
-	.complete = imx_media_probe_complete,
+	.complete = imx6_media_probe_complete,
 };
 
 static int imx_media_probe(struct platform_device *pdev)
@@ -85,6 +110,7 @@
 	v4l2_async_notifier_unregister(&imxmd->notifier);
 	imx_media_unregister_ipu_internal_subdevs(imxmd);
 	v4l2_async_notifier_cleanup(&imxmd->notifier);
+	imx_media_csc_scaler_device_unregister(imxmd->m2m_vdev);
 	media_device_unregister(&imxmd->md);
 	v4l2_device_unregister(&imxmd->v4l2_dev);
 	media_device_cleanup(&imxmd->md);
diff --git a/drivers/staging/media/imx/imx-media-internal-sd.c b/drivers/staging/media/imx/imx-media-internal-sd.c
index cb1e4cd..d4237e1 100644
--- a/drivers/staging/media/imx/imx-media-internal-sd.c
+++ b/drivers/staging/media/imx/imx-media-internal-sd.c
@@ -210,6 +210,10 @@
 
 	mutex_lock(&imxmd->mutex);
 
+	/* record this IPU */
+	if (!imxmd->ipu[ipu_id])
+		imxmd->ipu[ipu_id] = ipu;
+
 	/* register the synchronous subdevs */
 	for (i = 0; i < NUM_IPU_SUBDEVS; i++) {
 		intsd = &int_subdev[i];
diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c
index 9088c4b..4cc6a74 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -841,7 +841,7 @@
 		if (sd->grp_id & grp_id)
 			return &sd->entity;
 	} else if (buftype && is_media_entity_v4l2_video_device(start)) {
-		vfd = media_entity_to_video_device(pad->entity);
+		vfd = media_entity_to_video_device(start);
 		if (buftype == vfd->queue->type)
 			return &vfd->entity;
 	}
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index 4d124a8..1186119 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -136,9 +136,15 @@
 	/* master video device list */
 	struct list_head vdev_list;
 
+	/* IPUs this media driver control, valid after subdevs bound */
+	struct ipu_soc *ipu[2];
+
 	/* for async subdev registration */
 	struct v4l2_async_notifier notifier;
 
+	/* IC scaler/CSC mem2mem video device */
+	struct imx_media_video_dev *m2m_vdev;
+
 	/* the IPU internal subdev's registered synchronously */
 	struct v4l2_subdev *sync_sd[2][NUM_IPU_SUBDEVS];
 };
@@ -269,6 +275,12 @@
 imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev);
 void imx_media_capture_device_error(struct imx_media_video_dev *vdev);
 
+/* imx-media-csc-scaler.c */
+struct imx_media_video_dev *
+imx_media_csc_scaler_device_init(struct imx_media_dev *dev);
+int imx_media_csc_scaler_device_register(struct imx_media_video_dev *vdev);
+void imx_media_csc_scaler_device_unregister(struct imx_media_video_dev *vdev);
+
 /* subdev group ids */
 #define IMX_MEDIA_GRP_ID_CSI2          BIT(8)
 #define IMX_MEDIA_GRP_ID_CSI           BIT(9)
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index f29e28d..bfa4b25 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -243,7 +243,7 @@
 }
 
 /* Waits for low-power LP-11 state on data and clock lanes. */
-static int csi2_dphy_wait_stopstate(struct csi2_dev *csi2)
+static void csi2_dphy_wait_stopstate(struct csi2_dev *csi2)
 {
 	u32 mask, reg;
 	int ret;
@@ -254,11 +254,9 @@
 	ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
 				 (reg & mask) == mask, 0, 500000);
 	if (ret) {
-		v4l2_err(&csi2->sd, "LP-11 timeout, phy_state = 0x%08x\n", reg);
-		return ret;
+		v4l2_warn(&csi2->sd, "LP-11 wait timeout, likely a sensor driver bug, expect capture failures.\n");
+		v4l2_warn(&csi2->sd, "phy_state = 0x%08x\n", reg);
 	}
-
-	return 0;
 }
 
 /* Wait for active clock on the clock lane. */
@@ -316,9 +314,7 @@
 	csi2_enable(csi2, true);
 
 	/* Step 5 */
-	ret = csi2_dphy_wait_stopstate(csi2);
-	if (ret)
-		goto err_assert_reset;
+	csi2_dphy_wait_stopstate(csi2);
 
 	/* Step 6 */
 	ret = v4l2_subdev_call(csi2->src_sd, video, s_stream, 1);
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index 500b4c0..4ca79ff 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * V4L2 Capture CSI Subdev for Freescale i.MX7 SOC
+ * V4L2 Capture CSI Subdev for Freescale i.MX6UL/L / i.MX7 SOC
  *
  * Copyright (c) 2019 Linaro Ltd
  *
@@ -765,6 +765,7 @@
 	struct v4l2_pix_format *out_pix = &vdev->fmt.fmt.pix;
 	__u32 in_code = csi->format_mbus[IMX7_CSI_PAD_SINK].code;
 	u32 cr1, cr18;
+	int width = out_pix->width;
 
 	if (out_pix->field == V4L2_FIELD_INTERLACED) {
 		imx7_csi_deinterlace_enable(csi, true);
@@ -774,15 +775,27 @@
 		imx7_csi_buf_stride_set(csi, 0);
 	}
 
-	imx7_csi_set_imagpara(csi, out_pix->width, out_pix->height);
+	cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
 
-	if (!csi->is_csi2)
+	if (!csi->is_csi2) {
+		if (out_pix->pixelformat == V4L2_PIX_FMT_UYVY ||
+		    out_pix->pixelformat == V4L2_PIX_FMT_YUYV)
+			width *= 2;
+
+		imx7_csi_set_imagpara(csi, width, out_pix->height);
+
+		cr18 |= (BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL |
+			BIT_BASEADDR_CHG_ERR_EN);
+		imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
+
 		return 0;
+	}
+
+	imx7_csi_set_imagpara(csi, width, out_pix->height);
 
 	cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
 	cr1 &= ~BIT_GCLK_MODE;
 
-	cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
 	cr18 &= BIT_MIPI_DATA_FORMAT_MASK;
 	cr18 |= BIT_DATA_FROM_MIPI;
 
@@ -817,11 +830,9 @@
 {
 	imx7_csi_sw_reset(csi);
 
-	if (csi->is_csi2) {
-		imx7_csi_dmareq_rff_enable(csi);
-		imx7_csi_hw_enable_irq(csi);
-		imx7_csi_hw_enable(csi);
-	}
+	imx7_csi_dmareq_rff_enable(csi);
+	imx7_csi_hw_enable_irq(csi);
+	imx7_csi_hw_enable(csi);
 }
 
 static void imx7_csi_disable(struct imx7_csi *csi)
@@ -1302,6 +1313,7 @@
 
 static const struct of_device_id imx7_csi_of_match[] = {
 	{ .compatible = "fsl,imx7-csi" },
+	{ .compatible = "fsl,imx6ul-csi" },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, imx7_csi_of_match);
diff --git a/drivers/staging/media/ipu3/ipu3-tables.h b/drivers/staging/media/ipu3/ipu3-tables.h
index a1bf328..9f719c4 100644
--- a/drivers/staging/media/ipu3/ipu3-tables.h
+++ b/drivers/staging/media/ipu3/ipu3-tables.h
@@ -4,6 +4,8 @@
 #ifndef __IPU3_TABLES_H
 #define __IPU3_TABLES_H
 
+#include <linux/bitops.h>
+
 #include "ipu3-abi.h"
 
 #define IMGU_BDS_GRANULARITY		32	/* Downscaling granularity */
@@ -12,7 +14,7 @@
 
 #define IMGU_SCALER_DOWNSCALE_4TAPS_LEN	128
 #define IMGU_SCALER_DOWNSCALE_2TAPS_LEN	64
-#define IMGU_SCALER_FP			((u32)1 << 31) /* 1.0 in fixed point */
+#define IMGU_SCALER_FP			BIT(31) /* 1.0 in fixed point */
 
 #define IMGU_XNR3_VMEM_LUT_LEN		16
 
diff --git a/drivers/staging/media/ipu3/ipu3.c b/drivers/staging/media/ipu3/ipu3.c
index a737239..06a61f3 100644
--- a/drivers/staging/media/ipu3/ipu3.c
+++ b/drivers/staging/media/ipu3/ipu3.c
@@ -778,8 +778,7 @@
 
 static int __maybe_unused imgu_resume(struct device *dev)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct imgu_device *imgu = pci_get_drvdata(pci_dev);
+	struct imgu_device *imgu = dev_get_drvdata(dev);
 	int r = 0;
 	unsigned int pipe;
 
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index c307707..54144dc 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -31,61 +31,61 @@
 static struct iss_format_info formats[] = {
 	{ MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8,
 	  MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_Y8_1X8,
-	  V4L2_PIX_FMT_GREY, 8, "Greyscale 8 bpp", },
+	  V4L2_PIX_FMT_GREY, 8, },
 	{ MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y10_1X10,
 	  MEDIA_BUS_FMT_Y10_1X10, MEDIA_BUS_FMT_Y8_1X8,
-	  V4L2_PIX_FMT_Y10, 10, "Greyscale 10 bpp", },
+	  V4L2_PIX_FMT_Y10, 10, },
 	{ MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y10_1X10,
 	  MEDIA_BUS_FMT_Y12_1X12, MEDIA_BUS_FMT_Y8_1X8,
-	  V4L2_PIX_FMT_Y12, 12, "Greyscale 12 bpp", },
+	  V4L2_PIX_FMT_Y12, 12, },
 	{ MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SBGGR8_1X8,
 	  MEDIA_BUS_FMT_SBGGR8_1X8, MEDIA_BUS_FMT_SBGGR8_1X8,
-	  V4L2_PIX_FMT_SBGGR8, 8, "BGGR Bayer 8 bpp", },
+	  V4L2_PIX_FMT_SBGGR8, 8, },
 	{ MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8,
 	  MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGBRG8_1X8,
-	  V4L2_PIX_FMT_SGBRG8, 8, "GBRG Bayer 8 bpp", },
+	  V4L2_PIX_FMT_SGBRG8, 8, },
 	{ MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8,
 	  MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8,
-	  V4L2_PIX_FMT_SGRBG8, 8, "GRBG Bayer 8 bpp", },
+	  V4L2_PIX_FMT_SGRBG8, 8, },
 	{ MEDIA_BUS_FMT_SRGGB8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8,
 	  MEDIA_BUS_FMT_SRGGB8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8,
-	  V4L2_PIX_FMT_SRGGB8, 8, "RGGB Bayer 8 bpp", },
+	  V4L2_PIX_FMT_SRGGB8, 8, },
 	{ MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
 	  MEDIA_BUS_FMT_SGRBG10_1X10, 0,
-	  V4L2_PIX_FMT_SGRBG10DPCM8, 8, "GRBG Bayer 10 bpp DPCM8",  },
+	  V4L2_PIX_FMT_SGRBG10DPCM8, 8, },
 	{ MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10,
 	  MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR8_1X8,
-	  V4L2_PIX_FMT_SBGGR10, 10, "BGGR Bayer 10 bpp", },
+	  V4L2_PIX_FMT_SBGGR10, 10, },
 	{ MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10,
 	  MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG8_1X8,
-	  V4L2_PIX_FMT_SGBRG10, 10, "GBRG Bayer 10 bpp", },
+	  V4L2_PIX_FMT_SGBRG10, 10, },
 	{ MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10,
 	  MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG8_1X8,
-	  V4L2_PIX_FMT_SGRBG10, 10, "GRBG Bayer 10 bpp", },
+	  V4L2_PIX_FMT_SGRBG10, 10, },
 	{ MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10,
 	  MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB8_1X8,
-	  V4L2_PIX_FMT_SRGGB10, 10, "RGGB Bayer 10 bpp", },
+	  V4L2_PIX_FMT_SRGGB10, 10, },
 	{ MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SBGGR10_1X10,
 	  MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SBGGR8_1X8,
-	  V4L2_PIX_FMT_SBGGR12, 12, "BGGR Bayer 12 bpp", },
+	  V4L2_PIX_FMT_SBGGR12, 12, },
 	{ MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGBRG10_1X10,
 	  MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGBRG8_1X8,
-	  V4L2_PIX_FMT_SGBRG12, 12, "GBRG Bayer 12 bpp", },
+	  V4L2_PIX_FMT_SGBRG12, 12, },
 	{ MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SGRBG10_1X10,
 	  MEDIA_BUS_FMT_SGRBG12_1X12, MEDIA_BUS_FMT_SGRBG8_1X8,
-	  V4L2_PIX_FMT_SGRBG12, 12, "GRBG Bayer 12 bpp", },
+	  V4L2_PIX_FMT_SGRBG12, 12, },
 	{ MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB10_1X10,
 	  MEDIA_BUS_FMT_SRGGB12_1X12, MEDIA_BUS_FMT_SRGGB8_1X8,
-	  V4L2_PIX_FMT_SRGGB12, 12, "RGGB Bayer 12 bpp", },
+	  V4L2_PIX_FMT_SRGGB12, 12, },
 	{ MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_UYVY8_1X16,
 	  MEDIA_BUS_FMT_UYVY8_1X16, 0,
-	  V4L2_PIX_FMT_UYVY, 16, "YUV 4:2:2 (UYVY)", },
+	  V4L2_PIX_FMT_UYVY, 16, },
 	{ MEDIA_BUS_FMT_YUYV8_1X16, MEDIA_BUS_FMT_YUYV8_1X16,
 	  MEDIA_BUS_FMT_YUYV8_1X16, 0,
-	  V4L2_PIX_FMT_YUYV, 16, "YUV 4:2:2 (YUYV)", },
+	  V4L2_PIX_FMT_YUYV, 16, },
 	{ MEDIA_BUS_FMT_YUYV8_1_5X8, MEDIA_BUS_FMT_YUYV8_1_5X8,
 	  MEDIA_BUS_FMT_YUYV8_1_5X8, 0,
-	  V4L2_PIX_FMT_NV12, 8, "YUV 4:2:0 (NV12)", },
+	  V4L2_PIX_FMT_NV12, 8, },
 };
 
 const struct iss_format_info *
@@ -563,8 +563,6 @@
 
 		if (index == 0) {
 			f->pixelformat = info->pixelformat;
-			strscpy(f->description, info->description,
-				sizeof(f->description));
 			return 0;
 		}
 
diff --git a/drivers/staging/media/omap4iss/iss_video.h b/drivers/staging/media/omap4iss/iss_video.h
index f22489e..8b3dd92 100644
--- a/drivers/staging/media/omap4iss/iss_video.h
+++ b/drivers/staging/media/omap4iss/iss_video.h
@@ -36,7 +36,6 @@
  *	shifted to be 8 bits per pixel. =0 if format is not shiftable.
  * @pixelformat: V4L2 pixel format FCC identifier
  * @bpp: Bits per pixel
- * @description: Human-readable format description
  */
 struct iss_format_info {
 	u32 code;
@@ -45,7 +44,6 @@
 	u32 flavor;
 	u32 pixelformat;
 	unsigned int bpp;
-	const char *description;
 };
 
 enum iss_pipeline_stream_state {
diff --git a/drivers/staging/media/soc_camera/soc_camera.c b/drivers/staging/media/soc_camera/soc_camera.c
index a6232dc..7b9448e 100644
--- a/drivers/staging/media/soc_camera/soc_camera.c
+++ b/drivers/staging/media/soc_camera/soc_camera.c
@@ -869,8 +869,6 @@
 
 	format = icd->user_formats[f->index].host_fmt;
 
-	if (format->name)
-		strscpy(f->description, format->name, sizeof(f->description));
 	f->pixelformat = format->fourcc;
 	return 0;
 }
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
index 370937e..2d3ea8b 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
@@ -29,47 +29,72 @@
 
 static const struct cedrus_control cedrus_controls[] = {
 	{
-		.id		= V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
-		.elem_size	= sizeof(struct v4l2_ctrl_mpeg2_slice_params),
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS,
+		},
 		.codec		= CEDRUS_CODEC_MPEG2,
 		.required	= true,
 	},
 	{
-		.id		= V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
-		.elem_size	= sizeof(struct v4l2_ctrl_mpeg2_quantization),
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION,
+		},
 		.codec		= CEDRUS_CODEC_MPEG2,
 		.required	= false,
 	},
 	{
-		.id		= V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
-		.elem_size	= sizeof(struct v4l2_ctrl_h264_decode_params),
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
+		},
 		.codec		= CEDRUS_CODEC_H264,
 		.required	= true,
 	},
 	{
-		.id		= V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
-		.elem_size	= sizeof(struct v4l2_ctrl_h264_slice_params),
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
+		},
 		.codec		= CEDRUS_CODEC_H264,
 		.required	= true,
 	},
 	{
-		.id		= V4L2_CID_MPEG_VIDEO_H264_SPS,
-		.elem_size	= sizeof(struct v4l2_ctrl_h264_sps),
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_H264_SPS,
+		},
 		.codec		= CEDRUS_CODEC_H264,
 		.required	= true,
 	},
 	{
-		.id		= V4L2_CID_MPEG_VIDEO_H264_PPS,
-		.elem_size	= sizeof(struct v4l2_ctrl_h264_pps),
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_H264_PPS,
+		},
 		.codec		= CEDRUS_CODEC_H264,
 		.required	= true,
 	},
 	{
-		.id		= V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
-		.elem_size	= sizeof(struct v4l2_ctrl_h264_scaling_matrix),
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
+		},
 		.codec		= CEDRUS_CODEC_H264,
 		.required	= true,
 	},
+	{
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE,
+			.max	= V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED,
+			.def	= V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED,
+		},
+		.codec		= CEDRUS_CODEC_H264,
+		.required	= false,
+	},
+	{
+		.cfg = {
+			.id	= V4L2_CID_MPEG_VIDEO_H264_START_CODE,
+			.max	= V4L2_MPEG_VIDEO_H264_START_CODE_NONE,
+			.def	= V4L2_MPEG_VIDEO_H264_START_CODE_NONE,
+		},
+		.codec		= CEDRUS_CODEC_H264,
+		.required	= false,
+	},
 };
 
 #define CEDRUS_CONTROLS_COUNT	ARRAY_SIZE(cedrus_controls)
@@ -106,12 +131,8 @@
 		return -ENOMEM;
 
 	for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) {
-		struct v4l2_ctrl_config cfg = {};
-
-		cfg.elem_size = cedrus_controls[i].elem_size;
-		cfg.id = cedrus_controls[i].id;
-
-		ctrl = v4l2_ctrl_new_custom(hdl, &cfg, NULL);
+		ctrl = v4l2_ctrl_new_custom(hdl, &cedrus_controls[i].cfg,
+					    NULL);
 		if (hdl->error) {
 			v4l2_err(&dev->v4l2_dev,
 				 "Failed to create new custom control\n");
@@ -178,7 +199,7 @@
 			continue;
 
 		ctrl_test = v4l2_ctrl_request_hdl_ctrl_find(hdl,
-							    cedrus_controls[i].id);
+							    cedrus_controls[i].cfg.id);
 		if (!ctrl_test) {
 			v4l2_info(&ctx->dev->v4l2_dev,
 				  "Missing required codec control\n");
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
index 3f476d0..2f017a6 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
@@ -49,8 +49,7 @@
 };
 
 struct cedrus_control {
-	u32			id;
-	u32			elem_size;
+	struct v4l2_ctrl_config cfg;
 	enum cedrus_codec	codec;
 	unsigned char		required:1;
 };
@@ -100,8 +99,6 @@
 	struct v4l2_ctrl_handler	hdl;
 	struct v4l2_ctrl		**ctrls;
 
-	struct vb2_buffer		*dst_bufs[VIDEO_MAX_FRAME];
-
 	union {
 		struct {
 			void		*mv_col_buf;
@@ -187,7 +184,7 @@
 	if (index < 0)
 		return 0;
 
-	buf = ctx->dst_bufs[index];
+	buf = ctx->fh.m2m_ctx->cap_q_ctx.q.bufs[index];
 	return buf ? cedrus_buf_addr(buf, &ctx->dst_fmt, plane) : 0;
 }
 
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
index bdad87e..56ca4c9 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
@@ -46,7 +46,7 @@
 			V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
 		break;
 
-	case V4L2_PIX_FMT_H264_SLICE_RAW:
+	case V4L2_PIX_FMT_H264_SLICE:
 		run.h264.decode_params = cedrus_find_control_data(ctx,
 			V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
 		run.h264.pps = cedrus_find_control_data(ctx,
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
index a30bb28..d6a7827 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
@@ -118,7 +118,7 @@
 		if (buf_idx < 0)
 			continue;
 
-		cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[buf_idx]);
+		cedrus_buf = vb2_to_cedrus_buffer(cap_q->bufs[buf_idx]);
 		position = cedrus_buf->codec.h264.position;
 		used_dpbs |= BIT(position);
 
@@ -193,7 +193,7 @@
 		if (buf_idx < 0)
 			continue;
 
-		ref_buf = to_vb2_v4l2_buffer(ctx->dst_bufs[buf_idx]);
+		ref_buf = to_vb2_v4l2_buffer(cap_q->bufs[buf_idx]);
 		cedrus_buf = vb2_v4l2_to_cedrus_buffer(ref_buf);
 		position = cedrus_buf->codec.h264.position;
 
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
index c34aec7..fc8579b 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
@@ -79,9 +79,6 @@
 		reg = VE_PRIMARY_OUT_FMT_NV12;
 		cedrus_write(dev, VE_PRIMARY_OUT_FMT, reg);
 
-		reg = VE_CHROMA_BUF_LEN_SDRT(chroma_size / 2);
-		cedrus_write(dev, VE_CHROMA_BUF_LEN, reg);
-
 		reg = chroma_size / 2;
 		cedrus_write(dev, VE_PRIMARY_CHROMA_BUF_LEN, reg);
 
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
index 3e99314..ddd2978 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
@@ -110,7 +110,7 @@
 #define VE_DEC_MPEG_MBADDR			(VE_ENGINE_DEC_MPEG + 0x10)
 
 #define VE_DEC_MPEG_MBADDR_X(w)			(((w) << 8) & GENMASK(15, 8))
-#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(0, 7))
+#define VE_DEC_MPEG_MBADDR_Y(h)			(((h) << 0) & GENMASK(7, 0))
 
 #define VE_DEC_MPEG_CTRL			(VE_ENGINE_DEC_MPEG + 0x14)
 
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
index e2b530b..eeee3ef 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
@@ -38,7 +38,7 @@
 		.directions	= CEDRUS_DECODE_SRC,
 	},
 	{
-		.pixelformat	= V4L2_PIX_FMT_H264_SLICE_RAW,
+		.pixelformat	= V4L2_PIX_FMT_H264_SLICE,
 		.directions	= CEDRUS_DECODE_SRC,
 	},
 	{
@@ -104,7 +104,7 @@
 
 	switch (pix_fmt->pixelformat) {
 	case V4L2_PIX_FMT_MPEG2_SLICE:
-	case V4L2_PIX_FMT_H264_SLICE_RAW:
+	case V4L2_PIX_FMT_H264_SLICE:
 		/* Zero bytes per line for encoded source. */
 		bytesperline = 0;
 
@@ -411,26 +411,6 @@
 	}
 }
 
-static int cedrus_buf_init(struct vb2_buffer *vb)
-{
-	struct vb2_queue *vq = vb->vb2_queue;
-	struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
-
-	if (!V4L2_TYPE_IS_OUTPUT(vq->type))
-		ctx->dst_bufs[vb->index] = vb;
-
-	return 0;
-}
-
-static void cedrus_buf_cleanup(struct vb2_buffer *vb)
-{
-	struct vb2_queue *vq = vb->vb2_queue;
-	struct cedrus_ctx *ctx = vb2_get_drv_priv(vq);
-
-	if (!V4L2_TYPE_IS_OUTPUT(vq->type))
-		ctx->dst_bufs[vb->index] = NULL;
-}
-
 static int cedrus_buf_out_validate(struct vb2_buffer *vb)
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
@@ -469,7 +449,7 @@
 		ctx->current_codec = CEDRUS_CODEC_MPEG2;
 		break;
 
-	case V4L2_PIX_FMT_H264_SLICE_RAW:
+	case V4L2_PIX_FMT_H264_SLICE:
 		ctx->current_codec = CEDRUS_CODEC_H264;
 		break;
 
@@ -517,8 +497,6 @@
 static struct vb2_ops cedrus_qops = {
 	.queue_setup		= cedrus_queue_setup,
 	.buf_prepare		= cedrus_buf_prepare,
-	.buf_init		= cedrus_buf_init,
-	.buf_cleanup		= cedrus_buf_cleanup,
 	.buf_queue		= cedrus_buf_queue,
 	.buf_out_validate	= cedrus_buf_out_validate,
 	.buf_request_complete	= cedrus_buf_request_complete,
diff --git a/drivers/staging/media/tegra-vde/Kconfig b/drivers/staging/media/tegra-vde/Kconfig
index 2e7f644..ba49ea5 100644
--- a/drivers/staging/media/tegra-vde/Kconfig
+++ b/drivers/staging/media/tegra-vde/Kconfig
@@ -3,7 +3,7 @@
 	tristate "NVIDIA Tegra Video Decoder Engine driver"
 	depends on ARCH_TEGRA || COMPILE_TEST
 	select DMA_SHARED_BUFFER
-	select IOMMU_IOVA if IOMMU_SUPPORT
+	select IOMMU_IOVA if (IOMMU_SUPPORT || COMPILE_TEST)
 	select SRAM
 	help
 	    Say Y here to enable support for the NVIDIA Tegra video decoder
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index ea54cc2..d4d1e44 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -75,34 +75,27 @@
 /* video formats */
 static struct mmal_fmt formats[] = {
 	{
-		.name = "4:2:0, planar, YUV",
 		.fourcc = V4L2_PIX_FMT_YUV420,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_I420,
 		.depth = 12,
 		.mmal_component = COMP_CAMERA,
 		.ybbp = 1,
 		.remove_padding = 1,
 	}, {
-		.name = "4:2:2, packed, YUYV",
 		.fourcc = V4L2_PIX_FMT_YUYV,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_YUYV,
 		.depth = 16,
 		.mmal_component = COMP_CAMERA,
 		.ybbp = 2,
 		.remove_padding = 0,
 	}, {
-		.name = "RGB24 (LE)",
 		.fourcc = V4L2_PIX_FMT_RGB24,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_RGB24,
 		.depth = 24,
 		.mmal_component = COMP_CAMERA,
 		.ybbp = 3,
 		.remove_padding = 0,
 	}, {
-		.name = "JPEG",
 		.fourcc = V4L2_PIX_FMT_JPEG,
 		.flags = V4L2_FMT_FLAG_COMPRESSED,
 		.mmal = MMAL_ENCODING_JPEG,
@@ -111,7 +104,6 @@
 		.ybbp = 0,
 		.remove_padding = 0,
 	}, {
-		.name = "H264",
 		.fourcc = V4L2_PIX_FMT_H264,
 		.flags = V4L2_FMT_FLAG_COMPRESSED,
 		.mmal = MMAL_ENCODING_H264,
@@ -120,7 +112,6 @@
 		.ybbp = 0,
 		.remove_padding = 0,
 	}, {
-		.name = "MJPEG",
 		.fourcc = V4L2_PIX_FMT_MJPEG,
 		.flags = V4L2_FMT_FLAG_COMPRESSED,
 		.mmal = MMAL_ENCODING_MJPEG,
@@ -129,72 +120,56 @@
 		.ybbp = 0,
 		.remove_padding = 0,
 	}, {
-		.name = "4:2:2, packed, YVYU",
 		.fourcc = V4L2_PIX_FMT_YVYU,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_YVYU,
 		.depth = 16,
 		.mmal_component = COMP_CAMERA,
 		.ybbp = 2,
 		.remove_padding = 0,
 	}, {
-		.name = "4:2:2, packed, VYUY",
 		.fourcc = V4L2_PIX_FMT_VYUY,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_VYUY,
 		.depth = 16,
 		.mmal_component = COMP_CAMERA,
 		.ybbp = 2,
 		.remove_padding = 0,
 	}, {
-		.name = "4:2:2, packed, UYVY",
 		.fourcc = V4L2_PIX_FMT_UYVY,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_UYVY,
 		.depth = 16,
 		.mmal_component = COMP_CAMERA,
 		.ybbp = 2,
 		.remove_padding = 0,
 	}, {
-		.name = "4:2:0, planar, NV12",
 		.fourcc = V4L2_PIX_FMT_NV12,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_NV12,
 		.depth = 12,
 		.mmal_component = COMP_CAMERA,
 		.ybbp = 1,
 		.remove_padding = 1,
 	}, {
-		.name = "RGB24 (BE)",
 		.fourcc = V4L2_PIX_FMT_BGR24,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_BGR24,
 		.depth = 24,
 		.mmal_component = COMP_CAMERA,
 		.ybbp = 3,
 		.remove_padding = 0,
 	}, {
-		.name = "4:2:0, planar, YVU",
 		.fourcc = V4L2_PIX_FMT_YVU420,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_YV12,
 		.depth = 12,
 		.mmal_component = COMP_CAMERA,
 		.ybbp = 1,
 		.remove_padding = 1,
 	}, {
-		.name = "4:2:0, planar, NV21",
 		.fourcc = V4L2_PIX_FMT_NV21,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_NV21,
 		.depth = 12,
 		.mmal_component = COMP_CAMERA,
 		.ybbp = 1,
 		.remove_padding = 1,
 	}, {
-		.name = "RGB32 (BE)",
 		.fourcc = V4L2_PIX_FMT_BGR32,
-		.flags = 0,
 		.mmal = MMAL_ENCODING_BGRA,
 		.depth = 32,
 		.mmal_component = COMP_CAMERA,
@@ -716,9 +691,7 @@
 
 	fmt = &formats[f->index];
 
-	strlcpy((char *)f->description, fmt->name, sizeof(f->description));
 	f->pixelformat = fmt->fourcc;
-	f->flags = fmt->flags;
 
 	return 0;
 }
@@ -919,9 +892,7 @@
 
 	fmt = &formats[f->index];
 
-	strlcpy((char *)f->description, fmt->name, sizeof(f->description));
 	f->pixelformat = fmt->fourcc;
-	f->flags = fmt->flags;
 
 	return 0;
 }
diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h
index 6f56c51..ff53987 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h
+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h
@@ -26,7 +26,6 @@
 
 /* mapping between v4l and mmal video modes */
 struct mmal_fmt {
-	char  *name;
 	u32   fourcc;          /* v4l2 format id */
 	int   flags;           /* v4l2 flags field */
 	u32   mmal;
diff --git a/include/linux/sort.h b/include/linux/sort.h
index 2b99a5d..61b96d0 100644
--- a/include/linux/sort.h
+++ b/include/linux/sort.h
@@ -4,6 +4,11 @@
 
 #include <linux/types.h>
 
+void sort_r(void *base, size_t num, size_t size,
+	    int (*cmp)(const void *, const void *, const void *),
+	    void (*swap)(void *, void *, int),
+	    const void *priv);
+
 void sort(void *base, size_t num, size_t size,
 	  int (*cmp)(const void *, const void *),
 	  void (*swap)(void *, void *, int));
diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h
index 2c5b3ea..4ad5303 100644
--- a/include/media/davinci/vpfe_capture.h
+++ b/include/media/davinci/vpfe_capture.h
@@ -32,7 +32,7 @@
 #define CAPTURE_DRV_NAME		"vpfe-capture"
 
 struct vpfe_pixel_format {
-	struct v4l2_fmtdesc fmtdesc;
+	u32 pixelformat;
 	/* bytes per pixel */
 	int bpp;
 };
diff --git a/include/media/drv-intf/exynos-fimc.h b/include/media/drv-intf/exynos-fimc.h
index 5970343..6b9ef63 100644
--- a/include/media/drv-intf/exynos-fimc.h
+++ b/include/media/drv-intf/exynos-fimc.h
@@ -87,7 +87,6 @@
 /**
  * struct fimc_fmt - color format data structure
  * @mbus_code: media bus pixel code, -1 if not applicable
- * @name: format description
  * @fourcc: fourcc code for this format, 0 if not applicable
  * @color: the driver's private color format id
  * @memplanes: number of physically non-contiguous data planes
@@ -99,7 +98,6 @@
  */
 struct fimc_fmt {
 	u32 mbus_code;
-	char	*name;
 	u32	fourcc;
 	u32	color;
 	u16	memplanes;
diff --git a/include/media/drv-intf/saa7146_vv.h b/include/media/drv-intf/saa7146_vv.h
index b34d86b..635805f 100644
--- a/include/media/drv-intf/saa7146_vv.h
+++ b/include/media/drv-intf/saa7146_vv.h
@@ -32,7 +32,6 @@
 #define FORMAT_IS_PLANAR	0x2
 
 struct saa7146_format {
-	char	*name;
 	u32	pixelformat;
 	u32	trans;
 	u8	depth;
diff --git a/include/media/drv-intf/soc_mediabus.h b/include/media/drv-intf/soc_mediabus.h
index 73de3bd..361f885 100644
--- a/include/media/drv-intf/soc_mediabus.h
+++ b/include/media/drv-intf/soc_mediabus.h
@@ -66,7 +66,6 @@
 
 /**
  * struct soc_mbus_pixelfmt - Data format on the media bus
- * @name:		Name of the format
  * @fourcc:		Fourcc code, that will be obtained if the data is
  *			stored in memory in the following way:
  * @packing:		Type of sample-packing, that has to be used
@@ -74,7 +73,6 @@
  * @bits_per_sample:	How many bits the bridge has to sample
  */
 struct soc_mbus_pixelfmt {
-	const char		*name;
 	u32			fourcc;
 	enum soc_mbus_packing	packing;
 	enum soc_mbus_order	order;
diff --git a/include/media/dvb-usb-ids.h b/include/media/dvb-usb-ids.h
index 52875e3..7ce4e83 100644
--- a/include/media/dvb-usb-ids.h
+++ b/include/media/dvb-usb-ids.h
@@ -388,6 +388,7 @@
 #define USB_PID_MYGICA_D689				0xd811
 #define USB_PID_MYGICA_T230				0xc688
 #define USB_PID_MYGICA_T230C				0xc689
+#define USB_PID_MYGICA_T230C2				0xc68a
 #define USB_PID_ELGATO_EYETV_DIVERSITY			0x0011
 #define USB_PID_ELGATO_EYETV_DTT			0x0021
 #define USB_PID_ELGATO_EYETV_DTT_2			0x003f
diff --git a/include/media/dvb_frontend.h b/include/media/dvb_frontend.h
index f05cd7b..0d76fa4 100644
--- a/include/media/dvb_frontend.h
+++ b/include/media/dvb_frontend.h
@@ -41,6 +41,7 @@
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/bitops.h>
 
 #include <linux/dvb/frontend.h>
 
@@ -141,10 +142,10 @@
  *	These devices have AUTO recovery capabilities from LOCK failure
  */
 enum dvbfe_algo {
-	DVBFE_ALGO_HW			= (1 <<  0),
-	DVBFE_ALGO_SW			= (1 <<  1),
-	DVBFE_ALGO_CUSTOM		= (1 <<  2),
-	DVBFE_ALGO_RECOVERY		= (1 << 31)
+	DVBFE_ALGO_HW			= BIT(0),
+	DVBFE_ALGO_SW			= BIT(1),
+	DVBFE_ALGO_CUSTOM		= BIT(2),
+	DVBFE_ALGO_RECOVERY		= BIT(31),
 };
 
 /**
@@ -170,12 +171,12 @@
  *	The frontend search algorithm was requested to search again
  */
 enum dvbfe_search {
-	DVBFE_ALGO_SEARCH_SUCCESS	= (1 <<  0),
-	DVBFE_ALGO_SEARCH_ASLEEP	= (1 <<  1),
-	DVBFE_ALGO_SEARCH_FAILED	= (1 <<  2),
-	DVBFE_ALGO_SEARCH_INVALID	= (1 <<  3),
-	DVBFE_ALGO_SEARCH_AGAIN		= (1 <<  4),
-	DVBFE_ALGO_SEARCH_ERROR		= (1 << 31),
+	DVBFE_ALGO_SEARCH_SUCCESS	= BIT(0),
+	DVBFE_ALGO_SEARCH_ASLEEP	= BIT(1),
+	DVBFE_ALGO_SEARCH_FAILED	= BIT(2),
+	DVBFE_ALGO_SEARCH_INVALID	= BIT(3),
+	DVBFE_ALGO_SEARCH_AGAIN		= BIT(4),
+	DVBFE_ALGO_SEARCH_ERROR		= BIT(31),
 };
 
 /**
diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
index e1404d7..e877bf1 100644
--- a/include/media/h264-ctrls.h
+++ b/include/media/h264-ctrls.h
@@ -14,7 +14,7 @@
 #include <linux/videodev2.h>
 
 /* Our pixel format isn't stable at the moment */
-#define V4L2_PIX_FMT_H264_SLICE_RAW v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
+#define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
 
 /*
  * This is put insanely high to avoid conflicting with controls that
@@ -26,6 +26,8 @@
 #define V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX	(V4L2_CID_MPEG_BASE+1002)
 #define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS	(V4L2_CID_MPEG_BASE+1003)
 #define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS	(V4L2_CID_MPEG_BASE+1004)
+#define V4L2_CID_MPEG_VIDEO_H264_DECODE_MODE	(V4L2_CID_MPEG_BASE+1005)
+#define V4L2_CID_MPEG_VIDEO_H264_START_CODE	(V4L2_CID_MPEG_BASE+1006)
 
 /* enum v4l2_ctrl_type type values */
 #define V4L2_CTRL_TYPE_H264_SPS			0x0110
@@ -34,6 +36,16 @@
 #define V4L2_CTRL_TYPE_H264_SLICE_PARAMS	0x0113
 #define V4L2_CTRL_TYPE_H264_DECODE_PARAMS	0x0114
 
+enum v4l2_mpeg_video_h264_decode_mode {
+	V4L2_MPEG_VIDEO_H264_DECODE_MODE_SLICE_BASED,
+	V4L2_MPEG_VIDEO_H264_DECODE_MODE_FRAME_BASED,
+};
+
+enum v4l2_mpeg_video_h264_start_code {
+	V4L2_MPEG_VIDEO_H264_START_CODE_NONE,
+	V4L2_MPEG_VIDEO_H264_START_CODE_ANNEX_B,
+};
+
 #define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG			0x01
 #define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG			0x02
 #define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG			0x04
@@ -125,6 +137,10 @@
 struct v4l2_ctrl_h264_slice_params {
 	/* Size in bytes, including header */
 	__u32 size;
+
+	/* Offset in bytes to the start of slice in the OUTPUT buffer. */
+	__u32 start_byte_offset;
+
 	/* Offset in bits to slice_data() from the beginning of this slice. */
 	__u32 header_bit_size;
 
@@ -186,9 +202,6 @@
 	struct v4l2_h264_dpb_entry dpb[16];
 	__u16 num_slices;
 	__u16 nal_ref_idc;
-	__u8 ref_pic_list_p0[32];
-	__u8 ref_pic_list_b0[32];
-	__u8 ref_pic_list_b1[32];
 	__s32 top_field_order_cnt;
 	__s32 bottom_field_order_cnt;
 	__u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index bebd3c4..afd2ab3 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -5,6 +5,9 @@
  * Copyright (c) 2010 by Mauro Carvalho Chehab
  */
 
+#ifndef _MEDIA_RC_MAP_H
+#define _MEDIA_RC_MAP_H
+
 #include <linux/input.h>
 #include <uapi/linux/lirc.h>
 
@@ -38,22 +41,6 @@
 #define RC_PROTO_BIT_RCMM32		BIT_ULL(RC_PROTO_RCMM32)
 #define RC_PROTO_BIT_XBOX_DVD		BIT_ULL(RC_PROTO_XBOX_DVD)
 
-#define RC_PROTO_BIT_ALL \
-			(RC_PROTO_BIT_UNKNOWN | RC_PROTO_BIT_OTHER | \
-			 RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \
-			 RC_PROTO_BIT_RC5_SZ | RC_PROTO_BIT_JVC | \
-			 RC_PROTO_BIT_SONY12 | RC_PROTO_BIT_SONY15 | \
-			 RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_NEC | \
-			 RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | \
-			 RC_PROTO_BIT_SANYO | \
-			 RC_PROTO_BIT_MCIR2_KBD | RC_PROTO_BIT_MCIR2_MSE | \
-			 RC_PROTO_BIT_RC6_0 | RC_PROTO_BIT_RC6_6A_20 | \
-			 RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | \
-			 RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SHARP | \
-			 RC_PROTO_BIT_XMP | RC_PROTO_BIT_CEC | \
-			 RC_PROTO_BIT_IMON | RC_PROTO_BIT_RCMM12 | \
-			 RC_PROTO_BIT_RCMM24 | RC_PROTO_BIT_RCMM32 | \
-			 RC_PROTO_BIT_XBOX_DVD)
 /* All rc protocols for which we have decoders */
 #define RC_PROTO_BIT_ALL_IR_DECODER \
 			(RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC5X_20 | \
@@ -224,6 +211,7 @@
 #define RC_MAP_IT913X_V1                 "rc-it913x-v1"
 #define RC_MAP_IT913X_V2                 "rc-it913x-v2"
 #define RC_MAP_KAIOMY                    "rc-kaiomy"
+#define RC_MAP_KHADAS                    "rc-khadas"
 #define RC_MAP_KWORLD_315U               "rc-kworld-315u"
 #define RC_MAP_KWORLD_PC150U             "rc-kworld-pc150u"
 #define RC_MAP_KWORLD_PLUS_TV_ANALOG     "rc-kworld-plus-tv-analog"
@@ -241,6 +229,7 @@
 #define RC_MAP_NEC_TERRATEC_CINERGY_XS   "rc-nec-terratec-cinergy-xs"
 #define RC_MAP_NORWOOD                   "rc-norwood"
 #define RC_MAP_NPGTECH                   "rc-npgtech"
+#define RC_MAP_ODROID                    "rc-odroid"
 #define RC_MAP_PCTV_SEDNA                "rc-pctv-sedna"
 #define RC_MAP_PINNACLE_COLOR            "rc-pinnacle-color"
 #define RC_MAP_PINNACLE_GREY             "rc-pinnacle-grey"
@@ -261,6 +250,8 @@
 #define RC_MAP_SNAPSTREAM_FIREFLY        "rc-snapstream-firefly"
 #define RC_MAP_STREAMZAP                 "rc-streamzap"
 #define RC_MAP_TANGO                     "rc-tango"
+#define RC_MAP_TANIX_TX3MINI             "rc-tanix-tx3mini"
+#define RC_MAP_TANIX_TX5MAX              "rc-tanix-tx5max"
 #define RC_MAP_TBS_NEC                   "rc-tbs-nec"
 #define RC_MAP_TECHNISAT_TS35            "rc-technisat-ts35"
 #define RC_MAP_TECHNISAT_USB2            "rc-technisat-usb2"
@@ -280,13 +271,18 @@
 #define RC_MAP_VIDEOMATE_K100            "rc-videomate-k100"
 #define RC_MAP_VIDEOMATE_S350            "rc-videomate-s350"
 #define RC_MAP_VIDEOMATE_TV_PVR          "rc-videomate-tv-pvr"
+#define RC_MAP_WETEK_HUB                 "rc-wetek-hub"
+#define RC_MAP_WETEK_PLAY2               "rc-wetek-play2"
 #define RC_MAP_WINFAST                   "rc-winfast"
 #define RC_MAP_WINFAST_USBII_DELUXE      "rc-winfast-usbii-deluxe"
 #define RC_MAP_SU3000                    "rc-su3000"
 #define RC_MAP_XBOX_DVD                  "rc-xbox-dvd"
+#define RC_MAP_X96MAX                    "rc-x96max"
 #define RC_MAP_ZX_IRDEC                  "rc-zx-irdec"
 
 /*
  * Please, do not just append newer Remote Controller names at the end.
  * The names should be ordered in alphabetical order
  */
+
+#endif /* _MEDIA_RC_MAP_H */
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 2e3d93f..8319284 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -172,8 +172,9 @@
  *		     the driver's async sub-device struct, i.e. both
  *		     begin at the same memory address.
  *
- * Allocate a fwnode-matched asd of size asd_struct_size, and add it
- * to the notifiers @asd_list.
+ * Allocate a fwnode-matched asd of size asd_struct_size, and add it to the
+ * notifiers @asd_list. The function also gets a reference of the fwnode which
+ * is released later at notifier cleanup time.
  */
 struct v4l2_async_subdev *
 v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
@@ -181,6 +182,31 @@
 				      unsigned int asd_struct_size);
 
 /**
+ * v4l2_async_notifier_add_fwnode_remote_subdev - Allocate and add a fwnode
+ *						  remote async subdev to the
+ *						  notifier's master asd_list.
+ *
+ * @notif: pointer to &struct v4l2_async_notifier
+ * @endpoint: local endpoint pointing to the remote sub-device to be matched
+ * @asd: Async sub-device struct allocated by the caller. The &struct
+ *	 v4l2_async_subdev shall be the first member of the driver's async
+ *	 sub-device struct, i.e. both begin at the same memory address.
+ *
+ * Gets the remote endpoint of a given local endpoint, set it up for fwnode
+ * matching and adds the async sub-device to the notifier's @asd_list. The
+ * function also gets a reference of the fwnode which is released later at
+ * notifier cleanup time.
+ *
+ * This is just like @v4l2_async_notifier_add_fwnode_subdev, but with the
+ * exception that the fwnode refers to a local endpoint, not the remote one, and
+ * the function relies on the caller to allocate the async sub-device struct.
+ */
+int
+v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif,
+					     struct fwnode_handle *endpoint,
+					     struct v4l2_async_subdev *asd);
+
+/**
  * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async
  *				subdev to the notifier's master asd_list.
  *
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 6b319d0..c070d8a 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -96,16 +96,45 @@
 
 /* ------------------------------------------------------------------------- */
 
-/* I2C Helper functions */
-
-struct i2c_driver;
-struct i2c_adapter;
-struct i2c_client;
-struct i2c_device_id;
 struct v4l2_device;
 struct v4l2_subdev;
 struct v4l2_subdev_ops;
 
+/* I2C Helper functions */
+#include <linux/i2c.h>
+
+/**
+ * enum v4l2_i2c_tuner_type - specifies the range of tuner address that
+ *	should be used when seeking for I2C devices.
+ *
+ * @ADDRS_RADIO:		Radio tuner addresses.
+ *				Represent the following I2C addresses:
+ *				0x10 (if compiled with tea5761 support)
+ *				and 0x60.
+ * @ADDRS_DEMOD:		Demod tuner addresses.
+ *				Represent the following I2C addresses:
+ *				0x42, 0x43, 0x4a and 0x4b.
+ * @ADDRS_TV:			TV tuner addresses.
+ *				Represent the following I2C addresses:
+ *				0x42, 0x43, 0x4a, 0x4b, 0x60, 0x61, 0x62,
+ *				0x63 and 0x64.
+ * @ADDRS_TV_WITH_DEMOD:	TV tuner addresses if demod is present, this
+ *				excludes addresses used by the demodulator
+ *				from the list of candidates.
+ *				Represent the following I2C addresses:
+ *				0x60, 0x61, 0x62, 0x63 and 0x64.
+ *
+ * NOTE: All I2C addresses above use the 7-bit notation.
+ */
+enum v4l2_i2c_tuner_type {
+	ADDRS_RADIO,
+	ADDRS_DEMOD,
+	ADDRS_TV,
+	ADDRS_TV_WITH_DEMOD,
+};
+
+#if defined(CONFIG_VIDEO_V4L2_I2C)
+
 /**
  * v4l2_i2c_new_subdev - Load an i2c module and return an initialized
  *	&struct v4l2_subdev.
@@ -123,8 +152,6 @@
 		struct i2c_adapter *adapter, const char *client_type,
 		u8 addr, const unsigned short *probe_addrs);
 
-struct i2c_board_info;
-
 /**
  * v4l2_i2c_new_subdev_board - Load an i2c module and return an initialized
  *	&struct v4l2_subdev.
@@ -175,35 +202,6 @@
 unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd);
 
 /**
- * enum v4l2_i2c_tuner_type - specifies the range of tuner address that
- *	should be used when seeking for I2C devices.
- *
- * @ADDRS_RADIO:		Radio tuner addresses.
- *				Represent the following I2C addresses:
- *				0x10 (if compiled with tea5761 support)
- *				and 0x60.
- * @ADDRS_DEMOD:		Demod tuner addresses.
- *				Represent the following I2C addresses:
- *				0x42, 0x43, 0x4a and 0x4b.
- * @ADDRS_TV:			TV tuner addresses.
- *				Represent the following I2C addresses:
- *				0x42, 0x43, 0x4a, 0x4b, 0x60, 0x61, 0x62,
- *				0x63 and 0x64.
- * @ADDRS_TV_WITH_DEMOD:	TV tuner addresses if demod is present, this
- *				excludes addresses used by the demodulator
- *				from the list of candidates.
- *				Represent the following I2C addresses:
- *				0x60, 0x61, 0x62, 0x63 and 0x64.
- *
- * NOTE: All I2C addresses above use the 7-bit notation.
- */
-enum v4l2_i2c_tuner_type {
-	ADDRS_RADIO,
-	ADDRS_DEMOD,
-	ADDRS_TV,
-	ADDRS_TV_WITH_DEMOD,
-};
-/**
  * v4l2_i2c_tuner_addrs - Return a list of I2C tuner addresses to probe.
  *
  * @type: type of the tuner to seek, as defined by
@@ -213,14 +211,64 @@
  */
 const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);
 
+/**
+ * v4l2_i2c_subdev_unregister - Unregister a v4l2_subdev
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
+void v4l2_i2c_subdev_unregister(struct v4l2_subdev *sd);
+
+#else
+
+static inline struct v4l2_subdev *
+v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
+		    struct i2c_adapter *adapter, const char *client_type,
+		    u8 addr, const unsigned short *probe_addrs)
+{
+	return NULL;
+}
+
+static inline struct v4l2_subdev *
+v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
+			  struct i2c_adapter *adapter, struct i2c_board_info *info,
+			  const unsigned short *probe_addrs)
+{
+	return NULL;
+}
+
+static inline void
+v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd, struct i2c_client *client,
+			 const char *devname, const char *postfix)
+{}
+
+static inline void
+v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
+		     const struct v4l2_subdev_ops *ops)
+{}
+
+static inline unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
+{
+	return I2C_CLIENT_END;
+}
+
+static inline const unsigned short *
+v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
+{
+	return NULL;
+}
+
+static inline void v4l2_i2c_subdev_unregister(struct v4l2_subdev *sd)
+{}
+
+#endif
+
 /* ------------------------------------------------------------------------- */
 
 /* SPI Helper functions */
-#if defined(CONFIG_SPI)
 
 #include <linux/spi/spi.h>
 
-struct spi_device;
+#if defined(CONFIG_SPI)
 
 /**
  *  v4l2_spi_new_subdev - Load an spi module and return an initialized
@@ -246,6 +294,30 @@
  */
 void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
 		const struct v4l2_subdev_ops *ops);
+
+/**
+ * v4l2_spi_subdev_unregister - Unregister a v4l2_subdev
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
+void v4l2_spi_subdev_unregister(struct v4l2_subdev *sd);
+
+#else
+
+static inline struct v4l2_subdev *
+v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
+		    struct spi_master *master, struct spi_board_info *info)
+{
+	return NULL;
+}
+
+static inline void
+v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
+		     const struct v4l2_subdev_ops *ops)
+{}
+
+static inline void v4l2_spi_subdev_unregister(struct v4l2_subdev *sd)
+{}
 #endif
 
 /* ------------------------------------------------------------------------- */
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index b443348..570ff4b 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -20,6 +20,7 @@
 #include <media/mpeg2-ctrls.h>
 #include <media/fwht-ctrls.h>
 #include <media/h264-ctrls.h>
+#include <media/vp8-ctrls.h>
 
 /* forward references */
 struct file;
@@ -48,6 +49,7 @@
  * @p_h264_scaling_matrix:	Pointer to a struct v4l2_ctrl_h264_scaling_matrix.
  * @p_h264_slice_params:	Pointer to a struct v4l2_ctrl_h264_slice_params.
  * @p_h264_decode_params:	Pointer to a struct v4l2_ctrl_h264_decode_params.
+ * @p_vp8_frame_header:		Pointer to a VP8 frame header structure.
  * @p:				Pointer to a compound value.
  */
 union v4l2_ctrl_ptr {
@@ -65,6 +67,7 @@
 	struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix;
 	struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
 	struct v4l2_ctrl_h264_decode_params *p_h264_decode_params;
+	struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header;
 	void *p;
 };
 
@@ -1265,25 +1268,28 @@
  *	:ref:`VIDIOC_G_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
  *
  * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @vdev: pointer to &struct video_device
  * @mdev: pointer to &struct media_device
  * @c: pointer to &struct v4l2_ext_controls
  *
  * If hdl == NULL then they will all return -EINVAL.
  */
-int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct media_device *mdev,
-		     struct v4l2_ext_controls *c);
+int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev,
+		     struct media_device *mdev, struct v4l2_ext_controls *c);
 
 /**
  * v4l2_try_ext_ctrls - Helper function to implement
  *	:ref:`VIDIOC_TRY_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
  *
  * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @vdev: pointer to &struct video_device
  * @mdev: pointer to &struct media_device
  * @c: pointer to &struct v4l2_ext_controls
  *
  * If hdl == NULL then they will all return -EINVAL.
  */
 int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl,
+		       struct video_device *vdev,
 		       struct media_device *mdev,
 		       struct v4l2_ext_controls *c);
 
@@ -1293,12 +1299,14 @@
  *
  * @fh: pointer to &struct v4l2_fh
  * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @vdev: pointer to &struct video_device
  * @mdev: pointer to &struct media_device
  * @c: pointer to &struct v4l2_ext_controls
  *
  * If hdl == NULL then they will all return -EINVAL.
  */
 int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
+		     struct video_device *vdev,
 		     struct media_device *mdev,
 		     struct v4l2_ext_controls *c);
 
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 400f2e4..4bba65a 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -602,6 +602,8 @@
 #define V4L2_DEV_DEBUG_STREAMING	0x08
 /* Log poll() */
 #define V4L2_DEV_DEBUG_POLL		0x10
+/* Log controls */
+#define V4L2_DEV_DEBUG_CTRL		0x20
 
 /*  Video standard functions  */
 
diff --git a/include/media/vp8-ctrls.h b/include/media/vp8-ctrls.h
new file mode 100644
index 0000000..53cba82
--- /dev/null
+++ b/include/media/vp8-ctrls.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * These are the VP8 state controls for use with stateless VP8
+ * codec drivers.
+ *
+ * It turns out that these structs are not stable yet and will undergo
+ * more changes. So keep them private until they are stable and ready to
+ * become part of the official public API.
+ */
+
+#ifndef _VP8_CTRLS_H_
+#define _VP8_CTRLS_H_
+
+#include <linux/types.h>
+
+#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F')
+
+#define V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER (V4L2_CID_MPEG_BASE + 2000)
+#define V4L2_CTRL_TYPE_VP8_FRAME_HEADER 0x301
+
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED              0x01
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP           0x02
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_FEATURE_DATA  0x04
+#define V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE     0x08
+
+struct v4l2_vp8_segment_header {
+	__s8 quant_update[4];
+	__s8 lf_update[4];
+	__u8 segment_probs[3];
+	__u8 padding;
+	__u32 flags;
+};
+
+#define V4L2_VP8_LF_HEADER_ADJ_ENABLE	0x01
+#define V4L2_VP8_LF_HEADER_DELTA_UPDATE	0x02
+#define V4L2_VP8_LF_FILTER_TYPE_SIMPLE	0x04
+struct v4l2_vp8_loopfilter_header {
+	__s8 ref_frm_delta[4];
+	__s8 mb_mode_delta[4];
+	__u8 sharpness_level;
+	__u8 level;
+	__u16 padding;
+	__u32 flags;
+};
+
+struct v4l2_vp8_quantization_header {
+	__u8 y_ac_qi;
+	__s8 y_dc_delta;
+	__s8 y2_dc_delta;
+	__s8 y2_ac_delta;
+	__s8 uv_dc_delta;
+	__s8 uv_ac_delta;
+	__u16 padding;
+};
+
+struct v4l2_vp8_entropy_header {
+	__u8 coeff_probs[4][8][3][11];
+	__u8 y_mode_probs[4];
+	__u8 uv_mode_probs[3];
+	__u8 mv_probs[2][19];
+	__u8 padding[3];
+};
+
+struct v4l2_vp8_entropy_coder_state {
+	__u8 range;
+	__u8 value;
+	__u8 bit_count;
+	__u8 padding;
+};
+
+#define V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME		0x01
+#define V4L2_VP8_FRAME_HEADER_FLAG_EXPERIMENTAL		0x02
+#define V4L2_VP8_FRAME_HEADER_FLAG_SHOW_FRAME		0x04
+#define V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF	0x08
+#define V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN	0x10
+#define V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT	0x20
+
+#define VP8_FRAME_IS_KEY_FRAME(hdr) \
+	(!!((hdr)->flags & V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME))
+
+struct v4l2_ctrl_vp8_frame_header {
+	struct v4l2_vp8_segment_header segment_header;
+	struct v4l2_vp8_loopfilter_header lf_header;
+	struct v4l2_vp8_quantization_header quant_header;
+	struct v4l2_vp8_entropy_header entropy_header;
+	struct v4l2_vp8_entropy_coder_state coder_state;
+
+	__u16 width;
+	__u16 height;
+
+	__u8 horizontal_scale;
+	__u8 vertical_scale;
+
+	__u8 version;
+	__u8 prob_skip_false;
+	__u8 prob_intra;
+	__u8 prob_last;
+	__u8 prob_gf;
+	__u8 num_dct_parts;
+
+	__u32 first_part_size;
+	__u32 first_part_header_bits;
+	__u32 dct_part_sizes[8];
+
+	__u64 last_frame_ts;
+	__u64 golden_frame_ts;
+	__u64 alt_frame_ts;
+
+	__u64 flags;
+};
+
+#endif
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 2427bc4..530638d 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -774,8 +774,10 @@
 	__u32		    reserved[4];
 };
 
-#define V4L2_FMT_FLAG_COMPRESSED 0x0001
-#define V4L2_FMT_FLAG_EMULATED   0x0002
+#define V4L2_FMT_FLAG_COMPRESSED		0x0001
+#define V4L2_FMT_FLAG_EMULATED			0x0002
+#define V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM	0x0004
+#define V4L2_FMT_FLAG_DYN_RESOLUTION		0x0008
 
 	/* Frame Size and frame rate enumeration */
 /*
diff --git a/lib/sort.c b/lib/sort.c
index cf408ae..d54cf97 100644
--- a/lib/sort.c
+++ b/lib/sort.c
@@ -144,6 +144,18 @@
 		swap_func(a, b, (int)size);
 }
 
+typedef int (*cmp_func_t)(const void *, const void *);
+typedef int (*cmp_r_func_t)(const void *, const void *, const void *);
+#define _CMP_WRAPPER ((cmp_r_func_t)0L)
+
+static int do_cmp(const void *a, const void *b,
+		  cmp_r_func_t cmp, const void *priv)
+{
+	if (cmp == _CMP_WRAPPER)
+		return ((cmp_func_t)(priv))(a, b);
+	return cmp(a, b, priv);
+}
+
 /**
  * parent - given the offset of the child, find the offset of the parent.
  * @i: the offset of the heap element whose parent is sought.  Non-zero.
@@ -171,12 +183,13 @@
 }
 
 /**
- * sort - sort an array of elements
+ * sort_r - sort an array of elements
  * @base: pointer to data to sort
  * @num: number of elements
  * @size: size of each element
  * @cmp_func: pointer to comparison function
  * @swap_func: pointer to swap function or NULL
+ * @priv: third argument passed to comparison function
  *
  * This function does a heapsort on the given array.  You may provide
  * a swap_func function if you need to do something more than a memory
@@ -188,9 +201,10 @@
  * O(n*n) worst-case behavior and extra memory requirements that make
  * it less suitable for kernel use.
  */
-void sort(void *base, size_t num, size_t size,
-	  int (*cmp_func)(const void *, const void *),
-	  void (*swap_func)(void *, void *, int size))
+void sort_r(void *base, size_t num, size_t size,
+	    int (*cmp_func)(const void *, const void *, const void *),
+	    void (*swap_func)(void *, void *, int size),
+	    const void *priv)
 {
 	/* pre-scale counters for performance */
 	size_t n = num * size, a = (num/2) * size;
@@ -238,12 +252,12 @@
 		 * average, 3/4 worst-case.)
 		 */
 		for (b = a; c = 2*b + size, (d = c + size) < n;)
-			b = cmp_func(base + c, base + d) >= 0 ? c : d;
+			b = do_cmp(base + c, base + d, cmp_func, priv) >= 0 ? c : d;
 		if (d == n)	/* Special case last leaf with no sibling */
 			b = c;
 
 		/* Now backtrack from "b" to the correct location for "a" */
-		while (b != a && cmp_func(base + a, base + b) >= 0)
+		while (b != a && do_cmp(base + a, base + b, cmp_func, priv) >= 0)
 			b = parent(b, lsbit, size);
 		c = b;			/* Where "a" belongs */
 		while (b != a) {	/* Shift it into place */
@@ -252,4 +266,12 @@
 		}
 	}
 }
+EXPORT_SYMBOL(sort_r);
+
+void sort(void *base, size_t num, size_t size,
+	  int (*cmp_func)(const void *, const void *),
+	  void (*swap_func)(void *, void *, int size))
+{
+	return sort_r(base, num, size, _CMP_WRAPPER, swap_func, cmp_func);
+}
 EXPORT_SYMBOL(sort);
diff --git a/tools/testing/selftests/ir/ir_loopback.c b/tools/testing/selftests/ir/ir_loopback.c
index e700e09..af7f9c7 100644
--- a/tools/testing/selftests/ir/ir_loopback.c
+++ b/tools/testing/selftests/ir/ir_loopback.c
@@ -54,9 +54,9 @@
 	{ RC_PROTO_RC6_MCE, "rc-6-mce", 0x00007fff, "rc-6" },
 	{ RC_PROTO_SHARP, "sharp", 0x1fff, "sharp" },
 	{ RC_PROTO_IMON, "imon", 0x7fffffff, "imon" },
-	{ RC_PROTO_RCMM12, "rcmm-12", 0x00000fff, "rcmm" },
-	{ RC_PROTO_RCMM24, "rcmm-24", 0x00ffffff, "rcmm" },
-	{ RC_PROTO_RCMM32, "rcmm-32", 0xffffffff, "rcmm" },
+	{ RC_PROTO_RCMM12, "rcmm-12", 0x00000fff, "rc-mm" },
+	{ RC_PROTO_RCMM24, "rcmm-24", 0x00ffffff, "rc-mm" },
+	{ RC_PROTO_RCMM32, "rcmm-32", 0xffffffff, "rc-mm" },
 };
 
 int lirc_open(const char *rc)