Merge tag 'afs-next-20180208' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs

Pull afs updates from David Howells:
 "Four fixes:

   - add a missing put

   - two fixes to reset the address iteration cursor correctly

   - fix setting up the fileserver iteration cursor.

  Two cleanups:

   - remove some dead code

   - rearrange a function to be more logically laid out

  And one new feature:

   - Support AFS dynamic root.

     With this one should be able to do, say:

        mkdir /afs
        mount -t afs none /afs -o dyn

     to create a dynamic root and then, provided you have keyutils
     installed, do:

        ls /afs/grand.central.org

     and:

        ls /afs/umich.edu

     to list the root volumes of both those organisations' AFS cells
     without requiring any other setup (the kernel upcall to a program
     in the keyutils package to do DNS access as does NFS)"

* tag 'afs-next-20180208' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
  afs: Support the AFS dynamic root
  afs: Rearrange afs_select_fileserver() a little
  afs: Remove unused code
  afs: Fix server list handling
  afs: Need to clear responded flag in addr cursor
  afs: Fix missing cursor clearance
  afs: Add missing afs_put_cell()
diff --git a/Documentation/ABI/testing/sysfs-driver-samsung-laptop b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
index 63c1ad0..34d3a33 100644
--- a/Documentation/ABI/testing/sysfs-driver-samsung-laptop
+++ b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
@@ -3,7 +3,7 @@
 KernelVersion:	2.6.33
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:	Some Samsung laptops have different "performance levels"
-		that are can be modified by a function key, and by this
+		that can be modified by a function key, and by this
 		sysfs file.  These values don't always make a whole lot
 		of sense, but some users like to modify them to keep
 		their fans quiet at all costs.  Reading from this file
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 512ccaf..39ac9d4 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3711,7 +3711,11 @@
 			[KNL, SMP] Set scheduler's default relax_domain_level.
 			See Documentation/cgroup-v1/cpusets.txt.
 
-	reserve=	[KNL,BUGS] Force the kernel to ignore some iomem area
+	reserve=	[KNL,BUGS] Force kernel to ignore I/O ports or memory
+			Format: <base1>,<size1>[,<base2>,<size2>,...]
+			Reserve I/O ports or memory so the kernel won't use
+			them.  If <base> is less than 0x10000, the region
+			is assumed to be I/O ports; otherwise it is memory.
 
 	reservetop=	[X86-32]
 			Format: nn[KMG]
diff --git a/Documentation/admin-guide/thunderbolt.rst b/Documentation/admin-guide/thunderbolt.rst
index 9b55952..9948ec3 100644
--- a/Documentation/admin-guide/thunderbolt.rst
+++ b/Documentation/admin-guide/thunderbolt.rst
@@ -3,13 +3,13 @@
 =============
 The interface presented here is not meant for end users. Instead there
 should be a userspace tool that handles all the low-level details, keeps
-database of the authorized devices and prompts user for new connections.
+a database of the authorized devices and prompts users for new connections.
 
 More details about the sysfs interface for Thunderbolt devices can be
 found in ``Documentation/ABI/testing/sysfs-bus-thunderbolt``.
 
 Those users who just want to connect any device without any sort of
-manual work, can add following line to
+manual work can add following line to
 ``/etc/udev/rules.d/99-local.rules``::
 
   ACTION=="add", SUBSYSTEM=="thunderbolt", ATTR{authorized}=="0", ATTR{authorized}="1"
@@ -20,7 +20,7 @@
 
 Security levels and how to use them
 -----------------------------------
-Starting from Intel Falcon Ridge Thunderbolt controller there are 4
+Starting with Intel Falcon Ridge Thunderbolt controller there are 4
 security levels available. The reason for these is the fact that the
 connected devices can be DMA masters and thus read contents of the host
 memory without CPU and OS knowing about it. There are ways to prevent
@@ -37,14 +37,14 @@
   user
     User is asked whether the device is allowed to be connected.
     Based on the device identification information available through
-    ``/sys/bus/thunderbolt/devices``. user then can do the decision.
+    ``/sys/bus/thunderbolt/devices``, the user then can make the decision.
     In BIOS settings this is typically called *Unique ID*.
 
   secure
     User is asked whether the device is allowed to be connected. In
     addition to UUID the device (if it supports secure connect) is sent
     a challenge that should match the expected one based on a random key
-    written to ``key`` sysfs attribute. In BIOS settings this is
+    written to the ``key`` sysfs attribute. In BIOS settings this is
     typically called *One time saved key*.
 
   dponly
@@ -78,7 +78,7 @@
   /sys/bus/thunderbolt/devices/0-1/unique_id	- e0376f00-0300-0100-ffff-ffffffffffff
 
 The ``authorized`` attribute reads 0 which means no PCIe tunnels are
-created yet. The user can authorize the device by simply::
+created yet. The user can authorize the device by simply entering::
 
   # echo 1 > /sys/bus/thunderbolt/devices/0-1/authorized
 
@@ -86,7 +86,7 @@
 
 If the device supports secure connect, and the domain security level is
 set to ``secure``, it has an additional attribute ``key`` which can hold
-a random 32 byte value used for authorization and challenging the device in
+a random 32-byte value used for authorization and challenging the device in
 future connects::
 
   /sys/bus/thunderbolt/devices/0-3/authorized	- 0
@@ -99,12 +99,12 @@
 
 Notice the key is empty by default.
 
-If the user does not want to use secure connect it can just ``echo 1``
+If the user does not want to use secure connect they can just ``echo 1``
 to the ``authorized`` attribute and the PCIe tunnels will be created in
-the same way than in ``user`` security level.
+the same way as in the ``user`` security level.
 
 If the user wants to use secure connect, the first time the device is
-plugged a key needs to be created and send to the device::
+plugged a key needs to be created and sent to the device::
 
   # key=$(openssl rand -hex 32)
   # echo $key > /sys/bus/thunderbolt/devices/0-3/key
@@ -121,27 +121,27 @@
 
 If the challenge the device returns back matches the one we expect based
 on the key, the device is connected and the PCIe tunnels are created.
-However, if the challenge failed no tunnels are created and error is
+However, if the challenge fails no tunnels are created and error is
 returned to the user.
 
-If the user still wants to connect the device it can either approve
-the device without a key or write new key and write 1 to the
+If the user still wants to connect the device they can either approve
+the device without a key or write a new key and write 1 to the
 ``authorized`` file to get the new key stored on the device NVM.
 
 Upgrading NVM on Thunderbolt device or host
 -------------------------------------------
-Since most of the functionality is handled in a firmware running on a
+Since most of the functionality is handled in firmware running on a
 host controller or a device, it is important that the firmware can be
 upgraded to the latest where possible bugs in it have been fixed.
 Typically OEMs provide this firmware from their support site.
 
-There is also a central site which has links where to download firmwares
+There is also a central site which has links where to download firmware
 for some machines:
 
   `Thunderbolt Updates <https://thunderbolttechnology.net/updates>`_
 
-Before you upgrade firmware on a device or host, please make sure it is
-the suitable. Failing to do that may render the device (or host) in a
+Before you upgrade firmware on a device or host, please make sure it is a
+suitable upgrade. Failing to do that may render the device (or host) in a
 state where it cannot be used properly anymore without special tools!
 
 Host NVM upgrade on Apple Macs is not supported.
@@ -151,7 +151,7 @@
 matter which device is connected (unless you are upgrading NVM on a
 device - then you need to connect that particular device).
 
-Note OEM-specific method to power the controller up ("force power") may
+Note an OEM-specific method to power the controller up ("force power") may
 be available for your system in which case there is no need to plug in a
 Thunderbolt device.
 
@@ -171,7 +171,7 @@
 After a while the host controller appears again and this time it should
 be fully functional.
 
-We can verify that the new NVM firmware is active by running following
+We can verify that the new NVM firmware is active by running the following
 commands::
 
   # cat /sys/bus/thunderbolt/devices/0-0/nvm_authenticate
@@ -179,38 +179,38 @@
   # cat /sys/bus/thunderbolt/devices/0-0/nvm_version
   18.0
 
-If ``nvm_authenticate`` contains anything else than 0x0 it is the error
+If ``nvm_authenticate`` contains anything other than 0x0 it is the error
 code from the last authentication cycle, which means the authentication
 of the NVM image failed.
 
 Note names of the NVMem devices ``nvm_activeN`` and ``nvm_non_activeN``
-depends on the order they are registered in the NVMem subsystem. N in
+depend on the order they are registered in the NVMem subsystem. N in
 the name is the identifier added by the NVMem subsystem.
 
 Upgrading NVM when host controller is in safe mode
 --------------------------------------------------
 If the existing NVM is not properly authenticated (or is missing) the
-host controller goes into safe mode which means that only available
-functionality is flashing new NVM image. When in this mode the reading
+host controller goes into safe mode which means that the only available
+functionality is flashing a new NVM image. When in this mode, reading
 ``nvm_version`` fails with ``ENODATA`` and the device identification
 information is missing.
 
 To recover from this mode, one needs to flash a valid NVM image to the
-host host controller in the same way it is done in the previous chapter.
+host controller in the same way it is done in the previous chapter.
 
 Networking over Thunderbolt cable
 ---------------------------------
-Thunderbolt technology allows software communication across two hosts
+Thunderbolt technology allows software communication between two hosts
 connected by a Thunderbolt cable.
 
-It is possible to tunnel any kind of traffic over Thunderbolt link but
+It is possible to tunnel any kind of traffic over a Thunderbolt link but
 currently we only support Apple ThunderboltIP protocol.
 
-If the other host is running Windows or macOS only thing you need to
-do is to connect Thunderbolt cable between the two hosts, the
-``thunderbolt-net`` is loaded automatically. If the other host is also
-Linux you should load ``thunderbolt-net`` manually on one host (it does
-not matter which one)::
+If the other host is running Windows or macOS, the only thing you need to
+do is to connect a Thunderbolt cable between the two hosts; the
+``thunderbolt-net`` driver is loaded automatically. If the other host is
+also Linux you should load ``thunderbolt-net`` manually on one host (it
+does not matter which one)::
 
   # modprobe thunderbolt-net
 
@@ -220,12 +220,12 @@
 The driver will create one virtual ethernet interface per Thunderbolt
 port which are named like ``thunderbolt0`` and so on. From this point
 you can either use standard userspace tools like ``ifconfig`` to
-configure the interface or let your GUI to handle it automatically.
+configure the interface or let your GUI handle it automatically.
 
 Forcing power
 -------------
 Many OEMs include a method that can be used to force the power of a
-thunderbolt controller to an "On" state even if nothing is connected.
+Thunderbolt controller to an "On" state even if nothing is connected.
 If supported by your machine this will be exposed by the WMI bus with
 a sysfs attribute called "force_power".
 
diff --git a/Documentation/bpf/bpf_devel_QA.txt b/Documentation/bpf/bpf_devel_QA.txt
index cefef85..84cbb30 100644
--- a/Documentation/bpf/bpf_devel_QA.txt
+++ b/Documentation/bpf/bpf_devel_QA.txt
@@ -516,4 +516,35 @@
    By the way, the BPF kernel selftests run with -mcpu=probe for better
    test coverage.
 
+Q: In some cases clang flag "-target bpf" is used but in other cases the
+   default clang target, which matches the underlying architecture, is used.
+   What is the difference and when I should use which?
+
+A: Although LLVM IR generation and optimization try to stay architecture
+   independent, "-target <arch>" still has some impact on generated code:
+
+     - BPF program may recursively include header file(s) with file scope
+       inline assembly codes. The default target can handle this well,
+       while bpf target may fail if bpf backend assembler does not
+       understand these assembly codes, which is true in most cases.
+
+     - When compiled without -g, additional elf sections, e.g.,
+       .eh_frame and .rela.eh_frame, may be present in the object file
+       with default target, but not with bpf target.
+
+     - The default target may turn a C switch statement into a switch table
+       lookup and jump operation. Since the switch table is placed
+       in the global readonly section, the bpf program will fail to load.
+       The bpf target does not support switch table optimization.
+       The clang option "-fno-jump-tables" can be used to disable
+       switch table generation.
+
+   You should use default target when:
+
+     - Your program includes a header file, e.g., ptrace.h, which eventually
+       pulls in some header files containing file scope host assembly codes.
+     - You can add "-fno-jump-tables" to work around the switch table issue.
+
+   Otherwise, you can use bpf target.
+
 Happy BPF hacking!
diff --git a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
index 857df92..1fd5d696 100644
--- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
+++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt
@@ -16,6 +16,9 @@
     - "renesas,ipmmu-r8a7793" for the R8A7793 (R-Car M2-N) IPMMU.
     - "renesas,ipmmu-r8a7794" for the R8A7794 (R-Car E2) IPMMU.
     - "renesas,ipmmu-r8a7795" for the R8A7795 (R-Car H3) IPMMU.
+    - "renesas,ipmmu-r8a7796" for the R8A7796 (R-Car M3-W) IPMMU.
+    - "renesas,ipmmu-r8a77970" for the R8A77970 (R-Car V3M) IPMMU.
+    - "renesas,ipmmu-r8a77995" for the R8A77995 (R-Car D3) IPMMU.
     - "renesas,ipmmu-vmsa" for generic R-Car Gen2 VMSA-compatible IPMMU.
 
   - reg: Base address and size of the IPMMU registers.
diff --git a/Documentation/devicetree/bindings/media/cec-gpio.txt b/Documentation/devicetree/bindings/media/cec-gpio.txt
index 46a0bac..12fcd55 100644
--- a/Documentation/devicetree/bindings/media/cec-gpio.txt
+++ b/Documentation/devicetree/bindings/media/cec-gpio.txt
@@ -4,6 +4,10 @@
 is hooked up to a pull-up GPIO line and - optionally - the HPD line is
 hooked up to another GPIO line.
 
+Please note: the maximum voltage for the CEC line is 3.63V, for the HPD
+line it is 5.3V. So you may need some sort of level conversion circuitry
+when connecting them to a GPIO line.
+
 Required properties:
   - compatible: value must be "cec-gpio".
   - cec-gpios: gpio that the CEC line is connected to. The line should be
@@ -21,7 +25,7 @@
 
 Example for the Raspberry Pi 3 where the CEC line is connected to
 pin 26 aka BCM7 aka CE1 on the GPIO pin header and the HPD line is
-connected to pin 11 aka BCM17:
+connected to pin 11 aka BCM17 (some level shifter is needed for this!):
 
 #include <dt-bindings/gpio/gpio.h>
 
diff --git a/Documentation/devicetree/bindings/media/i2c/mt9m111.txt b/Documentation/devicetree/bindings/media/i2c/mt9m111.txt
index ed5a334..6b91003 100644
--- a/Documentation/devicetree/bindings/media/i2c/mt9m111.txt
+++ b/Documentation/devicetree/bindings/media/i2c/mt9m111.txt
@@ -6,6 +6,8 @@
 
 Required Properties:
 - compatible: value should be "micron,mt9m111"
+- clocks: reference to the master clock.
+- clock-names: shall be "mclk".
 
 For further reading on port node refer to
 Documentation/devicetree/bindings/media/video-interfaces.txt.
@@ -16,6 +18,8 @@
 		mt9m111@5d {
 			compatible = "micron,mt9m111";
 			reg = <0x5d>;
+			clocks = <&mclk>;
+			clock-names = "mclk";
 
 			remote = <&pxa_camera>;
 			port {
diff --git a/Documentation/devicetree/bindings/media/i2c/ov5640.txt b/Documentation/devicetree/bindings/media/i2c/ov5640.txt
index 540b36c..8e36da0 100644
--- a/Documentation/devicetree/bindings/media/i2c/ov5640.txt
+++ b/Documentation/devicetree/bindings/media/i2c/ov5640.txt
@@ -1,4 +1,4 @@
-* Omnivision OV5640 MIPI CSI-2 sensor
+* Omnivision OV5640 MIPI CSI-2 / parallel sensor
 
 Required Properties:
 - compatible: should be "ovti,ov5640"
@@ -18,7 +18,25 @@
 video port, in accordance with the video interface bindings defined in
 Documentation/devicetree/bindings/media/video-interfaces.txt.
 
-Example:
+OV5640 can be connected to a MIPI CSI-2 bus or a parallel bus endpoint.
+
+Endpoint node required properties for CSI-2 connection are:
+- remote-endpoint: a phandle to the bus receiver's endpoint node.
+- clock-lanes: should be set to <0> (clock lane on hardware lane 0)
+- data-lanes: should be set to <1> or <1 2> (one or two CSI-2 lanes supported)
+
+Endpoint node required properties for parallel connection are:
+- remote-endpoint: a phandle to the bus receiver's endpoint node.
+- bus-width: shall be set to <8> for 8 bits parallel bus
+	     or <10> for 10 bits parallel bus
+- data-shift: shall be set to <2> for 8 bits parallel bus
+	      (lines 9:2 are used) or <0> for 10 bits parallel bus
+- hsync-active: active state of the HSYNC signal, 0/1 for LOW/HIGH respectively.
+- vsync-active: active state of the VSYNC signal, 0/1 for LOW/HIGH respectively.
+- pclk-sample: sample data on rising (1) or falling (0) edge of the pixel clock
+	       signal.
+
+Examples:
 
 &i2c1 {
 	ov5640: camera@3c {
@@ -35,6 +53,7 @@
 		reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
 
 		port {
+			/* MIPI CSI-2 bus endpoint */
 			ov5640_to_mipi_csi2: endpoint {
 				remote-endpoint = <&mipi_csi2_from_ov5640>;
 				clock-lanes = <0>;
@@ -43,3 +62,26 @@
 		};
 	};
 };
+
+&i2c1 {
+	ov5640: camera@3c {
+		compatible = "ovti,ov5640";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ov5640>;
+		reg = <0x3c>;
+		clocks = <&clk_ext_camera>;
+		clock-names = "xclk";
+
+		port {
+			/* Parallel bus endpoint */
+			ov5640_to_parallel: endpoint {
+				remote-endpoint = <&parallel_from_ov5640>;
+				bus-width = <8>;
+				data-shift = <2>; /* lines 9:2 are used */
+				hsync-active = <0>;
+				vsync-active = <0>;
+				pclk-sample = <1>;
+			};
+		};
+	};
+};
diff --git a/Documentation/devicetree/bindings/media/i2c/ov7740.txt b/Documentation/devicetree/bindings/media/i2c/ov7740.txt
new file mode 100644
index 0000000..af781c3
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ov7740.txt
@@ -0,0 +1,47 @@
+* Omnivision OV7740 CMOS image sensor
+
+The Omnivision OV7740 image sensor supports multiple output image
+size, such as VGA, and QVGA, CIF and any size smaller. It also
+supports the RAW RGB and YUV output formats.
+
+The common video interfaces bindings (see video-interfaces.txt) should
+be used to specify link to the image data receiver. The OV7740 device
+node should contain one 'port' child node with an 'endpoint' subnode.
+
+Required Properties:
+- compatible:	"ovti,ov7740".
+- reg:		I2C slave address of the sensor.
+- clocks:	Reference to the xvclk input clock.
+- clock-names:	"xvclk".
+
+Optional Properties:
+- reset-gpios: Rreference to the GPIO connected to the reset_b pin,
+  if any. Active low with pull-ip resistor.
+- powerdown-gpios: Reference to the GPIO connected to the pwdn pin,
+  if any. Active high with pull-down resistor.
+
+Endpoint node mandatory properties:
+- remote-endpoint: A phandle to the bus receiver's endpoint node.
+
+Example:
+
+	i2c1: i2c@fc028000 {
+		ov7740: camera@21 {
+			compatible = "ovti,ov7740";
+			reg = <0x21>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_sensor_power &pinctrl_sensor_reset>;
+			clocks = <&isc>;
+			clock-names = "xvclk";
+			assigned-clocks = <&isc>;
+			assigned-clock-rates = <24000000>;
+			reset-gpios = <&pioA 43 GPIO_ACTIVE_LOW>;
+			powerdown-gpios = <&pioA 44 GPIO_ACTIVE_HIGH>;
+
+			port {
+				ov7740_0: endpoint {
+					remote-endpoint = <&isc_0>;
+				};
+			};
+		};
+	};
diff --git a/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt b/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
index 0b7b6a4..e80d589 100644
--- a/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
+++ b/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
@@ -20,6 +20,13 @@
   is in hardware standby mode when the signal is in the low state.
 
 
+Optional properties
+-------------------
+
+- flash-leds: See ../video-interfaces.txt
+- lens-focus: See ../video-interfaces.txt
+
+
 Endpoint node mandatory properties
 ----------------------------------
 
diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
new file mode 100644
index 0000000..470237e
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
@@ -0,0 +1,55 @@
+NVIDIA Tegra Video Decoder Engine
+
+Required properties:
+- compatible : Must contain one of the following values:
+   - "nvidia,tegra20-vde"
+   - "nvidia,tegra30-vde"
+   - "nvidia,tegra114-vde"
+   - "nvidia,tegra124-vde"
+   - "nvidia,tegra132-vde"
+- reg : Must contain an entry for each entry in reg-names.
+- reg-names : Must include the following entries:
+  - sxe
+  - bsev
+  - mbe
+  - ppe
+  - mce
+  - tfe
+  - ppb
+  - vdma
+  - frameid
+- iram : Must contain phandle to the mmio-sram device node that represents
+         IRAM region used by VDE.
+- interrupts : Must contain an entry for each entry in interrupt-names.
+- interrupt-names : Must include the following entries:
+  - sync-token
+  - bsev
+  - sxe
+- clocks : Must include the following entries:
+  - vde
+- resets : Must include the following entries:
+  - vde
+
+Example:
+
+video-codec@6001a000 {
+	compatible = "nvidia,tegra20-vde";
+	reg = <0x6001a000 0x1000 /* Syntax Engine */
+	       0x6001b000 0x1000 /* Video Bitstream Engine */
+	       0x6001c000  0x100 /* Macroblock Engine */
+	       0x6001c200  0x100 /* Post-processing Engine */
+	       0x6001c400  0x100 /* Motion Compensation Engine */
+	       0x6001c600  0x100 /* Transform Engine */
+	       0x6001c800  0x100 /* Pixel prediction block */
+	       0x6001ca00  0x100 /* Video DMA */
+	       0x6001d800  0x300 /* Video frame controls */>;
+	reg-names = "sxe", "bsev", "mbe", "ppe", "mce",
+		    "tfe", "ppb", "vdma", "frameid";
+	iram = <&vde_pool>; /* IRAM region */
+	interrupts = <GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>, /* Sync token interrupt */
+		     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, /* BSE-V interrupt */
+		     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; /* SXE interrupt */
+	interrupt-names = "sync-token", "bsev", "sxe";
+	clocks = <&tegra_car TEGRA20_CLK_VDE>;
+	resets = <&tegra_car 61>;
+};
diff --git a/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt b/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
index 9dd86b3..439351a 100644
--- a/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
+++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
@@ -66,6 +66,6 @@
 				tpg1_out: endpoint {
 					remote-endpoint = <&switch_in0>;
 				};
-			}:
+			};
 		};
 	};
diff --git a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt
index 4e4aee4..979dc7b 100644
--- a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt
@@ -4,7 +4,10 @@
 and thus inherits all the common properties defined in designware-pcie.txt.
 
 Required properties:
-- compatible: "axis,artpec6-pcie", "snps,dw-pcie"
+- compatible: "axis,artpec6-pcie", "snps,dw-pcie" for ARTPEC-6 in RC mode;
+	      "axis,artpec6-pcie-ep", "snps,dw-pcie" for ARTPEC-6 in EP mode;
+	      "axis,artpec7-pcie", "snps,dw-pcie" for ARTPEC-7 in RC mode;
+	      "axis,artpec7-pcie-ep", "snps,dw-pcie" for ARTPEC-7 in EP mode;
 - reg: base addresses and lengths of the PCIe controller (DBI),
 	the PHY controller, and configuration address space.
 - reg-names: Must include the following entries:
diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt
new file mode 100644
index 0000000..9a305237
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt
@@ -0,0 +1,22 @@
+* Cadence PCIe endpoint controller
+
+Required properties:
+- compatible: Should contain "cdns,cdns-pcie-ep" to identify the IP used.
+- reg: Should contain the controller register base address and AXI interface
+  region base address respectively.
+- reg-names: Must be "reg" and "mem" respectively.
+- cdns,max-outbound-regions: Set to maximum number of outbound regions
+
+Optional properties:
+- max-functions: Maximum number of functions that can be configured (default 1).
+
+Example:
+
+pcie@fc000000 {
+	compatible = "cdns,cdns-pcie-ep";
+	reg = <0x0 0xfc000000 0x0 0x01000000>,
+	      <0x0 0x80000000 0x0 0x40000000>;
+	reg-names = "reg", "mem";
+	cdns,max-outbound-regions = <16>;
+	max-functions = /bits/ 8 <8>;
+};
diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt
new file mode 100644
index 0000000..20a33f3
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt
@@ -0,0 +1,60 @@
+* Cadence PCIe host controller
+
+This PCIe controller inherits the base properties defined in
+host-generic-pci.txt.
+
+Required properties:
+- compatible: Should contain "cdns,cdns-pcie-host" to identify the IP used.
+- reg: Should contain the controller register base address, PCIe configuration
+  window base address, and AXI interface region base address respectively.
+- reg-names: Must be "reg", "cfg" and "mem" respectively.
+- #address-cells: Set to <3>
+- #size-cells: Set to <2>
+- device_type: Set to "pci"
+- ranges: Ranges for the PCI memory and I/O regions
+- #interrupt-cells: Set to <1>
+- interrupt-map-mask and interrupt-map: Standard PCI properties to define the
+  mapping of the PCIe interface to interrupt numbers.
+
+Optional properties:
+- cdns,max-outbound-regions: Set to maximum number of outbound regions
+  (default 32)
+- cdns,no-bar-match-nbits: Set into the no BAR match register to configure the
+  number of least significant bits kept during inbound (PCIe -> AXI) address
+  translations (default 32)
+- vendor-id: The PCI vendor ID (16 bits, default is design dependent)
+- device-id: The PCI device ID (16 bits, default is design dependent)
+
+Example:
+
+pcie@fb000000 {
+	compatible = "cdns,cdns-pcie-host";
+	device_type = "pci";
+	#address-cells = <3>;
+	#size-cells = <2>;
+	bus-range = <0x0 0xff>;
+	linux,pci-domain = <0>;
+	cdns,max-outbound-regions = <16>;
+	cdns,no-bar-match-nbits = <32>;
+	vendor-id = /bits/ 16 <0x17cd>;
+	device-id = /bits/ 16 <0x0200>;
+
+	reg = <0x0 0xfb000000  0x0 0x01000000>,
+	      <0x0 0x41000000  0x0 0x00001000>,
+	      <0x0 0x40000000  0x0 0x04000000>;
+	reg-names = "reg", "cfg", "mem";
+
+	ranges = <0x02000000 0x0 0x42000000  0x0 0x42000000  0x0 0x1000000>,
+		 <0x01000000 0x0 0x43000000  0x0 0x43000000  0x0 0x0010000>;
+
+	#interrupt-cells = <0x1>;
+
+	interrupt-map = <0x0 0x0 0x0  0x1  &gic  0x0 0x0 0x0 14 0x1
+			 0x0 0x0 0x0  0x2  &gic  0x0 0x0 0x0 15 0x1
+			 0x0 0x0 0x0  0x3  &gic  0x0 0x0 0x0 16 0x1
+			 0x0 0x0 0x0  0x4  &gic  0x0 0x0 0x0 17 0x1>;
+
+	interrupt-map-mask = <0x0 0x0 0x0  0x7>;
+
+	msi-parent = <&its_pci>;
+};
diff --git a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
index 34a11bf..651d957 100644
--- a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
@@ -6,9 +6,6 @@
 Required properties:
 - compatible: "samsung,exynos5440-pcie"
 - reg: base addresses and lengths of the PCIe controller,
-	the PHY controller, additional register for the PHY controller.
-	(Registers for the PHY controller are DEPRECATED.
-	 Use the PHY framework.)
 - reg-names : First name should be set to "elbi".
 	And use the "config" instead of getting the configuration address space
 	from "ranges".
@@ -23,49 +20,8 @@
 
 Example:
 
-SoC-specific DT Entry:
+SoC-specific DT Entry (with using PHY framework):
 
-	pcie@290000 {
-		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
-		reg = <0x290000 0x1000
-			0x270000 0x1000
-			0x271000 0x40>;
-		interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
-		clocks = <&clock 28>, <&clock 27>;
-		clock-names = "pcie", "pcie_bus";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000   /* configuration space */
-			  0x81000000 0 0	  0x40001000 0 0x00010000   /* downstream I/O */
-			  0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
-		num-lanes = <4>;
-	};
-
-	pcie@2a0000 {
-		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
-		reg = <0x2a0000 0x1000
-			0x272000 0x1000
-			0x271040 0x40>;
-		interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
-		clocks = <&clock 29>, <&clock 27>;
-		clock-names = "pcie", "pcie_bus";
-		#address-cells = <3>;
-		#size-cells = <2>;
-		device_type = "pci";
-		ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000   /* configuration space */
-			  0x81000000 0 0	  0x60001000 0 0x00010000   /* downstream I/O */
-			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
-		#interrupt-cells = <1>;
-		interrupt-map-mask = <0 0 0 0>;
-		interrupt-map = <0 0 0 0 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
-		num-lanes = <4>;
-	};
-
-With using PHY framework:
 	pcie_phy0: pcie-phy@270000 {
 		...
 		reg = <0x270000 0x1000>, <0x271000 0x40>;
@@ -74,13 +30,21 @@
 	};
 
 	pcie@290000 {
-		...
+		compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
 		reg = <0x290000 0x1000>, <0x40000000 0x1000>;
 		reg-names = "elbi", "config";
+		clocks = <&clock 28>, <&clock 27>;
+		clock-names = "pcie", "pcie_bus";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
 		phys = <&pcie_phy0>;
 		ranges = <0x81000000 0 0	  0x60001000 0 0x00010000
 			  0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>;
-		...
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 0>;
+		interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+		num-lanes = <4>;
 	};
 
 Board-specific DT Entry:
diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
index 24aacf8..e0d013a 100644
--- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
@@ -2,22 +2,35 @@
 
 Required properties:
 
-- compatible:	Should be set to one of the following:
-		marvell,armada370-thermal
-		marvell,armada375-thermal
-		marvell,armada380-thermal
-		marvell,armadaxp-thermal
+- compatible: Should be set to one of the following:
+    * marvell,armada370-thermal
+    * marvell,armada375-thermal
+    * marvell,armada380-thermal
+    * marvell,armadaxp-thermal
+    * marvell,armada-ap806-thermal
+    * marvell,armada-cp110-thermal
 
-- reg:		Device's register space.
-		Two entries are expected, see the examples below.
-		The first one is required for the sensor register;
-		the second one is required for the control register
-		to be used for sensor initialization (a.k.a. calibration).
+- reg: Device's register space.
+  Two entries are expected, see the examples below. The first one points
+  to the status register (4B). The second one points to the control
+  registers (8B).
+  Note: The compatibles marvell,armada370-thermal,
+  marvell,armada380-thermal, and marvell,armadaxp-thermal must point to
+  "control MSB/control 1", with size of 4 (deprecated binding), or point
+  to "control LSB/control 0" with size of 8 (current binding). All other
+  compatibles must point to "control LSB/control 0" with size of 8.
 
-Example:
+Examples:
 
+	/* Legacy bindings */
 	thermal@d0018300 {
 		compatible = "marvell,armada370-thermal";
-                reg = <0xd0018300 0x4
+		reg = <0xd0018300 0x4
 		       0xd0018304 0x4>;
 	};
+
+	ap_thermal: thermal@6f8084 {
+		compatible = "marvell,armada-ap806-thermal";
+		reg = <0x6f808C 0x4>,
+		      <0x6f8084 0x8>;
+	};
diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
index a8e52c8c..349e635 100644
--- a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
@@ -6,6 +6,7 @@
 			   "renesas,rcar-thermal" (without thermal-zone) as fallback.
 			  Examples with soctypes are:
 			    - "renesas,thermal-r8a73a4" (R-Mobile APE6)
+			    - "renesas,thermal-r8a7743" (RZ/G1M)
 			    - "renesas,thermal-r8a7779" (R-Car H1)
 			    - "renesas,thermal-r8a7790" (R-Car H2)
 			    - "renesas,thermal-r8a7791" (R-Car M2-W)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index b1fa64a..ae850d6 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -125,6 +125,7 @@
 friendlyarm	Guangzhou FriendlyARM Computer Tech Co., Ltd
 fsl	Freescale Semiconductor
 fujitsu	Fujitsu Ltd.
+gcw Game Consoles Worldwide
 ge	General Electric Company
 geekbuying	GeekBuying
 gef	GE Fanuc Intelligent Platforms Embedded Systems, Inc.
diff --git a/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt b/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt
deleted file mode 100644
index bc4b865..0000000
--- a/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Cortina Systems Gemini SoC Watchdog
-
-Required properties:
-- compatible : must be "cortina,gemini-watchdog"
-- reg : shall contain base register location and length
-- interrupts : shall contain the interrupt for the watchdog
-
-Optional properties:
-- timeout-sec : the default watchdog timeout in seconds.
-
-Example:
-
-watchdog@41000000 {
-	compatible = "cortina,gemini-watchdog";
-	reg = <0x41000000 0x1000>;
-	interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
-};
diff --git a/Documentation/devicetree/bindings/watchdog/cortina,gemini-watchdog.txt b/Documentation/devicetree/bindings/watchdog/cortina,gemini-watchdog.txt
deleted file mode 100644
index bc4b865..0000000
--- a/Documentation/devicetree/bindings/watchdog/cortina,gemini-watchdog.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Cortina Systems Gemini SoC Watchdog
-
-Required properties:
-- compatible : must be "cortina,gemini-watchdog"
-- reg : shall contain base register location and length
-- interrupts : shall contain the interrupt for the watchdog
-
-Optional properties:
-- timeout-sec : the default watchdog timeout in seconds.
-
-Example:
-
-watchdog@41000000 {
-	compatible = "cortina,gemini-watchdog";
-	reg = <0x41000000 0x1000>;
-	interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
-};
diff --git a/Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.txt b/Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.txt
new file mode 100644
index 0000000..9ecdb50
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.txt
@@ -0,0 +1,22 @@
+Faraday Technology FTWDT010 watchdog
+
+This is an IP part from Faraday Technology found in the Gemini
+SoCs and others.
+
+Required properties:
+- compatible : must be one of
+  "faraday,ftwdt010"
+  "cortina,gemini-watchdog", "faraday,ftwdt010"
+- reg : shall contain base register location and length
+- interrupts : shall contain the interrupt for the watchdog
+
+Optional properties:
+- timeout-sec : the default watchdog timeout in seconds.
+
+Example:
+
+watchdog@41000000 {
+	compatible = "faraday,ftwdt010";
+	reg = <0x41000000 0x1000>;
+	interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
+};
diff --git a/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt b/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt
index 3c7a1cd..cb44918 100644
--- a/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt
@@ -1,7 +1,7 @@
-Ingenic Watchdog Timer (WDT) Controller for JZ4740
+Ingenic Watchdog Timer (WDT) Controller for JZ4740 & JZ4780
 
 Required properties:
-compatible: "ingenic,jz4740-watchdog"
+compatible: "ingenic,jz4740-watchdog" or "ingenic,jz4780-watchdog"
 reg: Register address and length for watchdog registers
 
 Example:
diff --git a/Documentation/devicetree/bindings/watchdog/realtek,rtd119x.txt b/Documentation/devicetree/bindings/watchdog/realtek,rtd119x.txt
new file mode 100644
index 0000000..0565305
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/realtek,rtd119x.txt
@@ -0,0 +1,17 @@
+Realtek RTD1295 Watchdog
+========================
+
+Required properties:
+
+- compatible :  Should be "realtek,rtd1295-watchdog"
+- reg        :  Specifies the physical base address and size of registers
+- clocks     :  Specifies one clock input
+
+
+Example:
+
+	watchdog@98007680 {
+		compatible = "realtek,rtd1295-watchdog";
+		reg = <0x98007680 0x100>;
+		clocks = <&osc27M>;
+	};
diff --git a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
index bf6d1ca..74b2f03 100644
--- a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
@@ -4,10 +4,11 @@
 - compatible : Should be "renesas,<soctype>-wdt", and
 	       "renesas,rcar-gen3-wdt" or "renesas,rza-wdt" as fallback.
 	       Examples with soctypes are:
+	         - "renesas,r7s72100-wdt" (RZ/A1)
 	         - "renesas,r8a7795-wdt" (R-Car H3)
 	         - "renesas,r8a7796-wdt" (R-Car M3-W)
+	         - "renesas,r8a77970-wdt" (R-Car V3M)
 	         - "renesas,r8a77995-wdt" (R-Car D3)
-	         - "renesas,r7s72100-wdt" (RZ/A1)
 
   When compatible with the generic version, nodes must list the SoC-specific
   version corresponding to the platform first, followed by the generic
diff --git a/Documentation/devicetree/bindings/watchdog/sprd-wdt.txt b/Documentation/devicetree/bindings/watchdog/sprd-wdt.txt
new file mode 100644
index 0000000..aeaf3e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/sprd-wdt.txt
@@ -0,0 +1,19 @@
+Spreadtrum SoCs Watchdog timer
+
+Required properties:
+- compatible : Should be "sprd,sp9860-wdt".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : Exactly one interrupt specifier.
+- timeout-sec : Contain the default watchdog timeout in seconds.
+- clock-names : Contain the input clock names.
+- clocks : Phandles to input clocks.
+
+Example:
+	watchdog: watchdog@40310000 {
+		compatible = "sprd,sp9860-wdt";
+		reg = <0 0x40310000 0 0x1000>;
+		interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+		timeout-sec = <12>;
+		clock-names = "enable", "rtc_enable";
+		clocks = <&clk_aon_apb_gates1 8>, <&clk_aon_apb_rtc_gates 9>;
+	};
diff --git a/Documentation/infiniband/user_verbs.txt b/Documentation/infiniband/user_verbs.txt
index e5092d6..df049b9 100644
--- a/Documentation/infiniband/user_verbs.txt
+++ b/Documentation/infiniband/user_verbs.txt
@@ -5,7 +5,7 @@
   described in chapter 11 of the InfiniBand Architecture Specification.
 
   To use the verbs, the libibverbs library, available from
-  http://www.openfabrics.org/, is required.  libibverbs contains a
+  https://github.com/linux-rdma/rdma-core, is required. libibverbs contains a
   device-independent API for using the ib_uverbs interface.
   libibverbs also requires appropriate device-dependent kernel and
   userspace driver for your InfiniBand hardware.  For example, to use
diff --git a/Documentation/media/dmx.h.rst.exceptions b/Documentation/media/dmx.h.rst.exceptions
index 629db38..63f55a9 100644
--- a/Documentation/media/dmx.h.rst.exceptions
+++ b/Documentation/media/dmx.h.rst.exceptions
@@ -54,3 +54,5 @@
 ignore symbol DMX_OUT_TAP
 ignore symbol DMX_OUT_TS_TAP
 ignore symbol DMX_OUT_TSDEMUX_TAP
+
+replace ioctl DMX_DQBUF dmx_qbuf
diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst
index d37e107..62b9a14 100644
--- a/Documentation/media/kapi/cec-core.rst
+++ b/Documentation/media/kapi/cec-core.rst
@@ -103,6 +103,7 @@
 		/* Low-level callbacks */
 		int (*adap_enable)(struct cec_adapter *adap, bool enable);
 		int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
+		int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
 		int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
 		int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
 				      u32 signal_free_time, struct cec_msg *msg);
@@ -144,6 +145,19 @@
 Note that adap_monitor_all_enable must return 0 if enable is false.
 
 
+To enable/disable the 'monitor pin' mode:
+
+.. c:function::
+	int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
+
+If enabled, then the adapter should be put in a mode to also monitor CEC pin
+changes. Not all hardware supports this and this function is only called if
+the CEC_CAP_MONITOR_PIN capability is set. This callback is optional
+(some hardware may always be in 'monitor pin' mode).
+
+Note that adap_monitor_pin_enable must return 0 if enable is false.
+
+
 To program a new logical address:
 
 .. c:function::
diff --git a/Documentation/media/kapi/dtv-ca.rst b/Documentation/media/kapi/dtv-ca.rst
index a4dd700..fded096 100644
--- a/Documentation/media/kapi/dtv-ca.rst
+++ b/Documentation/media/kapi/dtv-ca.rst
@@ -1,4 +1,4 @@
 Digital TV Conditional Access kABI
 ----------------------------------
 
-.. kernel-doc:: drivers/media/dvb-core/dvb_ca_en50221.h
+.. kernel-doc:: include/media/dvb_ca_en50221.h
diff --git a/Documentation/media/kapi/dtv-common.rst b/Documentation/media/kapi/dtv-common.rst
index 40cf103..7a9574f 100644
--- a/Documentation/media/kapi/dtv-common.rst
+++ b/Documentation/media/kapi/dtv-common.rst
@@ -7,7 +7,7 @@
 Provide some commonly-used math functions, usually required in order to
 estimate signal strength and signal to noise measurements in dB.
 
-.. kernel-doc:: drivers/media/dvb-core/dvb_math.h
+.. kernel-doc:: include/media/dvb_math.h
 
 
 DVB devices
@@ -15,7 +15,7 @@
 
 Those functions are responsible for handling the DVB device nodes.
 
-.. kernel-doc:: drivers/media/dvb-core/dvbdev.h
+.. kernel-doc:: include/media/dvbdev.h
 
 Digital TV Ring buffer
 ~~~~~~~~~~~~~~~~~~~~~~
@@ -52,4 +52,9 @@
      Resetting the buffer counts as a read and write operation.
      Two or more writers must be locked against each other.
 
-.. kernel-doc:: drivers/media/dvb-core/dvb_ringbuffer.h
+.. kernel-doc:: include/media/dvb_ringbuffer.h
+
+Digital TV VB2 handler
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/media/dvb_vb2.h
diff --git a/Documentation/media/kapi/dtv-demux.rst b/Documentation/media/kapi/dtv-demux.rst
index 7aa865a..2485713 100644
--- a/Documentation/media/kapi/dtv-demux.rst
+++ b/Documentation/media/kapi/dtv-demux.rst
@@ -8,7 +8,7 @@
 registering low-level, hardware specific driver to a hardware independent
 demux layer. It is only of interest for Digital TV device driver writers.
 The header file for this kABI is named ``demux.h`` and located in
-``drivers/media/dvb-core``.
+``include/media``.
 
 The demux kABI should be implemented for each demux in the system. It is
 used to select the TS source of a demux and to manage the demux resources.
@@ -69,14 +69,14 @@
 Digital TV Demux device registration functions and data structures
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. kernel-doc:: drivers/media/dvb-core/dmxdev.h
+.. kernel-doc:: include/media/dmxdev.h
 
 High-level Digital TV demux interface
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. kernel-doc:: drivers/media/dvb-core/dvb_demux.h
+.. kernel-doc:: include/media/dvb_demux.h
 
 Driver-internal low-level hardware specific driver demux interface
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. kernel-doc:: drivers/media/dvb-core/demux.h
+.. kernel-doc:: include/media/demux.h
diff --git a/Documentation/media/kapi/dtv-frontend.rst b/Documentation/media/kapi/dtv-frontend.rst
index f1a2fda..472650c 100644
--- a/Documentation/media/kapi/dtv-frontend.rst
+++ b/Documentation/media/kapi/dtv-frontend.rst
@@ -8,7 +8,7 @@
 registering low-level, hardware specific driver to a hardware independent
 frontend layer. It is only of interest for Digital TV device driver writers.
 The header file for this API is named ``dvb_frontend.h`` and located in
-``drivers/media/dvb-core``.
+``include/media/``.
 
 Demodulator driver
 ^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@
 hardware. Such driver should implement :c:type:`dvb_frontend_ops`, with
 tells what type of digital TV standards are supported, and points to a
 series of functions that allow the DVB core to command the hardware via
-the code under ``drivers/media/dvb-core/dvb_frontend.c``.
+the code under ``include/media/dvb_frontend.c``.
 
 A typical example of such struct in a driver ``foo`` is::
 
@@ -118,7 +118,7 @@
 
 .. |delta|   unicode:: U+00394
 
-The ``drivers/media/dvb-core/dvb_frontend.c`` has a kernel thread with is
+The ``include/media/dvb_frontend.c`` has a kernel thread with is
 responsible for tuning the device. It supports multiple algorithms to
 detect a channel, as defined at enum :c:func:`dvbfe_algo`.
 
@@ -440,4 +440,4 @@
 Digital TV Frontend functions and types
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. kernel-doc:: drivers/media/dvb-core/dvb_frontend.h
+.. kernel-doc:: include/media/dvb_frontend.h
diff --git a/Documentation/media/kapi/dtv-net.rst b/Documentation/media/kapi/dtv-net.rst
index ced991b..158c7cb 100644
--- a/Documentation/media/kapi/dtv-net.rst
+++ b/Documentation/media/kapi/dtv-net.rst
@@ -1,4 +1,4 @@
 Digital TV Network kABI
 -----------------------
 
-.. kernel-doc:: drivers/media/dvb-core/dvb_net.h
+.. kernel-doc:: include/media/dvb_net.h
diff --git a/Documentation/media/kapi/rc-core.rst b/Documentation/media/kapi/rc-core.rst
index a458958..4759f02 100644
--- a/Documentation/media/kapi/rc-core.rst
+++ b/Documentation/media/kapi/rc-core.rst
@@ -4,11 +4,83 @@
 Remote Controller core
 ~~~~~~~~~~~~~~~~~~~~~~
 
+The remote controller core implements infrastructure to receive and send
+remote controller keyboard keystrokes and mouse events.
+
+Every time a key is pressed on a remote controller, a scan code is produced.
+Also, on most hardware, keeping a key pressed for more than a few dozens of
+milliseconds produce a repeat key event. That's somewhat similar to what
+a normal keyboard or mouse is handled internally on Linux\ [#f1]_. So, the
+remote controller core is implemented on the top of the linux input/evdev
+interface.
+
+.. [#f1]
+
+   The main difference is that, on keyboard events, the keyboard controller
+   produces one event for a key press and another one for key release. On
+   infrared-based remote controllers, there's no key release event. Instead,
+   an extra code is produced to indicate key repeats.
+
+However, most of the remote controllers use infrared (IR) to transmit signals.
+As there are several protocols used to modulate infrared signals, one
+important part of the core is dedicated to adjust the driver and the core
+system to support the infrared protocol used by the emitter.
+
+The infrared transmission is done by blinking a infrared emitter using a
+carrier. The carrier can be switched on or off by the IR transmitter
+hardware. When the carrier is switched on, it is called *PULSE*.
+When the carrier is switched off, it is called *SPACE*.
+
+In other words, a typical IR transmission can be viewed as a sequence of
+*PULSE* and *SPACE* events, each with a given duration.
+
+The carrier parameters (frequency, duty cycle) and the intervals for
+*PULSE* and *SPACE* events depend on the protocol.
+For example, the NEC protocol uses a carrier of 38kHz, and transmissions
+start with a 9ms *PULSE* and a 4.5ms SPACE. It then transmits 16 bits of
+scan code, being 8 bits for address (usually it is a fixed number for a
+given remote controller), followed by 8 bits of code. A bit "1" is modulated
+with 560µs *PULSE* followed by 1690µs *SPACE* and a bit "0"  is modulated
+with 560µs *PULSE* followed by 560µs *SPACE*.
+
+At receiver, a simple low-pass filter can be used to convert the received
+signal in a sequence of *PULSE/SPACE* events, filtering out the carrier
+frequency. Due to that, the receiver doesn't care about the carrier's
+actual frequency parameters: all it has to do is to measure the amount
+of time it receives *PULSE/SPACE* events.
+So, a simple IR receiver hardware will just provide a sequence of timings
+for those events to the Kernel. The drivers for hardware with such kind of
+receivers are identified by  ``RC_DRIVER_IR_RAW``, as defined by
+:c:type:`rc_driver_type`\ [#f2]_. Other hardware come with a
+microcontroller that decode the *PULSE/SPACE* sequence and return scan
+codes to the Kernel. Such kind of receivers are identified
+by ``RC_DRIVER_SCANCODE``.
+
+.. [#f2]
+
+   The RC core also supports devices that have just IR emitters,
+   without any receivers. Right now, all such devices work only in
+   raw TX mode. Such kind of hardware is identified as
+   ``RC_DRIVER_IR_RAW_TX``.
+
+When the RC core receives events produced by ``RC_DRIVER_IR_RAW`` IR
+receivers, it needs to decode the IR protocol, in order to obtain the
+corresponding scan code. The protocols supported by the RC core are
+defined at enum :c:type:`rc_proto`.
+
+When the RC code receives a scan code (either directly, by a driver
+of the type ``RC_DRIVER_SCANCODE``, or via its IR decoders), it needs
+to convert into a Linux input event code. This is done via a mapping
+table.
+
+The Kernel has support for mapping tables available on most media
+devices. It also supports loading a table in runtime, via some
+sysfs nodes. See the :ref:`RC userspace API <Remote_controllers_Intro>`
+for more details.
+
+Remote controller data structures and functions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 .. kernel-doc:: include/media/rc-core.h
 
 .. kernel-doc:: include/media/rc-map.h
-
-LIRC
-~~~~
-
-.. kernel-doc:: include/media/lirc_dev.h
diff --git a/Documentation/media/kapi/v4l2-dev.rst b/Documentation/media/kapi/v4l2-dev.rst
index b29aa61..7bb0505 100644
--- a/Documentation/media/kapi/v4l2-dev.rst
+++ b/Documentation/media/kapi/v4l2-dev.rst
@@ -196,11 +196,18 @@
 Which device is registered depends on the type argument. The following
 types exist:
 
-- ``VFL_TYPE_GRABBER``: ``/dev/videoX`` for video input/output devices
-- ``VFL_TYPE_VBI``: ``/dev/vbiX`` for vertical blank data (i.e. closed captions, teletext)
-- ``VFL_TYPE_RADIO``: ``/dev/radioX`` for radio tuners
-- ``VFL_TYPE_SDR``: ``/dev/swradioX`` for Software Defined Radio tuners
-- ``VFL_TYPE_TOUCH``: ``/dev/v4l-touchX`` for touch sensors
+========================== ====================	 ==============================
+:c:type:`vfl_devnode_type` Device name		 Usage
+========================== ====================	 ==============================
+``VFL_TYPE_GRABBER``       ``/dev/videoX``       for video input/output devices
+``VFL_TYPE_VBI``           ``/dev/vbiX``         for vertical blank data (i.e.
+						 closed captions, teletext)
+``VFL_TYPE_RADIO``         ``/dev/radioX``       for radio tuners
+``VFL_TYPE_SUBDEV``        ``/dev/v4l-subdevX``  for V4L2 subdevices
+``VFL_TYPE_SDR``           ``/dev/swradioX``     for Software Defined Radio
+						 (SDR) tuners
+``VFL_TYPE_TOUCH``         ``/dev/v4l-touchX``   for touch sensors
+========================== ====================	 ==============================
 
 The last argument gives you a certain amount of control over the device
 device node number used (i.e. the X in ``videoX``). Normally you will pass -1
diff --git a/Documentation/media/kapi/v4l2-event.rst b/Documentation/media/kapi/v4l2-event.rst
index 9938d21..5c7e312 100644
--- a/Documentation/media/kapi/v4l2-event.rst
+++ b/Documentation/media/kapi/v4l2-event.rst
@@ -5,27 +5,68 @@
 The V4L2 events provide a generic way to pass events to user space.
 The driver must use :c:type:`v4l2_fh` to be able to support V4L2 events.
 
-Events are defined by a type and an optional ID. The ID may refer to a V4L2
-object such as a control ID. If unused, then the ID is 0.
+Events are subscribed per-filehandle. An event specification consists of a
+``type`` and is optionally associated with an object identified through the
+``id`` field. If unused, then the ``id`` is 0. So an event is uniquely
+identified by the ``(type, id)`` tuple.
 
-When the user subscribes to an event the driver will allocate a number of
-kevent structs for that event. So every (type, ID) event tuple will have
-its own set of kevent structs. This guarantees that if a driver is generating
-lots of events of one type in a short time, then that will not overwrite
-events of another type.
+The :c:type:`v4l2_fh` struct has a list of subscribed events on its
+``subscribed`` field.
 
-But if you get more events of one type than the number of kevents that were
-reserved, then the oldest event will be dropped and the new one added.
+When the user subscribes to an event, a :c:type:`v4l2_subscribed_event`
+struct is added to :c:type:`v4l2_fh`\ ``.subscribed``, one for every
+subscribed event.
+
+Each :c:type:`v4l2_subscribed_event` struct ends with a
+:c:type:`v4l2_kevent` ringbuffer, with the size given by the caller
+of :c:func:`v4l2_event_subscribe`. This ringbuffer is used to store any events
+raised by the driver.
+
+So every ``(type, ID)`` event tuple will have its own
+:c:type:`v4l2_kevent` ringbuffer. This guarantees that if a driver is
+generating lots of events of one type in a short time, then that will
+not overwrite events of another type.
+
+But if you get more events of one type than the size of the
+:c:type:`v4l2_kevent` ringbuffer, then the oldest event will be dropped
+and the new one added.
+
+The :c:type:`v4l2_kevent` struct links into the ``available``
+list of the :c:type:`v4l2_fh` struct so :ref:`VIDIOC_DQEVENT` will
+know which event to dequeue first.
+
+Finally, if the event subscription is associated with a particular object
+such as a V4L2 control, then that object needs to know about that as well
+so that an event can be raised by that object. So the ``node`` field can
+be used to link the :c:type:`v4l2_subscribed_event` struct into a list of
+such objects.
+
+So to summarize:
+
+- struct :c:type:`v4l2_fh` has two lists: one of the ``subscribed`` events,
+  and one of the ``available`` events.
+
+- struct :c:type:`v4l2_subscribed_event` has a ringbuffer of raised
+  (pending) events of that particular type.
+
+- If struct :c:type:`v4l2_subscribed_event` is associated with a specific
+  object, then that object will have an internal list of
+  struct :c:type:`v4l2_subscribed_event` so it knows who subscribed an
+  event to that object.
 
 Furthermore, the internal struct :c:type:`v4l2_subscribed_event` has
 ``merge()`` and ``replace()`` callbacks which drivers can set. These
 callbacks are called when a new event is raised and there is no more room.
+
 The ``replace()`` callback allows you to replace the payload of the old event
 with that of the new event, merging any relevant data from the old payload
 into the new payload that replaces it. It is called when this event type has
-only one kevent struct allocated. The ``merge()`` callback allows you to merge
-the oldest event payload into that of the second-oldest event payload. It is
-called when there are two or more kevent structs allocated.
+a ringbuffer with size is one, i.e. only one event can be stored in the
+ringbuffer.
+
+The ``merge()`` callback allows you to merge the oldest event payload into
+that of the second-oldest event payload. It is called when
+the ringbuffer has size is greater than one.
 
 This way no status information is lost, just the intermediate steps leading
 up to that state.
@@ -73,7 +114,7 @@
 Callback Description
 ======== ==============================================================
 add      called when a new listener gets added (subscribing to the same
-         event twice will only cause this callback to get called once)
+	 event twice will only cause this callback to get called once)
 del      called when a listener stops listening
 replace  replace event 'old' with event 'new'.
 merge    merge event 'old' into event 'new'.
diff --git a/Documentation/media/lirc.h.rst.exceptions b/Documentation/media/lirc.h.rst.exceptions
index c130617..c6e3a35 100644
--- a/Documentation/media/lirc.h.rst.exceptions
+++ b/Documentation/media/lirc.h.rst.exceptions
@@ -28,6 +28,36 @@
 ignore define LIRC_CAN_REC_MASK
 ignore define LIRC_CAN_SET_REC_DUTY_CYCLE
 
+# Obsolete ioctls
+
+ignore ioctl LIRC_GET_LENGTH
+
+# rc protocols
+
+ignore symbol RC_PROTO_UNKNOWN
+ignore symbol RC_PROTO_OTHER
+ignore symbol RC_PROTO_RC5
+ignore symbol RC_PROTO_RC5X_20
+ignore symbol RC_PROTO_RC5_SZ
+ignore symbol RC_PROTO_JVC
+ignore symbol RC_PROTO_SONY12
+ignore symbol RC_PROTO_SONY15
+ignore symbol RC_PROTO_SONY20
+ignore symbol RC_PROTO_NEC
+ignore symbol RC_PROTO_NECX
+ignore symbol RC_PROTO_NEC32
+ignore symbol RC_PROTO_SANYO
+ignore symbol RC_PROTO_MCIR2_KBD
+ignore symbol RC_PROTO_MCIR2_MSE
+ignore symbol RC_PROTO_RC6_0
+ignore symbol RC_PROTO_RC6_6A_20
+ignore symbol RC_PROTO_RC6_6A_24
+ignore symbol RC_PROTO_RC6_6A_32
+ignore symbol RC_PROTO_RC6_MCE
+ignore symbol RC_PROTO_SHARP
+ignore symbol RC_PROTO_XMP
+ignore symbol RC_PROTO_CEC
+
 # Undocumented macros
 
 ignore define PULSE_BIT
@@ -40,3 +70,4 @@
 ignore define LIRC_MODE2_MASK
 
 ignore define LIRC_MODE_RAW
+ignore define LIRC_MODE_LIRCCODE
diff --git a/Documentation/media/uapi/dvb/dmx-expbuf.rst b/Documentation/media/uapi/dvb/dmx-expbuf.rst
new file mode 100644
index 0000000..2d96cfe
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-expbuf.rst
@@ -0,0 +1,88 @@
+.. _DMX_EXPBUF:
+
+****************
+ioctl DMX_EXPBUF
+****************
+
+Name
+====
+
+DMX_EXPBUF - Export a buffer as a DMABUF file descriptor.
+
+.. warning:: this API is still experimental
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, DMX_EXPBUF, struct dmx_exportbuffer *argp )
+    :name: DMX_EXPBUF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <dmx_fopen>`.
+
+``argp``
+    Pointer to struct :c:type:`dmx_exportbuffer`.
+
+
+Description
+===========
+
+This ioctl is an extension to the memory mapping I/O method.
+It can be used to export a buffer as a DMABUF file at any time after
+buffers have been allocated with the :ref:`DMX_REQBUFS` ioctl.
+
+To export a buffer, applications fill struct :c:type:`dmx_exportbuffer`.
+Applications must set the ``index`` field. Valid index numbers
+range from zero to the number of buffers allocated with :ref:`DMX_REQBUFS`
+(struct :c:type:`dmx_requestbuffers` ``count``) minus one.
+Additional flags may be posted in the ``flags`` field. Refer to a manual
+for open() for details. Currently only O_CLOEXEC, O_RDONLY, O_WRONLY,
+and O_RDWR are supported.
+All other fields must be set to zero. In the
+case of multi-planar API, every plane is exported separately using
+multiple :ref:`DMX_EXPBUF` calls.
+
+After calling :ref:`DMX_EXPBUF` the ``fd`` field will be set by a
+driver, on success. This is a DMABUF file descriptor. The application may
+pass it to other DMABUF-aware devices. It is recommended to close a DMABUF
+file when it is no longer used to allow the associated memory to be reclaimed.
+
+
+Examples
+========
+
+
+.. code-block:: c
+
+    int buffer_export(int v4lfd, enum dmx_buf_type bt, int index, int *dmafd)
+    {
+	struct dmx_exportbuffer expbuf;
+
+	memset(&expbuf, 0, sizeof(expbuf));
+	expbuf.type = bt;
+	expbuf.index = index;
+	if (ioctl(v4lfd, DMX_EXPBUF, &expbuf) == -1) {
+	    perror("DMX_EXPBUF");
+	    return -1;
+	}
+
+	*dmafd = expbuf.fd;
+
+	return 0;
+    }
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+EINVAL
+    A queue is not in MMAP mode or DMABUF exporting is not supported or
+    ``flags`` or ``index`` fields are invalid.
diff --git a/Documentation/media/uapi/dvb/dmx-mmap.rst b/Documentation/media/uapi/dvb/dmx-mmap.rst
new file mode 100644
index 0000000..15d1073
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-mmap.rst
@@ -0,0 +1,116 @@
+.. _dmx-mmap:
+
+*****************
+Digital TV mmap()
+*****************
+
+Name
+====
+
+dmx-mmap - Map device memory into application address space
+
+.. warning:: this API is still experimental
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+    #include <sys/mman.h>
+
+
+.. c:function:: void *mmap( void *start, size_t length, int prot, int flags, int fd, off_t offset )
+    :name: dmx-mmap
+
+Arguments
+=========
+
+``start``
+    Map the buffer to this address in the application's address space.
+    When the ``MAP_FIXED`` flag is specified, ``start`` must be a
+    multiple of the pagesize and mmap will fail when the specified
+    address cannot be used. Use of this option is discouraged;
+    applications should just specify a ``NULL`` pointer here.
+
+``length``
+    Length of the memory area to map. This must be a multiple of the
+    DVB packet length (188, on most drivers).
+
+``prot``
+    The ``prot`` argument describes the desired memory protection.
+    Regardless of the device type and the direction of data exchange it
+    should be set to ``PROT_READ`` | ``PROT_WRITE``, permitting read
+    and write access to image buffers. Drivers should support at least
+    this combination of flags.
+
+``flags``
+    The ``flags`` parameter specifies the type of the mapped object,
+    mapping options and whether modifications made to the mapped copy of
+    the page are private to the process or are to be shared with other
+    references.
+
+    ``MAP_FIXED`` requests that the driver selects no other address than
+    the one specified. If the specified address cannot be used,
+    :ref:`mmap() <dmx-mmap>` will fail. If ``MAP_FIXED`` is specified,
+    ``start`` must be a multiple of the pagesize. Use of this option is
+    discouraged.
+
+    One of the ``MAP_SHARED`` or ``MAP_PRIVATE`` flags must be set.
+    ``MAP_SHARED`` allows applications to share the mapped memory with
+    other (e. g. child-) processes.
+
+    .. note::
+
+       The Linux Digital TV applications should not set the
+       ``MAP_PRIVATE``, ``MAP_DENYWRITE``, ``MAP_EXECUTABLE`` or ``MAP_ANON``
+       flags.
+
+``fd``
+    File descriptor returned by :ref:`open() <dmx_fopen>`.
+
+``offset``
+    Offset of the buffer in device memory, as returned by
+    :ref:`DMX_QUERYBUF` ioctl.
+
+
+Description
+===========
+
+The :ref:`mmap() <dmx-mmap>` function asks to map ``length`` bytes starting at
+``offset`` in the memory of the device specified by ``fd`` into the
+application address space, preferably at address ``start``. This latter
+address is a hint only, and is usually specified as 0.
+
+Suitable length and offset parameters are queried with the
+:ref:`DMX_QUERYBUF` ioctl. Buffers must be allocated with the
+:ref:`DMX_REQBUFS` ioctl before they can be queried.
+
+To unmap buffers the :ref:`munmap() <dmx-munmap>` function is used.
+
+
+Return Value
+============
+
+On success :ref:`mmap() <dmx-mmap>` returns a pointer to the mapped buffer. On
+error ``MAP_FAILED`` (-1) is returned, and the ``errno`` variable is set
+appropriately. Possible error codes are:
+
+EBADF
+    ``fd`` is not a valid file descriptor.
+
+EACCES
+    ``fd`` is not open for reading and writing.
+
+EINVAL
+    The ``start`` or ``length`` or ``offset`` are not suitable. (E. g.
+    they are too large, or not aligned on a ``PAGESIZE`` boundary.)
+
+    The ``flags`` or ``prot`` value is not supported.
+
+    No buffers have been allocated with the
+    :ref:`DMX_REQBUFS` ioctl.
+
+ENOMEM
+    Not enough physical or virtual memory was available to complete the
+    request.
diff --git a/Documentation/media/uapi/dvb/dmx-munmap.rst b/Documentation/media/uapi/dvb/dmx-munmap.rst
new file mode 100644
index 0000000..d772187
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-munmap.rst
@@ -0,0 +1,54 @@
+.. _dmx-munmap:
+
+************
+DVB munmap()
+************
+
+Name
+====
+
+dmx-munmap - Unmap device memory
+
+.. warning:: This API is still experimental.
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+    #include <unistd.h>
+    #include <sys/mman.h>
+
+
+.. c:function:: int munmap( void *start, size_t length )
+    :name: dmx-munmap
+
+Arguments
+=========
+
+``start``
+    Address of the mapped buffer as returned by the
+    :ref:`mmap() <dmx-mmap>` function.
+
+``length``
+    Length of the mapped buffer. This must be the same value as given to
+    :ref:`mmap() <dmx-mmap>`.
+
+
+Description
+===========
+
+Unmaps a previously with the :ref:`mmap() <dmx-mmap>` function mapped
+buffer and frees it, if possible.
+
+
+Return Value
+============
+
+On success :ref:`munmap() <dmx-munmap>` returns 0, on failure -1 and the
+``errno`` variable is set appropriately:
+
+EINVAL
+    The ``start`` or ``length`` is incorrect, or no buffers have been
+    mapped yet.
diff --git a/Documentation/media/uapi/dvb/dmx-qbuf.rst b/Documentation/media/uapi/dvb/dmx-qbuf.rst
new file mode 100644
index 0000000..b48c493
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-qbuf.rst
@@ -0,0 +1,83 @@
+.. _DMX_QBUF:
+
+*************************
+ioctl DMX_QBUF, DMX_DQBUF
+*************************
+
+Name
+====
+
+DMX_QBUF - DMX_DQBUF - Exchange a buffer with the driver
+
+.. warning:: this API is still experimental
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, DMX_QBUF, struct dmx_buffer *argp )
+    :name: DMX_QBUF
+
+.. c:function:: int ioctl( int fd, DMX_DQBUF, struct dmx_buffer *argp )
+    :name: DMX_DQBUF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <dmx_fopen>`.
+
+``argp``
+    Pointer to struct :c:type:`dmx_buffer`.
+
+
+Description
+===========
+
+Applications call the ``DMX_QBUF`` ioctl to enqueue an empty
+(capturing) or filled (output) buffer in the driver's incoming queue.
+The semantics depend on the selected I/O method.
+
+To enqueue a buffer applications set the ``index`` field. Valid index
+numbers range from zero to the number of buffers allocated with
+:ref:`DMX_REQBUFS` (struct :c:type:`dmx_requestbuffers` ``count``) minus
+one. The contents of the struct :c:type:`dmx_buffer` returned
+by a :ref:`DMX_QUERYBUF` ioctl will do as well.
+
+When ``DMX_QBUF`` is called with a pointer to this structure, it locks the
+memory pages of the buffer in physical memory, so they cannot be swapped
+out to disk. Buffers remain locked until dequeued, until the
+the device is closed.
+
+Applications call the ``DMX_DQBUF`` ioctl to dequeue a filled
+(capturing) buffer from the driver's outgoing queue. They just set the ``reserved`` field array to zero. When ``DMX_DQBUF`` is called with a
+pointer to this structure, the driver fills the remaining fields or
+returns an error code.
+
+By default ``DMX_DQBUF`` blocks when no buffer is in the outgoing
+queue. When the ``O_NONBLOCK`` flag was given to the
+:ref:`open() <dmx_fopen>` function, ``DMX_DQBUF`` returns
+immediately with an ``EAGAIN`` error code when no buffer is available.
+
+The struct :c:type:`dmx_buffer` structure is specified in
+:ref:`buffer`.
+
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+EAGAIN
+    Non-blocking I/O has been selected using ``O_NONBLOCK`` and no
+    buffer was in the outgoing queue.
+
+EINVAL
+    The ``index`` is out of bounds, or no buffers have been allocated yet.
+
+EIO
+    ``DMX_DQBUF`` failed due to an internal error. Can also indicate
+    temporary problems like signal loss or CRC errors.
diff --git a/Documentation/media/uapi/dvb/dmx-querybuf.rst b/Documentation/media/uapi/dvb/dmx-querybuf.rst
new file mode 100644
index 0000000..89481e2
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-querybuf.rst
@@ -0,0 +1,63 @@
+.. _DMX_QUERYBUF:
+
+******************
+ioctl DMX_QUERYBUF
+******************
+
+Name
+====
+
+DMX_QUERYBUF - Query the status of a buffer
+
+.. warning:: this API is still experimental
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, DMX_QUERYBUF, struct dvb_buffer *argp )
+    :name: DMX_QUERYBUF
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <dmx_fopen>`.
+
+``argp``
+    Pointer to struct :c:type:`dvb_buffer`.
+
+
+Description
+===========
+
+This ioctl is part of the mmap streaming I/O method. It can
+be used to query the status of a buffer at any time after buffers have
+been allocated with the :ref:`DMX_REQBUFS` ioctl.
+
+Applications set the ``index`` field. Valid index numbers range from zero
+to the number of buffers allocated with :ref:`DMX_REQBUFS`
+(struct :c:type:`dvb_requestbuffers` ``count``) minus one.
+
+After calling :ref:`DMX_QUERYBUF` with a pointer to this structure,
+drivers return an error code or fill the rest of the structure.
+
+On success, the ``offset`` will contain the offset of the buffer from the
+start of the device memory, the ``length`` field its size, and the
+``bytesused`` the number of bytes occupied by data in the buffer (payload).
+
+Return Value
+============
+
+On success 0 is returned, the ``offset`` will contain the offset of the
+buffer from the start of the device memory, the ``length`` field its size,
+and the ``bytesused`` the number of bytes occupied by data in the buffer
+(payload).
+
+On error it returns -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+EINVAL
+    The ``index`` is out of bounds.
diff --git a/Documentation/media/uapi/dvb/dmx-reqbufs.rst b/Documentation/media/uapi/dvb/dmx-reqbufs.rst
new file mode 100644
index 0000000..14b80d6
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-reqbufs.rst
@@ -0,0 +1,74 @@
+.. _DMX_REQBUFS:
+
+*****************
+ioctl DMX_REQBUFS
+*****************
+
+Name
+====
+
+DMX_REQBUFS - Initiate Memory Mapping and/or DMA buffer I/O
+
+.. warning:: this API is still experimental
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, DMX_REQBUFS, struct dmx_requestbuffers *argp )
+    :name: DMX_REQBUFS
+
+
+Arguments
+=========
+
+``fd``
+    File descriptor returned by :ref:`open() <dmx_fopen>`.
+
+``argp``
+    Pointer to struct :c:type:`dmx_requestbuffers`.
+
+Description
+===========
+
+This ioctl is used to initiate a memory mapped or DMABUF based demux I/O.
+
+Memory mapped buffers are located in device memory and must be allocated
+with this ioctl before they can be mapped into the application's address
+space. User buffers are allocated by applications themselves, and this
+ioctl is merely used to switch the driver into user pointer I/O mode and
+to setup some internal structures. Similarly, DMABUF buffers are
+allocated by applications through a device driver, and this ioctl only
+configures the driver into DMABUF I/O mode without performing any direct
+allocation.
+
+To allocate device buffers applications initialize all fields of the
+struct :c:type:`dmx_requestbuffers` structure. They set the  ``count`` field
+to the desired number of buffers,  and ``size`` to the size of each
+buffer.
+
+When the ioctl is called with a pointer to this structure, the driver will
+attempt to allocate the requested number of buffers and it stores the actual
+number allocated in the ``count`` field. The ``count`` can be smaller than the number requested, even zero, when the driver runs out of free memory. A larger
+number is also possible when the driver requires more buffers to
+function correctly. The actual allocated buffer size can is returned
+at ``size``, and can be smaller than what's requested.
+
+When this I/O method is not supported, the ioctl returns an ``EOPNOTSUPP``
+error code.
+
+Applications can call :ref:`DMX_REQBUFS` again to change the number of
+buffers, however this cannot succeed when any buffers are still mapped.
+A ``count`` value of zero frees all buffers, after aborting or finishing
+any DMA in progress.
+
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+EOPNOTSUPP
+    The  the requested I/O method is not supported.
diff --git a/Documentation/media/uapi/dvb/dmx_fcalls.rst b/Documentation/media/uapi/dvb/dmx_fcalls.rst
index a172891..4c391cf 100644
--- a/Documentation/media/uapi/dvb/dmx_fcalls.rst
+++ b/Documentation/media/uapi/dvb/dmx_fcalls.rst
@@ -13,6 +13,8 @@
     dmx-fclose
     dmx-fread
     dmx-fwrite
+    dmx-mmap
+    dmx-munmap
     dmx-start
     dmx-stop
     dmx-set-filter
@@ -22,3 +24,7 @@
     dmx-get-pes-pids
     dmx-add-pid
     dmx-remove-pid
+    dmx-reqbufs
+    dmx-querybuf
+    dmx-expbuf
+    dmx-qbuf
diff --git a/Documentation/media/uapi/dvb/fe_property_parameters.rst b/Documentation/media/uapi/dvb/fe_property_parameters.rst
index 6eef507..3524dca 100644
--- a/Documentation/media/uapi/dvb/fe_property_parameters.rst
+++ b/Documentation/media/uapi/dvb/fe_property_parameters.rst
@@ -987,3 +987,21 @@
 1, LNA on
 
 use the special macro LNA_AUTO to set LNA auto
+
+
+.. _DTV-SCRAMBLING-SEQUENCE-INDEX:
+
+DTV_SCRAMBLING_SEQUENCE_INDEX
+=============================
+
+Used on DVB-S2.
+
+This 18 bit field, when present, carries the index of the DVB-S2 physical
+layer scrambling sequence as defined in clause 5.5.4 of EN 302 307.
+There is no explicit signalling method to convey scrambling sequence index
+to the receiver. If S2 satellite delivery system descriptor is available
+it can be used to read the scrambling sequence index (EN 300 468 table 41).
+
+By default, gold scrambling sequence index 0 is used.
+
+The valid scrambling sequence index range is from 0 to 262142.
diff --git a/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst b/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst
index 1f40399..2929e69 100644
--- a/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst
+++ b/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst
@@ -60,6 +60,8 @@
 
 -  :ref:`DTV_STREAM_ID <DTV-STREAM-ID>`
 
+-  :ref:`DTV_SCRAMBLING_SEQUENCE_INDEX <DTV-SCRAMBLING-SEQUENCE-INDEX>`
+
 In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
 are also valid.
 
diff --git a/Documentation/media/uapi/rc/lirc-dev-intro.rst b/Documentation/media/uapi/rc/lirc-dev-intro.rst
index d1936ee..3a74fec 100644
--- a/Documentation/media/uapi/rc/lirc-dev-intro.rst
+++ b/Documentation/media/uapi/rc/lirc-dev-intro.rst
@@ -6,11 +6,12 @@
 Introduction
 ************
 
-The LIRC device interface is a bi-directional interface for transporting
-raw IR data between userspace and kernelspace. Fundamentally, it is just
-a chardev (/dev/lircX, for X = 0, 1, 2, ...), with a number of standard
-struct file_operations defined on it. With respect to transporting raw
-IR data to and fro, the essential fops are read, write and ioctl.
+LIRC stands for Linux Infrared Remote Control. The LIRC device interface is
+a bi-directional interface for transporting raw IR and decoded scancodes
+data between userspace and kernelspace. Fundamentally, it is just a chardev
+(/dev/lircX, for X = 0, 1, 2, ...), with a number of standard struct
+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.
 
 Example dmesg output upon a driver registering w/LIRC:
 
@@ -18,7 +19,7 @@
 
     $ dmesg |grep lirc_dev
     lirc_dev: IR Remote Control driver registered, major 248
-    rc rc0: lirc_dev: driver ir-lirc-codec (mceusb) registered at minor = 0
+    rc rc0: lirc_dev: driver mceusb registered at minor = 0
 
 What you should see for a chardev:
 
@@ -36,6 +37,43 @@
 LIRC supports some modes of receiving and sending IR codes, as shown
 on the following table.
 
+.. _lirc-mode-scancode:
+.. _lirc-scancode-flag-toggle:
+.. _lirc-scancode-flag-repeat:
+
+``LIRC_MODE_SCANCODE``
+
+    This mode is for both sending and receiving IR.
+
+    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.
+
+    For receiving, you read ``struct lirc_scancode`` from the lirc device,
+    with ``scancode`` set to the received scancode and the IR protocol
+    :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``.
+
+    The ``flags`` can have ``LIRC_SCANCODE_FLAG_TOGGLE`` set if the toggle
+    bit is set in protocols that support it (e.g. rc-5 and rc-6), or
+    ``LIRC_SCANCODE_FLAG_REPEAT`` for when a repeat is received for protocols
+    that support it (e.g. nec).
+
+    In the Sanyo and NEC protocol, if you hold a button on remote, rather than
+    repeating the entire scancode, the remote sends a shorter message with
+    no scancode, which just means button is held, a "repeat". When this is
+    received, the ``LIRC_SCANCODE_FLAG_REPEAT`` is set and the scancode and
+    keycode is repeated.
+
+    With nec, there is no way to distinguish "button hold" from "repeatedly
+    pressing the same button". The rc-5 and rc-6 protocols have a toggle bit.
+    When a button is released and pressed again, the toggle bit is inverted.
+    If the toggle bit is set, the ``LIRC_SCANCODE_FLAG_TOGGLE`` is set.
+
+    The ``timestamp`` field is filled with the time nanoseconds
+    (in ``CLOCK_MONOTONIC``) when the scancode was decoded.
+
 .. _lirc-mode-mode2:
 
 ``LIRC_MODE_MODE2``
@@ -72,21 +110,6 @@
         this packet will be sent, with the number of microseconds with
         no IR.
 
-.. _lirc-mode-lirccode:
-
-``LIRC_MODE_LIRCCODE``
-
-    This mode can be used for IR receive and send.
-
-    The IR signal is decoded internally by the receiver, or encoded by the
-    transmitter. The LIRC interface represents the scancode as byte string,
-    which might not be a u32, it can be any length. The value is entirely
-    driver dependent. This mode is used by some older lirc drivers.
-
-    The length of each code depends on the driver, which can be retrieved
-    with :ref:`lirc_get_length`. This length is used both
-    for transmitting and receiving IR.
-
 .. _lirc-mode-pulse:
 
 ``LIRC_MODE_PULSE``
@@ -99,3 +122,13 @@
     of entries.
 
     This mode is used only for IR send.
+
+
+**************************
+Remote Controller protocol
+**************************
+
+An enum :c:type:`rc_proto` in the :ref:`lirc_header` lists all the
+supported IR protocols:
+
+.. kernel-doc:: include/uapi/linux/lirc.h
diff --git a/Documentation/media/uapi/rc/lirc-func.rst b/Documentation/media/uapi/rc/lirc-func.rst
index 9b5a772..ddb4620 100644
--- a/Documentation/media/uapi/rc/lirc-func.rst
+++ b/Documentation/media/uapi/rc/lirc-func.rst
@@ -18,7 +18,6 @@
     lirc-set-send-duty-cycle
     lirc-get-timeout
     lirc-set-rec-timeout
-    lirc-get-length
     lirc-set-rec-carrier
     lirc-set-rec-carrier-range
     lirc-set-send-carrier
diff --git a/Documentation/media/uapi/rc/lirc-get-features.rst b/Documentation/media/uapi/rc/lirc-get-features.rst
index 64f89a4..889a880 100644
--- a/Documentation/media/uapi/rc/lirc-get-features.rst
+++ b/Documentation/media/uapi/rc/lirc-get-features.rst
@@ -55,15 +55,24 @@
 
 ``LIRC_CAN_REC_MODE2``
 
-    The driver is capable of receiving using
-    :ref:`LIRC_MODE_MODE2 <lirc-mode-MODE2>`.
+    This is raw IR driver for receiving. This means that
+    :ref:`LIRC_MODE_MODE2 <lirc-mode-MODE2>` is used. This also implies
+    that :ref:`LIRC_MODE_SCANCODE <lirc-mode-SCANCODE>` is also supported,
+    as long as the kernel is recent enough. Use the
+    :ref:`lirc_set_rec_mode` to switch modes.
 
 .. _LIRC-CAN-REC-LIRCCODE:
 
 ``LIRC_CAN_REC_LIRCCODE``
 
-    The driver is capable of receiving using
-    :ref:`LIRC_MODE_LIRCCODE <lirc-mode-LIRCCODE>`.
+    Unused. Kept just to avoid breaking uAPI.
+
+.. _LIRC-CAN-REC-SCANCODE:
+
+``LIRC_CAN_REC_SCANCODE``
+
+    This is a scancode driver for receiving. This means that
+    :ref:`LIRC_MODE_SCANCODE <lirc-mode-SCANCODE>` is used.
 
 .. _LIRC-CAN-SET-SEND-CARRIER:
 
@@ -157,7 +166,10 @@
 ``LIRC_CAN_SEND_PULSE``
 
     The driver supports sending (also called as IR blasting or IR TX) using
-    :ref:`LIRC_MODE_PULSE <lirc-mode-pulse>`.
+    :ref:`LIRC_MODE_PULSE <lirc-mode-pulse>`. This implies that
+    :ref:`LIRC_MODE_SCANCODE <lirc-mode-SCANCODE>` is also supported for
+    transmit, as long as the kernel is recent enough. Use the
+    :ref:`lirc_set_send_mode` to switch modes.
 
 .. _LIRC-CAN-SEND-MODE2:
 
@@ -170,8 +182,7 @@
 
 ``LIRC_CAN_SEND_LIRCCODE``
 
-    The driver supports sending (also called as IR blasting or IR TX) using
-    :ref:`LIRC_MODE_LIRCCODE <lirc-mode-LIRCCODE>`.
+    Unused. Kept just to avoid breaking uAPI.
 
 
 Return Value
diff --git a/Documentation/media/uapi/rc/lirc-get-length.rst b/Documentation/media/uapi/rc/lirc-get-length.rst
deleted file mode 100644
index 3990af5..0000000
--- a/Documentation/media/uapi/rc/lirc-get-length.rst
+++ /dev/null
@@ -1,44 +0,0 @@
-.. -*- coding: utf-8; mode: rst -*-
-
-.. _lirc_get_length:
-
-*********************
-ioctl LIRC_GET_LENGTH
-*********************
-
-Name
-====
-
-LIRC_GET_LENGTH - Retrieves the code length in bits.
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_GET_LENGTH, __u32 *length )
-    :name: LIRC_GET_LENGTH
-
-Arguments
-=========
-
-``fd``
-    File descriptor returned by open().
-
-``length``
-    length, in bits
-
-
-Description
-===========
-
-Retrieves the code length in bits (only for
-:ref:`LIRC_MODE_LIRCCODE <lirc-mode-lirccode>`).
-Reads on the device must be done in blocks matching the bit count.
-The bit could should be rounded up so that it matches full bytes.
-
-
-Return Value
-============
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/rc/lirc-get-rec-mode.rst b/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
index a4eb6c0..2722118 100644
--- a/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
+++ b/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
@@ -10,15 +10,15 @@
 Name
 ====
 
-LIRC_GET_REC_MODE/LIRC_SET_REC_MODE - Get/set supported receive modes.
+LIRC_GET_REC_MODE/LIRC_SET_REC_MODE - Get/set current receive mode.
 
 Synopsis
 ========
 
-.. c:function:: int ioctl( int fd, LIRC_GET_REC_MODE, __u32 rx_modes)
+.. c:function:: int ioctl( int fd, LIRC_GET_REC_MODE, __u32 *mode)
 	:name: LIRC_GET_REC_MODE
 
-.. c:function:: int ioctl( int fd, LIRC_SET_REC_MODE, __u32 rx_modes)
+.. c:function:: int ioctl( int fd, LIRC_SET_REC_MODE, __u32 *mode)
 	:name: LIRC_SET_REC_MODE
 
 Arguments
@@ -27,20 +27,41 @@
 ``fd``
     File descriptor returned by open().
 
-``rx_modes``
-    Bitmask with the supported transmit modes.
+``mode``
+    Mode used for receive.
 
 Description
 ===========
 
-Get/set supported receive modes. Only :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`
-and :ref:`LIRC_MODE_LIRCCODE <lirc-mode-lirccode>` are supported for IR
-receive. Use :ref:`lirc_get_features` to find out which modes the driver
-supports.
+Get and set the current receive mode. Only
+:ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>` and
+:ref:`LIRC_MODE_SCANCODE <lirc-mode-scancode>` are supported.
+Use :ref:`lirc_get_features` to find out which modes the driver supports.
 
 Return Value
 ============
 
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``ENODEV``
+
+       -  Device not available.
+
+    -  .. row 2
+
+       -  ``ENOTTY``
+
+       -  Device does not support receiving.
+
+    -  .. row 3
+
+       -  ``EINVAL``
+
+       -  Invalid mode or invalid mode for this device.
diff --git a/Documentation/media/uapi/rc/lirc-get-send-mode.rst b/Documentation/media/uapi/rc/lirc-get-send-mode.rst
index a169b23..c44e61a7 100644
--- a/Documentation/media/uapi/rc/lirc-get-send-mode.rst
+++ b/Documentation/media/uapi/rc/lirc-get-send-mode.rst
@@ -10,15 +10,15 @@
 Name
 ====
 
-LIRC_GET_SEND_MODE/LIRC_SET_SEND_MODE - Get/set supported transmit mode.
+LIRC_GET_SEND_MODE/LIRC_SET_SEND_MODE - Get/set current transmit mode.
 
 Synopsis
 ========
 
-.. c:function:: int ioctl( int fd, LIRC_GET_SEND_MODE, __u32 *tx_modes )
+.. c:function:: int ioctl( int fd, LIRC_GET_SEND_MODE, __u32 *mode )
     :name: LIRC_GET_SEND_MODE
 
-.. c:function:: int ioctl( int fd, LIRC_SET_SEND_MODE, __u32 *tx_modes )
+.. c:function:: int ioctl( int fd, LIRC_SET_SEND_MODE, __u32 *mode )
     :name: LIRC_SET_SEND_MODE
 
 Arguments
@@ -27,8 +27,8 @@
 ``fd``
     File descriptor returned by open().
 
-``tx_modes``
-    Bitmask with the supported transmit modes.
+``mode``
+    The mode used for transmitting.
 
 
 Description
@@ -37,13 +37,35 @@
 Get/set current transmit mode.
 
 Only :ref:`LIRC_MODE_PULSE <lirc-mode-pulse>` and
-:ref:`LIRC_MODE_LIRCCODE <lirc-mode-lirccode>` is supported by for IR send,
+:ref:`LIRC_MODE_SCANCODE <lirc-mode-scancode>` are supported by for IR send,
 depending on the driver. Use :ref:`lirc_get_features` to find out which
 modes the driver supports.
 
 Return Value
 ============
 
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+    :header-rows:  0
+    :stub-columns: 0
+
+
+    -  .. row 1
+
+       -  ``ENODEV``
+
+       -  Device not available.
+
+    -  .. row 2
+
+       -  ``ENOTTY``
+
+       -  Device does not support transmitting.
+
+    -  .. row 3
+
+       -  ``EINVAL``
+
+       -  Invalid mode or invalid mode for this device.
diff --git a/Documentation/media/uapi/rc/lirc-read.rst b/Documentation/media/uapi/rc/lirc-read.rst
index ff14a69..c024aaf 100644
--- a/Documentation/media/uapi/rc/lirc-read.rst
+++ b/Documentation/media/uapi/rc/lirc-read.rst
@@ -45,13 +45,20 @@
 is greater than ``SSIZE_MAX``, the result is unspecified.
 
 The exact format of the data depends on what :ref:`lirc_modes` a driver
-uses. Use :ref:`lirc_get_features` to get the supported mode.
+uses. Use :ref:`lirc_get_features` to get the supported mode, and use
+:ref:`lirc_set_rec_mode` set the current active mode.
 
-The generally preferred mode for receive is
-:ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`,
-in which packets containing an int value describing an IR signal are
+The mode :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>` is for raw IR,
+in which packets containing an unsigned int value describing an IR signal are
 read from the chardev.
 
+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,
+and the ``keycode`` set to the keycode or ``KEY_RESERVED``.
+
+
 Return Value
 ============
 
diff --git a/Documentation/media/uapi/rc/lirc-write.rst b/Documentation/media/uapi/rc/lirc-write.rst
index 2aad0fe..d4566b0a 100644
--- a/Documentation/media/uapi/rc/lirc-write.rst
+++ b/Documentation/media/uapi/rc/lirc-write.rst
@@ -42,21 +42,32 @@
 referenced by the file descriptor ``fd`` from the buffer starting at
 ``buf``.
 
-The exact format of the data depends on what mode a driver uses, use
-:ref:`lirc_get_features` to get the supported mode.
+The exact format of the data depends on what mode a driver is in, use
+:ref:`lirc_get_features` to get the supported modes and use
+:ref:`lirc_set_send_mode` set the mode.
 
 When in :ref:`LIRC_MODE_PULSE <lirc-mode-PULSE>` mode, the data written to
 the chardev is a pulse/space sequence of integer values. Pulses and spaces
 are only marked implicitly by their position. The data must start and end
 with a pulse, therefore, the data must always include an uneven number of
-samples. The write function must block until the data has been transmitted
+samples. The write function blocks until the data has been transmitted
 by the hardware. If more data is provided than the hardware can send, the
 driver returns ``EINVAL``.
 
+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
+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
+is transmitted by the hardware.
+
+
 Return Value
 ============
 
-On success, the number of bytes read is returned. It is not an error if
+On success, the number of bytes written is returned. It is not an error if
 this number is smaller than the number of bytes requested, or the amount
 of data required for one frame.  On error, -1 is returned, and the ``errno``
 variable is set appropriately. The generic error codes are described at the
diff --git a/Documentation/media/uapi/v4l/meta-formats.rst b/Documentation/media/uapi/v4l/meta-formats.rst
index 01e24e3..0c4e1ec 100644
--- a/Documentation/media/uapi/v4l/meta-formats.rst
+++ b/Documentation/media/uapi/v4l/meta-formats.rst
@@ -12,5 +12,6 @@
 .. toctree::
     :maxdepth: 1
 
+    pixfmt-meta-uvc
     pixfmt-meta-vsp1-hgo
     pixfmt-meta-vsp1-hgt
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst b/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst
new file mode 100644
index 0000000..b5165dc
--- /dev/null
+++ b/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst
@@ -0,0 +1,51 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _v4l2-meta-fmt-uvc:
+
+*******************************
+V4L2_META_FMT_UVC ('UVCH')
+*******************************
+
+UVC Payload Header Data
+
+
+Description
+===========
+
+This format describes standard UVC metadata, extracted from UVC packet headers
+and provided by the UVC driver through metadata video nodes. That data includes
+exact copies of the standard part of UVC Payload Header contents and auxiliary
+timing information, required for precise interpretation of timestamps, contained
+in those headers. See section "2.4.3.3 Video and Still Image Payload Headers" of
+the "UVC 1.5 Class specification" for details.
+
+Each UVC payload header can be between 2 and 12 bytes large. Buffers can
+contain multiple headers, if multiple such headers have been transmitted by the
+camera for the respective frame. However, the driver may drop headers when the
+buffer is full, when they contain no useful information (e.g. those without the
+SCR field or with that field identical to the previous header), or generally to
+perform rate limiting when the device sends a large number of headers.
+
+Each individual block contains the following fields:
+
+.. flat-table:: UVC Metadata Block
+    :widths: 1 4
+    :header-rows:  1
+    :stub-columns: 0
+
+    * - Field
+      - Description
+    * - __u64 ts;
+      - system timestamp in host byte order, measured by the driver upon
+        reception of the payload
+    * - __u16 sof;
+      - USB Frame Number in host byte order, also obtained by the driver as
+        close as possible to the above timestamp to enable correlation between
+        them
+    * - :cspan:`1` *The rest is an exact copy of the UVC payload header:*
+    * - __u8 length;
+      - length of the rest of the block, including this field
+    * - __u8 flags;
+      - Flags, indicating presence of other standard UVC fields
+    * - __u8 buf[];
+      - The rest of the header, possibly including UVC PTS and SCR fields
diff --git a/Documentation/media/uapi/v4l/pixfmt-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-rgb.rst
index 4cc2719..cf2ef7d 100644
--- a/Documentation/media/uapi/v4l/pixfmt-rgb.rst
+++ b/Documentation/media/uapi/v4l/pixfmt-rgb.rst
@@ -16,6 +16,7 @@
     pixfmt-srggb10p
     pixfmt-srggb10alaw8
     pixfmt-srggb10dpcm8
+    pixfmt-srggb10-ipu3
     pixfmt-srggb12
     pixfmt-srggb12p
     pixfmt-srggb16
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst
new file mode 100644
index 0000000..99cde50
--- /dev/null
+++ b/Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst
@@ -0,0 +1,335 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _v4l2-pix-fmt-ipu3-sbggr10:
+.. _v4l2-pix-fmt-ipu3-sgbrg10:
+.. _v4l2-pix-fmt-ipu3-sgrbg10:
+.. _v4l2-pix-fmt-ipu3-srggb10:
+
+**********************************************************************************************************************************************
+V4L2_PIX_FMT_IPU3_SBGGR10 ('ip3b'), V4L2_PIX_FMT_IPU3_SGBRG10 ('ip3g'), V4L2_PIX_FMT_IPU3_SGRBG10 ('ip3G'), V4L2_PIX_FMT_IPU3_SRGGB10 ('ip3r')
+**********************************************************************************************************************************************
+
+10-bit Bayer formats
+
+Description
+===========
+
+These four pixel formats are used by Intel IPU3 driver, they are raw
+sRGB / Bayer formats with 10 bits per sample with every 25 pixels packed
+to 32 bytes leaving 6 most significant bits padding in the last byte.
+The format is little endian.
+
+In other respects this format is similar to :ref:`V4L2-PIX-FMT-SRGGB10`.
+Below is an example of a small image in V4L2_PIX_FMT_IPU3_SBGGR10 format.
+
+**Byte Order.**
+Each cell is one byte.
+
+.. tabularcolumns:: |p{0.8cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}|
+
+.. flat-table::
+
+    * - start + 0:
+      - B\ :sub:`0000low`
+      - G\ :sub:`0001low`\ (bits 7--2)
+
+        B\ :sub:`0000high`\ (bits 1--0)
+      - B\ :sub:`0002low`\ (bits 7--4)
+
+        G\ :sub:`0001high`\ (bits 3--0)
+      - G\ :sub:`0003low`\ (bits 7--6)
+
+        B\ :sub:`0002high`\ (bits 5--0)
+    * - start + 4:
+      - G\ :sub:`0003high`
+      - B\ :sub:`0004low`
+      - G\ :sub:`0005low`\ (bits 7--2)
+
+        B\ :sub:`0004high`\ (bits 1--0)
+      - B\ :sub:`0006low`\ (bits 7--4)
+
+        G\ :sub:`0005high`\ (bits 3--0)
+    * - start + 8:
+      - G\ :sub:`0007low`\ (bits 7--6)
+
+        B\ :sub:`0006high`\ (bits 5--0)
+      - G\ :sub:`0007high`
+      - B\ :sub:`0008low`
+      - G\ :sub:`0009low`\ (bits 7--2)
+
+        B\ :sub:`0008high`\ (bits 1--0)
+    * - start + 12:
+      - B\ :sub:`0010low`\ (bits 7--4)
+
+        G\ :sub:`0009high`\ (bits 3--0)
+      - G\ :sub:`0011low`\ (bits 7--6)
+
+        B\ :sub:`0010high`\ (bits 5--0)
+      - G\ :sub:`0011high`
+      - B\ :sub:`0012low`
+    * - start + 16:
+      - G\ :sub:`0013low`\ (bits 7--2)
+
+        B\ :sub:`0012high`\ (bits 1--0)
+      - B\ :sub:`0014low`\ (bits 7--4)
+
+        G\ :sub:`0013high`\ (bits 3--0)
+      - G\ :sub:`0015low`\ (bits 7--6)
+
+        B\ :sub:`0014high`\ (bits 5--0)
+      - G\ :sub:`0015high`
+    * - start + 20
+      - B\ :sub:`0016low`
+      - G\ :sub:`0017low`\ (bits 7--2)
+
+        B\ :sub:`0016high`\ (bits 1--0)
+      - B\ :sub:`0018low`\ (bits 7--4)
+
+        G\ :sub:`0017high`\ (bits 3--0)
+      - G\ :sub:`0019low`\ (bits 7--6)
+
+        B\ :sub:`0018high`\ (bits 5--0)
+    * - start + 24:
+      - G\ :sub:`0019high`
+      - B\ :sub:`0020low`
+      - G\ :sub:`0021low`\ (bits 7--2)
+
+        B\ :sub:`0020high`\ (bits 1--0)
+      - B\ :sub:`0022low`\ (bits 7--4)
+
+        G\ :sub:`0021high`\ (bits 3--0)
+    * - start + 28:
+      - G\ :sub:`0023low`\ (bits 7--6)
+
+        B\ :sub:`0022high`\ (bits 5--0)
+      - G\ :sub:`0023high`
+      - B\ :sub:`0024low`
+      - B\ :sub:`0024high`\ (bits 1--0)
+    * - start + 32:
+      - G\ :sub:`0100low`
+      - R\ :sub:`0101low`\ (bits 7--2)
+
+        G\ :sub:`0100high`\ (bits 1--0)
+      - G\ :sub:`0102low`\ (bits 7--4)
+
+        R\ :sub:`0101high`\ (bits 3--0)
+      - R\ :sub:`0103low`\ (bits 7--6)
+
+        G\ :sub:`0102high`\ (bits 5--0)
+    * - start + 36:
+      - R\ :sub:`0103high`
+      - G\ :sub:`0104low`
+      - R\ :sub:`0105low`\ (bits 7--2)
+
+        G\ :sub:`0104high`\ (bits 1--0)
+      - G\ :sub:`0106low`\ (bits 7--4)
+
+        R\ :sub:`0105high`\ (bits 3--0)
+    * - start + 40:
+      - R\ :sub:`0107low`\ (bits 7--6)
+
+        G\ :sub:`0106high`\ (bits 5--0)
+      - R\ :sub:`0107high`
+      - G\ :sub:`0108low`
+      - R\ :sub:`0109low`\ (bits 7--2)
+
+        G\ :sub:`0108high`\ (bits 1--0)
+    * - start + 44:
+      - G\ :sub:`0110low`\ (bits 7--4)
+
+        R\ :sub:`0109high`\ (bits 3--0)
+      - R\ :sub:`0111low`\ (bits 7--6)
+
+        G\ :sub:`0110high`\ (bits 5--0)
+      - R\ :sub:`0111high`
+      - G\ :sub:`0112low`
+    * - start + 48:
+      - R\ :sub:`0113low`\ (bits 7--2)
+
+        G\ :sub:`0112high`\ (bits 1--0)
+      - G\ :sub:`0114low`\ (bits 7--4)
+
+        R\ :sub:`0113high`\ (bits 3--0)
+      - R\ :sub:`0115low`\ (bits 7--6)
+
+        G\ :sub:`0114high`\ (bits 5--0)
+      - R\ :sub:`0115high`
+    * - start + 52:
+      - G\ :sub:`0116low`
+      - R\ :sub:`0117low`\ (bits 7--2)
+
+        G\ :sub:`0116high`\ (bits 1--0)
+      - G\ :sub:`0118low`\ (bits 7--4)
+
+        R\ :sub:`0117high`\ (bits 3--0)
+      - R\ :sub:`0119low`\ (bits 7--6)
+
+        G\ :sub:`0118high`\ (bits 5--0)
+    * - start + 56:
+      - R\ :sub:`0119high`
+      - G\ :sub:`0120low`
+      - R\ :sub:`0121low`\ (bits 7--2)
+
+        G\ :sub:`0120high`\ (bits 1--0)
+      - G\ :sub:`0122low`\ (bits 7--4)
+
+        R\ :sub:`0121high`\ (bits 3--0)
+    * - start + 60:
+      - R\ :sub:`0123low`\ (bits 7--6)
+
+        G\ :sub:`0122high`\ (bits 5--0)
+      - R\ :sub:`0123high`
+      - G\ :sub:`0124low`
+      - G\ :sub:`0124high`\ (bits 1--0)
+    * - start + 64:
+      - B\ :sub:`0200low`
+      - G\ :sub:`0201low`\ (bits 7--2)
+
+        B\ :sub:`0200high`\ (bits 1--0)
+      - B\ :sub:`0202low`\ (bits 7--4)
+
+        G\ :sub:`0201high`\ (bits 3--0)
+      - G\ :sub:`0203low`\ (bits 7--6)
+
+        B\ :sub:`0202high`\ (bits 5--0)
+    * - start + 68:
+      - G\ :sub:`0203high`
+      - B\ :sub:`0204low`
+      - G\ :sub:`0205low`\ (bits 7--2)
+
+        B\ :sub:`0204high`\ (bits 1--0)
+      - B\ :sub:`0206low`\ (bits 7--4)
+
+        G\ :sub:`0205high`\ (bits 3--0)
+    * - start + 72:
+      - G\ :sub:`0207low`\ (bits 7--6)
+
+        B\ :sub:`0206high`\ (bits 5--0)
+      - G\ :sub:`0207high`
+      - B\ :sub:`0208low`
+      - G\ :sub:`0209low`\ (bits 7--2)
+
+        B\ :sub:`0208high`\ (bits 1--0)
+    * - start + 76:
+      - B\ :sub:`0210low`\ (bits 7--4)
+
+        G\ :sub:`0209high`\ (bits 3--0)
+      - G\ :sub:`0211low`\ (bits 7--6)
+
+        B\ :sub:`0210high`\ (bits 5--0)
+      - G\ :sub:`0211high`
+      - B\ :sub:`0212low`
+    * - start + 80:
+      - G\ :sub:`0213low`\ (bits 7--2)
+
+        B\ :sub:`0212high`\ (bits 1--0)
+      - B\ :sub:`0214low`\ (bits 7--4)
+
+        G\ :sub:`0213high`\ (bits 3--0)
+      - G\ :sub:`0215low`\ (bits 7--6)
+
+        B\ :sub:`0214high`\ (bits 5--0)
+      - G\ :sub:`0215high`
+    * - start + 84:
+      - B\ :sub:`0216low`
+      - G\ :sub:`0217low`\ (bits 7--2)
+
+        B\ :sub:`0216high`\ (bits 1--0)
+      - B\ :sub:`0218low`\ (bits 7--4)
+
+        G\ :sub:`0217high`\ (bits 3--0)
+      - G\ :sub:`0219low`\ (bits 7--6)
+
+        B\ :sub:`0218high`\ (bits 5--0)
+    * - start + 88:
+      - G\ :sub:`0219high`
+      - B\ :sub:`0220low`
+      - G\ :sub:`0221low`\ (bits 7--2)
+
+        B\ :sub:`0220high`\ (bits 1--0)
+      - B\ :sub:`0222low`\ (bits 7--4)
+
+        G\ :sub:`0221high`\ (bits 3--0)
+    * - start + 92:
+      - G\ :sub:`0223low`\ (bits 7--6)
+
+        B\ :sub:`0222high`\ (bits 5--0)
+      - G\ :sub:`0223high`
+      - B\ :sub:`0224low`
+      - B\ :sub:`0224high`\ (bits 1--0)
+    * - start + 96:
+      - G\ :sub:`0300low`
+      - R\ :sub:`0301low`\ (bits 7--2)
+
+        G\ :sub:`0300high`\ (bits 1--0)
+      - G\ :sub:`0302low`\ (bits 7--4)
+
+        R\ :sub:`0301high`\ (bits 3--0)
+      - R\ :sub:`0303low`\ (bits 7--6)
+
+        G\ :sub:`0302high`\ (bits 5--0)
+    * - start + 100:
+      - R\ :sub:`0303high`
+      - G\ :sub:`0304low`
+      - R\ :sub:`0305low`\ (bits 7--2)
+
+        G\ :sub:`0304high`\ (bits 1--0)
+      - G\ :sub:`0306low`\ (bits 7--4)
+
+        R\ :sub:`0305high`\ (bits 3--0)
+    * - start + 104:
+      - R\ :sub:`0307low`\ (bits 7--6)
+
+        G\ :sub:`0306high`\ (bits 5--0)
+      - R\ :sub:`0307high`
+      - G\ :sub:`0308low`
+      - R\ :sub:`0309low`\ (bits 7--2)
+
+        G\ :sub:`0308high`\ (bits 1--0)
+    * - start + 108:
+      - G\ :sub:`0310low`\ (bits 7--4)
+
+        R\ :sub:`0309high`\ (bits 3--0)
+      - R\ :sub:`0311low`\ (bits 7--6)
+
+        G\ :sub:`0310high`\ (bits 5--0)
+      - R\ :sub:`0311high`
+      - G\ :sub:`0312low`
+    * - start + 112:
+      - R\ :sub:`0313low`\ (bits 7--2)
+
+        G\ :sub:`0312high`\ (bits 1--0)
+      - G\ :sub:`0314low`\ (bits 7--4)
+
+        R\ :sub:`0313high`\ (bits 3--0)
+      - R\ :sub:`0315low`\ (bits 7--6)
+
+        G\ :sub:`0314high`\ (bits 5--0)
+      - R\ :sub:`0315high`
+    * - start + 116:
+      - G\ :sub:`0316low`
+      - R\ :sub:`0317low`\ (bits 7--2)
+
+        G\ :sub:`0316high`\ (bits 1--0)
+      - G\ :sub:`0318low`\ (bits 7--4)
+
+        R\ :sub:`0317high`\ (bits 3--0)
+      - R\ :sub:`0319low`\ (bits 7--6)
+
+        G\ :sub:`0318high`\ (bits 5--0)
+    * - start + 120:
+      - R\ :sub:`0319high`
+      - G\ :sub:`0320low`
+      - R\ :sub:`0321low`\ (bits 7--2)
+
+        G\ :sub:`0320high`\ (bits 1--0)
+      - G\ :sub:`0322low`\ (bits 7--4)
+
+        R\ :sub:`0321high`\ (bits 3--0)
+    * - start + 124:
+      - R\ :sub:`0323low`\ (bits 7--6)
+
+        G\ :sub:`0322high`\ (bits 5--0)
+      - R\ :sub:`0323high`
+      - G\ :sub:`0324low`
+      - G\ :sub:`0324high`\ (bits 1--0)
diff --git a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst
index 2696380..1a034e8 100644
--- a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst
+++ b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst
@@ -267,7 +267,7 @@
 	will also be cleared.
     * - ``V4L2_DV_FL_HALF_LINE``
       - Specific to interlaced formats: if set, then the vertical
-	frontporch of field 1 (aka the odd field) is really one half-line
+	backporch of field 1 (aka the odd field) is really one half-line
 	longer and the vertical backporch of field 2 (aka the even field)
 	is really one half-line shorter, so each field has exactly the
 	same number of half-lines. Whether half-lines can be detected or
diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README
index 52844a5..ff675a1 100644
--- a/Documentation/mips/AU1xxx_IDE.README
+++ b/Documentation/mips/AU1xxx_IDE.README
@@ -56,8 +56,6 @@
 
   CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA    - enable the PIO+DBDMA mode
   CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA  - enable the MWDMA mode
-  CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - set Burstable FIFO in DBDMA
-                                           controller
 
 
 SUPPORTED IDE MODES
@@ -82,11 +80,9 @@
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_BLK_DEV_GENERIC=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_IDEDMA_PCI_AUTO=y
 CONFIG_BLK_DEV_IDE_AU1XXX=y
 CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y
 CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_AUTO=y
 
 Also define 'IDE_AU1XXX_BURSTMODE' in 'drivers/ide/mips/au1xxx-ide.c' to enable
 the burst support on DBDMA controller.
@@ -94,16 +90,13 @@
 If the used system need the USB support enable the following kernel configs for
 high IDE to USB throughput.
 
-CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDE_GENERIC=y
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_BLK_DEV_GENERIC=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_IDEDMA_PCI_AUTO=y
 CONFIG_BLK_DEV_IDE_AU1XXX=y
 CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y
 CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_AUTO=y
 
 Also undefine 'IDE_AU1XXX_BURSTMODE' in 'drivers/ide/mips/au1xxx-ide.c' to
 disable the burst support on DBDMA controller.
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 3f2c40d..a553d4e 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -508,7 +508,7 @@
 	min: Minimal size of receive buffer used by TCP sockets.
 	It is guaranteed to each TCP socket, even under moderate memory
 	pressure.
-	Default: 1 page
+	Default: 4K
 
 	default: initial size of receive buffer used by TCP sockets.
 	This value overrides net.core.rmem_default used by other protocols.
@@ -667,7 +667,7 @@
 tcp_wmem - vector of 3 INTEGERs: min, default, max
 	min: Amount of memory reserved for send buffers for TCP sockets.
 	Each TCP socket has rights to use it due to fact of its birth.
-	Default: 1 page
+	Default: 4K
 
 	default: initial size of send buffer used by TCP sockets.  This
 	value overrides net.core.wmem_default used by other protocols.
diff --git a/Documentation/process/index.rst b/Documentation/process/index.rst
index a430f6e..1c9fe65 100644
--- a/Documentation/process/index.rst
+++ b/Documentation/process/index.rst
@@ -24,6 +24,7 @@
    development-process
    submitting-patches
    coding-style
+   maintainer-pgp-guide
    email-clients
    kernel-enforcement-statement
    kernel-driver-statement
diff --git a/Documentation/process/kernel-docs.rst b/Documentation/process/kernel-docs.rst
index b8cac85..3fb28de 100644
--- a/Documentation/process/kernel-docs.rst
+++ b/Documentation/process/kernel-docs.rst
@@ -58,7 +58,7 @@
     * Title: **Linux Kernel Mailing List Glossary**
 
       :Author: various
-      :URL: http://kernelnewbies.org/glossary/
+      :URL: https://kernelnewbies.org/KernelGlossary
       :Date: rolling version
       :Keywords: glossary, terms, linux-kernel.
       :Description: From the introduction: "This glossary is intended as
diff --git a/Documentation/process/maintainer-pgp-guide.rst b/Documentation/process/maintainer-pgp-guide.rst
new file mode 100644
index 0000000..b453561
--- /dev/null
+++ b/Documentation/process/maintainer-pgp-guide.rst
@@ -0,0 +1,929 @@
+.. _pgpguide:
+
+===========================
+Kernel Maintainer PGP guide
+===========================
+
+:Author: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
+
+This document is aimed at Linux kernel developers, and especially at
+subsystem maintainers. It contains a subset of information discussed in
+the more general "`Protecting Code Integrity`_" guide published by the
+Linux Foundation. Please read that document for more in-depth discussion
+on some of the topics mentioned in this guide.
+
+.. _`Protecting Code Integrity`: https://github.com/lfit/itpol/blob/master/protecting-code-integrity.md
+
+The role of PGP in Linux Kernel development
+===========================================
+
+PGP helps ensure the integrity of the code that is produced by the Linux
+kernel development community and, to a lesser degree, establish trusted
+communication channels between developers via PGP-signed email exchange.
+
+The Linux kernel source code is available in two main formats:
+
+- Distributed source repositories (git)
+- Periodic release snapshots (tarballs)
+
+Both git repositories and tarballs carry PGP signatures of the kernel
+developers who create official kernel releases. These signatures offer a
+cryptographic guarantee that downloadable versions made available via
+kernel.org or any other mirrors are identical to what these developers
+have on their workstations. To this end:
+
+- git repositories provide PGP signatures on all tags
+- tarballs provide detached PGP signatures with all downloads
+
+.. _devs_not_infra:
+
+Trusting the developers, not infrastructure
+-------------------------------------------
+
+Ever since the 2011 compromise of core kernel.org systems, the main
+operating principle of the Kernel Archives project has been to assume
+that any part of the infrastructure can be compromised at any time. For
+this reason, the administrators have taken deliberate steps to emphasize
+that trust must always be placed with developers and never with the code
+hosting infrastructure, regardless of how good the security practices
+for the latter may be.
+
+The above guiding principle is the reason why this guide is needed. We
+want to make sure that by placing trust into developers we do not simply
+shift the blame for potential future security incidents to someone else.
+The goal is to provide a set of guidelines developers can use to create
+a secure working environment and safeguard the PGP keys used to
+establish the integrity of the Linux kernel itself.
+
+.. _pgp_tools:
+
+PGP tools
+=========
+
+Use GnuPG v2
+------------
+
+Your distro should already have GnuPG installed by default, you just
+need to verify that you are using version 2.x and not the legacy 1.4
+release -- many distributions still package both, with the default
+``gpg`` command invoking GnuPG v.1. To check, run::
+
+    $ gpg --version | head -n1
+
+If you see ``gpg (GnuPG) 1.4.x``, then you are using GnuPG v.1. Try the
+``gpg2`` command (if you don't have it, you may need to install the
+gnupg2 package)::
+
+    $ gpg2 --version | head -n1
+
+If you see ``gpg (GnuPG) 2.x.x``, then you are good to go. This guide
+will assume you have the version 2.2 of GnuPG (or later). If you are
+using version 2.0 of GnuPG, then some of the commands in this guide will
+not work, and you should consider installing the latest 2.2 version of
+GnuPG. Versions of gnupg-2.1.11 and later should be compatible for the
+purposes of this guide as well.
+
+If you have both ``gpg`` and ``gpg2`` commands, you should make sure you
+are always using GnuPG v2, not the legacy version. You can enforce this
+by setting the appropriate alias::
+
+    $ alias gpg=gpg2
+
+You can put that in your ``.bashrc`` to make sure it's always the case.
+
+Configure gpg-agent options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The GnuPG agent is a helper tool that will start automatically whenever
+you use the ``gpg`` command and run in the background with the purpose
+of caching the private key passphrase. There are two options you should
+know in order to tweak when the passphrase should be expired from cache:
+
+- ``default-cache-ttl`` (seconds): If you use the same key again before
+  the time-to-live expires, the countdown will reset for another period.
+  The default is 600 (10 minutes).
+- ``max-cache-ttl`` (seconds): Regardless of how recently you've used
+  the key since initial passphrase entry, if the maximum time-to-live
+  countdown expires, you'll have to enter the passphrase again. The
+  default is 30 minutes.
+
+If you find either of these defaults too short (or too long), you can
+edit your ``~/.gnupg/gpg-agent.conf`` file to set your own values::
+
+    # set to 30 minutes for regular ttl, and 2 hours for max ttl
+    default-cache-ttl 1800
+    max-cache-ttl 7200
+
+.. note::
+
+    It is no longer necessary to start gpg-agent manually at the
+    beginning of your shell session. You may want to check your rc files
+    to remove anything you had in place for older versions of GnuPG, as
+    it may not be doing the right thing any more.
+
+Set up a refresh cronjob
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+You will need to regularly refresh your keyring in order to get the
+latest changes on other people's public keys, which is best done with a
+daily cronjob::
+
+    @daily /usr/bin/gpg2 --refresh >/dev/null 2>&1
+
+Check the full path to your ``gpg`` or ``gpg2`` command and use the
+``gpg2`` command if regular ``gpg`` for you is the legacy GnuPG v.1.
+
+.. _master_key:
+
+Protect your master PGP key
+===========================
+
+This guide assumes that you already have a PGP key that you use for Linux
+kernel development purposes. If you do not yet have one, please see the
+"`Protecting Code Integrity`_" document mentioned earlier for guidance
+on how to create a new one.
+
+You should also make a new key if your current one is weaker than 2048 bits
+(RSA).
+
+Master key vs. Subkeys
+----------------------
+
+Subkeys are fully independent PGP keypairs that are tied to the "master"
+key using certifying key signatures (certificates). It is important to
+understand the following:
+
+1. There are no technical differences between the "master key" and "subkeys."
+2. At creation time, we assign functional limitations to each key by
+   giving it specific capabilities.
+3. A PGP key can have 4 capabilities:
+
+   - **[S]** key can be used for signing
+   - **[E]** key can be used for encryption
+   - **[A]** key can be used for authentication
+   - **[C]** key can be used for certifying other keys
+
+4. A single key may have multiple capabilities.
+5. A subkey is fully independent from the master key. A message
+   encrypted to a subkey cannot be decrypted with the master key. If you
+   lose your private subkey, it cannot be recreated from the master key
+   in any way.
+
+The key carrying the **[C]** (certify) capability is considered the
+"master" key because it is the only key that can be used to indicate
+relationship with other keys. Only the **[C]** key can be used to:
+
+- add or revoke other keys (subkeys) with S/E/A capabilities
+- add, change or revoke identities (uids) associated with the key
+- add or change the expiration date on itself or any subkey
+- sign other people's keys for web of trust purposes
+
+By default, GnuPG creates the following when generating new keys:
+
+- A master key carrying both Certify and Sign capabilities (**[SC]**)
+- A separate subkey with the Encryption capability (**[E]**)
+
+If you used the default parameters when generating your key, then that
+is what you will have. You can verify by running ``gpg --list-secret-keys``,
+for example::
+
+    sec   rsa2048 2018-01-23 [SC] [expires: 2020-01-23]
+          000000000000000000000000AAAABBBBCCCCDDDD
+    uid           [ultimate] Alice Dev <adev@kernel.org>
+    ssb   rsa2048 2018-01-23 [E] [expires: 2020-01-23]
+
+Any key carrying the **[C]** capability is your master key, regardless
+of any other capabilities it may have assigned to it.
+
+The long line under the ``sec`` entry is your key fingerprint --
+whenever you see ``[fpr]`` in the examples below, that 40-character
+string is what it refers to.
+
+Ensure your passphrase is strong
+--------------------------------
+
+GnuPG uses passphrases to encrypt your private keys before storing them on
+disk. This way, even if your ``.gnupg`` directory is leaked or stolen in
+its entirety, the attackers cannot use your private keys without first
+obtaining the passphrase to decrypt them.
+
+It is absolutely essential that your private keys are protected by a
+strong passphrase. To set it or change it, use::
+
+    $ gpg --change-passphrase [fpr]
+
+Create a separate Signing subkey
+--------------------------------
+
+Our goal is to protect your master key by moving it to offline media, so
+if you only have a combined **[SC]** key, then you should create a separate
+signing subkey::
+
+    $ gpg --quick-add-key [fpr] ed25519 sign
+
+Remember to tell the keyservers about this change, so others can pull down
+your new subkey::
+
+    $ gpg --send-key [fpr]
+
+.. note:: ECC support in GnuPG
+
+    GnuPG 2.1 and later has full support for Elliptic Curve
+    Cryptography, with ability to combine ECC subkeys with traditional
+    RSA master keys. The main upside of ECC cryptography is that it is
+    much faster computationally and creates much smaller signatures when
+    compared byte for byte with 2048+ bit RSA keys. Unless you plan on
+    using a smartcard device that does not support ECC operations, we
+    recommend that you create an ECC signing subkey for your kernel
+    work.
+
+    If for some reason you prefer to stay with RSA subkeys, just replace
+    "ed25519" with "rsa2048" in the above command.
+
+
+Back up your master key for disaster recovery
+---------------------------------------------
+
+The more signatures you have on your PGP key from other developers, the
+more reasons you have to create a backup version that lives on something
+other than digital media, for disaster recovery reasons.
+
+The best way to create a printable hardcopy of your private key is by
+using the ``paperkey`` software written for this very purpose. See ``man
+paperkey`` for more details on the output format and its benefits over
+other solutions. Paperkey should already be packaged for most
+distributions.
+
+Run the following command to create a hardcopy backup of your private
+key::
+
+    $ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt
+
+Print out that file (or pipe the output straight to lpr), then take a
+pen and write your passphrase on the margin of the paper. **This is
+strongly recommended** because the key printout is still encrypted with
+that passphrase, and if you ever change it you will not remember what it
+used to be when you had created the backup -- *guaranteed*.
+
+Put the resulting printout and the hand-written passphrase into an envelope
+and store in a secure and well-protected place, preferably away from your
+home, such as your bank vault.
+
+.. note::
+
+    Your printer is probably no longer a simple dumb device connected to
+    your parallel port, but since the output is still encrypted with
+    your passphrase, printing out even to "cloud-integrated" modern
+    printers should remain a relatively safe operation. One option is to
+    change the passphrase on your master key immediately after you are
+    done with paperkey.
+
+Back up your whole GnuPG directory
+----------------------------------
+
+.. warning::
+
+    **!!!Do not skip this step!!!**
+
+It is important to have a readily available backup of your PGP keys
+should you need to recover them. This is different from the
+disaster-level preparedness we did with ``paperkey``. You will also rely
+on these external copies whenever you need to use your Certify key --
+such as when making changes to your own key or signing other people's
+keys after conferences and summits.
+
+Start by getting a small USB "thumb" drive (preferably two!) that you
+will use for backup purposes. You will need to encrypt them using LUKS
+-- refer to your distro's documentation on how to accomplish this.
+
+For the encryption passphrase, you can use the same one as on your
+master key.
+
+Once the encryption process is over, re-insert the USB drive and make
+sure it gets properly mounted. Copy your entire ``.gnupg`` directory
+over to the encrypted storage::
+
+    $ cp -a ~/.gnupg /media/disk/foo/gnupg-backup
+
+You should now test to make sure everything still works::
+
+    $ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr]
+
+If you don't get any errors, then you should be good to go. Unmount the
+USB drive, distinctly label it so you don't blow it away next time you
+need to use a random USB drive, and put in a safe place -- but not too
+far away, because you'll need to use it every now and again for things
+like editing identities, adding or revoking subkeys, or signing other
+people's keys.
+
+Remove the master key from  your homedir
+----------------------------------------
+
+The files in our home directory are not as well protected as we like to
+think.  They can be leaked or stolen via many different means:
+
+- by accident when making quick homedir copies to set up a new workstation
+- by systems administrator negligence or malice
+- via poorly secured backups
+- via malware in desktop apps (browsers, pdf viewers, etc)
+- via coercion when crossing international borders
+
+Protecting your key with a good passphrase greatly helps reduce the risk
+of any of the above, but passphrases can be discovered via keyloggers,
+shoulder-surfing, or any number of other means. For this reason, the
+recommended setup is to remove your master key from your home directory
+and store it on offline storage.
+
+.. warning::
+
+    Please see the previous section and make sure you have backed up
+    your GnuPG directory in its entirety. What we are about to do will
+    render your key useless if you do not have a usable backup!
+
+First, identify the keygrip of your master key::
+
+    $ gpg --with-keygrip --list-key [fpr]
+
+The output will be something like this::
+
+    pub   rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
+          000000000000000000000000AAAABBBBCCCCDDDD
+          Keygrip = 1111000000000000000000000000000000000000
+    uid           [ultimate] Alice Dev <adev@kernel.org>
+    sub   rsa2048 2018-01-24 [E] [expires: 2020-01-24]
+          Keygrip = 2222000000000000000000000000000000000000
+    sub   ed25519 2018-01-24 [S]
+          Keygrip = 3333000000000000000000000000000000000000
+
+Find the keygrip entry that is beneath the ``pub`` line (right under the
+master key fingerprint). This will correspond directly to a file in your
+``~/.gnupg`` directory::
+
+    $ cd ~/.gnupg/private-keys-v1.d
+    $ ls
+    1111000000000000000000000000000000000000.key
+    2222000000000000000000000000000000000000.key
+    3333000000000000000000000000000000000000.key
+
+All you have to do is simply remove the .key file that corresponds to
+the master keygrip::
+
+    $ cd ~/.gnupg/private-keys-v1.d
+    $ rm 1111000000000000000000000000000000000000.key
+
+Now, if you issue the ``--list-secret-keys`` command, it will show that
+the master key is missing (the ``#`` indicates it is not available)::
+
+    $ gpg --list-secret-keys
+    sec#  rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
+          000000000000000000000000AAAABBBBCCCCDDDD
+    uid           [ultimate] Alice Dev <adev@kernel.org>
+    ssb   rsa2048 2018-01-24 [E] [expires: 2020-01-24]
+    ssb   ed25519 2018-01-24 [S]
+
+You should also remove any ``secring.gpg`` files in the ``~/.gnupg``
+directory, which are left over from earlier versions of GnuPG.
+
+If you don't have the "private-keys-v1.d" directory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you do not have a ``~/.gnupg/private-keys-v1.d`` directory, then your
+secret keys are still stored in the legacy ``secring.gpg`` file used by
+GnuPG v1. Making any changes to your key, such as changing the
+passphrase or adding a subkey, should automatically convert the old
+``secring.gpg`` format to use ``private-keys-v1.d`` instead.
+
+Once you get that done, make sure to delete the obsolete ``secring.gpg``
+file, which still contains your private keys.
+
+.. _smartcards:
+
+Move the subkeys to a dedicated crypto device
+=============================================
+
+Even though the master key is now safe from being leaked or stolen, the
+subkeys are still in your home directory. Anyone who manages to get
+their hands on those will be able to decrypt your communication or fake
+your signatures (if they know the passphrase). Furthermore, each time a
+GnuPG operation is performed, the keys are loaded into system memory and
+can be stolen from there by sufficiently advanced malware (think
+Meltdown and Spectre).
+
+The best way to completely protect your keys is to move them to a
+specialized hardware device that is capable of smartcard operations.
+
+The benefits of smartcards
+--------------------------
+
+A smartcard contains a cryptographic chip that is capable of storing
+private keys and performing crypto operations directly on the card
+itself. Because the key contents never leave the smartcard, the
+operating system of the computer into which you plug in the hardware
+device is not able to retrieve the private keys themselves. This is very
+different from the encrypted USB storage device we used earlier for
+backup purposes -- while that USB device is plugged in and mounted, the
+operating system is able to access the private key contents.
+
+Using external encrypted USB media is not a substitute to having a
+smartcard-capable device.
+
+Available smartcard devices
+---------------------------
+
+Unless all your laptops and workstations have smartcard readers, the
+easiest is to get a specialized USB device that implements smartcard
+functionality.  There are several options available:
+
+- `Nitrokey Start`_: Open hardware and Free Software, based on FSI
+  Japan's `Gnuk`_. Offers support for ECC keys, but fewest security
+  features (such as resistance to tampering or some side-channel
+  attacks).
+- `Nitrokey Pro`_: Similar to the Nitrokey Start, but more
+  tamper-resistant and offers more security features, but no ECC
+  support.
+- `Yubikey 4`_: proprietary hardware and software, but cheaper than
+  Nitrokey Pro and comes available in the USB-C form that is more useful
+  with newer laptops. Offers additional security features such as FIDO
+  U2F, but no ECC.
+
+`LWN has a good review`_ of some of the above models, as well as several
+others. If you want to use ECC keys, your best bet among commercially
+available devices is the Nitrokey Start.
+
+.. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6
+.. _`Nitrokey Pro`: https://shop.nitrokey.com/shop/product/nitrokey-pro-3
+.. _`Yubikey 4`: https://www.yubico.com/product/yubikey-4-series/
+.. _Gnuk: http://www.fsij.org/doc-gnuk/
+.. _`LWN has a good review`: https://lwn.net/Articles/736231/
+
+Configure your smartcard device
+-------------------------------
+
+Your smartcard device should Just Work (TM) the moment you plug it into
+any modern Linux workstation. You can verify it by running::
+
+    $ gpg --card-status
+
+If you see full smartcard details, then you are good to go.
+Unfortunately, troubleshooting all possible reasons why things may not
+be working for you is way beyond the scope of this guide. If you are
+having trouble getting the card to work with GnuPG, please seek help via
+usual support channels.
+
+To configure your smartcard, you will need to use the GnuPG menu system, as
+there are no convenient command-line switches::
+
+    $ gpg --card-edit
+    [...omitted...]
+    gpg/card> admin
+    Admin commands are allowed
+    gpg/card> passwd
+
+You should set the user PIN (1), Admin PIN (3), and the Reset Code (4).
+Please make sure to record and store these in a safe place -- especially
+the Admin PIN and the Reset Code (which allows you to completely wipe
+the smartcard).  You so rarely need to use the Admin PIN, that you will
+inevitably forget what it is if you do not record it.
+
+Getting back to the main card menu, you can also set other values (such
+as name, sex, login data, etc), but it's not necessary and will
+additionally leak information about your smartcard should you lose it.
+
+.. note::
+
+    Despite having the name "PIN", neither the user PIN nor the admin
+    PIN on the card need to be numbers.
+
+Move the subkeys to your smartcard
+----------------------------------
+
+Exit the card menu (using "q") and save all changes. Next, let's move
+your subkeys onto the smartcard. You will need both your PGP key
+passphrase and the admin PIN of the card for most operations::
+
+    $ gpg --edit-key [fpr]
+
+    Secret subkeys are available.
+
+    pub  rsa2048/AAAABBBBCCCCDDDD
+         created: 2018-01-23  expires: 2020-01-23  usage: SC
+         trust: ultimate      validity: ultimate
+    ssb  rsa2048/1111222233334444
+         created: 2018-01-23  expires: never       usage: E
+    ssb  ed25519/5555666677778888
+         created: 2017-12-07  expires: never       usage: S
+    [ultimate] (1). Alice Dev <adev@kernel.org>
+
+    gpg>
+
+Using ``--edit-key`` puts us into the menu mode again, and you will
+notice that the key listing is a little different. From here on, all
+commands are done from inside this menu mode, as indicated by ``gpg>``.
+
+First, let's select the key we'll be putting onto the card -- you do
+this by typing ``key 1`` (it's the first one in the listing, the **[E]**
+subkey)::
+
+    gpg> key 1
+
+In the output, you should now see ``ssb*`` on the **[E]** key. The ``*``
+indicates which key is currently "selected." It works as a *toggle*,
+meaning that if you type ``key 1`` again, the ``*`` will disappear and
+the key will not be selected any more.
+
+Now, let's move that key onto the smartcard::
+
+    gpg> keytocard
+    Please select where to store the key:
+       (2) Encryption key
+    Your selection? 2
+
+Since it's our **[E]** key, it makes sense to put it into the Encryption
+slot.  When you submit your selection, you will be prompted first for
+your PGP key passphrase, and then for the admin PIN. If the command
+returns without an error, your key has been moved.
+
+**Important**: Now type ``key 1`` again to unselect the first key, and
+``key 2`` to select the **[S]** key::
+
+    gpg> key 1
+    gpg> key 2
+    gpg> keytocard
+    Please select where to store the key:
+       (1) Signature key
+       (3) Authentication key
+    Your selection? 1
+
+You can use the **[S]** key both for Signature and Authentication, but
+we want to make sure it's in the Signature slot, so choose (1). Once
+again, if your command returns without an error, then the operation was
+successful::
+
+    gpg> q
+    Save changes? (y/N) y
+
+Saving the changes will delete the keys you moved to the card from your
+home directory (but it's okay, because we have them in our backups
+should we need to do this again for a replacement smartcard).
+
+Verifying that the keys were moved
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you perform ``--list-secret-keys`` now, you will see a subtle
+difference in the output::
+
+    $ gpg --list-secret-keys
+    sec#  rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
+          000000000000000000000000AAAABBBBCCCCDDDD
+    uid           [ultimate] Alice Dev <adev@kernel.org>
+    ssb>  rsa2048 2018-01-24 [E] [expires: 2020-01-24]
+    ssb>  ed25519 2018-01-24 [S]
+
+The ``>`` in the ``ssb>`` output indicates that the subkey is only
+available on the smartcard. If you go back into your secret keys
+directory and look at the contents there, you will notice that the
+``.key`` files there have been replaced with stubs::
+
+    $ cd ~/.gnupg/private-keys-v1.d
+    $ strings *.key | grep 'private-key'
+
+The output should contain ``shadowed-private-key`` to indicate that
+these files are only stubs and the actual content is on the smartcard.
+
+Verifying that the smartcard is functioning
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To verify that the smartcard is working as intended, you can create a
+signature::
+
+    $ echo "Hello world" | gpg --clearsign > /tmp/test.asc
+    $ gpg --verify /tmp/test.asc
+
+This should ask for your smartcard PIN on your first command, and then
+show "Good signature" after you run ``gpg --verify``.
+
+Congratulations, you have successfully made it extremely difficult to
+steal your digital developer identity!
+
+Other common GnuPG operations
+-----------------------------
+
+Here is a quick reference for some common operations you'll need to do
+with your PGP key.
+
+Mounting your master key offline storage
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You will need your master key for any of the operations below, so you
+will first need to mount your backup offline storage and tell GnuPG to
+use it::
+
+    $ export GNUPGHOME=/media/disk/foo/gnupg-backup
+    $ gpg --list-secret-keys
+
+You want to make sure that you see ``sec`` and not ``sec#`` in the
+output (the ``#`` means the key is not available and you're still using
+your regular home directory location).
+
+Extending key expiration date
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The master key has the default expiration date of 2 years from the date
+of creation. This is done both for security reasons and to make obsolete
+keys eventually disappear from keyservers.
+
+To extend the expiration on your key by a year from current date, just
+run::
+
+    $ gpg --quick-set-expire [fpr] 1y
+
+You can also use a specific date if that is easier to remember (e.g.
+your birthday, January 1st, or Canada Day)::
+
+    $ gpg --quick-set-expire [fpr] 2020-07-01
+
+Remember to send the updated key back to keyservers::
+
+    $ gpg --send-key [fpr]
+
+Updating your work directory after any changes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After you make any changes to your key using the offline storage, you will
+want to import these changes back into your regular working directory::
+
+    $ gpg --export | gpg --homedir ~/.gnupg --import
+    $ unset GNUPGHOME
+
+
+Using PGP with Git
+==================
+
+One of the core features of Git is its decentralized nature -- once a
+repository is cloned to your system, you have full history of the
+project, including all of its tags, commits and branches. However, with
+hundreds of cloned repositories floating around, how does anyone verify
+that their copy of linux.git has not been tampered with by a malicious
+third party?
+
+Or what happens if a backdoor is discovered in the code and the "Author"
+line in the commit says it was done by you, while you're pretty sure you
+had `nothing to do with it`_?
+
+To address both of these issues, Git introduced PGP integration. Signed
+tags prove the repository integrity by assuring that its contents are
+exactly the same as on the workstation of the developer who created the
+tag, while signed commits make it nearly impossible for someone to
+impersonate you without having access to your PGP keys.
+
+.. _`nothing to do with it`: https://github.com/jayphelps/git-blame-someone-else
+
+Configure git to use your PGP key
+---------------------------------
+
+If you only have one secret key in your keyring, then you don't really
+need to do anything extra, as it becomes your default key.  However, if
+you happen to have multiple secret keys, you can tell git which key
+should be used (``[fpr]`` is the fingerprint of your key)::
+
+    $ git config --global user.signingKey [fpr]
+
+**IMPORTANT**: If you have a distinct ``gpg2`` command, then you should
+tell git to always use it instead of the legacy ``gpg`` from version 1::
+
+    $ git config --global gpg.program gpg2
+
+How to work with signed tags
+----------------------------
+
+To create a signed tag, simply pass the ``-s`` switch to the tag
+command::
+
+    $ git tag -s [tagname]
+
+Our recommendation is to always sign git tags, as this allows other
+developers to ensure that the git repository they are pulling from has
+not been maliciously altered.
+
+How to verify signed tags
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To verify a signed tag, simply use the ``verify-tag`` command::
+
+    $ git verify-tag [tagname]
+
+If you are pulling a tag from another fork of the project repository,
+git should automatically verify the signature at the tip you're pulling
+and show you the results during the merge operation::
+
+    $ git pull [url] tags/sometag
+
+The merge message will contain something like this::
+
+    Merge tag 'sometag' of [url]
+
+    [Tag message]
+
+    # gpg: Signature made [...]
+    # gpg: Good signature from [...]
+
+If you are verifying someone else's git tag, then you will need to
+import their PGP key. Please refer to the
+":ref:`verify_identities`" section below.
+
+Configure git to always sign annotated tags
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Chances are, if you're creating an annotated tag, you'll want to sign
+it. To force git to always sign annotated tags, you can set a global
+configuration option::
+
+    $ git config --global tag.forceSignAnnotated true
+
+How to work with signed commits
+-------------------------------
+
+It is easy to create signed commits, but it is much more difficult to
+use them in Linux kernel development, since it relies on patches sent to
+the mailing list, and this workflow does not preserve PGP commit
+signatures. Furthermore, when rebasing your repository to match
+upstream, even your own PGP commit signatures will end up discarded. For
+this reason, most kernel developers don't bother signing their commits
+and will ignore signed commits in any external repositories that they
+rely upon in their work.
+
+However, if you have your working git tree publicly available at some
+git hosting service (kernel.org, infradead.org, ozlabs.org, or others),
+then the recommendation is that you sign all your git commits even if
+upstream developers do not directly benefit from this practice.
+
+We recommend this for the following reasons:
+
+1. Should there ever be a need to perform code forensics or track code
+   provenance, even externally maintained trees carrying PGP commit
+   signatures will be valuable for such purposes.
+2. If you ever need to re-clone your local repository (for example,
+   after a disk failure), this lets you easily verify the repository
+   integrity before resuming your work.
+3. If someone needs to cherry-pick your commits, this allows them to
+   quickly verify their integrity before applying them.
+
+Creating signed commits
+~~~~~~~~~~~~~~~~~~~~~~~
+
+To create a signed commit, you just need to pass the ``-S`` flag to the
+``git commit`` command (it's capital ``-S`` due to collision with
+another flag)::
+
+    $ git commit -S
+
+Configure git to always sign commits
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can tell git to always sign commits::
+
+    git config --global commit.gpgSign true
+
+.. note::
+
+    Make sure you configure ``gpg-agent`` before you turn this on.
+
+.. _verify_identities:
+
+How to verify kernel developer identities
+=========================================
+
+Signing tags and commits is easy, but how does one go about verifying
+that the key used to sign something belongs to the actual kernel
+developer and not to a malicious imposter?
+
+Configure auto-key-retrieval using WKD and DANE
+-----------------------------------------------
+
+If you are not already someone with an extensive collection of other
+developers' public keys, then you can jumpstart your keyring by relying
+on key auto-discovery and auto-retrieval. GnuPG can piggyback on other
+delegated trust technologies, namely DNSSEC and TLS, to get you going if
+the prospect of starting your own Web of Trust from scratch is too
+daunting.
+
+Add the following to your ``~/.gnupg/gpg.conf``::
+
+    auto-key-locate wkd,dane,local
+    auto-key-retrieve
+
+DNS-Based Authentication of Named Entities ("DANE") is a method for
+publishing public keys in DNS and securing them using DNSSEC signed
+zones. Web Key Directory ("WKD") is the alternative method that uses
+https lookups for the same purpose. When using either DANE or WKD for
+looking up public keys, GnuPG will validate DNSSEC or TLS certificates,
+respectively, before adding auto-retrieved public keys to your local
+keyring.
+
+Kernel.org publishes the WKD for all developers who have kernel.org
+accounts. Once you have the above changes in your ``gpg.conf``, you can
+auto-retrieve the keys for Linus Torvalds and Greg Kroah-Hartman (if you
+don't already have them)::
+
+    $ gpg --locate-keys torvalds@kernel.org gregkh@kernel.org
+
+If you have a kernel.org account, then you should `add the kernel.org
+UID to your key`_ to make WKD more useful to other kernel developers.
+
+.. _`add the kernel.org UID to your key`: https://korg.wiki.kernel.org/userdoc/mail#adding_a_kernelorg_uid_to_your_pgp_key
+
+Web of Trust (WOT) vs. Trust on First Use (TOFU)
+------------------------------------------------
+
+PGP incorporates a trust delegation mechanism known as the "Web of
+Trust." At its core, this is an attempt to replace the need for
+centralized Certification Authorities of the HTTPS/TLS world. Instead of
+various software makers dictating who should be your trusted certifying
+entity, PGP leaves this responsibility to each user.
+
+Unfortunately, very few people understand how the Web of Trust works.
+While it remains an important aspect of the OpenPGP specification,
+recent versions of GnuPG (2.2 and above) have implemented an alternative
+mechanism called "Trust on First Use" (TOFU). You can think of TOFU as
+"the SSH-like approach to trust." With SSH, the first time you connect
+to a remote system, its key fingerprint is recorded and remembered. If
+the key changes in the future, the SSH client will alert you and refuse
+to connect, forcing you to make a decision on whether you choose to
+trust the changed key or not. Similarly, the first time you import
+someone's PGP key, it is assumed to be valid. If at any point in the
+future GnuPG comes across another key with the same identity, both the
+previously imported key and the new key will be marked as invalid and
+you will need to manually figure out which one to keep.
+
+We recommend that you use the combined TOFU+PGP trust model (which is
+the new default in GnuPG v2). To set it, add (or modify) the
+``trust-model`` setting in ``~/.gnupg/gpg.conf``::
+
+    trust-model tofu+pgp
+
+How to use keyservers (more) safely
+-----------------------------------
+
+If you get a "No public key" error when trying to validate someone's
+tag, then you should attempt to lookup that key using a keyserver. It is
+important to keep in mind that there is absolutely no guarantee that the
+key you retrieve from PGP keyservers belongs to the actual person --
+that much is by design. You are supposed to use the Web of Trust to
+establish key validity.
+
+How to properly maintain the Web of Trust is beyond the scope of this
+document, simply because doing it properly requires both effort and
+dedication that tends to be beyond the caring threshold of most human
+beings. Here are some shortcuts that will help you reduce the risk of
+importing a malicious key.
+
+First, let's say you've tried to run ``git verify-tag`` but it returned
+an error saying the key is not found::
+
+    $ git verify-tag sunxi-fixes-for-4.15-2
+    gpg: Signature made Sun 07 Jan 2018 10:51:55 PM EST
+    gpg:                using RSA key DA73759BF8619E484E5A3B47389A54219C0F2430
+    gpg:                issuer "wens@...org"
+    gpg: Can't check signature: No public key
+
+Let's query the keyserver for more info about that key fingerprint (the
+fingerprint probably belongs to a subkey, so we can't use it directly
+without finding out the ID of the master key it is associated with)::
+
+    $ gpg --search DA73759BF8619E484E5A3B47389A54219C0F2430
+    gpg: data source: hkp://keys.gnupg.net
+    (1) Chen-Yu Tsai <wens@...org>
+          4096 bit RSA key C94035C21B4F2AEB, created: 2017-03-14, expires: 2019-03-15
+    Keys 1-1 of 1 for "DA73759BF8619E484E5A3B47389A54219C0F2430".  Enter number(s), N)ext, or Q)uit > q
+
+Locate the ID of the master key in the output, in our example
+``C94035C21B4F2AEB``. Now display the key of Linus Torvalds that you
+have on your keyring::
+
+    $ gpg --list-key torvalds@kernel.org
+    pub   rsa2048 2011-09-20 [SC]
+          ABAF11C65A2970B130ABE3C479BE3E4300411886
+    uid           [ unknown] Linus Torvalds <torvalds@kernel.org>
+    sub   rsa2048 2011-09-20 [E]
+
+Next, open the `PGP pathfinder`_. In the "From" field, paste the key
+fingerprint of Linus Torvalds from the output above. In the "To" field,
+paste they key-id you found via ``gpg --search`` of the unknown key, and
+check the results:
+
+- `Finding paths to Linus`_
+
+If you get a few decent trust paths, then it's a pretty good indication
+that it is a valid key. You can add it to your keyring from the
+keyserver now::
+
+    $ gpg --recv-key C94035C21B4F2AEB
+
+This process is not perfect, and you are obviously trusting the
+administrators of the PGP Pathfinder service to not be malicious (in
+fact, this goes against :ref:`devs_not_infra`). However, if you
+do not carefully maintain your own web of trust, then it is a marked
+improvement over blindly trusting keyservers.
+
+.. _`PGP pathfinder`: https://pgp.cs.uu.nl/
+.. _`Finding paths to Linus`: https://pgp.cs.uu.nl/paths/79BE3E4300411886/to/C94035C21B4F2AEB.html
diff --git a/Documentation/sysctl/user.txt b/Documentation/sysctl/user.txt
index 1291c49..a588286 100644
--- a/Documentation/sysctl/user.txt
+++ b/Documentation/sysctl/user.txt
@@ -3,7 +3,7 @@
 
 ==============================================================
 
-This file contains the documetation for the sysctl files in
+This file contains the documentation for the sysctl files in
 /proc/sys/user.
 
 The files in this directory can be used to override the default
diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt
index 6f9d7b4..beea975 100644
--- a/Documentation/watchdog/watchdog-parameters.txt
+++ b/Documentation/watchdog/watchdog-parameters.txt
@@ -40,11 +40,6 @@
 nowayout: Disable watchdog shutdown on close
 	(default=kernel config parameter)
 -------------------------------------------------
-at32ap700x_wdt:
-timeout: Timeout value. Limited to be 1 or 2 seconds. (default=2)
-nowayout: Watchdog cannot be stopped once started
-	(default=kernel config parameter)
--------------------------------------------------
 at91rm9200_wdt:
 wdt_time: Watchdog time in seconds. (default=5)
 nowayout: Watchdog cannot be stopped once started
@@ -162,11 +157,6 @@
 nowayout: Watchdog cannot be stopped once started
 	(default=kernel config parameter)
 -------------------------------------------------
-ixp2000_wdt:
-heartbeat: Watchdog heartbeat in seconds (default 60s)
-nowayout: Watchdog cannot be stopped once started
-	(default=kernel config parameter)
--------------------------------------------------
 ixp4xx_wdt:
 heartbeat: Watchdog heartbeat in seconds (default 60s)
 nowayout: Watchdog cannot be stopped once started
@@ -381,19 +371,6 @@
 nowayout: Watchdog cannot be stopped once started
 	(default=kernel config parameter)
 -------------------------------------------------
-w83697hf_wdt:
-wdt_io: w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)
-timeout: Watchdog timeout in seconds. 1<= timeout <=255 (default=60)
-nowayout: Watchdog cannot be stopped once started
-	(default=kernel config parameter)
-early_disable: Watchdog gets disabled at boot time (default=1)
--------------------------------------------------
-w83697ug_wdt:
-wdt_io: w83697ug/uf WDT io port (default 0x2e)
-timeout: Watchdog timeout in seconds. 1<= timeout <=255 (default=60)
-nowayout: Watchdog cannot be stopped once started
-	(default=kernel config parameter)
--------------------------------------------------
 w83877f_wdt:
 timeout: Watchdog timeout in seconds. (1<=timeout<=3600, default=30)
 nowayout: Watchdog cannot be stopped once started
diff --git a/MAINTAINERS b/MAINTAINERS
index b59a8cd..4c7a2fd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -903,7 +903,6 @@
 S:	Supported
 F:	drivers/staging/android/ion
 F:	drivers/staging/android/uapi/ion.h
-F:	drivers/staging/android/uapi/ion_test.h
 
 AOA (Apple Onboard Audio) ALSA DRIVER
 M:	Johannes Berg <johannes@sipsolutions.net>
@@ -1308,7 +1307,6 @@
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 T:	git git://git.armlinux.org.uk/~rmk/linux-arm.git clkdev
-F:	arch/arm/include/asm/clkdev.h
 F:	drivers/clk/clkdev.c
 
 ARM/COMPULAB CM-X270/EM-X270 and CM-X300 MACHINE SUPPORT
@@ -1360,7 +1358,7 @@
 F:	Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt
 F:	Documentation/devicetree/bindings/rtc/faraday,ftrtc010.txt
 F:	arch/arm/mach-gemini/
-F:	drivers/net/ethernet/cortina/gemini/*
+F:	drivers/net/ethernet/cortina/
 F:	drivers/pinctrl/pinctrl-gemini.c
 F:	drivers/rtc/rtc-ftrtc010.c
 
@@ -1737,9 +1735,7 @@
 L:	linux-oxnas@lists.tuxfamily.org (moderated for non-subscribers)
 S:	Maintained
 F:	arch/arm/mach-oxnas/
-F:	arch/arm/boot/dts/ox8*.dtsi
-F:	arch/arm/boot/dts/wd-mbwe.dts
-F:	arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
+F:	arch/arm/boot/dts/ox8*.dts*
 N:	oxnas
 
 ARM/PALM TREO SUPPORT
@@ -1747,8 +1743,7 @@
 L:	linux-arm-kernel@lists.infradead.org
 W:	http://hackndev.com
 S:	Maintained
-F:	arch/arm/mach-pxa/include/mach/palmtreo.h
-F:	arch/arm/mach-pxa/palmtreo.c
+F:	arch/arm/mach-pxa/palmtreo.*
 
 ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT
 M:	Marek Vasut <marek.vasut@gmail.com>
@@ -1757,12 +1752,10 @@
 S:	Maintained
 F:	arch/arm/mach-pxa/include/mach/palmtx.h
 F:	arch/arm/mach-pxa/palmtx.c
-F:	arch/arm/mach-pxa/include/mach/palmt5.h
-F:	arch/arm/mach-pxa/palmt5.c
+F:	arch/arm/mach-pxa/palmt5.*
 F:	arch/arm/mach-pxa/include/mach/palmld.h
 F:	arch/arm/mach-pxa/palmld.c
-F:	arch/arm/mach-pxa/include/mach/palmte2.h
-F:	arch/arm/mach-pxa/palmte2.c
+F:	arch/arm/mach-pxa/palmte2.*
 F:	arch/arm/mach-pxa/include/mach/palmtc.h
 F:	arch/arm/mach-pxa/palmtc.c
 
@@ -1771,8 +1764,7 @@
 L:	linux-arm-kernel@lists.infradead.org
 W:	http://hackndev.com
 S:	Maintained
-F:	arch/arm/mach-pxa/include/mach/palmz72.h
-F:	arch/arm/mach-pxa/palmz72.c
+F:	arch/arm/mach-pxa/palmz72.*
 
 ARM/PLEB SUPPORT
 M:	Peter Chubb <pleb@gelato.unsw.edu.au>
@@ -1801,7 +1793,6 @@
 F:	drivers/dma/qcom/
 F:	drivers/soc/qcom/
 F:	drivers/spi/spi-qup.c
-F:	drivers/tty/serial/msm_serial.h
 F:	drivers/tty/serial/msm_serial.c
 F:	drivers/*/pm8???-*
 F:	drivers/mfd/ssbi.c
@@ -2228,14 +2219,6 @@
 S:	Maintained
 F:	drivers/leds/leds-as3645a.c
 
-AS3645A LED FLASH CONTROLLER DRIVER
-M:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-L:	linux-media@vger.kernel.org
-T:	git git://linuxtv.org/media_tree.git
-S:	Maintained
-F:	drivers/media/i2c/as3645a.c
-F:	include/media/i2c/as3645a.h
-
 ASAHI KASEI AK8974 DRIVER
 M:	Linus Walleij <linus.walleij@linaro.org>
 L:	linux-iio@vger.kernel.org
@@ -3575,7 +3558,7 @@
 
 COMMON CLK FRAMEWORK
 M:	Michael Turquette <mturquette@baylibre.com>
-M:	Stephen Boyd <sboyd@codeaurora.org>
+M:	Stephen Boyd <sboyd@kernel.org>
 L:	linux-clk@vger.kernel.org
 Q:	http://patchwork.kernel.org/project/linux-clk/list/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
@@ -6009,6 +5992,12 @@
 S:	Maintained
 F:	drivers/input/touchscreen/goodix.c
 
+GPD POCKET FAN DRIVER
+M:	Hans de Goede <hdegoede@redhat.com>
+L:	platform-driver-x86@vger.kernel.org
+S:	Maintained
+F:	drivers/platform/x86/gpd-pocket-fan.c
+
 GPIO ACPI SUPPORT
 M:	Mika Westerberg <mika.westerberg@linux.intel.com>
 M:	Andy Shevchenko <andriy.shevchenko@linux.intel.com>
@@ -6946,7 +6935,7 @@
 M:	Doug Ledford <dledford@redhat.com>
 M:	Jason Gunthorpe <jgg@mellanox.com>
 L:	linux-rdma@vger.kernel.org
-W:	http://www.openfabrics.org/
+W:	https://github.com/linux-rdma/rdma-core
 Q:	http://patchwork.kernel.org/project/linux-rdma/list/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git
 S:	Supported
@@ -7136,6 +7125,14 @@
 S:	Odd fixes
 F:	drivers/dma/iop-adma.c
 
+INTEL IPU3 CSI-2 CIO2 DRIVER
+M:	Yong Zhi <yong.zhi@intel.com>
+M:	Sakari Ailus <sakari.ailus@linux.intel.com>
+L:	linux-media@vger.kernel.org
+S:	Maintained
+F:	drivers/media/pci/intel/ipu3/
+F:	Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst
+
 INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
 M:	Krzysztof Halasa <khalasa@piap.pl>
 S:	Maintained
@@ -8749,6 +8746,15 @@
 S:	Maintained
 F:	drivers/media/dvb-frontends/stv6111*
 
+MEDIA DRIVERS FOR NVIDIA TEGRA - VDE
+M:	Dmitry Osipenko <digetx@gmail.com>
+L:	linux-media@vger.kernel.org
+L:	linux-tegra@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
+F:	drivers/staging/media/tegra-vde/
+
 MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
 M:	Mauro Carvalho Chehab <mchehab@s-opensource.com>
 M:	Mauro Carvalho Chehab <mchehab@kernel.org>
@@ -8930,12 +8936,13 @@
 Q:	http://patchwork.ozlabs.org/project/netdev/list/
 F:	drivers/net/ethernet/mellanox/mlxfw/
 
-MELLANOX MLX CPLD HOTPLUG DRIVER
+MELLANOX HARDWARE PLATFORM SUPPORT
+M:	Andy Shevchenko <andy@infradead.org>
+M:	Darren Hart <dvhart@infradead.org>
 M:	Vadim Pasternak <vadimp@mellanox.com>
 L:	platform-driver-x86@vger.kernel.org
 S:	Supported
-F:	drivers/platform/x86/mlxcpld-hotplug.c
-F:	include/linux/platform_data/mlxcpld-hotplug.h
+F:	drivers/platform/mellanox/
 
 MELLANOX MLX4 core VPI driver
 M:	Tariq Toukan <tariqt@mellanox.com>
@@ -9009,6 +9016,7 @@
 S:	Supported
 F:	kernel/sched/membarrier.c
 F:	include/uapi/linux/membarrier.h
+F:	arch/powerpc/include/asm/membarrier.h
 
 MEMORY MANAGEMENT
 L:	linux-mm@kvack.org
@@ -9180,6 +9188,7 @@
 F:	Documentation/devicetree/bindings/mips/
 F:	Documentation/mips/
 F:	arch/mips/
+F:	drivers/platform/mips/
 
 MIPS BOSTON DEVELOPMENT BOARD
 M:	Paul Burton <paul.burton@mips.com>
@@ -9207,6 +9216,25 @@
 F:	drivers/*/*loongson1*
 F:	drivers/*/*/*loongson1*
 
+MIPS/LOONGSON2 ARCHITECTURE
+M:	Jiaxun Yang <jiaxun.yang@flygoat.com>
+L:	linux-mips@linux-mips.org
+S:	Maintained
+F:	arch/mips/loongson64/*{2e/2f}*
+F:	arch/mips/include/asm/mach-loongson64/
+F:	drivers/*/*loongson2*
+F:	drivers/*/*/*loongson2*
+
+MIPS/LOONGSON3 ARCHITECTURE
+M:	Huacai Chen <chenhc@lemote.com>
+L:	linux-mips@linux-mips.org
+S:	Maintained
+F:	arch/mips/loongson64/
+F:	arch/mips/include/asm/mach-loongson64/
+F:	drivers/platform/mips/cpu_hwmon.c
+F:	drivers/*/*loongson3*
+F:	drivers/*/*/*loongson3*
+
 MIPS RINT INSTRUCTION EMULATION
 M:	Aleksandar Markovic <aleksandar.markovic@mips.com>
 L:	linux-mips@linux-mips.org
@@ -9252,7 +9280,6 @@
 
 MODULE SUPPORT
 M:	Jessica Yu <jeyu@kernel.org>
-M:	Rusty Russell <rusty@rustcorp.com.au>
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git modules-next
 S:	Maintained
 F:	include/linux/module.h
@@ -10165,6 +10192,14 @@
 F:	drivers/media/i2c/ov7670.c
 F:	Documentation/devicetree/bindings/media/i2c/ov7670.txt
 
+OMNIVISION OV7740 SENSOR DRIVER
+M:	Wenyou Yang <wenyou.yang@microchip.com>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+S:	Maintained
+F:	drivers/media/i2c/ov7740.c
+F:	Documentation/devicetree/bindings/media/i2c/ov7740.txt
+
 ONENAND FLASH DRIVER
 M:	Kyungmin Park <kyungmin.park@samsung.com>
 L:	linux-mtd@lists.infradead.org
@@ -10259,7 +10294,7 @@
 OPERATING PERFORMANCE POINTS (OPP)
 M:	Viresh Kumar <vireshk@kernel.org>
 M:	Nishanth Menon <nm@ti.com>
-M:	Stephen Boyd <sboyd@codeaurora.org>
+M:	Stephen Boyd <sboyd@kernel.org>
 L:	linux-pm@vger.kernel.org
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git
@@ -10394,7 +10429,6 @@
 PARAVIRT_OPS INTERFACE
 M:	Juergen Gross <jgross@suse.com>
 M:	Alok Kataria <akataria@vmware.com>
-M:	Rusty Russell <rusty@rustcorp.com.au>
 L:	virtualization@lists.linux-foundation.org
 S:	Supported
 F:	Documentation/virtual/paravirt_ops.txt
@@ -10513,6 +10547,13 @@
 F:	Documentation/devicetree/bindings/pci/pci-armada8k.txt
 F:	drivers/pci/dwc/pcie-armada8k.c
 
+PCI DRIVER FOR CADENCE PCIE IP
+M:	Alan Douglas <adouglas@cadence.com>
+L:	linux-pci@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/pci/cdns,*.txt
+F:	drivers/pci/cadence/pcie-cadence*
+
 PCI DRIVER FOR FREESCALE LAYERSCAPE
 M:	Minghuan Lian <minghuan.Lian@freescale.com>
 M:	Mingkai Hu <mingkai.hu@freescale.com>
@@ -10663,8 +10704,12 @@
 S:	Supported
 F:	Documentation/devicetree/bindings/pci/
 F:	Documentation/PCI/
+F:	drivers/acpi/pci*
 F:	drivers/pci/
+F:	include/asm-generic/pci*
 F:	include/linux/pci*
+F:	include/uapi/linux/pci*
+F:	lib/pci*
 F:	arch/x86/pci/
 F:	arch/x86/kernel/quirks.c
 
@@ -10754,11 +10799,9 @@
 F:	drivers/pci/dwc/*spear*
 
 PCMCIA SUBSYSTEM
-P:	Linux PCMCIA Team
-L:	linux-pcmcia@lists.infradead.org
-W:	http://lists.infradead.org/mailman/listinfo/linux-pcmcia
+M:	Dominik Brodowski <linux@dominikbrodowski.net>
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia.git
-S:	Maintained
+S:	Odd Fixes
 F:	Documentation/pcmcia/
 F:	tools/pcmcia/
 F:	drivers/pcmcia/
@@ -11559,6 +11602,13 @@
 F:	Documentation/blockdev/ramdisk.txt
 F:	drivers/block/brd.c
 
+RANCHU VIRTUAL BOARD FOR MIPS
+M:	Miodrag Dinic <miodrag.dinic@mips.com>
+L:	linux-mips@linux-mips.org
+S:	Supported
+F:	arch/mips/generic/board-ranchu.c
+F:	arch/mips/configs/generic/board-ranchu.config
+
 RANDOM NUMBER DRIVER
 M:	"Theodore Ts'o" <tytso@mit.edu>
 S:	Maintained
@@ -12460,6 +12510,14 @@
 S:	Maintained
 F:	drivers/media/tuners/si2157*
 
+SI2165 MEDIA DRIVER
+M:	Matthias Schwarzott <zzam@gentoo.org>
+L:	linux-media@vger.kernel.org
+W:	https://linuxtv.org
+Q:	http://patchwork.linuxtv.org/project/linux-media/list/
+S:	Maintained
+F:	drivers/media/dvb-frontends/si2165*
+
 SI2168 MEDIA DRIVER
 M:	Antti Palosaari <crope@iki.fi>
 L:	linux-media@vger.kernel.org
@@ -12976,7 +13034,7 @@
 F:	drivers/net/ethernet/toshiba/spider_net*
 
 SPMI SUBSYSTEM
-R:	Stephen Boyd <sboyd@codeaurora.org>
+R:	Stephen Boyd <sboyd@kernel.org>
 L:	linux-arm-msm@vger.kernel.org
 F:	Documentation/devicetree/bindings/spmi/
 F:	drivers/spmi/
@@ -13037,12 +13095,6 @@
 F:	Documentation/devicetree/bindings/staging/iio/
 F:	drivers/staging/iio/
 
-STAGING - LIRC (LINUX INFRARED REMOTE CONTROL) DRIVERS
-M:	Jarod Wilson <jarod@wilsonet.com>
-W:	http://www.lirc.org/
-S:	Odd Fixes
-F:	drivers/staging/media/lirc/
-
 STAGING - LUSTRE PARALLEL FILESYSTEM
 M:	Oleg Drokin <oleg.drokin@intel.com>
 M:	Andreas Dilger <andreas.dilger@intel.com>
@@ -13289,7 +13341,6 @@
 F:	drivers/dma/dw/
 
 SYNOPSYS DESIGNWARE ENTERPRISE ETHERNET DRIVER
-M:	Jie Deng <jiedeng@synopsys.com>
 M:	Jose Abreu <Jose.Abreu@synopsys.com>
 L:	netdev@vger.kernel.org
 S:	Supported
@@ -13429,6 +13480,15 @@
 S:	Maintained
 F:	drivers/media/tuners/tda18218*
 
+TDA18250 MEDIA DRIVER
+M:	Olli Salonen <olli.salonen@iki.fi>
+L:	linux-media@vger.kernel.org
+W:	https://linuxtv.org
+Q:	http://patchwork.linuxtv.org/project/linux-media/list/
+T:	git git://linuxtv.org/media_tree.git
+S:	Maintained
+F:	drivers/media/tuners/tda18250*
+
 TDA18271 MEDIA DRIVER
 M:	Michael Krufky <mkrufky@linuxtv.org>
 L:	linux-media@vger.kernel.org
@@ -13859,7 +13919,7 @@
 TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
 M:	John Stultz <john.stultz@linaro.org>
 M:	Thomas Gleixner <tglx@linutronix.de>
-R:	Stephen Boyd <sboyd@codeaurora.org>
+R:	Stephen Boyd <sboyd@kernel.org>
 L:	linux-kernel@vger.kernel.org
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
 S:	Supported
@@ -14927,8 +14987,8 @@
 F:	drivers/input/tablet/wacom_serial4.c
 
 WATCHDOG DEVICE DRIVERS
-M:	Wim Van Sebroeck <wim@iguana.be>
-R:	Guenter Roeck <linux@roeck-us.net>
+M:	Wim Van Sebroeck <wim@linux-watchdog.org>
+M:	Guenter Roeck <linux@roeck-us.net>
 L:	linux-watchdog@vger.kernel.org
 W:	http://www.linux-watchdog.org/
 T:	git git://www.linux-watchdog.org/linux-watchdog.git
@@ -15095,7 +15155,7 @@
 M:	Darren Hart <dvhart@infradead.org>
 M:	Andy Shevchenko <andy@infradead.org>
 L:	platform-driver-x86@vger.kernel.org
-T:	git git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git
+T:	git git://git.infradead.org/linux-platform-drivers-x86.git
 S:	Maintained
 F:	drivers/platform/x86/
 F:	drivers/platform/olpc/
diff --git a/Makefile b/Makefile
index 11aff0f..d192dd8 100644
--- a/Makefile
+++ b/Makefile
@@ -434,7 +434,8 @@
 export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
 
 export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
-export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_KASAN CFLAGS_UBSAN
+export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN
 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
 export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
@@ -679,6 +680,10 @@
 # This selects the stack protector compiler flag. Testing it is delayed
 # until after .config has been reprocessed, in the prepare-compiler-check
 # target.
+ifdef CONFIG_CC_STACKPROTECTOR_AUTO
+  stackp-flag := $(call cc-option,-fstack-protector-strong,$(call cc-option,-fstack-protector))
+  stackp-name := AUTO
+else
 ifdef CONFIG_CC_STACKPROTECTOR_REGULAR
   stackp-flag := -fstack-protector
   stackp-name := REGULAR
@@ -687,16 +692,40 @@
   stackp-flag := -fstack-protector-strong
   stackp-name := STRONG
 else
+  # If either there is no stack protector for this architecture or
+  # CONFIG_CC_STACKPROTECTOR_NONE is selected, we're done, and $(stackp-name)
+  # is empty, skipping all remaining stack protector tests.
+  #
   # Force off for distro compilers that enable stack protector by default.
-  stackp-flag := $(call cc-option, -fno-stack-protector)
+  KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
+endif
 endif
 endif
 # Find arch-specific stack protector compiler sanity-checking script.
-ifdef CONFIG_CC_STACKPROTECTOR
+ifdef stackp-name
+ifneq ($(stackp-flag),)
   stackp-path := $(srctree)/scripts/gcc-$(SRCARCH)_$(BITS)-has-stack-protector.sh
   stackp-check := $(wildcard $(stackp-path))
+  # If the wildcard test matches a test script, run it to check functionality.
+  ifdef stackp-check
+    ifneq ($(shell $(CONFIG_SHELL) $(stackp-check) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
+      stackp-broken := y
+    endif
+  endif
+  ifndef stackp-broken
+    # If the stack protector is functional, enable code that depends on it.
+    KBUILD_CPPFLAGS += -DCONFIG_CC_STACKPROTECTOR
+    # Either we've already detected the flag (for AUTO) or we'll fail the
+    # build in the prepare-compiler-check rule (for specific flag).
+    KBUILD_CFLAGS += $(stackp-flag)
+  else
+    # We have to make sure stack protector is unconditionally disabled if
+    # the compiler is broken (in case we're going to continue the build in
+    # AUTO mode).
+    KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
+  endif
 endif
-KBUILD_CFLAGS += $(stackp-flag)
+endif
 
 ifeq ($(cc-name),clang)
 KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
@@ -1091,14 +1120,25 @@
 prepare-compiler-check: FORCE
 # Make sure compiler supports requested stack protector flag.
 ifdef stackp-name
+  # Warn about CONFIG_CC_STACKPROTECTOR_AUTO having found no option.
+  ifeq ($(stackp-flag),)
+	@echo CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
+		  Compiler does not support any known stack-protector >&2
+  else
+  # Fail if specifically requested stack protector is missing.
   ifeq ($(call cc-option, $(stackp-flag)),)
 	@echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
 		  $(stackp-flag) not supported by compiler >&2 && exit 1
   endif
+  endif
 endif
-# Make sure compiler does not have buggy stack-protector support.
-ifdef stackp-check
-  ifneq ($(shell $(CONFIG_SHELL) $(stackp-check) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
+# Make sure compiler does not have buggy stack-protector support. If a
+# specific stack-protector was requested, fail the build, otherwise warn.
+ifdef stackp-broken
+  ifeq ($(stackp-name),AUTO)
+	@echo CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
+                  $(stackp-flag) available but compiler is broken: disabling >&2
+  else
 	@echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
                   $(stackp-flag) available but compiler is broken >&2 && exit 1
   endif
diff --git a/arch/Kconfig b/arch/Kconfig
index 467dfa3..76c0b54 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -538,16 +538,10 @@
 	  - its compiler supports the -fstack-protector option
 	  - it has implemented a stack canary (e.g. __stack_chk_guard)
 
-config CC_STACKPROTECTOR
-	def_bool n
-	help
-	  Set when a stack-protector mode is enabled, so that the build
-	  can enable kernel-side support for the GCC feature.
-
 choice
 	prompt "Stack Protector buffer overflow detection"
 	depends on HAVE_CC_STACKPROTECTOR
-	default CC_STACKPROTECTOR_NONE
+	default CC_STACKPROTECTOR_AUTO
 	help
 	  This option turns on the "stack-protector" GCC feature. This
 	  feature puts, at the beginning of functions, a canary value on
@@ -564,7 +558,6 @@
 
 config CC_STACKPROTECTOR_REGULAR
 	bool "Regular"
-	select CC_STACKPROTECTOR
 	help
 	  Functions will have the stack-protector canary logic added if they
 	  have an 8-byte or larger character array on the stack.
@@ -578,7 +571,6 @@
 
 config CC_STACKPROTECTOR_STRONG
 	bool "Strong"
-	select CC_STACKPROTECTOR
 	help
 	  Functions will have the stack-protector canary logic added in any
 	  of the following conditions:
@@ -596,6 +588,12 @@
 	  about 20% of all kernel functions, which increases the kernel code
 	  size by about 2%.
 
+config CC_STACKPROTECTOR_AUTO
+	bool "Automatic"
+	help
+	  If the compiler supports it, the best available stack-protector
+	  option will be chosen.
+
 endchoice
 
 config THIN_ARCHIVES
diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c
index 8e9a4196..5476279 100644
--- a/arch/alpha/kernel/console.c
+++ b/arch/alpha/kernel/console.c
@@ -21,6 +21,7 @@
 struct pci_controller *pci_vga_hose;
 static struct resource alpha_vga = {
 	.name	= "alpha-vga+",
+	.flags	= IORESOURCE_IO,
 	.start	= 0x3C0,
 	.end	= 0x3DF
 };
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 72c765a..ab93058 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -780,6 +780,8 @@
 
 		reset-gpio = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */
 
+		lens-focus = <&ad5820>;
+
 		port {
 			csi_cam1: endpoint {
 				bus-type = <3>; /* CCP2 */
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index ce5ee76..4cab9bb 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -338,6 +338,7 @@ static inline int find_next_bit_le(const void *p, int size, int offset)
 
 #endif
 
+#include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/le.h>
 
 /*
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index acbf9ec..ef54013 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -306,4 +306,11 @@ static inline void kvm_fpsimd_flush_cpu_state(void) {}
 
 static inline void kvm_arm_vhe_guest_enter(void) {}
 static inline void kvm_arm_vhe_guest_exit(void) {}
+
+static inline bool kvm_arm_harden_branch_predictor(void)
+{
+	/* No way to detect it yet, pretend it is not there. */
+	return false;
+}
+
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/include/asm/kvm_psci.h b/arch/arm/include/asm/kvm_psci.h
deleted file mode 100644
index 6bda945..0000000
--- a/arch/arm/include/asm/kvm_psci.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2012 - ARM Ltd
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __ARM_KVM_PSCI_H__
-#define __ARM_KVM_PSCI_H__
-
-#define KVM_ARM_PSCI_0_1	1
-#define KVM_ARM_PSCI_0_2	2
-
-int kvm_psci_version(struct kvm_vcpu *vcpu);
-int kvm_psci_call(struct kvm_vcpu *vcpu);
-
-#endif /* __ARM_KVM_PSCI_H__ */
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 960d9dc..1f0de80 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -10,10 +10,7 @@ extern unsigned long pcibios_min_io;
 extern unsigned long pcibios_min_mem;
 #define PCIBIOS_MIN_MEM pcibios_min_mem
 
-static inline int pcibios_assign_all_busses(void)
-{
-	return pci_has_flag(PCI_REASSIGN_ALL_RSRC);
-}
+#define pcibios_assign_all_busses()	pci_has_flag(PCI_REASSIGN_ALL_BUS)
 
 #ifdef CONFIG_PCI_DOMAINS
 static inline int pci_proc_domain(struct pci_bus *bus)
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 0cd0aef..ed46ca6 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -527,7 +527,7 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
 	struct pci_sys_data *sys;
 	LIST_HEAD(head);
 
-	pci_add_flags(PCI_REASSIGN_ALL_RSRC);
+	pci_add_flags(PCI_REASSIGN_ALL_BUS);
 	if (hw->preinit)
 		hw->preinit();
 	pcibios_init_hw(parent, hw, &head);
diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c
index cf8bf6b..910bd8d 100644
--- a/arch/arm/kvm/handle_exit.c
+++ b/arch/arm/kvm/handle_exit.c
@@ -21,7 +21,7 @@
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_coproc.h>
 #include <asm/kvm_mmu.h>
-#include <asm/kvm_psci.h>
+#include <kvm/arm_psci.h>
 #include <trace/events/kvm.h>
 
 #include "trace.h"
@@ -36,9 +36,9 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		      kvm_vcpu_hvc_get_imm(vcpu));
 	vcpu->stat.hvc_exit_stat++;
 
-	ret = kvm_psci_call(vcpu);
+	ret = kvm_hvc_call_handler(vcpu);
 	if (ret < 0) {
-		kvm_inject_undefined(vcpu);
+		vcpu_set_reg(vcpu, 0, ~0UL);
 		return 1;
 	}
 
@@ -47,7 +47,16 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
 static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
-	kvm_inject_undefined(vcpu);
+	/*
+	 * "If an SMC instruction executed at Non-secure EL1 is
+	 * trapped to EL2 because HCR_EL2.TSC is 1, the exception is a
+	 * Trap exception, not a Secure Monitor Call exception [...]"
+	 *
+	 * We need to advance the PC after the trap, as it would
+	 * otherwise return to the same address...
+	 */
+	vcpu_set_reg(vcpu, 0, ~0UL);
+	kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
 	return 1;
 }
 
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 9b49867..6b32dc5 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -10,7 +10,6 @@
 	select ZONE_DMA if ARM_LPAE
 	select GPIOLIB
 	select PCI_QUIRKS if PCI
-	select OF_ADDRESS_PCI
 
 if ARCH_MVEBU
 
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 5361287..7381eeb 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -16,6 +16,7 @@
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_GIGANTIC_PAGE if (MEMORY_ISOLATION && COMPACTION) || CMA
 	select ARCH_HAS_KCOV
+	select ARCH_HAS_MEMBARRIER_SYNC_CORE
 	select ARCH_HAS_SET_MEMORY
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAS_STRICT_KERNEL_RWX
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 3873dd7..1241fb2 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -116,6 +116,24 @@
 	.endm
 
 /*
+ * Value prediction barrier
+ */
+	.macro	csdb
+	hint	#20
+	.endm
+
+/*
+ * Sanitise a 64-bit bounded index wrt speculation, returning zero if out
+ * of bounds.
+ */
+	.macro	mask_nospec64, idx, limit, tmp
+	sub	\tmp, \idx, \limit
+	bic	\tmp, \tmp, \idx
+	and	\idx, \idx, \tmp, asr #63
+	csdb
+	.endm
+
+/*
  * NOP sequence
  */
 	.macro	nops, num
@@ -514,7 +532,7 @@ alternative_endif
  * 	phys:	physical address, preserved
  * 	ttbr:	returns the TTBR value
  */
-	.macro	phys_to_ttbr, phys, ttbr
+	.macro	phys_to_ttbr, ttbr, phys
 #ifdef CONFIG_ARM64_PA_BITS_52
 	orr	\ttbr, \phys, \phys, lsr #46
 	and	\ttbr, \ttbr, #TTBR_BADDR_MASK_52
@@ -523,6 +541,29 @@ alternative_endif
 #endif
 	.endm
 
+	.macro	phys_to_pte, pte, phys
+#ifdef CONFIG_ARM64_PA_BITS_52
+	/*
+	 * We assume \phys is 64K aligned and this is guaranteed by only
+	 * supporting this configuration with 64K pages.
+	 */
+	orr	\pte, \phys, \phys, lsr #36
+	and	\pte, \pte, #PTE_ADDR_MASK
+#else
+	mov	\pte, \phys
+#endif
+	.endm
+
+	.macro	pte_to_phys, phys, pte
+#ifdef CONFIG_ARM64_PA_BITS_52
+	ubfiz	\phys, \pte, #(48 - 16 - 12), #16
+	bfxil	\phys, \pte, #16, #32
+	lsl	\phys, \phys, #16
+#else
+	and	\phys, \pte, #PTE_ADDR_MASK
+#endif
+	.endm
+
 /**
  * Errata workaround prior to disable MMU. Insert an ISB immediately prior
  * to executing the MSR that will change SCTLR_ELn[M] from a value of 1 to 0.
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
index 77651c4..f11518a 100644
--- a/arch/arm64/include/asm/barrier.h
+++ b/arch/arm64/include/asm/barrier.h
@@ -32,6 +32,7 @@
 #define dsb(opt)	asm volatile("dsb " #opt : : : "memory")
 
 #define psb_csync()	asm volatile("hint #17" : : : "memory")
+#define csdb()		asm volatile("hint #20" : : : "memory")
 
 #define mb()		dsb(sy)
 #define rmb()		dsb(ld)
@@ -40,6 +41,27 @@
 #define dma_rmb()	dmb(oshld)
 #define dma_wmb()	dmb(oshst)
 
+/*
+ * Generate a mask for array_index__nospec() that is ~0UL when 0 <= idx < sz
+ * and 0 otherwise.
+ */
+#define array_index_mask_nospec array_index_mask_nospec
+static inline unsigned long array_index_mask_nospec(unsigned long idx,
+						    unsigned long sz)
+{
+	unsigned long mask;
+
+	asm volatile(
+	"	cmp	%1, %2\n"
+	"	sbc	%0, xzr, xzr\n"
+	: "=r" (mask)
+	: "r" (idx), "Ir" (sz)
+	: "cc");
+
+	csdb();
+	return mask;
+}
+
 #define __smp_mb()	dmb(ish)
 #define __smp_rmb()	dmb(ishld)
 #define __smp_wmb()	dmb(ishst)
diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h
index 5bb2fd4..07fe247 100644
--- a/arch/arm64/include/asm/futex.h
+++ b/arch/arm64/include/asm/futex.h
@@ -48,9 +48,10 @@ do {									\
 } while (0)
 
 static inline int
-arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
+arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *_uaddr)
 {
 	int oldval = 0, ret, tmp;
+	u32 __user *uaddr = __uaccess_mask_ptr(_uaddr);
 
 	pagefault_disable();
 
@@ -88,15 +89,17 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
 }
 
 static inline int
-futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *_uaddr,
 			      u32 oldval, u32 newval)
 {
 	int ret = 0;
 	u32 val, tmp;
+	u32 __user *uaddr;
 
-	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+	if (!access_ok(VERIFY_WRITE, _uaddr, sizeof(u32)))
 		return -EFAULT;
 
+	uaddr = __uaccess_mask_ptr(_uaddr);
 	uaccess_enable();
 	asm volatile("// futex_atomic_cmpxchg_inatomic\n"
 "	prfm	pstl1strm, %2\n"
diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
index e266f80e..8758bb0 100644
--- a/arch/arm64/include/asm/kasan.h
+++ b/arch/arm64/include/asm/kasan.h
@@ -12,7 +12,8 @@
 
 /*
  * KASAN_SHADOW_START: beginning of the kernel virtual addresses.
- * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/8 of kernel virtual addresses.
+ * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/N of kernel virtual addresses,
+ * where N = (1 << KASAN_SHADOW_SCALE_SHIFT).
  */
 #define KASAN_SHADOW_START      (VA_START)
 #define KASAN_SHADOW_END        (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
@@ -20,14 +21,16 @@
 /*
  * This value is used to map an address to the corresponding shadow
  * address by the following formula:
- *     shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;
+ *     shadow_addr = (address >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET
  *
- * (1 << 61) shadow addresses - [KASAN_SHADOW_OFFSET,KASAN_SHADOW_END]
- * cover all 64-bits of virtual addresses. So KASAN_SHADOW_OFFSET
- * should satisfy the following equation:
- *      KASAN_SHADOW_OFFSET = KASAN_SHADOW_END - (1ULL << 61)
+ * (1 << (64 - KASAN_SHADOW_SCALE_SHIFT)) shadow addresses that lie in range
+ * [KASAN_SHADOW_OFFSET, KASAN_SHADOW_END) cover all 64-bits of virtual
+ * addresses. So KASAN_SHADOW_OFFSET should satisfy the following equation:
+ *      KASAN_SHADOW_OFFSET = KASAN_SHADOW_END -
+ *				(1ULL << (64 - KASAN_SHADOW_SCALE_SHIFT))
  */
-#define KASAN_SHADOW_OFFSET     (KASAN_SHADOW_END - (1ULL << (64 - 3)))
+#define KASAN_SHADOW_OFFSET     (KASAN_SHADOW_END - (1ULL << \
+					(64 - KASAN_SHADOW_SCALE_SHIFT)))
 
 void kasan_init(void);
 void kasan_copy_shadow(pgd_t *pgdir);
diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 82386e8..a780f67 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -123,16 +123,8 @@
 /*
  * Initial memory map attributes.
  */
-#define _SWAPPER_PTE_FLAGS	(PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
-#define _SWAPPER_PMD_FLAGS	(PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
-
-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
-#define SWAPPER_PTE_FLAGS	(_SWAPPER_PTE_FLAGS | PTE_NG)
-#define SWAPPER_PMD_FLAGS	(_SWAPPER_PMD_FLAGS | PMD_SECT_NG)
-#else
-#define SWAPPER_PTE_FLAGS	_SWAPPER_PTE_FLAGS
-#define SWAPPER_PMD_FLAGS	_SWAPPER_PMD_FLAGS
-#endif
+#define SWAPPER_PTE_FLAGS	(PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
+#define SWAPPER_PMD_FLAGS	(PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
 
 #if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_MM_MMUFLAGS	(PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 4485ae8..a73f63a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -415,4 +415,10 @@ static inline void kvm_arm_vhe_guest_exit(void)
 {
 	local_daif_restore(DAIF_PROCCTX_NOIRQ);
 }
+
+static inline bool kvm_arm_harden_branch_predictor(void)
+{
+	return cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR);
+}
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/include/asm/kvm_psci.h b/arch/arm64/include/asm/kvm_psci.h
deleted file mode 100644
index bc39e55..0000000
--- a/arch/arm64/include/asm/kvm_psci.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2012,2013 - ARM Ltd
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __ARM64_KVM_PSCI_H__
-#define __ARM64_KVM_PSCI_H__
-
-#define KVM_ARM_PSCI_0_1	1
-#define KVM_ARM_PSCI_0_2	2
-
-int kvm_psci_version(struct kvm_vcpu *vcpu);
-int kvm_psci_call(struct kvm_vcpu *vcpu);
-
-#endif /* __ARM64_KVM_PSCI_H__ */
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index d4bae7d..50fa96a 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -85,7 +85,8 @@
  * stack size when KASAN is in use.
  */
 #ifdef CONFIG_KASAN
-#define KASAN_SHADOW_SIZE	(UL(1) << (VA_BITS - 3))
+#define KASAN_SHADOW_SCALE_SHIFT 3
+#define KASAN_SHADOW_SIZE	(UL(1) << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT))
 #define KASAN_THREAD_SHIFT	1
 #else
 #define KASAN_SHADOW_SIZE	(0)
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 22a9268..2db84df 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -37,13 +37,11 @@
 #define _PROT_DEFAULT		(PTE_TYPE_PAGE | PTE_AF | PTE_SHARED)
 #define _PROT_SECT_DEFAULT	(PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S)
 
-#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
-#define PROT_DEFAULT		(_PROT_DEFAULT | PTE_NG)
-#define PROT_SECT_DEFAULT	(_PROT_SECT_DEFAULT | PMD_SECT_NG)
-#else
-#define PROT_DEFAULT		_PROT_DEFAULT
-#define PROT_SECT_DEFAULT	_PROT_SECT_DEFAULT
-#endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */
+#define PTE_MAYBE_NG		(arm64_kernel_unmapped_at_el0() ? PTE_NG : 0)
+#define PMD_MAYBE_NG		(arm64_kernel_unmapped_at_el0() ? PMD_SECT_NG : 0)
+
+#define PROT_DEFAULT		(_PROT_DEFAULT | PTE_MAYBE_NG)
+#define PROT_SECT_DEFAULT	(_PROT_SECT_DEFAULT | PMD_MAYBE_NG)
 
 #define PROT_DEVICE_nGnRnE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRnE))
 #define PROT_DEVICE_nGnRE	(PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_DEVICE_nGnRE))
@@ -55,22 +53,22 @@
 #define PROT_SECT_NORMAL	(PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
 #define PROT_SECT_NORMAL_EXEC	(PROT_SECT_DEFAULT | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
 
-#define _PAGE_DEFAULT		(PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
-#define _HYP_PAGE_DEFAULT	(_PAGE_DEFAULT & ~PTE_NG)
+#define _PAGE_DEFAULT		(_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL))
+#define _HYP_PAGE_DEFAULT	_PAGE_DEFAULT
 
-#define PAGE_KERNEL		__pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE)
-#define PAGE_KERNEL_RO		__pgprot(_PAGE_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
-#define PAGE_KERNEL_ROX		__pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_RDONLY)
-#define PAGE_KERNEL_EXEC	__pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE)
-#define PAGE_KERNEL_EXEC_CONT	__pgprot(_PAGE_DEFAULT | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_CONT)
+#define PAGE_KERNEL		__pgprot(PROT_NORMAL)
+#define PAGE_KERNEL_RO		__pgprot((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY)
+#define PAGE_KERNEL_ROX		__pgprot((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY)
+#define PAGE_KERNEL_EXEC	__pgprot(PROT_NORMAL & ~PTE_PXN)
+#define PAGE_KERNEL_EXEC_CONT	__pgprot((PROT_NORMAL & ~PTE_PXN) | PTE_CONT)
 
 #define PAGE_HYP		__pgprot(_HYP_PAGE_DEFAULT | PTE_HYP | PTE_HYP_XN)
 #define PAGE_HYP_EXEC		__pgprot(_HYP_PAGE_DEFAULT | PTE_HYP | PTE_RDONLY)
 #define PAGE_HYP_RO		__pgprot(_HYP_PAGE_DEFAULT | PTE_HYP | PTE_RDONLY | PTE_HYP_XN)
 #define PAGE_HYP_DEVICE		__pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
 
-#define PAGE_S2			__pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
-#define PAGE_S2_DEVICE		__pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN)
+#define PAGE_S2			__pgprot(_PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
+#define PAGE_S2_DEVICE		__pgprot(_PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN)
 
 #define PAGE_NONE		__pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
 #define PAGE_SHARED		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6db43eb..fce604e 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -21,6 +21,9 @@
 
 #define TASK_SIZE_64		(UL(1) << VA_BITS)
 
+#define KERNEL_DS	UL(-1)
+#define USER_DS		(TASK_SIZE_64 - 1)
+
 #ifndef __ASSEMBLY__
 
 /*
diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h
index fdb827c..ebdae15 100644
--- a/arch/arm64/include/asm/spinlock.h
+++ b/arch/arm64/include/asm/spinlock.h
@@ -87,8 +87,8 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)
 	"	cbnz	%w1, 1f\n"
 	"	add	%w1, %w0, %3\n"
 	"	casa	%w0, %w1, %2\n"
-	"	and	%w1, %w1, #0xffff\n"
-	"	eor	%w1, %w1, %w0, lsr #16\n"
+	"	sub	%w1, %w1, %3\n"
+	"	eor	%w1, %w1, %w0\n"
 	"1:")
 	: "=&r" (lockval), "=&r" (tmp), "+Q" (*lock)
 	: "I" (1 << TICKET_SHIFT)
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index 59fda529..543e11f 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -35,16 +35,20 @@
 #include <asm/compiler.h>
 #include <asm/extable.h>
 
-#define KERNEL_DS	(-1UL)
 #define get_ds()	(KERNEL_DS)
-
-#define USER_DS		TASK_SIZE_64
 #define get_fs()	(current_thread_info()->addr_limit)
 
 static inline void set_fs(mm_segment_t fs)
 {
 	current_thread_info()->addr_limit = fs;
 
+	/*
+	 * Prevent a mispredicted conditional call to set_fs from forwarding
+	 * the wrong address limit to access_ok under speculation.
+	 */
+	dsb(nsh);
+	isb();
+
 	/* On user-mode return, check fs is correct */
 	set_thread_flag(TIF_FSCHECK);
 
@@ -66,22 +70,32 @@ static inline void set_fs(mm_segment_t fs)
  * Returns 1 if the range is valid, 0 otherwise.
  *
  * This is equivalent to the following test:
- * (u65)addr + (u65)size <= current->addr_limit
- *
- * This needs 65-bit arithmetic.
+ * (u65)addr + (u65)size <= (u65)current->addr_limit + 1
  */
-#define __range_ok(addr, size)						\
-({									\
-	unsigned long __addr = (unsigned long)(addr);			\
-	unsigned long flag, roksum;					\
-	__chk_user_ptr(addr);						\
-	asm("adds %1, %1, %3; ccmp %1, %4, #2, cc; cset %0, ls"		\
-		: "=&r" (flag), "=&r" (roksum)				\
-		: "1" (__addr), "Ir" (size),				\
-		  "r" (current_thread_info()->addr_limit)		\
-		: "cc");						\
-	flag;								\
-})
+static inline unsigned long __range_ok(unsigned long addr, unsigned long size)
+{
+	unsigned long limit = current_thread_info()->addr_limit;
+
+	__chk_user_ptr(addr);
+	asm volatile(
+	// A + B <= C + 1 for all A,B,C, in four easy steps:
+	// 1: X = A + B; X' = X % 2^64
+	"	adds	%0, %0, %2\n"
+	// 2: Set C = 0 if X > 2^64, to guarantee X' > C in step 4
+	"	csel	%1, xzr, %1, hi\n"
+	// 3: Set X' = ~0 if X >= 2^64. For X == 2^64, this decrements X'
+	//    to compensate for the carry flag being set in step 4. For
+	//    X > 2^64, X' merely has to remain nonzero, which it does.
+	"	csinv	%0, %0, xzr, cc\n"
+	// 4: For X < 2^64, this gives us X' - C - 1 <= 0, where the -1
+	//    comes from the carry in being clear. Otherwise, we are
+	//    testing X' - C == 0, subject to the previous adjustments.
+	"	sbcs	xzr, %0, %1\n"
+	"	cset	%0, ls\n"
+	: "+r" (addr), "+r" (limit) : "Ir" (size) : "cc");
+
+	return addr;
+}
 
 /*
  * When dealing with data aborts, watchpoints, or instruction traps we may end
@@ -90,7 +104,7 @@ static inline void set_fs(mm_segment_t fs)
  */
 #define untagged_addr(addr)		sign_extend64(addr, 55)
 
-#define access_ok(type, addr, size)	__range_ok(addr, size)
+#define access_ok(type, addr, size)	__range_ok((unsigned long)(addr), size)
 #define user_addr_max			get_fs
 
 #define _ASM_EXTABLE(from, to)						\
@@ -221,6 +235,26 @@ static inline void uaccess_enable_not_uao(void)
 }
 
 /*
+ * Sanitise a uaccess pointer such that it becomes NULL if above the
+ * current addr_limit.
+ */
+#define uaccess_mask_ptr(ptr) (__typeof__(ptr))__uaccess_mask_ptr(ptr)
+static inline void __user *__uaccess_mask_ptr(const void __user *ptr)
+{
+	void __user *safe_ptr;
+
+	asm volatile(
+	"	bics	xzr, %1, %2\n"
+	"	csel	%0, %1, xzr, eq\n"
+	: "=&r" (safe_ptr)
+	: "r" (ptr), "r" (current_thread_info()->addr_limit)
+	: "cc");
+
+	csdb();
+	return safe_ptr;
+}
+
+/*
  * The "__xxx" versions of the user access functions do not verify the address
  * space - it must have been done previously with a separate "access_ok()"
  * call.
@@ -272,28 +306,33 @@ do {									\
 	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
 } while (0)
 
-#define __get_user(x, ptr)						\
+#define __get_user_check(x, ptr, err)					\
 ({									\
-	int __gu_err = 0;						\
-	__get_user_err((x), (ptr), __gu_err);				\
-	__gu_err;							\
+	__typeof__(*(ptr)) __user *__p = (ptr);				\
+	might_fault();							\
+	if (access_ok(VERIFY_READ, __p, sizeof(*__p))) {		\
+		__p = uaccess_mask_ptr(__p);				\
+		__get_user_err((x), __p, (err));			\
+	} else {							\
+		(x) = 0; (err) = -EFAULT;				\
+	}								\
 })
 
 #define __get_user_error(x, ptr, err)					\
 ({									\
-	__get_user_err((x), (ptr), (err));				\
+	__get_user_check((x), (ptr), (err));				\
 	(void)0;							\
 })
 
-#define get_user(x, ptr)						\
+#define __get_user(x, ptr)						\
 ({									\
-	__typeof__(*(ptr)) __user *__p = (ptr);				\
-	might_fault();							\
-	access_ok(VERIFY_READ, __p, sizeof(*__p)) ?			\
-		__get_user((x), __p) :					\
-		((x) = 0, -EFAULT);					\
+	int __gu_err = 0;						\
+	__get_user_check((x), (ptr), __gu_err);				\
+	__gu_err;							\
 })
 
+#define get_user	__get_user
+
 #define __put_user_asm(instr, alt_instr, reg, x, addr, err, feature)	\
 	asm volatile(							\
 	"1:"ALTERNATIVE(instr "     " reg "1, [%2]\n",			\
@@ -336,43 +375,63 @@ do {									\
 	uaccess_disable_not_uao();					\
 } while (0)
 
-#define __put_user(x, ptr)						\
+#define __put_user_check(x, ptr, err)					\
 ({									\
-	int __pu_err = 0;						\
-	__put_user_err((x), (ptr), __pu_err);				\
-	__pu_err;							\
+	__typeof__(*(ptr)) __user *__p = (ptr);				\
+	might_fault();							\
+	if (access_ok(VERIFY_WRITE, __p, sizeof(*__p))) {		\
+		__p = uaccess_mask_ptr(__p);				\
+		__put_user_err((x), __p, (err));			\
+	} else	{							\
+		(err) = -EFAULT;					\
+	}								\
 })
 
 #define __put_user_error(x, ptr, err)					\
 ({									\
-	__put_user_err((x), (ptr), (err));				\
+	__put_user_check((x), (ptr), (err));				\
 	(void)0;							\
 })
 
-#define put_user(x, ptr)						\
+#define __put_user(x, ptr)						\
 ({									\
-	__typeof__(*(ptr)) __user *__p = (ptr);				\
-	might_fault();							\
-	access_ok(VERIFY_WRITE, __p, sizeof(*__p)) ?			\
-		__put_user((x), __p) :					\
-		-EFAULT;						\
+	int __pu_err = 0;						\
+	__put_user_check((x), (ptr), __pu_err);				\
+	__pu_err;							\
 })
 
+#define put_user	__put_user
+
 extern unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n);
-#define raw_copy_from_user __arch_copy_from_user
+#define raw_copy_from_user(to, from, n)					\
+({									\
+	__arch_copy_from_user((to), __uaccess_mask_ptr(from), (n));	\
+})
+
 extern unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n);
-#define raw_copy_to_user __arch_copy_to_user
-extern unsigned long __must_check raw_copy_in_user(void __user *to, const void __user *from, unsigned long n);
-extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
+#define raw_copy_to_user(to, from, n)					\
+({									\
+	__arch_copy_to_user(__uaccess_mask_ptr(to), (from), (n));	\
+})
+
+extern unsigned long __must_check __arch_copy_in_user(void __user *to, const void __user *from, unsigned long n);
+#define raw_copy_in_user(to, from, n)					\
+({									\
+	__arch_copy_in_user(__uaccess_mask_ptr(to),			\
+			    __uaccess_mask_ptr(from), (n));		\
+})
+
 #define INLINE_COPY_TO_USER
 #define INLINE_COPY_FROM_USER
 
-static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
+extern unsigned long __must_check __arch_clear_user(void __user *to, unsigned long n);
+static inline unsigned long __must_check __clear_user(void __user *to, unsigned long n)
 {
 	if (access_ok(VERIFY_WRITE, to, n))
-		n = __clear_user(to, n);
+		n = __arch_clear_user(__uaccess_mask_ptr(to), n);
 	return n;
 }
+#define clear_user	__clear_user
 
 extern long strncpy_from_user(char *dest, const char __user *src, long count);
 
@@ -386,7 +445,7 @@ extern unsigned long __must_check __copy_user_flushcache(void *to, const void __
 static inline int __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size)
 {
 	kasan_check_write(dst, size);
-	return __copy_user_flushcache(dst, src, size);
+	return __copy_user_flushcache(dst, __uaccess_mask_ptr(src), size);
 }
 #endif
 
diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c
index 67368c7..66be504 100644
--- a/arch/arm64/kernel/arm64ksyms.c
+++ b/arch/arm64/kernel/arm64ksyms.c
@@ -37,8 +37,8 @@ EXPORT_SYMBOL(clear_page);
 	/* user mem (segment) */
 EXPORT_SYMBOL(__arch_copy_from_user);
 EXPORT_SYMBOL(__arch_copy_to_user);
-EXPORT_SYMBOL(__clear_user);
-EXPORT_SYMBOL(raw_copy_in_user);
+EXPORT_SYMBOL(__arch_clear_user);
+EXPORT_SYMBOL(__arch_copy_in_user);
 
 	/* physical memory */
 EXPORT_SYMBOL(memstart_addr);
diff --git a/arch/arm64/kernel/bpi.S b/arch/arm64/kernel/bpi.S
index 76225c2..e5de335 100644
--- a/arch/arm64/kernel/bpi.S
+++ b/arch/arm64/kernel/bpi.S
@@ -17,6 +17,7 @@
  */
 
 #include <linux/linkage.h>
+#include <linux/arm-smccc.h>
 
 .macro ventry target
 	.rept 31
@@ -53,30 +54,6 @@
 	vectors __kvm_hyp_vector
 	.endr
 ENTRY(__bp_harden_hyp_vecs_end)
-ENTRY(__psci_hyp_bp_inval_start)
-	sub	sp, sp, #(8 * 18)
-	stp	x16, x17, [sp, #(16 * 0)]
-	stp	x14, x15, [sp, #(16 * 1)]
-	stp	x12, x13, [sp, #(16 * 2)]
-	stp	x10, x11, [sp, #(16 * 3)]
-	stp	x8, x9, [sp, #(16 * 4)]
-	stp	x6, x7, [sp, #(16 * 5)]
-	stp	x4, x5, [sp, #(16 * 6)]
-	stp	x2, x3, [sp, #(16 * 7)]
-	stp	x0, x1, [sp, #(16 * 8)]
-	mov	x0, #0x84000000
-	smc	#0
-	ldp	x16, x17, [sp, #(16 * 0)]
-	ldp	x14, x15, [sp, #(16 * 1)]
-	ldp	x12, x13, [sp, #(16 * 2)]
-	ldp	x10, x11, [sp, #(16 * 3)]
-	ldp	x8, x9, [sp, #(16 * 4)]
-	ldp	x6, x7, [sp, #(16 * 5)]
-	ldp	x4, x5, [sp, #(16 * 6)]
-	ldp	x2, x3, [sp, #(16 * 7)]
-	ldp	x0, x1, [sp, #(16 * 8)]
-	add	sp, sp, #(8 * 18)
-ENTRY(__psci_hyp_bp_inval_end)
 
 ENTRY(__qcom_hyp_sanitize_link_stack_start)
 	stp     x29, x30, [sp, #-16]!
@@ -85,3 +62,22 @@
 	.endr
 	ldp	x29, x30, [sp], #16
 ENTRY(__qcom_hyp_sanitize_link_stack_end)
+
+.macro smccc_workaround_1 inst
+	sub	sp, sp, #(8 * 4)
+	stp	x2, x3, [sp, #(8 * 0)]
+	stp	x0, x1, [sp, #(8 * 2)]
+	mov	w0, #ARM_SMCCC_ARCH_WORKAROUND_1
+	\inst	#0
+	ldp	x2, x3, [sp, #(8 * 0)]
+	ldp	x0, x1, [sp, #(8 * 2)]
+	add	sp, sp, #(8 * 4)
+.endm
+
+ENTRY(__smccc_workaround_1_smc_start)
+	smccc_workaround_1	smc
+ENTRY(__smccc_workaround_1_smc_end)
+
+ENTRY(__smccc_workaround_1_hvc_start)
+	smccc_workaround_1	hvc
+ENTRY(__smccc_workaround_1_hvc_end)
diff --git a/arch/arm64/kernel/cpu-reset.S b/arch/arm64/kernel/cpu-reset.S
index 2a752cb2..8021b46 100644
--- a/arch/arm64/kernel/cpu-reset.S
+++ b/arch/arm64/kernel/cpu-reset.S
@@ -16,7 +16,7 @@
 #include <asm/virt.h>
 
 .text
-.pushsection    .idmap.text, "ax"
+.pushsection    .idmap.text, "awx"
 
 /*
  * __cpu_soft_restart(el2_switch, entry, arg0, arg1, arg2) - Helper for
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index ed68818..0782359 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -67,9 +67,12 @@ static int cpu_enable_trap_ctr_access(void *__unused)
 DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
 
 #ifdef CONFIG_KVM
-extern char __psci_hyp_bp_inval_start[], __psci_hyp_bp_inval_end[];
 extern char __qcom_hyp_sanitize_link_stack_start[];
 extern char __qcom_hyp_sanitize_link_stack_end[];
+extern char __smccc_workaround_1_smc_start[];
+extern char __smccc_workaround_1_smc_end[];
+extern char __smccc_workaround_1_hvc_start[];
+extern char __smccc_workaround_1_hvc_end[];
 
 static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
 				const char *hyp_vecs_end)
@@ -112,10 +115,12 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
 	spin_unlock(&bp_lock);
 }
 #else
-#define __psci_hyp_bp_inval_start		NULL
-#define __psci_hyp_bp_inval_end			NULL
 #define __qcom_hyp_sanitize_link_stack_start	NULL
 #define __qcom_hyp_sanitize_link_stack_end	NULL
+#define __smccc_workaround_1_smc_start		NULL
+#define __smccc_workaround_1_smc_end		NULL
+#define __smccc_workaround_1_hvc_start		NULL
+#define __smccc_workaround_1_hvc_end		NULL
 
 static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
 				      const char *hyp_vecs_start,
@@ -142,17 +147,59 @@ static void  install_bp_hardening_cb(const struct arm64_cpu_capabilities *entry,
 	__install_bp_hardening_cb(fn, hyp_vecs_start, hyp_vecs_end);
 }
 
+#include <uapi/linux/psci.h>
+#include <linux/arm-smccc.h>
 #include <linux/psci.h>
 
-static int enable_psci_bp_hardening(void *data)
+static void call_smc_arch_workaround_1(void)
+{
+	arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
+}
+
+static void call_hvc_arch_workaround_1(void)
+{
+	arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
+}
+
+static int enable_smccc_arch_workaround_1(void *data)
 {
 	const struct arm64_cpu_capabilities *entry = data;
+	bp_hardening_cb_t cb;
+	void *smccc_start, *smccc_end;
+	struct arm_smccc_res res;
 
-	if (psci_ops.get_version)
-		install_bp_hardening_cb(entry,
-				       (bp_hardening_cb_t)psci_ops.get_version,
-				       __psci_hyp_bp_inval_start,
-				       __psci_hyp_bp_inval_end);
+	if (!entry->matches(entry, SCOPE_LOCAL_CPU))
+		return 0;
+
+	if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
+		return 0;
+
+	switch (psci_ops.conduit) {
+	case PSCI_CONDUIT_HVC:
+		arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+				  ARM_SMCCC_ARCH_WORKAROUND_1, &res);
+		if (res.a0)
+			return 0;
+		cb = call_hvc_arch_workaround_1;
+		smccc_start = __smccc_workaround_1_hvc_start;
+		smccc_end = __smccc_workaround_1_hvc_end;
+		break;
+
+	case PSCI_CONDUIT_SMC:
+		arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+				  ARM_SMCCC_ARCH_WORKAROUND_1, &res);
+		if (res.a0)
+			return 0;
+		cb = call_smc_arch_workaround_1;
+		smccc_start = __smccc_workaround_1_smc_start;
+		smccc_end = __smccc_workaround_1_smc_end;
+		break;
+
+	default:
+		return 0;
+	}
+
+	install_bp_hardening_cb(entry, cb, smccc_start, smccc_end);
 
 	return 0;
 }
@@ -333,22 +380,22 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 	{
 		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
-		.enable = enable_psci_bp_hardening,
+		.enable = enable_smccc_arch_workaround_1,
 	},
 	{
 		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
-		.enable = enable_psci_bp_hardening,
+		.enable = enable_smccc_arch_workaround_1,
 	},
 	{
 		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
-		.enable = enable_psci_bp_hardening,
+		.enable = enable_smccc_arch_workaround_1,
 	},
 	{
 		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
-		.enable = enable_psci_bp_hardening,
+		.enable = enable_smccc_arch_workaround_1,
 	},
 	{
 		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
@@ -362,12 +409,12 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 	{
 		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
 		MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
-		.enable = enable_psci_bp_hardening,
+		.enable = enable_smccc_arch_workaround_1,
 	},
 	{
 		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
 		MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
-		.enable = enable_psci_bp_hardening,
+		.enable = enable_smccc_arch_workaround_1,
 	},
 #endif
 	{
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 0fb6a31..29b1f87 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -856,12 +856,23 @@ static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
 static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
 				int __unused)
 {
+	char const *str = "command line option";
 	u64 pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
 
-	/* Forced on command line? */
+	/*
+	 * For reasons that aren't entirely clear, enabling KPTI on Cavium
+	 * ThunderX leads to apparent I-cache corruption of kernel text, which
+	 * ends as well as you might imagine. Don't even try.
+	 */
+	if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_27456)) {
+		str = "ARM64_WORKAROUND_CAVIUM_27456";
+		__kpti_forced = -1;
+	}
+
+	/* Forced? */
 	if (__kpti_forced) {
-		pr_info_once("kernel page table isolation forced %s by command line option\n",
-			     __kpti_forced > 0 ? "ON" : "OFF");
+		pr_info_once("kernel page table isolation forced %s by %s\n",
+			     __kpti_forced > 0 ? "ON" : "OFF", str);
 		return __kpti_forced > 0;
 	}
 
@@ -881,6 +892,30 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
 						     ID_AA64PFR0_CSV3_SHIFT);
 }
 
+static int kpti_install_ng_mappings(void *__unused)
+{
+	typedef void (kpti_remap_fn)(int, int, phys_addr_t);
+	extern kpti_remap_fn idmap_kpti_install_ng_mappings;
+	kpti_remap_fn *remap_fn;
+
+	static bool kpti_applied = false;
+	int cpu = smp_processor_id();
+
+	if (kpti_applied)
+		return 0;
+
+	remap_fn = (void *)__pa_symbol(idmap_kpti_install_ng_mappings);
+
+	cpu_install_idmap();
+	remap_fn(cpu, num_online_cpus(), __pa_symbol(swapper_pg_dir));
+	cpu_uninstall_idmap();
+
+	if (!cpu)
+		kpti_applied = true;
+
+	return 0;
+}
+
 static int __init parse_kpti(char *str)
 {
 	bool enabled;
@@ -1004,6 +1039,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.capability = ARM64_UNMAP_KERNEL_AT_EL0,
 		.def_scope = SCOPE_SYSTEM,
 		.matches = unmap_kernel_at_el0,
+		.enable = kpti_install_ng_mappings,
 	},
 #endif
 	{
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index b34e717..ec2ee72 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -167,10 +167,10 @@
 	.else
 	add	x21, sp, #S_FRAME_SIZE
 	get_thread_info tsk
-	/* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
+	/* Save the task's original addr_limit and set USER_DS */
 	ldr	x20, [tsk, #TSK_TI_ADDR_LIMIT]
 	str	x20, [sp, #S_ORIG_ADDR_LIMIT]
-	mov	x20, #TASK_SIZE_64
+	mov	x20, #USER_DS
 	str	x20, [tsk, #TSK_TI_ADDR_LIMIT]
 	/* No need to reset PSTATE.UAO, hardware's already set it to 0 for us */
 	.endif /* \el == 0 */
@@ -324,6 +324,10 @@
 	ldp	x28, x29, [sp, #16 * 14]
 	ldr	lr, [sp, #S_LR]
 	add	sp, sp, #S_FRAME_SIZE		// restore sp
+	/*
+	 * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on eret context synchronization
+	 * when returning from IPI handler, and when returning to user-space.
+	 */
 
 	.if	\el == 0
 alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
@@ -378,6 +382,7 @@
  * x7 is reserved for the system call number in 32-bit mode.
  */
 wsc_nr	.req	w25		// number of system calls
+xsc_nr	.req	x25		// number of system calls (zero-extended)
 wscno	.req	w26		// syscall number
 xscno	.req	x26		// syscall number (zero-extended)
 stbl	.req	x27		// syscall table pointer
@@ -766,7 +771,10 @@
 	 * Stack or PC alignment exception handling
 	 */
 	mrs	x26, far_el1
-	enable_daif
+	enable_da_f
+#ifdef CONFIG_TRACE_IRQFLAGS
+	bl	trace_hardirqs_off
+#endif
 	ct_user_exit
 	mov	x0, x26
 	mov	x1, x25
@@ -824,6 +832,11 @@
 #endif
 
 	ct_user_exit
+#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
+	tbz	x22, #55, 1f
+	bl	do_el0_irq_bp_hardening
+1:
+#endif
 	irq_handler
 
 #ifdef CONFIG_TRACE_IRQFLAGS
@@ -935,6 +948,7 @@
 	b.ne	__sys_trace
 	cmp     wscno, wsc_nr			// check upper syscall limit
 	b.hs	ni_sys
+	mask_nospec64 xscno, xsc_nr, x19	// enforce bounds for syscall number
 	ldr	x16, [stbl, xscno, lsl #3]	// address in the syscall table
 	blr	x16				// call sys_* routine
 	b	ret_fast_syscall
@@ -1013,16 +1027,9 @@
 	orr	\tmp, \tmp, #USER_ASID_FLAG
 	msr	ttbr1_el1, \tmp
 	/*
-	 * We avoid running the post_ttbr_update_workaround here because the
-	 * user and kernel ASIDs don't have conflicting mappings, so any
-	 * "blessing" as described in:
-	 *
-	 *   http://lkml.kernel.org/r/56BB848A.6060603@caviumnetworks.com
-	 *
-	 * will not hurt correctness. Whilst this may partially defeat the
-	 * point of using split ASIDs in the first place, it avoids
-	 * the hit of invalidating the entire I-cache on every return to
-	 * userspace.
+	 * We avoid running the post_ttbr_update_workaround here because
+	 * it's only needed by Cavium ThunderX, which requires KPTI to be
+	 * disabled.
 	 */
 	.endm
 
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index ba3ab047..2b6b8b2 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -148,26 +148,6 @@
 ENDPROC(preserve_boot_args)
 
 /*
- * Macro to arrange a physical address in a page table entry, taking care of
- * 52-bit addresses.
- *
- * Preserves:	phys
- * Returns:	pte
- */
-	.macro	phys_to_pte, phys, pte
-#ifdef CONFIG_ARM64_PA_BITS_52
-	/*
-	 * We assume \phys is 64K aligned and this is guaranteed by only
-	 * supporting this configuration with 64K pages.
-	 */
-	orr	\pte, \phys, \phys, lsr #36
-	and	\pte, \pte, #PTE_ADDR_MASK
-#else
-	mov	\pte, \phys
-#endif
-	.endm
-
-/*
  * Macro to create a table entry to the next page.
  *
  *	tbl:	page table address
@@ -181,7 +161,7 @@
  */
 	.macro	create_table_entry, tbl, virt, shift, ptrs, tmp1, tmp2
 	add	\tmp1, \tbl, #PAGE_SIZE
-	phys_to_pte \tmp1, \tmp2
+	phys_to_pte \tmp2, \tmp1
 	orr	\tmp2, \tmp2, #PMD_TYPE_TABLE	// address of next table and entry type
 	lsr	\tmp1, \virt, #\shift
 	sub	\ptrs, \ptrs, #1
@@ -207,7 +187,7 @@
  * Returns:	rtbl
  */
 	.macro populate_entries, tbl, rtbl, index, eindex, flags, inc, tmp1
-.Lpe\@:	phys_to_pte \rtbl, \tmp1
+.Lpe\@:	phys_to_pte \tmp1, \rtbl
 	orr	\tmp1, \tmp1, \flags	// tmp1 = table entry
 	str	\tmp1, [\tbl, \index, lsl #3]
 	add	\rtbl, \rtbl, \inc	// rtbl = pa next level
@@ -475,7 +455,7 @@
  * end early head section, begin head code that is also used for
  * hotplug and needs to have the same protections as the text region
  */
-	.section ".idmap.text","ax"
+	.section ".idmap.text","awx"
 
 ENTRY(kimage_vaddr)
 	.quad		_text - TEXT_OFFSET
@@ -776,8 +756,8 @@
 	update_early_cpu_boot_status 0, x1, x2
 	adrp	x1, idmap_pg_dir
 	adrp	x2, swapper_pg_dir
-	phys_to_ttbr x1, x3
-	phys_to_ttbr x2, x4
+	phys_to_ttbr x3, x1
+	phys_to_ttbr x4, x2
 	msr	ttbr0_el1, x3			// load TTBR0
 	msr	ttbr1_el1, x4			// load TTBR1
 	isb
diff --git a/arch/arm64/kernel/hibernate-asm.S b/arch/arm64/kernel/hibernate-asm.S
index 84f5d52f..dd14ab8 100644
--- a/arch/arm64/kernel/hibernate-asm.S
+++ b/arch/arm64/kernel/hibernate-asm.S
@@ -34,12 +34,12 @@
  * each stage of the walk.
  */
 .macro break_before_make_ttbr_switch zero_page, page_table, tmp
-	phys_to_ttbr \zero_page, \tmp
+	phys_to_ttbr \tmp, \zero_page
 	msr	ttbr1_el1, \tmp
 	isb
 	tlbi	vmalle1
 	dsb	nsh
-	phys_to_ttbr \page_table, \tmp
+	phys_to_ttbr \tmp, \page_table
 	msr	ttbr1_el1, \tmp
 	isb
 .endm
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 3affca3..75b220b 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -925,9 +925,8 @@ static void __armv8pmu_probe_pmu(void *info)
 	pmceid[0] = read_sysreg(pmceid0_el0);
 	pmceid[1] = read_sysreg(pmceid1_el0);
 
-	bitmap_from_u32array(cpu_pmu->pmceid_bitmap,
-			     ARMV8_PMUV3_MAX_COMMON_EVENTS, pmceid,
-			     ARRAY_SIZE(pmceid));
+	bitmap_from_arr32(cpu_pmu->pmceid_bitmap,
+			     pmceid, ARMV8_PMUV3_MAX_COMMON_EVENTS);
 }
 
 static int armv8pmu_probe_pmu(struct arm_pmu *cpu_pmu)
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index 10dd16d..bebec8e 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -96,7 +96,7 @@
 	ret
 ENDPROC(__cpu_suspend_enter)
 
-	.pushsection ".idmap.text", "ax"
+	.pushsection ".idmap.text", "awx"
 ENTRY(cpu_resume)
 	bl	el2_setup		// if in EL2 drop to EL1 cleanly
 	bl	__cpu_setup
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 520b0da..e5e741b 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -22,13 +22,14 @@
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 
+#include <kvm/arm_psci.h>
+
 #include <asm/esr.h>
 #include <asm/exception.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_coproc.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_mmu.h>
-#include <asm/kvm_psci.h>
 #include <asm/debug-monitors.h>
 #include <asm/traps.h>
 
@@ -51,7 +52,7 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 			    kvm_vcpu_hvc_get_imm(vcpu));
 	vcpu->stat.hvc_exit_stat++;
 
-	ret = kvm_psci_call(vcpu);
+	ret = kvm_hvc_call_handler(vcpu);
 	if (ret < 0) {
 		vcpu_set_reg(vcpu, 0, ~0UL);
 		return 1;
@@ -62,7 +63,16 @@ static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
 static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
+	/*
+	 * "If an SMC instruction executed at Non-secure EL1 is
+	 * trapped to EL2 because HCR_EL2.TSC is 1, the exception is a
+	 * Trap exception, not a Secure Monitor Call exception [...]"
+	 *
+	 * We need to advance the PC after the trap, as it would
+	 * otherwise return to the same address...
+	 */
 	vcpu_set_reg(vcpu, 0, ~0UL);
+	kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
 	return 1;
 }
 
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index e086c6ef..5aa9ccf 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -63,7 +63,7 @@
 	cmp	x0, #HVC_STUB_HCALL_NR
 	b.lo	__kvm_handle_stub_hvc
 
-	phys_to_ttbr x0, x4
+	phys_to_ttbr x4, x0
 	msr	ttbr0_el2, x4
 
 	mrs	x4, tcr_el1
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index e4f37b9..f36464b 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/arm-smccc.h>
 #include <linux/linkage.h>
 
 #include <asm/alternative.h>
@@ -64,10 +65,11 @@
 	lsr	x0, x1, #ESR_ELx_EC_SHIFT
 
 	cmp	x0, #ESR_ELx_EC_HVC64
+	ccmp	x0, #ESR_ELx_EC_HVC32, #4, ne
 	b.ne	el1_trap
 
-	mrs	x1, vttbr_el2		// If vttbr is valid, the 64bit guest
-	cbnz	x1, el1_trap		// called HVC
+	mrs	x1, vttbr_el2		// If vttbr is valid, the guest
+	cbnz	x1, el1_hvc_guest	// called HVC
 
 	/* Here, we're pretty sure the host called HVC. */
 	ldp	x0, x1, [sp], #16
@@ -100,6 +102,20 @@
 
 	eret
 
+el1_hvc_guest:
+	/*
+	 * Fastest possible path for ARM_SMCCC_ARCH_WORKAROUND_1.
+	 * The workaround has already been applied on the host,
+	 * so let's quickly get back to the guest. We don't bother
+	 * restoring x1, as it can be clobbered anyway.
+	 */
+	ldr	x1, [sp]				// Guest's x0
+	eor	w1, w1, #ARM_SMCCC_ARCH_WORKAROUND_1
+	cbnz	w1, el1_trap
+	mov	x0, x1
+	add	sp, sp, #16
+	eret
+
 el1_trap:
 	/*
 	 * x0: ESR_EC
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 036e1f3..cac6a05 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -19,6 +19,8 @@
 #include <linux/jump_label.h>
 #include <uapi/linux/psci.h>
 
+#include <kvm/arm_psci.h>
+
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_hyp.h>
@@ -348,18 +350,6 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
 	if (exit_code == ARM_EXCEPTION_TRAP && !__populate_fault_info(vcpu))
 		goto again;
 
-	if (exit_code == ARM_EXCEPTION_TRAP &&
-	    (kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_HVC64 ||
-	     kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_HVC32) &&
-	    vcpu_get_reg(vcpu, 0) == PSCI_0_2_FN_PSCI_VERSION) {
-		u64 val = PSCI_RET_NOT_SUPPORTED;
-		if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
-			val = 2;
-
-		vcpu_set_reg(vcpu, 0, val);
-		goto again;
-	}
-
 	if (static_branch_unlikely(&vgic_v2_cpuif_trap) &&
 	    exit_code == ARM_EXCEPTION_TRAP) {
 		bool valid;
diff --git a/arch/arm64/lib/clear_user.S b/arch/arm64/lib/clear_user.S
index 3d69a8d..21ba0b2 100644
--- a/arch/arm64/lib/clear_user.S
+++ b/arch/arm64/lib/clear_user.S
@@ -21,7 +21,7 @@
 
 	.text
 
-/* Prototype: int __clear_user(void *addr, size_t sz)
+/* Prototype: int __arch_clear_user(void *addr, size_t sz)
  * Purpose  : clear some user memory
  * Params   : addr - user memory address to clear
  *          : sz   - number of bytes to clear
@@ -29,7 +29,7 @@
  *
  * Alignment fixed up by hardware.
  */
-ENTRY(__clear_user)
+ENTRY(__arch_clear_user)
 	uaccess_enable_not_uao x2, x3, x4
 	mov	x2, x1			// save the size for fixup return
 	subs	x1, x1, #8
@@ -52,7 +52,7 @@
 5:	mov	x0, #0
 	uaccess_disable_not_uao x2, x3
 	ret
-ENDPROC(__clear_user)
+ENDPROC(__arch_clear_user)
 
 	.section .fixup,"ax"
 	.align	2
diff --git a/arch/arm64/lib/copy_in_user.S b/arch/arm64/lib/copy_in_user.S
index fbb090f..54b75de 100644
--- a/arch/arm64/lib/copy_in_user.S
+++ b/arch/arm64/lib/copy_in_user.S
@@ -64,14 +64,15 @@
 	.endm
 
 end	.req	x5
-ENTRY(raw_copy_in_user)
+
+ENTRY(__arch_copy_in_user)
 	uaccess_enable_not_uao x3, x4, x5
 	add	end, x0, x2
 #include "copy_template.S"
 	uaccess_disable_not_uao x3, x4
 	mov	x0, #0
 	ret
-ENDPROC(raw_copy_in_user)
+ENDPROC(__arch_copy_in_user)
 
 	.section .fixup,"ax"
 	.align	2
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index ce441d2..f76bb2c 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -240,7 +240,7 @@ static inline bool is_permission_fault(unsigned int esr, struct pt_regs *regs,
 	if (fsc_type == ESR_ELx_FSC_PERM)
 		return true;
 
-	if (addr < USER_DS && system_uses_ttbr0_pan())
+	if (addr < TASK_SIZE && system_uses_ttbr0_pan())
 		return fsc_type == ESR_ELx_FSC_FAULT &&
 			(regs->pstate & PSR_PAN_BIT);
 
@@ -414,7 +414,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
 		mm_flags |= FAULT_FLAG_WRITE;
 	}
 
-	if (addr < USER_DS && is_permission_fault(esr, regs, addr)) {
+	if (addr < TASK_SIZE && is_permission_fault(esr, regs, addr)) {
 		/* regs->orig_addr_limit may be 0 if we entered from EL0 */
 		if (regs->orig_addr_limit == KERNEL_DS)
 			die("Accessing user space memory with fs=KERNEL_DS", regs, esr);
@@ -707,6 +707,12 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
 	arm64_notify_die("", regs, &info, esr);
 }
 
+asmlinkage void __exception do_el0_irq_bp_hardening(void)
+{
+	/* PC has already been checked in entry.S */
+	arm64_apply_bp_hardening();
+}
+
 asmlinkage void __exception do_el0_ia_bp_hardening(unsigned long addr,
 						   unsigned int esr,
 						   struct pt_regs *regs)
@@ -731,6 +737,12 @@ asmlinkage void __exception do_sp_pc_abort(unsigned long addr,
 	struct siginfo info;
 	struct task_struct *tsk = current;
 
+	if (user_mode(regs)) {
+		if (instruction_pointer(regs) > TASK_SIZE)
+			arm64_apply_bp_hardening();
+		local_irq_enable();
+	}
+
 	if (show_unhandled_signals && unhandled_signal(tsk, SIGBUS))
 		pr_info_ratelimited("%s[%d]: %s exception: pc=%p sp=%p\n",
 				    tsk->comm, task_pid_nr(tsk),
@@ -790,6 +802,9 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
 	if (interrupts_enabled(regs))
 		trace_hardirqs_off();
 
+	if (user_mode(regs) && instruction_pointer(regs) > TASK_SIZE)
+		arm64_apply_bp_hardening();
+
 	if (!inf->fn(addr, esr, regs)) {
 		rv = 1;
 	} else {
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index acba49f..6e02e6f 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -135,7 +135,8 @@ static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
 /* The early shadow maps everything to a single page of zeroes */
 asmlinkage void __init kasan_early_init(void)
 {
-	BUILD_BUG_ON(KASAN_SHADOW_OFFSET != KASAN_SHADOW_END - (1UL << 61));
+	BUILD_BUG_ON(KASAN_SHADOW_OFFSET !=
+		KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT)));
 	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
 	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
 	kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE,
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index b44992e..4694cda 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -118,6 +118,10 @@ static bool pgattr_change_is_safe(u64 old, u64 new)
 	if ((old | new) & PTE_CONT)
 		return false;
 
+	/* Transitioning from Global to Non-Global is safe */
+	if (((old ^ new) == PTE_NG) && (new & PTE_NG))
+		return true;
+
 	return ((old ^ new) & ~mask) == 0;
 }
 
@@ -685,12 +689,14 @@ int kern_addr_valid(unsigned long addr)
 }
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 #if !ARM64_SWAPPER_USES_SECTION_MAPS
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+		struct vmem_altmap *altmap)
 {
 	return vmemmap_populate_basepages(start, end, node);
 }
 #else	/* !ARM64_SWAPPER_USES_SECTION_MAPS */
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+		struct vmem_altmap *altmap)
 {
 	unsigned long addr = start;
 	unsigned long next;
@@ -725,7 +731,8 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
 	return 0;
 }
 #endif	/* CONFIG_ARM64_64K_PAGES */
-void vmemmap_free(unsigned long start, unsigned long end)
+void vmemmap_free(unsigned long start, unsigned long end,
+		struct vmem_altmap *altmap)
 {
 }
 #endif	/* CONFIG_SPARSEMEM_VMEMMAP */
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 9f177aa..71baed7 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -90,7 +90,7 @@
  *
  * x0: Address of context pointer
  */
-	.pushsection ".idmap.text", "ax"
+	.pushsection ".idmap.text", "awx"
 ENTRY(cpu_do_resume)
 	ldp	x2, x3, [x0]
 	ldp	x4, x5, [x0, #16]
@@ -153,7 +153,7 @@
 ENTRY(cpu_do_switch_mm)
 	mrs	x2, ttbr1_el1
 	mmid	x1, x1				// get mm->context.id
-	phys_to_ttbr x0, x3
+	phys_to_ttbr x3, x0
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
 	bfi	x3, x1, #48, #16		// set the ASID field in TTBR0
 #endif
@@ -165,7 +165,18 @@
 	b	post_ttbr_update_workaround	// Back to C code...
 ENDPROC(cpu_do_switch_mm)
 
-	.pushsection ".idmap.text", "ax"
+	.pushsection ".idmap.text", "awx"
+
+.macro	__idmap_cpu_set_reserved_ttbr1, tmp1, tmp2
+	adrp	\tmp1, empty_zero_page
+	phys_to_ttbr \tmp2, \tmp1
+	msr	ttbr1_el1, \tmp2
+	isb
+	tlbi	vmalle1
+	dsb	nsh
+	isb
+.endm
+
 /*
  * void idmap_cpu_replace_ttbr1(phys_addr_t new_pgd)
  *
@@ -175,16 +186,9 @@
 ENTRY(idmap_cpu_replace_ttbr1)
 	save_and_disable_daif flags=x2
 
-	adrp	x1, empty_zero_page
-	phys_to_ttbr x1, x3
-	msr	ttbr1_el1, x3
-	isb
+	__idmap_cpu_set_reserved_ttbr1 x1, x3
 
-	tlbi	vmalle1
-	dsb	nsh
-	isb
-
-	phys_to_ttbr x0, x3
+	phys_to_ttbr x3, x0
 	msr	ttbr1_el1, x3
 	isb
 
@@ -194,13 +198,197 @@
 ENDPROC(idmap_cpu_replace_ttbr1)
 	.popsection
 
+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+	.pushsection ".idmap.text", "awx"
+
+	.macro	__idmap_kpti_get_pgtable_ent, type
+	dc	cvac, cur_\()\type\()p		// Ensure any existing dirty
+	dmb	sy				// lines are written back before
+	ldr	\type, [cur_\()\type\()p]	// loading the entry
+	tbz	\type, #0, next_\()\type	// Skip invalid entries
+	.endm
+
+	.macro __idmap_kpti_put_pgtable_ent_ng, type
+	orr	\type, \type, #PTE_NG		// Same bit for blocks and pages
+	str	\type, [cur_\()\type\()p]	// Update the entry and ensure it
+	dc	civac, cur_\()\type\()p		// is visible to all CPUs.
+	.endm
+
+/*
+ * void __kpti_install_ng_mappings(int cpu, int num_cpus, phys_addr_t swapper)
+ *
+ * Called exactly once from stop_machine context by each CPU found during boot.
+ */
+__idmap_kpti_flag:
+	.long	1
+ENTRY(idmap_kpti_install_ng_mappings)
+	cpu		.req	w0
+	num_cpus	.req	w1
+	swapper_pa	.req	x2
+	swapper_ttb	.req	x3
+	flag_ptr	.req	x4
+	cur_pgdp	.req	x5
+	end_pgdp	.req	x6
+	pgd		.req	x7
+	cur_pudp	.req	x8
+	end_pudp	.req	x9
+	pud		.req	x10
+	cur_pmdp	.req	x11
+	end_pmdp	.req	x12
+	pmd		.req	x13
+	cur_ptep	.req	x14
+	end_ptep	.req	x15
+	pte		.req	x16
+
+	mrs	swapper_ttb, ttbr1_el1
+	adr	flag_ptr, __idmap_kpti_flag
+
+	cbnz	cpu, __idmap_kpti_secondary
+
+	/* We're the boot CPU. Wait for the others to catch up */
+	sevl
+1:	wfe
+	ldaxr	w18, [flag_ptr]
+	eor	w18, w18, num_cpus
+	cbnz	w18, 1b
+
+	/* We need to walk swapper, so turn off the MMU. */
+	pre_disable_mmu_workaround
+	mrs	x18, sctlr_el1
+	bic	x18, x18, #SCTLR_ELx_M
+	msr	sctlr_el1, x18
+	isb
+
+	/* Everybody is enjoying the idmap, so we can rewrite swapper. */
+	/* PGD */
+	mov	cur_pgdp, swapper_pa
+	add	end_pgdp, cur_pgdp, #(PTRS_PER_PGD * 8)
+do_pgd:	__idmap_kpti_get_pgtable_ent	pgd
+	tbnz	pgd, #1, walk_puds
+	__idmap_kpti_put_pgtable_ent_ng	pgd
+next_pgd:
+	add	cur_pgdp, cur_pgdp, #8
+	cmp	cur_pgdp, end_pgdp
+	b.ne	do_pgd
+
+	/* Publish the updated tables and nuke all the TLBs */
+	dsb	sy
+	tlbi	vmalle1is
+	dsb	ish
+	isb
+
+	/* We're done: fire up the MMU again */
+	mrs	x18, sctlr_el1
+	orr	x18, x18, #SCTLR_ELx_M
+	msr	sctlr_el1, x18
+	isb
+
+	/* Set the flag to zero to indicate that we're all done */
+	str	wzr, [flag_ptr]
+	ret
+
+	/* PUD */
+walk_puds:
+	.if CONFIG_PGTABLE_LEVELS > 3
+	pte_to_phys	cur_pudp, pgd
+	add	end_pudp, cur_pudp, #(PTRS_PER_PUD * 8)
+do_pud:	__idmap_kpti_get_pgtable_ent	pud
+	tbnz	pud, #1, walk_pmds
+	__idmap_kpti_put_pgtable_ent_ng	pud
+next_pud:
+	add	cur_pudp, cur_pudp, 8
+	cmp	cur_pudp, end_pudp
+	b.ne	do_pud
+	b	next_pgd
+	.else /* CONFIG_PGTABLE_LEVELS <= 3 */
+	mov	pud, pgd
+	b	walk_pmds
+next_pud:
+	b	next_pgd
+	.endif
+
+	/* PMD */
+walk_pmds:
+	.if CONFIG_PGTABLE_LEVELS > 2
+	pte_to_phys	cur_pmdp, pud
+	add	end_pmdp, cur_pmdp, #(PTRS_PER_PMD * 8)
+do_pmd:	__idmap_kpti_get_pgtable_ent	pmd
+	tbnz	pmd, #1, walk_ptes
+	__idmap_kpti_put_pgtable_ent_ng	pmd
+next_pmd:
+	add	cur_pmdp, cur_pmdp, #8
+	cmp	cur_pmdp, end_pmdp
+	b.ne	do_pmd
+	b	next_pud
+	.else /* CONFIG_PGTABLE_LEVELS <= 2 */
+	mov	pmd, pud
+	b	walk_ptes
+next_pmd:
+	b	next_pud
+	.endif
+
+	/* PTE */
+walk_ptes:
+	pte_to_phys	cur_ptep, pmd
+	add	end_ptep, cur_ptep, #(PTRS_PER_PTE * 8)
+do_pte:	__idmap_kpti_get_pgtable_ent	pte
+	__idmap_kpti_put_pgtable_ent_ng	pte
+next_pte:
+	add	cur_ptep, cur_ptep, #8
+	cmp	cur_ptep, end_ptep
+	b.ne	do_pte
+	b	next_pmd
+
+	/* Secondary CPUs end up here */
+__idmap_kpti_secondary:
+	/* Uninstall swapper before surgery begins */
+	__idmap_cpu_set_reserved_ttbr1 x18, x17
+
+	/* Increment the flag to let the boot CPU we're ready */
+1:	ldxr	w18, [flag_ptr]
+	add	w18, w18, #1
+	stxr	w17, w18, [flag_ptr]
+	cbnz	w17, 1b
+
+	/* Wait for the boot CPU to finish messing around with swapper */
+	sevl
+1:	wfe
+	ldxr	w18, [flag_ptr]
+	cbnz	w18, 1b
+
+	/* All done, act like nothing happened */
+	msr	ttbr1_el1, swapper_ttb
+	isb
+	ret
+
+	.unreq	cpu
+	.unreq	num_cpus
+	.unreq	swapper_pa
+	.unreq	swapper_ttb
+	.unreq	flag_ptr
+	.unreq	cur_pgdp
+	.unreq	end_pgdp
+	.unreq	pgd
+	.unreq	cur_pudp
+	.unreq	end_pudp
+	.unreq	pud
+	.unreq	cur_pmdp
+	.unreq	end_pmdp
+	.unreq	pmd
+	.unreq	cur_ptep
+	.unreq	end_ptep
+	.unreq	pte
+ENDPROC(idmap_kpti_install_ng_mappings)
+	.popsection
+#endif
+
 /*
  *	__cpu_setup
  *
  *	Initialise the processor for turning the MMU on.  Return in x0 the
  *	value of the SCTLR_EL1 register.
  */
-	.pushsection ".idmap.text", "ax"
+	.pushsection ".idmap.text", "awx"
 ENTRY(__cpu_setup)
 	tlbi	vmalle1				// Invalidate local TLB
 	dsb	nsh
diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile
index e69de29..f6bfee6 100644
--- a/arch/cris/kernel/Makefile
+++ b/arch/cris/kernel/Makefile
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the CRIS port.
+#
+
+CPPFLAGS_vmlinux.lds := -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE)
+extra-y := vmlinux.lds
+
+obj-y := process.o traps.o irq.o ptrace.o setup.o time.o sys_cris.o
+obj-y += stacktrace.o
+
+obj-$(CONFIG_MODULES)		+= crisksyms.o
+obj-$(CONFIG_MODULES)		+= module.o
+obj-$(CONFIG_SYSTEM_PROFILER)	+= profile.o
+
+clean:
+
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
index 524d475..1b61a72 100644
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -24,6 +24,7 @@
 #include <linux/of_fdt.h>
 #include <asm/setup.h>
 #include <arch/system.h>
+#include <asm/sections.h>
 
 /*
  * Setup options
@@ -31,7 +32,6 @@
 struct screen_info screen_info;
 
 extern int root_mountflags;
-extern char _etext, _edata, _end;
 
 char __initdata cris_command_line[COMMAND_LINE_SIZE] = { 0, };
 
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index c44f002..8586024 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2610,17 +2610,10 @@ pfm_get_task(pfm_context_t *ctx, pid_t pid, struct task_struct **task)
 	if (pid < 2) return -EPERM;
 
 	if (pid != task_pid_vnr(current)) {
-
-		read_lock(&tasklist_lock);
-
-		p = find_task_by_vpid(pid);
-
 		/* make sure task cannot go away while we operate on it */
-		if (p) get_task_struct(p);
-
-		read_unlock(&tasklist_lock);
-
-		if (p == NULL) return -ESRCH;
+		p = find_get_task_by_vpid(pid);
+		if (!p)
+			return -ESRCH;
 	}
 
 	ret = pfm_task_incompatible(ctx, p);
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index ac46f0d..7d9bd20 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -754,12 +754,14 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat)
 #endif
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+		struct vmem_altmap *altmap)
 {
 	return vmemmap_populate_basepages(start, end, node);
 }
 
-void vmemmap_free(unsigned long start, unsigned long end)
+void vmemmap_free(unsigned long start, unsigned long end,
+		struct vmem_altmap *altmap)
 {
 }
 #endif
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 7af4e05..18278b4 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -501,7 +501,7 @@ virtual_memmap_init(u64 start, u64 end, void *arg)
 	if (map_start < map_end)
 		memmap_init_zone((unsigned long)(map_end - map_start),
 				 args->nid, args->zone, page_to_pfn(map_start),
-				 MEMMAP_EARLY);
+				 MEMMAP_EARLY, NULL);
 	return 0;
 }
 
@@ -509,9 +509,10 @@ void __meminit
 memmap_init (unsigned long size, int nid, unsigned long zone,
 	     unsigned long start_pfn)
 {
-	if (!vmem_map)
-		memmap_init_zone(size, nid, zone, start_pfn, MEMMAP_EARLY);
-	else {
+	if (!vmem_map) {
+		memmap_init_zone(size, nid, zone, start_pfn, MEMMAP_EARLY,
+				NULL);
+	} else {
 		struct page *start;
 		struct memmap_init_callback_data args;
 
@@ -647,13 +648,14 @@ mem_init (void)
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+		bool want_memblock)
 {
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
 	int ret;
 
-	ret = __add_pages(nid, start_pfn, nr_pages, want_memblock);
+	ret = __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
 	if (ret)
 		printk("%s: Problem encountered in __add_pages() as ret=%d\n",
 		       __func__,  ret);
@@ -662,7 +664,7 @@ int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
 }
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
+int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
 {
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
@@ -670,7 +672,7 @@ int arch_remove_memory(u64 start, u64 size)
 	int ret;
 
 	zone = page_zone(pfn_to_page(start_pfn));
-	ret = __remove_pages(zone, start_pfn, nr_pages);
+	ret = __remove_pages(zone, start_pfn, nr_pages, altmap);
 	if (ret)
 		pr_warn("%s: Problem encountered in __remove_pages() as"
 			" ret=%d\n", __func__,  ret);
diff --git a/arch/m68k/include/asm/bitops.h b/arch/m68k/include/asm/bitops.h
index dda58cf..93b47b1 100644
--- a/arch/m68k/include/asm/bitops.h
+++ b/arch/m68k/include/asm/bitops.h
@@ -311,7 +311,6 @@ static inline int bfchg_mem_test_and_change_bit(int nr,
  *	functions.
  */
 #if defined(CONFIG_CPU_HAS_NO_BITFIELDS)
-#include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/ffz.h>
 #else
 
@@ -441,6 +440,8 @@ static inline unsigned long ffz(unsigned long word)
 
 #endif
 
+#include <asm-generic/bitops/find.h>
+
 #ifdef __KERNEL__
 
 #if defined(CONFIG_CPU_HAS_NO_BITFIELDS)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ab98569..449397c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -7,8 +7,6 @@
 	select ARCH_DISCARD_MEMBLOCK
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
-	select ARCH_MIGHT_HAVE_PC_PARPORT
-	select ARCH_MIGHT_HAVE_PC_SERIO
 	select ARCH_SUPPORTS_UPROBES
 	select ARCH_USE_BUILTIN_BSWAP
 	select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
@@ -119,12 +117,12 @@
 	select SYS_SUPPORTS_MULTITHREADING
 	select SYS_SUPPORTS_RELOCATABLE
 	select SYS_SUPPORTS_SMARTMIPS
-	select USB_EHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
-	select USB_EHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
-	select USB_OHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
-	select USB_OHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
-	select USB_UHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
-	select USB_UHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
+	select USB_EHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+	select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+	select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+	select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+	select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+	select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
 	select USE_OF
 	help
 	  Select this to build a kernel which aims to support multiple boards,
@@ -253,6 +251,7 @@
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_MIPS16
+	select SYS_SUPPORTS_ZBOOT
 	select SYS_HAS_EARLY_PRINTK
 	select USE_GENERIC_EARLY_PRINTK_8250
 	select GPIOLIB
@@ -341,6 +340,8 @@
 
 config MACH_JAZZ
 	bool "Jazz family of machines"
+	select ARCH_MIGHT_HAVE_PC_PARPORT
+	select ARCH_MIGHT_HAVE_PC_SERIO
 	select FW_ARC
 	select FW_ARC32
 	select ARCH_MAY_HAVE_PC_FDC
@@ -476,6 +477,8 @@
 config MIPS_MALTA
 	bool "MIPS Malta board"
 	select ARCH_MAY_HAVE_PC_FDC
+	select ARCH_MIGHT_HAVE_PC_PARPORT
+	select ARCH_MIGHT_HAVE_PC_SERIO
 	select BOOT_ELF32
 	select BOOT_RAW
 	select BUILTIN_DTB
@@ -613,6 +616,7 @@
 	bool "SGI IP22 (Indy/Indigo2)"
 	select FW_ARC
 	select FW_ARC32
+	select ARCH_MIGHT_HAVE_PC_SERIO
 	select BOOT_ELF32
 	select CEVT_R4K
 	select CSRC_R4K
@@ -675,6 +679,7 @@
 	bool "SGI IP28 (Indigo2 R10k)"
 	select FW_ARC
 	select FW_ARC64
+	select ARCH_MIGHT_HAVE_PC_SERIO
 	select BOOT_ELF64
 	select CEVT_R4K
 	select CSRC_R4K
@@ -824,6 +829,8 @@
 	select FW_ARC32 if CPU_LITTLE_ENDIAN
 	select FW_SNIPROM if CPU_BIG_ENDIAN
 	select ARCH_MAY_HAVE_PC_FDC
+	select ARCH_MIGHT_HAVE_PC_PARPORT
+	select ARCH_MIGHT_HAVE_PC_SERIO
 	select BOOT_ELF32
 	select CEVT_R4K
 	select CSRC_R4K
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 9f6a26d..d1ca839 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -216,6 +216,12 @@
 endif
 toolchain-virt				:= $(call cc-option-yn,$(mips-cflags) -mvirt)
 cflags-$(toolchain-virt)		+= -DTOOLCHAIN_SUPPORTS_VIRT
+# For -mmicromips, use -Wa,-fatal-warnings to catch unsupported -mxpa which
+# only warns
+xpa-cflags-y				:= $(mips-cflags)
+xpa-cflags-$(micromips-ase)		+= -mmicromips -Wa$(comma)-fatal-warnings
+toolchain-xpa				:= $(call cc-option-yn,$(xpa-cflags-y) -mxpa)
+cflags-$(toolchain-xpa)			+= -DTOOLCHAIN_SUPPORTS_XPA
 
 #
 # Firmware support
@@ -228,7 +234,7 @@
 #
 # Kernel compression
 #
-ifdef SYS_SUPPORTS_ZBOOT
+ifdef CONFIG_SYS_SUPPORTS_ZBOOT
 COMPRESSION_FNAME		= vmlinuz
 else
 COMPRESSION_FNAME		= vmlinux
diff --git a/arch/mips/bcm47xx/Platform b/arch/mips/bcm47xx/Platform
index 874b7ca..70783b7 100644
--- a/arch/mips/bcm47xx/Platform
+++ b/arch/mips/bcm47xx/Platform
@@ -5,3 +5,4 @@
 cflags-$(CONFIG_BCM47XX)	+=					\
 		-I$(srctree)/arch/mips/include/asm/mach-bcm47xx
 load-$(CONFIG_BCM47XX)		:= 0xffffffff80001000
+zload-$(CONFIG_BCM47XX)		+= 0xffffffff80400000
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index c675eec..adce180 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -133,4 +133,8 @@
 uzImage.bin: vmlinuz.bin FORCE
 	$(call if_changed,uimage,none)
 
-clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec}
+clean-files += $(objtree)/vmlinuz
+clean-files += $(objtree)/vmlinuz.32
+clean-files += $(objtree)/vmlinuz.ecoff
+clean-files += $(objtree)/vmlinuz.bin
+clean-files += $(objtree)/vmlinuz.srec
diff --git a/arch/mips/boot/dts/ingenic/Makefile b/arch/mips/boot/dts/ingenic/Makefile
index 6a31759..5b1361a 100644
--- a/arch/mips/boot/dts/ingenic/Makefile
+++ b/arch/mips/boot/dts/ingenic/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_JZ4740_QI_LB60)	+= qi_lb60.dtb
+dtb-$(CONFIG_JZ4770_GCW0)	+= gcw0.dtb
 dtb-$(CONFIG_JZ4780_CI20)	+= ci20.dtb
 
 obj-y				+= $(patsubst %.dtb, %.dtb.o, $(dtb-y))
diff --git a/arch/mips/boot/dts/ingenic/gcw0.dts b/arch/mips/boot/dts/ingenic/gcw0.dts
new file mode 100644
index 0000000..35f0291
--- /dev/null
+++ b/arch/mips/boot/dts/ingenic/gcw0.dts
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "jz4770.dtsi"
+
+/ {
+	compatible = "gcw,zero", "ingenic,jz4770";
+	model = "GCW Zero";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+	};
+
+	chosen {
+		stdout-path = "serial2:57600n8";
+	};
+
+	board {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		otg_phy: otg-phy {
+			compatible = "usb-nop-xceiv";
+			clocks = <&cgu JZ4770_CLK_OTG_PHY>;
+			clock-names = "main_clk";
+		};
+	};
+};
+
+&ext {
+	clock-frequency = <12000000>;
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&cgu {
+	/* Put high-speed peripherals under PLL1, such that we can change the
+	 * PLL0 frequency on demand without having to suspend peripherals.
+	 * We use a rate of 432 MHz, which is the least common multiple of
+	 * 27 MHz (required by TV encoder) and 48 MHz (required by USB host).
+	 */
+	assigned-clocks =
+		<&cgu JZ4770_CLK_PLL1>,
+		<&cgu JZ4770_CLK_UHC>;
+	assigned-clock-parents =
+		<0>,
+		<&cgu JZ4770_CLK_PLL1>;
+	assigned-clock-rates =
+		<432000000>;
+};
+
+&uhc {
+	/* The WiFi module is connected to the UHC. */
+	status = "okay";
+};
diff --git a/arch/mips/boot/dts/ingenic/jz4770.dtsi b/arch/mips/boot/dts/ingenic/jz4770.dtsi
new file mode 100644
index 0000000..7c2804f
--- /dev/null
+++ b/arch/mips/boot/dts/ingenic/jz4770.dtsi
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dt-bindings/clock/jz4770-cgu.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ingenic,jz4770";
+
+	cpuintc: interrupt-controller {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	intc: interrupt-controller@10001000 {
+		compatible = "ingenic,jz4770-intc";
+		reg = <0x10001000 0x40>;
+
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <2>;
+	};
+
+	ext: ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+	};
+
+	osc32k: osc32k {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	cgu: jz4770-cgu@10000000 {
+		compatible = "ingenic,jz4770-cgu";
+		reg = <0x10000000 0x100>;
+
+		clocks = <&ext>, <&osc32k>;
+		clock-names = "ext", "osc32k";
+
+		#clock-cells = <1>;
+	};
+
+	pinctrl: pin-controller@10010000 {
+		compatible = "ingenic,jz4770-pinctrl";
+		reg = <0x10010000 0x600>;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		gpa: gpio@0 {
+			compatible = "ingenic,jz4770-gpio";
+			reg = <0>;
+
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 0 32>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <17>;
+		};
+
+		gpb: gpio@1 {
+			compatible = "ingenic,jz4770-gpio";
+			reg = <1>;
+
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 32 32>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <16>;
+		};
+
+		gpc: gpio@2 {
+			compatible = "ingenic,jz4770-gpio";
+			reg = <2>;
+
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 64 32>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <15>;
+		};
+
+		gpd: gpio@3 {
+			compatible = "ingenic,jz4770-gpio";
+			reg = <3>;
+
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 96 32>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <14>;
+		};
+
+		gpe: gpio@4 {
+			compatible = "ingenic,jz4770-gpio";
+			reg = <4>;
+
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 128 32>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <13>;
+		};
+
+		gpf: gpio@5 {
+			compatible = "ingenic,jz4770-gpio";
+			reg = <5>;
+
+			gpio-controller;
+			gpio-ranges = <&pinctrl 0 160 32>;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+
+			interrupt-parent = <&intc>;
+			interrupts = <12>;
+		};
+	};
+
+	uart0: serial@10030000 {
+		compatible = "ingenic,jz4770-uart";
+		reg = <0x10030000 0x100>;
+
+		clocks = <&ext>, <&cgu JZ4770_CLK_UART0>;
+		clock-names = "baud", "module";
+
+		interrupt-parent = <&intc>;
+		interrupts = <5>;
+
+		status = "disabled";
+	};
+
+	uart1: serial@10031000 {
+		compatible = "ingenic,jz4770-uart";
+		reg = <0x10031000 0x100>;
+
+		clocks = <&ext>, <&cgu JZ4770_CLK_UART1>;
+		clock-names = "baud", "module";
+
+		interrupt-parent = <&intc>;
+		interrupts = <4>;
+
+		status = "disabled";
+	};
+
+	uart2: serial@10032000 {
+		compatible = "ingenic,jz4770-uart";
+		reg = <0x10032000 0x100>;
+
+		clocks = <&ext>, <&cgu JZ4770_CLK_UART2>;
+		clock-names = "baud", "module";
+
+		interrupt-parent = <&intc>;
+		interrupts = <3>;
+
+		status = "disabled";
+	};
+
+	uart3: serial@10033000 {
+		compatible = "ingenic,jz4770-uart";
+		reg = <0x10033000 0x100>;
+
+		clocks = <&ext>, <&cgu JZ4770_CLK_UART3>;
+		clock-names = "baud", "module";
+
+		interrupt-parent = <&intc>;
+		interrupts = <2>;
+
+		status = "disabled";
+	};
+
+	uhc: uhc@13430000 {
+		compatible = "generic-ohci";
+		reg = <0x13430000 0x1000>;
+
+		clocks = <&cgu JZ4770_CLK_UHC>, <&cgu JZ4770_CLK_UHC_PHY>;
+		assigned-clocks = <&cgu JZ4770_CLK_UHC>;
+		assigned-clock-rates = <48000000>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <20>;
+
+		status = "disabled";
+	};
+};
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index a55009e..5e73fe7 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -153,7 +153,6 @@
 CONFIG_SLIP_SMART=y
 CONFIG_SLIP_MODE_SLIP6=y
 # CONFIG_INPUT is not set
-# CONFIG_SERIO_I8042 is not set
 CONFIG_SERIO_RAW=m
 # CONFIG_VT is not set
 CONFIG_SERIAL_NONSTANDARD=y
diff --git a/arch/mips/configs/gcw0_defconfig b/arch/mips/configs/gcw0_defconfig
new file mode 100644
index 0000000..99ac1fa
--- /dev/null
+++ b/arch/mips/configs/gcw0_defconfig
@@ -0,0 +1,27 @@
+CONFIG_MACH_INGENIC=y
+CONFIG_JZ4770_GCW0=y
+CONFIG_HIGHMEM=y
+# CONFIG_BOUNCE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_SECCOMP is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_EMBEDDED=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_NETDEVICES=y
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_INGENIC=y
+CONFIG_USB=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_TMPFS=y
diff --git a/arch/mips/configs/generic/board-ranchu.config b/arch/mips/configs/generic/board-ranchu.config
new file mode 100644
index 0000000..fee9ad4
--- /dev/null
+++ b/arch/mips/configs/generic/board-ranchu.config
@@ -0,0 +1,30 @@
+CONFIG_VIRT_BOARD_RANCHU=y
+
+CONFIG_BATTERY_GOLDFISH=y
+CONFIG_FB=y
+CONFIG_FB_GOLDFISH=y
+CONFIG_GOLDFISH=y
+CONFIG_STAGING=y
+CONFIG_GOLDFISH_AUDIO=y
+CONFIG_GOLDFISH_PIC=y
+CONFIG_GOLDFISH_PIPE=y
+CONFIG_GOLDFISH_TTY=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GOLDFISH=y
+
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_GOLDFISH_EVENTS=y
+
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+
+CONFIG_VIRTIO_BLK=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
+CONFIG_NETDEVICES=y
+CONFIG_VIRTIO_NET=y
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index a0d5932..91a9c13 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -252,7 +252,6 @@
 CONFIG_WL12XX=m
 CONFIG_WL1251=m
 # CONFIG_INPUT is not set
-# CONFIG_SERIO_I8042 is not set
 CONFIG_SERIO_LIBPS2=m
 CONFIG_SERIO_RAW=m
 CONFIG_SERIO_ALTERA_PS2=m
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 1e26e58..ebff297 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -75,7 +75,6 @@
 CONFIG_TULIP=m
 CONFIG_TULIP_MMIO=y
 CONFIG_INPUT_EVDEV=m
-# CONFIG_SERIO_I8042 is not set
 CONFIG_SERIO_MACEPS2=y
 CONFIG_SERIO_RAW=y
 # CONFIG_CONSOLE_TRANSLATIONS is not set
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 3964084..df8a9a1 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -312,9 +312,8 @@
 CONFIG_IPW2100=m
 CONFIG_IPW2100_MONITOR=y
 CONFIG_LIBERTAS=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_POWER_RESET=y
diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig
index 5691673..14df9ef1 100644
--- a/arch/mips/configs/malta_kvm_defconfig
+++ b/arch/mips/configs/malta_kvm_defconfig
@@ -324,9 +324,7 @@
 CONFIG_IPW2100=m
 CONFIG_IPW2100_MONITOR=y
 CONFIG_LIBERTAS=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
+CONFIG_INPUT_MOUSEDEV=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_POWER_RESET=y
diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig
index e9cadb3..25092e3 100644
--- a/arch/mips/configs/malta_kvm_guest_defconfig
+++ b/arch/mips/configs/malta_kvm_guest_defconfig
@@ -326,9 +326,7 @@
 CONFIG_IPW2100=m
 CONFIG_IPW2100_MONITOR=y
 CONFIG_LIBERTAS=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
+CONFIG_INPUT_MOUSEDEV=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_POWER_RESET=y
diff --git a/arch/mips/configs/malta_qemu_32r6_defconfig b/arch/mips/configs/malta_qemu_32r6_defconfig
index 77145ec..210bf60 100644
--- a/arch/mips/configs/malta_qemu_32r6_defconfig
+++ b/arch/mips/configs/malta_qemu_32r6_defconfig
@@ -126,6 +126,7 @@
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 # CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=y
 # CONFIG_VT is not set
 CONFIG_LEGACY_PTY_COUNT=4
 CONFIG_SERIAL_8250=y
diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig
index cc2687c..e5934aa 100644
--- a/arch/mips/configs/maltaaprp_defconfig
+++ b/arch/mips/configs/maltaaprp_defconfig
@@ -126,6 +126,7 @@
 # CONFIG_NET_VENDOR_TOSHIBA is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=y
 # CONFIG_VT is not set
 CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_8250=y
diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig
index d8c8f5f..cb2ca11 100644
--- a/arch/mips/configs/maltasmvp_defconfig
+++ b/arch/mips/configs/maltasmvp_defconfig
@@ -127,6 +127,7 @@
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 # CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=y
 # CONFIG_VT is not set
 CONFIG_LEGACY_PTY_COUNT=4
 CONFIG_SERIAL_8250=y
diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig
index 04827bc..be29fce 100644
--- a/arch/mips/configs/maltasmvp_eva_defconfig
+++ b/arch/mips/configs/maltasmvp_eva_defconfig
@@ -130,6 +130,7 @@
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_NET_VENDOR_WIZNET is not set
 # CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=y
 # CONFIG_VT is not set
 CONFIG_LEGACY_PTY_COUNT=4
 CONFIG_SERIAL_8250=y
diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig
index 7ea7c0b..40462d4 100644
--- a/arch/mips/configs/maltaup_defconfig
+++ b/arch/mips/configs/maltaup_defconfig
@@ -125,6 +125,7 @@
 # CONFIG_NET_VENDOR_TOSHIBA is not set
 # CONFIG_NET_VENDOR_VIA is not set
 # CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=y
 # CONFIG_VT is not set
 CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_8250=y
diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig
index 2942610..4e50176 100644
--- a/arch/mips/configs/maltaup_xpa_defconfig
+++ b/arch/mips/configs/maltaup_xpa_defconfig
@@ -321,9 +321,8 @@
 CONFIG_IPW2100=m
 CONFIG_IPW2100_MONITOR=y
 CONFIG_LIBERTAS=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_POWER_RESET=y
diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig
index 7357248..e8e1dd8 100644
--- a/arch/mips/configs/nlm_xlp_defconfig
+++ b/arch/mips/configs/nlm_xlp_defconfig
@@ -399,7 +399,6 @@
 CONFIG_INPUT_EVBUG=m
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
 CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIO_RAW=m
diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig
index 1e18fd7..c4477a4 100644
--- a/arch/mips/configs/nlm_xlr_defconfig
+++ b/arch/mips/configs/nlm_xlr_defconfig
@@ -332,7 +332,6 @@
 CONFIG_INPUT_EVBUG=m
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
 CONFIG_SERIO_SERPORT=m
 CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIO_RAW=m
diff --git a/arch/mips/configs/pnx8335_stb225_defconfig b/arch/mips/configs/pnx8335_stb225_defconfig
index 81b5eb8..e73cdb0 100644
--- a/arch/mips/configs/pnx8335_stb225_defconfig
+++ b/arch/mips/configs/pnx8335_stb225_defconfig
@@ -49,7 +49,6 @@
 CONFIG_INPUT_EVBUG=m
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
 # CONFIG_VT_CONSOLE is not set
 CONFIG_SERIAL_PNX8XXX=y
 CONFIG_SERIAL_PNX8XXX_CONSOLE=y
diff --git a/arch/mips/configs/sb1250_swarm_defconfig b/arch/mips/configs/sb1250_swarm_defconfig
index c724bdd..1edd843 100644
--- a/arch/mips/configs/sb1250_swarm_defconfig
+++ b/arch/mips/configs/sb1250_swarm_defconfig
@@ -65,7 +65,6 @@
 CONFIG_MII=y
 CONFIG_SB1250_MAC=y
 # CONFIG_INPUT is not set
-# CONFIG_SERIO_I8042 is not set
 CONFIG_SERIO_RAW=m
 # CONFIG_VT is not set
 # CONFIG_HW_RANDOM is not set
diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig
index 52e0286..2ff3b17 100644
--- a/arch/mips/generic/Kconfig
+++ b/arch/mips/generic/Kconfig
@@ -49,4 +49,14 @@
 	  Enable this to include the FDT for the MIPSfpga platform
 	  from Imagination Technologies in the FIT kernel image.
 
+config VIRT_BOARD_RANCHU
+	bool "Support Ranchu platform for Android emulator"
+	help
+	  This enables support for the platform used by Android emulator.
+
+	  Ranchu platform consists of a set of virtual devices. This platform
+	  enables emulation of variety of virtual configurations while using
+	  Android emulator. Android emulator is based on Qemu, and contains
+	  the support for the same set of virtual devices.
+
 endif
diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile
index 87496736..5c31e0c 100644
--- a/arch/mips/generic/Makefile
+++ b/arch/mips/generic/Makefile
@@ -15,3 +15,4 @@
 obj-$(CONFIG_YAMON_DT_SHIM)		+= yamon-dt.o
 obj-$(CONFIG_LEGACY_BOARD_SEAD3)	+= board-sead3.o
 obj-$(CONFIG_KEXEC)			+= kexec.o
+obj-$(CONFIG_VIRT_BOARD_RANCHU)		+= board-ranchu.o
diff --git a/arch/mips/generic/board-ranchu.c b/arch/mips/generic/board-ranchu.c
new file mode 100644
index 0000000..59a8c18
--- /dev/null
+++ b/arch/mips/generic/board-ranchu.c
@@ -0,0 +1,93 @@
+/*
+ * Support code for virtual Ranchu board for MIPS.
+ *
+ * Author: Miodrag Dinic <miodrag.dinic@mips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/of_address.h>
+#include <linux/types.h>
+
+#include <asm/machine.h>
+#include <asm/mipsregs.h>
+#include <asm/time.h>
+
+#define GOLDFISH_TIMER_LOW		0x00
+#define GOLDFISH_TIMER_HIGH		0x04
+
+static __init u64 read_rtc_time(void __iomem *base)
+{
+	u32 time_low;
+	u32 time_high;
+
+	/*
+	 * Reading the low address latches the high value
+	 * as well so there is no fear that we may read
+	 * inaccurate high value.
+	 */
+	time_low = readl(base + GOLDFISH_TIMER_LOW);
+	time_high = readl(base + GOLDFISH_TIMER_HIGH);
+
+	return ((u64)time_high << 32) | time_low;
+}
+
+static __init unsigned int ranchu_measure_hpt_freq(void)
+{
+	u64 rtc_start, rtc_current, rtc_delta;
+	unsigned int start, count;
+	struct device_node *np;
+	void __iomem *rtc_base;
+
+	np = of_find_compatible_node(NULL, NULL, "google,goldfish-rtc");
+	if (!np)
+		panic("%s(): Failed to find 'google,goldfish-rtc' dt node!",
+		      __func__);
+
+	rtc_base = of_iomap(np, 0);
+	if (!rtc_base)
+		panic("%s(): Failed to ioremap Goldfish RTC base!", __func__);
+
+	/*
+	 * Poll the nanosecond resolution RTC for one
+	 * second to calibrate the CPU frequency.
+	 */
+	rtc_start = read_rtc_time(rtc_base);
+	start = read_c0_count();
+
+	do {
+		rtc_current = read_rtc_time(rtc_base);
+		rtc_delta = rtc_current - rtc_start;
+	} while (rtc_delta < NSEC_PER_SEC);
+
+	count = read_c0_count() - start;
+
+	/*
+	 * Make sure the frequency will be a round number.
+	 * Without this correction, the returned value may vary
+	 * between subsequent emulation executions.
+	 *
+	 * TODO: Set this value using device tree.
+	 */
+	count += 5000;
+	count -= count % 10000;
+
+	iounmap(rtc_base);
+
+	return count;
+}
+
+static const struct of_device_id ranchu_of_match[] __initconst = {
+	{
+		.compatible = "mti,ranchu",
+	},
+	{}
+};
+
+MIPS_MACHINE(ranchu) = {
+	.matches = ranchu_of_match,
+	.measure_hpt_freq = ranchu_measure_hpt_freq,
+};
diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c
index 394f816..cb7fdae 100644
--- a/arch/mips/generic/irq.c
+++ b/arch/mips/generic/irq.c
@@ -22,10 +22,10 @@ int get_c0_fdc_int(void)
 {
 	int mips_cpu_fdc_irq;
 
-	if (cpu_has_veic)
-		panic("Unimplemented!");
-	else if (mips_gic_present())
+	if (mips_gic_present())
 		mips_cpu_fdc_irq = gic_get_c0_fdc_int();
+	else if (cpu_has_veic)
+		panic("Unimplemented!");
 	else if (cp0_fdc_irq >= 0)
 		mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
 	else
@@ -38,10 +38,10 @@ int get_c0_perfcount_int(void)
 {
 	int mips_cpu_perf_irq;
 
-	if (cpu_has_veic)
-		panic("Unimplemented!");
-	else if (mips_gic_present())
+	if (mips_gic_present())
 		mips_cpu_perf_irq = gic_get_c0_perfcount_int();
+	else if (cpu_has_veic)
+		panic("Unimplemented!");
 	else if (cp0_perfcount_irq >= 0)
 		mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
 	else
@@ -54,10 +54,10 @@ unsigned int get_c0_compare_int(void)
 {
 	int mips_cpu_timer_irq;
 
-	if (cpu_has_veic)
-		panic("Unimplemented!");
-	else if (mips_gic_present())
+	if (mips_gic_present())
 		mips_cpu_timer_irq = gic_get_c0_compare_int();
+	else if (cpu_has_veic)
+		panic("Unimplemented!");
 	else
 		mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
 
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index e26a093..a301a8f 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -79,6 +79,8 @@ enum loongson_machine_type {
  */
 #define  MACH_INGENIC_JZ4730	0	/* JZ4730 SOC		*/
 #define  MACH_INGENIC_JZ4740	1	/* JZ4740 SOC		*/
+#define  MACH_INGENIC_JZ4770	2	/* JZ4770 SOC		*/
+#define  MACH_INGENIC_JZ4780	3	/* JZ4780 SOC		*/
 
 extern char *system_type;
 const char *get_system_type(void);
diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h
index 77cad23..e8161e4 100644
--- a/arch/mips/include/asm/checksum.h
+++ b/arch/mips/include/asm/checksum.h
@@ -110,7 +110,7 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst,
  */
 static inline __sum16 csum_fold(__wsum csum)
 {
-	u32 sum = (__force u32)csum;;
+	u32 sum = (__force u32)csum;
 
 	sum += (sum << 16);
 	csum = (sum < csum);
diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h
index 4f69f08..8c286be 100644
--- a/arch/mips/include/asm/mach-loongson64/boot_param.h
+++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
@@ -4,7 +4,7 @@
 
 #define SYSTEM_RAM_LOW		1
 #define SYSTEM_RAM_HIGH		2
-#define MEM_RESERVED		3
+#define SYSTEM_RAM_RESERVED	3
 #define PCI_IO			4
 #define PCI_MEM			5
 #define LOONGSON_CFG_REG	6
diff --git a/arch/mips/include/asm/machine.h b/arch/mips/include/asm/machine.h
index e0d9b37..f83879d 100644
--- a/arch/mips/include/asm/machine.h
+++ b/arch/mips/include/asm/machine.h
@@ -52,7 +52,7 @@ mips_machine_is_compatible(const struct mips_machine *mach, const void *fdt)
 	if (!mach->matches)
 		return NULL;
 
-	for (match = mach->matches; match->compatible; match++) {
+	for (match = mach->matches; match->compatible[0]; match++) {
 		if (fdt_node_check_compatible(fdt, 0, match->compatible) == 0)
 			return match;
 	}
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 6b1f1ad..858752d 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1181,6 +1181,89 @@ static inline int mm_insn_16bit(u16 insn)
 #endif
 
 /*
+ * parse_r var, r - Helper assembler macro for parsing register names.
+ *
+ * This converts the register name in $n form provided in \r to the
+ * corresponding register number, which is assigned to the variable \var. It is
+ * needed to allow explicit encoding of instructions in inline assembly where
+ * registers are chosen by the compiler in $n form, allowing us to avoid using
+ * fixed register numbers.
+ *
+ * It also allows newer instructions (not implemented by the assembler) to be
+ * transparently implemented using assembler macros, instead of needing separate
+ * cases depending on toolchain support.
+ *
+ * Simple usage example:
+ * __asm__ __volatile__("parse_r __rt, %0\n\t"
+ *			".insn\n\t"
+ *			"# di    %0\n\t"
+ *			".word   (0x41606000 | (__rt << 16))"
+ *			: "=r" (status);
+ */
+
+/* Match an individual register number and assign to \var */
+#define _IFC_REG(n)				\
+	".ifc	\\r, $" #n "\n\t"		\
+	"\\var	= " #n "\n\t"			\
+	".endif\n\t"
+
+__asm__(".macro	parse_r var r\n\t"
+	"\\var	= -1\n\t"
+	_IFC_REG(0)  _IFC_REG(1)  _IFC_REG(2)  _IFC_REG(3)
+	_IFC_REG(4)  _IFC_REG(5)  _IFC_REG(6)  _IFC_REG(7)
+	_IFC_REG(8)  _IFC_REG(9)  _IFC_REG(10) _IFC_REG(11)
+	_IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15)
+	_IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19)
+	_IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23)
+	_IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27)
+	_IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31)
+	".iflt	\\var\n\t"
+	".error	\"Unable to parse register name \\r\"\n\t"
+	".endif\n\t"
+	".endm");
+
+#undef _IFC_REG
+
+/*
+ * C macros for generating assembler macros for common instruction formats.
+ *
+ * The names of the operands can be chosen by the caller, and the encoding of
+ * register operand \<Rn> is assigned to __<Rn> where it can be accessed from
+ * the ENC encodings.
+ */
+
+/* Instructions with no operands */
+#define _ASM_MACRO_0(OP, ENC)						\
+	__asm__(".macro	" #OP "\n\t"					\
+		ENC							\
+		".endm")
+
+/* Instructions with 2 register operands */
+#define _ASM_MACRO_2R(OP, R1, R2, ENC)					\
+	__asm__(".macro	" #OP " " #R1 ", " #R2 "\n\t"			\
+		"parse_r __" #R1 ", \\" #R1 "\n\t"			\
+		"parse_r __" #R2 ", \\" #R2 "\n\t"			\
+		ENC							\
+		".endm")
+
+/* Instructions with 3 register operands */
+#define _ASM_MACRO_3R(OP, R1, R2, R3, ENC)				\
+	__asm__(".macro	" #OP " " #R1 ", " #R2 ", " #R3 "\n\t"		\
+		"parse_r __" #R1 ", \\" #R1 "\n\t"			\
+		"parse_r __" #R2 ", \\" #R2 "\n\t"			\
+		"parse_r __" #R3 ", \\" #R3 "\n\t"			\
+		ENC							\
+		".endm")
+
+/* Instructions with 2 register operands and 1 optional select operand */
+#define _ASM_MACRO_2R_1S(OP, R1, R2, SEL3, ENC)				\
+	__asm__(".macro	" #OP " " #R1 ", " #R2 ", " #SEL3 " = 0\n\t"	\
+		"parse_r __" #R1 ", \\" #R1 "\n\t"			\
+		"parse_r __" #R2 ", \\" #R2 "\n\t"			\
+		ENC							\
+		".endm")
+
+/*
  * TLB Invalidate Flush
  */
 static inline void tlbinvf(void)
@@ -1245,14 +1328,14 @@ do {								\
  * Macros to access the system control coprocessor
  */
 
-#define __read_32bit_c0_register(source, sel)				\
+#define ___read_32bit_c0_register(source, sel, vol)			\
 ({ unsigned int __res;							\
 	if (sel == 0)							\
-		__asm__ __volatile__(					\
+		__asm__ vol(						\
 			"mfc0\t%0, " #source "\n\t"			\
 			: "=r" (__res));				\
 	else								\
-		__asm__ __volatile__(					\
+		__asm__ vol(						\
 			".set\tmips32\n\t"				\
 			"mfc0\t%0, " #source ", " #sel "\n\t"		\
 			".set\tmips0\n\t"				\
@@ -1260,18 +1343,18 @@ do {								\
 	__res;								\
 })
 
-#define __read_64bit_c0_register(source, sel)				\
+#define ___read_64bit_c0_register(source, sel, vol)			\
 ({ unsigned long long __res;						\
 	if (sizeof(unsigned long) == 4)					\
-		__res = __read_64bit_c0_split(source, sel);		\
+		__res = __read_64bit_c0_split(source, sel, vol);	\
 	else if (sel == 0)						\
-		__asm__ __volatile__(					\
+		__asm__ vol(						\
 			".set\tmips3\n\t"				\
 			"dmfc0\t%0, " #source "\n\t"			\
 			".set\tmips0"					\
 			: "=r" (__res));				\
 	else								\
-		__asm__ __volatile__(					\
+		__asm__ vol(						\
 			".set\tmips64\n\t"				\
 			"dmfc0\t%0, " #source ", " #sel "\n\t"		\
 			".set\tmips0"					\
@@ -1279,6 +1362,18 @@ do {								\
 	__res;								\
 })
 
+#define __read_32bit_c0_register(source, sel)				\
+	___read_32bit_c0_register(source, sel, __volatile__)
+
+#define __read_const_32bit_c0_register(source, sel)			\
+	___read_32bit_c0_register(source, sel,)
+
+#define __read_64bit_c0_register(source, sel)				\
+	___read_64bit_c0_register(source, sel, __volatile__)
+
+#define __read_const_64bit_c0_register(source, sel)			\
+	___read_64bit_c0_register(source, sel,)
+
 #define __write_32bit_c0_register(register, sel, value)			\
 do {									\
 	if (sel == 0)							\
@@ -1316,6 +1411,11 @@ do {									\
 	(unsigned long) __read_32bit_c0_register(reg, sel) :		\
 	(unsigned long) __read_64bit_c0_register(reg, sel))
 
+#define __read_const_ulong_c0_register(reg, sel)			\
+	((sizeof(unsigned long) == 4) ?					\
+	(unsigned long) __read_const_32bit_c0_register(reg, sel) :	\
+	(unsigned long) __read_const_64bit_c0_register(reg, sel))
+
 #define __write_ulong_c0_register(reg, sel, val)			\
 do {									\
 	if (sizeof(unsigned long) == 4)					\
@@ -1346,14 +1446,14 @@ do {									\
  * These versions are only needed for systems with more than 38 bits of
  * physical address space running the 32-bit kernel.  That's none atm :-)
  */
-#define __read_64bit_c0_split(source, sel)				\
+#define __read_64bit_c0_split(source, sel, vol)				\
 ({									\
 	unsigned long long __val;					\
 	unsigned long __flags;						\
 									\
 	local_irq_save(__flags);					\
 	if (sel == 0)							\
-		__asm__ __volatile__(					\
+		__asm__ vol(						\
 			".set\tmips64\n\t"				\
 			"dmfc0\t%L0, " #source "\n\t"			\
 			"dsra\t%M0, %L0, 32\n\t"			\
@@ -1361,7 +1461,7 @@ do {									\
 			".set\tmips0"					\
 			: "=r" (__val));				\
 	else								\
-		__asm__ __volatile__(					\
+		__asm__ vol(						\
 			".set\tmips64\n\t"				\
 			"dmfc0\t%L0, " #source ", " #sel "\n\t"		\
 			"dsra\t%M0, %L0, 32\n\t"			\
@@ -1404,37 +1504,43 @@ do {									\
 	local_irq_restore(__flags);					\
 } while (0)
 
-#define __readx_32bit_c0_register(source)				\
+#ifndef TOOLCHAIN_SUPPORTS_XPA
+_ASM_MACRO_2R_1S(mfhc0, rt, rs, sel,
+	_ASM_INSN_IF_MIPS(0x40400000 | __rt << 16 | __rs << 11 | \\sel)
+	_ASM_INSN32_IF_MM(0x000000f4 | __rt << 21 | __rs << 16 | \\sel << 11));
+_ASM_MACRO_2R_1S(mthc0, rt, rd, sel,
+	_ASM_INSN_IF_MIPS(0x40c00000 | __rt << 16 | __rd << 11 | \\sel)
+	_ASM_INSN32_IF_MM(0x000002f4 | __rt << 21 | __rd << 16 | \\sel << 11));
+#define _ASM_SET_XPA ""
+#else	/* !TOOLCHAIN_SUPPORTS_XPA */
+#define _ASM_SET_XPA ".set\txpa\n\t"
+#endif
+
+#define __readx_32bit_c0_register(source, sel)				\
 ({									\
 	unsigned int __res;						\
 									\
 	__asm__ __volatile__(						\
 	"	.set	push					\n"	\
-	"	.set	noat					\n"	\
 	"	.set	mips32r2				\n"	\
-	"	# mfhc0 $1, %1					\n"	\
-	_ASM_INSN_IF_MIPS(0x40410000 | ((%1 & 0x1f) << 11))		\
-	_ASM_INSN32_IF_MM(0x002000f4 | ((%1 & 0x1f) << 16))		\
-	"	move	%0, $1					\n"	\
+	_ASM_SET_XPA							\
+	"	mfhc0	%0, " #source ", %1			\n"	\
 	"	.set	pop					\n"	\
 	: "=r" (__res)							\
-	: "i" (source));						\
+	: "i" (sel));							\
 	__res;								\
 })
 
-#define __writex_32bit_c0_register(register, value)			\
+#define __writex_32bit_c0_register(register, sel, value)		\
 do {									\
 	__asm__ __volatile__(						\
 	"	.set	push					\n"	\
-	"	.set	noat					\n"	\
 	"	.set	mips32r2				\n"	\
-	"	move	$1, %0					\n"	\
-	"	# mthc0 $1, %1					\n"	\
-	_ASM_INSN_IF_MIPS(0x40c10000 | ((%1 & 0x1f) << 11))		\
-	_ASM_INSN32_IF_MM(0x002002f4 | ((%1 & 0x1f) << 16))		\
+	_ASM_SET_XPA							\
+	"	mthc0	%z0, " #register ", %1			\n"	\
 	"	.set	pop					\n"	\
 	:								\
-	: "r" (value), "i" (register));					\
+	: "Jr" (value), "i" (sel));					\
 } while (0)
 
 #define read_c0_index()		__read_32bit_c0_register($0, 0)
@@ -1446,14 +1552,14 @@ do {									\
 #define read_c0_entrylo0()	__read_ulong_c0_register($2, 0)
 #define write_c0_entrylo0(val)	__write_ulong_c0_register($2, 0, val)
 
-#define readx_c0_entrylo0()	__readx_32bit_c0_register(2)
-#define writex_c0_entrylo0(val)	__writex_32bit_c0_register(2, val)
+#define readx_c0_entrylo0()	__readx_32bit_c0_register($2, 0)
+#define writex_c0_entrylo0(val)	__writex_32bit_c0_register($2, 0, val)
 
 #define read_c0_entrylo1()	__read_ulong_c0_register($3, 0)
 #define write_c0_entrylo1(val)	__write_ulong_c0_register($3, 0, val)
 
-#define readx_c0_entrylo1()	__readx_32bit_c0_register(3)
-#define writex_c0_entrylo1(val)	__writex_32bit_c0_register(3, val)
+#define readx_c0_entrylo1()	__readx_32bit_c0_register($3, 0)
+#define writex_c0_entrylo1(val)	__writex_32bit_c0_register($3, 0, val)
 
 #define read_c0_conf()		__read_32bit_c0_register($3, 0)
 #define write_c0_conf(val)	__write_32bit_c0_register($3, 0, val)
@@ -1541,7 +1647,7 @@ do {									\
 #define read_c0_epc()		__read_ulong_c0_register($14, 0)
 #define write_c0_epc(val)	__write_ulong_c0_register($14, 0, val)
 
-#define read_c0_prid()		__read_32bit_c0_register($15, 0)
+#define read_c0_prid()		__read_const_32bit_c0_register($15, 0)
 
 #define read_c0_cmgcrbase()	__read_ulong_c0_register($15, 3)
 
@@ -1830,18 +1936,44 @@ do {									\
  * Macros to access the guest system control coprocessor
  */
 
-#ifdef TOOLCHAIN_SUPPORTS_VIRT
+#ifndef TOOLCHAIN_SUPPORTS_VIRT
+_ASM_MACRO_2R_1S(mfgc0, rt, rs, sel,
+	_ASM_INSN_IF_MIPS(0x40600000 | __rt << 16 | __rs << 11 | \\sel)
+	_ASM_INSN32_IF_MM(0x000004fc | __rt << 21 | __rs << 16 | \\sel << 11));
+_ASM_MACRO_2R_1S(dmfgc0, rt, rs, sel,
+	_ASM_INSN_IF_MIPS(0x40600100 | __rt << 16 | __rs << 11 | \\sel)
+	_ASM_INSN32_IF_MM(0x580004fc | __rt << 21 | __rs << 16 | \\sel << 11));
+_ASM_MACRO_2R_1S(mtgc0, rt, rd, sel,
+	_ASM_INSN_IF_MIPS(0x40600200 | __rt << 16 | __rd << 11 | \\sel)
+	_ASM_INSN32_IF_MM(0x000006fc | __rt << 21 | __rd << 16 | \\sel << 11));
+_ASM_MACRO_2R_1S(dmtgc0, rt, rd, sel,
+	_ASM_INSN_IF_MIPS(0x40600300 | __rt << 16 | __rd << 11 | \\sel)
+	_ASM_INSN32_IF_MM(0x580006fc | __rt << 21 | __rd << 16 | \\sel << 11));
+_ASM_MACRO_0(tlbgp,    _ASM_INSN_IF_MIPS(0x42000010)
+		       _ASM_INSN32_IF_MM(0x0000017c));
+_ASM_MACRO_0(tlbgr,    _ASM_INSN_IF_MIPS(0x42000009)
+		       _ASM_INSN32_IF_MM(0x0000117c));
+_ASM_MACRO_0(tlbgwi,   _ASM_INSN_IF_MIPS(0x4200000a)
+		       _ASM_INSN32_IF_MM(0x0000217c));
+_ASM_MACRO_0(tlbgwr,   _ASM_INSN_IF_MIPS(0x4200000e)
+		       _ASM_INSN32_IF_MM(0x0000317c));
+_ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c)
+		       _ASM_INSN32_IF_MM(0x0000517c));
+#define _ASM_SET_VIRT ""
+#else	/* !TOOLCHAIN_SUPPORTS_VIRT */
+#define _ASM_SET_VIRT ".set\tvirt\n\t"
+#endif
 
 #define __read_32bit_gc0_register(source, sel)				\
 ({ int __res;								\
 	__asm__ __volatile__(						\
 		".set\tpush\n\t"					\
 		".set\tmips32r2\n\t"					\
-		".set\tvirt\n\t"					\
-		"mfgc0\t%0, $%1, %2\n\t"				\
+		_ASM_SET_VIRT						\
+		"mfgc0\t%0, " #source ", %1\n\t"			\
 		".set\tpop"						\
 		: "=r" (__res)						\
-		: "i" (source), "i" (sel));				\
+		: "i" (sel));						\
 	__res;								\
 })
 
@@ -1850,11 +1982,11 @@ do {									\
 	__asm__ __volatile__(						\
 		".set\tpush\n\t"					\
 		".set\tmips64r2\n\t"					\
-		".set\tvirt\n\t"					\
-		"dmfgc0\t%0, $%1, %2\n\t"			\
+		_ASM_SET_VIRT						\
+		"dmfgc0\t%0, " #source ", %1\n\t"			\
 		".set\tpop"						\
 		: "=r" (__res)						\
-		: "i" (source), "i" (sel));				\
+		: "i" (sel));						\
 	__res;								\
 })
 
@@ -1863,11 +1995,11 @@ do {									\
 	__asm__ __volatile__(						\
 		".set\tpush\n\t"					\
 		".set\tmips32r2\n\t"					\
-		".set\tvirt\n\t"					\
-		"mtgc0\t%z0, $%1, %2\n\t"				\
+		_ASM_SET_VIRT						\
+		"mtgc0\t%z0, " #register ", %1\n\t"			\
 		".set\tpop"						\
 		: : "Jr" ((unsigned int)(value)),			\
-		    "i" (register), "i" (sel));				\
+		    "i" (sel));						\
 } while (0)
 
 #define __write_64bit_gc0_register(register, sel, value)		\
@@ -1875,75 +2007,13 @@ do {									\
 	__asm__ __volatile__(						\
 		".set\tpush\n\t"					\
 		".set\tmips64r2\n\t"					\
-		".set\tvirt\n\t"					\
-		"dmtgc0\t%z0, $%1, %2\n\t"				\
+		_ASM_SET_VIRT						\
+		"dmtgc0\t%z0, " #register ", %1\n\t"			\
 		".set\tpop"						\
 		: : "Jr" (value),					\
-		    "i" (register), "i" (sel));				\
+		    "i" (sel));						\
 } while (0)
 
-#else	/* TOOLCHAIN_SUPPORTS_VIRT */
-
-#define __read_32bit_gc0_register(source, sel)				\
-({ int __res;								\
-	__asm__ __volatile__(						\
-		".set\tpush\n\t"					\
-		".set\tnoat\n\t"					\
-		"# mfgc0\t$1, $%1, %2\n\t"				\
-		_ASM_INSN_IF_MIPS(0x40610000 | %1 << 11 | %2)		\
-		_ASM_INSN32_IF_MM(0x002004fc | %1 << 16 | %2 << 11)	\
-		"move\t%0, $1\n\t"					\
-		".set\tpop"						\
-		: "=r" (__res)						\
-		: "i" (source), "i" (sel));				\
-	__res;								\
-})
-
-#define __read_64bit_gc0_register(source, sel)				\
-({ unsigned long long __res;						\
-	__asm__ __volatile__(						\
-		".set\tpush\n\t"					\
-		".set\tnoat\n\t"					\
-		"# dmfgc0\t$1, $%1, %2\n\t"				\
-		_ASM_INSN_IF_MIPS(0x40610100 | %1 << 11 | %2)		\
-		_ASM_INSN32_IF_MM(0x582004fc | %1 << 16 | %2 << 11)	\
-		"move\t%0, $1\n\t"					\
-		".set\tpop"						\
-		: "=r" (__res)						\
-		: "i" (source), "i" (sel));				\
-	__res;								\
-})
-
-#define __write_32bit_gc0_register(register, sel, value)		\
-do {									\
-	__asm__ __volatile__(						\
-		".set\tpush\n\t"					\
-		".set\tnoat\n\t"					\
-		"move\t$1, %z0\n\t"					\
-		"# mtgc0\t$1, $%1, %2\n\t"				\
-		_ASM_INSN_IF_MIPS(0x40610200 | %1 << 11 | %2)		\
-		_ASM_INSN32_IF_MM(0x002006fc | %1 << 16 | %2 << 11)	\
-		".set\tpop"						\
-		: : "Jr" ((unsigned int)(value)),			\
-		    "i" (register), "i" (sel));				\
-} while (0)
-
-#define __write_64bit_gc0_register(register, sel, value)		\
-do {									\
-	__asm__ __volatile__(						\
-		".set\tpush\n\t"					\
-		".set\tnoat\n\t"					\
-		"move\t$1, %z0\n\t"					\
-		"# dmtgc0\t$1, $%1, %2\n\t"				\
-		_ASM_INSN_IF_MIPS(0x40610300 | %1 << 11 | %2)		\
-		_ASM_INSN32_IF_MM(0x582006fc | %1 << 16 | %2 << 11)	\
-		".set\tpop"						\
-		: : "Jr" (value),					\
-		    "i" (register), "i" (sel));				\
-} while (0)
-
-#endif	/* !TOOLCHAIN_SUPPORTS_VIRT */
-
 #define __read_ulong_gc0_register(reg, sel)				\
 	((sizeof(unsigned long) == 4) ?					\
 	(unsigned long) __read_32bit_gc0_register(reg, sel) :		\
@@ -1957,207 +2027,207 @@ do {									\
 		__write_64bit_gc0_register(reg, sel, val);		\
 } while (0)
 
-#define read_gc0_index()		__read_32bit_gc0_register(0, 0)
-#define write_gc0_index(val)		__write_32bit_gc0_register(0, 0, val)
+#define read_gc0_index()		__read_32bit_gc0_register($0, 0)
+#define write_gc0_index(val)		__write_32bit_gc0_register($0, 0, val)
 
-#define read_gc0_entrylo0()		__read_ulong_gc0_register(2, 0)
-#define write_gc0_entrylo0(val)		__write_ulong_gc0_register(2, 0, val)
+#define read_gc0_entrylo0()		__read_ulong_gc0_register($2, 0)
+#define write_gc0_entrylo0(val)		__write_ulong_gc0_register($2, 0, val)
 
-#define read_gc0_entrylo1()		__read_ulong_gc0_register(3, 0)
-#define write_gc0_entrylo1(val)		__write_ulong_gc0_register(3, 0, val)
+#define read_gc0_entrylo1()		__read_ulong_gc0_register($3, 0)
+#define write_gc0_entrylo1(val)		__write_ulong_gc0_register($3, 0, val)
 
-#define read_gc0_context()		__read_ulong_gc0_register(4, 0)
-#define write_gc0_context(val)		__write_ulong_gc0_register(4, 0, val)
+#define read_gc0_context()		__read_ulong_gc0_register($4, 0)
+#define write_gc0_context(val)		__write_ulong_gc0_register($4, 0, val)
 
-#define read_gc0_contextconfig()	__read_32bit_gc0_register(4, 1)
-#define write_gc0_contextconfig(val)	__write_32bit_gc0_register(4, 1, val)
+#define read_gc0_contextconfig()	__read_32bit_gc0_register($4, 1)
+#define write_gc0_contextconfig(val)	__write_32bit_gc0_register($4, 1, val)
 
-#define read_gc0_userlocal()		__read_ulong_gc0_register(4, 2)
-#define write_gc0_userlocal(val)	__write_ulong_gc0_register(4, 2, val)
+#define read_gc0_userlocal()		__read_ulong_gc0_register($4, 2)
+#define write_gc0_userlocal(val)	__write_ulong_gc0_register($4, 2, val)
 
-#define read_gc0_xcontextconfig()	__read_ulong_gc0_register(4, 3)
-#define write_gc0_xcontextconfig(val)	__write_ulong_gc0_register(4, 3, val)
+#define read_gc0_xcontextconfig()	__read_ulong_gc0_register($4, 3)
+#define write_gc0_xcontextconfig(val)	__write_ulong_gc0_register($4, 3, val)
 
-#define read_gc0_pagemask()		__read_32bit_gc0_register(5, 0)
-#define write_gc0_pagemask(val)		__write_32bit_gc0_register(5, 0, val)
+#define read_gc0_pagemask()		__read_32bit_gc0_register($5, 0)
+#define write_gc0_pagemask(val)		__write_32bit_gc0_register($5, 0, val)
 
-#define read_gc0_pagegrain()		__read_32bit_gc0_register(5, 1)
-#define write_gc0_pagegrain(val)	__write_32bit_gc0_register(5, 1, val)
+#define read_gc0_pagegrain()		__read_32bit_gc0_register($5, 1)
+#define write_gc0_pagegrain(val)	__write_32bit_gc0_register($5, 1, val)
 
-#define read_gc0_segctl0()		__read_ulong_gc0_register(5, 2)
-#define write_gc0_segctl0(val)		__write_ulong_gc0_register(5, 2, val)
+#define read_gc0_segctl0()		__read_ulong_gc0_register($5, 2)
+#define write_gc0_segctl0(val)		__write_ulong_gc0_register($5, 2, val)
 
-#define read_gc0_segctl1()		__read_ulong_gc0_register(5, 3)
-#define write_gc0_segctl1(val)		__write_ulong_gc0_register(5, 3, val)
+#define read_gc0_segctl1()		__read_ulong_gc0_register($5, 3)
+#define write_gc0_segctl1(val)		__write_ulong_gc0_register($5, 3, val)
 
-#define read_gc0_segctl2()		__read_ulong_gc0_register(5, 4)
-#define write_gc0_segctl2(val)		__write_ulong_gc0_register(5, 4, val)
+#define read_gc0_segctl2()		__read_ulong_gc0_register($5, 4)
+#define write_gc0_segctl2(val)		__write_ulong_gc0_register($5, 4, val)
 
-#define read_gc0_pwbase()		__read_ulong_gc0_register(5, 5)
-#define write_gc0_pwbase(val)		__write_ulong_gc0_register(5, 5, val)
+#define read_gc0_pwbase()		__read_ulong_gc0_register($5, 5)
+#define write_gc0_pwbase(val)		__write_ulong_gc0_register($5, 5, val)
 
-#define read_gc0_pwfield()		__read_ulong_gc0_register(5, 6)
-#define write_gc0_pwfield(val)		__write_ulong_gc0_register(5, 6, val)
+#define read_gc0_pwfield()		__read_ulong_gc0_register($5, 6)
+#define write_gc0_pwfield(val)		__write_ulong_gc0_register($5, 6, val)
 
-#define read_gc0_pwsize()		__read_ulong_gc0_register(5, 7)
-#define write_gc0_pwsize(val)		__write_ulong_gc0_register(5, 7, val)
+#define read_gc0_pwsize()		__read_ulong_gc0_register($5, 7)
+#define write_gc0_pwsize(val)		__write_ulong_gc0_register($5, 7, val)
 
-#define read_gc0_wired()		__read_32bit_gc0_register(6, 0)
-#define write_gc0_wired(val)		__write_32bit_gc0_register(6, 0, val)
+#define read_gc0_wired()		__read_32bit_gc0_register($6, 0)
+#define write_gc0_wired(val)		__write_32bit_gc0_register($6, 0, val)
 
-#define read_gc0_pwctl()		__read_32bit_gc0_register(6, 6)
-#define write_gc0_pwctl(val)		__write_32bit_gc0_register(6, 6, val)
+#define read_gc0_pwctl()		__read_32bit_gc0_register($6, 6)
+#define write_gc0_pwctl(val)		__write_32bit_gc0_register($6, 6, val)
 
-#define read_gc0_hwrena()		__read_32bit_gc0_register(7, 0)
-#define write_gc0_hwrena(val)		__write_32bit_gc0_register(7, 0, val)
+#define read_gc0_hwrena()		__read_32bit_gc0_register($7, 0)
+#define write_gc0_hwrena(val)		__write_32bit_gc0_register($7, 0, val)
 
-#define read_gc0_badvaddr()		__read_ulong_gc0_register(8, 0)
-#define write_gc0_badvaddr(val)		__write_ulong_gc0_register(8, 0, val)
+#define read_gc0_badvaddr()		__read_ulong_gc0_register($8, 0)
+#define write_gc0_badvaddr(val)		__write_ulong_gc0_register($8, 0, val)
 
-#define read_gc0_badinstr()		__read_32bit_gc0_register(8, 1)
-#define write_gc0_badinstr(val)		__write_32bit_gc0_register(8, 1, val)
+#define read_gc0_badinstr()		__read_32bit_gc0_register($8, 1)
+#define write_gc0_badinstr(val)		__write_32bit_gc0_register($8, 1, val)
 
-#define read_gc0_badinstrp()		__read_32bit_gc0_register(8, 2)
-#define write_gc0_badinstrp(val)	__write_32bit_gc0_register(8, 2, val)
+#define read_gc0_badinstrp()		__read_32bit_gc0_register($8, 2)
+#define write_gc0_badinstrp(val)	__write_32bit_gc0_register($8, 2, val)
 
-#define read_gc0_count()		__read_32bit_gc0_register(9, 0)
+#define read_gc0_count()		__read_32bit_gc0_register($9, 0)
 
-#define read_gc0_entryhi()		__read_ulong_gc0_register(10, 0)
-#define write_gc0_entryhi(val)		__write_ulong_gc0_register(10, 0, val)
+#define read_gc0_entryhi()		__read_ulong_gc0_register($10, 0)
+#define write_gc0_entryhi(val)		__write_ulong_gc0_register($10, 0, val)
 
-#define read_gc0_compare()		__read_32bit_gc0_register(11, 0)
-#define write_gc0_compare(val)		__write_32bit_gc0_register(11, 0, val)
+#define read_gc0_compare()		__read_32bit_gc0_register($11, 0)
+#define write_gc0_compare(val)		__write_32bit_gc0_register($11, 0, val)
 
-#define read_gc0_status()		__read_32bit_gc0_register(12, 0)
-#define write_gc0_status(val)		__write_32bit_gc0_register(12, 0, val)
+#define read_gc0_status()		__read_32bit_gc0_register($12, 0)
+#define write_gc0_status(val)		__write_32bit_gc0_register($12, 0, val)
 
-#define read_gc0_intctl()		__read_32bit_gc0_register(12, 1)
-#define write_gc0_intctl(val)		__write_32bit_gc0_register(12, 1, val)
+#define read_gc0_intctl()		__read_32bit_gc0_register($12, 1)
+#define write_gc0_intctl(val)		__write_32bit_gc0_register($12, 1, val)
 
-#define read_gc0_cause()		__read_32bit_gc0_register(13, 0)
-#define write_gc0_cause(val)		__write_32bit_gc0_register(13, 0, val)
+#define read_gc0_cause()		__read_32bit_gc0_register($13, 0)
+#define write_gc0_cause(val)		__write_32bit_gc0_register($13, 0, val)
 
-#define read_gc0_epc()			__read_ulong_gc0_register(14, 0)
-#define write_gc0_epc(val)		__write_ulong_gc0_register(14, 0, val)
+#define read_gc0_epc()			__read_ulong_gc0_register($14, 0)
+#define write_gc0_epc(val)		__write_ulong_gc0_register($14, 0, val)
 
-#define read_gc0_prid()			__read_32bit_gc0_register(15, 0)
+#define read_gc0_prid()			__read_32bit_gc0_register($15, 0)
 
-#define read_gc0_ebase()		__read_32bit_gc0_register(15, 1)
-#define write_gc0_ebase(val)		__write_32bit_gc0_register(15, 1, val)
+#define read_gc0_ebase()		__read_32bit_gc0_register($15, 1)
+#define write_gc0_ebase(val)		__write_32bit_gc0_register($15, 1, val)
 
-#define read_gc0_ebase_64()		__read_64bit_gc0_register(15, 1)
-#define write_gc0_ebase_64(val)		__write_64bit_gc0_register(15, 1, val)
+#define read_gc0_ebase_64()		__read_64bit_gc0_register($15, 1)
+#define write_gc0_ebase_64(val)		__write_64bit_gc0_register($15, 1, val)
 
-#define read_gc0_config()		__read_32bit_gc0_register(16, 0)
-#define read_gc0_config1()		__read_32bit_gc0_register(16, 1)
-#define read_gc0_config2()		__read_32bit_gc0_register(16, 2)
-#define read_gc0_config3()		__read_32bit_gc0_register(16, 3)
-#define read_gc0_config4()		__read_32bit_gc0_register(16, 4)
-#define read_gc0_config5()		__read_32bit_gc0_register(16, 5)
-#define read_gc0_config6()		__read_32bit_gc0_register(16, 6)
-#define read_gc0_config7()		__read_32bit_gc0_register(16, 7)
-#define write_gc0_config(val)		__write_32bit_gc0_register(16, 0, val)
-#define write_gc0_config1(val)		__write_32bit_gc0_register(16, 1, val)
-#define write_gc0_config2(val)		__write_32bit_gc0_register(16, 2, val)
-#define write_gc0_config3(val)		__write_32bit_gc0_register(16, 3, val)
-#define write_gc0_config4(val)		__write_32bit_gc0_register(16, 4, val)
-#define write_gc0_config5(val)		__write_32bit_gc0_register(16, 5, val)
-#define write_gc0_config6(val)		__write_32bit_gc0_register(16, 6, val)
-#define write_gc0_config7(val)		__write_32bit_gc0_register(16, 7, val)
+#define read_gc0_config()		__read_32bit_gc0_register($16, 0)
+#define read_gc0_config1()		__read_32bit_gc0_register($16, 1)
+#define read_gc0_config2()		__read_32bit_gc0_register($16, 2)
+#define read_gc0_config3()		__read_32bit_gc0_register($16, 3)
+#define read_gc0_config4()		__read_32bit_gc0_register($16, 4)
+#define read_gc0_config5()		__read_32bit_gc0_register($16, 5)
+#define read_gc0_config6()		__read_32bit_gc0_register($16, 6)
+#define read_gc0_config7()		__read_32bit_gc0_register($16, 7)
+#define write_gc0_config(val)		__write_32bit_gc0_register($16, 0, val)
+#define write_gc0_config1(val)		__write_32bit_gc0_register($16, 1, val)
+#define write_gc0_config2(val)		__write_32bit_gc0_register($16, 2, val)
+#define write_gc0_config3(val)		__write_32bit_gc0_register($16, 3, val)
+#define write_gc0_config4(val)		__write_32bit_gc0_register($16, 4, val)
+#define write_gc0_config5(val)		__write_32bit_gc0_register($16, 5, val)
+#define write_gc0_config6(val)		__write_32bit_gc0_register($16, 6, val)
+#define write_gc0_config7(val)		__write_32bit_gc0_register($16, 7, val)
 
-#define read_gc0_lladdr()		__read_ulong_gc0_register(17, 0)
-#define write_gc0_lladdr(val)		__write_ulong_gc0_register(17, 0, val)
+#define read_gc0_lladdr()		__read_ulong_gc0_register($17, 0)
+#define write_gc0_lladdr(val)		__write_ulong_gc0_register($17, 0, val)
 
-#define read_gc0_watchlo0()		__read_ulong_gc0_register(18, 0)
-#define read_gc0_watchlo1()		__read_ulong_gc0_register(18, 1)
-#define read_gc0_watchlo2()		__read_ulong_gc0_register(18, 2)
-#define read_gc0_watchlo3()		__read_ulong_gc0_register(18, 3)
-#define read_gc0_watchlo4()		__read_ulong_gc0_register(18, 4)
-#define read_gc0_watchlo5()		__read_ulong_gc0_register(18, 5)
-#define read_gc0_watchlo6()		__read_ulong_gc0_register(18, 6)
-#define read_gc0_watchlo7()		__read_ulong_gc0_register(18, 7)
-#define write_gc0_watchlo0(val)		__write_ulong_gc0_register(18, 0, val)
-#define write_gc0_watchlo1(val)		__write_ulong_gc0_register(18, 1, val)
-#define write_gc0_watchlo2(val)		__write_ulong_gc0_register(18, 2, val)
-#define write_gc0_watchlo3(val)		__write_ulong_gc0_register(18, 3, val)
-#define write_gc0_watchlo4(val)		__write_ulong_gc0_register(18, 4, val)
-#define write_gc0_watchlo5(val)		__write_ulong_gc0_register(18, 5, val)
-#define write_gc0_watchlo6(val)		__write_ulong_gc0_register(18, 6, val)
-#define write_gc0_watchlo7(val)		__write_ulong_gc0_register(18, 7, val)
+#define read_gc0_watchlo0()		__read_ulong_gc0_register($18, 0)
+#define read_gc0_watchlo1()		__read_ulong_gc0_register($18, 1)
+#define read_gc0_watchlo2()		__read_ulong_gc0_register($18, 2)
+#define read_gc0_watchlo3()		__read_ulong_gc0_register($18, 3)
+#define read_gc0_watchlo4()		__read_ulong_gc0_register($18, 4)
+#define read_gc0_watchlo5()		__read_ulong_gc0_register($18, 5)
+#define read_gc0_watchlo6()		__read_ulong_gc0_register($18, 6)
+#define read_gc0_watchlo7()		__read_ulong_gc0_register($18, 7)
+#define write_gc0_watchlo0(val)		__write_ulong_gc0_register($18, 0, val)
+#define write_gc0_watchlo1(val)		__write_ulong_gc0_register($18, 1, val)
+#define write_gc0_watchlo2(val)		__write_ulong_gc0_register($18, 2, val)
+#define write_gc0_watchlo3(val)		__write_ulong_gc0_register($18, 3, val)
+#define write_gc0_watchlo4(val)		__write_ulong_gc0_register($18, 4, val)
+#define write_gc0_watchlo5(val)		__write_ulong_gc0_register($18, 5, val)
+#define write_gc0_watchlo6(val)		__write_ulong_gc0_register($18, 6, val)
+#define write_gc0_watchlo7(val)		__write_ulong_gc0_register($18, 7, val)
 
-#define read_gc0_watchhi0()		__read_32bit_gc0_register(19, 0)
-#define read_gc0_watchhi1()		__read_32bit_gc0_register(19, 1)
-#define read_gc0_watchhi2()		__read_32bit_gc0_register(19, 2)
-#define read_gc0_watchhi3()		__read_32bit_gc0_register(19, 3)
-#define read_gc0_watchhi4()		__read_32bit_gc0_register(19, 4)
-#define read_gc0_watchhi5()		__read_32bit_gc0_register(19, 5)
-#define read_gc0_watchhi6()		__read_32bit_gc0_register(19, 6)
-#define read_gc0_watchhi7()		__read_32bit_gc0_register(19, 7)
-#define write_gc0_watchhi0(val)		__write_32bit_gc0_register(19, 0, val)
-#define write_gc0_watchhi1(val)		__write_32bit_gc0_register(19, 1, val)
-#define write_gc0_watchhi2(val)		__write_32bit_gc0_register(19, 2, val)
-#define write_gc0_watchhi3(val)		__write_32bit_gc0_register(19, 3, val)
-#define write_gc0_watchhi4(val)		__write_32bit_gc0_register(19, 4, val)
-#define write_gc0_watchhi5(val)		__write_32bit_gc0_register(19, 5, val)
-#define write_gc0_watchhi6(val)		__write_32bit_gc0_register(19, 6, val)
-#define write_gc0_watchhi7(val)		__write_32bit_gc0_register(19, 7, val)
+#define read_gc0_watchhi0()		__read_32bit_gc0_register($19, 0)
+#define read_gc0_watchhi1()		__read_32bit_gc0_register($19, 1)
+#define read_gc0_watchhi2()		__read_32bit_gc0_register($19, 2)
+#define read_gc0_watchhi3()		__read_32bit_gc0_register($19, 3)
+#define read_gc0_watchhi4()		__read_32bit_gc0_register($19, 4)
+#define read_gc0_watchhi5()		__read_32bit_gc0_register($19, 5)
+#define read_gc0_watchhi6()		__read_32bit_gc0_register($19, 6)
+#define read_gc0_watchhi7()		__read_32bit_gc0_register($19, 7)
+#define write_gc0_watchhi0(val)		__write_32bit_gc0_register($19, 0, val)
+#define write_gc0_watchhi1(val)		__write_32bit_gc0_register($19, 1, val)
+#define write_gc0_watchhi2(val)		__write_32bit_gc0_register($19, 2, val)
+#define write_gc0_watchhi3(val)		__write_32bit_gc0_register($19, 3, val)
+#define write_gc0_watchhi4(val)		__write_32bit_gc0_register($19, 4, val)
+#define write_gc0_watchhi5(val)		__write_32bit_gc0_register($19, 5, val)
+#define write_gc0_watchhi6(val)		__write_32bit_gc0_register($19, 6, val)
+#define write_gc0_watchhi7(val)		__write_32bit_gc0_register($19, 7, val)
 
-#define read_gc0_xcontext()		__read_ulong_gc0_register(20, 0)
-#define write_gc0_xcontext(val)		__write_ulong_gc0_register(20, 0, val)
+#define read_gc0_xcontext()		__read_ulong_gc0_register($20, 0)
+#define write_gc0_xcontext(val)		__write_ulong_gc0_register($20, 0, val)
 
-#define read_gc0_perfctrl0()		__read_32bit_gc0_register(25, 0)
-#define write_gc0_perfctrl0(val)	__write_32bit_gc0_register(25, 0, val)
-#define read_gc0_perfcntr0()		__read_32bit_gc0_register(25, 1)
-#define write_gc0_perfcntr0(val)	__write_32bit_gc0_register(25, 1, val)
-#define read_gc0_perfcntr0_64()		__read_64bit_gc0_register(25, 1)
-#define write_gc0_perfcntr0_64(val)	__write_64bit_gc0_register(25, 1, val)
-#define read_gc0_perfctrl1()		__read_32bit_gc0_register(25, 2)
-#define write_gc0_perfctrl1(val)	__write_32bit_gc0_register(25, 2, val)
-#define read_gc0_perfcntr1()		__read_32bit_gc0_register(25, 3)
-#define write_gc0_perfcntr1(val)	__write_32bit_gc0_register(25, 3, val)
-#define read_gc0_perfcntr1_64()		__read_64bit_gc0_register(25, 3)
-#define write_gc0_perfcntr1_64(val)	__write_64bit_gc0_register(25, 3, val)
-#define read_gc0_perfctrl2()		__read_32bit_gc0_register(25, 4)
-#define write_gc0_perfctrl2(val)	__write_32bit_gc0_register(25, 4, val)
-#define read_gc0_perfcntr2()		__read_32bit_gc0_register(25, 5)
-#define write_gc0_perfcntr2(val)	__write_32bit_gc0_register(25, 5, val)
-#define read_gc0_perfcntr2_64()		__read_64bit_gc0_register(25, 5)
-#define write_gc0_perfcntr2_64(val)	__write_64bit_gc0_register(25, 5, val)
-#define read_gc0_perfctrl3()		__read_32bit_gc0_register(25, 6)
-#define write_gc0_perfctrl3(val)	__write_32bit_gc0_register(25, 6, val)
-#define read_gc0_perfcntr3()		__read_32bit_gc0_register(25, 7)
-#define write_gc0_perfcntr3(val)	__write_32bit_gc0_register(25, 7, val)
-#define read_gc0_perfcntr3_64()		__read_64bit_gc0_register(25, 7)
-#define write_gc0_perfcntr3_64(val)	__write_64bit_gc0_register(25, 7, val)
+#define read_gc0_perfctrl0()		__read_32bit_gc0_register($25, 0)
+#define write_gc0_perfctrl0(val)	__write_32bit_gc0_register($25, 0, val)
+#define read_gc0_perfcntr0()		__read_32bit_gc0_register($25, 1)
+#define write_gc0_perfcntr0(val)	__write_32bit_gc0_register($25, 1, val)
+#define read_gc0_perfcntr0_64()		__read_64bit_gc0_register($25, 1)
+#define write_gc0_perfcntr0_64(val)	__write_64bit_gc0_register($25, 1, val)
+#define read_gc0_perfctrl1()		__read_32bit_gc0_register($25, 2)
+#define write_gc0_perfctrl1(val)	__write_32bit_gc0_register($25, 2, val)
+#define read_gc0_perfcntr1()		__read_32bit_gc0_register($25, 3)
+#define write_gc0_perfcntr1(val)	__write_32bit_gc0_register($25, 3, val)
+#define read_gc0_perfcntr1_64()		__read_64bit_gc0_register($25, 3)
+#define write_gc0_perfcntr1_64(val)	__write_64bit_gc0_register($25, 3, val)
+#define read_gc0_perfctrl2()		__read_32bit_gc0_register($25, 4)
+#define write_gc0_perfctrl2(val)	__write_32bit_gc0_register($25, 4, val)
+#define read_gc0_perfcntr2()		__read_32bit_gc0_register($25, 5)
+#define write_gc0_perfcntr2(val)	__write_32bit_gc0_register($25, 5, val)
+#define read_gc0_perfcntr2_64()		__read_64bit_gc0_register($25, 5)
+#define write_gc0_perfcntr2_64(val)	__write_64bit_gc0_register($25, 5, val)
+#define read_gc0_perfctrl3()		__read_32bit_gc0_register($25, 6)
+#define write_gc0_perfctrl3(val)	__write_32bit_gc0_register($25, 6, val)
+#define read_gc0_perfcntr3()		__read_32bit_gc0_register($25, 7)
+#define write_gc0_perfcntr3(val)	__write_32bit_gc0_register($25, 7, val)
+#define read_gc0_perfcntr3_64()		__read_64bit_gc0_register($25, 7)
+#define write_gc0_perfcntr3_64(val)	__write_64bit_gc0_register($25, 7, val)
 
-#define read_gc0_errorepc()		__read_ulong_gc0_register(30, 0)
-#define write_gc0_errorepc(val)		__write_ulong_gc0_register(30, 0, val)
+#define read_gc0_errorepc()		__read_ulong_gc0_register($30, 0)
+#define write_gc0_errorepc(val)		__write_ulong_gc0_register($30, 0, val)
 
-#define read_gc0_kscratch1()		__read_ulong_gc0_register(31, 2)
-#define read_gc0_kscratch2()		__read_ulong_gc0_register(31, 3)
-#define read_gc0_kscratch3()		__read_ulong_gc0_register(31, 4)
-#define read_gc0_kscratch4()		__read_ulong_gc0_register(31, 5)
-#define read_gc0_kscratch5()		__read_ulong_gc0_register(31, 6)
-#define read_gc0_kscratch6()		__read_ulong_gc0_register(31, 7)
-#define write_gc0_kscratch1(val)	__write_ulong_gc0_register(31, 2, val)
-#define write_gc0_kscratch2(val)	__write_ulong_gc0_register(31, 3, val)
-#define write_gc0_kscratch3(val)	__write_ulong_gc0_register(31, 4, val)
-#define write_gc0_kscratch4(val)	__write_ulong_gc0_register(31, 5, val)
-#define write_gc0_kscratch5(val)	__write_ulong_gc0_register(31, 6, val)
-#define write_gc0_kscratch6(val)	__write_ulong_gc0_register(31, 7, val)
+#define read_gc0_kscratch1()		__read_ulong_gc0_register($31, 2)
+#define read_gc0_kscratch2()		__read_ulong_gc0_register($31, 3)
+#define read_gc0_kscratch3()		__read_ulong_gc0_register($31, 4)
+#define read_gc0_kscratch4()		__read_ulong_gc0_register($31, 5)
+#define read_gc0_kscratch5()		__read_ulong_gc0_register($31, 6)
+#define read_gc0_kscratch6()		__read_ulong_gc0_register($31, 7)
+#define write_gc0_kscratch1(val)	__write_ulong_gc0_register($31, 2, val)
+#define write_gc0_kscratch2(val)	__write_ulong_gc0_register($31, 3, val)
+#define write_gc0_kscratch3(val)	__write_ulong_gc0_register($31, 4, val)
+#define write_gc0_kscratch4(val)	__write_ulong_gc0_register($31, 5, val)
+#define write_gc0_kscratch5(val)	__write_ulong_gc0_register($31, 6, val)
+#define write_gc0_kscratch6(val)	__write_ulong_gc0_register($31, 7, val)
 
 /* Cavium OCTEON (cnMIPS) */
-#define read_gc0_cvmcount()		__read_ulong_gc0_register(9, 6)
-#define write_gc0_cvmcount(val)		__write_ulong_gc0_register(9, 6, val)
+#define read_gc0_cvmcount()		__read_ulong_gc0_register($9, 6)
+#define write_gc0_cvmcount(val)		__write_ulong_gc0_register($9, 6, val)
 
-#define read_gc0_cvmctl()		__read_64bit_gc0_register(9, 7)
-#define write_gc0_cvmctl(val)		__write_64bit_gc0_register(9, 7, val)
+#define read_gc0_cvmctl()		__read_64bit_gc0_register($9, 7)
+#define write_gc0_cvmctl(val)		__write_64bit_gc0_register($9, 7, val)
 
-#define read_gc0_cvmmemctl()		__read_64bit_gc0_register(11, 7)
-#define write_gc0_cvmmemctl(val)	__write_64bit_gc0_register(11, 7, val)
+#define read_gc0_cvmmemctl()		__read_64bit_gc0_register($11, 7)
+#define write_gc0_cvmmemctl(val)	__write_64bit_gc0_register($11, 7, val)
 
-#define read_gc0_cvmmemctl2()		__read_64bit_gc0_register(16, 6)
-#define write_gc0_cvmmemctl2(val)	__write_64bit_gc0_register(16, 6, val)
+#define read_gc0_cvmmemctl2()		__read_64bit_gc0_register($16, 6)
+#define write_gc0_cvmmemctl2(val)	__write_64bit_gc0_register($16, 6, val)
 
 /*
  * Macros to access the floating point coprocessor control registers
@@ -2581,8 +2651,6 @@ static inline void tlb_write_random(void)
 		".set reorder");
 }
 
-#ifdef TOOLCHAIN_SUPPORTS_VIRT
-
 /*
  * Guest TLB operations.
  *
@@ -2593,7 +2661,7 @@ static inline void guest_tlb_probe(void)
 	__asm__ __volatile__(
 		".set push\n\t"
 		".set noreorder\n\t"
-		".set virt\n\t"
+		_ASM_SET_VIRT
 		"tlbgp\n\t"
 		".set pop");
 }
@@ -2603,7 +2671,7 @@ static inline void guest_tlb_read(void)
 	__asm__ __volatile__(
 		".set push\n\t"
 		".set noreorder\n\t"
-		".set virt\n\t"
+		_ASM_SET_VIRT
 		"tlbgr\n\t"
 		".set pop");
 }
@@ -2613,7 +2681,7 @@ static inline void guest_tlb_write_indexed(void)
 	__asm__ __volatile__(
 		".set push\n\t"
 		".set noreorder\n\t"
-		".set virt\n\t"
+		_ASM_SET_VIRT
 		"tlbgwi\n\t"
 		".set pop");
 }
@@ -2623,7 +2691,7 @@ static inline void guest_tlb_write_random(void)
 	__asm__ __volatile__(
 		".set push\n\t"
 		".set noreorder\n\t"
-		".set virt\n\t"
+		_ASM_SET_VIRT
 		"tlbgwr\n\t"
 		".set pop");
 }
@@ -2636,63 +2704,11 @@ static inline void guest_tlbinvf(void)
 	__asm__ __volatile__(
 		".set push\n\t"
 		".set noreorder\n\t"
-		".set virt\n\t"
+		_ASM_SET_VIRT
 		"tlbginvf\n\t"
 		".set pop");
 }
 
-#else	/* TOOLCHAIN_SUPPORTS_VIRT */
-
-/*
- * Guest TLB operations.
- *
- * It is responsibility of the caller to take care of any TLB hazards.
- */
-static inline void guest_tlb_probe(void)
-{
-	__asm__ __volatile__(
-		"# tlbgp\n\t"
-		_ASM_INSN_IF_MIPS(0x42000010)
-		_ASM_INSN32_IF_MM(0x0000017c));
-}
-
-static inline void guest_tlb_read(void)
-{
-	__asm__ __volatile__(
-		"# tlbgr\n\t"
-		_ASM_INSN_IF_MIPS(0x42000009)
-		_ASM_INSN32_IF_MM(0x0000117c));
-}
-
-static inline void guest_tlb_write_indexed(void)
-{
-	__asm__ __volatile__(
-		"# tlbgwi\n\t"
-		_ASM_INSN_IF_MIPS(0x4200000a)
-		_ASM_INSN32_IF_MM(0x0000217c));
-}
-
-static inline void guest_tlb_write_random(void)
-{
-	__asm__ __volatile__(
-		"# tlbgwr\n\t"
-		_ASM_INSN_IF_MIPS(0x4200000e)
-		_ASM_INSN32_IF_MM(0x0000317c));
-}
-
-/*
- * Guest TLB Invalidate Flush
- */
-static inline void guest_tlbinvf(void)
-{
-	__asm__ __volatile__(
-		"# tlbginvf\n\t"
-		_ASM_INSN_IF_MIPS(0x4200000c)
-		_ASM_INSN32_IF_MM(0x0000517c));
-}
-
-#endif	/* !TOOLCHAIN_SUPPORTS_VIRT */
-
 /*
  * Manipulate bits in a register.
  */
diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h
index b184510..b4f9577 100644
--- a/arch/mips/include/asm/msa.h
+++ b/arch/mips/include/asm/msa.h
@@ -160,7 +160,23 @@ static inline void init_msa_upper(void)
 	_init_msa_upper();
 }
 
-#ifdef TOOLCHAIN_SUPPORTS_MSA
+#ifndef TOOLCHAIN_SUPPORTS_MSA
+/*
+ * Define assembler macros using .word for the c[ft]cmsa instructions in order
+ * to allow compilation with toolchains that do not support MSA. Once all
+ * toolchains in use support MSA these can be removed.
+ */
+_ASM_MACRO_2R(cfcmsa, rd, cs,
+	_ASM_INSN_IF_MIPS(0x787e0019 | __cs << 11 | __rd << 6)
+	_ASM_INSN32_IF_MM(0x587e0016 | __cs << 11 | __rd << 6));
+_ASM_MACRO_2R(ctcmsa, cd, rs,
+	_ASM_INSN_IF_MIPS(0x783e0019 | __rs << 11 | __cd << 6)
+	_ASM_INSN32_IF_MM(0x583e0016 | __rs << 11 | __cd << 6));
+#define _ASM_SET_MSA ""
+#else /* TOOLCHAIN_SUPPORTS_MSA */
+#define _ASM_SET_MSA ".set\tfp=64\n\t"				\
+		     ".set\tmsa\n\t"
+#endif
 
 #define __BUILD_MSA_CTL_REG(name, cs)				\
 static inline unsigned int read_msa_##name(void)		\
@@ -168,8 +184,7 @@ static inline unsigned int read_msa_##name(void)		\
 	unsigned int reg;					\
 	__asm__ __volatile__(					\
 	"	.set	push\n"					\
-	"	.set	fp=64\n"				\
-	"	.set	msa\n"					\
+	_ASM_SET_MSA						\
 	"	cfcmsa	%0, $" #cs "\n"				\
 	"	.set	pop\n"					\
 	: "=r"(reg));						\
@@ -180,52 +195,12 @@ static inline void write_msa_##name(unsigned int val)		\
 {								\
 	__asm__ __volatile__(					\
 	"	.set	push\n"					\
-	"	.set	fp=64\n"				\
-	"	.set	msa\n"					\
+	_ASM_SET_MSA						\
 	"	ctcmsa	$" #cs ", %0\n"				\
 	"	.set	pop\n"					\
 	: : "r"(val));						\
 }
 
-#else /* !TOOLCHAIN_SUPPORTS_MSA */
-
-/*
- * Define functions using .word for the c[ft]cmsa instructions in order to
- * allow compilation with toolchains that do not support MSA. Once all
- * toolchains in use support MSA these can be removed.
- */
-
-#define __BUILD_MSA_CTL_REG(name, cs)				\
-static inline unsigned int read_msa_##name(void)		\
-{								\
-	unsigned int reg;					\
-	__asm__ __volatile__(					\
-	"	.set	push\n"					\
-	"	.set	noat\n"					\
-	"	# cfcmsa $1, $%1\n"				\
-	_ASM_INSN_IF_MIPS(0x787e0059 | %1 << 11)		\
-	_ASM_INSN32_IF_MM(0x587e0056 | %1 << 11)		\
-	"	move	%0, $1\n"				\
-	"	.set	pop\n"					\
-	: "=r"(reg) : "i"(cs));					\
-	return reg;						\
-}								\
-								\
-static inline void write_msa_##name(unsigned int val)		\
-{								\
-	__asm__ __volatile__(					\
-	"	.set	push\n"					\
-	"	.set	noat\n"					\
-	"	move	$1, %0\n"				\
-	"	# ctcmsa $%1, $1\n"				\
-	_ASM_INSN_IF_MIPS(0x783e0819 | %1 << 6)			\
-	_ASM_INSN32_IF_MM(0x583e0816 | %1 << 6)			\
-	"	.set	pop\n"					\
-	: : "r"(val), "i"(cs));					\
-}
-
-#endif /* !TOOLCHAIN_SUPPORTS_MSA */
-
 __BUILD_MSA_CTL_REG(ir, 0)
 __BUILD_MSA_CTL_REG(csr, 1)
 __BUILD_MSA_CTL_REG(access, 2)
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index e4374a5..448fd41 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -32,22 +32,22 @@ static struct resource jazz_io_resources[] = {
 		.start	= 0x00,
 		.end	= 0x1f,
 		.name	= "dma1",
-		.flags	= IORESOURCE_BUSY
+		.flags	= IORESOURCE_IO | IORESOURCE_BUSY
 	}, {
 		.start	= 0x40,
 		.end	= 0x5f,
 		.name	= "timer",
-		.flags	= IORESOURCE_BUSY
+		.flags	= IORESOURCE_IO | IORESOURCE_BUSY
 	}, {
 		.start	= 0x80,
 		.end	= 0x8f,
 		.name	= "dma page reg",
-		.flags	= IORESOURCE_BUSY
+		.flags	= IORESOURCE_IO | IORESOURCE_BUSY
 	}, {
 		.start	= 0xc0,
 		.end	= 0xdf,
 		.name	= "dma2",
-		.flags	= IORESOURCE_BUSY
+		.flags	= IORESOURCE_IO | IORESOURCE_BUSY
 	}
 };
 
diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
index 643af20..4dd0c44 100644
--- a/arch/mips/jz4740/Kconfig
+++ b/arch/mips/jz4740/Kconfig
@@ -8,6 +8,10 @@
 	bool "Qi Hardware Ben NanoNote"
 	select MACH_JZ4740
 
+config JZ4770_GCW0
+	bool "Game Consoles Worldwide GCW Zero"
+	select MACH_JZ4770
+
 config JZ4780_CI20
 	bool "MIPS Creator CI20"
 	select MACH_JZ4780
@@ -18,6 +22,12 @@
 	bool
 	select SYS_HAS_CPU_MIPS32_R1
 
+config MACH_JZ4770
+	bool
+	select MIPS_CPU_SCACHE
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_HIGHMEM
+
 config MACH_JZ4780
 	bool
 	select MIPS_CPU_SCACHE
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c
index 47e8571..eb9f2f9 100644
--- a/arch/mips/jz4740/prom.c
+++ b/arch/mips/jz4740/prom.c
@@ -20,33 +20,12 @@
 #include <linux/serial_reg.h>
 
 #include <asm/bootinfo.h>
+#include <asm/fw/fw.h>
 #include <asm/mach-jz4740/base.h>
 
-static __init void jz4740_init_cmdline(int argc, char *argv[])
-{
-	unsigned int count = COMMAND_LINE_SIZE - 1;
-	int i;
-	char *dst = &(arcs_cmdline[0]);
-	char *src;
-
-	for (i = 1; i < argc && count; ++i) {
-		src = argv[i];
-		while (*src && count) {
-			*dst++ = *src++;
-			--count;
-		}
-		*dst++ = ' ';
-	}
-	if (i > 1)
-		--dst;
-
-	*dst = 0;
-}
-
 void __init prom_init(void)
 {
-	jz4740_init_cmdline((int)fw_arg0, (char **)fw_arg1);
-	mips_machtype = MACH_INGENIC_JZ4740;
+	fw_init_cmdline();
 }
 
 void __init prom_free_prom_memory(void)
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index 6d01523..afb40f8 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -53,6 +53,16 @@ static void __init jz4740_detect_mem(void)
 	add_memory_region(0, size, BOOT_MEM_RAM);
 }
 
+static unsigned long __init get_board_mach_type(const void *fdt)
+{
+	if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4780"))
+		return MACH_INGENIC_JZ4780;
+	if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4770"))
+		return MACH_INGENIC_JZ4770;
+
+	return MACH_INGENIC_JZ4740;
+}
+
 void __init plat_mem_setup(void)
 {
 	int offset;
@@ -63,6 +73,8 @@ void __init plat_mem_setup(void)
 	offset = fdt_path_offset(__dtb_start, "/memory");
 	if (offset < 0)
 		jz4740_detect_mem();
+
+	mips_machtype = get_board_mach_type(__dtb_start);
 }
 
 void __init device_tree_init(void)
@@ -75,10 +87,14 @@ void __init device_tree_init(void)
 
 const char *get_system_type(void)
 {
-	if (IS_ENABLED(CONFIG_MACH_JZ4780))
+	switch (mips_machtype) {
+	case MACH_INGENIC_JZ4780:
 		return "JZ4780";
-
-	return "JZ4740";
+	case MACH_INGENIC_JZ4770:
+		return "JZ4770";
+	default:
+		return "JZ4740";
+	}
 }
 
 void __init arch_init_irq(void)
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index bb1ad51..2ca9160 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -113,7 +113,7 @@ static struct clock_event_device jz4740_clockevent = {
 #ifdef CONFIG_MACH_JZ4740
 	.irq = JZ4740_IRQ_TCU0,
 #endif
-#ifdef CONFIG_MACH_JZ4780
+#if defined(CONFIG_MACH_JZ4770) || defined(CONFIG_MACH_JZ4780)
 	.irq = JZ4780_IRQ_TCU2,
 #endif
 };
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index b79ed9a..e48f6c0a 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -399,7 +399,7 @@ int __MIPS16e_compute_return_epc(struct pt_regs *regs)
  *
  * @regs:	Pointer to pt_regs
  * @insn:	branch instruction to decode
- * @returns:	-EFAULT on error and forces SIGILL, and on success
+ * Return:	-EFAULT on error and forces SIGILL, and on success
  *		returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
  *		evaluating the branch.
  *
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index e68e6e0..1025f93 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -388,15 +388,16 @@
 
 #elif defined(CONFIG_MIPS_MT)
 
-	.set	push
-	.set	MIPS_ISA_LEVEL_RAW
-	.set	mt
-
 	/* If the core doesn't support MT then return */
 	has_mt	t0, 5f
 
 	/* Enter VPE configuration state */
+	.set	push
+	.set	MIPS_ISA_LEVEL_RAW
+	.set	mt
 	dvpe
+	.set	pop
+
 	PTR_LA	t1, 1f
 	jr.hb	t1
 	 nop
@@ -422,6 +423,10 @@
 	mtc0	t0, CP0_VPECONTROL
 	ehb
 
+	.set	push
+	.set	MIPS_ISA_LEVEL_RAW
+	.set	mt
+
 	/* Skip the VPE if its TC is not halted */
 	mftc0	t0, CP0_TCHALT
 	beqz	t0, 2f
@@ -495,6 +500,8 @@
 	ehb
 	evpe
 
+	.set	pop
+
 	/* Check whether this VPE is meant to be running */
 	li	t0, 1
 	sll	t0, t0, a1
@@ -509,7 +516,7 @@
 1:	jr.hb	t0
 	 nop
 
-2:	.set	pop
+2:
 
 #endif /* CONFIG_MIPS_MT_SMP */
 
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index 99285be..7f3dfdb 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -361,7 +361,7 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
 	 * If fails when getting the stack address of the non-leaf function's
 	 * ra, stop function graph tracer and return
 	 */
-	if (parent_ra_addr == 0)
+	if (parent_ra_addr == NULL)
 		goto out;
 #endif
 	/* *parent_ra_addr = return_hooker; */
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 702c678..85bc601 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -826,25 +826,6 @@ static void __init arch_mem_init(char **cmdline_p)
 	struct memblock_region *reg;
 	extern void plat_mem_setup(void);
 
-	/* call board setup routine */
-	plat_mem_setup();
-
-	/*
-	 * Make sure all kernel memory is in the maps.  The "UP" and
-	 * "DOWN" are opposite for initdata since if it crosses over
-	 * into another memory section you don't want that to be
-	 * freed when the initdata is freed.
-	 */
-	arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
-			 PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
-			 BOOT_MEM_RAM);
-	arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
-			 PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
-			 BOOT_MEM_INIT_RAM);
-
-	pr_info("Determined physical RAM map:\n");
-	print_memory_map();
-
 #if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
 	strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
 #else
@@ -872,6 +853,26 @@ static void __init arch_mem_init(char **cmdline_p)
 	}
 #endif
 #endif
+
+	/* call board setup routine */
+	plat_mem_setup();
+
+	/*
+	 * Make sure all kernel memory is in the maps.  The "UP" and
+	 * "DOWN" are opposite for initdata since if it crosses over
+	 * into another memory section you don't want that to be
+	 * freed when the initdata is freed.
+	 */
+	arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
+			 PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
+			 BOOT_MEM_RAM);
+	arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
+			 PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
+			 BOOT_MEM_INIT_RAM);
+
+	pr_info("Determined physical RAM map:\n");
+	print_memory_map();
+
 	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
 
 	*cmdline_p = command_line;
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index ecc1a85..03f1026a 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -439,8 +439,6 @@ void play_dead(void)
 	pr_debug("CPU%d going offline\n", cpu);
 
 	if (cpu_has_mipsmt || cpu_has_vp) {
-		core = cpu_core(&cpu_data[cpu]);
-
 		/* Look for another online VPE within the core */
 		for_each_online_cpu(cpu_death_sibling) {
 			if (!cpus_are_siblings(cpu, cpu_death_sibling))
diff --git a/arch/mips/kernel/watch.c b/arch/mips/kernel/watch.c
index 19fcab7..0e61a5b 100644
--- a/arch/mips/kernel/watch.c
+++ b/arch/mips/kernel/watch.c
@@ -18,27 +18,24 @@
 void mips_install_watch_registers(struct task_struct *t)
 {
 	struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264;
+	unsigned int watchhi = MIPS_WATCHHI_G |		/* Trap all ASIDs */
+			       MIPS_WATCHHI_IRW;	/* Clear result bits */
+
 	switch (current_cpu_data.watch_reg_use_cnt) {
 	default:
 		BUG();
 	case 4:
 		write_c0_watchlo3(watches->watchlo[3]);
-		/* Write 1 to the I, R, and W bits to clear them, and
-		   1 to G so all ASIDs are trapped. */
-		write_c0_watchhi3(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
-				  watches->watchhi[3]);
+		write_c0_watchhi3(watchhi | watches->watchhi[3]);
 	case 3:
 		write_c0_watchlo2(watches->watchlo[2]);
-		write_c0_watchhi2(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
-				  watches->watchhi[2]);
+		write_c0_watchhi2(watchhi | watches->watchhi[2]);
 	case 2:
 		write_c0_watchlo1(watches->watchlo[1]);
-		write_c0_watchhi1(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
-				  watches->watchhi[1]);
+		write_c0_watchhi1(watchhi | watches->watchhi[1]);
 	case 1:
 		write_c0_watchlo0(watches->watchlo[0]);
-		write_c0_watchhi0(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
-				  watches->watchhi[0]);
+		write_c0_watchhi0(watchhi | watches->watchhi[0]);
 	}
 }
 
@@ -51,21 +48,19 @@ void mips_read_watch_registers(void)
 {
 	struct mips3264_watch_reg_state *watches =
 		&current->thread.watch.mips3264;
+	unsigned int watchhi_mask = MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW;
+
 	switch (current_cpu_data.watch_reg_use_cnt) {
 	default:
 		BUG();
 	case 4:
-		watches->watchhi[3] = (read_c0_watchhi3() &
-				       (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
+		watches->watchhi[3] = (read_c0_watchhi3() & watchhi_mask);
 	case 3:
-		watches->watchhi[2] = (read_c0_watchhi2() &
-				       (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
+		watches->watchhi[2] = (read_c0_watchhi2() & watchhi_mask);
 	case 2:
-		watches->watchhi[1] = (read_c0_watchhi1() &
-				       (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
+		watches->watchhi[1] = (read_c0_watchhi1() & watchhi_mask);
 	case 1:
-		watches->watchhi[0] = (read_c0_watchhi0() &
-				       (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
+		watches->watchhi[0] = (read_c0_watchhi0() & watchhi_mask);
 	}
 	if (current_cpu_data.watch_reg_use_cnt == 1 &&
 	    (watches->watchhi[0] & MIPS_WATCHHI_IRW) == 0) {
diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig
index 6f109bb..bc2fdbf 100644
--- a/arch/mips/loongson64/Kconfig
+++ b/arch/mips/loongson64/Kconfig
@@ -17,7 +17,6 @@
 	select I8259
 	select ISA
 	select IRQ_MIPS_CPU
-	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 	select SYS_SUPPORTS_HIGHMEM
@@ -49,7 +48,6 @@
 	select ISA
 	select SYS_HAS_CPU_LOONGSON2F
 	select SYS_HAS_EARLY_PRINTK
-	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_HIGHMEM
 	select SYS_SUPPORTS_LITTLE_ENDIAN
diff --git a/arch/mips/loongson64/common/mem.c b/arch/mips/loongson64/common/mem.c
index b01d524..c549e52 100644
--- a/arch/mips/loongson64/common/mem.c
+++ b/arch/mips/loongson64/common/mem.c
@@ -79,7 +79,7 @@ void __init prom_init_memory(void)
 					(u64)loongson_memmap->map[i].mem_size << 20,
 					BOOT_MEM_RAM);
 				break;
-			case MEM_RESERVED:
+			case SYSTEM_RAM_RESERVED:
 				add_memory_region(loongson_memmap->map[i].mem_start,
 					(u64)loongson_memmap->map[i].mem_size << 20,
 					BOOT_MEM_RESERVED);
diff --git a/arch/mips/loongson64/loongson-3/numa.c b/arch/mips/loongson64/loongson-3/numa.c
index f17ef52..9717106 100644
--- a/arch/mips/loongson64/loongson-3/numa.c
+++ b/arch/mips/loongson64/loongson-3/numa.c
@@ -166,7 +166,7 @@ static void __init szmem(unsigned int node)
 			memblock_add_node(PFN_PHYS(start_pfn),
 				PFN_PHYS(end_pfn - start_pfn), node);
 			break;
-		case MEM_RESERVED:
+		case SYSTEM_RAM_RESERVED:
 			pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n",
 				(u32)node_id, mem_type, mem_start, mem_size);
 			add_memory_region((node_id << 44) + mem_start,
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index da6c1c0..62deb02 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -451,7 +451,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 					regs->cp0_epc + dec_insn.pc_inc +
 					dec_insn.next_pc_inc;
 			}
-			/* Fall through */
+			/* fall through */
 		case jr_op:
 			/* For R6, JR already emulated in jalr_op */
 			if (NO_R6EMU && insn.r_format.func == jr_op)
@@ -471,10 +471,11 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 			regs->regs[31] = regs->cp0_epc +
 				dec_insn.pc_inc +
 				dec_insn.next_pc_inc;
-			/* Fall through */
+			/* fall through */
 		case bltzl_op:
 			if (NO_R6EMU)
 				break;
+			/* fall through */
 		case bltz_op:
 			if ((long)regs->regs[insn.i_format.rs] < 0)
 				*contpc = regs->cp0_epc +
@@ -494,10 +495,11 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 			regs->regs[31] = regs->cp0_epc +
 				dec_insn.pc_inc +
 				dec_insn.next_pc_inc;
-			/* Fall through */
+			/* fall through */
 		case bgezl_op:
 			if (NO_R6EMU)
 				break;
+			/* fall through */
 		case bgez_op:
 			if ((long)regs->regs[insn.i_format.rs] >= 0)
 				*contpc = regs->cp0_epc +
@@ -512,11 +514,12 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 		break;
 	case jalx_op:
 		set_isa16_mode(bit);
+		/* fall through */
 	case jal_op:
 		regs->regs[31] = regs->cp0_epc +
 			dec_insn.pc_inc +
 			dec_insn.next_pc_inc;
-		/* Fall through */
+		/* fall through */
 	case j_op:
 		*contpc = regs->cp0_epc + dec_insn.pc_inc;
 		*contpc >>= 28;
@@ -528,6 +531,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 	case beql_op:
 		if (NO_R6EMU)
 			break;
+		/* fall through */
 	case beq_op:
 		if (regs->regs[insn.i_format.rs] ==
 		    regs->regs[insn.i_format.rt])
@@ -542,6 +546,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 	case bnel_op:
 		if (NO_R6EMU)
 			break;
+		/* fall through */
 	case bne_op:
 		if (regs->regs[insn.i_format.rs] !=
 		    regs->regs[insn.i_format.rt])
@@ -556,6 +561,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 	case blezl_op:
 		if (!insn.i_format.rt && NO_R6EMU)
 			break;
+		/* fall through */
 	case blez_op:
 
 		/*
@@ -593,6 +599,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 	case bgtzl_op:
 		if (!insn.i_format.rt && NO_R6EMU)
 			break;
+		/* fall through */
 	case bgtz_op:
 		/*
 		 * Compact branches for R6 for the
@@ -729,7 +736,8 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
 
 			return 1;
 		}
-		/* R2/R6 compatible cop1 instruction. Fall through */
+		/* R2/R6 compatible cop1 instruction */
+		/* fall through */
 	case cop2_op:
 	case cop1x_op:
 		if (insn.i_format.rs == bc_op) {
@@ -1190,7 +1198,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 			if (!cpu_has_mips_r6 || delay_slot(xcp))
 				return SIGILL;
 
-			cond = likely = 0;
+			likely = 0;
+			cond = 0;
 			fpr = &current->thread.fpu.fpr[MIPSInst_RT(ir)];
 			bit0 = get_fpr32(fpr, 0) & 0x1;
 			switch (MIPSInst_RS(ir)) {
@@ -1220,14 +1229,14 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 			case bcfl_op:
 				if (cpu_has_mips_2_3_4_5_r)
 					likely = 1;
-				/* Fall through */
+				/* fall through */
 			case bcf_op:
 				cond = !cond;
 				break;
 			case bctl_op:
 				if (cpu_has_mips_2_3_4_5_r)
 					likely = 1;
-				/* Fall through */
+				/* fall through */
 			case bct_op:
 				break;
 			}
@@ -1353,7 +1362,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 				return SIGILL;
 
 			/* a real fpu computation instruction */
-			if ((sig = fpu_emu(xcp, ctx, ir)))
+			sig = fpu_emu(xcp, ctx, ir);
+			if (sig)
 				return sig;
 		}
 		break;
diff --git a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c
index 8954ef0..678de20 100644
--- a/arch/mips/math-emu/dp_add.c
+++ b/arch/mips/math-emu/dp_add.c
@@ -104,8 +104,7 @@ union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
-
-		/* FALL THROUGH */
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		DPDNORMY;
diff --git a/arch/mips/math-emu/dp_div.c b/arch/mips/math-emu/dp_div.c
index f4746f7..3063ae3 100644
--- a/arch/mips/math-emu/dp_div.c
+++ b/arch/mips/math-emu/dp_div.c
@@ -103,6 +103,7 @@ union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		DPDNORMY;
diff --git a/arch/mips/math-emu/dp_fmax.c b/arch/mips/math-emu/dp_fmax.c
index 5bec64f..d1f984b 100644
--- a/arch/mips/math-emu/dp_fmax.c
+++ b/arch/mips/math-emu/dp_fmax.c
@@ -96,6 +96,7 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		DPDNORMY;
@@ -224,6 +225,7 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		DPDNORMY;
diff --git a/arch/mips/math-emu/dp_fmin.c b/arch/mips/math-emu/dp_fmin.c
index a287b23..f98b9613 100644
--- a/arch/mips/math-emu/dp_fmin.c
+++ b/arch/mips/math-emu/dp_fmin.c
@@ -96,6 +96,7 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		DPDNORMY;
@@ -224,6 +225,7 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		DPDNORMY;
diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c
index 7ad79ed..7ea2f82 100644
--- a/arch/mips/math-emu/dp_maddf.c
+++ b/arch/mips/math-emu/dp_maddf.c
@@ -16,7 +16,7 @@
 
 
 /* 128 bits shift right logical with rounding. */
-void srl128(u64 *hptr, u64 *lptr, int count)
+static void srl128(u64 *hptr, u64 *lptr, int count)
 {
 	u64 low;
 
@@ -157,6 +157,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		if (zc == IEEE754_CLASS_INF)
@@ -173,7 +174,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
 		if (zc == IEEE754_CLASS_INF)
 			return ieee754dp_inf(zs);
-		/* fall through to real computations */
+		/* continue to real computations */
 	}
 
 	/* Finally get to do some computation */
@@ -201,9 +202,6 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
 	 * Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm.
 	 */
 
-	/* 32 * 32 => 64 */
-#define DPXMULT(x, y)	((u64)(x) * (u64)y)
-
 	lxm = xm;
 	hxm = xm >> 32;
 	lym = ym;
diff --git a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c
index 60c8bfe..c34a6cd 100644
--- a/arch/mips/math-emu/dp_mul.c
+++ b/arch/mips/math-emu/dp_mul.c
@@ -101,6 +101,7 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		DPDNORMY;
@@ -128,9 +129,6 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y)
 	 * Multiply 64 bits xm, ym to give high 64 bits rm with stickness.
 	 */
 
-	/* 32 * 32 => 64 */
-#define DPXMULT(x, y)	((u64)(x) * (u64)y)
-
 	lxm = xm;
 	hxm = xm >> 32;
 	lym = ym;
diff --git a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c
index cea907b..1d26c92 100644
--- a/arch/mips/math-emu/dp_sqrt.c
+++ b/arch/mips/math-emu/dp_sqrt.c
@@ -91,7 +91,8 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x)
 		scalx -= 256;
 	}
 
-	y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+	x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+	y = x;
 
 	/* magic initial approximation to almost 8 sig. bits */
 	yh = y.bits >> 32;
@@ -108,7 +109,8 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x)
 
 	/* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */
 	/* t=y*y; z=t;	pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */
-	z = t = ieee754dp_mul(y, y);
+	t = ieee754dp_mul(y, y);
+	z = t;
 	t.bexp += 0x001;
 	t = ieee754dp_add(t, z);
 	z = ieee754dp_mul(ieee754dp_sub(x, z), y);
@@ -140,7 +142,7 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x)
 		switch (oldcsr.rm) {
 		case FPU_CSR_RU:
 			y.bits += 1;
-			/* drop through */
+			/* fall through */
 		case FPU_CSR_RN:
 			t.bits += 1;
 			break;
diff --git a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c
index fc17a78..3cc48b8 100644
--- a/arch/mips/math-emu/dp_sub.c
+++ b/arch/mips/math-emu/dp_sub.c
@@ -106,7 +106,7 @@ union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		DPDNORMX;
-		/* FALL THROUGH */
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		/* normalize ym,ye */
diff --git a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h
index 9ba0230..a56707b 100644
--- a/arch/mips/math-emu/ieee754dp.h
+++ b/arch/mips/math-emu/ieee754dp.h
@@ -55,6 +55,9 @@ static inline int ieee754dp_finite(union ieee754dp x)
 #define XDPSRS1(v)	\
 	(((v) >> 1) | ((v) & 1))
 
+/* 32bit * 32bit => 64bit unsigned integer multiplication */
+#define DPXMULT(x, y)	((u64)(x) * (u64)y)
+
 /* convert denormal to normalized with extended exponent */
 #define DPDNORMx(m,e) \
 	while ((m >> DP_FBITS) == 0) { m <<= 1; e--; }
diff --git a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c
index c55c0c0..51dced9 100644
--- a/arch/mips/math-emu/sp_add.c
+++ b/arch/mips/math-emu/sp_add.c
@@ -104,8 +104,7 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
-
-		/* FALL THROUGH */
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		SPDNORMY;
diff --git a/arch/mips/math-emu/sp_div.c b/arch/mips/math-emu/sp_div.c
index 23587b3..5d29049 100644
--- a/arch/mips/math-emu/sp_div.c
+++ b/arch/mips/math-emu/sp_div.c
@@ -103,6 +103,7 @@ union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		SPDNORMY;
diff --git a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c
index 5060e8f..36a50f9 100644
--- a/arch/mips/math-emu/sp_fdp.c
+++ b/arch/mips/math-emu/sp_fdp.c
@@ -46,7 +46,8 @@ union ieee754sp ieee754sp_fdp(union ieee754dp x)
 	case IEEE754_CLASS_SNAN:
 		x = ieee754dp_nanxcpt(x);
 		EXPLODEXDP;
-		/* Fall through.  */
+		/* fall through */
+
 	case IEEE754_CLASS_QNAN:
 		y = ieee754sp_nan_fdp(xs, xm);
 		if (!ieee754_csr.nan2008) {
diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c
index 74a5a00..22019ed 100644
--- a/arch/mips/math-emu/sp_fmax.c
+++ b/arch/mips/math-emu/sp_fmax.c
@@ -96,6 +96,7 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		SPDNORMY;
@@ -224,6 +225,7 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		SPDNORMY;
diff --git a/arch/mips/math-emu/sp_fmin.c b/arch/mips/math-emu/sp_fmin.c
index c51385f..feaec39 100644
--- a/arch/mips/math-emu/sp_fmin.c
+++ b/arch/mips/math-emu/sp_fmin.c
@@ -96,6 +96,7 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		SPDNORMY;
@@ -224,6 +225,7 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		SPDNORMY;
diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c
index f823338..07ba675 100644
--- a/arch/mips/math-emu/sp_maddf.c
+++ b/arch/mips/math-emu/sp_maddf.c
@@ -126,6 +126,7 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		if (zc == IEEE754_CLASS_INF)
@@ -142,7 +143,7 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
 		if (zc == IEEE754_CLASS_INF)
 			return ieee754sp_inf(zs);
-		/* fall through to real computations */
+		/* continue to real computations */
 	}
 
 	/* Finally get to do some computation */
diff --git a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c
index 4015101..fde71e2 100644
--- a/arch/mips/math-emu/sp_mul.c
+++ b/arch/mips/math-emu/sp_mul.c
@@ -101,6 +101,7 @@ union ieee754sp ieee754sp_mul(union ieee754sp x, union ieee754sp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		SPDNORMY;
diff --git a/arch/mips/math-emu/sp_sqrt.c b/arch/mips/math-emu/sp_sqrt.c
index 67059c3..9cc83f0 100644
--- a/arch/mips/math-emu/sp_sqrt.c
+++ b/arch/mips/math-emu/sp_sqrt.c
@@ -82,7 +82,8 @@ union ieee754sp ieee754sp_sqrt(union ieee754sp x)
 
 	/* generate sqrt(x) bit by bit */
 	ix += ix;
-	q = s = 0;		/* q = sqrt(x) */
+	s = 0;
+	q = 0;			/* q = sqrt(x) */
 	r = 0x01000000;		/* r = moving bit from right to left */
 
 	while (r != 0) {
diff --git a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c
index dc998ed..9f2ff72 100644
--- a/arch/mips/math-emu/sp_sub.c
+++ b/arch/mips/math-emu/sp_sub.c
@@ -106,6 +106,7 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
 
 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
 		SPDNORMX;
+		/* fall through */
 
 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 		SPDNORMY;
diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c
index a2450c7..bca5ac9 100644
--- a/arch/mips/math-emu/sp_tlong.c
+++ b/arch/mips/math-emu/sp_tlong.c
@@ -20,7 +20,6 @@
  */
 
 #include "ieee754sp.h"
-#include "ieee754dp.h"
 
 s64 ieee754sp_tlong(union ieee754sp x)
 {
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 237532e..dcafa43 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -370,11 +370,6 @@ static void mips_dma_sync_sg_for_device(struct device *dev,
 	}
 }
 
-static int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-	return 0;
-}
-
 static int mips_dma_supported(struct device *dev, u64 mask)
 {
 	return plat_dma_supported(dev, mask);
@@ -401,7 +396,6 @@ static const struct dma_map_ops mips_default_dma_map_ops = {
 	.sync_single_for_device = mips_dma_sync_single_for_device,
 	.sync_sg_for_cpu = mips_dma_sync_sg_for_cpu,
 	.sync_sg_for_device = mips_dma_sync_sg_for_device,
-	.mapping_error = mips_dma_mapping_error,
 	.dma_supported = mips_dma_supported,
 	.cache_sync = mips_dma_cache_sync,
 };
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 548acb7..3946739 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -16,6 +16,7 @@
 #include <asm/mmu_context.h>
 #include <asm/r4kcache.h>
 #include <asm/mips-cps.h>
+#include <asm/bootinfo.h>
 
 /*
  * MIPS32/MIPS64 L2 cache handling
@@ -220,6 +221,14 @@ static inline int __init mips_sc_probe(void)
 	else
 		return 0;
 
+	/*
+	 * According to config2 it would be 5-ways, but that is contradicted
+	 * by all documentation.
+	 */
+	if (current_cpu_type() == CPU_JZRISC &&
+				mips_machtype == MACH_INGENIC_JZ4770)
+		c->scache.ways = 4;
+
 	c->scache.waysize = c->scache.sets * c->scache.linesz;
 	c->scache.waybit = __ffs(c->scache.waysize);
 
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
index de34adb..7b63914 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -47,31 +47,31 @@ static struct resource standard_io_resources[] = {
 		.name = "dma1",
 		.start = 0x00,
 		.end = 0x1f,
-		.flags = IORESOURCE_BUSY
+		.flags = IORESOURCE_IO | IORESOURCE_BUSY
 	},
 	{
 		.name = "timer",
 		.start = 0x40,
 		.end = 0x5f,
-		.flags = IORESOURCE_BUSY
+		.flags = IORESOURCE_IO | IORESOURCE_BUSY
 	},
 	{
 		.name = "keyboard",
 		.start = 0x60,
 		.end = 0x6f,
-		.flags = IORESOURCE_BUSY
+		.flags = IORESOURCE_IO | IORESOURCE_BUSY
 	},
 	{
 		.name = "dma page reg",
 		.start = 0x80,
 		.end = 0x8f,
-		.flags = IORESOURCE_BUSY
+		.flags = IORESOURCE_IO | IORESOURCE_BUSY
 	},
 	{
 		.name = "dma2",
 		.start = 0xc0,
 		.end = 0xdf,
-		.flags = IORESOURCE_BUSY
+		.flags = IORESOURCE_IO | IORESOURCE_BUSY
 	},
 };
 
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index 8b93730..fd26fad 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -186,7 +186,7 @@ static void __init rbtx4939_update_ioc_pen(void)
 
 #define RBTX4939_MAX_7SEGLEDS	8
 
-#if IS_ENABLED(CONFIG_LEDS_CLASS)
+#if IS_BUILTIN(CONFIG_LEDS_CLASS)
 static u8 led_val[RBTX4939_MAX_7SEGLEDS];
 struct rbtx4939_led_data {
 	struct led_classdev cdev;
@@ -261,7 +261,7 @@ static inline void rbtx4939_led_setup(void)
 
 static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
 {
-#if IS_ENABLED(CONFIG_LEDS_CLASS)
+#if IS_BUILTIN(CONFIG_LEDS_CLASS)
 	unsigned long flags;
 	local_irq_save(flags);
 	/* bit7: reserved for LED class */
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9d33298..73ce5dd 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -141,6 +141,7 @@
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_PHYS_TO_DMA
 	select ARCH_HAS_PMEM_API                if PPC64
+	select ARCH_HAS_MEMBARRIER_CALLBACKS
 	select ARCH_HAS_SCALED_CPUTIME		if VIRT_CPU_ACCOUNTING_NATIVE
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAS_STRICT_KERNEL_RWX	if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION)
diff --git a/arch/powerpc/include/asm/membarrier.h b/arch/powerpc/include/asm/membarrier.h
new file mode 100644
index 0000000..6e20bb5
--- /dev/null
+++ b/arch/powerpc/include/asm/membarrier.h
@@ -0,0 +1,27 @@
+#ifndef _ASM_POWERPC_MEMBARRIER_H
+#define _ASM_POWERPC_MEMBARRIER_H
+
+static inline void membarrier_arch_switch_mm(struct mm_struct *prev,
+					     struct mm_struct *next,
+					     struct task_struct *tsk)
+{
+	/*
+	 * Only need the full barrier when switching between processes.
+	 * Barrier when switching from kernel to userspace is not
+	 * required here, given that it is implied by mmdrop(). Barrier
+	 * when switching from userspace to kernel is not needed after
+	 * store to rq->curr.
+	 */
+	if (likely(!(atomic_read(&next->membarrier_state) &
+		     (MEMBARRIER_STATE_PRIVATE_EXPEDITED |
+		      MEMBARRIER_STATE_GLOBAL_EXPEDITED)) || !prev))
+		return;
+
+	/*
+	 * The membarrier system call requires a full memory barrier
+	 * after storing to rq->curr, before going back to user-space.
+	 */
+	smp_mb();
+}
+
+#endif /* _ASM_POWERPC_MEMBARRIER_H */
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index cc649809..2b9df00 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -756,14 +756,14 @@ int eeh_restore_vf_config(struct pci_dn *pdn)
 		eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
 				      2, devctl);
 
-		/* Disable Completion Timeout */
+		/* Disable Completion Timeout if possible */
 		eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2,
 				     4, &cap2);
-		if (cap2 & 0x10) {
+		if (cap2 & PCI_EXP_DEVCAP2_COMP_TMOUT_DIS) {
 			eeh_ops->read_config(pdn,
 					     edev->pcie_cap + PCI_EXP_DEVCTL2,
 					     4, &cap2);
-			cap2 |= 0x10;
+			cap2 |= PCI_EXP_DEVCTL2_COMP_TMOUT_DIS;
 			eeh_ops->write_config(pdn,
 					      edev->pcie_cap + PCI_EXP_DEVCTL2,
 					      4, cap2);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 208e623..ae2ede4 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -362,8 +362,7 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
  */
 static int pci_read_irq_line(struct pci_dev *pci_dev)
 {
-	struct of_phandle_args oirq;
-	unsigned int virq;
+	unsigned int virq = 0;
 
 	pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
 
@@ -371,7 +370,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
 	memset(&oirq, 0xff, sizeof(oirq));
 #endif
 	/* Try to get a mapping from the device-tree */
-	if (of_irq_parse_pci(pci_dev, &oirq)) {
+	if (!of_irq_parse_and_map_pci(pci_dev, 0, 0)) {
 		u8 line, pin;
 
 		/* If that fails, lets fallback to what is in the config
@@ -395,11 +394,6 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
 		virq = irq_create_mapping(NULL, line);
 		if (virq)
 			irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
-	} else {
-		pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %pOF\n",
-			 oirq.args_count, oirq.args[0], oirq.args[1], oirq.np);
-
-		virq = irq_create_of_mapping(&oirq);
 	}
 
 	if (!virq) {
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index 2d71269..cf47b1a 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -104,7 +104,7 @@ EXPORT_SYMBOL_GPL(pci_hp_remove_devices);
  */
 void pci_hp_add_devices(struct pci_bus *bus)
 {
-	int slotno, mode, pass, max;
+	int slotno, mode, max;
 	struct pci_dev *dev;
 	struct pci_controller *phb;
 	struct device_node *dn = pci_bus_to_OF_node(bus);
@@ -133,13 +133,17 @@ void pci_hp_add_devices(struct pci_bus *bus)
 		pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
 		pcibios_setup_bus_devices(bus);
 		max = bus->busn_res.start;
-		for (pass = 0; pass < 2; pass++) {
-			list_for_each_entry(dev, &bus->devices, bus_list) {
-				if (pci_is_bridge(dev))
-					max = pci_scan_bridge(bus, dev,
-							      max, pass);
-			}
-		}
+		/*
+		 * Scan bridges that are already configured. We don't touch
+		 * them unless they are misconfigured (which will be done in
+		 * the second scan below).
+		 */
+		for_each_pci_bridge(dev, bus)
+			max = pci_scan_bridge(bus, dev, max, 0);
+
+		/* Scan bridges that need to be reconfigured */
+		for_each_pci_bridge(dev, bus)
+			max = pci_scan_bridge(bus, dev, max, 1);
 	}
 	pcibios_finish_adding_to_bus(bus);
 }
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 1d817f4..85ad2f7 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -96,7 +96,8 @@ make_one_node_map(struct device_node* node, u8 pci_bus)
 		reg = of_get_property(node, "reg", NULL);
 		if (!reg)
 			continue;
-		dev = pci_get_bus_and_slot(pci_bus, ((reg[0] >> 8) & 0xff));
+		dev = pci_get_domain_bus_and_slot(0, pci_bus,
+						  ((reg[0] >> 8) & 0xff));
 		if (!dev || !dev->subordinate) {
 			pci_dev_put(dev);
 			continue;
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 20ceec4..98f0472 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -369,11 +369,8 @@ static void __of_scan_bus(struct device_node *node, struct pci_bus *bus,
 	pcibios_setup_bus_devices(bus);
 
 	/* Now scan child busses */
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		if (pci_is_bridge(dev)) {
-			of_scan_pci_bridge(dev);
-		}
-	}
+	for_each_pci_bridge(dev, bus)
+		of_scan_pci_bridge(dev);
 }
 
 /**
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index f6eb7e8..fdb424a 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -183,7 +183,8 @@ static __meminit void vmemmap_list_populate(unsigned long phys,
 	vmemmap_list = vmem_back;
 }
 
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+		struct vmem_altmap *altmap)
 {
 	unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
 
@@ -193,17 +194,16 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
 	pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node);
 
 	for (; start < end; start += page_size) {
-		struct vmem_altmap *altmap;
 		void *p;
 		int rc;
 
 		if (vmemmap_populated(start, page_size))
 			continue;
 
-		/* altmap lookups only work at section boundaries */
-		altmap = to_vmem_altmap(SECTION_ALIGN_DOWN(start));
-
-		p =  __vmemmap_alloc_block_buf(page_size, node, altmap);
+		if (altmap)
+			p = altmap_alloc_block_buf(page_size, altmap);
+		else
+			p = vmemmap_alloc_block_buf(page_size, node);
 		if (!p)
 			return -ENOMEM;
 
@@ -256,7 +256,8 @@ static unsigned long vmemmap_list_free(unsigned long start)
 	return vmem_back->phys;
 }
 
-void __ref vmemmap_free(unsigned long start, unsigned long end)
+void __ref vmemmap_free(unsigned long start, unsigned long end,
+		struct vmem_altmap *altmap)
 {
 	unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
 	unsigned long page_order = get_order(page_size);
@@ -267,7 +268,6 @@ void __ref vmemmap_free(unsigned long start, unsigned long end)
 
 	for (; start < end; start += page_size) {
 		unsigned long nr_pages, addr;
-		struct vmem_altmap *altmap;
 		struct page *section_base;
 		struct page *page;
 
@@ -287,7 +287,6 @@ void __ref vmemmap_free(unsigned long start, unsigned long end)
 		section_base = pfn_to_page(vmemmap_section_start(start));
 		nr_pages = 1 << page_order;
 
-		altmap = to_vmem_altmap((unsigned long) section_base);
 		if (altmap) {
 			vmem_altmap_free(altmap, nr_pages);
 		} else if (PageReserved(page)) {
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 1281c6e..fe8c611 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -127,7 +127,8 @@ int __weak remove_section_mapping(unsigned long start, unsigned long end)
 	return -ENODEV;
 }
 
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+		bool want_memblock)
 {
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
@@ -143,15 +144,14 @@ int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
 		return -EFAULT;
 	}
 
-	return __add_pages(nid, start_pfn, nr_pages, want_memblock);
+	return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
 }
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
+int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
 {
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
-	struct vmem_altmap *altmap;
 	struct page *page;
 	int ret;
 
@@ -160,11 +160,10 @@ int arch_remove_memory(u64 start, u64 size)
 	 * when querying the zone.
 	 */
 	page = pfn_to_page(start_pfn);
-	altmap = to_vmem_altmap((unsigned long) page);
 	if (altmap)
 		page += vmem_altmap_offset(altmap);
 
-	ret = __remove_pages(page_zone(page), start_pfn, nr_pages);
+	ret = __remove_pages(page_zone(page), start_pfn, nr_pages, altmap);
 	if (ret)
 		return ret;
 
diff --git a/arch/powerpc/mm/mmu_context.c b/arch/powerpc/mm/mmu_context.c
index d60a62b..0ab297c 100644
--- a/arch/powerpc/mm/mmu_context.c
+++ b/arch/powerpc/mm/mmu_context.c
@@ -12,6 +12,7 @@
 
 #include <linux/mm.h>
 #include <linux/cpu.h>
+#include <linux/sched/mm.h>
 
 #include <asm/mmu_context.h>
 
@@ -58,6 +59,10 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 		 *
 		 * On the read side the barrier is in pte_xchg(), which orders
 		 * the store to the PTE vs the load of mm_cpumask.
+		 *
+		 * This full barrier is needed by membarrier when switching
+		 * between processes after store to rq->curr, before user-space
+		 * memory accesses.
 		 */
 		smp_mb();
 
@@ -80,6 +85,8 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 
 	if (new_on_cpu)
 		radix_kvm_prefetch_workaround(next);
+	else
+		membarrier_arch_switch_mm(prev, next, tsk);
 
 	/*
 	 * The actual HW switching method differs between the various
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c
index 81799d7..cfddc87 100644
--- a/arch/powerpc/platforms/maple/time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -134,7 +134,7 @@ int maple_set_rtc_time(struct rtc_time *tm)
 
 static struct resource rtc_iores = {
 	.name = "rtc",
-	.flags = IORESOURCE_BUSY,
+	.flags = IORESOURCE_IO | IORESOURCE_BUSY,
 };
 
 unsigned long __init maple_get_boot_time(void)
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 466b842..3f82cb2 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -829,7 +829,7 @@ core99_ata100_enable(struct device_node *node, long value)
 
 	if (value) {
 		if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
-			pdev = pci_get_bus_and_slot(pbus, pid);
+			pdev = pci_get_domain_bus_and_slot(0, pbus, pid);
 		if (pdev == NULL)
 			return 0;
 		rc = pci_enable_device(pdev);
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index bafb014..cb9a8b7 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -145,21 +145,21 @@ static struct resource pic1_iores = {
 	.name = "8259 (master)",
 	.start = 0x20,
 	.end = 0x21,
-	.flags = IORESOURCE_BUSY,
+	.flags = IORESOURCE_IO | IORESOURCE_BUSY,
 };
 
 static struct resource pic2_iores = {
 	.name = "8259 (slave)",
 	.start = 0xa0,
 	.end = 0xa1,
-	.flags = IORESOURCE_BUSY,
+	.flags = IORESOURCE_IO | IORESOURCE_BUSY,
 };
 
 static struct resource pic_edgectrl_iores = {
 	.name = "8259 edge control",
 	.start = 0x4d0,
 	.end = 0x4d1,
-	.flags = IORESOURCE_BUSY,
+	.flags = IORESOURCE_IO | IORESOURCE_BUSY,
 };
 
 static int i8259_host_match(struct irq_domain *h, struct device_node *node,
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c
index 50c411b..1afcdb4 100644
--- a/arch/powerpc/sysdev/mv64x60_pci.c
+++ b/arch/powerpc/sysdev/mv64x60_pci.c
@@ -37,7 +37,7 @@ static ssize_t mv64x60_hs_reg_read(struct file *filp, struct kobject *kobj,
 	if (count < MV64X60_VAL_LEN_MAX)
 		return -EINVAL;
 
-	phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+	phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
 	if (!phb)
 		return -ENODEV;
 	pci_read_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, &v);
@@ -61,7 +61,7 @@ static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj,
 	if (sscanf(buf, "%i", &v) != 1)
 		return -EINVAL;
 
-	phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+	phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
 	if (!phb)
 		return -ENODEV;
 	pci_write_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, v);
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 865e14f..b6722c2 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -22,6 +22,7 @@
 	select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select HAVE_MEMBLOCK
+	select HAVE_MEMBLOCK_NODE_MAP
 	select HAVE_DMA_API_DEBUG
 	select HAVE_DMA_CONTIGUOUS
 	select HAVE_GENERIC_DMA_COHERENT
@@ -43,6 +44,10 @@
 config ARCH_PHYS_ADDR_T_64BIT
 	def_bool y
 
+config ZONE_DMA32
+	bool
+	default y
+
 config ARCH_DMA_ADDR_T_64BIT
 	def_bool y
 
@@ -55,6 +60,9 @@
 config STACKTRACE_SUPPORT
 	def_bool y
 
+config TRACE_IRQFLAGS_SUPPORT
+	def_bool y
+
 config RWSEM_GENERIC_SPINLOCK
 	def_bool y
 
@@ -107,6 +115,8 @@
 	bool "RV64I"
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select 64BIT
+	select HAVE_FUNCTION_TRACER
+	select HAVE_FUNCTION_GRAPH_TRACER
 
 endchoice
 
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index 681ac0d..4286a5f 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -12,7 +12,6 @@
 generic-y += exec.h
 generic-y += fb.h
 generic-y += fcntl.h
-generic-y += ftrace.h
 generic-y += futex.h
 generic-y += hardirq.h
 generic-y += hash.h
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 3c7a2c9..421fa35 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -40,15 +40,15 @@
 #define SR_SD   _AC(0x8000000000000000, UL) /* FS/XS dirty */
 #endif
 
-/* SPTBR flags */
+/* SATP flags */
 #if __riscv_xlen == 32
-#define SPTBR_PPN     _AC(0x003FFFFF, UL)
-#define SPTBR_MODE_32 _AC(0x80000000, UL)
-#define SPTBR_MODE    SPTBR_MODE_32
+#define SATP_PPN     _AC(0x003FFFFF, UL)
+#define SATP_MODE_32 _AC(0x80000000, UL)
+#define SATP_MODE    SATP_MODE_32
 #else
-#define SPTBR_PPN     _AC(0x00000FFFFFFFFFFF, UL)
-#define SPTBR_MODE_39 _AC(0x8000000000000000, UL)
-#define SPTBR_MODE    SPTBR_MODE_39
+#define SATP_PPN     _AC(0x00000FFFFFFFFFFF, UL)
+#define SATP_MODE_39 _AC(0x8000000000000000, UL)
+#define SATP_MODE    SATP_MODE_39
 #endif
 
 /* Interrupt Enable and Interrupt Pending flags */
diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
new file mode 100644
index 0000000..66d4175
--- /dev/null
+++ b/arch/riscv/include/asm/ftrace.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2017 Andes Technology Corporation */
+
+/*
+ * The graph frame test is not possible if CONFIG_FRAME_POINTER is not enabled.
+ * Check arch/riscv/kernel/mcount.S for detail.
+ */
+#if defined(CONFIG_FUNCTION_GRAPH_TRACER) && defined(CONFIG_FRAME_POINTER)
+#define HAVE_FUNCTION_GRAPH_FP_TEST
+#endif
diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h
index 9742483..336d60e 100644
--- a/arch/riscv/include/asm/mmu_context.h
+++ b/arch/riscv/include/asm/mmu_context.h
@@ -39,16 +39,6 @@ static inline void destroy_context(struct mm_struct *mm)
 {
 }
 
-static inline pgd_t *current_pgdir(void)
-{
-	return pfn_to_virt(csr_read(sptbr) & SPTBR_PPN);
-}
-
-static inline void set_pgdir(pgd_t *pgd)
-{
-	csr_write(sptbr, virt_to_pfn(pgd) | SPTBR_MODE);
-}
-
 /*
  * When necessary, performs a deferred icache flush for the given MM context,
  * on the local CPU.  RISC-V has no direct mechanism for instruction cache
@@ -93,7 +83,12 @@ static inline void switch_mm(struct mm_struct *prev,
 		cpumask_clear_cpu(cpu, mm_cpumask(prev));
 		cpumask_set_cpu(cpu, mm_cpumask(next));
 
-		set_pgdir(next->pgd);
+		/*
+		 * Use the old spbtr name instead of using the current satp
+		 * name to support binutils 2.29 which doesn't know about the
+		 * privileged ISA 1.10 yet.
+		 */
+		csr_write(sptbr, virt_to_pfn(next->pgd) | SATP_MODE);
 		local_flush_tlb_all();
 
 		flush_icache_deferred(next);
diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
index 7b9c24e..7b209ae 100644
--- a/arch/riscv/include/asm/tlbflush.h
+++ b/arch/riscv/include/asm/tlbflush.h
@@ -36,7 +36,14 @@ static inline void local_flush_tlb_page(unsigned long addr)
 
 #define flush_tlb_all() local_flush_tlb_all()
 #define flush_tlb_page(vma, addr) local_flush_tlb_page(addr)
-#define flush_tlb_range(vma, start, end) local_flush_tlb_all()
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+		unsigned long start, unsigned long end)
+{
+	local_flush_tlb_all();
+}
+
+#define flush_tlb_mm(mm) flush_tlb_all()
 
 #else /* CONFIG_SMP */
 
@@ -45,16 +52,13 @@ static inline void local_flush_tlb_page(unsigned long addr)
 #define flush_tlb_all() sbi_remote_sfence_vma(0, 0, -1)
 #define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, 0)
 #define flush_tlb_range(vma, start, end) \
-	sbi_remote_sfence_vma(0, start, (end) - (start))
+	sbi_remote_sfence_vma(mm_cpumask((vma)->vm_mm)->bits, \
+			      start, (end) - (start))
+#define flush_tlb_mm(mm) \
+	sbi_remote_sfence_vma(mm_cpumask(mm)->bits, 0, -1)
 
 #endif /* CONFIG_SMP */
 
-/* Flush the TLB entries of the specified mm context */
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
-	flush_tlb_all();
-}
-
 /* Flush a range of kernel pages */
 static inline void flush_tlb_kernel_range(unsigned long start,
 	unsigned long end)
diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h
index 2f704a5..080fb28 100644
--- a/arch/riscv/include/asm/unistd.h
+++ b/arch/riscv/include/asm/unistd.h
@@ -11,7 +11,6 @@
  *   GNU General Public License for more details.
  */
 
-#define __ARCH_HAVE_MMU
 #define __ARCH_WANT_SYS_CLONE
 #include <uapi/asm/unistd.h>
 #include <uapi/asm/syscalls.h>
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index ab8baf7..196f62f 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -2,6 +2,11 @@
 # Makefile for the RISC-V Linux kernel
 #
 
+ifdef CONFIG_FTRACE
+CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_setup.o = -pg
+endif
+
 extra-y += head.o
 extra-y += vmlinux.lds
 
@@ -29,5 +34,7 @@
 obj-$(CONFIG_SMP)		+= smpboot.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_MODULES)		+= module.o
+obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
 
 clean:
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 7404ec2..87fc045 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -78,10 +78,13 @@
 	REG_S x31, PT_T6(sp)
 
 	/*
-	 * Disable FPU to detect illegal usage of
-	 * floating point in kernel space
+	 * Disable user-mode memory access as it should only be set in the
+	 * actual user copy routines.
+	 *
+	 * Disable the FPU to detect illegal usage of floating point in kernel
+	 * space.
 	 */
-	li t0, SR_FS
+	li t0, SR_SUM | SR_FS
 
 	REG_L s0, TASK_TI_USER_SP(tp)
 	csrrc s1, sstatus, t0
diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
new file mode 100644
index 0000000..d0de68d
--- /dev/null
+++ b/arch/riscv/kernel/ftrace.c
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2013 Linaro Limited
+ * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
+ * Copyright (C) 2017 Andes Technology Corporation
+ */
+
+#include <linux/ftrace.h>
+
+/*
+ * Most of this file is copied from arm64.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+			   unsigned long frame_pointer)
+{
+	unsigned long return_hooker = (unsigned long)&return_to_handler;
+	unsigned long old;
+	struct ftrace_graph_ent trace;
+	int err;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return;
+
+	/*
+	 * We don't suffer access faults, so no extra fault-recovery assembly
+	 * is needed here.
+	 */
+	old = *parent;
+
+	trace.func = self_addr;
+	trace.depth = current->curr_ret_stack + 1;
+
+	if (!ftrace_graph_entry(&trace))
+		return;
+
+	err = ftrace_push_return_trace(old, self_addr, &trace.depth,
+				       frame_pointer, NULL);
+	if (err == -EBUSY)
+		return;
+	*parent = return_hooker;
+}
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 78f670d..226eeb1 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -74,15 +74,15 @@
 	sub a1, a1, a0
 	add ra, ra, a1
 
-	/* Point stvec to virtual address of intruction after sptbr write */
+	/* Point stvec to virtual address of intruction after satp write */
 	la a0, 1f
 	add a0, a0, a1
 	csrw stvec, a0
 
-	/* Compute sptbr for kernel page tables, but don't load it yet */
+	/* Compute satp for kernel page tables, but don't load it yet */
 	la a2, swapper_pg_dir
 	srl a2, a2, PAGE_SHIFT
-	li a1, SPTBR_MODE
+	li a1, SATP_MODE
 	or a2, a2, a1
 
 	/*
diff --git a/arch/riscv/kernel/mcount.S b/arch/riscv/kernel/mcount.S
new file mode 100644
index 0000000..c46a778
--- /dev/null
+++ b/arch/riscv/kernel/mcount.S
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2017 Andes Technology Corporation */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/asm.h>
+#include <asm/csr.h>
+#include <asm/unistd.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+#include <asm-generic/export.h>
+#include <asm/ftrace.h>
+
+	.text
+
+	.macro SAVE_ABI_STATE
+	addi	sp, sp, -16
+	sd	s0, 0(sp)
+	sd	ra, 8(sp)
+	addi	s0, sp, 16
+	.endm
+
+	/*
+	 * The call to ftrace_return_to_handler would overwrite the return
+	 * register if a0 was not saved.
+	 */
+	.macro SAVE_RET_ABI_STATE
+	addi	sp, sp, -32
+	sd	s0, 16(sp)
+	sd	ra, 24(sp)
+	sd	a0, 8(sp)
+	addi	s0, sp, 32
+	.endm
+
+	.macro STORE_ABI_STATE
+	ld	ra, 8(sp)
+	ld	s0, 0(sp)
+	addi	sp, sp, 16
+	.endm
+
+	.macro STORE_RET_ABI_STATE
+	ld	ra, 24(sp)
+	ld	s0, 16(sp)
+	ld	a0, 8(sp)
+	addi	sp, sp, 32
+	.endm
+
+ENTRY(ftrace_stub)
+	ret
+ENDPROC(ftrace_stub)
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(return_to_handler)
+/*
+ * On implementing the frame point test, the ideal way is to compare the
+ * s0 (frame pointer, if enabled) on entry and the sp (stack pointer) on return.
+ * However, the psABI of variable-length-argument functions does not allow this.
+ *
+ * So alternatively we check the *old* frame pointer position, that is, the
+ * value stored in -16(s0) on entry, and the s0 on return.
+ */
+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
+	mv	t6, s0
+#endif
+	SAVE_RET_ABI_STATE
+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
+	mv	a0, t6
+#endif
+	la	t0, ftrace_return_to_handler
+	jalr	t0
+	mv	a1, a0
+	STORE_RET_ABI_STATE
+	jalr	a1
+ENDPROC(return_to_handler)
+EXPORT_SYMBOL(return_to_handler)
+#endif
+
+ENTRY(_mcount)
+	la	t4, ftrace_stub
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	la	t0, ftrace_graph_return
+	ld	t1, 0(t0)
+	bne	t1, t4, do_ftrace_graph_caller
+
+	la	t3, ftrace_graph_entry
+	ld	t2, 0(t3)
+	la	t6, ftrace_graph_entry_stub
+	bne	t2, t6, do_ftrace_graph_caller
+#endif
+	la	t3, ftrace_trace_function
+	ld	t5, 0(t3)
+	bne	t5, t4, do_trace
+	ret
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+/*
+ * A pseudo representation for the function graph tracer:
+ * prepare_to_return(&ra_to_caller_of_caller, ra_to_caller)
+ */
+do_ftrace_graph_caller:
+	addi	a0, s0, -8
+	mv	a1, ra
+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
+	ld	a2, -16(s0)
+#endif
+	SAVE_ABI_STATE
+	la	t0, prepare_ftrace_return
+	jalr	t0
+	STORE_ABI_STATE
+	ret
+#endif
+
+/*
+ * A pseudo representation for the function tracer:
+ * (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller)
+ */
+do_trace:
+	ld	a1, -8(s0)
+	mv	a0, ra
+
+	SAVE_ABI_STATE
+	jalr	t5
+	STORE_ABI_STATE
+	ret
+ENDPROC(_mcount)
+EXPORT_SYMBOL(_mcount)
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index cb7b0c6..09f7064 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -49,10 +49,6 @@ struct screen_info screen_info = {
 };
 #endif
 
-#ifdef CONFIG_CMDLINE_BOOL
-static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
-#endif /* CONFIG_CMDLINE_BOOL */
-
 unsigned long va_pa_offset;
 EXPORT_SYMBOL(va_pa_offset);
 unsigned long pfn_base;
@@ -153,25 +149,6 @@ void __init sbi_save(unsigned int hartid, void *dtb)
 	early_init_dt_scan(__va(dtb));
 }
 
-/*
- * Allow the user to manually add a memory region (in case DTS is broken);
- * "mem_end=nn[KkMmGg]"
- */
-static int __init mem_end_override(char *p)
-{
-	resource_size_t base, end;
-
-	if (!p)
-		return -EINVAL;
-	base = (uintptr_t) __pa(PAGE_OFFSET);
-	end = memparse(p, &p) & PMD_MASK;
-	if (end == 0)
-		return -EINVAL;
-	memblock_add(base, end - base);
-	return 0;
-}
-early_param("mem_end", mem_end_override);
-
 static void __init setup_bootmem(void)
 {
 	struct memblock_region *reg;
@@ -204,22 +181,19 @@ static void __init setup_bootmem(void)
 	early_init_fdt_scan_reserved_mem();
 	memblock_allow_resize();
 	memblock_dump_all();
+
+	for_each_memblock(memory, reg) {
+		unsigned long start_pfn = memblock_region_memory_base_pfn(reg);
+		unsigned long end_pfn = memblock_region_memory_end_pfn(reg);
+
+		memblock_set_node(PFN_PHYS(start_pfn),
+		                  PFN_PHYS(end_pfn - start_pfn),
+		                  &memblock.memory, 0);
+	}
 }
 
 void __init setup_arch(char **cmdline_p)
 {
-#ifdef CONFIG_CMDLINE_BOOL
-#ifdef CONFIG_CMDLINE_OVERRIDE
-	strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-#else
-	if (builtin_cmdline[0] != '\0') {
-		/* Append bootloader command line to built-in */
-		strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
-		strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
-		strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-	}
-#endif /* CONFIG_CMDLINE_OVERRIDE */
-#endif /* CONFIG_CMDLINE_BOOL */
 	*cmdline_p = boot_command_line;
 
 	parse_early_param();
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index e8a178d..582cb15 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -74,7 +74,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
 
 	down_write(&mm->mmap_sem);
 	vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0);
-	if (unlikely(IS_ERR_VALUE(vdso_base))) {
+	if (IS_ERR_VALUE(vdso_base)) {
 		ret = vdso_base;
 		goto end;
 	}
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index ceebfc29..148c98c 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -238,6 +238,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs)
 		 * Do _not_ use "tsk->active_mm->pgd" here.
 		 * We might be inside an interrupt in the middle
 		 * of a task switch.
+		 *
+		 * Note: Use the old spbtr name instead of using the current
+		 * satp name to support binutils 2.29 which doesn't know about
+		 * the privileged ISA 1.10 yet.
 		 */
 		index = pgd_index(addr);
 		pgd = (pgd_t *)pfn_to_virt(csr_read(sptbr)) + index;
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 9f4bee5..c77df81 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -17,6 +17,7 @@
 #include <linux/initrd.h>
 #include <linux/memblock.h>
 #include <linux/swap.h>
+#include <linux/sizes.h>
 
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
@@ -25,11 +26,12 @@
 
 static void __init zone_sizes_init(void)
 {
-	unsigned long zones_size[MAX_NR_ZONES];
+	unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, };
 
-	memset(zones_size, 0, sizeof(zones_size));
-	zones_size[ZONE_NORMAL] = max_mapnr;
-	free_area_init_node(0, zones_size, pfn_base, NULL);
+	max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, max_low_pfn));
+	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+
+	free_area_init_nodes(max_zone_pfns);
 }
 
 void setup_zero_page(void)
@@ -39,8 +41,6 @@ void setup_zero_page(void)
 
 void __init paging_init(void)
 {
-	init_mm.pgd = (pgd_t *)pfn_to_virt(csr_read(sptbr));
-
 	setup_zero_page();
 	local_flush_tlb_all();
 	zone_sizes_init();
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 671535e..3fa3e53 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -222,7 +222,8 @@ device_initcall(s390_cma_mem_init);
 
 #endif /* CONFIG_CMA */
 
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+		bool want_memblock)
 {
 	unsigned long start_pfn = PFN_DOWN(start);
 	unsigned long size_pages = PFN_DOWN(size);
@@ -232,14 +233,14 @@ int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
 	if (rc)
 		return rc;
 
-	rc = __add_pages(nid, start_pfn, size_pages, want_memblock);
+	rc = __add_pages(nid, start_pfn, size_pages, altmap, want_memblock);
 	if (rc)
 		vmem_remove_mapping(start, size);
 	return rc;
 }
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
+int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
 {
 	/*
 	 * There is no hardware or firmware interface which could trigger a
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 3316d46..db55561 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -211,7 +211,8 @@ static void vmem_remove_range(unsigned long start, unsigned long size)
 /*
  * Add a backed mem_map array to the virtual mem_map array.
  */
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+		struct vmem_altmap *altmap)
 {
 	unsigned long pgt_prot, sgt_prot;
 	unsigned long address = start;
@@ -296,7 +297,8 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
 	return ret;
 }
 
-void vmemmap_free(unsigned long start, unsigned long end)
+void vmemmap_free(unsigned long start, unsigned long end,
+		struct vmem_altmap *altmap)
 {
 }
 
diff --git a/arch/score/kernel/setup.c b/arch/score/kernel/setup.c
index f3a0649..627416b 100644
--- a/arch/score/kernel/setup.c
+++ b/arch/score/kernel/setup.c
@@ -124,9 +124,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 {
 	unsigned long n = (unsigned long) v - 1;
 
-	seq_printf(m, "processor\t\t: %ld\n", n);
-	seq_printf(m, "\n");
-
+	seq_printf(m, "processor\t\t: %ld\n\n", n);
 	return 0;
 }
 
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index bf726af..ce0bbaa 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -485,20 +485,20 @@ void free_initrd_mem(unsigned long start, unsigned long end)
 #endif
 
 #ifdef CONFIG_MEMORY_HOTPLUG
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+		bool want_memblock)
 {
 	unsigned long start_pfn = PFN_DOWN(start);
 	unsigned long nr_pages = size >> PAGE_SHIFT;
 	int ret;
 
 	/* We only have ZONE_NORMAL, so this is easy.. */
-	ret = __add_pages(nid, start_pfn, nr_pages, want_memblock);
+	ret = __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
 	if (unlikely(ret))
 		printk("%s: Failed, __add_pages() == %d\n", __func__, ret);
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(arch_add_memory);
 
 #ifdef CONFIG_NUMA
 int memory_add_physaddr_to_nid(u64 addr)
@@ -510,7 +510,7 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 #endif
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
+int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
 {
 	unsigned long start_pfn = PFN_DOWN(start);
 	unsigned long nr_pages = size >> PAGE_SHIFT;
@@ -518,7 +518,7 @@ int arch_remove_memory(u64 start, u64 size)
 	int ret;
 
 	zone = page_zone(pfn_to_page(start_pfn));
-	ret = __remove_pages(zone, start_pfn, nr_pages);
+	ret = __remove_pages(zone, start_pfn, nr_pages, altmap);
 	if (unlikely(ret))
 		pr_warn("%s: Failed, __remove_pages() == %d\n", __func__,
 			ret);
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 55ba629..995f949 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -2628,7 +2628,7 @@ EXPORT_SYMBOL(_PAGE_CACHE);
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend,
-			       int node)
+			       int node, struct vmem_altmap *altmap)
 {
 	unsigned long pte_base;
 
@@ -2671,7 +2671,8 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend,
 	return 0;
 }
 
-void vmemmap_free(unsigned long start, unsigned long end)
+void vmemmap_free(unsigned long start, unsigned long end,
+		struct vmem_altmap *altmap)
 {
 }
 #endif /* CONFIG_SPARSEMEM_VMEMMAP */
diff --git a/arch/unicore32/include/asm/bitops.h b/arch/unicore32/include/asm/bitops.h
index 401f597..c0cbdbe 100644
--- a/arch/unicore32/include/asm/bitops.h
+++ b/arch/unicore32/include/asm/bitops.h
@@ -44,4 +44,6 @@ static inline int fls(int x)
 #define find_first_bit		find_first_bit
 #define find_first_zero_bit	find_first_zero_bit
 
+#include <asm-generic/bitops/find.h>
+
 #endif /* __UNICORE_BITOPS_H__ */
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b0771ce..63bf349 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -55,6 +55,7 @@
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_KCOV			if X86_64
 	select ARCH_HAS_PHYS_TO_DMA
+	select ARCH_HAS_MEMBARRIER_SYNC_CORE
 	select ARCH_HAS_PMEM_API		if X86_64
 	select ARCH_HAS_REFCOUNT
 	select ARCH_HAS_UACCESS_FLUSHCACHE	if X86_64
@@ -62,6 +63,7 @@
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAS_STRICT_KERNEL_RWX
 	select ARCH_HAS_STRICT_MODULE_RWX
+	select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
 	select ARCH_HAS_UBSAN_SANITIZE_ALL
 	select ARCH_HAS_ZONE_DEVICE		if X86_64
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
@@ -322,7 +324,7 @@
 
 config X86_32_LAZY_GS
 	def_bool y
-	depends on X86_32 && !CC_STACKPROTECTOR
+	depends on X86_32 && CC_STACKPROTECTOR_NONE
 
 config ARCH_SUPPORTS_UPROBES
 	def_bool y
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index 2a35b1e..abee6d2 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -566,6 +566,11 @@
 .Lrestore_nocheck:
 	RESTORE_REGS 4				# skip orig_eax/error_code
 .Lirq_return:
+	/*
+	 * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization
+	 * when returning from IPI handler and when returning from
+	 * scheduler to user-space.
+	 */
 	INTERRUPT_RETURN
 
 .section .fixup, "ax"
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index c752abe..4a9bef6 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -691,6 +691,10 @@
 	POP_EXTRA_REGS
 	POP_C_REGS
 	addq	$8, %rsp	/* skip regs->orig_ax */
+	/*
+	 * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization
+	 * when returning from IPI handler.
+	 */
 	INTERRUPT_RETURN
 
 ENTRY(native_iret)
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 8e4ea143..78f91ec 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -93,7 +93,8 @@ struct amd_nb {
 	PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \
 	PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \
 	PERF_SAMPLE_TRANSACTION | PERF_SAMPLE_PHYS_ADDR | \
-	PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER)
+	PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER | \
+	PERF_SAMPLE_PERIOD)
 
 #define PEBS_REGS \
 	(PERF_REG_X86_AX | \
diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
index 35a6bc4..cf090e5 100644
--- a/arch/x86/include/asm/intel-family.h
+++ b/arch/x86/include/asm/intel-family.h
@@ -10,6 +10,10 @@
  *
  * Things ending in "2" are usually because we have no better
  * name for them.  There's no processor called "SILVERMONT2".
+ *
+ * While adding a new CPUID for a new microarchitecture, add a new
+ * group to keep logically sorted out in chronological order. Within
+ * that group keep the CPUID for the variants sorted by model number.
  */
 
 #define INTEL_FAM6_CORE_YONAH		0x0E
@@ -49,6 +53,8 @@
 #define INTEL_FAM6_KABYLAKE_MOBILE	0x8E
 #define INTEL_FAM6_KABYLAKE_DESKTOP	0x9E
 
+#define INTEL_FAM6_CANNONLAKE_MOBILE	0x66
+
 /* "Small Core" Processors (Atom) */
 
 #define INTEL_FAM6_ATOM_PINEVIEW	0x1C
diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
index 528ed4b..9e7adcd 100644
--- a/arch/x86/include/asm/intel_pmc_ipc.h
+++ b/arch/x86/include/asm/intel_pmc_ipc.h
@@ -38,6 +38,7 @@ int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
 		u32 *out, u32 outlen);
 int intel_pmc_s0ix_counter_read(u64 *data);
 int intel_pmc_gcr_read(u32 offset, u32 *data);
+int intel_pmc_gcr_read64(u32 offset, u64 *data);
 int intel_pmc_gcr_write(u32 offset, u32 data);
 int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val);
 
@@ -70,6 +71,11 @@ static inline int intel_pmc_gcr_read(u32 offset, u32 *data)
 	return -EINVAL;
 }
 
+static inline int intel_pmc_gcr_read64(u32 offset, u64 *data)
+{
+	return -EINVAL;
+}
+
 static inline int intel_pmc_gcr_write(u32 offset, u32 data)
 {
 	return -EINVAL;
diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h
index b577dd0..13e70da 100644
--- a/arch/x86/include/asm/kasan.h
+++ b/arch/x86/include/asm/kasan.h
@@ -4,6 +4,7 @@
 
 #include <linux/const.h>
 #define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
+#define KASAN_SHADOW_SCALE_SHIFT 3
 
 /*
  * Compiler uses shadow offset assuming that addresses start
@@ -12,12 +13,15 @@
  * 'kernel address space start' >> KASAN_SHADOW_SCALE_SHIFT
  */
 #define KASAN_SHADOW_START      (KASAN_SHADOW_OFFSET + \
-					((-1UL << __VIRTUAL_MASK_SHIFT) >> 3))
+					((-1UL << __VIRTUAL_MASK_SHIFT) >> \
+						KASAN_SHADOW_SCALE_SHIFT))
 /*
- * 47 bits for kernel address -> (47 - 3) bits for shadow
- * 56 bits for kernel address -> (56 - 3) bits for shadow
+ * 47 bits for kernel address -> (47 - KASAN_SHADOW_SCALE_SHIFT) bits for shadow
+ * 56 bits for kernel address -> (56 - KASAN_SHADOW_SCALE_SHIFT) bits for shadow
  */
-#define KASAN_SHADOW_END        (KASAN_SHADOW_START + (1ULL << (__VIRTUAL_MASK_SHIFT - 3)))
+#define KASAN_SHADOW_END        (KASAN_SHADOW_START + \
+					(1ULL << (__VIRTUAL_MASK_SHIFT - \
+						  KASAN_SHADOW_SCALE_SHIFT)))
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/x86/include/asm/pmc_core.h b/arch/x86/include/asm/pmc_core.h
deleted file mode 100644
index d4855f1..0000000
--- a/arch/x86/include/asm/pmc_core.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Intel Core SoC Power Management Controller Header File
- *
- * Copyright (c) 2016, Intel Corporation.
- * All Rights Reserved.
- *
- * Authors: Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
- *          Vishwanath Somayaji <vishwanath.somayaji@intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- */
-
-#ifndef _ASM_PMC_CORE_H
-#define _ASM_PMC_CORE_H
-
-/* API to read SLP_S0_RESIDENCY counter */
-int intel_pmc_slp_s0_counter_read(u32 *data);
-
-#endif /* _ASM_PMC_CORE_H */
diff --git a/arch/x86/include/asm/sync_core.h b/arch/x86/include/asm/sync_core.h
new file mode 100644
index 0000000..c67caafd3
--- /dev/null
+++ b/arch/x86/include/asm/sync_core.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_SYNC_CORE_H
+#define _ASM_X86_SYNC_CORE_H
+
+#include <linux/preempt.h>
+#include <asm/processor.h>
+#include <asm/cpufeature.h>
+
+/*
+ * Ensure that a core serializing instruction is issued before returning
+ * to user-mode. x86 implements return to user-space through sysexit,
+ * sysrel, and sysretq, which are not core serializing.
+ */
+static inline void sync_core_before_usermode(void)
+{
+	/* With PTI, we unconditionally serialize before running user code. */
+	if (static_cpu_has(X86_FEATURE_PTI))
+		return;
+	/*
+	 * Return from interrupt and NMI is done through iret, which is core
+	 * serializing.
+	 */
+	if (in_irq() || in_nmi())
+		return;
+	sync_core();
+}
+
+#endif /* _ASM_X86_SYNC_CORE_H */
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 135c9a7..79cb066 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -829,23 +829,24 @@ void __init mem_init(void)
 }
 
 #ifdef CONFIG_MEMORY_HOTPLUG
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+		bool want_memblock)
 {
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
 
-	return __add_pages(nid, start_pfn, nr_pages, want_memblock);
+	return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
 }
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
+int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
 {
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
 	struct zone *zone;
 
 	zone = page_zone(pfn_to_page(start_pfn));
-	return __remove_pages(zone, start_pfn, nr_pages);
+	return __remove_pages(zone, start_pfn, nr_pages, altmap);
 }
 #endif
 #endif
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 4a83728..1ab42c8 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -772,12 +772,12 @@ static void update_end_of_memory_vars(u64 start, u64 size)
 	}
 }
 
-int add_pages(int nid, unsigned long start_pfn,
-	      unsigned long nr_pages, bool want_memblock)
+int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
+		struct vmem_altmap *altmap, bool want_memblock)
 {
 	int ret;
 
-	ret = __add_pages(nid, start_pfn, nr_pages, want_memblock);
+	ret = __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
 	WARN_ON_ONCE(ret);
 
 	/* update max_pfn, max_low_pfn and high_memory */
@@ -787,24 +787,24 @@ int add_pages(int nid, unsigned long start_pfn,
 	return ret;
 }
 
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+		bool want_memblock)
 {
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
 
 	init_memory_mapping(start, start + size);
 
-	return add_pages(nid, start_pfn, nr_pages, want_memblock);
+	return add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
 }
-EXPORT_SYMBOL_GPL(arch_add_memory);
 
 #define PAGE_INUSE 0xFD
 
-static void __meminit free_pagetable(struct page *page, int order)
+static void __meminit free_pagetable(struct page *page, int order,
+		struct vmem_altmap *altmap)
 {
 	unsigned long magic;
 	unsigned int nr_pages = 1 << order;
-	struct vmem_altmap *altmap = to_vmem_altmap((unsigned long) page);
 
 	if (altmap) {
 		vmem_altmap_free(altmap, nr_pages);
@@ -826,7 +826,8 @@ static void __meminit free_pagetable(struct page *page, int order)
 		free_pages((unsigned long)page_address(page), order);
 }
 
-static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
+static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd,
+		struct vmem_altmap *altmap)
 {
 	pte_t *pte;
 	int i;
@@ -838,13 +839,14 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
 	}
 
 	/* free a pte talbe */
-	free_pagetable(pmd_page(*pmd), 0);
+	free_pagetable(pmd_page(*pmd), 0, altmap);
 	spin_lock(&init_mm.page_table_lock);
 	pmd_clear(pmd);
 	spin_unlock(&init_mm.page_table_lock);
 }
 
-static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
+static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud,
+		struct vmem_altmap *altmap)
 {
 	pmd_t *pmd;
 	int i;
@@ -856,13 +858,14 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
 	}
 
 	/* free a pmd talbe */
-	free_pagetable(pud_page(*pud), 0);
+	free_pagetable(pud_page(*pud), 0, altmap);
 	spin_lock(&init_mm.page_table_lock);
 	pud_clear(pud);
 	spin_unlock(&init_mm.page_table_lock);
 }
 
-static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d)
+static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d,
+		struct vmem_altmap *altmap)
 {
 	pud_t *pud;
 	int i;
@@ -874,7 +877,7 @@ static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d)
 	}
 
 	/* free a pud talbe */
-	free_pagetable(p4d_page(*p4d), 0);
+	free_pagetable(p4d_page(*p4d), 0, altmap);
 	spin_lock(&init_mm.page_table_lock);
 	p4d_clear(p4d);
 	spin_unlock(&init_mm.page_table_lock);
@@ -882,7 +885,7 @@ static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d)
 
 static void __meminit
 remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
-		 bool direct)
+		 struct vmem_altmap *altmap, bool direct)
 {
 	unsigned long next, pages = 0;
 	pte_t *pte;
@@ -913,7 +916,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 			 * freed when offlining, or simplely not in use.
 			 */
 			if (!direct)
-				free_pagetable(pte_page(*pte), 0);
+				free_pagetable(pte_page(*pte), 0, altmap);
 
 			spin_lock(&init_mm.page_table_lock);
 			pte_clear(&init_mm, addr, pte);
@@ -936,7 +939,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 
 			page_addr = page_address(pte_page(*pte));
 			if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) {
-				free_pagetable(pte_page(*pte), 0);
+				free_pagetable(pte_page(*pte), 0, altmap);
 
 				spin_lock(&init_mm.page_table_lock);
 				pte_clear(&init_mm, addr, pte);
@@ -953,7 +956,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
 
 static void __meminit
 remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
-		 bool direct)
+		 bool direct, struct vmem_altmap *altmap)
 {
 	unsigned long next, pages = 0;
 	pte_t *pte_base;
@@ -972,7 +975,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
 			    IS_ALIGNED(next, PMD_SIZE)) {
 				if (!direct)
 					free_pagetable(pmd_page(*pmd),
-						       get_order(PMD_SIZE));
+						       get_order(PMD_SIZE),
+						       altmap);
 
 				spin_lock(&init_mm.page_table_lock);
 				pmd_clear(pmd);
@@ -986,7 +990,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
 				if (!memchr_inv(page_addr, PAGE_INUSE,
 						PMD_SIZE)) {
 					free_pagetable(pmd_page(*pmd),
-						       get_order(PMD_SIZE));
+						       get_order(PMD_SIZE),
+						       altmap);
 
 					spin_lock(&init_mm.page_table_lock);
 					pmd_clear(pmd);
@@ -998,8 +1003,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
 		}
 
 		pte_base = (pte_t *)pmd_page_vaddr(*pmd);
-		remove_pte_table(pte_base, addr, next, direct);
-		free_pte_table(pte_base, pmd);
+		remove_pte_table(pte_base, addr, next, altmap, direct);
+		free_pte_table(pte_base, pmd, altmap);
 	}
 
 	/* Call free_pmd_table() in remove_pud_table(). */
@@ -1009,7 +1014,7 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
 
 static void __meminit
 remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
-		 bool direct)
+		 struct vmem_altmap *altmap, bool direct)
 {
 	unsigned long next, pages = 0;
 	pmd_t *pmd_base;
@@ -1028,7 +1033,8 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
 			    IS_ALIGNED(next, PUD_SIZE)) {
 				if (!direct)
 					free_pagetable(pud_page(*pud),
-						       get_order(PUD_SIZE));
+						       get_order(PUD_SIZE),
+						       altmap);
 
 				spin_lock(&init_mm.page_table_lock);
 				pud_clear(pud);
@@ -1042,7 +1048,8 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
 				if (!memchr_inv(page_addr, PAGE_INUSE,
 						PUD_SIZE)) {
 					free_pagetable(pud_page(*pud),
-						       get_order(PUD_SIZE));
+						       get_order(PUD_SIZE),
+						       altmap);
 
 					spin_lock(&init_mm.page_table_lock);
 					pud_clear(pud);
@@ -1054,8 +1061,8 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
 		}
 
 		pmd_base = pmd_offset(pud, 0);
-		remove_pmd_table(pmd_base, addr, next, direct);
-		free_pmd_table(pmd_base, pud);
+		remove_pmd_table(pmd_base, addr, next, direct, altmap);
+		free_pmd_table(pmd_base, pud, altmap);
 	}
 
 	if (direct)
@@ -1064,7 +1071,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
 
 static void __meminit
 remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
-		 bool direct)
+		 struct vmem_altmap *altmap, bool direct)
 {
 	unsigned long next, pages = 0;
 	pud_t *pud_base;
@@ -1080,14 +1087,14 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
 		BUILD_BUG_ON(p4d_large(*p4d));
 
 		pud_base = pud_offset(p4d, 0);
-		remove_pud_table(pud_base, addr, next, direct);
+		remove_pud_table(pud_base, addr, next, altmap, direct);
 		/*
 		 * For 4-level page tables we do not want to free PUDs, but in the
 		 * 5-level case we should free them. This code will have to change
 		 * to adapt for boot-time switching between 4 and 5 level page tables.
 		 */
 		if (CONFIG_PGTABLE_LEVELS == 5)
-			free_pud_table(pud_base, p4d);
+			free_pud_table(pud_base, p4d, altmap);
 	}
 
 	if (direct)
@@ -1096,7 +1103,8 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
 
 /* start and end are both virtual address. */
 static void __meminit
-remove_pagetable(unsigned long start, unsigned long end, bool direct)
+remove_pagetable(unsigned long start, unsigned long end, bool direct,
+		struct vmem_altmap *altmap)
 {
 	unsigned long next;
 	unsigned long addr;
@@ -1111,15 +1119,16 @@ remove_pagetable(unsigned long start, unsigned long end, bool direct)
 			continue;
 
 		p4d = p4d_offset(pgd, 0);
-		remove_p4d_table(p4d, addr, next, direct);
+		remove_p4d_table(p4d, addr, next, altmap, direct);
 	}
 
 	flush_tlb_all();
 }
 
-void __ref vmemmap_free(unsigned long start, unsigned long end)
+void __ref vmemmap_free(unsigned long start, unsigned long end,
+		struct vmem_altmap *altmap)
 {
-	remove_pagetable(start, end, false);
+	remove_pagetable(start, end, false, altmap);
 }
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
@@ -1129,24 +1138,22 @@ kernel_physical_mapping_remove(unsigned long start, unsigned long end)
 	start = (unsigned long)__va(start);
 	end = (unsigned long)__va(end);
 
-	remove_pagetable(start, end, true);
+	remove_pagetable(start, end, true, NULL);
 }
 
-int __ref arch_remove_memory(u64 start, u64 size)
+int __ref arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
 {
 	unsigned long start_pfn = start >> PAGE_SHIFT;
 	unsigned long nr_pages = size >> PAGE_SHIFT;
 	struct page *page = pfn_to_page(start_pfn);
-	struct vmem_altmap *altmap;
 	struct zone *zone;
 	int ret;
 
 	/* With altmap the first mapped page is offset from @start */
-	altmap = to_vmem_altmap((unsigned long) page);
 	if (altmap)
 		page += vmem_altmap_offset(altmap);
 	zone = page_zone(page);
-	ret = __remove_pages(zone, start_pfn, nr_pages);
+	ret = __remove_pages(zone, start_pfn, nr_pages, altmap);
 	WARN_ON_ONCE(ret);
 	kernel_physical_mapping_remove(start, start + size);
 
@@ -1378,7 +1385,10 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start,
 		if (pmd_none(*pmd)) {
 			void *p;
 
-			p = __vmemmap_alloc_block_buf(PMD_SIZE, node, altmap);
+			if (altmap)
+				p = altmap_alloc_block_buf(PMD_SIZE, altmap);
+			else
+				p = vmemmap_alloc_block_buf(PMD_SIZE, node);
 			if (p) {
 				pte_t entry;
 
@@ -1411,9 +1421,9 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start,
 	return 0;
 }
 
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+		struct vmem_altmap *altmap)
 {
-	struct vmem_altmap *altmap = to_vmem_altmap(start);
 	int err;
 
 	if (boot_cpu_has(X86_FEATURE_PSE))
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 012d026..8dcc060 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -229,6 +229,12 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 #endif
 	this_cpu_write(cpu_tlbstate.is_lazy, false);
 
+	/*
+	 * The membarrier system call requires a full memory barrier and
+	 * core serialization before returning to user-space, after
+	 * storing to rq->curr. Writing to CR3 provides that full
+	 * memory barrier and core serializing instruction.
+	 */
 	if (real_prev == next) {
 		VM_WARN_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) !=
 			   next->context.ctx_id);
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 0452629..52e5510 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -839,7 +839,8 @@ static void __init pirq_find_router(struct irq_router *r)
 	DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for [%04x:%04x]\n",
 	    rt->rtr_vendor, rt->rtr_device);
 
-	pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn);
+	pirq_router_dev = pci_get_domain_bus_and_slot(0, rt->rtr_bus,
+						      rt->rtr_devfn);
 	if (!pirq_router_dev) {
 		DBG(KERN_DEBUG "PCI: Interrupt router not found at "
 			"%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index c4b3646..9542a746 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -409,10 +409,8 @@ int __init pci_xen_init(void)
 	pcibios_enable_irq = xen_pcifront_enable_irq;
 	pcibios_disable_irq = NULL;
 
-#ifdef CONFIG_ACPI
 	/* Keep ACPI out of the picture */
-	acpi_noirq = 1;
-#endif
+	acpi_noirq_set();
 
 #ifdef CONFIG_PCI_MSI
 	x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
diff --git a/drivers/Makefile b/drivers/Makefile
index 7a04387..24cd470 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -16,10 +16,7 @@
 obj-$(CONFIG_GPIOLIB)		+= gpio/
 obj-y				+= pwm/
 
-obj-$(CONFIG_PCI)		+= pci/
-obj-$(CONFIG_PCI_ENDPOINT)	+= pci/endpoint/
-# PCI dwc controller drivers
-obj-y				+= pci/dwc/
+obj-y				+= pci/
 
 obj-$(CONFIG_PARISC)		+= parisc/
 obj-$(CONFIG_RAPIDIO)		+= rapidio/
diff --git a/drivers/acpi/acpi_lpit.c b/drivers/acpi/acpi_lpit.c
index e94e478..cf4fc01 100644
--- a/drivers/acpi/acpi_lpit.c
+++ b/drivers/acpi/acpi_lpit.c
@@ -100,6 +100,7 @@ int lpit_read_residency_count_address(u64 *address)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(lpit_read_residency_count_address);
 
 static void lpit_update_residency(struct lpit_residency_info *info,
 				 struct acpi_lpit_native *lpit_native)
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index abeb4df..bbe48ad 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -838,6 +838,18 @@ static bool add_flush(struct acpi_nfit_desc *acpi_desc,
 	return true;
 }
 
+static bool add_platform_cap(struct acpi_nfit_desc *acpi_desc,
+		struct acpi_nfit_capabilities *pcap)
+{
+	struct device *dev = acpi_desc->dev;
+	u32 mask;
+
+	mask = (1 << (pcap->highest_capability + 1)) - 1;
+	acpi_desc->platform_cap = pcap->capabilities & mask;
+	dev_dbg(dev, "%s: cap: %#x\n", __func__, acpi_desc->platform_cap);
+	return true;
+}
+
 static void *add_table(struct acpi_nfit_desc *acpi_desc,
 		struct nfit_table_prev *prev, void *table, const void *end)
 {
@@ -883,6 +895,10 @@ static void *add_table(struct acpi_nfit_desc *acpi_desc,
 	case ACPI_NFIT_TYPE_SMBIOS:
 		dev_dbg(dev, "%s: smbios\n", __func__);
 		break;
+	case ACPI_NFIT_TYPE_CAPABILITIES:
+		if (!add_platform_cap(acpi_desc, table))
+			return err;
+		break;
 	default:
 		dev_err(dev, "unknown table '%d' parsing nfit\n", hdr->type);
 		break;
@@ -1867,6 +1883,9 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
 		struct kernfs_node *nfit_kernfs;
 
 		nvdimm = nfit_mem->nvdimm;
+		if (!nvdimm)
+			continue;
+
 		nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit");
 		if (nfit_kernfs)
 			nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs,
@@ -2656,6 +2675,12 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
 	else
 		ndr_desc->numa_node = NUMA_NO_NODE;
 
+	if(acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_CACHE_FLUSH)
+		set_bit(ND_REGION_PERSIST_CACHE, &ndr_desc->flags);
+
+	if (acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_MEM_FLUSH)
+		set_bit(ND_REGION_PERSIST_MEMCTRL, &ndr_desc->flags);
+
 	list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
 		struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
 		struct nd_mapping_desc *mapping;
@@ -3464,6 +3489,7 @@ static __init int nfit_init(void)
 	BUILD_BUG_ON(sizeof(struct acpi_nfit_smbios) != 9);
 	BUILD_BUG_ON(sizeof(struct acpi_nfit_control_region) != 80);
 	BUILD_BUG_ON(sizeof(struct acpi_nfit_data_region) != 40);
+	BUILD_BUG_ON(sizeof(struct acpi_nfit_capabilities) != 16);
 
 	guid_parse(UUID_VOLATILE_MEMORY, &nfit_uuid[NFIT_SPA_VOLATILE]);
 	guid_parse(UUID_PERSISTENT_MEMORY, &nfit_uuid[NFIT_SPA_PM]);
diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
index f0cf18b..50d36e1 100644
--- a/drivers/acpi/nfit/nfit.h
+++ b/drivers/acpi/nfit/nfit.h
@@ -202,6 +202,7 @@ struct acpi_nfit_desc {
 	unsigned long dimm_cmd_force_en;
 	unsigned long bus_cmd_force_en;
 	unsigned long bus_nfit_cmd_force_en;
+	unsigned int platform_cap;
 	int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
 			void *iobuf, u64 len, int rw);
 };
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index d19cd88..0b122f90 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -466,7 +466,8 @@ static void ali_init_chipset(struct pci_dev *pdev)
 			tmp |= 0x01;	/* CD_ROM enable for DMA */
 		pci_write_config_byte(pdev, 0x53, tmp);
 	}
-	north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+	north = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus), 0,
+					    PCI_DEVFN(0, 0));
 	if (north && north->vendor == PCI_VENDOR_ID_AL && ali_isa_bridge) {
 		/* Configure the ALi bridge logic. For non ALi rely on BIOS.
 		   Set the south bridge enable bit */
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 7280752..f781eff 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -268,17 +268,17 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
   void *AllocationPointer = NULL;
   void *ScatterGatherCPU = NULL;
   dma_addr_t ScatterGatherDMA;
-  struct pci_pool *ScatterGatherPool;
+  struct dma_pool *ScatterGatherPool;
   void *RequestSenseCPU = NULL;
   dma_addr_t RequestSenseDMA;
-  struct pci_pool *RequestSensePool = NULL;
+  struct dma_pool *RequestSensePool = NULL;
 
   if (Controller->FirmwareType == DAC960_V1_Controller)
     {
       CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker);
       CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize;
-      ScatterGatherPool = pci_pool_create("DAC960_V1_ScatterGather",
-		Controller->PCIDevice,
+      ScatterGatherPool = dma_pool_create("DAC960_V1_ScatterGather",
+		&Controller->PCIDevice->dev,
 	DAC960_V1_ScatterGatherLimit * sizeof(DAC960_V1_ScatterGatherSegment_T),
 	sizeof(DAC960_V1_ScatterGatherSegment_T), 0);
       if (ScatterGatherPool == NULL)
@@ -290,18 +290,18 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
     {
       CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker);
       CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize;
-      ScatterGatherPool = pci_pool_create("DAC960_V2_ScatterGather",
-		Controller->PCIDevice,
+      ScatterGatherPool = dma_pool_create("DAC960_V2_ScatterGather",
+		&Controller->PCIDevice->dev,
 	DAC960_V2_ScatterGatherLimit * sizeof(DAC960_V2_ScatterGatherSegment_T),
 	sizeof(DAC960_V2_ScatterGatherSegment_T), 0);
       if (ScatterGatherPool == NULL)
 	    return DAC960_Failure(Controller,
 			"AUXILIARY STRUCTURE CREATION (SG)");
-      RequestSensePool = pci_pool_create("DAC960_V2_RequestSense",
-		Controller->PCIDevice, sizeof(DAC960_SCSI_RequestSense_T),
+      RequestSensePool = dma_pool_create("DAC960_V2_RequestSense",
+		&Controller->PCIDevice->dev, sizeof(DAC960_SCSI_RequestSense_T),
 		sizeof(int), 0);
       if (RequestSensePool == NULL) {
-	    pci_pool_destroy(ScatterGatherPool);
+	    dma_pool_destroy(ScatterGatherPool);
 	    return DAC960_Failure(Controller,
 			"AUXILIARY STRUCTURE CREATION (SG)");
       }
@@ -335,16 +335,16 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
       Command->Next = Controller->FreeCommands;
       Controller->FreeCommands = Command;
       Controller->Commands[CommandIdentifier-1] = Command;
-      ScatterGatherCPU = pci_pool_alloc(ScatterGatherPool, GFP_ATOMIC,
+      ScatterGatherCPU = dma_pool_alloc(ScatterGatherPool, GFP_ATOMIC,
 							&ScatterGatherDMA);
       if (ScatterGatherCPU == NULL)
 	  return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
 
       if (RequestSensePool != NULL) {
-  	  RequestSenseCPU = pci_pool_alloc(RequestSensePool, GFP_ATOMIC,
+	  RequestSenseCPU = dma_pool_alloc(RequestSensePool, GFP_ATOMIC,
 						&RequestSenseDMA);
   	  if (RequestSenseCPU == NULL) {
-                pci_pool_free(ScatterGatherPool, ScatterGatherCPU,
+                dma_pool_free(ScatterGatherPool, ScatterGatherCPU,
                                 ScatterGatherDMA);
     		return DAC960_Failure(Controller,
 					"AUXILIARY STRUCTURE CREATION");
@@ -379,8 +379,8 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
 static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
 {
   int i;
-  struct pci_pool *ScatterGatherPool = Controller->ScatterGatherPool;
-  struct pci_pool *RequestSensePool = NULL;
+  struct dma_pool *ScatterGatherPool = Controller->ScatterGatherPool;
+  struct dma_pool *RequestSensePool = NULL;
   void *ScatterGatherCPU;
   dma_addr_t ScatterGatherDMA;
   void *RequestSenseCPU;
@@ -411,9 +411,9 @@ static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
 	  RequestSenseDMA = Command->V2.RequestSenseDMA;
       }
       if (ScatterGatherCPU != NULL)
-          pci_pool_free(ScatterGatherPool, ScatterGatherCPU, ScatterGatherDMA);
+          dma_pool_free(ScatterGatherPool, ScatterGatherCPU, ScatterGatherDMA);
       if (RequestSenseCPU != NULL)
-          pci_pool_free(RequestSensePool, RequestSenseCPU, RequestSenseDMA);
+          dma_pool_free(RequestSensePool, RequestSenseCPU, RequestSenseDMA);
 
       if ((Command->CommandIdentifier
 	   % Controller->CommandAllocationGroupSize) == 1) {
@@ -437,13 +437,11 @@ static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
       Controller->CurrentStatusBuffer = NULL;
     }
 
-  if (ScatterGatherPool != NULL)
-  	pci_pool_destroy(ScatterGatherPool);
+  dma_pool_destroy(ScatterGatherPool);
   if (Controller->FirmwareType == DAC960_V1_Controller)
   	return;
 
-  if (RequestSensePool != NULL)
-	pci_pool_destroy(RequestSensePool);
+  dma_pool_destroy(RequestSensePool);
 
   for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
 	kfree(Controller->V2.LogicalDeviceInformation[i]);
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index 6a6226a..21aff47 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -2316,7 +2316,7 @@ typedef struct DAC960_Controller
   bool SuppressEnclosureMessages;
   struct timer_list MonitoringTimer;
   struct gendisk *disks[DAC960_MaxLogicalDrives];
-  struct pci_pool *ScatterGatherPool;
+  struct dma_pool *ScatterGatherPool;
   DAC960_Command_T *FreeCommands;
   unsigned char *CombinedStatusBuffer;
   unsigned char *CurrentStatusBuffer;
@@ -2429,7 +2429,7 @@ typedef struct DAC960_Controller
       bool NeedDeviceSerialNumberInformation;
       bool StartLogicalDeviceInformationScan;
       bool StartPhysicalDeviceInformationScan;
-      struct pci_pool *RequestSensePool;
+      struct dma_pool *RequestSensePool;
 
       dma_addr_t	FirstCommandMailboxDMA;
       DAC960_V2_CommandMailbox_T *FirstCommandMailbox;
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index cc93522..8e40da0 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -124,11 +124,13 @@ static int atomic_dec_return_safe(atomic_t *v)
 #define RBD_FEATURE_STRIPINGV2		(1ULL<<1)
 #define RBD_FEATURE_EXCLUSIVE_LOCK	(1ULL<<2)
 #define RBD_FEATURE_DATA_POOL		(1ULL<<7)
+#define RBD_FEATURE_OPERATIONS		(1ULL<<8)
 
 #define RBD_FEATURES_ALL	(RBD_FEATURE_LAYERING |		\
 				 RBD_FEATURE_STRIPINGV2 |	\
 				 RBD_FEATURE_EXCLUSIVE_LOCK |	\
-				 RBD_FEATURE_DATA_POOL)
+				 RBD_FEATURE_DATA_POOL |	\
+				 RBD_FEATURE_OPERATIONS)
 
 /* Features supported by this (client software) implementation. */
 
@@ -281,7 +283,6 @@ struct rbd_obj_request {
 	int			result;
 
 	rbd_obj_callback_t	callback;
-	struct completion	completion;
 
 	struct kref		kref;
 };
@@ -1734,10 +1735,7 @@ static void rbd_obj_request_complete(struct rbd_obj_request *obj_request)
 {
 	dout("%s: obj %p cb %p\n", __func__, obj_request,
 		obj_request->callback);
-	if (obj_request->callback)
-		obj_request->callback(obj_request);
-	else
-		complete_all(&obj_request->completion);
+	obj_request->callback(obj_request);
 }
 
 static void rbd_obj_request_error(struct rbd_obj_request *obj_request, int err)
@@ -2013,7 +2011,6 @@ rbd_obj_request_create(enum obj_request_type type)
 	obj_request->which = BAD_WHICH;
 	obj_request->type = type;
 	INIT_LIST_HEAD(&obj_request->links);
-	init_completion(&obj_request->completion);
 	kref_init(&obj_request->kref);
 
 	dout("%s %p\n", __func__, obj_request);
@@ -2129,15 +2126,13 @@ static struct rbd_img_request *rbd_img_request_create(
 {
 	struct rbd_img_request *img_request;
 
-	img_request = kmem_cache_alloc(rbd_img_request_cache, GFP_NOIO);
+	img_request = kmem_cache_zalloc(rbd_img_request_cache, GFP_NOIO);
 	if (!img_request)
 		return NULL;
 
-	img_request->rq = NULL;
 	img_request->rbd_dev = rbd_dev;
 	img_request->offset = offset;
 	img_request->length = length;
-	img_request->flags = 0;
 	if (op_type == OBJ_OP_DISCARD) {
 		img_request_discard_set(img_request);
 		img_request->snapc = snapc;
@@ -2149,11 +2144,8 @@ static struct rbd_img_request *rbd_img_request_create(
 	}
 	if (rbd_dev_parent_get(rbd_dev))
 		img_request_layered_set(img_request);
+
 	spin_lock_init(&img_request->completion_lock);
-	img_request->next_completion = 0;
-	img_request->callback = NULL;
-	img_request->result = 0;
-	img_request->obj_request_count = 0;
 	INIT_LIST_HEAD(&img_request->obj_requests);
 	kref_init(&img_request->kref);
 
@@ -2692,8 +2684,6 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request)
 
 	parent_request->copyup_pages = NULL;
 	parent_request->copyup_page_count = 0;
-	parent_request->obj_request = NULL;
-	rbd_obj_request_put(obj_request);
 out_err:
 	if (pages)
 		ceph_release_page_vector(pages, page_count);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 79908e6..4a07593c 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -373,14 +373,12 @@ static ssize_t virtblk_serial_show(struct device *dev,
 
 static DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL);
 
-static void virtblk_config_changed_work(struct work_struct *work)
+/* The queue's logical block size must be set before calling this */
+static void virtblk_update_capacity(struct virtio_blk *vblk, bool resize)
 {
-	struct virtio_blk *vblk =
-		container_of(work, struct virtio_blk, config_work);
 	struct virtio_device *vdev = vblk->vdev;
 	struct request_queue *q = vblk->disk->queue;
 	char cap_str_2[10], cap_str_10[10];
-	char *envp[] = { "RESIZE=1", NULL };
 	unsigned long long nblocks;
 	u64 capacity;
 
@@ -402,13 +400,24 @@ static void virtblk_config_changed_work(struct work_struct *work)
 			STRING_UNITS_10, cap_str_10, sizeof(cap_str_10));
 
 	dev_notice(&vdev->dev,
-		   "new size: %llu %d-byte logical blocks (%s/%s)\n",
+		   "[%s] %s%llu %d-byte logical blocks (%s/%s)\n",
+		   vblk->disk->disk_name,
+		   resize ? "new size: " : "",
 		   nblocks,
 		   queue_logical_block_size(q),
 		   cap_str_10,
 		   cap_str_2);
 
 	set_capacity(vblk->disk, capacity);
+}
+
+static void virtblk_config_changed_work(struct work_struct *work)
+{
+	struct virtio_blk *vblk =
+		container_of(work, struct virtio_blk, config_work);
+	char *envp[] = { "RESIZE=1", NULL };
+
+	virtblk_update_capacity(vblk, true);
 	revalidate_disk(vblk->disk);
 	kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp);
 }
@@ -621,7 +630,6 @@ static int virtblk_probe(struct virtio_device *vdev)
 	struct request_queue *q;
 	int err, index;
 
-	u64 cap;
 	u32 v, blk_size, sg_elems, opt_io_size;
 	u16 min_io_size;
 	u8 physical_block_exp, alignment_offset;
@@ -719,17 +727,6 @@ static int virtblk_probe(struct virtio_device *vdev)
 	if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO))
 		set_disk_ro(vblk->disk, 1);
 
-	/* Host must always specify the capacity. */
-	virtio_cread(vdev, struct virtio_blk_config, capacity, &cap);
-
-	/* If capacity is too big, truncate with warning. */
-	if ((sector_t)cap != cap) {
-		dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n",
-			 (unsigned long long)cap);
-		cap = (sector_t)-1;
-	}
-	set_capacity(vblk->disk, cap);
-
 	/* We can handle whatever the host told us to handle. */
 	blk_queue_max_segments(q, vblk->sg_elems-2);
 
@@ -780,6 +777,7 @@ static int virtblk_probe(struct virtio_device *vdev)
 	if (!err && opt_io_size)
 		blk_queue_io_opt(q, blk_size * opt_io_size);
 
+	virtblk_update_capacity(vblk, false);
 	virtio_device_ready(vdev);
 
 	device_add_disk(&vdev->dev, vblk->disk);
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 828b344..623205b 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -340,11 +340,17 @@ static int agp_nvidia_probe(struct pci_dev *pdev,
 	u8 cap_ptr;
 
 	nvidia_private.dev_1 =
-		pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1));
+		pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
+					    (unsigned int)pdev->bus->number,
+					    PCI_DEVFN(0, 1));
 	nvidia_private.dev_2 =
-		pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2));
+		pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
+					    (unsigned int)pdev->bus->number,
+					    PCI_DEVFN(0, 2));
 	nvidia_private.dev_3 =
-		pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0));
+		pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
+					    (unsigned int)pdev->bus->number,
+					    PCI_DEVFN(30, 0));
 
 	if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) {
 		printk(KERN_INFO PFX "Detected an NVIDIA nForce/nForce2 "
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 03be4ac..4dbdd3b 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -474,7 +474,8 @@ static int agp_serverworks_probe(struct pci_dev *pdev,
 	}
 
 	/* Everything is on func 1 here so we are hardcoding function one */
-	bridge_dev = pci_get_bus_and_slot((unsigned int)pdev->bus->number,
+	bridge_dev = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
+			(unsigned int)pdev->bus->number,
 			PCI_DEVFN(0, 1));
 	if (!bridge_dev) {
 		dev_info(&pdev->dev, "can't find secondary device\n");
diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile
index cd47b06..1456e4c 100644
--- a/drivers/clk/ingenic/Makefile
+++ b/drivers/clk/ingenic/Makefile
@@ -1,3 +1,4 @@
 obj-y				+= cgu.o
 obj-$(CONFIG_MACH_JZ4740)	+= jz4740-cgu.o
+obj-$(CONFIG_MACH_JZ4770)	+= jz4770-cgu.o
 obj-$(CONFIG_MACH_JZ4780)	+= jz4780-cgu.o
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index ab39363..56a712c 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -100,15 +100,13 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 	n += pll_info->n_offset;
 	od_enc = ctl >> pll_info->od_shift;
 	od_enc &= GENMASK(pll_info->od_bits - 1, 0);
-	bypass = !!(ctl & BIT(pll_info->bypass_bit));
+	bypass = !pll_info->no_bypass_bit &&
+		 !!(ctl & BIT(pll_info->bypass_bit));
 	enable = !!(ctl & BIT(pll_info->enable_bit));
 
 	if (bypass)
 		return parent_rate;
 
-	if (!enable)
-		return 0;
-
 	for (od = 0; od < pll_info->od_max; od++) {
 		if (pll_info->od_encoding[od] == od_enc)
 			break;
@@ -152,17 +150,25 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
 	return div_u64((u64)parent_rate * m, n * od);
 }
 
-static long
-ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
-		       unsigned long *prate)
+static inline const struct ingenic_cgu_clk_info *to_clk_info(
+		struct ingenic_clk *ingenic_clk)
 {
-	struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
 	struct ingenic_cgu *cgu = ingenic_clk->cgu;
 	const struct ingenic_cgu_clk_info *clk_info;
 
 	clk_info = &cgu->clock_info[ingenic_clk->idx];
 	BUG_ON(clk_info->type != CGU_CLK_PLL);
 
+	return clk_info;
+}
+
+static long
+ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
+		       unsigned long *prate)
+{
+	struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+	const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
+
 	return ingenic_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL);
 }
 
@@ -170,19 +176,14 @@ static int
 ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
 		     unsigned long parent_rate)
 {
-	const unsigned timeout = 100;
 	struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
 	struct ingenic_cgu *cgu = ingenic_clk->cgu;
-	const struct ingenic_cgu_clk_info *clk_info;
-	const struct ingenic_cgu_pll_info *pll_info;
+	const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
+	const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
 	unsigned long rate, flags;
-	unsigned m, n, od, i;
+	unsigned int m, n, od;
 	u32 ctl;
 
-	clk_info = &cgu->clock_info[ingenic_clk->idx];
-	BUG_ON(clk_info->type != CGU_CLK_PLL);
-	pll_info = &clk_info->pll;
-
 	rate = ingenic_pll_calc(clk_info, req_rate, parent_rate,
 			       &m, &n, &od);
 	if (rate != req_rate)
@@ -201,6 +202,26 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
 	ctl &= ~(GENMASK(pll_info->od_bits - 1, 0) << pll_info->od_shift);
 	ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift;
 
+	writel(ctl, cgu->base + pll_info->reg);
+	spin_unlock_irqrestore(&cgu->lock, flags);
+
+	return 0;
+}
+
+static int ingenic_pll_enable(struct clk_hw *hw)
+{
+	struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+	struct ingenic_cgu *cgu = ingenic_clk->cgu;
+	const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
+	const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
+	const unsigned int timeout = 100;
+	unsigned long flags;
+	unsigned int i;
+	u32 ctl;
+
+	spin_lock_irqsave(&cgu->lock, flags);
+	ctl = readl(cgu->base + pll_info->reg);
+
 	ctl &= ~BIT(pll_info->bypass_bit);
 	ctl |= BIT(pll_info->enable_bit);
 
@@ -222,10 +243,48 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
 	return 0;
 }
 
+static void ingenic_pll_disable(struct clk_hw *hw)
+{
+	struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+	struct ingenic_cgu *cgu = ingenic_clk->cgu;
+	const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
+	const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
+	unsigned long flags;
+	u32 ctl;
+
+	spin_lock_irqsave(&cgu->lock, flags);
+	ctl = readl(cgu->base + pll_info->reg);
+
+	ctl &= ~BIT(pll_info->enable_bit);
+
+	writel(ctl, cgu->base + pll_info->reg);
+	spin_unlock_irqrestore(&cgu->lock, flags);
+}
+
+static int ingenic_pll_is_enabled(struct clk_hw *hw)
+{
+	struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+	struct ingenic_cgu *cgu = ingenic_clk->cgu;
+	const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
+	const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
+	unsigned long flags;
+	u32 ctl;
+
+	spin_lock_irqsave(&cgu->lock, flags);
+	ctl = readl(cgu->base + pll_info->reg);
+	spin_unlock_irqrestore(&cgu->lock, flags);
+
+	return !!(ctl & BIT(pll_info->enable_bit));
+}
+
 static const struct clk_ops ingenic_pll_ops = {
 	.recalc_rate = ingenic_pll_recalc_rate,
 	.round_rate = ingenic_pll_round_rate,
 	.set_rate = ingenic_pll_set_rate,
+
+	.enable = ingenic_pll_enable,
+	.disable = ingenic_pll_disable,
+	.is_enabled = ingenic_pll_is_enabled,
 };
 
 /*
@@ -328,6 +387,8 @@ ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 		div *= clk_info->div.div;
 
 		rate /= div;
+	} else if (clk_info->type & CGU_CLK_FIXDIV) {
+		rate /= clk_info->fixdiv.div;
 	}
 
 	return rate;
@@ -598,6 +659,7 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
 		}
 	} else if (caps & CGU_CLK_PLL) {
 		clk_init.ops = &ingenic_pll_ops;
+		clk_init.flags |= CLK_SET_RATE_GATE;
 
 		caps &= ~CGU_CLK_PLL;
 
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
index e78b586..9da3491 100644
--- a/drivers/clk/ingenic/cgu.h
+++ b/drivers/clk/ingenic/cgu.h
@@ -48,6 +48,7 @@
  * @bypass_bit: the index of the bypass bit in the PLL control register
  * @enable_bit: the index of the enable bit in the PLL control register
  * @stable_bit: the index of the stable bit in the PLL control register
+ * @no_bypass_bit: if set, the PLL has no bypass functionality
  */
 struct ingenic_cgu_pll_info {
 	unsigned reg;
@@ -58,6 +59,7 @@ struct ingenic_cgu_pll_info {
 	u8 bypass_bit;
 	u8 enable_bit;
 	u8 stable_bit;
+	bool no_bypass_bit;
 };
 
 /**
@@ -120,7 +122,7 @@ struct ingenic_cgu_gate_info {
  * @clk_ops: custom clock operation callbacks
  */
 struct ingenic_cgu_custom_info {
-	struct clk_ops *clk_ops;
+	const struct clk_ops *clk_ops;
 };
 
 /**
diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c
new file mode 100644
index 0000000..c78d369
--- /dev/null
+++ b/drivers/clk/ingenic/jz4770-cgu.c
@@ -0,0 +1,483 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * JZ4770 SoC CGU driver
+ * Copyright 2018, Paul Cercueil <paul@crapouillou.net>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/jz4770-cgu.h>
+#include "cgu.h"
+
+/*
+ * CPM registers offset address definition
+ */
+#define CGU_REG_CPCCR		0x00
+#define CGU_REG_LCR		0x04
+#define CGU_REG_CPPCR0		0x10
+#define CGU_REG_CLKGR0		0x20
+#define CGU_REG_OPCR		0x24
+#define CGU_REG_CLKGR1		0x28
+#define CGU_REG_CPPCR1		0x30
+#define CGU_REG_USBPCR1		0x48
+#define CGU_REG_USBCDR		0x50
+#define CGU_REG_I2SCDR		0x60
+#define CGU_REG_LPCDR		0x64
+#define CGU_REG_MSC0CDR		0x68
+#define CGU_REG_UHCCDR		0x6c
+#define CGU_REG_SSICDR		0x74
+#define CGU_REG_CIMCDR		0x7c
+#define CGU_REG_GPSCDR		0x80
+#define CGU_REG_PCMCDR		0x84
+#define CGU_REG_GPUCDR		0x88
+#define CGU_REG_MSC1CDR		0xA4
+#define CGU_REG_MSC2CDR		0xA8
+#define CGU_REG_BCHCDR		0xAC
+
+/* bits within the LCR register */
+#define LCR_LPM			BIT(0)		/* Low Power Mode */
+
+/* bits within the OPCR register */
+#define OPCR_SPENDH		BIT(5)		/* UHC PHY suspend */
+#define OPCR_SPENDN		BIT(7)		/* OTG PHY suspend */
+
+/* bits within the USBPCR1 register */
+#define USBPCR1_UHC_POWER	BIT(5)		/* UHC PHY power down */
+
+static struct ingenic_cgu *cgu;
+
+static int jz4770_uhc_phy_enable(struct clk_hw *hw)
+{
+	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
+	void __iomem *reg_usbpcr1	= cgu->base + CGU_REG_USBPCR1;
+
+	writel(readl(reg_opcr) & ~OPCR_SPENDH, reg_opcr);
+	writel(readl(reg_usbpcr1) | USBPCR1_UHC_POWER, reg_usbpcr1);
+	return 0;
+}
+
+static void jz4770_uhc_phy_disable(struct clk_hw *hw)
+{
+	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
+	void __iomem *reg_usbpcr1	= cgu->base + CGU_REG_USBPCR1;
+
+	writel(readl(reg_usbpcr1) & ~USBPCR1_UHC_POWER, reg_usbpcr1);
+	writel(readl(reg_opcr) | OPCR_SPENDH, reg_opcr);
+}
+
+static int jz4770_uhc_phy_is_enabled(struct clk_hw *hw)
+{
+	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
+	void __iomem *reg_usbpcr1	= cgu->base + CGU_REG_USBPCR1;
+
+	return !(readl(reg_opcr) & OPCR_SPENDH) &&
+		(readl(reg_usbpcr1) & USBPCR1_UHC_POWER);
+}
+
+static const struct clk_ops jz4770_uhc_phy_ops = {
+	.enable = jz4770_uhc_phy_enable,
+	.disable = jz4770_uhc_phy_disable,
+	.is_enabled = jz4770_uhc_phy_is_enabled,
+};
+
+static int jz4770_otg_phy_enable(struct clk_hw *hw)
+{
+	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
+
+	writel(readl(reg_opcr) | OPCR_SPENDN, reg_opcr);
+
+	/* Wait for the clock to be stable */
+	udelay(50);
+	return 0;
+}
+
+static void jz4770_otg_phy_disable(struct clk_hw *hw)
+{
+	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
+
+	writel(readl(reg_opcr) & ~OPCR_SPENDN, reg_opcr);
+}
+
+static int jz4770_otg_phy_is_enabled(struct clk_hw *hw)
+{
+	void __iomem *reg_opcr		= cgu->base + CGU_REG_OPCR;
+
+	return !!(readl(reg_opcr) & OPCR_SPENDN);
+}
+
+static const struct clk_ops jz4770_otg_phy_ops = {
+	.enable = jz4770_otg_phy_enable,
+	.disable = jz4770_otg_phy_disable,
+	.is_enabled = jz4770_otg_phy_is_enabled,
+};
+
+static const s8 pll_od_encoding[8] = {
+	0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
+};
+
+static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
+
+	/* External clocks */
+
+	[JZ4770_CLK_EXT] = { "ext", CGU_CLK_EXT },
+	[JZ4770_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT },
+
+	/* PLLs */
+
+	[JZ4770_CLK_PLL0] = {
+		"pll0", CGU_CLK_PLL,
+		.parents = { JZ4770_CLK_EXT },
+		.pll = {
+			.reg = CGU_REG_CPPCR0,
+			.m_shift = 24,
+			.m_bits = 7,
+			.m_offset = 1,
+			.n_shift = 18,
+			.n_bits = 5,
+			.n_offset = 1,
+			.od_shift = 16,
+			.od_bits = 2,
+			.od_max = 8,
+			.od_encoding = pll_od_encoding,
+			.bypass_bit = 9,
+			.enable_bit = 8,
+			.stable_bit = 10,
+		},
+	},
+
+	[JZ4770_CLK_PLL1] = {
+		/* TODO: PLL1 can depend on PLL0 */
+		"pll1", CGU_CLK_PLL,
+		.parents = { JZ4770_CLK_EXT },
+		.pll = {
+			.reg = CGU_REG_CPPCR1,
+			.m_shift = 24,
+			.m_bits = 7,
+			.m_offset = 1,
+			.n_shift = 18,
+			.n_bits = 5,
+			.n_offset = 1,
+			.od_shift = 16,
+			.od_bits = 2,
+			.od_max = 8,
+			.od_encoding = pll_od_encoding,
+			.enable_bit = 7,
+			.stable_bit = 6,
+			.no_bypass_bit = true,
+		},
+	},
+
+	/* Main clocks */
+
+	[JZ4770_CLK_CCLK] = {
+		"cclk", CGU_CLK_DIV,
+		.parents = { JZ4770_CLK_PLL0, },
+		.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
+	},
+	[JZ4770_CLK_H0CLK] = {
+		"h0clk", CGU_CLK_DIV,
+		.parents = { JZ4770_CLK_PLL0, },
+		.div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
+	},
+	[JZ4770_CLK_H1CLK] = {
+		"h1clk", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_PLL0, },
+		.div = { CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1 },
+		.gate = { CGU_REG_LCR, 30 },
+	},
+	[JZ4770_CLK_H2CLK] = {
+		"h2clk", CGU_CLK_DIV,
+		.parents = { JZ4770_CLK_PLL0, },
+		.div = { CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1 },
+	},
+	[JZ4770_CLK_C1CLK] = {
+		"c1clk", CGU_CLK_DIV,
+		.parents = { JZ4770_CLK_PLL0, },
+		.div = { CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1 },
+	},
+	[JZ4770_CLK_PCLK] = {
+		"pclk", CGU_CLK_DIV,
+		.parents = { JZ4770_CLK_PLL0, },
+		.div = { CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1 },
+	},
+
+	/* Those divided clocks can connect to PLL0 or PLL1 */
+
+	[JZ4770_CLK_MMC0_MUX] = {
+		"mmc0_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+		.mux = { CGU_REG_MSC0CDR, 30, 1 },
+		.div = { CGU_REG_MSC0CDR, 0, 1, 7, -1, -1, 31 },
+		.gate = { CGU_REG_MSC0CDR, 31 },
+	},
+	[JZ4770_CLK_MMC1_MUX] = {
+		"mmc1_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+		.mux = { CGU_REG_MSC1CDR, 30, 1 },
+		.div = { CGU_REG_MSC1CDR, 0, 1, 7, -1, -1, 31 },
+		.gate = { CGU_REG_MSC1CDR, 31 },
+	},
+	[JZ4770_CLK_MMC2_MUX] = {
+		"mmc2_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+		.mux = { CGU_REG_MSC2CDR, 30, 1 },
+		.div = { CGU_REG_MSC2CDR, 0, 1, 7, -1, -1, 31 },
+		.gate = { CGU_REG_MSC2CDR, 31 },
+	},
+	[JZ4770_CLK_CIM] = {
+		"cim", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+		.mux = { CGU_REG_CIMCDR, 31, 1 },
+		.div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR0, 26 },
+	},
+	[JZ4770_CLK_UHC] = {
+		"uhc", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+		.mux = { CGU_REG_UHCCDR, 29, 1 },
+		.div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR0, 24 },
+	},
+	[JZ4770_CLK_GPU] = {
+		"gpu", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, -1 },
+		.mux = { CGU_REG_GPUCDR, 31, 1 },
+		.div = { CGU_REG_GPUCDR, 0, 1, 3, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR1, 9 },
+	},
+	[JZ4770_CLK_BCH] = {
+		"bch", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+		.mux = { CGU_REG_BCHCDR, 31, 1 },
+		.div = { CGU_REG_BCHCDR, 0, 1, 3, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR0, 1 },
+	},
+	[JZ4770_CLK_LPCLK_MUX] = {
+		"lpclk", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+		.mux = { CGU_REG_LPCDR, 29, 1 },
+		.div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR0, 28 },
+	},
+	[JZ4770_CLK_GPS] = {
+		"gps", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+		.mux = { CGU_REG_GPSCDR, 31, 1 },
+		.div = { CGU_REG_GPSCDR, 0, 1, 4, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR0, 22 },
+	},
+
+	/* Those divided clocks can connect to EXT, PLL0 or PLL1 */
+
+	[JZ4770_CLK_SSI_MUX] = {
+		"ssi_mux", CGU_CLK_DIV | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_EXT, -1,
+			JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 },
+		.mux = { CGU_REG_SSICDR, 30, 2 },
+		.div = { CGU_REG_SSICDR, 0, 1, 6, -1, -1, -1 },
+	},
+	[JZ4770_CLK_PCM_MUX] = {
+		"pcm_mux", CGU_CLK_DIV | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_EXT, -1,
+			JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 },
+		.mux = { CGU_REG_PCMCDR, 30, 2 },
+		.div = { CGU_REG_PCMCDR, 0, 1, 9, -1, -1, -1 },
+	},
+	[JZ4770_CLK_I2S] = {
+		"i2s", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_EXT, -1,
+			JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 },
+		.mux = { CGU_REG_I2SCDR, 30, 2 },
+		.div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR1, 13 },
+	},
+	[JZ4770_CLK_OTG] = {
+		"usb", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_EXT, -1,
+			JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 },
+		.mux = { CGU_REG_USBCDR, 30, 2 },
+		.div = { CGU_REG_USBCDR, 0, 1, 8, -1, -1, -1 },
+		.gate = { CGU_REG_CLKGR0, 2 },
+	},
+
+	/* Gate-only clocks */
+
+	[JZ4770_CLK_SSI0] = {
+		"ssi0", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_SSI_MUX, },
+		.gate = { CGU_REG_CLKGR0, 4 },
+	},
+	[JZ4770_CLK_SSI1] = {
+		"ssi1", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_SSI_MUX, },
+		.gate = { CGU_REG_CLKGR0, 19 },
+	},
+	[JZ4770_CLK_SSI2] = {
+		"ssi2", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_SSI_MUX, },
+		.gate = { CGU_REG_CLKGR0, 20 },
+	},
+	[JZ4770_CLK_PCM0] = {
+		"pcm0", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_PCM_MUX, },
+		.gate = { CGU_REG_CLKGR1, 8 },
+	},
+	[JZ4770_CLK_PCM1] = {
+		"pcm1", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_PCM_MUX, },
+		.gate = { CGU_REG_CLKGR1, 10 },
+	},
+	[JZ4770_CLK_DMA] = {
+		"dma", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_H2CLK, },
+		.gate = { CGU_REG_CLKGR0, 21 },
+	},
+	[JZ4770_CLK_I2C0] = {
+		"i2c0", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 5 },
+	},
+	[JZ4770_CLK_I2C1] = {
+		"i2c1", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 6 },
+	},
+	[JZ4770_CLK_I2C2] = {
+		"i2c2", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR1, 15 },
+	},
+	[JZ4770_CLK_UART0] = {
+		"uart0", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 15 },
+	},
+	[JZ4770_CLK_UART1] = {
+		"uart1", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 16 },
+	},
+	[JZ4770_CLK_UART2] = {
+		"uart2", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 17 },
+	},
+	[JZ4770_CLK_UART3] = {
+		"uart3", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 18 },
+	},
+	[JZ4770_CLK_IPU] = {
+		"ipu", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_H0CLK, },
+		.gate = { CGU_REG_CLKGR0, 29 },
+	},
+	[JZ4770_CLK_ADC] = {
+		"adc", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 14 },
+	},
+	[JZ4770_CLK_AIC] = {
+		"aic", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_EXT, },
+		.gate = { CGU_REG_CLKGR0, 8 },
+	},
+	[JZ4770_CLK_AUX] = {
+		"aux", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_C1CLK, },
+		.gate = { CGU_REG_CLKGR1, 14 },
+	},
+	[JZ4770_CLK_VPU] = {
+		"vpu", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_H1CLK, },
+		.gate = { CGU_REG_CLKGR1, 7 },
+	},
+	[JZ4770_CLK_MMC0] = {
+		"mmc0", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_MMC0_MUX, },
+		.gate = { CGU_REG_CLKGR0, 3 },
+	},
+	[JZ4770_CLK_MMC1] = {
+		"mmc1", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_MMC1_MUX, },
+		.gate = { CGU_REG_CLKGR0, 11 },
+	},
+	[JZ4770_CLK_MMC2] = {
+		"mmc2", CGU_CLK_GATE,
+		.parents = { JZ4770_CLK_MMC2_MUX, },
+		.gate = { CGU_REG_CLKGR0, 12 },
+	},
+
+	/* Custom clocks */
+
+	[JZ4770_CLK_UHC_PHY] = {
+		"uhc_phy", CGU_CLK_CUSTOM,
+		.parents = { JZ4770_CLK_UHC, -1, -1, -1 },
+		.custom = { &jz4770_uhc_phy_ops },
+	},
+	[JZ4770_CLK_OTG_PHY] = {
+		"usb_phy", CGU_CLK_CUSTOM,
+		.parents = { JZ4770_CLK_OTG, -1, -1, -1 },
+		.custom = { &jz4770_otg_phy_ops },
+	},
+
+	[JZ4770_CLK_EXT512] = {
+		"ext/512", CGU_CLK_FIXDIV,
+		.parents = { JZ4770_CLK_EXT },
+		.fixdiv = { 512 },
+	},
+
+	[JZ4770_CLK_RTC] = {
+		"rtc", CGU_CLK_MUX,
+		.parents = { JZ4770_CLK_EXT512, JZ4770_CLK_OSC32K, },
+		.mux = { CGU_REG_OPCR, 2, 1},
+	},
+};
+
+#if IS_ENABLED(CONFIG_PM_SLEEP)
+static int jz4770_cgu_pm_suspend(void)
+{
+	u32 val;
+
+	val = readl(cgu->base + CGU_REG_LCR);
+	writel(val | LCR_LPM, cgu->base + CGU_REG_LCR);
+	return 0;
+}
+
+static void jz4770_cgu_pm_resume(void)
+{
+	u32 val;
+
+	val = readl(cgu->base + CGU_REG_LCR);
+	writel(val & ~LCR_LPM, cgu->base + CGU_REG_LCR);
+}
+
+static struct syscore_ops jz4770_cgu_pm_ops = {
+	.suspend = jz4770_cgu_pm_suspend,
+	.resume = jz4770_cgu_pm_resume,
+};
+#endif /* CONFIG_PM_SLEEP */
+
+static void __init jz4770_cgu_init(struct device_node *np)
+{
+	int retval;
+
+	cgu = ingenic_cgu_new(jz4770_cgu_clocks,
+			      ARRAY_SIZE(jz4770_cgu_clocks), np);
+	if (!cgu)
+		pr_err("%s: failed to initialise CGU\n", __func__);
+
+	retval = ingenic_cgu_register_clocks(cgu);
+	if (retval)
+		pr_err("%s: failed to register CGU Clocks\n", __func__);
+
+#if IS_ENABLED(CONFIG_PM_SLEEP)
+	register_syscore_ops(&jz4770_cgu_pm_ops);
+#endif
+}
+
+/* We only probe via devicetree, no need for a platform driver */
+CLK_OF_DECLARE(jz4770_cgu, "ingenic,jz4770-cgu", jz4770_cgu_init);
diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c
index ac3585e..6427be1 100644
--- a/drivers/clk/ingenic/jz4780-cgu.c
+++ b/drivers/clk/ingenic/jz4780-cgu.c
@@ -203,7 +203,7 @@ static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate,
 	return 0;
 }
 
-static struct clk_ops jz4780_otg_phy_ops = {
+static const struct clk_ops jz4780_otg_phy_ops = {
 	.get_parent = jz4780_otg_phy_get_parent,
 	.set_parent = jz4780_otg_phy_set_parent,
 
diff --git a/drivers/dax/device.c b/drivers/dax/device.c
index 7b0bf82..2137dbc 100644
--- a/drivers/dax/device.c
+++ b/drivers/dax/device.c
@@ -133,7 +133,7 @@ struct dax_region *alloc_dax_region(struct device *parent, int region_id,
 	dax_region->base = addr;
 	if (sysfs_create_groups(&parent->kobj, dax_region_attribute_groups)) {
 		kfree(dax_region);
-		return NULL;;
+		return NULL;
 	}
 
 	kref_get(&dax_region->kref);
diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
index 8d8c852..31b6ecc 100644
--- a/drivers/dax/pmem.c
+++ b/drivers/dax/pmem.c
@@ -21,6 +21,7 @@
 struct dax_pmem {
 	struct device *dev;
 	struct percpu_ref ref;
+	struct dev_pagemap pgmap;
 	struct completion cmp;
 };
 
@@ -69,20 +70,23 @@ static int dax_pmem_probe(struct device *dev)
 	struct nd_namespace_common *ndns;
 	struct nd_dax *nd_dax = to_nd_dax(dev);
 	struct nd_pfn *nd_pfn = &nd_dax->nd_pfn;
-	struct vmem_altmap __altmap, *altmap = NULL;
 
 	ndns = nvdimm_namespace_common_probe(dev);
 	if (IS_ERR(ndns))
 		return PTR_ERR(ndns);
 	nsio = to_nd_namespace_io(&ndns->dev);
 
+	dax_pmem = devm_kzalloc(dev, sizeof(*dax_pmem), GFP_KERNEL);
+	if (!dax_pmem)
+		return -ENOMEM;
+
 	/* parse the 'pfn' info block via ->rw_bytes */
 	rc = devm_nsio_enable(dev, nsio);
 	if (rc)
 		return rc;
-	altmap = nvdimm_setup_pfn(nd_pfn, &res, &__altmap);
-	if (IS_ERR(altmap))
-		return PTR_ERR(altmap);
+	rc = nvdimm_setup_pfn(nd_pfn, &dax_pmem->pgmap);
+	if (rc)
+		return rc;
 	devm_nsio_disable(dev, nsio);
 
 	pfn_sb = nd_pfn->pfn_sb;
@@ -94,10 +98,6 @@ static int dax_pmem_probe(struct device *dev)
 		return -EBUSY;
 	}
 
-	dax_pmem = devm_kzalloc(dev, sizeof(*dax_pmem), GFP_KERNEL);
-	if (!dax_pmem)
-		return -ENOMEM;
-
 	dax_pmem->dev = dev;
 	init_completion(&dax_pmem->cmp);
 	rc = percpu_ref_init(&dax_pmem->ref, dax_pmem_percpu_release, 0,
@@ -110,7 +110,8 @@ static int dax_pmem_probe(struct device *dev)
 	if (rc)
 		return rc;
 
-	addr = devm_memremap_pages(dev, &res, &dax_pmem->ref, altmap);
+	dax_pmem->pgmap.ref = &dax_pmem->ref;
+	addr = devm_memremap_pages(dev, &dax_pmem->pgmap);
 	if (IS_ERR(addr))
 		return PTR_ERR(addr);
 
@@ -120,6 +121,7 @@ static int dax_pmem_probe(struct device *dev)
 		return rc;
 
 	/* adjust the dax_region resource to the start of data */
+	memcpy(&res, &dax_pmem->pgmap.res, sizeof(res));
 	res.start += le64_to_cpu(pfn_sb->dataoff);
 
 	rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", &region_id, &id);
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 3ec8046..473af69 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -15,6 +15,7 @@
 #include <linux/mount.h>
 #include <linux/magic.h>
 #include <linux/genhd.h>
+#include <linux/pfn_t.h>
 #include <linux/cdev.h>
 #include <linux/hash.h>
 #include <linux/slab.h>
@@ -123,6 +124,15 @@ int __bdev_dax_supported(struct super_block *sb, int blocksize)
 		return len < 0 ? len : -EIO;
 	}
 
+	if ((IS_ENABLED(CONFIG_FS_DAX_LIMITED) && pfn_t_special(pfn))
+			|| pfn_t_devmap(pfn))
+		/* pass */;
+	else {
+		pr_debug("VFS (%s): error: dax support not enabled\n",
+				sb->s_id);
+		return -EOPNOTSUPP;
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(__bdev_dax_supported);
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index e229576..60a8f13 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -669,10 +669,10 @@ edd_get_pci_dev(struct edd_device *edev)
 	struct edd_info *info = edd_dev_get_info(edev);
 
 	if (edd_dev_is_type(edev, "PCI") || edd_dev_is_type(edev, "XPRS")) {
-		return pci_get_bus_and_slot(info->params.interface_path.pci.bus,
-				     PCI_DEVFN(info->params.interface_path.pci.slot,
-					       info->params.interface_path.pci.
-					       function));
+		return pci_get_domain_bus_and_slot(0,
+				info->params.interface_path.pci.bus,
+				PCI_DEVFN(info->params.interface_path.pci.slot,
+				info->params.interface_path.pci.function));
 	}
 	return NULL;
 }
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index 14042a6..6bc8e66 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -719,8 +719,9 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header,
 		* executes only devices which are in domain 0. Furthermore, the
 		* iBFT spec doesn't have a domain id field :-(
 		*/
-		pci_dev = pci_get_bus_and_slot((nic->pci_bdf & 0xff00) >> 8,
-					       (nic->pci_bdf & 0xff));
+		pci_dev = pci_get_domain_bus_and_slot(0,
+						(nic->pci_bdf & 0xff00) >> 8,
+						(nic->pci_bdf & 0xff));
 		if (pci_dev) {
 			rc = sysfs_create_link(&boot_kobj->kobj,
 					       &pci_dev->dev.kobj, "device");
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index 8b25d31..c80ec1d 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -59,7 +59,10 @@ bool psci_tos_resident_on(int cpu)
 	return cpu == resident_cpu;
 }
 
-struct psci_operations psci_ops;
+struct psci_operations psci_ops = {
+	.conduit = PSCI_CONDUIT_NONE,
+	.smccc_version = SMCCC_VERSION_1_0,
+};
 
 typedef unsigned long (psci_fn)(unsigned long, unsigned long,
 				unsigned long, unsigned long);
@@ -210,6 +213,22 @@ static unsigned long psci_migrate_info_up_cpu(void)
 			      0, 0, 0);
 }
 
+static void set_conduit(enum psci_conduit conduit)
+{
+	switch (conduit) {
+	case PSCI_CONDUIT_HVC:
+		invoke_psci_fn = __invoke_psci_fn_hvc;
+		break;
+	case PSCI_CONDUIT_SMC:
+		invoke_psci_fn = __invoke_psci_fn_smc;
+		break;
+	default:
+		WARN(1, "Unexpected PSCI conduit %d\n", conduit);
+	}
+
+	psci_ops.conduit = conduit;
+}
+
 static int get_set_conduit_method(struct device_node *np)
 {
 	const char *method;
@@ -222,9 +241,9 @@ static int get_set_conduit_method(struct device_node *np)
 	}
 
 	if (!strcmp("hvc", method)) {
-		invoke_psci_fn = __invoke_psci_fn_hvc;
+		set_conduit(PSCI_CONDUIT_HVC);
 	} else if (!strcmp("smc", method)) {
-		invoke_psci_fn = __invoke_psci_fn_smc;
+		set_conduit(PSCI_CONDUIT_SMC);
 	} else {
 		pr_warn("invalid \"method\" property: %s\n", method);
 		return -EINVAL;
@@ -493,6 +512,31 @@ static void __init psci_init_migrate(void)
 	pr_info("Trusted OS resident on physical CPU 0x%lx\n", cpuid);
 }
 
+static void __init psci_init_smccc(void)
+{
+	u32 ver = ARM_SMCCC_VERSION_1_0;
+	int feature;
+
+	feature = psci_features(ARM_SMCCC_VERSION_FUNC_ID);
+
+	if (feature != PSCI_RET_NOT_SUPPORTED) {
+		u32 ret;
+		ret = invoke_psci_fn(ARM_SMCCC_VERSION_FUNC_ID, 0, 0, 0);
+		if (ret == ARM_SMCCC_VERSION_1_1) {
+			psci_ops.smccc_version = SMCCC_VERSION_1_1;
+			ver = ret;
+		}
+	}
+
+	/*
+	 * Conveniently, the SMCCC and PSCI versions are encoded the
+	 * same way. No, this isn't accidental.
+	 */
+	pr_info("SMC Calling Convention v%d.%d\n",
+		PSCI_VERSION_MAJOR(ver), PSCI_VERSION_MINOR(ver));
+
+}
+
 static void __init psci_0_2_set_functions(void)
 {
 	pr_info("Using standard PSCI v0.2 function IDs\n");
@@ -541,6 +585,7 @@ static int __init psci_probe(void)
 	psci_init_migrate();
 
 	if (PSCI_VERSION_MAJOR(ver) >= 1) {
+		psci_init_smccc();
 		psci_init_cpu_suspend();
 		psci_init_system_suspend();
 	}
@@ -654,9 +699,9 @@ int __init psci_acpi_init(void)
 	pr_info("probing for conduit method from ACPI.\n");
 
 	if (acpi_psci_use_hvc())
-		invoke_psci_fn = __invoke_psci_fn_hvc;
+		set_conduit(PSCI_CONDUIT_HVC);
 	else
-		invoke_psci_fn = __invoke_psci_fn_smc;
+		set_conduit(PSCI_CONDUIT_SMC);
 
 	return psci_probe();
 }
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
index deb4830..a41b572 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -694,10 +694,8 @@ static int fw_cfg_cmdline_set(const char *arg, const struct kernel_param *kp)
 	 */
 	fw_cfg_cmdline_dev = platform_device_register_simple("fw_cfg",
 					PLATFORM_DEVID_NONE, res, processed);
-	if (IS_ERR(fw_cfg_cmdline_dev))
-		return PTR_ERR(fw_cfg_cmdline_dev);
 
-	return 0;
+	return PTR_ERR_OR_ZERO(fw_cfg_cmdline_dev);
 }
 
 static int fw_cfg_cmdline_get(char *buf, const struct kernel_param *kp)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
index bb40d25..239bf2a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -179,8 +179,12 @@ static int amdgpu_gfx_kiq_acquire(struct amdgpu_device *adev,
 
 		amdgpu_gfx_bit_to_queue(adev, queue_bit, &mec, &pipe, &queue);
 
-		/* Using pipes 2/3 from MEC 2 seems cause problems */
-		if (mec == 1 && pipe > 1)
+		/*
+		 * 1. Using pipes 2/3 from MEC 2 seems cause problems.
+		 * 2. It must use queue id 0, because CGPG_IDLE/SAVE/LOAD/RUN
+		 * only can be issued on queue 0.
+		 */
+		if ((mec == 1 && pipe > 1) || queue != 0)
 			continue;
 
 		ring->me = mec + 1;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 6fc16ee..5afbc5e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2262,12 +2262,12 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 {
 	const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE,
 		AMDGPU_VM_PTE_COUNT(adev) * 8);
+	uint64_t init_pde_value = 0, flags;
 	unsigned ring_instance;
 	struct amdgpu_ring *ring;
 	struct drm_sched_rq *rq;
+	unsigned long size;
 	int r, i;
-	u64 flags;
-	uint64_t init_pde_value = 0;
 
 	vm->va = RB_ROOT_CACHED;
 	for (i = 0; i < AMDGPU_MAX_VMHUBS; i++)
@@ -2318,29 +2318,21 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 		flags |= (AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
 				AMDGPU_GEM_CREATE_SHADOW);
 
-	r = amdgpu_bo_create(adev,
-			     amdgpu_vm_bo_size(adev, adev->vm_manager.root_level),
-			     align, true,
-			     AMDGPU_GEM_DOMAIN_VRAM,
-			     flags,
-			     NULL, NULL, init_pde_value, &vm->root.base.bo);
+	size = amdgpu_vm_bo_size(adev, adev->vm_manager.root_level);
+	r = amdgpu_bo_create(adev, size, align, true, AMDGPU_GEM_DOMAIN_VRAM,
+			     flags, NULL, NULL, init_pde_value,
+			     &vm->root.base.bo);
 	if (r)
 		goto error_free_sched_entity;
 
+	r = amdgpu_bo_reserve(vm->root.base.bo, true);
+	if (r)
+		goto error_free_root;
+
 	vm->root.base.vm = vm;
 	list_add_tail(&vm->root.base.bo_list, &vm->root.base.bo->va);
-	INIT_LIST_HEAD(&vm->root.base.vm_status);
-
-	if (vm->use_cpu_for_update) {
-		r = amdgpu_bo_reserve(vm->root.base.bo, false);
-		if (r)
-			goto error_free_root;
-
-		r = amdgpu_bo_kmap(vm->root.base.bo, NULL);
-		amdgpu_bo_unreserve(vm->root.base.bo);
-		if (r)
-			goto error_free_root;
-	}
+	list_add_tail(&vm->root.base.vm_status, &vm->evicted);
+	amdgpu_bo_unreserve(vm->root.base.bo);
 
 	if (pasid) {
 		unsigned long flags;
diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
index b69ceaf..ee14d78 100644
--- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c
@@ -278,9 +278,9 @@ static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev)
 	/* Track retry faults in per-VM fault FIFO. */
 	spin_lock(&adev->vm_manager.pasid_lock);
 	vm = idr_find(&adev->vm_manager.pasid_idr, pasid);
-	spin_unlock(&adev->vm_manager.pasid_lock);
-	if (WARN_ON_ONCE(!vm)) {
+	if (!vm) {
 		/* VM not found, process it normally */
+		spin_unlock(&adev->vm_manager.pasid_lock);
 		amdgpu_ih_clear_fault(adev, key);
 		return true;
 	}
@@ -288,9 +288,11 @@ static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev)
 	r = kfifo_put(&vm->faults, key);
 	if (!r) {
 		/* FIFO is full. Ignore it until there is space */
+		spin_unlock(&adev->vm_manager.pasid_lock);
 		amdgpu_ih_clear_fault(adev, key);
 		goto ignore_iv;
 	}
+	spin_unlock(&adev->vm_manager.pasid_lock);
 
 	/* It's the first fault for this address, process it normally */
 	return true;
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index da2b99c..1e3e05a 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -1049,7 +1049,6 @@ static int vi_common_early_init(void *handle)
 			AMD_CG_SUPPORT_GFX_CP_LS |
 			AMD_CG_SUPPORT_GFX_CGTS |
 			AMD_CG_SUPPORT_GFX_CGTS_LS |
-			AMD_CG_SUPPORT_GFX_CGCG |
 			AMD_CG_SUPPORT_GFX_CGLS |
 			AMD_CG_SUPPORT_BIF_LS |
 			AMD_CG_SUPPORT_HDP_MGCG |
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index 8745971..3a3bf75 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -185,21 +185,22 @@ static int cdv_backlight_init(struct drm_device *dev)
  *	for this and the MID devices.
  */
 
-static inline u32 CDV_MSG_READ32(uint port, uint offset)
+static inline u32 CDV_MSG_READ32(int domain, uint port, uint offset)
 {
 	int mcr = (0x10<<24) | (port << 16) | (offset << 8);
 	uint32_t ret_val = 0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+	struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
 	pci_write_config_dword(pci_root, 0xD0, mcr);
 	pci_read_config_dword(pci_root, 0xD4, &ret_val);
 	pci_dev_put(pci_root);
 	return ret_val;
 }
 
-static inline void CDV_MSG_WRITE32(uint port, uint offset, u32 value)
+static inline void CDV_MSG_WRITE32(int domain, uint port, uint offset,
+				   u32 value)
 {
 	int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+	struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
 	pci_write_config_dword(pci_root, 0xD4, value);
 	pci_write_config_dword(pci_root, 0xD0, mcr);
 	pci_dev_put(pci_root);
@@ -216,11 +217,12 @@ static void cdv_init_pm(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	u32 pwr_cnt;
+	int domain = pci_domain_nr(dev->pdev->bus);
 	int i;
 
-	dev_priv->apm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
+	dev_priv->apm_base = CDV_MSG_READ32(domain, PSB_PUNIT_PORT,
 							PSB_APMBA) & 0xFFFF;
-	dev_priv->ospm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
+	dev_priv->ospm_base = CDV_MSG_READ32(domain, PSB_PUNIT_PORT,
 							PSB_OSPMBA) & 0xFFFF;
 
 	/* Power status */
@@ -251,7 +253,7 @@ static void cdv_errata(struct drm_device *dev)
 	 *	Bonus Launch to work around the issue, by degrading
 	 *	performance.
 	 */
-	 CDV_MSG_WRITE32(3, 0x30, 0x08027108);
+	 CDV_MSG_WRITE32(pci_domain_nr(dev->pdev->bus), 3, 0x30, 0x08027108);
 }
 
 /**
diff --git a/drivers/gpu/drm/gma500/gma_device.c b/drivers/gpu/drm/gma500/gma_device.c
index 4a295f9b..a7fb6de 100644
--- a/drivers/gpu/drm/gma500/gma_device.c
+++ b/drivers/gpu/drm/gma500/gma_device.c
@@ -19,7 +19,9 @@
 void gma_get_core_freq(struct drm_device *dev)
 {
 	uint32_t clock;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+	struct pci_dev *pci_root =
+		pci_get_domain_bus_and_slot(pci_domain_nr(dev->pdev->bus),
+					    0, 0);
 	struct drm_psb_private *dev_priv = dev->dev_private;
 
 	/*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/
diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c
index 1fa1633..7171b74 100644
--- a/drivers/gpu/drm/gma500/mid_bios.c
+++ b/drivers/gpu/drm/gma500/mid_bios.c
@@ -32,7 +32,9 @@
 static void mid_get_fuse_settings(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+	struct pci_dev *pci_root =
+		pci_get_domain_bus_and_slot(pci_domain_nr(dev->pdev->bus),
+					    0, 0);
 	uint32_t fuse_value = 0;
 	uint32_t fuse_value_tmp = 0;
 
@@ -104,7 +106,9 @@ static void mid_get_fuse_settings(struct drm_device *dev)
 static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
 {
 	uint32_t platform_rev_id = 0;
-	struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
+	int domain = pci_domain_nr(dev_priv->dev->pdev->bus);
+	struct pci_dev *pci_gfx_root =
+		pci_get_domain_bus_and_slot(domain, 0, PCI_DEVFN(2, 0));
 
 	if (pci_gfx_root == NULL) {
 		WARN_ON(1);
@@ -281,7 +285,9 @@ static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
 	u32 addr;
 	u8 __iomem *vbt_virtual;
 	struct mid_vbt_header vbt_header;
-	struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
+	struct pci_dev *pci_gfx_root =
+		pci_get_domain_bus_and_slot(pci_domain_nr(dev->pdev->bus),
+					    0, PCI_DEVFN(2, 0));
 	int ret = -1;
 
 	/* Get the address of the platform config vbt */
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 38d09d4..ac32ab5 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -248,7 +248,11 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
 		goto out_err;
 
 	if (IS_MRST(dev)) {
-		dev_priv->aux_pdev = pci_get_bus_and_slot(0, PCI_DEVFN(3, 0));
+		int domain = pci_domain_nr(dev->pdev->bus);
+
+		dev_priv->aux_pdev =
+			pci_get_domain_bus_and_slot(domain, 0,
+						    PCI_DEVFN(3, 0));
 
 		if (dev_priv->aux_pdev) {
 			resource_start = pci_resource_start(dev_priv->aux_pdev,
@@ -268,7 +272,9 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
 		}
 		dev_priv->gmbus_reg = dev_priv->aux_reg;
 
-		dev_priv->lpc_pdev = pci_get_bus_and_slot(0, PCI_DEVFN(31, 0));
+		dev_priv->lpc_pdev =
+			pci_get_domain_bus_and_slot(domain, 0,
+						    PCI_DEVFN(31, 0));
 		if (dev_priv->lpc_pdev) {
 			pci_read_config_word(dev_priv->lpc_pdev, PSB_LPC_GBA,
 				&dev_priv->lpc_gpio_base);
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 4918efc..e8300f5 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -780,38 +780,40 @@ extern const struct psb_ops cdv_chip_ops;
 extern int drm_idle_check_interval;
 
 /* Utilities */
-static inline u32 MRST_MSG_READ32(uint port, uint offset)
+static inline u32 MRST_MSG_READ32(int domain, uint port, uint offset)
 {
 	int mcr = (0xD0<<24) | (port << 16) | (offset << 8);
 	uint32_t ret_val = 0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+	struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
 	pci_write_config_dword(pci_root, 0xD0, mcr);
 	pci_read_config_dword(pci_root, 0xD4, &ret_val);
 	pci_dev_put(pci_root);
 	return ret_val;
 }
-static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value)
+static inline void MRST_MSG_WRITE32(int domain, uint port, uint offset,
+				    u32 value)
 {
 	int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+	struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
 	pci_write_config_dword(pci_root, 0xD4, value);
 	pci_write_config_dword(pci_root, 0xD0, mcr);
 	pci_dev_put(pci_root);
 }
-static inline u32 MDFLD_MSG_READ32(uint port, uint offset)
+static inline u32 MDFLD_MSG_READ32(int domain, uint port, uint offset)
 {
 	int mcr = (0x10<<24) | (port << 16) | (offset << 8);
 	uint32_t ret_val = 0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+	struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
 	pci_write_config_dword(pci_root, 0xD0, mcr);
 	pci_read_config_dword(pci_root, 0xD4, &ret_val);
 	pci_dev_put(pci_root);
 	return ret_val;
 }
-static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value)
+static inline void MDFLD_MSG_WRITE32(int domain, uint port, uint offset,
+				     u32 value)
 {
 	int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
-	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+	struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
 	pci_write_config_dword(pci_root, 0xD4, value);
 	pci_write_config_dword(pci_root, 0xD0, mcr);
 	pci_dev_put(pci_root);
diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c
index 97bfc00..c62346f 100644
--- a/drivers/gpu/drm/i915/gvt/cfg_space.c
+++ b/drivers/gpu/drm/i915/gvt/cfg_space.c
@@ -119,16 +119,6 @@ static int map_aperture(struct intel_vgpu *vgpu, bool map)
 	if (map == vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked)
 		return 0;
 
-	if (map) {
-		vgpu->gm.aperture_va = memremap(aperture_pa, aperture_sz,
-						MEMREMAP_WC);
-		if (!vgpu->gm.aperture_va)
-			return -ENOMEM;
-	} else {
-		memunmap(vgpu->gm.aperture_va);
-		vgpu->gm.aperture_va = NULL;
-	}
-
 	val = vgpu_cfg_space(vgpu)[PCI_BASE_ADDRESS_2];
 	if (val & PCI_BASE_ADDRESS_MEM_TYPE_64)
 		val = *(u64 *)(vgpu_cfg_space(vgpu) + PCI_BASE_ADDRESS_2);
@@ -141,11 +131,8 @@ static int map_aperture(struct intel_vgpu *vgpu, bool map)
 						  aperture_pa >> PAGE_SHIFT,
 						  aperture_sz >> PAGE_SHIFT,
 						  map);
-	if (ret) {
-		memunmap(vgpu->gm.aperture_va);
-		vgpu->gm.aperture_va = NULL;
+	if (ret)
 		return ret;
-	}
 
 	vgpu->cfg_space.bar[INTEL_GVT_PCI_BAR_APERTURE].tracked = map;
 	return 0;
diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c
index 2ab584f..2fb7b34 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -472,7 +472,6 @@ int intel_vgpu_get_dmabuf(struct intel_vgpu *vgpu, unsigned int dmabuf_id)
 		ret = PTR_ERR(dmabuf);
 		goto out_free_gem;
 	}
-	obj->base.dma_buf = dmabuf;
 
 	i915_gem_object_put(obj);
 
diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c
index 769c1c2..70494e3 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -521,24 +521,23 @@ static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id)
 
 	ctx_status_ptr_reg = execlist_ring_mmio(vgpu->gvt, ring_id,
 			_EL_OFFSET_STATUS_PTR);
-
 	ctx_status_ptr.dw = vgpu_vreg(vgpu, ctx_status_ptr_reg);
 	ctx_status_ptr.read_ptr = 0;
 	ctx_status_ptr.write_ptr = 0x7;
 	vgpu_vreg(vgpu, ctx_status_ptr_reg) = ctx_status_ptr.dw;
 }
 
-static void clean_execlist(struct intel_vgpu *vgpu)
+static void clean_execlist(struct intel_vgpu *vgpu, unsigned long engine_mask)
 {
-	enum intel_engine_id i;
+	unsigned int tmp;
+	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
 	struct intel_engine_cs *engine;
+	struct intel_vgpu_submission *s = &vgpu->submission;
 
-	for_each_engine(engine, vgpu->gvt->dev_priv, i) {
-		struct intel_vgpu_submission *s = &vgpu->submission;
-
-		kfree(s->ring_scan_buffer[i]);
-		s->ring_scan_buffer[i] = NULL;
-		s->ring_scan_buffer_size[i] = 0;
+	for_each_engine_masked(engine, dev_priv, engine_mask, tmp) {
+		kfree(s->ring_scan_buffer[engine->id]);
+		s->ring_scan_buffer[engine->id] = NULL;
+		s->ring_scan_buffer_size[engine->id] = 0;
 	}
 }
 
@@ -553,9 +552,10 @@ static void reset_execlist(struct intel_vgpu *vgpu,
 		init_vgpu_execlist(vgpu, engine->id);
 }
 
-static int init_execlist(struct intel_vgpu *vgpu)
+static int init_execlist(struct intel_vgpu *vgpu,
+			 unsigned long engine_mask)
 {
-	reset_execlist(vgpu, ALL_ENGINES);
+	reset_execlist(vgpu, engine_mask);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index a529d2b..8d5317d0 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -997,9 +997,11 @@ static inline void ppgtt_generate_shadow_entry(struct intel_gvt_gtt_entry *se,
 static int ppgtt_populate_shadow_page(struct intel_vgpu_ppgtt_spt *spt)
 {
 	struct intel_vgpu *vgpu = spt->vgpu;
+	struct intel_gvt *gvt = vgpu->gvt;
+	struct intel_gvt_gtt_pte_ops *ops = gvt->gtt.pte_ops;
 	struct intel_vgpu_ppgtt_spt *s;
 	struct intel_gvt_gtt_entry se, ge;
-	unsigned long i;
+	unsigned long gfn, i;
 	int ret;
 
 	trace_spt_change(spt->vgpu->id, "born", spt,
@@ -1007,9 +1009,10 @@ static int ppgtt_populate_shadow_page(struct intel_vgpu_ppgtt_spt *spt)
 
 	if (gtt_type_is_pte_pt(spt->shadow_page.type)) {
 		for_each_present_guest_entry(spt, &ge, i) {
-			ret = gtt_entry_p2m(vgpu, &ge, &se);
-			if (ret)
-				goto fail;
+			gfn = ops->get_pfn(&ge);
+			if (!intel_gvt_hypervisor_is_valid_gfn(vgpu, gfn) ||
+				gtt_entry_p2m(vgpu, &ge, &se))
+				ops->set_pfn(&se, gvt->gtt.scratch_mfn);
 			ppgtt_set_shadow_entry(spt, &se, i);
 		}
 		return 0;
@@ -1906,7 +1909,7 @@ static int emulate_gtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
 	struct intel_vgpu_mm *ggtt_mm = vgpu->gtt.ggtt_mm;
 	struct intel_gvt_gtt_pte_ops *ops = gvt->gtt.pte_ops;
 	unsigned long g_gtt_index = off >> info->gtt_entry_size_shift;
-	unsigned long gma;
+	unsigned long gma, gfn;
 	struct intel_gvt_gtt_entry e, m;
 	int ret;
 
@@ -1925,6 +1928,16 @@ static int emulate_gtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
 			bytes);
 
 	if (ops->test_present(&e)) {
+		gfn = ops->get_pfn(&e);
+
+		/* one PTE update may be issued in multiple writes and the
+		 * first write may not construct a valid gfn
+		 */
+		if (!intel_gvt_hypervisor_is_valid_gfn(vgpu, gfn)) {
+			ops->set_pfn(&m, gvt->gtt.scratch_mfn);
+			goto out;
+		}
+
 		ret = gtt_entry_p2m(vgpu, &e, &m);
 		if (ret) {
 			gvt_vgpu_err("fail to translate guest gtt entry\n");
@@ -1939,6 +1952,7 @@ static int emulate_gtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
 		ops->set_pfn(&m, gvt->gtt.scratch_mfn);
 	}
 
+out:
 	ggtt_set_shadow_entry(ggtt_mm, &m, g_gtt_index);
 	gtt_invalidate(gvt->dev_priv);
 	ggtt_set_guest_entry(ggtt_mm, &e, g_gtt_index);
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 7dc7a80..c6197d9 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -82,7 +82,6 @@ struct intel_gvt_device_info {
 struct intel_vgpu_gm {
 	u64 aperture_sz;
 	u64 hidden_sz;
-	void *aperture_va;
 	struct drm_mm_node low_gm_node;
 	struct drm_mm_node high_gm_node;
 };
@@ -127,7 +126,6 @@ struct intel_vgpu_irq {
 struct intel_vgpu_opregion {
 	bool mapped;
 	void *va;
-	void *va_gopregion;
 	u32 gfn[INTEL_GVT_OPREGION_PAGES];
 };
 
@@ -152,8 +150,8 @@ enum {
 
 struct intel_vgpu_submission_ops {
 	const char *name;
-	int (*init)(struct intel_vgpu *vgpu);
-	void (*clean)(struct intel_vgpu *vgpu);
+	int (*init)(struct intel_vgpu *vgpu, unsigned long engine_mask);
+	void (*clean)(struct intel_vgpu *vgpu, unsigned long engine_mask);
 	void (*reset)(struct intel_vgpu *vgpu, unsigned long engine_mask);
 };
 
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index 92d6468..9be639a 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -1494,7 +1494,6 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
 static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
 		void *p_data, unsigned int bytes)
 {
-	struct intel_vgpu_submission *s = &vgpu->submission;
 	u32 data = *(u32 *)p_data;
 	int ring_id = intel_gvt_render_mmio_to_ring_id(vgpu->gvt, offset);
 	bool enable_execlist;
@@ -1523,11 +1522,9 @@ static int ring_mode_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
 		if (!enable_execlist)
 			return 0;
 
-		if (s->active)
-			return 0;
-
 		ret = intel_vgpu_select_submission_ops(vgpu,
-				INTEL_VGPU_EXECLIST_SUBMISSION);
+			       ENGINE_MASK(ring_id),
+			       INTEL_VGPU_EXECLIST_SUBMISSION);
 		if (ret)
 			return ret;
 
@@ -2843,6 +2840,9 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
 	MMIO_D(_MMIO(_PLANE_KEYVAL_1(PIPE_A)), D_SKL_PLUS);
 	MMIO_D(_MMIO(_PLANE_KEYVAL_1(PIPE_B)), D_SKL_PLUS);
 	MMIO_D(_MMIO(_PLANE_KEYVAL_1(PIPE_C)), D_SKL_PLUS);
+	MMIO_D(_MMIO(_PLANE_KEYMAX_1(PIPE_A)), D_SKL_PLUS);
+	MMIO_D(_MMIO(_PLANE_KEYMAX_1(PIPE_B)), D_SKL_PLUS);
+	MMIO_D(_MMIO(_PLANE_KEYMAX_1(PIPE_C)), D_SKL_PLUS);
 	MMIO_D(_MMIO(_PLANE_KEYMSK_1(PIPE_A)), D_SKL_PLUS);
 	MMIO_D(_MMIO(_PLANE_KEYMSK_1(PIPE_B)), D_SKL_PLUS);
 	MMIO_D(_MMIO(_PLANE_KEYMSK_1(PIPE_C)), D_SKL_PLUS);
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index a1bd82f..f8e77e1 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -58,6 +58,7 @@ struct intel_gvt_mpt {
 	int (*set_opregion)(void *vgpu);
 	int (*get_vfio_device)(void *vgpu);
 	void (*put_vfio_device)(void *vgpu);
+	bool (*is_valid_gfn)(unsigned long handle, unsigned long gfn);
 };
 
 extern struct intel_gvt_mpt xengt_mpt;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 554d1db..909499b 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -651,6 +651,39 @@ static int intel_vgpu_bar_rw(struct intel_vgpu *vgpu, int bar, uint64_t off,
 	return ret;
 }
 
+static inline bool intel_vgpu_in_aperture(struct intel_vgpu *vgpu, uint64_t off)
+{
+	return off >= vgpu_aperture_offset(vgpu) &&
+	       off < vgpu_aperture_offset(vgpu) + vgpu_aperture_sz(vgpu);
+}
+
+static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, uint64_t off,
+		void *buf, unsigned long count, bool is_write)
+{
+	void *aperture_va;
+
+	if (!intel_vgpu_in_aperture(vgpu, off) ||
+	    !intel_vgpu_in_aperture(vgpu, off + count)) {
+		gvt_vgpu_err("Invalid aperture offset %llu\n", off);
+		return -EINVAL;
+	}
+
+	aperture_va = io_mapping_map_wc(&vgpu->gvt->dev_priv->ggtt.iomap,
+					ALIGN_DOWN(off, PAGE_SIZE),
+					count + offset_in_page(off));
+	if (!aperture_va)
+		return -EIO;
+
+	if (is_write)
+		memcpy(aperture_va + offset_in_page(off), buf, count);
+	else
+		memcpy(buf, aperture_va + offset_in_page(off), count);
+
+	io_mapping_unmap(aperture_va);
+
+	return 0;
+}
+
 static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
 			size_t count, loff_t *ppos, bool is_write)
 {
@@ -679,8 +712,7 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
 					buf, count, is_write);
 		break;
 	case VFIO_PCI_BAR2_REGION_INDEX:
-		ret = intel_vgpu_bar_rw(vgpu, PCI_BASE_ADDRESS_2, pos,
-					buf, count, is_write);
+		ret = intel_vgpu_aperture_rw(vgpu, pos, buf, count, is_write);
 		break;
 	case VFIO_PCI_BAR1_REGION_INDEX:
 	case VFIO_PCI_BAR3_REGION_INDEX:
@@ -1575,6 +1607,21 @@ static unsigned long kvmgt_virt_to_pfn(void *addr)
 	return PFN_DOWN(__pa(addr));
 }
 
+static bool kvmgt_is_valid_gfn(unsigned long handle, unsigned long gfn)
+{
+	struct kvmgt_guest_info *info;
+	struct kvm *kvm;
+
+	if (!handle_valid(handle))
+		return false;
+
+	info = (struct kvmgt_guest_info *)handle;
+	kvm = info->kvm;
+
+	return kvm_is_visible_gfn(kvm, gfn);
+
+}
+
 struct intel_gvt_mpt kvmgt_mpt = {
 	.host_init = kvmgt_host_init,
 	.host_exit = kvmgt_host_exit,
@@ -1590,6 +1637,7 @@ struct intel_gvt_mpt kvmgt_mpt = {
 	.set_opregion = kvmgt_set_opregion,
 	.get_vfio_device = kvmgt_get_vfio_device,
 	.put_vfio_device = kvmgt_put_vfio_device,
+	.is_valid_gfn = kvmgt_is_valid_gfn,
 };
 EXPORT_SYMBOL_GPL(kvmgt_mpt);
 
diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c
index 562b5ad..5c869e3 100644
--- a/drivers/gpu/drm/i915/gvt/mmio.c
+++ b/drivers/gpu/drm/i915/gvt/mmio.c
@@ -56,38 +56,6 @@ int intel_vgpu_gpa_to_mmio_offset(struct intel_vgpu *vgpu, u64 gpa)
 	(reg >= gvt->device_info.gtt_start_offset \
 	 && reg < gvt->device_info.gtt_start_offset + gvt_ggtt_sz(gvt))
 
-static bool vgpu_gpa_is_aperture(struct intel_vgpu *vgpu, uint64_t gpa)
-{
-	u64 aperture_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_2);
-	u64 aperture_sz = vgpu_aperture_sz(vgpu);
-
-	return gpa >= aperture_gpa && gpa < aperture_gpa + aperture_sz;
-}
-
-static int vgpu_aperture_rw(struct intel_vgpu *vgpu, uint64_t gpa,
-			    void *pdata, unsigned int size, bool is_read)
-{
-	u64 aperture_gpa = intel_vgpu_get_bar_gpa(vgpu, PCI_BASE_ADDRESS_2);
-	u64 offset = gpa - aperture_gpa;
-
-	if (!vgpu_gpa_is_aperture(vgpu, gpa + size - 1)) {
-		gvt_vgpu_err("Aperture rw out of range, offset %llx, size %d\n",
-			     offset, size);
-		return -EINVAL;
-	}
-
-	if (!vgpu->gm.aperture_va) {
-		gvt_vgpu_err("BAR is not enabled\n");
-		return -ENXIO;
-	}
-
-	if (is_read)
-		memcpy(pdata, vgpu->gm.aperture_va + offset, size);
-	else
-		memcpy(vgpu->gm.aperture_va + offset, pdata, size);
-	return 0;
-}
-
 static void failsafe_emulate_mmio_rw(struct intel_vgpu *vgpu, uint64_t pa,
 		void *p_data, unsigned int bytes, bool read)
 {
@@ -144,11 +112,6 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, uint64_t pa,
 	}
 	mutex_lock(&gvt->lock);
 
-	if (vgpu_gpa_is_aperture(vgpu, pa)) {
-		ret = vgpu_aperture_rw(vgpu, pa, p_data, bytes, true);
-		goto out;
-	}
-
 	offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa);
 
 	if (WARN_ON(bytes > 8))
@@ -222,11 +185,6 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, uint64_t pa,
 
 	mutex_lock(&gvt->lock);
 
-	if (vgpu_gpa_is_aperture(vgpu, pa)) {
-		ret = vgpu_aperture_rw(vgpu, pa, p_data, bytes, false);
-		goto out;
-	}
-
 	offset = intel_vgpu_gpa_to_mmio_offset(vgpu, pa);
 
 	if (WARN_ON(bytes > 8))
diff --git a/drivers/gpu/drm/i915/gvt/mmio_context.c b/drivers/gpu/drm/i915/gvt/mmio_context.c
index 7483439..73ad6e90 100644
--- a/drivers/gpu/drm/i915/gvt/mmio_context.c
+++ b/drivers/gpu/drm/i915/gvt/mmio_context.c
@@ -80,7 +80,7 @@ static struct engine_mmio gen8_engine_mmio_list[] __cacheline_aligned = {
 	{BCS, RING_INSTPM(BLT_RING_BASE), 0xffff, false}, /* 0x220c0 */
 	{BCS, RING_HWSTAM(BLT_RING_BASE), 0x0, false}, /* 0x22098 */
 	{BCS, RING_EXCC(BLT_RING_BASE), 0x0, false}, /* 0x22028 */
-	{ /* Terminated */ }
+	{RCS, INVALID_MMIO_REG, 0, false } /* Terminated */
 };
 
 static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = {
@@ -146,7 +146,7 @@ static struct engine_mmio gen9_engine_mmio_list[] __cacheline_aligned = {
 	{RCS, GEN8_GARBCNTL, 0x0, false}, /* 0xb004 */
 	{RCS, GEN7_FF_THREAD_MODE, 0x0, false}, /* 0x20a0 */
 	{RCS, FF_SLICE_CS_CHICKEN2, 0xffff, false}, /* 0x20e4 */
-	{ /* Terminated */ }
+	{RCS, INVALID_MMIO_REG, 0, false } /* Terminated */
 };
 
 static struct {
@@ -167,7 +167,7 @@ static void load_render_mocs(struct drm_i915_private *dev_priv)
 	};
 	int ring_id, i;
 
-	for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) {
+	for (ring_id = 0; ring_id < ARRAY_SIZE(regs); ring_id++) {
 		offset.reg = regs[ring_id];
 		for (i = 0; i < 64; i++) {
 			gen9_render_mocs.control_table[ring_id][i] =
@@ -310,8 +310,8 @@ static void switch_mmio(struct intel_vgpu *pre,
 	if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
 		switch_mocs(pre, next, ring_id);
 
-	mmio = dev_priv->gvt->engine_mmio_list;
-	while (i915_mmio_reg_offset((mmio++)->reg)) {
+	for (mmio = dev_priv->gvt->engine_mmio_list;
+	     i915_mmio_reg_valid(mmio->reg); mmio++) {
 		if (mmio->ring_id != ring_id)
 			continue;
 		// save
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index ca8005a..81aff4e 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -339,4 +339,21 @@ static inline void intel_gvt_hypervisor_put_vfio_device(struct intel_vgpu *vgpu)
 	intel_gvt_host.mpt->put_vfio_device(vgpu);
 }
 
+/**
+ * intel_gvt_hypervisor_is_valid_gfn - check if a visible gfn
+ * @vgpu: a vGPU
+ * @gfn: guest PFN
+ *
+ * Returns:
+ * true on valid gfn, false on not.
+ */
+static inline bool intel_gvt_hypervisor_is_valid_gfn(
+		struct intel_vgpu *vgpu, unsigned long gfn)
+{
+	if (!intel_gvt_host.mpt->is_valid_gfn)
+		return true;
+
+	return intel_gvt_host.mpt->is_valid_gfn(vgpu->handle, gfn);
+}
+
 #endif /* _GVT_MPT_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c
index 8420d1f..fa75a2e 100644
--- a/drivers/gpu/drm/i915/gvt/opregion.c
+++ b/drivers/gpu/drm/i915/gvt/opregion.c
@@ -299,21 +299,13 @@ int intel_vgpu_opregion_base_write_handler(struct intel_vgpu *vgpu, u32 gpa)
 {
 
 	int i, ret = 0;
-	unsigned long pfn;
 
 	gvt_dbg_core("emulate opregion from kernel\n");
 
 	switch (intel_gvt_host.hypervisor_type) {
 	case INTEL_GVT_HYPERVISOR_KVM:
-		pfn = intel_gvt_hypervisor_gfn_to_mfn(vgpu, gpa >> PAGE_SHIFT);
-		vgpu_opregion(vgpu)->va_gopregion = memremap(pfn << PAGE_SHIFT,
-						INTEL_GVT_OPREGION_SIZE,
-						MEMREMAP_WB);
-		if (!vgpu_opregion(vgpu)->va_gopregion) {
-			gvt_vgpu_err("failed to map guest opregion\n");
-			ret = -EFAULT;
-		}
-		vgpu_opregion(vgpu)->mapped = true;
+		for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++)
+			vgpu_opregion(vgpu)->gfn[i] = (gpa >> PAGE_SHIFT) + i;
 		break;
 	case INTEL_GVT_HYPERVISOR_XEN:
 		/**
@@ -352,10 +344,7 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu)
 		if (vgpu_opregion(vgpu)->mapped)
 			map_vgpu_opregion(vgpu, false);
 	} else if (intel_gvt_host.hypervisor_type == INTEL_GVT_HYPERVISOR_KVM) {
-		if (vgpu_opregion(vgpu)->mapped) {
-			memunmap(vgpu_opregion(vgpu)->va_gopregion);
-			vgpu_opregion(vgpu)->va_gopregion = NULL;
-		}
+		/* Guest opregion is released by VFIO */
 	}
 	free_pages((unsigned long)vgpu_opregion(vgpu)->va,
 		   get_order(INTEL_GVT_OPREGION_SIZE));
@@ -480,19 +469,40 @@ static bool querying_capabilities(u32 scic)
  */
 int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci)
 {
-	u32 *scic, *parm;
+	u32 scic, parm;
 	u32 func, subfunc;
+	u64 scic_pa = 0, parm_pa = 0;
+	int ret;
 
 	switch (intel_gvt_host.hypervisor_type) {
 	case INTEL_GVT_HYPERVISOR_XEN:
-		scic = vgpu_opregion(vgpu)->va + INTEL_GVT_OPREGION_SCIC;
-		parm = vgpu_opregion(vgpu)->va + INTEL_GVT_OPREGION_PARM;
+		scic = *((u32 *)vgpu_opregion(vgpu)->va +
+					INTEL_GVT_OPREGION_SCIC);
+		parm = *((u32 *)vgpu_opregion(vgpu)->va +
+					INTEL_GVT_OPREGION_PARM);
 		break;
 	case INTEL_GVT_HYPERVISOR_KVM:
-		scic = vgpu_opregion(vgpu)->va_gopregion +
-						INTEL_GVT_OPREGION_SCIC;
-		parm = vgpu_opregion(vgpu)->va_gopregion +
-						INTEL_GVT_OPREGION_PARM;
+		scic_pa = (vgpu_opregion(vgpu)->gfn[0] << PAGE_SHIFT) +
+					INTEL_GVT_OPREGION_SCIC;
+		parm_pa = (vgpu_opregion(vgpu)->gfn[0] << PAGE_SHIFT) +
+					INTEL_GVT_OPREGION_PARM;
+
+		ret = intel_gvt_hypervisor_read_gpa(vgpu, scic_pa,
+						    &scic, sizeof(scic));
+		if (ret) {
+			gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
+				ret, scic_pa, sizeof(scic));
+			return ret;
+		}
+
+		ret = intel_gvt_hypervisor_read_gpa(vgpu, parm_pa,
+						    &parm, sizeof(parm));
+		if (ret) {
+			gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
+				ret, scic_pa, sizeof(scic));
+			return ret;
+		}
+
 		break;
 	default:
 		gvt_vgpu_err("not supported hypervisor\n");
@@ -510,9 +520,9 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci)
 		return 0;
 	}
 
-	func = GVT_OPREGION_FUNC(*scic);
-	subfunc = GVT_OPREGION_SUBFUNC(*scic);
-	if (!querying_capabilities(*scic)) {
+	func = GVT_OPREGION_FUNC(scic);
+	subfunc = GVT_OPREGION_SUBFUNC(scic);
+	if (!querying_capabilities(scic)) {
 		gvt_vgpu_err("requesting runtime service: func \"%s\","
 				" subfunc \"%s\"\n",
 				opregion_func_name(func),
@@ -521,11 +531,43 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci)
 		 * emulate exit status of function call, '0' means
 		 * "failure, generic, unsupported or unknown cause"
 		 */
-		*scic &= ~OPREGION_SCIC_EXIT_MASK;
-		return 0;
+		scic &= ~OPREGION_SCIC_EXIT_MASK;
+		goto out;
 	}
 
-	*scic = 0;
-	*parm = 0;
+	scic = 0;
+	parm = 0;
+
+out:
+	switch (intel_gvt_host.hypervisor_type) {
+	case INTEL_GVT_HYPERVISOR_XEN:
+		*((u32 *)vgpu_opregion(vgpu)->va +
+					INTEL_GVT_OPREGION_SCIC) = scic;
+		*((u32 *)vgpu_opregion(vgpu)->va +
+					INTEL_GVT_OPREGION_PARM) = parm;
+		break;
+	case INTEL_GVT_HYPERVISOR_KVM:
+		ret = intel_gvt_hypervisor_write_gpa(vgpu, scic_pa,
+						    &scic, sizeof(scic));
+		if (ret) {
+			gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
+				ret, scic_pa, sizeof(scic));
+			return ret;
+		}
+
+		ret = intel_gvt_hypervisor_write_gpa(vgpu, parm_pa,
+						    &parm, sizeof(parm));
+		if (ret) {
+			gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
+				ret, scic_pa, sizeof(scic));
+			return ret;
+		}
+
+		break;
+	default:
+		gvt_vgpu_err("not supported hypervisor\n");
+		return -EINVAL;
+	}
+
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c
index eea1a2f..cc1ce36 100644
--- a/drivers/gpu/drm/i915/gvt/sched_policy.c
+++ b/drivers/gpu/drm/i915/gvt/sched_policy.c
@@ -50,6 +50,7 @@ static bool vgpu_has_pending_workload(struct intel_vgpu *vgpu)
 struct vgpu_sched_data {
 	struct list_head lru_list;
 	struct intel_vgpu *vgpu;
+	bool active;
 
 	ktime_t sched_in_time;
 	ktime_t sched_out_time;
@@ -308,8 +309,15 @@ static int tbs_sched_init_vgpu(struct intel_vgpu *vgpu)
 
 static void tbs_sched_clean_vgpu(struct intel_vgpu *vgpu)
 {
+	struct intel_gvt *gvt = vgpu->gvt;
+	struct gvt_sched_data *sched_data = gvt->scheduler.sched_data;
+
 	kfree(vgpu->sched_data);
 	vgpu->sched_data = NULL;
+
+	/* this vgpu id has been removed */
+	if (idr_is_empty(&gvt->vgpu_idr))
+		hrtimer_cancel(&sched_data->timer);
 }
 
 static void tbs_sched_start_schedule(struct intel_vgpu *vgpu)
@@ -325,6 +333,7 @@ static void tbs_sched_start_schedule(struct intel_vgpu *vgpu)
 	if (!hrtimer_active(&sched_data->timer))
 		hrtimer_start(&sched_data->timer, ktime_add_ns(ktime_get(),
 			sched_data->period), HRTIMER_MODE_ABS);
+	vgpu_data->active = true;
 }
 
 static void tbs_sched_stop_schedule(struct intel_vgpu *vgpu)
@@ -332,6 +341,7 @@ static void tbs_sched_stop_schedule(struct intel_vgpu *vgpu)
 	struct vgpu_sched_data *vgpu_data = vgpu->sched_data;
 
 	list_del_init(&vgpu_data->lru_list);
+	vgpu_data->active = false;
 }
 
 static struct intel_gvt_sched_policy_ops tbs_schedule_ops = {
@@ -367,9 +377,12 @@ void intel_vgpu_clean_sched_policy(struct intel_vgpu *vgpu)
 
 void intel_vgpu_start_schedule(struct intel_vgpu *vgpu)
 {
-	gvt_dbg_core("vgpu%d: start schedule\n", vgpu->id);
+	struct vgpu_sched_data *vgpu_data = vgpu->sched_data;
 
-	vgpu->gvt->scheduler.sched_ops->start_schedule(vgpu);
+	if (!vgpu_data->active) {
+		gvt_dbg_core("vgpu%d: start schedule\n", vgpu->id);
+		vgpu->gvt->scheduler.sched_ops->start_schedule(vgpu);
+	}
 }
 
 void intel_gvt_kick_schedule(struct intel_gvt *gvt)
@@ -382,6 +395,10 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
 	struct intel_gvt_workload_scheduler *scheduler =
 		&vgpu->gvt->scheduler;
 	int ring_id;
+	struct vgpu_sched_data *vgpu_data = vgpu->sched_data;
+
+	if (!vgpu_data->active)
+		return;
 
 	gvt_dbg_core("vgpu%d: stop schedule\n", vgpu->id);
 
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index 0056638..b55b358 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -991,7 +991,7 @@ void intel_vgpu_clean_submission(struct intel_vgpu *vgpu)
 {
 	struct intel_vgpu_submission *s = &vgpu->submission;
 
-	intel_vgpu_select_submission_ops(vgpu, 0);
+	intel_vgpu_select_submission_ops(vgpu, ALL_ENGINES, 0);
 	i915_gem_context_put(s->shadow_ctx);
 	kmem_cache_destroy(s->workloads);
 }
@@ -1079,6 +1079,7 @@ int intel_vgpu_setup_submission(struct intel_vgpu *vgpu)
  *
  */
 int intel_vgpu_select_submission_ops(struct intel_vgpu *vgpu,
+				     unsigned long engine_mask,
 				     unsigned int interface)
 {
 	struct intel_vgpu_submission *s = &vgpu->submission;
@@ -1091,21 +1092,21 @@ int intel_vgpu_select_submission_ops(struct intel_vgpu *vgpu,
 	if (WARN_ON(interface >= ARRAY_SIZE(ops)))
 		return -EINVAL;
 
-	if (s->active) {
-		s->ops->clean(vgpu);
-		s->active = false;
-		gvt_dbg_core("vgpu%d: de-select ops [ %s ] \n",
-				vgpu->id, s->ops->name);
-	}
+	if (WARN_ON(interface == 0 && engine_mask != ALL_ENGINES))
+		return -EINVAL;
+
+	if (s->active)
+		s->ops->clean(vgpu, engine_mask);
 
 	if (interface == 0) {
 		s->ops = NULL;
 		s->virtual_submission_interface = 0;
-		gvt_dbg_core("vgpu%d: no submission ops\n", vgpu->id);
+		s->active = false;
+		gvt_dbg_core("vgpu%d: remove submission ops\n", vgpu->id);
 		return 0;
 	}
 
-	ret = ops[interface]->init(vgpu);
+	ret = ops[interface]->init(vgpu, engine_mask);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h
index 3de77df..ff175a9 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.h
+++ b/drivers/gpu/drm/i915/gvt/scheduler.h
@@ -141,6 +141,7 @@ void intel_vgpu_reset_submission(struct intel_vgpu *vgpu,
 void intel_vgpu_clean_submission(struct intel_vgpu *vgpu);
 
 int intel_vgpu_select_submission_ops(struct intel_vgpu *vgpu,
+				     unsigned long engine_mask,
 				     unsigned int interface);
 
 extern const struct intel_vgpu_submission_ops
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 4688619..b87b19d 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -258,6 +258,8 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
 
 	intel_gvt_debugfs_remove_vgpu(vgpu);
 	idr_remove(&gvt->vgpu_idr, vgpu->id);
+	if (idr_is_empty(&gvt->vgpu_idr))
+		intel_gvt_clean_irq(gvt);
 	intel_vgpu_clean_sched_policy(vgpu);
 	intel_vgpu_clean_submission(vgpu);
 	intel_vgpu_clean_display(vgpu);
@@ -518,8 +520,7 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
 	intel_vgpu_reset_submission(vgpu, resetting_eng);
 	/* full GPU reset or device model level reset */
 	if (engine_mask == ALL_ENGINES || dmlr) {
-		intel_vgpu_select_submission_ops(vgpu, 0);
-
+		intel_vgpu_select_submission_ops(vgpu, ALL_ENGINES, 0);
 		/*fence will not be reset during virtual reset */
 		if (dmlr) {
 			intel_vgpu_reset_gtt(vgpu);
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
index ccb5ba0..95478db 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -1032,7 +1032,7 @@ find_reg(const struct intel_engine_cs *engine, bool is_master, u32 addr)
 	const struct drm_i915_reg_table *table = engine->reg_tables;
 	int count = engine->reg_table_count;
 
-	do {
+	for (; count > 0; ++table, --count) {
 		if (!table->master || is_master) {
 			const struct drm_i915_reg_descriptor *reg;
 
@@ -1040,7 +1040,7 @@ find_reg(const struct intel_engine_cs *engine, bool is_master, u32 addr)
 			if (reg != NULL)
 				return reg;
 		}
-	} while (table++, --count);
+	}
 
 	return NULL;
 }
@@ -1212,6 +1212,12 @@ static bool check_cmd(const struct intel_engine_cs *engine,
 					continue;
 			}
 
+			if (desc->bits[i].offset >= length) {
+				DRM_DEBUG_DRIVER("CMD: Rejected command 0x%08X, too short to check bitmask (%s)\n",
+						 *cmd, engine->name);
+				return false;
+			}
+
 			dword = cmd[desc->bits[i].offset] &
 				desc->bits[i].mask;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 6c8da9d..173d009 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1842,6 +1842,8 @@ static int i915_drm_resume_early(struct drm_device *dev)
 	if (IS_GEN9_LP(dev_priv) ||
 	    !(dev_priv->suspended_to_idle && dev_priv->csr.dmc_payload))
 		intel_power_domains_init_hw(dev_priv, true);
+	else
+		intel_display_set_init_power(dev_priv, true);
 
 	i915_gem_sanitize(dev_priv);
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index caebd58..a42deeb 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3717,7 +3717,11 @@ extern void intel_display_print_error_state(struct drm_i915_error_state_buf *e,
 					    struct intel_display_error_state *error);
 
 int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val);
-int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u32 mbox, u32 val);
+int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv, u32 mbox,
+				    u32 val, int timeout_us);
+#define sandybridge_pcode_write(dev_priv, mbox, val)	\
+	sandybridge_pcode_write_timeout(dev_priv, mbox, val, 500)
+
 int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
 		      u32 reply_mask, u32 reply, int timeout_base_ms);
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 8bc3283..dd89abd 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3323,16 +3323,15 @@ i915_gem_retire_work_handler(struct work_struct *work)
 		mutex_unlock(&dev->struct_mutex);
 	}
 
-	/* Keep the retire handler running until we are finally idle.
+	/*
+	 * Keep the retire handler running until we are finally idle.
 	 * We do not need to do this test under locking as in the worst-case
 	 * we queue the retire worker once too often.
 	 */
-	if (READ_ONCE(dev_priv->gt.awake)) {
-		i915_queue_hangcheck(dev_priv);
+	if (READ_ONCE(dev_priv->gt.awake))
 		queue_delayed_work(dev_priv->wq,
 				   &dev_priv->gt.retire_work,
 				   round_jiffies_up_relative(HZ));
-	}
 }
 
 static inline bool
@@ -5283,6 +5282,8 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
 	intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 
+	intel_uc_fini_wq(dev_priv);
+
 	if (ret != -EIO)
 		i915_gem_cleanup_userptr(dev_priv);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index c5f3938..7e403ea 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -377,6 +377,7 @@ static gen6_pte_t iris_pte_encode(dma_addr_t addr,
 static struct page *vm_alloc_page(struct i915_address_space *vm, gfp_t gfp)
 {
 	struct pagevec *pvec = &vm->free_pages;
+	struct pagevec stash;
 
 	if (I915_SELFTEST_ONLY(should_fail(&vm->fault_attr, 1)))
 		i915_gem_shrink_all(vm->i915);
@@ -395,7 +396,15 @@ static struct page *vm_alloc_page(struct i915_address_space *vm, gfp_t gfp)
 	if (likely(pvec->nr))
 		return pvec->pages[--pvec->nr];
 
-	/* Otherwise batch allocate pages to amoritize cost of set_pages_wc. */
+	/*
+	 * Otherwise batch allocate pages to amoritize cost of set_pages_wc.
+	 *
+	 * We have to be careful as page allocation may trigger the shrinker
+	 * (via direct reclaim) which will fill up the WC stash underneath us.
+	 * So we add our WB pages into a temporary pvec on the stack and merge
+	 * them into the WC stash after all the allocations are complete.
+	 */
+	pagevec_init(&stash);
 	do {
 		struct page *page;
 
@@ -403,15 +412,24 @@ static struct page *vm_alloc_page(struct i915_address_space *vm, gfp_t gfp)
 		if (unlikely(!page))
 			break;
 
-		pvec->pages[pvec->nr++] = page;
-	} while (pagevec_space(pvec));
+		stash.pages[stash.nr++] = page;
+	} while (stash.nr < pagevec_space(pvec));
 
-	if (unlikely(!pvec->nr))
-		return NULL;
+	if (stash.nr) {
+		int nr = min_t(int, stash.nr, pagevec_space(pvec));
+		struct page **pages = stash.pages + stash.nr - nr;
 
-	set_pages_array_wc(pvec->pages, pvec->nr);
+		if (nr && !set_pages_array_wc(pages, nr)) {
+			memcpy(pvec->pages + pvec->nr,
+			       pages, sizeof(pages[0]) * nr);
+			pvec->nr += nr;
+			stash.nr -= nr;
+		}
 
-	return pvec->pages[--pvec->nr];
+		pagevec_release(&stash);
+	}
+
+	return likely(pvec->nr) ? pvec->pages[--pvec->nr] : NULL;
 }
 
 static void vm_free_pages_release(struct i915_address_space *vm,
@@ -1341,15 +1359,18 @@ static int gen8_ppgtt_alloc_pd(struct i915_address_space *vm,
 		int count = gen8_pte_count(start, length);
 
 		if (pt == vm->scratch_pt) {
+			pd->used_pdes++;
+
 			pt = alloc_pt(vm);
-			if (IS_ERR(pt))
+			if (IS_ERR(pt)) {
+				pd->used_pdes--;
 				goto unwind;
+			}
 
 			if (count < GEN8_PTES || intel_vgpu_active(vm->i915))
 				gen8_initialize_pt(vm, pt);
 
 			gen8_ppgtt_set_pde(vm, pd, pt, pde);
-			pd->used_pdes++;
 			GEM_BUG_ON(pd->used_pdes > I915_PDES);
 		}
 
@@ -1373,13 +1394,16 @@ static int gen8_ppgtt_alloc_pdp(struct i915_address_space *vm,
 
 	gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
 		if (pd == vm->scratch_pd) {
+			pdp->used_pdpes++;
+
 			pd = alloc_pd(vm);
-			if (IS_ERR(pd))
+			if (IS_ERR(pd)) {
+				pdp->used_pdpes--;
 				goto unwind;
+			}
 
 			gen8_initialize_pd(vm, pd);
 			gen8_ppgtt_set_pdpe(vm, pdp, pd, pdpe);
-			pdp->used_pdpes++;
 			GEM_BUG_ON(pdp->used_pdpes > i915_pdpes_per_pdp(vm));
 
 			mark_tlbs_dirty(i915_vm_to_ppgtt(vm));
@@ -2287,12 +2311,23 @@ static void gen8_check_and_clear_faults(struct drm_i915_private *dev_priv)
 	u32 fault = I915_READ(GEN8_RING_FAULT_REG);
 
 	if (fault & RING_FAULT_VALID) {
+		u32 fault_data0, fault_data1;
+		u64 fault_addr;
+
+		fault_data0 = I915_READ(GEN8_FAULT_TLB_DATA0);
+		fault_data1 = I915_READ(GEN8_FAULT_TLB_DATA1);
+		fault_addr = ((u64)(fault_data1 & FAULT_VA_HIGH_BITS) << 44) |
+			     ((u64)fault_data0 << 12);
+
 		DRM_DEBUG_DRIVER("Unexpected fault\n"
-				 "\tAddr: 0x%08lx\n"
+				 "\tAddr: 0x%08x_%08x\n"
+				 "\tAddress space: %s\n"
 				 "\tEngine ID: %d\n"
 				 "\tSource ID: %d\n"
 				 "\tType: %d\n",
-				 fault & PAGE_MASK,
+				 upper_32_bits(fault_addr),
+				 lower_32_bits(fault_addr),
+				 fault_data1 & FAULT_GTT_SEL ? "GGTT" : "PPGTT",
 				 GEN8_RING_FAULT_ENGINE_ID(fault),
 				 RING_FAULT_SRCID(fault),
 				 RING_FAULT_FAULT_TYPE(fault));
diff --git a/drivers/gpu/drm/i915/i915_gem_request.c b/drivers/gpu/drm/i915/i915_gem_request.c
index d575109..e09d18d 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.c
+++ b/drivers/gpu/drm/i915/i915_gem_request.c
@@ -276,6 +276,8 @@ static void mark_busy(struct drm_i915_private *i915)
 
 	intel_engines_unpark(i915);
 
+	i915_queue_hangcheck(i915);
+
 	queue_delayed_work(i915->wq,
 			   &i915->gt.retire_work,
 			   round_jiffies_up_relative(HZ));
diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
index 9029ed0..0e158f9 100644
--- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
@@ -363,13 +363,13 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
 				I915_SHRINK_BOUND |
 				I915_SHRINK_UNBOUND |
 				I915_SHRINK_PURGEABLE);
-	if (freed < sc->nr_to_scan)
+	if (sc->nr_scanned < sc->nr_to_scan)
 		freed += i915_gem_shrink(i915,
 					 sc->nr_to_scan - sc->nr_scanned,
 					 &sc->nr_scanned,
 					 I915_SHRINK_BOUND |
 					 I915_SHRINK_UNBOUND);
-	if (freed < sc->nr_to_scan && current_is_kswapd()) {
+	if (sc->nr_scanned < sc->nr_to_scan && current_is_kswapd()) {
 		intel_runtime_pm_get(i915);
 		freed += i915_gem_shrink(i915,
 					 sc->nr_to_scan - sc->nr_scanned,
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 36d4842..1c30c68 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -74,19 +74,19 @@
 	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
 
-static const struct intel_device_info intel_i830_info __initconst = {
+static const struct intel_device_info intel_i830_info = {
 	GEN2_FEATURES,
 	.platform = INTEL_I830,
 	.is_mobile = 1, .cursor_needs_physical = 1,
 	.num_pipes = 2, /* legal, last one wins */
 };
 
-static const struct intel_device_info intel_i845g_info __initconst = {
+static const struct intel_device_info intel_i845g_info = {
 	GEN2_FEATURES,
 	.platform = INTEL_I845G,
 };
 
-static const struct intel_device_info intel_i85x_info __initconst = {
+static const struct intel_device_info intel_i85x_info = {
 	GEN2_FEATURES,
 	.platform = INTEL_I85X, .is_mobile = 1,
 	.num_pipes = 2, /* legal, last one wins */
@@ -94,7 +94,7 @@ static const struct intel_device_info intel_i85x_info __initconst = {
 	.has_fbc = 1,
 };
 
-static const struct intel_device_info intel_i865g_info __initconst = {
+static const struct intel_device_info intel_i865g_info = {
 	GEN2_FEATURES,
 	.platform = INTEL_I865G,
 };
@@ -108,7 +108,7 @@ static const struct intel_device_info intel_i865g_info __initconst = {
 	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
 
-static const struct intel_device_info intel_i915g_info __initconst = {
+static const struct intel_device_info intel_i915g_info = {
 	GEN3_FEATURES,
 	.platform = INTEL_I915G, .cursor_needs_physical = 1,
 	.has_overlay = 1, .overlay_needs_physical = 1,
@@ -116,7 +116,7 @@ static const struct intel_device_info intel_i915g_info __initconst = {
 	.unfenced_needs_alignment = 1,
 };
 
-static const struct intel_device_info intel_i915gm_info __initconst = {
+static const struct intel_device_info intel_i915gm_info = {
 	GEN3_FEATURES,
 	.platform = INTEL_I915GM,
 	.is_mobile = 1,
@@ -128,7 +128,7 @@ static const struct intel_device_info intel_i915gm_info __initconst = {
 	.unfenced_needs_alignment = 1,
 };
 
-static const struct intel_device_info intel_i945g_info __initconst = {
+static const struct intel_device_info intel_i945g_info = {
 	GEN3_FEATURES,
 	.platform = INTEL_I945G,
 	.has_hotplug = 1, .cursor_needs_physical = 1,
@@ -137,7 +137,7 @@ static const struct intel_device_info intel_i945g_info __initconst = {
 	.unfenced_needs_alignment = 1,
 };
 
-static const struct intel_device_info intel_i945gm_info __initconst = {
+static const struct intel_device_info intel_i945gm_info = {
 	GEN3_FEATURES,
 	.platform = INTEL_I945GM, .is_mobile = 1,
 	.has_hotplug = 1, .cursor_needs_physical = 1,
@@ -148,14 +148,14 @@ static const struct intel_device_info intel_i945gm_info __initconst = {
 	.unfenced_needs_alignment = 1,
 };
 
-static const struct intel_device_info intel_g33_info __initconst = {
+static const struct intel_device_info intel_g33_info = {
 	GEN3_FEATURES,
 	.platform = INTEL_G33,
 	.has_hotplug = 1,
 	.has_overlay = 1,
 };
 
-static const struct intel_device_info intel_pineview_info __initconst = {
+static const struct intel_device_info intel_pineview_info = {
 	GEN3_FEATURES,
 	.platform = INTEL_PINEVIEW, .is_mobile = 1,
 	.has_hotplug = 1,
@@ -172,7 +172,7 @@ static const struct intel_device_info intel_pineview_info __initconst = {
 	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
 
-static const struct intel_device_info intel_i965g_info __initconst = {
+static const struct intel_device_info intel_i965g_info = {
 	GEN4_FEATURES,
 	.platform = INTEL_I965G,
 	.has_overlay = 1,
@@ -180,7 +180,7 @@ static const struct intel_device_info intel_i965g_info __initconst = {
 	.has_snoop = false,
 };
 
-static const struct intel_device_info intel_i965gm_info __initconst = {
+static const struct intel_device_info intel_i965gm_info = {
 	GEN4_FEATURES,
 	.platform = INTEL_I965GM,
 	.is_mobile = 1, .has_fbc = 1,
@@ -190,13 +190,13 @@ static const struct intel_device_info intel_i965gm_info __initconst = {
 	.has_snoop = false,
 };
 
-static const struct intel_device_info intel_g45_info __initconst = {
+static const struct intel_device_info intel_g45_info = {
 	GEN4_FEATURES,
 	.platform = INTEL_G45,
 	.ring_mask = RENDER_RING | BSD_RING,
 };
 
-static const struct intel_device_info intel_gm45_info __initconst = {
+static const struct intel_device_info intel_gm45_info = {
 	GEN4_FEATURES,
 	.platform = INTEL_GM45,
 	.is_mobile = 1, .has_fbc = 1,
@@ -215,12 +215,12 @@ static const struct intel_device_info intel_gm45_info __initconst = {
 	GEN_DEFAULT_PAGE_SIZES, \
 	CURSOR_OFFSETS
 
-static const struct intel_device_info intel_ironlake_d_info __initconst = {
+static const struct intel_device_info intel_ironlake_d_info = {
 	GEN5_FEATURES,
 	.platform = INTEL_IRONLAKE,
 };
 
-static const struct intel_device_info intel_ironlake_m_info __initconst = {
+static const struct intel_device_info intel_ironlake_m_info = {
 	GEN5_FEATURES,
 	.platform = INTEL_IRONLAKE,
 	.is_mobile = 1, .has_fbc = 1,
@@ -243,12 +243,12 @@ static const struct intel_device_info intel_ironlake_m_info __initconst = {
 	GEN6_FEATURES, \
 	.platform = INTEL_SANDYBRIDGE
 
-static const struct intel_device_info intel_sandybridge_d_gt1_info __initconst = {
+static const struct intel_device_info intel_sandybridge_d_gt1_info = {
 	SNB_D_PLATFORM,
 	.gt = 1,
 };
 
-static const struct intel_device_info intel_sandybridge_d_gt2_info __initconst = {
+static const struct intel_device_info intel_sandybridge_d_gt2_info = {
 	SNB_D_PLATFORM,
 	.gt = 2,
 };
@@ -259,12 +259,12 @@ static const struct intel_device_info intel_sandybridge_d_gt2_info __initconst =
 	.is_mobile = 1
 
 
-static const struct intel_device_info intel_sandybridge_m_gt1_info __initconst = {
+static const struct intel_device_info intel_sandybridge_m_gt1_info = {
 	SNB_M_PLATFORM,
 	.gt = 1,
 };
 
-static const struct intel_device_info intel_sandybridge_m_gt2_info __initconst = {
+static const struct intel_device_info intel_sandybridge_m_gt2_info = {
 	SNB_M_PLATFORM,
 	.gt = 2,
 };
@@ -288,12 +288,12 @@ static const struct intel_device_info intel_sandybridge_m_gt2_info __initconst =
 	.platform = INTEL_IVYBRIDGE, \
 	.has_l3_dpf = 1
 
-static const struct intel_device_info intel_ivybridge_d_gt1_info __initconst = {
+static const struct intel_device_info intel_ivybridge_d_gt1_info = {
 	IVB_D_PLATFORM,
 	.gt = 1,
 };
 
-static const struct intel_device_info intel_ivybridge_d_gt2_info __initconst = {
+static const struct intel_device_info intel_ivybridge_d_gt2_info = {
 	IVB_D_PLATFORM,
 	.gt = 2,
 };
@@ -304,17 +304,17 @@ static const struct intel_device_info intel_ivybridge_d_gt2_info __initconst = {
 	.is_mobile = 1, \
 	.has_l3_dpf = 1
 
-static const struct intel_device_info intel_ivybridge_m_gt1_info __initconst = {
+static const struct intel_device_info intel_ivybridge_m_gt1_info = {
 	IVB_M_PLATFORM,
 	.gt = 1,
 };
 
-static const struct intel_device_info intel_ivybridge_m_gt2_info __initconst = {
+static const struct intel_device_info intel_ivybridge_m_gt2_info = {
 	IVB_M_PLATFORM,
 	.gt = 2,
 };
 
-static const struct intel_device_info intel_ivybridge_q_info __initconst = {
+static const struct intel_device_info intel_ivybridge_q_info = {
 	GEN7_FEATURES,
 	.platform = INTEL_IVYBRIDGE,
 	.gt = 2,
@@ -322,7 +322,7 @@ static const struct intel_device_info intel_ivybridge_q_info __initconst = {
 	.has_l3_dpf = 1,
 };
 
-static const struct intel_device_info intel_valleyview_info __initconst = {
+static const struct intel_device_info intel_valleyview_info = {
 	.platform = INTEL_VALLEYVIEW,
 	.gen = 7,
 	.is_lp = 1,
@@ -358,17 +358,17 @@ static const struct intel_device_info intel_valleyview_info __initconst = {
 	.platform = INTEL_HASWELL, \
 	.has_l3_dpf = 1
 
-static const struct intel_device_info intel_haswell_gt1_info __initconst = {
+static const struct intel_device_info intel_haswell_gt1_info = {
 	HSW_PLATFORM,
 	.gt = 1,
 };
 
-static const struct intel_device_info intel_haswell_gt2_info __initconst = {
+static const struct intel_device_info intel_haswell_gt2_info = {
 	HSW_PLATFORM,
 	.gt = 2,
 };
 
-static const struct intel_device_info intel_haswell_gt3_info __initconst = {
+static const struct intel_device_info intel_haswell_gt3_info = {
 	HSW_PLATFORM,
 	.gt = 3,
 };
@@ -388,17 +388,17 @@ static const struct intel_device_info intel_haswell_gt3_info __initconst = {
 	.gen = 8, \
 	.platform = INTEL_BROADWELL
 
-static const struct intel_device_info intel_broadwell_gt1_info __initconst = {
+static const struct intel_device_info intel_broadwell_gt1_info = {
 	BDW_PLATFORM,
 	.gt = 1,
 };
 
-static const struct intel_device_info intel_broadwell_gt2_info __initconst = {
+static const struct intel_device_info intel_broadwell_gt2_info = {
 	BDW_PLATFORM,
 	.gt = 2,
 };
 
-static const struct intel_device_info intel_broadwell_rsvd_info __initconst = {
+static const struct intel_device_info intel_broadwell_rsvd_info = {
 	BDW_PLATFORM,
 	.gt = 3,
 	/* According to the device ID those devices are GT3, they were
@@ -406,13 +406,13 @@ static const struct intel_device_info intel_broadwell_rsvd_info __initconst = {
 	 */
 };
 
-static const struct intel_device_info intel_broadwell_gt3_info __initconst = {
+static const struct intel_device_info intel_broadwell_gt3_info = {
 	BDW_PLATFORM,
 	.gt = 3,
 	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
 };
 
-static const struct intel_device_info intel_cherryview_info __initconst = {
+static const struct intel_device_info intel_cherryview_info = {
 	.gen = 8, .num_pipes = 3,
 	.has_hotplug = 1,
 	.is_lp = 1,
@@ -455,12 +455,12 @@ static const struct intel_device_info intel_cherryview_info __initconst = {
 	.gen = 9, \
 	.platform = INTEL_SKYLAKE
 
-static const struct intel_device_info intel_skylake_gt1_info __initconst = {
+static const struct intel_device_info intel_skylake_gt1_info = {
 	SKL_PLATFORM,
 	.gt = 1,
 };
 
-static const struct intel_device_info intel_skylake_gt2_info __initconst = {
+static const struct intel_device_info intel_skylake_gt2_info = {
 	SKL_PLATFORM,
 	.gt = 2,
 };
@@ -470,12 +470,12 @@ static const struct intel_device_info intel_skylake_gt2_info __initconst = {
 	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING
 
 
-static const struct intel_device_info intel_skylake_gt3_info __initconst = {
+static const struct intel_device_info intel_skylake_gt3_info = {
 	SKL_GT3_PLUS_PLATFORM,
 	.gt = 3,
 };
 
-static const struct intel_device_info intel_skylake_gt4_info __initconst = {
+static const struct intel_device_info intel_skylake_gt4_info = {
 	SKL_GT3_PLUS_PLATFORM,
 	.gt = 4,
 };
@@ -511,13 +511,13 @@ static const struct intel_device_info intel_skylake_gt4_info __initconst = {
 	IVB_CURSOR_OFFSETS, \
 	BDW_COLORS
 
-static const struct intel_device_info intel_broxton_info __initconst = {
+static const struct intel_device_info intel_broxton_info = {
 	GEN9_LP_FEATURES,
 	.platform = INTEL_BROXTON,
 	.ddb_size = 512,
 };
 
-static const struct intel_device_info intel_geminilake_info __initconst = {
+static const struct intel_device_info intel_geminilake_info = {
 	GEN9_LP_FEATURES,
 	.platform = INTEL_GEMINILAKE,
 	.ddb_size = 1024,
@@ -529,17 +529,17 @@ static const struct intel_device_info intel_geminilake_info __initconst = {
 	.gen = 9, \
 	.platform = INTEL_KABYLAKE
 
-static const struct intel_device_info intel_kabylake_gt1_info __initconst = {
+static const struct intel_device_info intel_kabylake_gt1_info = {
 	KBL_PLATFORM,
 	.gt = 1,
 };
 
-static const struct intel_device_info intel_kabylake_gt2_info __initconst = {
+static const struct intel_device_info intel_kabylake_gt2_info = {
 	KBL_PLATFORM,
 	.gt = 2,
 };
 
-static const struct intel_device_info intel_kabylake_gt3_info __initconst = {
+static const struct intel_device_info intel_kabylake_gt3_info = {
 	KBL_PLATFORM,
 	.gt = 3,
 	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
@@ -550,17 +550,17 @@ static const struct intel_device_info intel_kabylake_gt3_info __initconst = {
 	.gen = 9, \
 	.platform = INTEL_COFFEELAKE
 
-static const struct intel_device_info intel_coffeelake_gt1_info __initconst = {
+static const struct intel_device_info intel_coffeelake_gt1_info = {
 	CFL_PLATFORM,
 	.gt = 1,
 };
 
-static const struct intel_device_info intel_coffeelake_gt2_info __initconst = {
+static const struct intel_device_info intel_coffeelake_gt2_info = {
 	CFL_PLATFORM,
 	.gt = 2,
 };
 
-static const struct intel_device_info intel_coffeelake_gt3_info __initconst = {
+static const struct intel_device_info intel_coffeelake_gt3_info = {
 	CFL_PLATFORM,
 	.gt = 3,
 	.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING | BSD2_RING,
@@ -571,7 +571,7 @@ static const struct intel_device_info intel_coffeelake_gt3_info __initconst = {
 	.ddb_size = 1024, \
 	GLK_COLORS
 
-static const struct intel_device_info intel_cannonlake_gt2_info __initconst = {
+static const struct intel_device_info intel_cannonlake_gt2_info = {
 	GEN10_FEATURES,
 	.is_alpha_support = 1,
 	.platform = INTEL_CANNONLAKE,
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 505c605..a2108e3 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2489,6 +2489,8 @@ enum i915_power_well_id {
 
 #define GEN8_FAULT_TLB_DATA0		_MMIO(0x4b10)
 #define GEN8_FAULT_TLB_DATA1		_MMIO(0x4b14)
+#define   FAULT_VA_HIGH_BITS		(0xf << 0)
+#define   FAULT_GTT_SEL			(1 << 4)
 
 #define FPGA_DBG		_MMIO(0x42300)
 #define   FPGA_DBG_RM_NOCLAIM	(1<<31)
diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c
index f1502a0..522d54f 100644
--- a/drivers/gpu/drm/i915/intel_audio.c
+++ b/drivers/gpu/drm/i915/intel_audio.c
@@ -779,7 +779,7 @@ static struct intel_encoder *get_saved_enc(struct drm_i915_private *dev_priv,
 {
 	struct intel_encoder *encoder;
 
-	if (WARN_ON(pipe >= INTEL_INFO(dev_priv)->num_pipes))
+	if (WARN_ON(pipe >= ARRAY_SIZE(dev_priv->av_enc_map)))
 		return NULL;
 
 	/* MST */
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 51108ff..f7f7717 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -1107,6 +1107,7 @@ static void sanitize_aux_ch(struct drm_i915_private *dev_priv,
 }
 
 static const u8 cnp_ddc_pin_map[] = {
+	[0] = 0, /* N/A */
 	[DDC_BUS_DDI_B] = GMBUS_PIN_1_BXT,
 	[DDC_BUS_DDI_C] = GMBUS_PIN_2_BXT,
 	[DDC_BUS_DDI_D] = GMBUS_PIN_4_CNP, /* sic */
@@ -1115,9 +1116,14 @@ static const u8 cnp_ddc_pin_map[] = {
 
 static u8 map_ddc_pin(struct drm_i915_private *dev_priv, u8 vbt_pin)
 {
-	if (HAS_PCH_CNP(dev_priv) &&
-	    vbt_pin > 0 && vbt_pin < ARRAY_SIZE(cnp_ddc_pin_map))
-		return cnp_ddc_pin_map[vbt_pin];
+	if (HAS_PCH_CNP(dev_priv)) {
+		if (vbt_pin < ARRAY_SIZE(cnp_ddc_pin_map)) {
+			return cnp_ddc_pin_map[vbt_pin];
+		} else {
+			DRM_DEBUG_KMS("Ignoring alternate pin: VBT claims DDC pin %d, which is not valid for this platform\n", vbt_pin);
+			return 0;
+		}
+	}
 
 	return vbt_pin;
 }
@@ -1323,11 +1329,13 @@ parse_general_definitions(struct drm_i915_private *dev_priv,
 		expected_size = LEGACY_CHILD_DEVICE_CONFIG_SIZE;
 	} else if (bdb->version == 195) {
 		expected_size = 37;
-	} else if (bdb->version <= 197) {
+	} else if (bdb->version <= 215) {
 		expected_size = 38;
+	} else if (bdb->version <= 216) {
+		expected_size = 39;
 	} else {
-		expected_size = 38;
-		BUILD_BUG_ON(sizeof(*child) < 38);
+		expected_size = sizeof(*child);
+		BUILD_BUG_ON(sizeof(*child) < 39);
 		DRM_DEBUG_DRIVER("Expected child device config size for VBT version %u not known; assuming %u\n",
 				 bdb->version, expected_size);
 	}
diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
index 58c624f..bd40fea 100644
--- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
+++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
@@ -149,17 +149,6 @@ static void intel_breadcrumbs_fake_irq(struct timer_list *t)
 		return;
 
 	mod_timer(&b->fake_irq, jiffies + 1);
-
-	/* Ensure that even if the GPU hangs, we get woken up.
-	 *
-	 * However, note that if no one is waiting, we never notice
-	 * a gpu hang. Eventually, we will have to wait for a resource
-	 * held by the GPU and so trigger a hangcheck. In the most
-	 * pathological case, this will be upon memory starvation! To
-	 * prevent this, we also queue the hangcheck from the retire
-	 * worker.
-	 */
-	i915_queue_hangcheck(engine->i915);
 }
 
 static void irq_enable(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index d77e2be..5dc118f 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -1370,10 +1370,15 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 		break;
 	}
 
-	/* Inform power controller of upcoming frequency change */
+	/*
+	 * Inform power controller of upcoming frequency change. BSpec
+	 * requires us to wait up to 150usec, but that leads to timeouts;
+	 * the 2ms used here is based on experiment.
+	 */
 	mutex_lock(&dev_priv->pcu_lock);
-	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
-				      0x80000000);
+	ret = sandybridge_pcode_write_timeout(dev_priv,
+					      HSW_PCODE_DE_WRITE_FREQ_REQ,
+					      0x80000000, 2000);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (ret) {
@@ -1404,8 +1409,15 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
 	I915_WRITE(CDCLK_CTL, val);
 
 	mutex_lock(&dev_priv->pcu_lock);
-	ret = sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ,
-				      cdclk_state->voltage_level);
+	/*
+	 * The timeout isn't specified, the 2ms used here is based on
+	 * experiment.
+	 * FIXME: Waiting for the request completion could be delayed until
+	 * the next PCODE request based on BSpec.
+	 */
+	ret = sandybridge_pcode_write_timeout(dev_priv,
+					      HSW_PCODE_DE_WRITE_FREQ_REQ,
+					      cdclk_state->voltage_level, 2000);
 	mutex_unlock(&dev_priv->pcu_lock);
 
 	if (ret) {
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0cd3559..f288bcc 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5661,8 +5661,8 @@ static u64 get_crtc_power_domains(struct drm_crtc *crtc,
 	if (!crtc_state->base.active)
 		return 0;
 
-	mask = BIT(POWER_DOMAIN_PIPE(pipe));
-	mask |= BIT(POWER_DOMAIN_TRANSCODER(transcoder));
+	mask = BIT_ULL(POWER_DOMAIN_PIPE(pipe));
+	mask |= BIT_ULL(POWER_DOMAIN_TRANSCODER(transcoder));
 	if (crtc_state->pch_pfit.enabled ||
 	    crtc_state->pch_pfit.force_thru)
 		mask |= BIT_ULL(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
@@ -5674,7 +5674,7 @@ static u64 get_crtc_power_domains(struct drm_crtc *crtc,
 	}
 
 	if (HAS_DDI(dev_priv) && crtc_state->has_audio)
-		mask |= BIT(POWER_DOMAIN_AUDIO);
+		mask |= BIT_ULL(POWER_DOMAIN_AUDIO);
 
 	if (crtc_state->shared_dpll)
 		mask |= BIT_ULL(POWER_DOMAIN_PLLS);
diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
index 05907fa..cf8fef8 100644
--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
@@ -328,14 +328,22 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 	return;
 
  failure_handling:
-	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
-		      intel_connector->base.base.id,
-		      intel_connector->base.name,
-		      intel_dp->link_rate, intel_dp->lane_count);
-	if (!intel_dp_get_link_train_fallback_values(intel_dp,
-						     intel_dp->link_rate,
-						     intel_dp->lane_count))
-		/* Schedule a Hotplug Uevent to userspace to start modeset */
-		schedule_work(&intel_connector->modeset_retry_work);
+	/* Dont fallback and prune modes if its eDP */
+	if (!intel_dp_is_edp(intel_dp)) {
+		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
+			      intel_connector->base.base.id,
+			      intel_connector->base.name,
+			      intel_dp->link_rate, intel_dp->lane_count);
+		if (!intel_dp_get_link_train_fallback_values(intel_dp,
+							     intel_dp->link_rate,
+							     intel_dp->lane_count))
+			/* Schedule a Hotplug Uevent to userspace to start modeset */
+			schedule_work(&intel_connector->modeset_retry_work);
+	} else {
+		DRM_ERROR("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
+			  intel_connector->base.base.id,
+			  intel_connector->base.name,
+			  intel_dp->link_rate, intel_dp->lane_count);
+	}
 	return;
 }
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c
index 6bb51a5..d790bdc 100644
--- a/drivers/gpu/drm/i915/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/intel_engine_cs.c
@@ -1951,8 +1951,22 @@ int intel_enable_engine_stats(struct intel_engine_cs *engine)
 	spin_lock_irqsave(&engine->stats.lock, flags);
 	if (engine->stats.enabled == ~0)
 		goto busy;
-	if (engine->stats.enabled++ == 0)
+	if (engine->stats.enabled++ == 0) {
+		struct intel_engine_execlists *execlists = &engine->execlists;
+		const struct execlist_port *port = execlists->port;
+		unsigned int num_ports = execlists_num_ports(execlists);
+
 		engine->stats.enabled_at = ktime_get();
+
+		/* XXX submission method oblivious? */
+		while (num_ports-- && port_isset(port)) {
+			engine->stats.active++;
+			port++;
+		}
+
+		if (engine->stats.active)
+			engine->stats.start = engine->stats.enabled_at;
+	}
 	spin_unlock_irqrestore(&engine->stats.lock, flags);
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/intel_guc_fw.c b/drivers/gpu/drm/i915/intel_guc_fw.c
index cbc51c9..3b09329 100644
--- a/drivers/gpu/drm/i915/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/intel_guc_fw.c
@@ -39,9 +39,6 @@
 #define KBL_FW_MAJOR 9
 #define KBL_FW_MINOR 39
 
-#define GLK_FW_MAJOR 10
-#define GLK_FW_MINOR 56
-
 #define GUC_FW_PATH(platform, major, minor) \
        "i915/" __stringify(platform) "_guc_ver" __stringify(major) "_" __stringify(minor) ".bin"
 
@@ -54,8 +51,6 @@ MODULE_FIRMWARE(I915_BXT_GUC_UCODE);
 #define I915_KBL_GUC_UCODE GUC_FW_PATH(kbl, KBL_FW_MAJOR, KBL_FW_MINOR)
 MODULE_FIRMWARE(I915_KBL_GUC_UCODE);
 
-#define I915_GLK_GUC_UCODE GUC_FW_PATH(glk, GLK_FW_MAJOR, GLK_FW_MINOR)
-
 static void guc_fw_select(struct intel_uc_fw *guc_fw)
 {
 	struct intel_guc *guc = container_of(guc_fw, struct intel_guc, fw);
@@ -82,10 +77,6 @@ static void guc_fw_select(struct intel_uc_fw *guc_fw)
 		guc_fw->path = I915_KBL_GUC_UCODE;
 		guc_fw->major_ver_wanted = KBL_FW_MAJOR;
 		guc_fw->minor_ver_wanted = KBL_FW_MINOR;
-	} else if (IS_GEMINILAKE(dev_priv)) {
-		guc_fw->path = I915_GLK_GUC_UCODE;
-		guc_fw->major_ver_wanted = GLK_FW_MAJOR;
-		guc_fw->minor_ver_wanted = GLK_FW_MINOR;
 	} else {
 		DRM_WARN("%s: No firmware known for this platform!\n",
 			 intel_uc_fw_type_repr(guc_fw->type));
diff --git a/drivers/gpu/drm/i915/intel_hangcheck.c b/drivers/gpu/drm/i915/intel_hangcheck.c
index 31f01d6..348a4f7 100644
--- a/drivers/gpu/drm/i915/intel_hangcheck.c
+++ b/drivers/gpu/drm/i915/intel_hangcheck.c
@@ -411,7 +411,6 @@ static void i915_hangcheck_elapsed(struct work_struct *work)
 	struct intel_engine_cs *engine;
 	enum intel_engine_id id;
 	unsigned int hung = 0, stuck = 0;
-	int busy_count = 0;
 
 	if (!i915_modparams.enable_hangcheck)
 		return;
@@ -429,7 +428,6 @@ static void i915_hangcheck_elapsed(struct work_struct *work)
 	intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
 
 	for_each_engine(engine, dev_priv, id) {
-		const bool busy = intel_engine_has_waiter(engine);
 		struct intel_engine_hangcheck hc;
 
 		semaphore_clear_deadlocks(dev_priv);
@@ -443,16 +441,13 @@ static void i915_hangcheck_elapsed(struct work_struct *work)
 			if (hc.action != ENGINE_DEAD)
 				stuck |= intel_engine_flag(engine);
 		}
-
-		busy_count += busy;
 	}
 
 	if (hung)
 		hangcheck_declare_hang(dev_priv, hung, stuck);
 
 	/* Reset timer in case GPU hangs without another request being added */
-	if (busy_count)
-		i915_queue_hangcheck(dev_priv);
+	i915_queue_hangcheck(dev_priv);
 }
 
 void intel_engine_init_hangcheck(struct intel_engine_cs *engine)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index bced7b9..179d0ad 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1595,12 +1595,20 @@ intel_hdmi_set_edid(struct drm_connector *connector)
 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
 	struct edid *edid;
 	bool connected = false;
+	struct i2c_adapter *i2c;
 
 	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
 
-	edid = drm_get_edid(connector,
-			    intel_gmbus_get_adapter(dev_priv,
-			    intel_hdmi->ddc_bus));
+	i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus);
+
+	edid = drm_get_edid(connector, i2c);
+
+	if (!edid && !intel_gmbus_is_forced_bit(i2c)) {
+		DRM_DEBUG_KMS("HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n");
+		intel_gmbus_force_bit(i2c, true);
+		edid = drm_get_edid(connector, i2c);
+		intel_gmbus_force_bit(i2c, false);
+	}
 
 	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
 
diff --git a/drivers/gpu/drm/i915/intel_huc.c b/drivers/gpu/drm/i915/intel_huc.c
index 974be3d..8ed0518 100644
--- a/drivers/gpu/drm/i915/intel_huc.c
+++ b/drivers/gpu/drm/i915/intel_huc.c
@@ -54,10 +54,6 @@
 #define KBL_HUC_FW_MINOR 00
 #define KBL_BLD_NUM 1810
 
-#define GLK_HUC_FW_MAJOR 02
-#define GLK_HUC_FW_MINOR 00
-#define GLK_BLD_NUM 1748
-
 #define HUC_FW_PATH(platform, major, minor, bld_num) \
 	"i915/" __stringify(platform) "_huc_ver" __stringify(major) "_" \
 	__stringify(minor) "_" __stringify(bld_num) ".bin"
@@ -74,9 +70,6 @@ MODULE_FIRMWARE(I915_BXT_HUC_UCODE);
 	KBL_HUC_FW_MINOR, KBL_BLD_NUM)
 MODULE_FIRMWARE(I915_KBL_HUC_UCODE);
 
-#define I915_GLK_HUC_UCODE HUC_FW_PATH(glk, GLK_HUC_FW_MAJOR, \
-	GLK_HUC_FW_MINOR, GLK_BLD_NUM)
-
 static void huc_fw_select(struct intel_uc_fw *huc_fw)
 {
 	struct intel_huc *huc = container_of(huc_fw, struct intel_huc, fw);
@@ -103,10 +96,6 @@ static void huc_fw_select(struct intel_uc_fw *huc_fw)
 		huc_fw->path = I915_KBL_HUC_UCODE;
 		huc_fw->major_ver_wanted = KBL_HUC_FW_MAJOR;
 		huc_fw->minor_ver_wanted = KBL_HUC_FW_MINOR;
-	} else if (IS_GEMINILAKE(dev_priv)) {
-		huc_fw->path = I915_GLK_HUC_UCODE;
-		huc_fw->major_ver_wanted = GLK_HUC_FW_MAJOR;
-		huc_fw->minor_ver_wanted = GLK_HUC_FW_MINOR;
 	} else {
 		DRM_WARN("%s: No firmware known for this platform!\n",
 			 intel_uc_fw_type_repr(huc_fw->type));
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1db79a8..1a6e699 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -9149,8 +9149,8 @@ int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u32 mbox, u32 *val
 	return 0;
 }
 
-int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
-			    u32 mbox, u32 val)
+int sandybridge_pcode_write_timeout(struct drm_i915_private *dev_priv,
+				    u32 mbox, u32 val, int timeout_us)
 {
 	int status;
 
@@ -9173,7 +9173,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv,
 
 	if (__intel_wait_for_register_fw(dev_priv,
 					 GEN6_PCODE_MAILBOX, GEN6_PCODE_READY, 0,
-					 500, 0, NULL)) {
+					 timeout_us, 0, NULL)) {
 		DRM_ERROR("timeout waiting for pcode write of 0x%08x to mbox %x to finish for %ps\n",
 			  val, mbox, __builtin_return_address(0));
 		return -ETIMEDOUT;
diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c
index 907deac..d82ca0f 100644
--- a/drivers/gpu/drm/i915/intel_uc.c
+++ b/drivers/gpu/drm/i915/intel_uc.c
@@ -209,8 +209,6 @@ void intel_uc_fini_wq(struct drm_i915_private *dev_priv)
 	if (!USES_GUC(dev_priv))
 		return;
 
-	GEM_BUG_ON(!HAS_GUC(dev_priv));
-
 	intel_guc_fini_wq(&dev_priv->guc);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h
index e3d7745..98dff60 100644
--- a/drivers/gpu/drm/i915/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/intel_vbt_defs.h
@@ -412,6 +412,8 @@ struct child_device_config {
 	u16 dp_gpio_pin_num;					/* 195 */
 	u8 dp_iboost_level:4;					/* 196 */
 	u8 hdmi_iboost_level:4;					/* 196 */
+	u8 dp_max_link_rate:2;					/* 216 CNL+ */
+	u8 dp_max_link_rate_reserved:6;				/* 216 */
 } __packed;
 
 struct bdb_general_definitions {
diff --git a/drivers/gpu/drm/nouveau/dispnv04/arb.c b/drivers/gpu/drm/nouveau/dispnv04/arb.c
index 90075b6..c79160c 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/arb.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/arb.c
@@ -213,8 +213,10 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
 	if ((dev->pdev->device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ ||
 	    (dev->pdev->device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) {
 		uint32_t type;
+		int domain = pci_domain_nr(dev->pdev->bus);
 
-		pci_read_config_dword(pci_get_bus_and_slot(0, 1), 0x7c, &type);
+		pci_read_config_dword(pci_get_domain_bus_and_slot(domain, 0, 1),
+				      0x7c, &type);
 
 		sim_data.memory_type = (type >> 12) & 1;
 		sim_data.memory_width = 64;
diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.c b/drivers/gpu/drm/nouveau/dispnv04/hw.c
index b985990..0c9bdf0 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/hw.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c
@@ -216,12 +216,15 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype)
 {
 	struct nvkm_pll_vals pllvals;
 	int ret;
+	int domain;
+
+	domain = pci_domain_nr(dev->pdev->bus);
 
 	if (plltype == PLL_MEMORY &&
 	    (dev->pdev->device & 0x0ff0) == CHIPSET_NFORCE) {
 		uint32_t mpllP;
-
-		pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP);
+		pci_read_config_dword(pci_get_domain_bus_and_slot(domain, 0, 3),
+				      0x6c, &mpllP);
 		mpllP = (mpllP >> 8) & 0xf;
 		if (!mpllP)
 			mpllP = 4;
@@ -232,7 +235,8 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype)
 	    (dev->pdev->device & 0xff0) == CHIPSET_NFORCE2) {
 		uint32_t clock;
 
-		pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock);
+		pci_read_config_dword(pci_get_domain_bus_and_slot(domain, 0, 5),
+				      0x4c, &clock);
 		return clock / 1000;
 	}
 
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
index adb78f7..92be0e5 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
@@ -75,6 +75,7 @@ int mcp89_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
 int gf100_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
 int gf108_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
 int gk104_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
+int gk110_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
 int gk20a_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
 int gm107_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
 int gm200_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/secboot.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/secboot.h
index 59f3ba5..b57fe4a 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/secboot.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/secboot.h
@@ -60,6 +60,7 @@ int nvkm_secboot_reset(struct nvkm_secboot *, unsigned long);
 int gm200_secboot_new(struct nvkm_device *, int, struct nvkm_secboot **);
 int gm20b_secboot_new(struct nvkm_device *, int, struct nvkm_secboot **);
 int gp102_secboot_new(struct nvkm_device *, int, struct nvkm_secboot **);
+int gp108_secboot_new(struct nvkm_device *, int, struct nvkm_secboot **);
 int gp10b_secboot_new(struct nvkm_device *, int, struct nvkm_secboot **);
 
 #endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
index b1ac47e..9398d9f 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h
@@ -46,6 +46,16 @@ enum nvkm_therm_attr_type {
 	NVKM_THERM_ATTR_THRS_SHUTDOWN_HYST = 17,
 };
 
+struct nvkm_therm_clkgate_init {
+	u32 addr;
+	u8  count;
+	u32 data;
+};
+
+struct nvkm_therm_clkgate_pack {
+	const struct nvkm_therm_clkgate_init *init;
+};
+
 struct nvkm_therm {
 	const struct nvkm_therm_func *func;
 	struct nvkm_subdev subdev;
@@ -85,17 +95,24 @@ struct nvkm_therm {
 
 	int (*attr_get)(struct nvkm_therm *, enum nvkm_therm_attr_type);
 	int (*attr_set)(struct nvkm_therm *, enum nvkm_therm_attr_type, int);
+
+	bool clkgating_enabled;
 };
 
 int nvkm_therm_temp_get(struct nvkm_therm *);
 int nvkm_therm_fan_sense(struct nvkm_therm *);
 int nvkm_therm_cstate(struct nvkm_therm *, int, int);
+void nvkm_therm_clkgate_init(struct nvkm_therm *,
+			     const struct nvkm_therm_clkgate_pack *);
+void nvkm_therm_clkgate_enable(struct nvkm_therm *);
+void nvkm_therm_clkgate_fini(struct nvkm_therm *, bool);
 
 int nv40_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
 int nv50_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
 int g84_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
 int gt215_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
 int gf119_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
+int gk104_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
 int gm107_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
 int gm200_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
 int gp100_therm_new(struct nvkm_device *, int, struct nvkm_therm **);
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h
index 7b5cc5c..be8e00b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.h
@@ -105,4 +105,32 @@ nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
 	return ioptr;
 }
 
+static inline void
+nouveau_bo_unmap_unpin_unref(struct nouveau_bo **pnvbo)
+{
+	if (*pnvbo) {
+		nouveau_bo_unmap(*pnvbo);
+		nouveau_bo_unpin(*pnvbo);
+		nouveau_bo_ref(NULL, pnvbo);
+	}
+}
+
+static inline int
+nouveau_bo_new_pin_map(struct nouveau_cli *cli, u64 size, int align, u32 flags,
+		       struct nouveau_bo **pnvbo)
+{
+	int ret = nouveau_bo_new(cli, size, align, flags,
+				 0, 0, NULL, NULL, pnvbo);
+	if (ret == 0) {
+		ret = nouveau_bo_pin(*pnvbo, flags, true);
+		if (ret == 0) {
+			ret = nouveau_bo_map(*pnvbo);
+			if (ret == 0)
+				return ret;
+			nouveau_bo_unpin(*pnvbo);
+		}
+		nouveau_bo_ref(NULL, pnvbo);
+	}
+	return ret;
+}
 #endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h
index b7a18fb..366acb9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_crtc.h
+++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h
@@ -60,7 +60,6 @@ struct nouveau_crtc {
 	} cursor;
 
 	struct {
-		struct nouveau_bo *nvbo;
 		int depth;
 	} lut;
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 56fe261..3e29302 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -524,7 +524,8 @@ nouveau_get_hdmi_dev(struct nouveau_drm *drm)
 	}
 
 	/* subfunction one is a hdmi audio device? */
-	drm->hdmi_device = pci_get_bus_and_slot((unsigned int)pdev->bus->number,
+	drm->hdmi_device = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
+						(unsigned int)pdev->bus->number,
 						PCI_DEVFN(PCI_SLOT(pdev->devfn), 1));
 
 	if (!drm->hdmi_device) {
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index ee5d1dc..85c1f10 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -56,6 +56,10 @@ MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
 int nouveau_nofbaccel = 0;
 module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
 
+MODULE_PARM_DESC(fbcon_bpp, "fbcon bits-per-pixel (default: auto)");
+static int nouveau_fbcon_bpp;
+module_param_named(fbcon_bpp, nouveau_fbcon_bpp, int, 0400);
+
 static void
 nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
@@ -488,7 +492,7 @@ nouveau_fbcon_init(struct drm_device *dev)
 {
 	struct nouveau_drm *drm = nouveau_drm(dev);
 	struct nouveau_fbdev *fbcon;
-	int preferred_bpp;
+	int preferred_bpp = nouveau_fbcon_bpp;
 	int ret;
 
 	if (!dev->mode_config.num_crtc ||
@@ -512,13 +516,15 @@ nouveau_fbcon_init(struct drm_device *dev)
 	if (ret)
 		goto fini;
 
-	if (drm->client.device.info.ram_size <= 32 * 1024 * 1024)
-		preferred_bpp = 8;
-	else
-	if (drm->client.device.info.ram_size <= 64 * 1024 * 1024)
-		preferred_bpp = 16;
-	else
-		preferred_bpp = 32;
+	if (preferred_bpp != 8 && preferred_bpp != 16 && preferred_bpp != 32) {
+		if (drm->client.device.info.ram_size <= 32 * 1024 * 1024)
+			preferred_bpp = 8;
+		else
+		if (drm->client.device.info.ram_size <= 64 * 1024 * 1024)
+			preferred_bpp = 16;
+		else
+			preferred_bpp = 32;
+	}
 
 	/* disable all the possible outputs/crtcs before entering KMS mode */
 	if (!drm_drv_uses_atomic_modeset(dev))
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index b22c37b..dd8d435 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -137,8 +137,10 @@ struct nv50_head_atom {
 	} mode;
 
 	struct {
+		bool visible;
 		u32 handle;
 		u64 offset:40;
+		u8  mode:4;
 	} lut;
 
 	struct {
@@ -192,6 +194,7 @@ struct nv50_head_atom {
 
 	union {
 		struct {
+			bool ilut:1;
 			bool core:1;
 			bool curs:1;
 		};
@@ -200,6 +203,7 @@ struct nv50_head_atom {
 
 	union {
 		struct {
+			bool ilut:1;
 			bool core:1;
 			bool curs:1;
 			bool view:1;
@@ -660,6 +664,10 @@ nv50_ovly_create(struct nvif_device *device, struct nvif_object *disp,
 
 struct nv50_head {
 	struct nouveau_crtc base;
+	struct {
+		struct nouveau_bo *nvbo[2];
+		int next;
+	} lut;
 	struct nv50_ovly ovly;
 	struct nv50_oimm oimm;
 };
@@ -1795,6 +1803,54 @@ nv50_head_lut_clr(struct nv50_head *head)
 }
 
 static void
+nv50_head_lut_load(struct drm_property_blob *blob, int mode,
+		   struct nouveau_bo *nvbo)
+{
+	struct drm_color_lut *in = (struct drm_color_lut *)blob->data;
+	void __iomem *lut = (u8 *)nvbo_kmap_obj_iovirtual(nvbo);
+	const int size = blob->length / sizeof(*in);
+	int bits, shift, i;
+	u16 zero, r, g, b;
+
+	/* This can't happen.. But it shuts the compiler up. */
+	if (WARN_ON(size != 256))
+		return;
+
+	switch (mode) {
+	case 0: /* LORES. */
+	case 1: /* HIRES. */
+		bits = 11;
+		shift = 3;
+		zero = 0x0000;
+		break;
+	case 7: /* INTERPOLATE_257_UNITY_RANGE. */
+		bits = 14;
+		shift = 0;
+		zero = 0x6000;
+		break;
+	default:
+		WARN_ON(1);
+		return;
+	}
+
+	for (i = 0; i < size; i++) {
+		r = (drm_color_lut_extract(in[i].  red, bits) + zero) << shift;
+		g = (drm_color_lut_extract(in[i].green, bits) + zero) << shift;
+		b = (drm_color_lut_extract(in[i]. blue, bits) + zero) << shift;
+		writew(r, lut + (i * 0x08) + 0);
+		writew(g, lut + (i * 0x08) + 2);
+		writew(b, lut + (i * 0x08) + 4);
+	}
+
+	/* INTERPOLATE modes require a "next" entry to interpolate with,
+	 * so we replicate the last entry to deal with this for now.
+	 */
+	writew(r, lut + (i * 0x08) + 0);
+	writew(g, lut + (i * 0x08) + 2);
+	writew(b, lut + (i * 0x08) + 4);
+}
+
+static void
 nv50_head_lut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
 {
 	struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base;
@@ -1802,18 +1858,18 @@ nv50_head_lut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
 	if ((push = evo_wait(core, 7))) {
 		if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) {
 			evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2);
-			evo_data(push, 0xc0000000);
+			evo_data(push, 0x80000000 | asyh->lut.mode << 30);
 			evo_data(push, asyh->lut.offset >> 8);
 		} else
 		if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
 			evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2);
-			evo_data(push, 0xc0000000);
+			evo_data(push, 0x80000000 | asyh->lut.mode << 30);
 			evo_data(push, asyh->lut.offset >> 8);
 			evo_mthd(push, 0x085c + (head->base.index * 0x400), 1);
 			evo_data(push, asyh->lut.handle);
 		} else {
 			evo_mthd(push, 0x0440 + (head->base.index * 0x300), 4);
-			evo_data(push, 0x83000000);
+			evo_data(push, 0x80000000 | asyh->lut.mode << 24);
 			evo_data(push, asyh->lut.offset >> 8);
 			evo_data(push, 0x00000000);
 			evo_data(push, 0x00000000);
@@ -1896,7 +1952,7 @@ nv50_head_view(struct nv50_head *head, struct nv50_head_atom *asyh)
 static void
 nv50_head_flush_clr(struct nv50_head *head, struct nv50_head_atom *asyh, bool y)
 {
-	if (asyh->clr.core && (!asyh->set.core || y))
+	if (asyh->clr.ilut && (!asyh->set.ilut || y))
 		nv50_head_lut_clr(head);
 	if (asyh->clr.core && (!asyh->set.core || y))
 		nv50_head_core_clr(head);
@@ -1909,7 +1965,15 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh)
 {
 	if (asyh->set.view   ) nv50_head_view    (head, asyh);
 	if (asyh->set.mode   ) nv50_head_mode    (head, asyh);
-	if (asyh->set.core   ) nv50_head_lut_set (head, asyh);
+	if (asyh->set.ilut   ) {
+		struct nouveau_bo *nvbo = head->lut.nvbo[head->lut.next];
+		struct drm_property_blob *blob = asyh->state.gamma_lut;
+		if (blob)
+			nv50_head_lut_load(blob, asyh->lut.mode, nvbo);
+		asyh->lut.offset = nvbo->bo.offset;
+		head->lut.next ^= 1;
+		nv50_head_lut_set(head, asyh);
+	}
 	if (asyh->set.core   ) nv50_head_core_set(head, asyh);
 	if (asyh->set.curs   ) nv50_head_curs_set(head, asyh);
 	if (asyh->set.base   ) nv50_head_base    (head, asyh);
@@ -2044,6 +2108,37 @@ nv50_head_atomic_check_view(struct nv50_head_atom *armh,
 }
 
 static void
+nv50_head_atomic_check_lut(struct nv50_head *head,
+			   struct nv50_head_atom *armh,
+			   struct nv50_head_atom *asyh)
+{
+	struct nv50_disp *disp = nv50_disp(head->base.base.dev);
+
+	/* An I8 surface without an input LUT makes no sense, and
+	 * EVO will throw an error if you try.
+	 *
+	 * Legacy clients actually cause this due to the order in
+	 * which they call ioctls, so we will enable the LUT with
+	 * whatever contents the buffer already contains to avoid
+	 * triggering the error check.
+	 */
+	if (!asyh->state.gamma_lut && asyh->base.cpp != 1) {
+		asyh->lut.handle = 0;
+		asyh->clr.ilut = armh->lut.visible;
+		return;
+	}
+
+	if (disp->disp->oclass < GF110_DISP) {
+		asyh->lut.mode = (asyh->base.cpp == 1) ? 0 : 1;
+		asyh->set.ilut = true;
+	} else {
+		asyh->lut.mode = 7;
+		asyh->set.ilut = asyh->state.color_mgmt_changed;
+	}
+	asyh->lut.handle = disp->mast.base.vram.handle;
+}
+
+static void
 nv50_head_atomic_check_mode(struct nv50_head *head, struct nv50_head_atom *asyh)
 {
 	struct drm_display_mode *mode = &asyh->state.adjusted_mode;
@@ -2128,6 +2223,11 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
 		if (asyh->state.mode_changed)
 			nv50_head_atomic_check_mode(head, asyh);
 
+		if (asyh->state.color_mgmt_changed ||
+		    asyh->base.cpp != armh->base.cpp)
+			nv50_head_atomic_check_lut(head, armh, asyh);
+		asyh->lut.visible = asyh->lut.handle != 0;
+
 		if (asyc) {
 			if (asyc->set.scaler)
 				nv50_head_atomic_check_view(armh, asyh, asyc);
@@ -2143,7 +2243,8 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
 			asyh->core.w = asyh->base.w;
 			asyh->core.h = asyh->base.h;
 		} else
-		if ((asyh->core.visible = asyh->curs.visible)) {
+		if ((asyh->core.visible = asyh->curs.visible) ||
+		    (asyh->core.visible = asyh->lut.visible)) {
 			/*XXX: We need to either find some way of having the
 			 *     primary base layer appear black, while still
 			 *     being able to display the other layers, or we
@@ -2161,11 +2262,10 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
 		asyh->core.layout = 1;
 		asyh->core.block = 0;
 		asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4;
-		asyh->lut.handle = disp->mast.base.vram.handle;
-		asyh->lut.offset = head->base.lut.nvbo->bo.offset;
 		asyh->set.base = armh->base.cpp != asyh->base.cpp;
 		asyh->set.ovly = armh->ovly.cpp != asyh->ovly.cpp;
 	} else {
+		asyh->lut.visible = false;
 		asyh->core.visible = false;
 		asyh->curs.visible = false;
 		asyh->base.cpp = 0;
@@ -2189,8 +2289,10 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
 			asyh->clr.curs = true;
 		}
 	} else {
+		asyh->clr.ilut = armh->lut.visible;
 		asyh->clr.core = armh->core.visible;
 		asyh->clr.curs = armh->curs.visible;
+		asyh->set.ilut = asyh->lut.visible;
 		asyh->set.core = asyh->core.visible;
 		asyh->set.curs = asyh->curs.visible;
 	}
@@ -2200,47 +2302,11 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
 	return 0;
 }
 
-static void
-nv50_head_lut_load(struct drm_crtc *crtc)
-{
-	struct nv50_disp *disp = nv50_disp(crtc->dev);
-	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
-	void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
-	u16 *r, *g, *b;
-	int i;
-
-	r = crtc->gamma_store;
-	g = r + crtc->gamma_size;
-	b = g + crtc->gamma_size;
-
-	for (i = 0; i < 256; i++) {
-		if (disp->disp->oclass < GF110_DISP) {
-			writew((*r++ >> 2) + 0x0000, lut + (i * 0x08) + 0);
-			writew((*g++ >> 2) + 0x0000, lut + (i * 0x08) + 2);
-			writew((*b++ >> 2) + 0x0000, lut + (i * 0x08) + 4);
-		} else {
-			/* 0x6000 interferes with the 14-bit color??? */
-			writew((*r++ >> 2) + 0x6000, lut + (i * 0x20) + 0);
-			writew((*g++ >> 2) + 0x6000, lut + (i * 0x20) + 2);
-			writew((*b++ >> 2) + 0x6000, lut + (i * 0x20) + 4);
-		}
-	}
-}
-
 static const struct drm_crtc_helper_funcs
 nv50_head_help = {
 	.atomic_check = nv50_head_atomic_check,
 };
 
-static int
-nv50_head_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
-		    uint32_t size,
-		    struct drm_modeset_acquire_ctx *ctx)
-{
-	nv50_head_lut_load(crtc);
-	return 0;
-}
-
 static void
 nv50_head_atomic_destroy_state(struct drm_crtc *crtc,
 			       struct drm_crtc_state *state)
@@ -2296,17 +2362,15 @@ nv50_head_reset(struct drm_crtc *crtc)
 static void
 nv50_head_destroy(struct drm_crtc *crtc)
 {
-	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
 	struct nv50_disp *disp = nv50_disp(crtc->dev);
 	struct nv50_head *head = nv50_head(crtc);
+	int i;
 
 	nv50_dmac_destroy(&head->ovly.base, disp->disp);
 	nv50_pioc_destroy(&head->oimm.base);
 
-	nouveau_bo_unmap(nv_crtc->lut.nvbo);
-	if (nv_crtc->lut.nvbo)
-		nouveau_bo_unpin(nv_crtc->lut.nvbo);
-	nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
+	for (i = 0; i < ARRAY_SIZE(head->lut.nvbo); i++)
+		nouveau_bo_unmap_unpin_unref(&head->lut.nvbo[i]);
 
 	drm_crtc_cleanup(crtc);
 	kfree(crtc);
@@ -2315,7 +2379,7 @@ nv50_head_destroy(struct drm_crtc *crtc)
 static const struct drm_crtc_funcs
 nv50_head_func = {
 	.reset = nv50_head_reset,
-	.gamma_set = nv50_head_gamma_set,
+	.gamma_set = drm_atomic_helper_legacy_gamma_set,
 	.destroy = nv50_head_destroy,
 	.set_config = drm_atomic_helper_set_config,
 	.page_flip = drm_atomic_helper_page_flip,
@@ -2333,7 +2397,7 @@ nv50_head_create(struct drm_device *dev, int index)
 	struct nv50_base *base;
 	struct nv50_curs *curs;
 	struct drm_crtc *crtc;
-	int ret;
+	int ret, i;
 
 	head = kzalloc(sizeof(*head), GFP_KERNEL);
 	if (!head)
@@ -2355,22 +2419,14 @@ nv50_head_create(struct drm_device *dev, int index)
 	drm_crtc_helper_add(crtc, &nv50_head_help);
 	drm_mode_crtc_set_gamma_size(crtc, 256);
 
-	ret = nouveau_bo_new(&drm->client, 8192, 0x100, TTM_PL_FLAG_VRAM,
-			     0, 0x0000, NULL, NULL, &head->base.lut.nvbo);
-	if (!ret) {
-		ret = nouveau_bo_pin(head->base.lut.nvbo, TTM_PL_FLAG_VRAM, true);
-		if (!ret) {
-			ret = nouveau_bo_map(head->base.lut.nvbo);
-			if (ret)
-				nouveau_bo_unpin(head->base.lut.nvbo);
-		}
+	for (i = 0; i < ARRAY_SIZE(head->lut.nvbo); i++) {
+		ret = nouveau_bo_new_pin_map(&drm->client, 1025 * 8, 0x100,
+					     TTM_PL_FLAG_VRAM,
+					     &head->lut.nvbo[i]);
 		if (ret)
-			nouveau_bo_ref(NULL, &head->base.lut.nvbo);
+			goto out;
 	}
 
-	if (ret)
-		goto out;
-
 	/* allocate overlay resources */
 	ret = nv50_oimm_create(device, disp->disp, index, &head->oimm);
 	if (ret)
@@ -4350,7 +4406,6 @@ nv50_display_init(struct drm_device *dev)
 {
 	struct drm_encoder *encoder;
 	struct drm_plane *plane;
-	struct drm_crtc *crtc;
 	u32 *push;
 
 	push = evo_wait(nv50_mast(dev), 32);
@@ -4369,10 +4424,6 @@ nv50_display_init(struct drm_device *dev)
 		}
 	}
 
-	drm_for_each_crtc(crtc, dev) {
-		nv50_head_lut_load(crtc);
-	}
-
 	drm_for_each_plane(plane, dev) {
 		struct nv50_wndw *wndw = nv50_wndw(plane);
 		if (plane->funcs != &nv50_wndw)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index 08e77cd..05cd674 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -28,6 +28,7 @@
 #include <core/option.h>
 
 #include <subdev/bios.h>
+#include <subdev/therm.h>
 
 static DEFINE_MUTEX(nv_devices_mutex);
 static LIST_HEAD(nv_devices);
@@ -1682,7 +1683,7 @@ nve4_chipset = {
 	.mxm = nv50_mxm_new,
 	.pci = gk104_pci_new,
 	.pmu = gk104_pmu_new,
-	.therm = gf119_therm_new,
+	.therm = gk104_therm_new,
 	.timer = nv41_timer_new,
 	.top = gk104_top_new,
 	.volt = gk104_volt_new,
@@ -1721,7 +1722,7 @@ nve6_chipset = {
 	.mxm = nv50_mxm_new,
 	.pci = gk104_pci_new,
 	.pmu = gk104_pmu_new,
-	.therm = gf119_therm_new,
+	.therm = gk104_therm_new,
 	.timer = nv41_timer_new,
 	.top = gk104_top_new,
 	.volt = gk104_volt_new,
@@ -1760,7 +1761,7 @@ nve7_chipset = {
 	.mxm = nv50_mxm_new,
 	.pci = gk104_pci_new,
 	.pmu = gk104_pmu_new,
-	.therm = gf119_therm_new,
+	.therm = gk104_therm_new,
 	.timer = nv41_timer_new,
 	.top = gk104_top_new,
 	.volt = gk104_volt_new,
@@ -1811,7 +1812,7 @@ nvf0_chipset = {
 	.bus = gf100_bus_new,
 	.clk = gk104_clk_new,
 	.devinit = gf100_devinit_new,
-	.fb = gk104_fb_new,
+	.fb = gk110_fb_new,
 	.fuse = gf100_fuse_new,
 	.gpio = gk104_gpio_new,
 	.i2c = gk104_i2c_new,
@@ -1824,7 +1825,7 @@ nvf0_chipset = {
 	.mxm = nv50_mxm_new,
 	.pci = gk104_pci_new,
 	.pmu = gk110_pmu_new,
-	.therm = gf119_therm_new,
+	.therm = gk104_therm_new,
 	.timer = nv41_timer_new,
 	.top = gk104_top_new,
 	.volt = gk104_volt_new,
@@ -1849,7 +1850,7 @@ nvf1_chipset = {
 	.bus = gf100_bus_new,
 	.clk = gk104_clk_new,
 	.devinit = gf100_devinit_new,
-	.fb = gk104_fb_new,
+	.fb = gk110_fb_new,
 	.fuse = gf100_fuse_new,
 	.gpio = gk104_gpio_new,
 	.i2c = gk104_i2c_new,
@@ -1862,7 +1863,7 @@ nvf1_chipset = {
 	.mxm = nv50_mxm_new,
 	.pci = gk104_pci_new,
 	.pmu = gk110_pmu_new,
-	.therm = gf119_therm_new,
+	.therm = gk104_therm_new,
 	.timer = nv41_timer_new,
 	.top = gk104_top_new,
 	.volt = gk104_volt_new,
@@ -1887,7 +1888,7 @@ nv106_chipset = {
 	.bus = gf100_bus_new,
 	.clk = gk104_clk_new,
 	.devinit = gf100_devinit_new,
-	.fb = gk104_fb_new,
+	.fb = gk110_fb_new,
 	.fuse = gf100_fuse_new,
 	.gpio = gk104_gpio_new,
 	.i2c = gk104_i2c_new,
@@ -1900,7 +1901,7 @@ nv106_chipset = {
 	.mxm = nv50_mxm_new,
 	.pci = gk104_pci_new,
 	.pmu = gk208_pmu_new,
-	.therm = gf119_therm_new,
+	.therm = gk104_therm_new,
 	.timer = nv41_timer_new,
 	.top = gk104_top_new,
 	.volt = gk104_volt_new,
@@ -1925,7 +1926,7 @@ nv108_chipset = {
 	.bus = gf100_bus_new,
 	.clk = gk104_clk_new,
 	.devinit = gf100_devinit_new,
-	.fb = gk104_fb_new,
+	.fb = gk110_fb_new,
 	.fuse = gf100_fuse_new,
 	.gpio = gk104_gpio_new,
 	.i2c = gk104_i2c_new,
@@ -1938,7 +1939,7 @@ nv108_chipset = {
 	.mxm = nv50_mxm_new,
 	.pci = gk104_pci_new,
 	.pmu = gk208_pmu_new,
-	.therm = gf119_therm_new,
+	.therm = gk104_therm_new,
 	.timer = nv41_timer_new,
 	.top = gk104_top_new,
 	.volt = gk104_volt_new,
@@ -2345,6 +2346,7 @@ nv138_chipset = {
 	.mc = gp100_mc_new,
 	.mmu = gp100_mmu_new,
 	.therm = gp100_therm_new,
+	.secboot = gp108_secboot_new,
 	.pci = gp100_pci_new,
 	.pmu = gp102_pmu_new,
 	.timer = gk20a_timer_new,
@@ -2356,6 +2358,10 @@ nv138_chipset = {
 	.disp = gp102_disp_new,
 	.dma = gf119_dma_new,
 	.fifo = gp100_fifo_new,
+	.gr = gp107_gr_new,
+	.nvdec = gp102_nvdec_new,
+	.sec2 = gp102_sec2_new,
+	.sw = gf100_sw_new,
 };
 
 static const struct nvkm_device_chip
@@ -2508,6 +2514,7 @@ nvkm_device_fini(struct nvkm_device *device, bool suspend)
 		}
 	}
 
+	nvkm_therm_clkgate_fini(device->therm, suspend);
 
 	if (device->func->fini)
 		device->func->fini(device, suspend);
@@ -2597,6 +2604,7 @@ nvkm_device_init(struct nvkm_device *device)
 	}
 
 	nvkm_acpi_init(device);
+	nvkm_therm_clkgate_enable(device->therm);
 
 	time = ktime_to_us(ktime_get()) - time;
 	nvdev_trace(device, "init completed in %lldus\n", time);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
index d7c2adb..c8ec3fd 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
@@ -137,6 +137,7 @@ struct gf100_gr_func {
 	int (*rops)(struct gf100_gr *);
 	int ppc_nr;
 	const struct gf100_grctx_func *grctx;
+	const struct nvkm_therm_clkgate_pack *clkgate_pack;
 	struct nvkm_sclass sclass[];
 };
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
index 5e82f94..1b52fcb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
@@ -22,6 +22,7 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 #include "gf100.h"
+#include "gk104.h"
 #include "ctxgf100.h"
 
 #include <nvif/class.h>
@@ -173,6 +174,208 @@ gk104_gr_pack_mmio[] = {
 	{}
 };
 
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_main_0[] = {
+	{ 0x4041f0, 1, 0x00004046 },
+	{ 0x409890, 1, 0x00000045 },
+	{ 0x4098b0, 1, 0x0000007f },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_rstr2d_0[] = {
+	{ 0x4078c0, 1, 0x00000042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_unk_0[] = {
+	{ 0x406000, 1, 0x00004044 },
+	{ 0x405860, 1, 0x00004042 },
+	{ 0x40590c, 1, 0x00004042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gcc_0[] = {
+	{ 0x408040, 1, 0x00004044 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_sked_0[] = {
+	{ 0x407000, 1, 0x00004044 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_unk_1[] = {
+	{ 0x405bf0, 1, 0x00004044 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_ctxctl_0[] = {
+	{ 0x41a890, 1, 0x00000042 },
+	{ 0x41a8b0, 1, 0x0000007f },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_unk_0[] = {
+	{ 0x418500, 1, 0x00004042 },
+	{ 0x418608, 1, 0x00004042 },
+	{ 0x418688, 1, 0x00004042 },
+	{ 0x418718, 1, 0x00000042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_esetup_0[] = {
+	{ 0x418828, 1, 0x00000044 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_tpbus_0[] = {
+	{ 0x418bbc, 1, 0x00004042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_zcull_0[] = {
+	{ 0x418970, 1, 0x00004042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_tpconf_0[] = {
+	{ 0x418c70, 1, 0x00004042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_unk_1[] = {
+	{ 0x418cf0, 1, 0x00004042 },
+	{ 0x418d70, 1, 0x00004042 },
+	{ 0x418f0c, 1, 0x00004042 },
+	{ 0x418e0c, 1, 0x00004042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_gcc_0[] = {
+	{ 0x419020, 1, 0x00004042 },
+	{ 0x419038, 1, 0x00000042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_ffb_0[] = {
+	{ 0x418898, 1, 0x00000042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_tex_0[] = {
+	{ 0x419a40, 9, 0x00004042 },
+	{ 0x419acc, 1, 0x00004047 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_poly_0[] = {
+	{ 0x419868, 1, 0x00000042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_l1c_0[] = {
+	{ 0x419ccc, 3, 0x00000042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_unk_2[] = {
+	{ 0x419c70, 1, 0x00004045 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_mp_0[] = {
+	{ 0x419fd0, 1, 0x00004043 },
+	{ 0x419fd8, 1, 0x00004049 },
+	{ 0x419fe0, 2, 0x00004042 },
+	{ 0x419ff0, 1, 0x00004046 },
+	{ 0x419ff8, 1, 0x00004042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_gpc_ppc_0[] = {
+	{ 0x41be28, 1, 0x00000042 },
+	{ 0x41bfe8, 1, 0x00004042 },
+	{ 0x41bed0, 1, 0x00004042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_rop_zrop_0[] = {
+	{ 0x408810, 2, 0x00004042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_rop_0[] = {
+	{ 0x408a80, 6, 0x00004042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_rop_crop_0[] = {
+	{ 0x4089a8, 1, 0x00004042 },
+	{ 0x4089b0, 1, 0x00000042 },
+	{ 0x4089b8, 1, 0x00004042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_clkgate_blcg_init_pxbar_0[] = {
+	{ 0x13c820, 1, 0x0001007f },
+	{ 0x13cbe0, 1, 0x00000042 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_pack
+gk104_clkgate_pack[] = {
+	{ gk104_clkgate_blcg_init_main_0 },
+	{ gk104_clkgate_blcg_init_rstr2d_0 },
+	{ gk104_clkgate_blcg_init_unk_0 },
+	{ gk104_clkgate_blcg_init_gcc_0 },
+	{ gk104_clkgate_blcg_init_sked_0 },
+	{ gk104_clkgate_blcg_init_unk_1 },
+	{ gk104_clkgate_blcg_init_gpc_ctxctl_0 },
+	{ gk104_clkgate_blcg_init_gpc_unk_0 },
+	{ gk104_clkgate_blcg_init_gpc_esetup_0 },
+	{ gk104_clkgate_blcg_init_gpc_tpbus_0 },
+	{ gk104_clkgate_blcg_init_gpc_zcull_0 },
+	{ gk104_clkgate_blcg_init_gpc_tpconf_0 },
+	{ gk104_clkgate_blcg_init_gpc_unk_1 },
+	{ gk104_clkgate_blcg_init_gpc_gcc_0 },
+	{ gk104_clkgate_blcg_init_gpc_ffb_0 },
+	{ gk104_clkgate_blcg_init_gpc_tex_0 },
+	{ gk104_clkgate_blcg_init_gpc_poly_0 },
+	{ gk104_clkgate_blcg_init_gpc_l1c_0 },
+	{ gk104_clkgate_blcg_init_gpc_unk_2 },
+	{ gk104_clkgate_blcg_init_gpc_mp_0 },
+	{ gk104_clkgate_blcg_init_gpc_ppc_0 },
+	{ gk104_clkgate_blcg_init_rop_zrop_0 },
+	{ gk104_clkgate_blcg_init_rop_0 },
+	{ gk104_clkgate_blcg_init_rop_crop_0 },
+	{ gk104_clkgate_blcg_init_pxbar_0 },
+	{}
+};
+
 /*******************************************************************************
  * PGRAPH engine/subdev functions
  ******************************************************************************/
@@ -214,6 +417,9 @@ gk104_gr_init(struct gf100_gr *gr)
 	gr->func->init_gpc_mmu(gr);
 
 	gf100_gr_mmio(gr, gr->func->mmio);
+	if (gr->func->clkgate_pack)
+		nvkm_therm_clkgate_init(gr->base.engine.subdev.device->therm,
+					gr->func->clkgate_pack);
 
 	nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001);
 
@@ -338,6 +544,7 @@ gk104_gr = {
 	.rops = gf100_gr_rops,
 	.ppc_nr = 1,
 	.grctx = &gk104_grctx,
+	.clkgate_pack = gk104_clkgate_pack,
 	.sclass = {
 		{ -1, -1, FERMI_TWOD_A },
 		{ -1, -1, KEPLER_INLINE_TO_MEMORY_A },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.h
new file mode 100644
index 0000000..a24c177
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Lyude Paul <lyude@redhat.com>
+ */
+#ifndef __GK104_GR_H__
+#define __GK104_GR_H__
+
+#include <subdev/therm.h>
+
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_main_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_rstr2d_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_unk_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gcc_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_sked_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_unk_1[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_ctxctl_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_unk_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_esetup_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_tpbus_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_zcull_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_tpconf_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_unk_1[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_gcc_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_ffb_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_tex_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_poly_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_l1c_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_unk_2[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_mp_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_gpc_ppc_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_rop_zrop_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_rop_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_rop_crop_0[];
+extern const struct nvkm_therm_clkgate_init gk104_clkgate_blcg_init_pxbar_0[];
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c
index a38e19b..4da916a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c
@@ -22,6 +22,7 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 #include "gf100.h"
+#include "gk104.h"
 #include "ctxgf100.h"
 
 #include <subdev/timer.h>
@@ -156,6 +157,159 @@ gk110_gr_pack_mmio[] = {
 	{}
 };
 
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_blcg_init_sked_0[] = {
+	{ 0x407000, 1, 0x00004041 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_blcg_init_gpc_gcc_0[] = {
+	{ 0x419020, 1, 0x00000042 },
+	{ 0x419038, 1, 0x00000042 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_blcg_init_gpc_l1c_0[] = {
+	{ 0x419cd4, 2, 0x00004042 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_blcg_init_gpc_mp_0[] = {
+	{ 0x419fd0, 1, 0x00004043 },
+	{ 0x419fd8, 1, 0x00004049 },
+	{ 0x419fe0, 2, 0x00004042 },
+	{ 0x419ff0, 1, 0x00000046 },
+	{ 0x419ff8, 1, 0x00004042 },
+	{ 0x419f90, 1, 0x00004042 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_main_0[] = {
+	{ 0x4041f4, 1, 0x00000000 },
+	{ 0x409894, 1, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_unk_0[] = {
+	{ 0x406004, 1, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_sked_0[] = {
+	{ 0x407004, 1, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_gpc_ctxctl_0[] = {
+	{ 0x41a894, 1, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_gpc_unk_0[] = {
+	{ 0x418504, 1, 0x00000000 },
+	{ 0x41860c, 1, 0x00000000 },
+	{ 0x41868c, 1, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_gpc_esetup_0[] = {
+	{ 0x41882c, 1, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_gpc_zcull_0[] = {
+	{ 0x418974, 1, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_gpc_l1c_0[] = {
+	{ 0x419cd8, 2, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_gpc_unk_1[] = {
+	{ 0x419c74, 1, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_gpc_mp_0[] = {
+	{ 0x419fd4, 1, 0x00004a4a },
+	{ 0x419fdc, 1, 0x00000014 },
+	{ 0x419fe4, 1, 0x00000000 },
+	{ 0x419ff4, 1, 0x00001724 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_gpc_ppc_0[] = {
+	{ 0x41be2c, 1, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_init
+gk110_clkgate_slcg_init_pcounter_0[] = {
+	{ 0x1be018, 1, 0x000001ff },
+	{ 0x1bc018, 1, 0x000001ff },
+	{ 0x1b8018, 1, 0x000001ff },
+	{ 0x1b4124, 1, 0x00000000 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_pack
+gk110_clkgate_pack[] = {
+	{ gk104_clkgate_blcg_init_main_0 },
+	{ gk104_clkgate_blcg_init_rstr2d_0 },
+	{ gk104_clkgate_blcg_init_unk_0 },
+	{ gk104_clkgate_blcg_init_gcc_0 },
+	{ gk110_clkgate_blcg_init_sked_0 },
+	{ gk104_clkgate_blcg_init_unk_1 },
+	{ gk104_clkgate_blcg_init_gpc_ctxctl_0 },
+	{ gk104_clkgate_blcg_init_gpc_unk_0 },
+	{ gk104_clkgate_blcg_init_gpc_esetup_0 },
+	{ gk104_clkgate_blcg_init_gpc_tpbus_0 },
+	{ gk104_clkgate_blcg_init_gpc_zcull_0 },
+	{ gk104_clkgate_blcg_init_gpc_tpconf_0 },
+	{ gk104_clkgate_blcg_init_gpc_unk_1 },
+	{ gk110_clkgate_blcg_init_gpc_gcc_0 },
+	{ gk104_clkgate_blcg_init_gpc_ffb_0 },
+	{ gk104_clkgate_blcg_init_gpc_tex_0 },
+	{ gk104_clkgate_blcg_init_gpc_poly_0 },
+	{ gk110_clkgate_blcg_init_gpc_l1c_0 },
+	{ gk104_clkgate_blcg_init_gpc_unk_2 },
+	{ gk110_clkgate_blcg_init_gpc_mp_0 },
+	{ gk104_clkgate_blcg_init_gpc_ppc_0 },
+	{ gk104_clkgate_blcg_init_rop_zrop_0 },
+	{ gk104_clkgate_blcg_init_rop_0 },
+	{ gk104_clkgate_blcg_init_rop_crop_0 },
+	{ gk104_clkgate_blcg_init_pxbar_0 },
+	{ gk110_clkgate_slcg_init_main_0 },
+	{ gk110_clkgate_slcg_init_unk_0 },
+	{ gk110_clkgate_slcg_init_sked_0 },
+	{ gk110_clkgate_slcg_init_gpc_ctxctl_0 },
+	{ gk110_clkgate_slcg_init_gpc_unk_0 },
+	{ gk110_clkgate_slcg_init_gpc_esetup_0 },
+	{ gk110_clkgate_slcg_init_gpc_zcull_0 },
+	{ gk110_clkgate_slcg_init_gpc_l1c_0 },
+	{ gk110_clkgate_slcg_init_gpc_unk_1 },
+	{ gk110_clkgate_slcg_init_gpc_mp_0 },
+	{ gk110_clkgate_slcg_init_gpc_ppc_0 },
+	{ gk110_clkgate_slcg_init_pcounter_0 },
+	{}
+};
+
 /*******************************************************************************
  * PGRAPH engine/subdev functions
  ******************************************************************************/
@@ -192,6 +346,7 @@ gk110_gr = {
 	.rops = gf100_gr_rops,
 	.ppc_nr = 2,
 	.grctx = &gk110_grctx,
+	.clkgate_pack = gk110_clkgate_pack,
 	.sclass = {
 		{ -1, -1, FERMI_TWOD_A },
 		{ -1, -1, KEPLER_INLINE_TO_MEMORY_B },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
index dde89a4..53859b6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
@@ -462,7 +462,7 @@ nvkm_perfmon_mthd_query_domain(struct nvkm_perfmon *perfmon,
 
 		args->v0.id         = di;
 		args->v0.signal_nr  = nvkm_perfdom_count_perfsig(dom);
-		strncpy(args->v0.name, dom->name, sizeof(args->v0.name));
+		strncpy(args->v0.name, dom->name, sizeof(args->v0.name) - 1);
 
 		/* Currently only global counters (PCOUNTER) are implemented
 		 * but this will be different for local counters (MP). */
@@ -514,7 +514,7 @@ nvkm_perfmon_mthd_query_signal(struct nvkm_perfmon *perfmon,
 				 "/%s/%02x", dom->name, si);
 		} else {
 			strncpy(args->v0.name, sig->name,
-				sizeof(args->v0.name));
+				sizeof(args->v0.name) - 1);
 		}
 
 		args->v0.signal = si;
@@ -572,7 +572,7 @@ nvkm_perfmon_mthd_query_source(struct nvkm_perfmon *perfmon,
 
 		args->v0.source = sig->source[si];
 		args->v0.mask   = src->mask;
-		strncpy(args->v0.name, src->name, sizeof(args->v0.name));
+		strncpy(args->v0.name, src->name, sizeof(args->v0.name) - 1);
 	}
 
 	if (++si < source_nr) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
index 77273b5..58a59b7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
+++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c
@@ -505,6 +505,7 @@ nvkm_msgqueue_new(u32 version, struct nvkm_falcon *falcon,
 		ret = msgqueue_0137bca5_new(falcon, sb, queue);
 		break;
 	case 0x0148cdec:
+	case 0x015ccf3e:
 		ret = msgqueue_0148cdec_new(falcon, sb, queue);
 		break;
 	default:
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
index 96e0941..f0a2688 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
@@ -110,6 +110,7 @@ read_pll(struct gt215_clk *clk, int idx, u32 pll)
 	struct nvkm_device *device = clk->base.subdev.device;
 	u32 ctrl = nvkm_rd32(device, pll + 0);
 	u32 sclk = 0, P = 1, N = 1, M = 1;
+	u32 MP;
 
 	if (!(ctrl & 0x00000008)) {
 		if (ctrl & 0x00000001) {
@@ -130,10 +131,12 @@ read_pll(struct gt215_clk *clk, int idx, u32 pll)
 		sclk = read_clk(clk, 0x10 + idx, false);
 	}
 
-	if (M * P)
-		return sclk * N / (M * P);
+	MP = M * P;
 
-	return 0;
+	if (!MP)
+		return 0;
+
+	return sclk * N / MP;
 }
 
 static int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
index 2571530..b4f22cc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
@@ -22,6 +22,7 @@
 nvkm-y += nvkm/subdev/fb/gf100.o
 nvkm-y += nvkm/subdev/fb/gf108.o
 nvkm-y += nvkm/subdev/fb/gk104.o
+nvkm-y += nvkm/subdev/fb/gk110.o
 nvkm-y += nvkm/subdev/fb/gk20a.o
 nvkm-y += nvkm/subdev/fb/gm107.o
 nvkm-y += nvkm/subdev/fb/gm200.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
index 47d28c2..cdc4e0a2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
@@ -26,6 +26,7 @@
 
 #include <core/memory.h>
 #include <core/option.h>
+#include <subdev/therm.h>
 
 void
 gf100_fb_intr(struct nvkm_fb *base)
@@ -92,6 +93,11 @@ gf100_fb_init(struct nvkm_fb *base)
 
 	if (fb->r100c10_page)
 		nvkm_wr32(device, 0x100c10, fb->r100c10 >> 8);
+
+	if (base->func->clkgate_pack) {
+		nvkm_therm_clkgate_init(device->therm,
+					base->func->clkgate_pack);
+	}
 }
 
 void *
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
index 0a6e8ea..48fd98e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
@@ -20,10 +20,56 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  * Authors: Ben Skeggs
+ *          Lyude Paul
  */
+#include "gk104.h"
 #include "gf100.h"
 #include "ram.h"
 
+/*
+ *******************************************************************************
+ * PGRAPH registers for clockgating
+ *******************************************************************************
+ */
+const struct nvkm_therm_clkgate_init
+gk104_fb_clkgate_blcg_init_unk_0[] = {
+	{ 0x100d10, 1, 0x0000c244 },
+	{ 0x100d30, 1, 0x0000c242 },
+	{ 0x100d3c, 1, 0x00000242 },
+	{ 0x100d48, 1, 0x00000242 },
+	{ 0x100d1c, 1, 0x00000042 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_fb_clkgate_blcg_init_vm_0[] = {
+	{ 0x100c98, 1, 0x00000242 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_fb_clkgate_blcg_init_main_0[] = {
+	{ 0x10f000, 1, 0x00000042 },
+	{ 0x17e030, 1, 0x00000044 },
+	{ 0x17e040, 1, 0x00000044 },
+	{}
+};
+
+const struct nvkm_therm_clkgate_init
+gk104_fb_clkgate_blcg_init_bcast_0[] = {
+	{ 0x17ea60, 4, 0x00000044 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_pack
+gk104_fb_clkgate_pack[] = {
+	{ gk104_fb_clkgate_blcg_init_unk_0 },
+	{ gk104_fb_clkgate_blcg_init_vm_0 },
+	{ gk104_fb_clkgate_blcg_init_main_0 },
+	{ gk104_fb_clkgate_blcg_init_bcast_0 },
+	{}
+};
+
 static const struct nvkm_fb_func
 gk104_fb = {
 	.dtor = gf100_fb_dtor,
@@ -33,6 +79,7 @@ gk104_fb = {
 	.intr = gf100_fb_intr,
 	.ram_new = gk104_ram_new,
 	.default_bigpage = 17,
+	.clkgate_pack = gk104_fb_clkgate_pack,
 };
 
 int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.h
new file mode 100644
index 0000000..b3c78e4
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Lyude Paul
+ */
+
+#ifndef __GK104_FB_H__
+#define __GK104_FB_H__
+
+#include <subdev/therm.h>
+
+extern const struct nvkm_therm_clkgate_init gk104_fb_clkgate_blcg_init_unk_0[];
+extern const struct nvkm_therm_clkgate_init gk104_fb_clkgate_blcg_init_vm_0[];
+extern const struct nvkm_therm_clkgate_init gk104_fb_clkgate_blcg_init_main_0[];
+extern const struct nvkm_therm_clkgate_init gk104_fb_clkgate_blcg_init_bcast_0[];
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c
new file mode 100644
index 0000000..0695e5d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk110.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2017 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Lyude Paul
+ */
+#include "gf100.h"
+#include "gk104.h"
+#include "ram.h"
+#include <subdev/therm.h>
+#include <subdev/fb.h>
+
+/*
+ *******************************************************************************
+ * PGRAPH registers for clockgating
+ *******************************************************************************
+ */
+
+static const struct nvkm_therm_clkgate_init
+gk110_fb_clkgate_blcg_init_unk_0[] = {
+	{ 0x100d10, 1, 0x0000c242 },
+	{ 0x100d30, 1, 0x0000c242 },
+	{ 0x100d3c, 1, 0x00000242 },
+	{ 0x100d48, 1, 0x0000c242 },
+	{ 0x100d1c, 1, 0x00000042 },
+	{}
+};
+
+static const struct nvkm_therm_clkgate_pack
+gk110_fb_clkgate_pack[] = {
+	{ gk110_fb_clkgate_blcg_init_unk_0 },
+	{ gk104_fb_clkgate_blcg_init_vm_0 },
+	{ gk104_fb_clkgate_blcg_init_main_0 },
+	{ gk104_fb_clkgate_blcg_init_bcast_0 },
+	{}
+};
+
+static const struct nvkm_fb_func
+gk110_fb = {
+	.dtor = gf100_fb_dtor,
+	.oneinit = gf100_fb_oneinit,
+	.init = gf100_fb_init,
+	.init_page = gf100_fb_init_page,
+	.intr = gf100_fb_intr,
+	.ram_new = gk104_ram_new,
+	.default_bigpage = 17,
+	.clkgate_pack = gk110_fb_clkgate_pack,
+};
+
+int
+gk110_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb)
+{
+	return gf100_fb_new_(&gk110_fb, device, index, pfb);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
index 9351188..414a423 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
@@ -3,6 +3,7 @@
 #define __NVKM_FB_PRIV_H__
 #define nvkm_fb(p) container_of((p), struct nvkm_fb, subdev)
 #include <subdev/fb.h>
+#include <subdev/therm.h>
 struct nvkm_bios;
 
 struct nvkm_fb_func {
@@ -27,6 +28,7 @@ struct nvkm_fb_func {
 	int (*ram_new)(struct nvkm_fb *, struct nvkm_ram **);
 
 	u8 default_bigpage;
+	const struct nvkm_therm_clkgate_pack *clkgate_pack;
 };
 
 void nvkm_fb_ctor(const struct nvkm_fb_func *, struct nvkm_device *device,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
index 4c07d10..18241c6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
@@ -28,8 +28,16 @@ nv1a_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
 {
 	struct pci_dev *bridge;
 	u32 mem, mib;
+	int domain = 0;
+	struct pci_dev *pdev = NULL;
 
-	bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
+	if (dev_is_pci(fb->subdev.device->dev))
+		pdev = to_pci_dev(fb->subdev.device->dev);
+
+	if (pdev)
+		domain = pci_domain_nr(pdev->bus);
+
+	bridge = pci_get_domain_bus_and_slot(domain, 0, PCI_DEVFN(0, 1));
 	if (!bridge) {
 		nvkm_error(&fb->subdev, "no bridge device\n");
 		return -ENODEV;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c
index fa81d0c..37b201b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c
@@ -106,7 +106,8 @@ nvkm_uvmm_mthd_map(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
 	} else
 		return ret;
 
-	if (IS_ERR((memory = nvkm_umem_search(client, handle)))) {
+	memory = nvkm_umem_search(client, handle);
+	if (IS_ERR(memory)) {
 		VMM_DEBUG(vmm, "memory %016llx %ld\n", handle, PTR_ERR(memory));
 		return PTR_ERR(memory);
 	}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
index e35d3e1..93946dc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
@@ -642,7 +642,7 @@ nvkm_vmm_ptes_sparse(struct nvkm_vmm *vmm, u64 addr, u64 size, bool ref)
 			else
 				block = (size >> page[i].shift) << page[i].shift;
 		} else {
-			block = (size >> page[i].shift) << page[i].shift;;
+			block = (size >> page[i].shift) << page[i].shift;
 		}
 
 		/* Perform operation. */
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h
index 53d01fb..1dbe593 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h
@@ -47,8 +47,8 @@ static uint32_t gf100_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x584d454d,
-	0x00000756,
-	0x00000748,
+	0x00000754,
+	0x00000746,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -69,8 +69,8 @@ static uint32_t gf100_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x46524550,
-	0x0000075a,
 	0x00000758,
+	0x00000756,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -91,8 +91,8 @@ static uint32_t gf100_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x5f433249,
-	0x00000b8a,
-	0x00000a2d,
+	0x00000b88,
+	0x00000a2b,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -113,8 +113,8 @@ static uint32_t gf100_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x54534554,
-	0x00000bb3,
-	0x00000b8c,
+	0x00000bb1,
+	0x00000b8a,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -135,8 +135,8 @@ static uint32_t gf100_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x454c4449,
-	0x00000bbf,
 	0x00000bbd,
+	0x00000bbb,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -237,19 +237,19 @@ static uint32_t gf100_pmu_data[] = {
 	0x000005d3,
 	0x00000003,
 	0x00000002,
-	0x0000069d,
+	0x0000069b,
 	0x00040004,
 	0x00000000,
-	0x000006b9,
+	0x000006b7,
 	0x00010005,
 	0x00000000,
-	0x000006d6,
+	0x000006d4,
 	0x00010006,
 	0x00000000,
 	0x0000065b,
 	0x00000007,
 	0x00000000,
-	0x000006e1,
+	0x000006df,
 /* 0x03c4: memx_func_tail */
 /* 0x03c4: memx_ts_start */
 	0x00000000,
@@ -1373,432 +1373,432 @@ static uint32_t gf100_pmu_code[] = {
 /* 0x065b: memx_func_wait_vblank */
 	0x9800f840,
 	0x66b00016,
-	0x130bf400,
+	0x120bf400,
 	0xf40166b0,
 	0x0ef4060b,
 /* 0x066d: memx_func_wait_vblank_head1 */
-	0x2077f12e,
-	0x070ef400,
-/* 0x0674: memx_func_wait_vblank_head0 */
-	0x000877f1,
-/* 0x0678: memx_func_wait_vblank_0 */
-	0x07c467f1,
-	0xcf0664b6,
-	0x67fd0066,
-	0xf31bf404,
-/* 0x0688: memx_func_wait_vblank_1 */
-	0x07c467f1,
-	0xcf0664b6,
-	0x67fd0066,
-	0xf30bf404,
-/* 0x0698: memx_func_wait_vblank_fini */
-	0xf80410b6,
-/* 0x069d: memx_func_wr32 */
-	0x00169800,
-	0xb6011598,
-	0x60f90810,
-	0xd0fc50f9,
-	0x21f4e0fc,
-	0x0242b640,
-	0xf8e91bf4,
-/* 0x06b9: memx_func_wait */
-	0x2c87f000,
-	0xcf0684b6,
-	0x1e980088,
-	0x011d9800,
-	0x98021c98,
-	0x10b6031b,
-	0xa321f410,
-/* 0x06d6: memx_func_delay */
-	0x1e9800f8,
-	0x0410b600,
-	0xf87e21f4,
-/* 0x06e1: memx_func_train */
-/* 0x06e3: memx_exec */
-	0xf900f800,
-	0xb9d0f9e0,
-	0xb2b902c1,
-/* 0x06ed: memx_exec_next */
-	0x00139802,
-	0xe70410b6,
-	0xe701f034,
-	0xb601e033,
-	0x30f00132,
-	0xde35980c,
-	0x12b855f9,
-	0xe41ef406,
-	0x98f10b98,
-	0xcbbbf20c,
-	0xc4b7f102,
-	0x06b4b607,
-	0xfc00bbcf,
-	0xf5e0fcd0,
-	0xf8033621,
-/* 0x0729: memx_info */
-	0x01c67000,
-/* 0x072f: memx_info_data */
-	0xf10e0bf4,
-	0xf103ccc7,
-	0xf40800b7,
-/* 0x073a: memx_info_train */
-	0xc7f10b0e,
-	0xb7f10bcc,
-/* 0x0742: memx_info_send */
-	0x21f50100,
-	0x00f80336,
-/* 0x0748: memx_recv */
-	0xf401d6b0,
-	0xd6b0980b,
-	0xd80bf400,
-/* 0x0756: memx_init */
+	0x2077f02c,
+/* 0x0673: memx_func_wait_vblank_head0 */
+	0xf0060ef4,
+/* 0x0676: memx_func_wait_vblank_0 */
+	0x67f10877,
+	0x64b607c4,
+	0x0066cf06,
+	0xf40467fd,
+/* 0x0686: memx_func_wait_vblank_1 */
+	0x67f1f31b,
+	0x64b607c4,
+	0x0066cf06,
+	0xf40467fd,
+/* 0x0696: memx_func_wait_vblank_fini */
+	0x10b6f30b,
+/* 0x069b: memx_func_wr32 */
+	0x9800f804,
+	0x15980016,
+	0x0810b601,
+	0x50f960f9,
+	0xe0fcd0fc,
+	0xb64021f4,
+	0x1bf40242,
+/* 0x06b7: memx_func_wait */
+	0xf000f8e9,
+	0x84b62c87,
+	0x0088cf06,
+	0x98001e98,
+	0x1c98011d,
+	0x031b9802,
+	0xf41010b6,
+	0x00f8a321,
+/* 0x06d4: memx_func_delay */
+	0xb6001e98,
+	0x21f40410,
+/* 0x06df: memx_func_train */
+	0xf800f87e,
+/* 0x06e1: memx_exec */
+	0xf9e0f900,
+	0x02c1b9d0,
+/* 0x06eb: memx_exec_next */
+	0x9802b2b9,
+	0x10b60013,
+	0xf034e704,
+	0xe033e701,
+	0x0132b601,
+	0x980c30f0,
+	0x55f9de35,
+	0xf40612b8,
+	0x0b98e41e,
+	0xf20c98f1,
+	0xf102cbbb,
+	0xb607c4b7,
+	0xbbcf06b4,
+	0xfcd0fc00,
+	0x3621f5e0,
+/* 0x0727: memx_info */
+	0x7000f803,
+	0x0bf401c6,
+/* 0x072d: memx_info_data */
+	0xccc7f10e,
+	0x00b7f103,
+	0x0b0ef408,
+/* 0x0738: memx_info_train */
+	0x0bccc7f1,
+	0x0100b7f1,
+/* 0x0740: memx_info_send */
+	0x033621f5,
+/* 0x0746: memx_recv */
+	0xd6b000f8,
+	0x980bf401,
+	0xf400d6b0,
+	0x00f8d80b,
+/* 0x0754: memx_init */
+/* 0x0756: perf_recv */
 	0x00f800f8,
-/* 0x0758: perf_recv */
-/* 0x075a: perf_init */
-	0x00f800f8,
-/* 0x075c: i2c_drive_scl */
-	0xf40036b0,
-	0x07f1110b,
-	0x04b607e0,
-	0x0001d006,
-	0x00f804bd,
-/* 0x0770: i2c_drive_scl_lo */
-	0x07e407f1,
-	0xd00604b6,
-	0x04bd0001,
-/* 0x077e: i2c_drive_sda */
+/* 0x0758: perf_init */
+/* 0x075a: i2c_drive_scl */
 	0x36b000f8,
 	0x110bf400,
 	0x07e007f1,
 	0xd00604b6,
-	0x04bd0002,
-/* 0x0792: i2c_drive_sda_lo */
+	0x04bd0001,
+/* 0x076e: i2c_drive_scl_lo */
 	0x07f100f8,
 	0x04b607e4,
+	0x0001d006,
+	0x00f804bd,
+/* 0x077c: i2c_drive_sda */
+	0xf40036b0,
+	0x07f1110b,
+	0x04b607e0,
 	0x0002d006,
 	0x00f804bd,
-/* 0x07a0: i2c_sense_scl */
-	0xf10132f4,
-	0xb607c437,
-	0x33cf0634,
-	0x0431fd00,
-	0xf4060bf4,
-/* 0x07b6: i2c_sense_scl_done */
-	0x00f80131,
-/* 0x07b8: i2c_sense_sda */
-	0xf10132f4,
-	0xb607c437,
-	0x33cf0634,
-	0x0432fd00,
-	0xf4060bf4,
-/* 0x07ce: i2c_sense_sda_done */
-	0x00f80131,
-/* 0x07d0: i2c_raise_scl */
-	0x47f140f9,
-	0x37f00898,
-	0x5c21f501,
-/* 0x07dd: i2c_raise_scl_wait */
+/* 0x0790: i2c_drive_sda_lo */
+	0x07e407f1,
+	0xd00604b6,
+	0x04bd0002,
+/* 0x079e: i2c_sense_scl */
+	0x32f400f8,
+	0xc437f101,
+	0x0634b607,
+	0xfd0033cf,
+	0x0bf40431,
+	0x0131f406,
+/* 0x07b4: i2c_sense_scl_done */
+/* 0x07b6: i2c_sense_sda */
+	0x32f400f8,
+	0xc437f101,
+	0x0634b607,
+	0xfd0033cf,
+	0x0bf40432,
+	0x0131f406,
+/* 0x07cc: i2c_sense_sda_done */
+/* 0x07ce: i2c_raise_scl */
+	0x40f900f8,
+	0x089847f1,
+	0xf50137f0,
+/* 0x07db: i2c_raise_scl_wait */
+	0xf1075a21,
+	0xf403e8e7,
+	0x21f57e21,
+	0x01f4079e,
+	0x0142b609,
+/* 0x07ef: i2c_raise_scl_done */
+	0xfcef1bf4,
+/* 0x07f3: i2c_start */
+	0xf500f840,
+	0xf4079e21,
+	0x21f50d11,
+	0x11f407b6,
+	0x300ef406,
+/* 0x0804: i2c_start_rep */
+	0xf50037f0,
+	0xf0075a21,
+	0x21f50137,
+	0x76bb077c,
+	0x0465b600,
+	0x659450f9,
+	0x0256bb04,
+	0x75fd50bd,
+	0xf550fc04,
+	0xb607ce21,
+	0x11f40464,
+/* 0x0831: i2c_start_send */
+	0x0037f01f,
+	0x077c21f5,
+	0x1388e7f1,
+	0xf07e21f4,
+	0x21f50037,
+	0xe7f1075a,
+	0x21f41388,
+/* 0x084d: i2c_start_out */
+/* 0x084f: i2c_stop */
+	0xf000f87e,
+	0x21f50037,
+	0x37f0075a,
+	0x7c21f500,
 	0xe8e7f107,
 	0x7e21f403,
-	0x07a021f5,
-	0xb60901f4,
-	0x1bf40142,
-/* 0x07f1: i2c_raise_scl_done */
-	0xf840fcef,
-/* 0x07f5: i2c_start */
-	0xa021f500,
-	0x0d11f407,
-	0x07b821f5,
-	0xf40611f4,
-/* 0x0806: i2c_start_rep */
-	0x37f0300e,
-	0x5c21f500,
-	0x0137f007,
-	0x077e21f5,
-	0xb60076bb,
-	0x50f90465,
-	0xbb046594,
-	0x50bd0256,
-	0xfc0475fd,
-	0xd021f550,
-	0x0464b607,
-/* 0x0833: i2c_start_send */
-	0xf01f11f4,
-	0x21f50037,
-	0xe7f1077e,
-	0x21f41388,
-	0x0037f07e,
-	0x075c21f5,
-	0x1388e7f1,
-/* 0x084f: i2c_start_out */
-	0xf87e21f4,
-/* 0x0851: i2c_stop */
-	0x0037f000,
-	0x075c21f5,
-	0xf50037f0,
-	0xf1077e21,
-	0xf403e8e7,
-	0x37f07e21,
-	0x5c21f501,
-	0x88e7f107,
-	0x7e21f413,
 	0xf50137f0,
-	0xf1077e21,
+	0xf1075a21,
 	0xf41388e7,
-	0x00f87e21,
-/* 0x0884: i2c_bitw */
-	0x077e21f5,
-	0x03e8e7f1,
-	0xbb7e21f4,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x07d021f5,
-	0xf40464b6,
-	0xe7f11811,
-	0x21f41388,
-	0x0037f07e,
-	0x075c21f5,
-	0x1388e7f1,
-/* 0x08c3: i2c_bitw_out */
-	0xf87e21f4,
-/* 0x08c5: i2c_bitr */
-	0x0137f000,
-	0x077e21f5,
-	0x03e8e7f1,
-	0xbb7e21f4,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x07d021f5,
-	0xf40464b6,
-	0x21f51b11,
-	0x37f007b8,
-	0x5c21f500,
+	0x37f07e21,
+	0x7c21f501,
 	0x88e7f107,
 	0x7e21f413,
-	0xf4013cf0,
-/* 0x090a: i2c_bitr_done */
-	0x00f80131,
-/* 0x090c: i2c_get_byte */
-	0xf00057f0,
-/* 0x0912: i2c_get_byte_next */
-	0x54b60847,
-	0x0076bb01,
-	0xf90465b6,
-	0x04659450,
-	0xbd0256bb,
-	0x0475fd50,
-	0x21f550fc,
-	0x64b608c5,
-	0x2b11f404,
-	0xb60553fd,
-	0x1bf40142,
-	0x0137f0d8,
-	0xb60076bb,
-	0x50f90465,
-	0xbb046594,
-	0x50bd0256,
-	0xfc0475fd,
-	0x8421f550,
-	0x0464b608,
-/* 0x095c: i2c_get_byte_done */
-/* 0x095e: i2c_put_byte */
-	0x47f000f8,
-/* 0x0961: i2c_put_byte_next */
-	0x0142b608,
-	0xbb3854ff,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x088421f5,
-	0xf40464b6,
-	0x46b03411,
-	0xd81bf400,
-	0xb60076bb,
-	0x50f90465,
-	0xbb046594,
-	0x50bd0256,
-	0xfc0475fd,
-	0xc521f550,
-	0x0464b608,
-	0xbb0f11f4,
-	0x36b00076,
-	0x061bf401,
-/* 0x09b7: i2c_put_byte_done */
-	0xf80132f4,
-/* 0x09b9: i2c_addr */
-	0x0076bb00,
-	0xf90465b6,
-	0x04659450,
-	0xbd0256bb,
-	0x0475fd50,
-	0x21f550fc,
-	0x64b607f5,
-	0x2911f404,
-	0x012ec3e7,
-	0xfd0134b6,
-	0x76bb0553,
-	0x0465b600,
-	0x659450f9,
-	0x0256bb04,
-	0x75fd50bd,
-	0xf550fc04,
-	0xb6095e21,
-/* 0x09fe: i2c_addr_done */
-	0x00f80464,
-/* 0x0a00: i2c_acquire_addr */
-	0xb6f8cec7,
-	0xe0b702e4,
-	0xee980d1c,
-/* 0x0a0f: i2c_acquire */
-	0xf500f800,
-	0xf40a0021,
-	0xd9f00421,
-	0x4021f403,
-/* 0x0a1e: i2c_release */
+/* 0x0882: i2c_bitw */
 	0x21f500f8,
-	0x21f40a00,
-	0x03daf004,
-	0xf84021f4,
-/* 0x0a2d: i2c_recv */
-	0x0132f400,
-	0xb6f8c1c7,
-	0x16b00214,
-	0x3a1ff528,
-	0xf413a001,
-	0x0032980c,
-	0x0ccc13a0,
-	0xf4003198,
-	0xd0f90231,
-	0xd0f9e0f9,
-	0x000067f1,
-	0x100063f1,
-	0xbb016792,
+	0xe7f1077c,
+	0x21f403e8,
+	0x0076bb7e,
+	0xf90465b6,
+	0x04659450,
+	0xbd0256bb,
+	0x0475fd50,
+	0x21f550fc,
+	0x64b607ce,
+	0x1811f404,
+	0x1388e7f1,
+	0xf07e21f4,
+	0x21f50037,
+	0xe7f1075a,
+	0x21f41388,
+/* 0x08c1: i2c_bitw_out */
+/* 0x08c3: i2c_bitr */
+	0xf000f87e,
+	0x21f50137,
+	0xe7f1077c,
+	0x21f403e8,
+	0x0076bb7e,
+	0xf90465b6,
+	0x04659450,
+	0xbd0256bb,
+	0x0475fd50,
+	0x21f550fc,
+	0x64b607ce,
+	0x1b11f404,
+	0x07b621f5,
+	0xf50037f0,
+	0xf1075a21,
+	0xf41388e7,
+	0x3cf07e21,
+	0x0131f401,
+/* 0x0908: i2c_bitr_done */
+/* 0x090a: i2c_get_byte */
+	0x57f000f8,
+	0x0847f000,
+/* 0x0910: i2c_get_byte_next */
+	0xbb0154b6,
 	0x65b60076,
 	0x9450f904,
 	0x56bb0465,
 	0xfd50bd02,
 	0x50fc0475,
-	0x0a0f21f5,
-	0xfc0464b6,
-	0x00d6b0d0,
-	0x00b31bf5,
-	0xbb0057f0,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x09b921f5,
-	0xf50464b6,
-	0xc700d011,
-	0x76bbe0c5,
+	0x08c321f5,
+	0xf40464b6,
+	0x53fd2b11,
+	0x0142b605,
+	0xf0d81bf4,
+	0x76bb0137,
 	0x0465b600,
 	0x659450f9,
 	0x0256bb04,
 	0x75fd50bd,
 	0xf550fc04,
-	0xb6095e21,
-	0x11f50464,
-	0x57f000ad,
+	0xb6088221,
+/* 0x095a: i2c_get_byte_done */
+	0x00f80464,
+/* 0x095c: i2c_put_byte */
+/* 0x095f: i2c_put_byte_next */
+	0xb60847f0,
+	0x54ff0142,
+	0x0076bb38,
+	0xf90465b6,
+	0x04659450,
+	0xbd0256bb,
+	0x0475fd50,
+	0x21f550fc,
+	0x64b60882,
+	0x3411f404,
+	0xf40046b0,
+	0x76bbd81b,
+	0x0465b600,
+	0x659450f9,
+	0x0256bb04,
+	0x75fd50bd,
+	0xf550fc04,
+	0xb608c321,
+	0x11f40464,
+	0x0076bb0f,
+	0xf40136b0,
+	0x32f4061b,
+/* 0x09b5: i2c_put_byte_done */
+/* 0x09b7: i2c_addr */
+	0xbb00f801,
+	0x65b60076,
+	0x9450f904,
+	0x56bb0465,
+	0xfd50bd02,
+	0x50fc0475,
+	0x07f321f5,
+	0xf40464b6,
+	0xc3e72911,
+	0x34b6012e,
+	0x0553fd01,
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0x5c21f550,
+	0x0464b609,
+/* 0x09fc: i2c_addr_done */
+/* 0x09fe: i2c_acquire_addr */
+	0xcec700f8,
+	0x02e4b6f8,
+	0x0d1ce0b7,
+	0xf800ee98,
+/* 0x0a0d: i2c_acquire */
+	0xfe21f500,
+	0x0421f409,
+	0xf403d9f0,
+	0x00f84021,
+/* 0x0a1c: i2c_release */
+	0x09fe21f5,
+	0xf00421f4,
+	0x21f403da,
+/* 0x0a2b: i2c_recv */
+	0xf400f840,
+	0xc1c70132,
+	0x0214b6f8,
+	0xf52816b0,
+	0xa0013a1f,
+	0x980cf413,
+	0x13a00032,
+	0x31980ccc,
+	0x0231f400,
+	0xe0f9d0f9,
+	0x67f1d0f9,
+	0x63f10000,
+	0x67921000,
 	0x0076bb01,
 	0xf90465b6,
 	0x04659450,
 	0xbd0256bb,
 	0x0475fd50,
 	0x21f550fc,
-	0x64b609b9,
-	0x8a11f504,
+	0x64b60a0d,
+	0xb0d0fc04,
+	0x1bf500d6,
+	0x57f000b3,
 	0x0076bb00,
 	0xf90465b6,
 	0x04659450,
 	0xbd0256bb,
 	0x0475fd50,
 	0x21f550fc,
-	0x64b6090c,
-	0x6a11f404,
-	0xbbe05bcb,
+	0x64b609b7,
+	0xd011f504,
+	0xe0c5c700,
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0x5c21f550,
+	0x0464b609,
+	0x00ad11f5,
+	0xbb0157f0,
 	0x65b60076,
 	0x9450f904,
 	0x56bb0465,
 	0xfd50bd02,
 	0x50fc0475,
-	0x085121f5,
-	0xb90464b6,
-	0x74bd025b,
-/* 0x0b33: i2c_recv_not_rd08 */
-	0xb0430ef4,
-	0x1bf401d6,
-	0x0057f03d,
-	0x09b921f5,
-	0xc73311f4,
-	0x21f5e0c5,
-	0x11f4095e,
-	0x0057f029,
-	0x09b921f5,
-	0xc71f11f4,
-	0x21f5e0b5,
-	0x11f4095e,
-	0x5121f515,
-	0xc774bd08,
-	0x1bf408c5,
-	0x0232f409,
-/* 0x0b73: i2c_recv_not_wr08 */
-/* 0x0b73: i2c_recv_done */
-	0xc7030ef4,
-	0x21f5f8ce,
-	0xe0fc0a1e,
-	0x12f4d0fc,
-	0x027cb90a,
-	0x033621f5,
-/* 0x0b88: i2c_recv_exit */
-/* 0x0b8a: i2c_init */
-	0x00f800f8,
-/* 0x0b8c: test_recv */
-	0x05d817f1,
-	0xcf0614b6,
-	0x10b60011,
-	0xd807f101,
-	0x0604b605,
-	0xbd0001d0,
-	0x00e7f104,
-	0x4fe3f1d9,
-	0x5621f513,
-/* 0x0bb3: test_init */
-	0xf100f802,
-	0xf50800e7,
-	0xf8025621,
-/* 0x0bbd: idle_recv */
-/* 0x0bbf: idle */
-	0xf400f800,
-	0x17f10031,
-	0x14b605d4,
+	0x09b721f5,
+	0xf50464b6,
+	0xbb008a11,
+	0x65b60076,
+	0x9450f904,
+	0x56bb0465,
+	0xfd50bd02,
+	0x50fc0475,
+	0x090a21f5,
+	0xf40464b6,
+	0x5bcb6a11,
+	0x0076bbe0,
+	0xf90465b6,
+	0x04659450,
+	0xbd0256bb,
+	0x0475fd50,
+	0x21f550fc,
+	0x64b6084f,
+	0x025bb904,
+	0x0ef474bd,
+/* 0x0b31: i2c_recv_not_rd08 */
+	0x01d6b043,
+	0xf03d1bf4,
+	0x21f50057,
+	0x11f409b7,
+	0xe0c5c733,
+	0x095c21f5,
+	0xf02911f4,
+	0x21f50057,
+	0x11f409b7,
+	0xe0b5c71f,
+	0x095c21f5,
+	0xf51511f4,
+	0xbd084f21,
+	0x08c5c774,
+	0xf4091bf4,
+	0x0ef40232,
+/* 0x0b71: i2c_recv_not_wr08 */
+/* 0x0b71: i2c_recv_done */
+	0xf8cec703,
+	0x0a1c21f5,
+	0xd0fce0fc,
+	0xb90a12f4,
+	0x21f5027c,
+/* 0x0b86: i2c_recv_exit */
+	0x00f80336,
+/* 0x0b88: i2c_init */
+/* 0x0b8a: test_recv */
+	0x17f100f8,
+	0x14b605d8,
 	0x0011cf06,
 	0xf10110b6,
-	0xb605d407,
+	0xb605d807,
 	0x01d00604,
-/* 0x0bdb: idle_loop */
-	0xf004bd00,
-	0x32f45817,
-/* 0x0be1: idle_proc */
-/* 0x0be1: idle_proc_exec */
-	0xb910f902,
-	0x21f5021e,
-	0x10fc033f,
-	0xf40911f4,
-	0x0ef40231,
-/* 0x0bf5: idle_proc_next */
-	0x5810b6ef,
-	0xf4061fb8,
-	0x02f4e61b,
-	0x0028f4dd,
-	0x00bb0ef4,
+	0xf104bd00,
+	0xf1d900e7,
+	0xf5134fe3,
+	0xf8025621,
+/* 0x0bb1: test_init */
+	0x00e7f100,
+	0x5621f508,
+/* 0x0bbb: idle_recv */
+	0xf800f802,
+/* 0x0bbd: idle */
+	0x0031f400,
+	0x05d417f1,
+	0xcf0614b6,
+	0x10b60011,
+	0xd407f101,
+	0x0604b605,
+	0xbd0001d0,
+/* 0x0bd9: idle_loop */
+	0x5817f004,
+/* 0x0bdf: idle_proc */
+/* 0x0bdf: idle_proc_exec */
+	0xf90232f4,
+	0x021eb910,
+	0x033f21f5,
+	0x11f410fc,
+	0x0231f409,
+/* 0x0bf3: idle_proc_next */
+	0xb6ef0ef4,
+	0x1fb85810,
+	0xe61bf406,
+	0xf4dd02f4,
+	0x0ef40028,
+	0x000000bb,
 	0x00000000,
 	0x00000000,
 	0x00000000,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h
index c4edbc7..e0222cb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h
@@ -47,8 +47,8 @@ static uint32_t gk208_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x584d454d,
-	0x000005f3,
-	0x000005e5,
+	0x000005ee,
+	0x000005e0,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -69,8 +69,8 @@ static uint32_t gk208_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x46524550,
-	0x000005f7,
-	0x000005f5,
+	0x000005f2,
+	0x000005f0,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -91,8 +91,8 @@ static uint32_t gk208_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x5f433249,
-	0x000009f8,
-	0x000008a2,
+	0x000009f3,
+	0x0000089d,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -113,8 +113,8 @@ static uint32_t gk208_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x54534554,
-	0x00000a16,
-	0x000009fa,
+	0x00000a11,
+	0x000009f5,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -135,8 +135,8 @@ static uint32_t gk208_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x454c4449,
-	0x00000a21,
-	0x00000a1f,
+	0x00000a1c,
+	0x00000a1a,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -234,22 +234,22 @@ static uint32_t gk208_pmu_data[] = {
 /* 0x037c: memx_func_next */
 	0x00000002,
 	0x00000000,
-	0x000004cf,
+	0x000004cc,
 	0x00000003,
 	0x00000002,
-	0x00000546,
+	0x00000541,
 	0x00040004,
 	0x00000000,
-	0x00000563,
+	0x0000055e,
 	0x00010005,
 	0x00000000,
-	0x0000057d,
+	0x00000578,
 	0x00010006,
 	0x00000000,
-	0x00000541,
+	0x0000053c,
 	0x00000007,
 	0x00000000,
-	0x00000589,
+	0x00000584,
 /* 0x03c4: memx_func_tail */
 /* 0x03c4: memx_ts_start */
 	0x00000000,
@@ -1239,454 +1239,454 @@ static uint32_t gk208_pmu_code[] = {
 	0x0001f604,
 	0x00f804bd,
 /* 0x045c: memx_func_enter */
-	0x162067f1,
-	0xf55d77f1,
-	0x047e6eb2,
-	0xd8b20000,
-	0xf90487fd,
-	0xfc80f960,
-	0x7ee0fcd0,
-	0x0700002d,
-	0x7e6eb2fe,
+	0x47162046,
+	0x6eb2f55d,
+	0x0000047e,
+	0x87fdd8b2,
+	0xf960f904,
+	0xfcd0fc80,
+	0x002d7ee0,
+	0xb2fe0700,
+	0x00047e6e,
+	0xfdd8b200,
+	0x60f90487,
+	0xd0fc80f9,
+	0x2d7ee0fc,
+	0xf0460000,
+	0x7e6eb226,
 	0xb2000004,
 	0x0487fdd8,
 	0x80f960f9,
 	0xe0fcd0fc,
 	0x00002d7e,
-	0x26f067f1,
-	0x047e6eb2,
-	0xd8b20000,
-	0xf90487fd,
-	0xfc80f960,
-	0x7ee0fcd0,
-	0x0600002d,
-	0x07e04004,
-	0xbd0006f6,
-/* 0x04b9: memx_func_enter_wait */
-	0x07c04604,
-	0xf00066cf,
-	0x0bf40464,
-	0xcf2c06f7,
-	0x06b50066,
-/* 0x04cf: memx_func_leave */
-	0x0600f8f1,
-	0x0066cf2c,
-	0x06f206b5,
-	0x07e44004,
-	0xbd0006f6,
-/* 0x04e1: memx_func_leave_wait */
-	0x07c04604,
-	0xf00066cf,
-	0x1bf40464,
-	0xf067f1f7,
+	0xe0400406,
+	0x0006f607,
+/* 0x04b6: memx_func_enter_wait */
+	0xc04604bd,
+	0x0066cf07,
+	0xf40464f0,
+	0x2c06f70b,
+	0xb50066cf,
+	0x00f8f106,
+/* 0x04cc: memx_func_leave */
+	0x66cf2c06,
+	0xf206b500,
+	0xe4400406,
+	0x0006f607,
+/* 0x04de: memx_func_leave_wait */
+	0xc04604bd,
+	0x0066cf07,
+	0xf40464f0,
+	0xf046f71b,
 	0xb2010726,
 	0x00047e6e,
 	0xfdd8b200,
 	0x60f90587,
 	0xd0fc80f9,
 	0x2d7ee0fc,
-	0x67f10000,
-	0x6eb21620,
-	0x0000047e,
-	0x87fdd8b2,
-	0xf960f905,
-	0xfcd0fc80,
-	0x002d7ee0,
-	0x0aa24700,
-	0x047e6eb2,
-	0xd8b20000,
-	0xf90587fd,
-	0xfc80f960,
-	0x7ee0fcd0,
-	0xf800002d,
-/* 0x0541: memx_func_wait_vblank */
-	0x0410b600,
-/* 0x0546: memx_func_wr32 */
-	0x169800f8,
-	0x01159800,
-	0xf90810b6,
-	0xfc50f960,
-	0x7ee0fcd0,
-	0xb600002d,
-	0x1bf40242,
-/* 0x0563: memx_func_wait */
-	0x0800f8e8,
-	0x0088cf2c,
-	0x98001e98,
-	0x1c98011d,
-	0x031b9802,
-	0x7e1010b6,
-	0xf8000074,
-/* 0x057d: memx_func_delay */
-	0x001e9800,
-	0x7e0410b6,
-	0xf8000058,
-/* 0x0589: memx_func_train */
-/* 0x058b: memx_exec */
-	0xf900f800,
-	0xb2d0f9e0,
-/* 0x0593: memx_exec_next */
-	0x98b2b2c1,
-	0x10b60013,
-	0xf034e704,
-	0xe033e701,
-	0x0132b601,
-	0x980c30f0,
-	0x55f9de35,
-	0x1ef412a6,
-	0xf10b98e5,
-	0xbbf20c98,
-	0xc44b02cb,
-	0x00bbcf07,
+	0x20460000,
+	0x7e6eb216,
+	0xb2000004,
+	0x0587fdd8,
+	0x80f960f9,
 	0xe0fcd0fc,
-	0x00029f7e,
-/* 0x05ca: memx_info */
-	0xc67000f8,
-	0x0c0bf401,
-/* 0x05d0: memx_info_data */
-	0x4b03cc4c,
-	0x0ef40800,
-/* 0x05d9: memx_info_train */
-	0x0bcc4c09,
-/* 0x05df: memx_info_send */
-	0x7e01004b,
-	0xf800029f,
-/* 0x05e5: memx_recv */
-	0x01d6b000,
-	0xb0a30bf4,
-	0x0bf400d6,
-/* 0x05f3: memx_init */
-	0xf800f8dc,
-/* 0x05f5: perf_recv */
-/* 0x05f7: perf_init */
-	0xf800f800,
-/* 0x05f9: i2c_drive_scl */
-	0x0036b000,
-	0x400d0bf4,
-	0x01f607e0,
-	0xf804bd00,
-/* 0x0609: i2c_drive_scl_lo */
-	0x07e44000,
-	0xbd0001f6,
-/* 0x0613: i2c_drive_sda */
-	0xb000f804,
-	0x0bf40036,
-	0x07e0400d,
-	0xbd0002f6,
-/* 0x0623: i2c_drive_sda_lo */
-	0x4000f804,
-	0x02f607e4,
-	0xf804bd00,
-/* 0x062d: i2c_sense_scl */
-	0x0132f400,
-	0xcf07c443,
-	0x31fd0033,
-	0x060bf404,
-/* 0x063f: i2c_sense_scl_done */
-	0xf80131f4,
-/* 0x0641: i2c_sense_sda */
-	0x0132f400,
-	0xcf07c443,
-	0x32fd0033,
-	0x060bf404,
-/* 0x0653: i2c_sense_sda_done */
-	0xf80131f4,
-/* 0x0655: i2c_raise_scl */
-	0x4440f900,
-	0x01030898,
-	0x0005f97e,
-/* 0x0660: i2c_raise_scl_wait */
-	0x7e03e84e,
-	0x7e000058,
-	0xf400062d,
-	0x42b60901,
-	0xef1bf401,
-/* 0x0674: i2c_raise_scl_done */
-	0x00f840fc,
-/* 0x0678: i2c_start */
-	0x00062d7e,
-	0x7e0d11f4,
-	0xf4000641,
-	0x0ef40611,
-/* 0x0689: i2c_start_rep */
-	0x7e00032e,
-	0x030005f9,
-	0x06137e01,
-	0x0076bb00,
-	0xf90465b6,
-	0x04659450,
-	0xbd0256bb,
-	0x0475fd50,
-	0x557e50fc,
-	0x64b60006,
-	0x1d11f404,
-/* 0x06b4: i2c_start_send */
-	0x137e0003,
-	0x884e0006,
-	0x00587e13,
-	0x7e000300,
-	0x4e0005f9,
-	0x587e1388,
-/* 0x06ce: i2c_start_out */
+	0x00002d7e,
+	0xb20aa247,
+	0x00047e6e,
+	0xfdd8b200,
+	0x60f90587,
+	0xd0fc80f9,
+	0x2d7ee0fc,
 	0x00f80000,
-/* 0x06d0: i2c_stop */
-	0xf97e0003,
-	0x00030005,
-	0x0006137e,
-	0x7e03e84e,
-	0x03000058,
-	0x05f97e01,
+/* 0x053c: memx_func_wait_vblank */
+	0xf80410b6,
+/* 0x0541: memx_func_wr32 */
+	0x00169800,
+	0xb6011598,
+	0x60f90810,
+	0xd0fc50f9,
+	0x2d7ee0fc,
+	0x42b60000,
+	0xe81bf402,
+/* 0x055e: memx_func_wait */
+	0x2c0800f8,
+	0x980088cf,
+	0x1d98001e,
+	0x021c9801,
+	0xb6031b98,
+	0x747e1010,
+	0x00f80000,
+/* 0x0578: memx_func_delay */
+	0xb6001e98,
+	0x587e0410,
+	0x00f80000,
+/* 0x0584: memx_func_train */
+/* 0x0586: memx_exec */
+	0xe0f900f8,
+	0xc1b2d0f9,
+/* 0x058e: memx_exec_next */
+	0x1398b2b2,
+	0x0410b600,
+	0x01f034e7,
+	0x01e033e7,
+	0xf00132b6,
+	0x35980c30,
+	0xa655f9de,
+	0xe51ef412,
+	0x98f10b98,
+	0xcbbbf20c,
+	0x07c44b02,
+	0xfc00bbcf,
+	0x7ee0fcd0,
+	0xf800029f,
+/* 0x05c5: memx_info */
+	0x01c67000,
+/* 0x05cb: memx_info_data */
+	0x4c0c0bf4,
+	0x004b03cc,
+	0x090ef408,
+/* 0x05d4: memx_info_train */
+	0x4b0bcc4c,
+/* 0x05da: memx_info_send */
+	0x9f7e0100,
+	0x00f80002,
+/* 0x05e0: memx_recv */
+	0xf401d6b0,
+	0xd6b0a30b,
+	0xdc0bf400,
+/* 0x05ee: memx_init */
+	0x00f800f8,
+/* 0x05f0: perf_recv */
+/* 0x05f2: perf_init */
+	0x00f800f8,
+/* 0x05f4: i2c_drive_scl */
+	0xf40036b0,
+	0xe0400d0b,
+	0x0001f607,
+	0x00f804bd,
+/* 0x0604: i2c_drive_scl_lo */
+	0xf607e440,
+	0x04bd0001,
+/* 0x060e: i2c_drive_sda */
+	0x36b000f8,
+	0x0d0bf400,
+	0xf607e040,
+	0x04bd0002,
+/* 0x061e: i2c_drive_sda_lo */
+	0xe44000f8,
+	0x0002f607,
+	0x00f804bd,
+/* 0x0628: i2c_sense_scl */
+	0x430132f4,
+	0x33cf07c4,
+	0x0431fd00,
+	0xf4060bf4,
+/* 0x063a: i2c_sense_scl_done */
+	0x00f80131,
+/* 0x063c: i2c_sense_sda */
+	0x430132f4,
+	0x33cf07c4,
+	0x0432fd00,
+	0xf4060bf4,
+/* 0x064e: i2c_sense_sda_done */
+	0x00f80131,
+/* 0x0650: i2c_raise_scl */
+	0x984440f9,
+	0x7e010308,
+/* 0x065b: i2c_raise_scl_wait */
+	0x4e0005f4,
+	0x587e03e8,
+	0x287e0000,
+	0x01f40006,
+	0x0142b609,
+/* 0x066f: i2c_raise_scl_done */
+	0xfcef1bf4,
+/* 0x0673: i2c_start */
+	0x7e00f840,
+	0xf4000628,
+	0x3c7e0d11,
+	0x11f40006,
+	0x2e0ef406,
+/* 0x0684: i2c_start_rep */
+	0xf47e0003,
+	0x01030005,
+	0x00060e7e,
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0x06507e50,
+	0x0464b600,
+/* 0x06af: i2c_start_send */
+	0x031d11f4,
+	0x060e7e00,
 	0x13884e00,
 	0x0000587e,
-	0x137e0103,
-	0x884e0006,
-	0x00587e13,
-/* 0x06ff: i2c_bitw */
-	0x7e00f800,
-	0x4e000613,
-	0x587e03e8,
-	0x76bb0000,
-	0x0465b600,
-	0x659450f9,
-	0x0256bb04,
-	0x75fd50bd,
-	0x7e50fc04,
-	0xb6000655,
-	0x11f40464,
-	0x13884e17,
-	0x0000587e,
-	0xf97e0003,
+	0xf47e0003,
 	0x884e0005,
 	0x00587e13,
-/* 0x073d: i2c_bitw_out */
-/* 0x073f: i2c_bitr */
+/* 0x06c9: i2c_start_out */
+/* 0x06cb: i2c_stop */
 	0x0300f800,
-	0x06137e01,
-	0x03e84e00,
-	0x0000587e,
-	0xb60076bb,
-	0x50f90465,
-	0xbb046594,
-	0x50bd0256,
-	0xfc0475fd,
-	0x06557e50,
-	0x0464b600,
-	0x7e1a11f4,
-	0x03000641,
-	0x05f97e00,
+	0x05f47e00,
+	0x7e000300,
+	0x4e00060e,
+	0x587e03e8,
+	0x01030000,
+	0x0005f47e,
+	0x7e13884e,
+	0x03000058,
+	0x060e7e01,
 	0x13884e00,
 	0x0000587e,
-	0xf4013cf0,
-/* 0x0782: i2c_bitr_done */
-	0x00f80131,
-/* 0x0784: i2c_get_byte */
-	0x08040005,
-/* 0x0788: i2c_get_byte_next */
-	0xbb0154b6,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x00073f7e,
-	0xf40464b6,
-	0x53fd2a11,
-	0x0142b605,
-	0x03d81bf4,
-	0x0076bb01,
-	0xf90465b6,
-	0x04659450,
-	0xbd0256bb,
-	0x0475fd50,
-	0xff7e50fc,
-	0x64b60006,
-/* 0x07d1: i2c_get_byte_done */
-/* 0x07d3: i2c_put_byte */
-	0x0400f804,
-/* 0x07d5: i2c_put_byte_next */
-	0x0142b608,
-	0xbb3854ff,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x0006ff7e,
-	0xf40464b6,
-	0x46b03411,
-	0xd81bf400,
-	0xb60076bb,
-	0x50f90465,
-	0xbb046594,
-	0x50bd0256,
-	0xfc0475fd,
-	0x073f7e50,
-	0x0464b600,
-	0xbb0f11f4,
-	0x36b00076,
-	0x061bf401,
-/* 0x082b: i2c_put_byte_done */
-	0xf80132f4,
-/* 0x082d: i2c_addr */
+/* 0x06fa: i2c_bitw */
+	0x0e7e00f8,
+	0xe84e0006,
+	0x00587e03,
 	0x0076bb00,
 	0xf90465b6,
 	0x04659450,
 	0xbd0256bb,
 	0x0475fd50,
-	0x787e50fc,
+	0x507e50fc,
 	0x64b60006,
-	0x2911f404,
-	0x012ec3e7,
-	0xfd0134b6,
-	0x76bb0553,
-	0x0465b600,
-	0x659450f9,
-	0x0256bb04,
-	0x75fd50bd,
-	0x7e50fc04,
-	0xb60007d3,
-/* 0x0872: i2c_addr_done */
-	0x00f80464,
-/* 0x0874: i2c_acquire_addr */
-	0xb6f8cec7,
-	0xe0b705e4,
-	0x00f8d014,
-/* 0x0880: i2c_acquire */
-	0x0008747e,
-	0x0000047e,
-	0x7e03d9f0,
-	0xf800002d,
-/* 0x0891: i2c_release */
-	0x08747e00,
-	0x00047e00,
-	0x03daf000,
-	0x00002d7e,
-/* 0x08a2: i2c_recv */
-	0x32f400f8,
-	0xf8c1c701,
-	0xb00214b6,
-	0x1ff52816,
-	0x13b80134,
-	0x98000cf4,
-	0x13b80032,
-	0x98000ccc,
-	0x31f40031,
-	0xf9d0f902,
-	0xd6d0f9e0,
-	0x10000000,
-	0xbb016792,
+	0x1711f404,
+	0x7e13884e,
+	0x03000058,
+	0x05f47e00,
+	0x13884e00,
+	0x0000587e,
+/* 0x0738: i2c_bitw_out */
+/* 0x073a: i2c_bitr */
+	0x010300f8,
+	0x00060e7e,
+	0x7e03e84e,
+	0xbb000058,
 	0x65b60076,
 	0x9450f904,
 	0x56bb0465,
 	0xfd50bd02,
 	0x50fc0475,
-	0x0008807e,
-	0xfc0464b6,
-	0x00d6b0d0,
-	0x00b01bf5,
-	0x76bb0005,
-	0x0465b600,
-	0x659450f9,
-	0x0256bb04,
-	0x75fd50bd,
-	0x7e50fc04,
-	0xb600082d,
-	0x11f50464,
-	0xc5c700cc,
-	0x0076bbe0,
-	0xf90465b6,
-	0x04659450,
-	0xbd0256bb,
-	0x0475fd50,
-	0xd37e50fc,
-	0x64b60007,
-	0xa911f504,
-	0xbb010500,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x00082d7e,
-	0xf50464b6,
-	0xbb008711,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x0007847e,
+	0x0006507e,
 	0xf40464b6,
-	0x5bcb6711,
-	0x0076bbe0,
+	0x3c7e1a11,
+	0x00030006,
+	0x0005f47e,
+	0x7e13884e,
+	0xf0000058,
+	0x31f4013c,
+/* 0x077d: i2c_bitr_done */
+/* 0x077f: i2c_get_byte */
+	0x0500f801,
+/* 0x0783: i2c_get_byte_next */
+	0xb6080400,
+	0x76bb0154,
+	0x0465b600,
+	0x659450f9,
+	0x0256bb04,
+	0x75fd50bd,
+	0x7e50fc04,
+	0xb600073a,
+	0x11f40464,
+	0x0553fd2a,
+	0xf40142b6,
+	0x0103d81b,
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0x06fa7e50,
+	0x0464b600,
+/* 0x07cc: i2c_get_byte_done */
+/* 0x07ce: i2c_put_byte */
+	0x080400f8,
+/* 0x07d0: i2c_put_byte_next */
+	0xff0142b6,
+	0x76bb3854,
+	0x0465b600,
+	0x659450f9,
+	0x0256bb04,
+	0x75fd50bd,
+	0x7e50fc04,
+	0xb60006fa,
+	0x11f40464,
+	0x0046b034,
+	0xbbd81bf4,
+	0x65b60076,
+	0x9450f904,
+	0x56bb0465,
+	0xfd50bd02,
+	0x50fc0475,
+	0x00073a7e,
+	0xf40464b6,
+	0x76bb0f11,
+	0x0136b000,
+	0xf4061bf4,
+/* 0x0826: i2c_put_byte_done */
+	0x00f80132,
+/* 0x0828: i2c_addr */
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0x06737e50,
+	0x0464b600,
+	0xe72911f4,
+	0xb6012ec3,
+	0x53fd0134,
+	0x0076bb05,
 	0xf90465b6,
 	0x04659450,
 	0xbd0256bb,
 	0x0475fd50,
-	0xd07e50fc,
-	0x64b60006,
-	0xbd5bb204,
-	0x410ef474,
-/* 0x09a4: i2c_recv_not_rd08 */
-	0xf401d6b0,
-	0x00053b1b,
-	0x00082d7e,
-	0xc73211f4,
-	0xd37ee0c5,
-	0x11f40007,
-	0x7e000528,
-	0xf400082d,
-	0xb5c71f11,
-	0x07d37ee0,
-	0x1511f400,
-	0x0006d07e,
-	0xc5c774bd,
-	0x091bf408,
-	0xf40232f4,
-/* 0x09e2: i2c_recv_not_wr08 */
-/* 0x09e2: i2c_recv_done */
-	0xcec7030e,
-	0x08917ef8,
-	0xfce0fc00,
-	0x0912f4d0,
-	0x9f7e7cb2,
-/* 0x09f6: i2c_recv_exit */
-	0x00f80002,
-/* 0x09f8: i2c_init */
-/* 0x09fa: test_recv */
-	0x584100f8,
-	0x0011cf04,
-	0x400110b6,
-	0x01f60458,
-	0xde04bd00,
-	0x134fd900,
-	0x0001de7e,
-/* 0x0a16: test_init */
-	0x004e00f8,
-	0x01de7e08,
-/* 0x0a1f: idle_recv */
+	0xce7e50fc,
+	0x64b60007,
+/* 0x086d: i2c_addr_done */
+/* 0x086f: i2c_acquire_addr */
+	0xc700f804,
+	0xe4b6f8ce,
+	0x14e0b705,
+/* 0x087b: i2c_acquire */
+	0x7e00f8d0,
+	0x7e00086f,
+	0xf0000004,
+	0x2d7e03d9,
+	0x00f80000,
+/* 0x088c: i2c_release */
+	0x00086f7e,
+	0x0000047e,
+	0x7e03daf0,
+	0xf800002d,
+/* 0x089d: i2c_recv */
+	0x0132f400,
+	0xb6f8c1c7,
+	0x16b00214,
+	0x341ff528,
+	0xf413b801,
+	0x3298000c,
+	0xcc13b800,
+	0x3198000c,
+	0x0231f400,
+	0xe0f9d0f9,
+	0x00d6d0f9,
+	0x92100000,
+	0x76bb0167,
+	0x0465b600,
+	0x659450f9,
+	0x0256bb04,
+	0x75fd50bd,
+	0x7e50fc04,
+	0xb600087b,
+	0xd0fc0464,
+	0xf500d6b0,
+	0x0500b01b,
+	0x0076bb00,
+	0xf90465b6,
+	0x04659450,
+	0xbd0256bb,
+	0x0475fd50,
+	0x287e50fc,
+	0x64b60008,
+	0xcc11f504,
+	0xe0c5c700,
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0x07ce7e50,
+	0x0464b600,
+	0x00a911f5,
+	0x76bb0105,
+	0x0465b600,
+	0x659450f9,
+	0x0256bb04,
+	0x75fd50bd,
+	0x7e50fc04,
+	0xb6000828,
+	0x11f50464,
+	0x76bb0087,
+	0x0465b600,
+	0x659450f9,
+	0x0256bb04,
+	0x75fd50bd,
+	0x7e50fc04,
+	0xb600077f,
+	0x11f40464,
+	0xe05bcb67,
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0x06cb7e50,
+	0x0464b600,
+	0x74bd5bb2,
+/* 0x099f: i2c_recv_not_rd08 */
+	0xb0410ef4,
+	0x1bf401d6,
+	0x7e00053b,
+	0xf4000828,
+	0xc5c73211,
+	0x07ce7ee0,
+	0x2811f400,
+	0x287e0005,
+	0x11f40008,
+	0xe0b5c71f,
+	0x0007ce7e,
+	0x7e1511f4,
+	0xbd0006cb,
+	0x08c5c774,
+	0xf4091bf4,
+	0x0ef40232,
+/* 0x09dd: i2c_recv_not_wr08 */
+/* 0x09dd: i2c_recv_done */
+	0xf8cec703,
+	0x00088c7e,
+	0xd0fce0fc,
+	0xb20912f4,
+	0x029f7e7c,
+/* 0x09f1: i2c_recv_exit */
+/* 0x09f3: i2c_init */
 	0xf800f800,
-/* 0x0a21: idle */
-	0x0031f400,
-	0xcf045441,
-	0x10b60011,
-	0x04544001,
-	0xbd0001f6,
-/* 0x0a35: idle_loop */
-	0xf4580104,
-/* 0x0a3a: idle_proc */
-/* 0x0a3a: idle_proc_exec */
-	0x10f90232,
-	0xa87e1eb2,
-	0x10fc0002,
-	0xf40911f4,
-	0x0ef40231,
-/* 0x0a4d: idle_proc_next */
-	0x5810b6f0,
-	0x1bf41fa6,
-	0xe002f4e8,
-	0xf40028f4,
-	0x0000c60e,
+/* 0x09f5: test_recv */
+	0x04584100,
+	0xb60011cf,
+	0x58400110,
+	0x0001f604,
+	0x00de04bd,
+	0x7e134fd9,
+	0xf80001de,
+/* 0x0a11: test_init */
+	0x08004e00,
+	0x0001de7e,
+/* 0x0a1a: idle_recv */
+	0x00f800f8,
+/* 0x0a1c: idle */
+	0x410031f4,
+	0x11cf0454,
+	0x0110b600,
+	0xf6045440,
+	0x04bd0001,
+/* 0x0a30: idle_loop */
+	0x32f45801,
+/* 0x0a35: idle_proc */
+/* 0x0a35: idle_proc_exec */
+	0xb210f902,
+	0x02a87e1e,
+	0xf410fc00,
+	0x31f40911,
+	0xf00ef402,
+/* 0x0a48: idle_proc_next */
+	0xa65810b6,
+	0xe81bf41f,
+	0xf4e002f4,
+	0x0ef40028,
+	0x000000c6,
+	0x00000000,
 	0x00000000,
 	0x00000000,
 	0x00000000,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h
index 6a2572e..defddf59 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h
@@ -47,8 +47,8 @@ static uint32_t gt215_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x584d454d,
-	0x0000083a,
-	0x0000082c,
+	0x00000833,
+	0x00000825,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -69,8 +69,8 @@ static uint32_t gt215_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x46524550,
-	0x0000083e,
-	0x0000083c,
+	0x00000837,
+	0x00000835,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -91,8 +91,8 @@ static uint32_t gt215_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x5f433249,
-	0x00000c6e,
-	0x00000b11,
+	0x00000c67,
+	0x00000b0a,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -113,8 +113,8 @@ static uint32_t gt215_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x54534554,
-	0x00000c97,
-	0x00000c70,
+	0x00000c90,
+	0x00000c69,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -135,8 +135,8 @@ static uint32_t gt215_pmu_data[] = {
 	0x00000000,
 	0x00000000,
 	0x454c4449,
-	0x00000ca3,
-	0x00000ca1,
+	0x00000c9c,
+	0x00000c9a,
 	0x00000000,
 	0x00000000,
 	0x00000000,
@@ -234,22 +234,22 @@ static uint32_t gt215_pmu_data[] = {
 /* 0x037c: memx_func_next */
 	0x00000002,
 	0x00000000,
-	0x000005a0,
+	0x0000059f,
 	0x00000003,
 	0x00000002,
-	0x00000632,
+	0x0000062f,
 	0x00040004,
 	0x00000000,
-	0x0000064e,
+	0x0000064b,
 	0x00010005,
 	0x00000000,
-	0x0000066b,
+	0x00000668,
 	0x00010006,
 	0x00000000,
-	0x000005f0,
+	0x000005ef,
 	0x00000007,
 	0x00000000,
-	0x00000676,
+	0x00000673,
 /* 0x03c4: memx_func_tail */
 /* 0x03c4: memx_ts_start */
 	0x00000000,
@@ -1305,560 +1305,560 @@ static uint32_t gt215_pmu_code[] = {
 	0x67f102d7,
 	0x63f1fffc,
 	0x76fdffff,
-	0x0267f104,
-	0x0576fd00,
-	0x70f980f9,
-	0xe0fcd0fc,
-	0xf04021f4,
+	0x0267f004,
+	0xf90576fd,
+	0xfc70f980,
+	0xf4e0fcd0,
+	0x67f04021,
+	0xe007f104,
+	0x0604b607,
+	0xbd0006d0,
+/* 0x0581: memx_func_enter_wait */
+	0xc067f104,
+	0x0664b607,
+	0xf00066cf,
+	0x0bf40464,
+	0x2c67f0f3,
+	0xcf0664b6,
+	0x06800066,
+/* 0x059f: memx_func_leave */
+	0xf000f8f1,
+	0x64b62c67,
+	0x0066cf06,
+	0xf0f20680,
 	0x07f10467,
-	0x04b607e0,
+	0x04b607e4,
 	0x0006d006,
-/* 0x0582: memx_func_enter_wait */
+/* 0x05ba: memx_func_leave_wait */
 	0x67f104bd,
 	0x64b607c0,
 	0x0066cf06,
 	0xf40464f0,
-	0x67f0f30b,
-	0x0664b62c,
-	0x800066cf,
-	0x00f8f106,
-/* 0x05a0: memx_func_leave */
-	0xb62c67f0,
-	0x66cf0664,
-	0xf2068000,
-	0xf10467f0,
-	0xb607e407,
-	0x06d00604,
-/* 0x05bb: memx_func_leave_wait */
-	0xf104bd00,
-	0xb607c067,
-	0x66cf0664,
-	0x0464f000,
-	0xf1f31bf4,
-	0xb9161087,
-	0x21f4028e,
-	0x02d7b904,
-	0xffcc67f1,
-	0xffff63f1,
-	0xf90476fd,
-	0xfc70f980,
-	0xf4e0fcd0,
-	0x00f84021,
-/* 0x05f0: memx_func_wait_vblank */
-	0xb0001698,
-	0x0bf40066,
-	0x0166b013,
-	0xf4060bf4,
-/* 0x0602: memx_func_wait_vblank_head1 */
-	0x77f12e0e,
-	0x0ef40020,
-/* 0x0609: memx_func_wait_vblank_head0 */
-	0x0877f107,
-/* 0x060d: memx_func_wait_vblank_0 */
-	0xc467f100,
-	0x0664b607,
-	0xfd0066cf,
-	0x1bf40467,
-/* 0x061d: memx_func_wait_vblank_1 */
-	0xc467f1f3,
-	0x0664b607,
-	0xfd0066cf,
-	0x0bf40467,
-/* 0x062d: memx_func_wait_vblank_fini */
-	0x0410b6f3,
-/* 0x0632: memx_func_wr32 */
-	0x169800f8,
-	0x01159800,
-	0xf90810b6,
-	0xfc50f960,
-	0xf4e0fcd0,
-	0x42b64021,
-	0xe91bf402,
-/* 0x064e: memx_func_wait */
-	0x87f000f8,
-	0x0684b62c,
-	0x980088cf,
-	0x1d98001e,
-	0x021c9801,
-	0xb6031b98,
-	0x21f41010,
-/* 0x066b: memx_func_delay */
-	0x9800f8a3,
-	0x10b6001e,
-	0x7e21f404,
-/* 0x0676: memx_func_train */
-	0x57f100f8,
-	0x77f10003,
-	0x97f10000,
-	0x93f00000,
-	0x029eb970,
-	0xb90421f4,
-	0xe7f102d8,
-	0x21f42710,
-/* 0x0695: memx_func_train_loop_outer */
-	0x0158e07e,
-	0x0083f101,
-	0xe097f102,
-	0x1193f011,
-	0x80f990f9,
+	0x87f1f31b,
+	0x8eb91610,
+	0x0421f402,
+	0xf102d7b9,
+	0xf1ffcc67,
+	0xfdffff63,
+	0x80f90476,
+	0xd0fc70f9,
+	0x21f4e0fc,
+/* 0x05ef: memx_func_wait_vblank */
+	0x9800f840,
+	0x66b00016,
+	0x120bf400,
+	0xf40166b0,
+	0x0ef4060b,
+/* 0x0601: memx_func_wait_vblank_head1 */
+	0x2077f02c,
+/* 0x0607: memx_func_wait_vblank_head0 */
+	0xf0060ef4,
+/* 0x060a: memx_func_wait_vblank_0 */
+	0x67f10877,
+	0x64b607c4,
+	0x0066cf06,
+	0xf40467fd,
+/* 0x061a: memx_func_wait_vblank_1 */
+	0x67f1f31b,
+	0x64b607c4,
+	0x0066cf06,
+	0xf40467fd,
+/* 0x062a: memx_func_wait_vblank_fini */
+	0x10b6f30b,
+/* 0x062f: memx_func_wr32 */
+	0x9800f804,
+	0x15980016,
+	0x0810b601,
+	0x50f960f9,
 	0xe0fcd0fc,
-	0xf94021f4,
-	0x0067f150,
-/* 0x06b5: memx_func_train_loop_inner */
-	0x1187f100,
-	0x9068ff11,
-	0xfd109894,
-	0x97f10589,
-	0x93f00720,
-	0xf990f910,
-	0xfcd0fc80,
-	0x4021f4e0,
-	0x008097f1,
-	0xb91093f0,
-	0x21f4029e,
-	0x02d8b904,
-	0xf92088c5,
+	0xb64021f4,
+	0x1bf40242,
+/* 0x064b: memx_func_wait */
+	0xf000f8e9,
+	0x84b62c87,
+	0x0088cf06,
+	0x98001e98,
+	0x1c98011d,
+	0x031b9802,
+	0xf41010b6,
+	0x00f8a321,
+/* 0x0668: memx_func_delay */
+	0xb6001e98,
+	0x21f40410,
+/* 0x0673: memx_func_train */
+	0xf000f87e,
+	0x77f00357,
+	0x0097f100,
+	0x7093f000,
+	0xf4029eb9,
+	0xd8b90421,
+	0x10e7f102,
+	0x7e21f427,
+/* 0x0690: memx_func_train_loop_outer */
+	0x010158e0,
+	0x020083f1,
+	0x11e097f1,
+	0xf91193f0,
+	0xfc80f990,
+	0xf4e0fcd0,
+	0x50f94021,
+/* 0x06af: memx_func_train_loop_inner */
+	0xf10067f0,
+	0xff111187,
+	0x98949068,
+	0x0589fd10,
+	0x072097f1,
+	0xf91093f0,
 	0xfc80f990,
 	0xf4e0fcd0,
 	0x97f14021,
-	0x93f0053c,
-	0x0287f110,
-	0x0083f130,
-	0xf990f980,
+	0x93f00080,
+	0x029eb910,
+	0xb90421f4,
+	0x88c502d8,
+	0xf990f920,
 	0xfcd0fc80,
 	0x4021f4e0,
-	0x0560e7f1,
-	0xf110e3f0,
-	0xf10000d7,
-	0x908000d3,
-	0xb7f100dc,
-	0xb3f08480,
-	0xa321f41e,
-	0x000057f1,
-	0xffff97f1,
-	0x830093f1,
-/* 0x0734: memx_func_train_loop_4x */
-	0x0080a7f1,
-	0xb910a3f0,
-	0x21f402ae,
-	0x02d8b904,
-	0xffdfb7f1,
-	0xffffb3f1,
-	0xf9048bfd,
-	0xfc80f9a0,
+	0x053c97f1,
+	0xf11093f0,
+	0xf1300287,
+	0xf9800083,
+	0xfc80f990,
 	0xf4e0fcd0,
-	0xa7f14021,
-	0xa3f0053c,
-	0x0287f110,
-	0x0083f130,
-	0xf9a0f980,
-	0xfcd0fc80,
-	0x4021f4e0,
-	0x0560e7f1,
-	0xf110e3f0,
-	0xf10000d7,
-	0xb98000d3,
-	0xb7f102dc,
-	0xb3f02710,
-	0xa321f400,
-	0xf402eeb9,
-	0xddb90421,
-	0x949dff02,
+	0xe7f14021,
+	0xe3f00560,
+	0x00d7f110,
+	0x00d3f100,
+	0x00dc9080,
+	0x8480b7f1,
+	0xf41eb3f0,
+	0x57f0a321,
+	0xff97f100,
+	0x0093f1ff,
+/* 0x072d: memx_func_train_loop_4x */
+	0x80a7f183,
+	0x10a3f000,
+	0xf402aeb9,
+	0xd8b90421,
+	0xdfb7f102,
+	0xffb3f1ff,
+	0x048bfdff,
+	0x80f9a0f9,
+	0xe0fcd0fc,
+	0xf14021f4,
+	0xf0053ca7,
+	0x87f110a3,
+	0x83f13002,
+	0xa0f98000,
+	0xd0fc80f9,
+	0x21f4e0fc,
+	0x60e7f140,
+	0x10e3f005,
+	0x0000d7f1,
+	0x8000d3f1,
+	0xf102dcb9,
+	0xf02710b7,
+	0x21f400b3,
+	0x02eeb9a3,
+	0xb90421f4,
+	0x9dff02dd,
+	0x0150b694,
+	0xf4045670,
+	0x7aa0921e,
+	0xa9800bcc,
+	0x0160b600,
+	0x700470b6,
+	0x1ef51066,
+	0x50fcff01,
 	0x700150b6,
-	0x1ef40456,
-	0xcc7aa092,
-	0x00a9800b,
-	0xb60160b6,
-	0x66700470,
-	0x001ef510,
-	0xb650fcff,
-	0x56700150,
-	0xd41ef507,
-/* 0x07c7: memx_exec */
-	0xf900f8fe,
-	0xb9d0f9e0,
-	0xb2b902c1,
-/* 0x07d1: memx_exec_next */
-	0x00139802,
-	0xe70410b6,
-	0xe701f034,
-	0xb601e033,
-	0x30f00132,
-	0xde35980c,
-	0x12b855f9,
-	0xe41ef406,
-	0x98f10b98,
-	0xcbbbf20c,
-	0xc4b7f102,
-	0x06b4b607,
-	0xfc00bbcf,
-	0xf5e0fcd0,
+	0x1ef50756,
+	0x00f8fed6,
+/* 0x07c0: memx_exec */
+	0xd0f9e0f9,
+	0xb902c1b9,
+/* 0x07ca: memx_exec_next */
+	0x139802b2,
+	0x0410b600,
+	0x01f034e7,
+	0x01e033e7,
+	0xf00132b6,
+	0x35980c30,
+	0xb855f9de,
+	0x1ef40612,
+	0xf10b98e4,
+	0xbbf20c98,
+	0xb7f102cb,
+	0xb4b607c4,
+	0x00bbcf06,
+	0xe0fcd0fc,
+	0x033621f5,
+/* 0x0806: memx_info */
+	0xc67000f8,
+	0x0e0bf401,
+/* 0x080c: memx_info_data */
+	0x03ccc7f1,
+	0x0800b7f1,
+/* 0x0817: memx_info_train */
+	0xf10b0ef4,
+	0xf10bccc7,
+/* 0x081f: memx_info_send */
+	0xf50100b7,
 	0xf8033621,
-/* 0x080d: memx_info */
-	0x01c67000,
-/* 0x0813: memx_info_data */
-	0xf10e0bf4,
-	0xf103ccc7,
-	0xf40800b7,
-/* 0x081e: memx_info_train */
-	0xc7f10b0e,
-	0xb7f10bcc,
-/* 0x0826: memx_info_send */
-	0x21f50100,
-	0x00f80336,
-/* 0x082c: memx_recv */
-	0xf401d6b0,
-	0xd6b0980b,
-	0xd80bf400,
-/* 0x083a: memx_init */
-	0x00f800f8,
-/* 0x083c: perf_recv */
-/* 0x083e: perf_init */
-	0x00f800f8,
-/* 0x0840: i2c_drive_scl */
-	0xf40036b0,
-	0x07f1110b,
-	0x04b607e0,
-	0x0001d006,
-	0x00f804bd,
-/* 0x0854: i2c_drive_scl_lo */
-	0x07e407f1,
-	0xd00604b6,
-	0x04bd0001,
-/* 0x0862: i2c_drive_sda */
-	0x36b000f8,
-	0x110bf400,
-	0x07e007f1,
-	0xd00604b6,
-	0x04bd0002,
-/* 0x0876: i2c_drive_sda_lo */
-	0x07f100f8,
-	0x04b607e4,
-	0x0002d006,
-	0x00f804bd,
-/* 0x0884: i2c_sense_scl */
-	0xf10132f4,
-	0xb607c437,
-	0x33cf0634,
-	0x0431fd00,
-	0xf4060bf4,
-/* 0x089a: i2c_sense_scl_done */
-	0x00f80131,
-/* 0x089c: i2c_sense_sda */
-	0xf10132f4,
-	0xb607c437,
-	0x33cf0634,
-	0x0432fd00,
-	0xf4060bf4,
-/* 0x08b2: i2c_sense_sda_done */
-	0x00f80131,
-/* 0x08b4: i2c_raise_scl */
-	0x47f140f9,
-	0x37f00898,
-	0x4021f501,
-/* 0x08c1: i2c_raise_scl_wait */
+/* 0x0825: memx_recv */
+	0x01d6b000,
+	0xb0980bf4,
+	0x0bf400d6,
+/* 0x0833: memx_init */
+	0xf800f8d8,
+/* 0x0835: perf_recv */
+/* 0x0837: perf_init */
+	0xf800f800,
+/* 0x0839: i2c_drive_scl */
+	0x0036b000,
+	0xf1110bf4,
+	0xb607e007,
+	0x01d00604,
+	0xf804bd00,
+/* 0x084d: i2c_drive_scl_lo */
+	0xe407f100,
+	0x0604b607,
+	0xbd0001d0,
+/* 0x085b: i2c_drive_sda */
+	0xb000f804,
+	0x0bf40036,
+	0xe007f111,
+	0x0604b607,
+	0xbd0002d0,
+/* 0x086f: i2c_drive_sda_lo */
+	0xf100f804,
+	0xb607e407,
+	0x02d00604,
+	0xf804bd00,
+/* 0x087d: i2c_sense_scl */
+	0x0132f400,
+	0x07c437f1,
+	0xcf0634b6,
+	0x31fd0033,
+	0x060bf404,
+/* 0x0893: i2c_sense_scl_done */
+	0xf80131f4,
+/* 0x0895: i2c_sense_sda */
+	0x0132f400,
+	0x07c437f1,
+	0xcf0634b6,
+	0x32fd0033,
+	0x060bf404,
+/* 0x08ab: i2c_sense_sda_done */
+	0xf80131f4,
+/* 0x08ad: i2c_raise_scl */
+	0xf140f900,
+	0xf0089847,
+	0x21f50137,
+/* 0x08ba: i2c_raise_scl_wait */
+	0xe7f10839,
+	0x21f403e8,
+	0x7d21f57e,
+	0x0901f408,
+	0xf40142b6,
+/* 0x08ce: i2c_raise_scl_done */
+	0x40fcef1b,
+/* 0x08d2: i2c_start */
+	0x21f500f8,
+	0x11f4087d,
+	0x9521f50d,
+	0x0611f408,
+/* 0x08e3: i2c_start_rep */
+	0xf0300ef4,
+	0x21f50037,
+	0x37f00839,
+	0x5b21f501,
+	0x0076bb08,
+	0xf90465b6,
+	0x04659450,
+	0xbd0256bb,
+	0x0475fd50,
+	0x21f550fc,
+	0x64b608ad,
+	0x1f11f404,
+/* 0x0910: i2c_start_send */
+	0xf50037f0,
+	0xf1085b21,
+	0xf41388e7,
+	0x37f07e21,
+	0x3921f500,
+	0x88e7f108,
+	0x7e21f413,
+/* 0x092c: i2c_start_out */
+/* 0x092e: i2c_stop */
+	0x37f000f8,
+	0x3921f500,
+	0x0037f008,
+	0x085b21f5,
+	0x03e8e7f1,
+	0xf07e21f4,
+	0x21f50137,
+	0xe7f10839,
+	0x21f41388,
+	0x0137f07e,
+	0x085b21f5,
+	0x1388e7f1,
+	0xf87e21f4,
+/* 0x0961: i2c_bitw */
+	0x5b21f500,
 	0xe8e7f108,
 	0x7e21f403,
-	0x088421f5,
-	0xb60901f4,
-	0x1bf40142,
-/* 0x08d5: i2c_raise_scl_done */
-	0xf840fcef,
-/* 0x08d9: i2c_start */
-	0x8421f500,
-	0x0d11f408,
-	0x089c21f5,
-	0xf40611f4,
-/* 0x08ea: i2c_start_rep */
-	0x37f0300e,
-	0x4021f500,
-	0x0137f008,
-	0x086221f5,
 	0xb60076bb,
 	0x50f90465,
 	0xbb046594,
 	0x50bd0256,
 	0xfc0475fd,
-	0xb421f550,
+	0xad21f550,
 	0x0464b608,
-/* 0x0917: i2c_start_send */
-	0xf01f11f4,
-	0x21f50037,
-	0xe7f10862,
-	0x21f41388,
-	0x0037f07e,
-	0x084021f5,
-	0x1388e7f1,
-/* 0x0933: i2c_start_out */
-	0xf87e21f4,
-/* 0x0935: i2c_stop */
-	0x0037f000,
-	0x084021f5,
-	0xf50037f0,
-	0xf1086221,
-	0xf403e8e7,
-	0x37f07e21,
-	0x4021f501,
-	0x88e7f108,
-	0x7e21f413,
-	0xf50137f0,
-	0xf1086221,
+	0xf11811f4,
 	0xf41388e7,
-	0x00f87e21,
-/* 0x0968: i2c_bitw */
-	0x086221f5,
-	0x03e8e7f1,
-	0xbb7e21f4,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x08b421f5,
-	0xf40464b6,
-	0xe7f11811,
-	0x21f41388,
-	0x0037f07e,
-	0x084021f5,
-	0x1388e7f1,
-/* 0x09a7: i2c_bitw_out */
-	0xf87e21f4,
-/* 0x09a9: i2c_bitr */
-	0x0137f000,
-	0x086221f5,
-	0x03e8e7f1,
-	0xbb7e21f4,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x08b421f5,
-	0xf40464b6,
-	0x21f51b11,
-	0x37f0089c,
-	0x4021f500,
+	0x37f07e21,
+	0x3921f500,
 	0x88e7f108,
 	0x7e21f413,
-	0xf4013cf0,
-/* 0x09ee: i2c_bitr_done */
-	0x00f80131,
-/* 0x09f0: i2c_get_byte */
-	0xf00057f0,
-/* 0x09f6: i2c_get_byte_next */
-	0x54b60847,
+/* 0x09a0: i2c_bitw_out */
+/* 0x09a2: i2c_bitr */
+	0x37f000f8,
+	0x5b21f501,
+	0xe8e7f108,
+	0x7e21f403,
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0xad21f550,
+	0x0464b608,
+	0xf51b11f4,
+	0xf0089521,
+	0x21f50037,
+	0xe7f10839,
+	0x21f41388,
+	0x013cf07e,
+/* 0x09e7: i2c_bitr_done */
+	0xf80131f4,
+/* 0x09e9: i2c_get_byte */
+	0x0057f000,
+/* 0x09ef: i2c_get_byte_next */
+	0xb60847f0,
+	0x76bb0154,
+	0x0465b600,
+	0x659450f9,
+	0x0256bb04,
+	0x75fd50bd,
+	0xf550fc04,
+	0xb609a221,
+	0x11f40464,
+	0x0553fd2b,
+	0xf40142b6,
+	0x37f0d81b,
 	0x0076bb01,
 	0xf90465b6,
 	0x04659450,
 	0xbd0256bb,
 	0x0475fd50,
 	0x21f550fc,
-	0x64b609a9,
-	0x2b11f404,
-	0xb60553fd,
-	0x1bf40142,
-	0x0137f0d8,
+	0x64b60961,
+/* 0x0a39: i2c_get_byte_done */
+/* 0x0a3b: i2c_put_byte */
+	0xf000f804,
+/* 0x0a3e: i2c_put_byte_next */
+	0x42b60847,
+	0x3854ff01,
 	0xb60076bb,
 	0x50f90465,
 	0xbb046594,
 	0x50bd0256,
 	0xfc0475fd,
-	0x6821f550,
+	0x6121f550,
 	0x0464b609,
-/* 0x0a40: i2c_get_byte_done */
-/* 0x0a42: i2c_put_byte */
-	0x47f000f8,
-/* 0x0a45: i2c_put_byte_next */
-	0x0142b608,
-	0xbb3854ff,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x096821f5,
-	0xf40464b6,
-	0x46b03411,
-	0xd81bf400,
-	0xb60076bb,
-	0x50f90465,
-	0xbb046594,
-	0x50bd0256,
-	0xfc0475fd,
-	0xa921f550,
-	0x0464b609,
-	0xbb0f11f4,
-	0x36b00076,
-	0x061bf401,
-/* 0x0a9b: i2c_put_byte_done */
-	0xf80132f4,
-/* 0x0a9d: i2c_addr */
-	0x0076bb00,
+	0xb03411f4,
+	0x1bf40046,
+	0x0076bbd8,
 	0xf90465b6,
 	0x04659450,
 	0xbd0256bb,
 	0x0475fd50,
 	0x21f550fc,
-	0x64b608d9,
-	0x2911f404,
-	0x012ec3e7,
-	0xfd0134b6,
-	0x76bb0553,
+	0x64b609a2,
+	0x0f11f404,
+	0xb00076bb,
+	0x1bf40136,
+	0x0132f406,
+/* 0x0a94: i2c_put_byte_done */
+/* 0x0a96: i2c_addr */
+	0x76bb00f8,
 	0x0465b600,
 	0x659450f9,
 	0x0256bb04,
 	0x75fd50bd,
 	0xf550fc04,
-	0xb60a4221,
-/* 0x0ae2: i2c_addr_done */
-	0x00f80464,
-/* 0x0ae4: i2c_acquire_addr */
-	0xb6f8cec7,
-	0xe0b702e4,
-	0xee980d1c,
-/* 0x0af3: i2c_acquire */
-	0xf500f800,
-	0xf40ae421,
-	0xd9f00421,
+	0xb608d221,
+	0x11f40464,
+	0x2ec3e729,
+	0x0134b601,
+	0xbb0553fd,
+	0x65b60076,
+	0x9450f904,
+	0x56bb0465,
+	0xfd50bd02,
+	0x50fc0475,
+	0x0a3b21f5,
+/* 0x0adb: i2c_addr_done */
+	0xf80464b6,
+/* 0x0add: i2c_acquire_addr */
+	0xf8cec700,
+	0xb702e4b6,
+	0x980d1ce0,
+	0x00f800ee,
+/* 0x0aec: i2c_acquire */
+	0x0add21f5,
+	0xf00421f4,
+	0x21f403d9,
+/* 0x0afb: i2c_release */
+	0xf500f840,
+	0xf40add21,
+	0xdaf00421,
 	0x4021f403,
-/* 0x0b02: i2c_release */
-	0x21f500f8,
-	0x21f40ae4,
-	0x03daf004,
-	0xf84021f4,
-/* 0x0b11: i2c_recv */
-	0x0132f400,
-	0xb6f8c1c7,
-	0x16b00214,
-	0x3a1ff528,
-	0xf413a001,
-	0x0032980c,
-	0x0ccc13a0,
-	0xf4003198,
-	0xd0f90231,
-	0xd0f9e0f9,
-	0x000067f1,
-	0x100063f1,
-	0xbb016792,
+/* 0x0b0a: i2c_recv */
+	0x32f400f8,
+	0xf8c1c701,
+	0xb00214b6,
+	0x1ff52816,
+	0x13a0013a,
+	0x32980cf4,
+	0xcc13a000,
+	0x0031980c,
+	0xf90231f4,
+	0xf9e0f9d0,
+	0x0067f1d0,
+	0x0063f100,
+	0x01679210,
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0xec21f550,
+	0x0464b60a,
+	0xd6b0d0fc,
+	0xb31bf500,
+	0x0057f000,
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0x9621f550,
+	0x0464b60a,
+	0x00d011f5,
+	0xbbe0c5c7,
 	0x65b60076,
 	0x9450f904,
 	0x56bb0465,
 	0xfd50bd02,
 	0x50fc0475,
-	0x0af321f5,
-	0xfc0464b6,
-	0x00d6b0d0,
-	0x00b31bf5,
-	0xbb0057f0,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x0a9d21f5,
+	0x0a3b21f5,
 	0xf50464b6,
-	0xc700d011,
-	0x76bbe0c5,
+	0xf000ad11,
+	0x76bb0157,
 	0x0465b600,
 	0x659450f9,
 	0x0256bb04,
 	0x75fd50bd,
 	0xf550fc04,
-	0xb60a4221,
+	0xb60a9621,
 	0x11f50464,
-	0x57f000ad,
-	0x0076bb01,
-	0xf90465b6,
-	0x04659450,
-	0xbd0256bb,
-	0x0475fd50,
-	0x21f550fc,
-	0x64b60a9d,
-	0x8a11f504,
-	0x0076bb00,
-	0xf90465b6,
-	0x04659450,
-	0xbd0256bb,
-	0x0475fd50,
-	0x21f550fc,
-	0x64b609f0,
-	0x6a11f404,
-	0xbbe05bcb,
-	0x65b60076,
-	0x9450f904,
-	0x56bb0465,
-	0xfd50bd02,
-	0x50fc0475,
-	0x093521f5,
-	0xb90464b6,
-	0x74bd025b,
-/* 0x0c17: i2c_recv_not_rd08 */
-	0xb0430ef4,
-	0x1bf401d6,
-	0x0057f03d,
-	0x0a9d21f5,
-	0xc73311f4,
-	0x21f5e0c5,
-	0x11f40a42,
-	0x0057f029,
-	0x0a9d21f5,
-	0xc71f11f4,
-	0x21f5e0b5,
-	0x11f40a42,
-	0x3521f515,
-	0xc774bd09,
-	0x1bf408c5,
-	0x0232f409,
-/* 0x0c57: i2c_recv_not_wr08 */
-/* 0x0c57: i2c_recv_done */
-	0xc7030ef4,
-	0x21f5f8ce,
-	0xe0fc0b02,
-	0x12f4d0fc,
-	0x027cb90a,
-	0x033621f5,
-/* 0x0c6c: i2c_recv_exit */
-/* 0x0c6e: i2c_init */
+	0x76bb008a,
+	0x0465b600,
+	0x659450f9,
+	0x0256bb04,
+	0x75fd50bd,
+	0xf550fc04,
+	0xb609e921,
+	0x11f40464,
+	0xe05bcb6a,
+	0xb60076bb,
+	0x50f90465,
+	0xbb046594,
+	0x50bd0256,
+	0xfc0475fd,
+	0x2e21f550,
+	0x0464b609,
+	0xbd025bb9,
+	0x430ef474,
+/* 0x0c10: i2c_recv_not_rd08 */
+	0xf401d6b0,
+	0x57f03d1b,
+	0x9621f500,
+	0x3311f40a,
+	0xf5e0c5c7,
+	0xf40a3b21,
+	0x57f02911,
+	0x9621f500,
+	0x1f11f40a,
+	0xf5e0b5c7,
+	0xf40a3b21,
+	0x21f51511,
+	0x74bd092e,
+	0xf408c5c7,
+	0x32f4091b,
+	0x030ef402,
+/* 0x0c50: i2c_recv_not_wr08 */
+/* 0x0c50: i2c_recv_done */
+	0xf5f8cec7,
+	0xfc0afb21,
+	0xf4d0fce0,
+	0x7cb90a12,
+	0x3621f502,
+/* 0x0c65: i2c_recv_exit */
+/* 0x0c67: i2c_init */
+	0xf800f803,
+/* 0x0c69: test_recv */
+	0xd817f100,
+	0x0614b605,
+	0xb60011cf,
+	0x07f10110,
+	0x04b605d8,
+	0x0001d006,
+	0xe7f104bd,
+	0xe3f1d900,
+	0x21f5134f,
+	0x00f80256,
+/* 0x0c90: test_init */
+	0x0800e7f1,
+	0x025621f5,
+/* 0x0c9a: idle_recv */
 	0x00f800f8,
-/* 0x0c70: test_recv */
-	0x05d817f1,
-	0xcf0614b6,
-	0x10b60011,
-	0xd807f101,
-	0x0604b605,
-	0xbd0001d0,
-	0x00e7f104,
-	0x4fe3f1d9,
-	0x5621f513,
-/* 0x0c97: test_init */
-	0xf100f802,
-	0xf50800e7,
-	0xf8025621,
-/* 0x0ca1: idle_recv */
-/* 0x0ca3: idle */
-	0xf400f800,
-	0x17f10031,
-	0x14b605d4,
-	0x0011cf06,
-	0xf10110b6,
-	0xb605d407,
-	0x01d00604,
-/* 0x0cbf: idle_loop */
-	0xf004bd00,
-	0x32f45817,
-/* 0x0cc5: idle_proc */
-/* 0x0cc5: idle_proc_exec */
-	0xb910f902,
-	0x21f5021e,
-	0x10fc033f,
-	0xf40911f4,
-	0x0ef40231,
-/* 0x0cd9: idle_proc_next */
-	0x5810b6ef,
-	0xf4061fb8,
-	0x02f4e61b,
-	0x0028f4dd,
-	0x00bb0ef4,
+/* 0x0c9c: idle */
+	0xf10031f4,
+	0xb605d417,
+	0x11cf0614,
+	0x0110b600,
+	0x05d407f1,
+	0xd00604b6,
+	0x04bd0001,
+/* 0x0cb8: idle_loop */
+	0xf45817f0,
+/* 0x0cbe: idle_proc */
+/* 0x0cbe: idle_proc_exec */
+	0x10f90232,
+	0xf5021eb9,
+	0xfc033f21,
+	0x0911f410,
+	0xf40231f4,
+/* 0x0cd2: idle_proc_next */
+	0x10b6ef0e,
+	0x061fb858,
+	0xf4e61bf4,
+	0x28f4dd02,
+	0xbb0ef400,
+	0x00000000,
+	0x00000000,
 	0x00000000,
 	0x00000000,
 	0x00000000,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/memx.fuc b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/memx.fuc
index ec03f9a..1663bf94 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/memx.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/memx.fuc
@@ -82,15 +82,15 @@
 // $r0  - zero
 memx_func_enter:
 #if NVKM_PPWR_CHIPSET == GT215
-	movw $r8 0x1610
+	mov $r8 0x1610
 	nv_rd32($r7, $r8)
 	imm32($r6, 0xfffffffc)
 	and $r7 $r6
-	movw $r6 0x2
+	mov $r6 0x2
 	or $r7 $r6
 	nv_wr32($r8, $r7)
 #else
-	movw $r6 0x001620
+	mov $r6 0x001620
 	imm32($r7, ~0x00000aa2);
 	nv_rd32($r8, $r6)
 	and $r8 $r7
@@ -101,7 +101,7 @@
 	and $r8 $r7
 	nv_wr32($r6, $r8)
 
-	movw $r6 0x0026f0
+	mov $r6 0x0026f0
 	nv_rd32($r8, $r6)
 	and $r8 $r7
 	nv_wr32($r6, $r8)
@@ -136,19 +136,19 @@
 		bra nz #memx_func_leave_wait
 
 #if NVKM_PPWR_CHIPSET == GT215
-	movw $r8 0x1610
+	mov $r8 0x1610
 	nv_rd32($r7, $r8)
 	imm32($r6, 0xffffffcc)
 	and $r7 $r6
 	nv_wr32($r8, $r7)
 #else
-	movw $r6 0x0026f0
+	mov $r6 0x0026f0
 	imm32($r7, 0x00000001)
 	nv_rd32($r8, $r6)
 	or $r8 $r7
 	nv_wr32($r6, $r8)
 
-	movw $r6 0x001620
+	mov $r6 0x001620
 	nv_rd32($r8, $r6)
 	or $r8 $r7
 	nv_wr32($r6, $r8)
@@ -177,11 +177,11 @@
 	bra #memx_func_wait_vblank_fini
 
 	memx_func_wait_vblank_head1:
-	movw $r7 0x20
+	mov $r7 0x20
 	bra #memx_func_wait_vblank_0
 
 	memx_func_wait_vblank_head0:
-	movw $r7 0x8
+	mov $r7 0x8
 
 	memx_func_wait_vblank_0:
 		nv_iord($r6, NV_PPWR_INPUT)
@@ -273,13 +273,13 @@
 // $r5 - outer loop counter
 // $r6 - inner loop counter
 // $r7 - entry counter (#memx_train_head + $r7)
-	movw $r5 0x3
-	movw $r7 0x0
+	mov $r5 0x3
+	mov $r7 0x0
 
 // Read random memory to wake up... things
 	imm32($r9, 0x700000)
 	nv_rd32($r8,$r9)
-	movw $r14 0x2710
+	mov $r14 0x2710
 	call(nsec)
 
 	memx_func_train_loop_outer:
@@ -289,9 +289,9 @@
 		nv_wr32($r9, $r8)
 		push $r5
 
-		movw $r6 0x0
+		mov $r6 0x0
 		memx_func_train_loop_inner:
-			movw $r8 0x1111
+			mov $r8 0x1111
 			mulu $r9 $r6 $r8
 			shl b32 $r8 $r9 0x10
 			or $r8 $r9
@@ -315,7 +315,7 @@
 
 			// $r5 - inner inner loop counter
 			// $r9 - result
-			movw $r5 0
+			mov $r5 0
 			imm32($r9, 0x8300ffff)
 			memx_func_train_loop_4x:
 				imm32($r10, 0x100080)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/Kbuild
index e698f483..ed08120 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/Kbuild
@@ -7,8 +7,10 @@
 nvkm-y += nvkm/subdev/secboot/acr_r361.o
 nvkm-y += nvkm/subdev/secboot/acr_r364.o
 nvkm-y += nvkm/subdev/secboot/acr_r367.o
+nvkm-y += nvkm/subdev/secboot/acr_r370.o
 nvkm-y += nvkm/subdev/secboot/acr_r375.o
 nvkm-y += nvkm/subdev/secboot/gm200.o
 nvkm-y += nvkm/subdev/secboot/gm20b.o
 nvkm-y += nvkm/subdev/secboot/gp102.o
+nvkm-y += nvkm/subdev/secboot/gp108.o
 nvkm-y += nvkm/subdev/secboot/gp10b.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.h
index b615fc8..73a2ac8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr.h
@@ -64,6 +64,7 @@ struct nvkm_acr *acr_r352_new(unsigned long);
 struct nvkm_acr *acr_r361_new(unsigned long);
 struct nvkm_acr *acr_r364_new(unsigned long);
 struct nvkm_acr *acr_r367_new(enum nvkm_secboot_falcon, unsigned long);
+struct nvkm_acr *acr_r370_new(enum nvkm_secboot_falcon, unsigned long);
 struct nvkm_acr *acr_r375_new(enum nvkm_secboot_falcon, unsigned long);
 
 #endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.c
new file mode 100644
index 0000000..2f890df
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "acr_r370.h"
+#include "acr_r367.h"
+
+#include <core/msgqueue.h>
+#include <engine/falcon.h>
+#include <engine/sec2.h>
+
+static void
+acr_r370_generate_flcn_bl_desc(const struct nvkm_acr *acr,
+			       const struct ls_ucode_img *img, u64 wpr_addr,
+			       void *_desc)
+{
+	struct acr_r370_flcn_bl_desc *desc = _desc;
+	const struct ls_ucode_img_desc *pdesc = &img->ucode_desc;
+	u64 base, addr_code, addr_data;
+
+	base = wpr_addr + img->ucode_off + pdesc->app_start_offset;
+	addr_code = base + pdesc->app_resident_code_offset;
+	addr_data = base + pdesc->app_resident_data_offset;
+
+	desc->ctx_dma = FALCON_DMAIDX_UCODE;
+	desc->code_dma_base = u64_to_flcn64(addr_code);
+	desc->non_sec_code_off = pdesc->app_resident_code_offset;
+	desc->non_sec_code_size = pdesc->app_resident_code_size;
+	desc->code_entry_point = pdesc->app_imem_entry;
+	desc->data_dma_base = u64_to_flcn64(addr_data);
+	desc->data_size = pdesc->app_resident_data_size;
+}
+
+const struct acr_r352_ls_func
+acr_r370_ls_fecs_func = {
+	.load = acr_ls_ucode_load_fecs,
+	.generate_bl_desc = acr_r370_generate_flcn_bl_desc,
+	.bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
+};
+
+const struct acr_r352_ls_func
+acr_r370_ls_gpccs_func = {
+	.load = acr_ls_ucode_load_gpccs,
+	.generate_bl_desc = acr_r370_generate_flcn_bl_desc,
+	.bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
+	/* GPCCS will be loaded using PRI */
+	.lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
+};
+
+static void
+acr_r370_generate_sec2_bl_desc(const struct nvkm_acr *acr,
+			       const struct ls_ucode_img *img, u64 wpr_addr,
+			       void *_desc)
+{
+	const struct ls_ucode_img_desc *pdesc = &img->ucode_desc;
+	const struct nvkm_sec2 *sec = acr->subdev->device->sec2;
+	struct acr_r370_flcn_bl_desc *desc = _desc;
+	u64 base, addr_code, addr_data;
+	u32 addr_args;
+
+	base = wpr_addr + img->ucode_off + pdesc->app_start_offset;
+	/* For some reason we should not add app_resident_code_offset here */
+	addr_code = base;
+	addr_data = base + pdesc->app_resident_data_offset;
+	addr_args = sec->falcon->data.limit;
+	addr_args -= NVKM_MSGQUEUE_CMDLINE_SIZE;
+
+	desc->ctx_dma = FALCON_SEC2_DMAIDX_UCODE;
+	desc->code_dma_base = u64_to_flcn64(addr_code);
+	desc->non_sec_code_off = pdesc->app_resident_code_offset;
+	desc->non_sec_code_size = pdesc->app_resident_code_size;
+	desc->code_entry_point = pdesc->app_imem_entry;
+	desc->data_dma_base = u64_to_flcn64(addr_data);
+	desc->data_size = pdesc->app_resident_data_size;
+	desc->argc = 1;
+	/* args are stored at the beginning of EMEM */
+	desc->argv = 0x01000000;
+}
+
+const struct acr_r352_ls_func
+acr_r370_ls_sec2_func = {
+	.load = acr_ls_ucode_load_sec2,
+	.generate_bl_desc = acr_r370_generate_sec2_bl_desc,
+	.bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
+	.post_run = acr_ls_sec2_post_run,
+};
+
+void
+acr_r370_generate_hs_bl_desc(const struct hsf_load_header *hdr, void *_bl_desc,
+			     u64 offset)
+{
+	struct acr_r370_flcn_bl_desc *bl_desc = _bl_desc;
+
+	bl_desc->ctx_dma = FALCON_DMAIDX_VIRT;
+	bl_desc->non_sec_code_off = hdr->non_sec_code_off;
+	bl_desc->non_sec_code_size = hdr->non_sec_code_size;
+	bl_desc->sec_code_off = hsf_load_header_app_off(hdr, 0);
+	bl_desc->sec_code_size = hsf_load_header_app_size(hdr, 0);
+	bl_desc->code_entry_point = 0;
+	bl_desc->code_dma_base = u64_to_flcn64(offset);
+	bl_desc->data_dma_base = u64_to_flcn64(offset + hdr->data_dma_base);
+	bl_desc->data_size = hdr->data_size;
+}
+
+const struct acr_r352_func
+acr_r370_func = {
+	.fixup_hs_desc = acr_r367_fixup_hs_desc,
+	.generate_hs_bl_desc = acr_r370_generate_hs_bl_desc,
+	.hs_bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
+	.shadow_blob = true,
+	.ls_ucode_img_load = acr_r367_ls_ucode_img_load,
+	.ls_fill_headers = acr_r367_ls_fill_headers,
+	.ls_write_wpr = acr_r367_ls_write_wpr,
+	.ls_func = {
+		[NVKM_SECBOOT_FALCON_SEC2] = &acr_r370_ls_sec2_func,
+		[NVKM_SECBOOT_FALCON_FECS] = &acr_r370_ls_fecs_func,
+		[NVKM_SECBOOT_FALCON_GPCCS] = &acr_r370_ls_gpccs_func,
+	},
+};
+
+struct nvkm_acr *
+acr_r370_new(enum nvkm_secboot_falcon boot_falcon,
+	     unsigned long managed_falcons)
+{
+	return acr_r352_new_(&acr_r370_func, boot_falcon, managed_falcons);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.h
new file mode 100644
index 0000000..3426f86
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r370.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __NVKM_SECBOOT_ACR_R370_H__
+#define __NVKM_SECBOOT_ACR_R370_H__
+
+#include "priv.h"
+struct hsf_load_header;
+
+/* Same as acr_r361_flcn_bl_desc, plus argc/argv */
+struct acr_r370_flcn_bl_desc {
+	u32 reserved[4];
+	u32 signature[4];
+	u32 ctx_dma;
+	struct flcn_u64 code_dma_base;
+	u32 non_sec_code_off;
+	u32 non_sec_code_size;
+	u32 sec_code_off;
+	u32 sec_code_size;
+	u32 code_entry_point;
+	struct flcn_u64 data_dma_base;
+	u32 data_size;
+	u32 argc;
+	u32 argv;
+};
+
+void acr_r370_generate_hs_bl_desc(const struct hsf_load_header *, void *, u64);
+extern const struct acr_r352_ls_func acr_r370_ls_fecs_func;
+extern const struct acr_r352_ls_func acr_r370_ls_gpccs_func;
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r375.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r375.c
index ddb795b..7bdef93 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r375.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/acr_r375.c
@@ -20,90 +20,12 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include "acr_r370.h"
 #include "acr_r367.h"
 
-#include <engine/falcon.h>
 #include <core/msgqueue.h>
 #include <subdev/pmu.h>
 
-/*
- * r375 ACR: similar to r367, but with a unified bootloader descriptor
- * structure for GR and PMU falcons.
- */
-
-/* Same as acr_r361_flcn_bl_desc, plus argc/argv */
-struct acr_r375_flcn_bl_desc {
-	u32 reserved[4];
-	u32 signature[4];
-	u32 ctx_dma;
-	struct flcn_u64 code_dma_base;
-	u32 non_sec_code_off;
-	u32 non_sec_code_size;
-	u32 sec_code_off;
-	u32 sec_code_size;
-	u32 code_entry_point;
-	struct flcn_u64 data_dma_base;
-	u32 data_size;
-	u32 argc;
-	u32 argv;
-};
-
-static void
-acr_r375_generate_flcn_bl_desc(const struct nvkm_acr *acr,
-			       const struct ls_ucode_img *img, u64 wpr_addr,
-			       void *_desc)
-{
-	struct acr_r375_flcn_bl_desc *desc = _desc;
-	const struct ls_ucode_img_desc *pdesc = &img->ucode_desc;
-	u64 base, addr_code, addr_data;
-
-	base = wpr_addr + img->ucode_off + pdesc->app_start_offset;
-	addr_code = base + pdesc->app_resident_code_offset;
-	addr_data = base + pdesc->app_resident_data_offset;
-
-	desc->ctx_dma = FALCON_DMAIDX_UCODE;
-	desc->code_dma_base = u64_to_flcn64(addr_code);
-	desc->non_sec_code_off = pdesc->app_resident_code_offset;
-	desc->non_sec_code_size = pdesc->app_resident_code_size;
-	desc->code_entry_point = pdesc->app_imem_entry;
-	desc->data_dma_base = u64_to_flcn64(addr_data);
-	desc->data_size = pdesc->app_resident_data_size;
-}
-
-static void
-acr_r375_generate_hs_bl_desc(const struct hsf_load_header *hdr, void *_bl_desc,
-			     u64 offset)
-{
-	struct acr_r375_flcn_bl_desc *bl_desc = _bl_desc;
-
-	bl_desc->ctx_dma = FALCON_DMAIDX_VIRT;
-	bl_desc->non_sec_code_off = hdr->non_sec_code_off;
-	bl_desc->non_sec_code_size = hdr->non_sec_code_size;
-	bl_desc->sec_code_off = hsf_load_header_app_off(hdr, 0);
-	bl_desc->sec_code_size = hsf_load_header_app_size(hdr, 0);
-	bl_desc->code_entry_point = 0;
-	bl_desc->code_dma_base = u64_to_flcn64(offset);
-	bl_desc->data_dma_base = u64_to_flcn64(offset + hdr->data_dma_base);
-	bl_desc->data_size = hdr->data_size;
-}
-
-const struct acr_r352_ls_func
-acr_r375_ls_fecs_func = {
-	.load = acr_ls_ucode_load_fecs,
-	.generate_bl_desc = acr_r375_generate_flcn_bl_desc,
-	.bl_desc_size = sizeof(struct acr_r375_flcn_bl_desc),
-};
-
-const struct acr_r352_ls_func
-acr_r375_ls_gpccs_func = {
-	.load = acr_ls_ucode_load_gpccs,
-	.generate_bl_desc = acr_r375_generate_flcn_bl_desc,
-	.bl_desc_size = sizeof(struct acr_r375_flcn_bl_desc),
-	/* GPCCS will be loaded using PRI */
-	.lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
-};
-
-
 static void
 acr_r375_generate_pmu_bl_desc(const struct nvkm_acr *acr,
 			      const struct ls_ucode_img *img, u64 wpr_addr,
@@ -111,7 +33,7 @@ acr_r375_generate_pmu_bl_desc(const struct nvkm_acr *acr,
 {
 	const struct ls_ucode_img_desc *pdesc = &img->ucode_desc;
 	const struct nvkm_pmu *pmu = acr->subdev->device->pmu;
-	struct acr_r375_flcn_bl_desc *desc = _desc;
+	struct acr_r370_flcn_bl_desc *desc = _desc;
 	u64 base, addr_code, addr_data;
 	u32 addr_args;
 
@@ -136,23 +58,22 @@ const struct acr_r352_ls_func
 acr_r375_ls_pmu_func = {
 	.load = acr_ls_ucode_load_pmu,
 	.generate_bl_desc = acr_r375_generate_pmu_bl_desc,
-	.bl_desc_size = sizeof(struct acr_r375_flcn_bl_desc),
+	.bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
 	.post_run = acr_ls_pmu_post_run,
 };
 
-
 const struct acr_r352_func
 acr_r375_func = {
 	.fixup_hs_desc = acr_r367_fixup_hs_desc,
-	.generate_hs_bl_desc = acr_r375_generate_hs_bl_desc,
-	.hs_bl_desc_size = sizeof(struct acr_r375_flcn_bl_desc),
+	.generate_hs_bl_desc = acr_r370_generate_hs_bl_desc,
+	.hs_bl_desc_size = sizeof(struct acr_r370_flcn_bl_desc),
 	.shadow_blob = true,
 	.ls_ucode_img_load = acr_r367_ls_ucode_img_load,
 	.ls_fill_headers = acr_r367_ls_fill_headers,
 	.ls_write_wpr = acr_r367_ls_write_wpr,
 	.ls_func = {
-		[NVKM_SECBOOT_FALCON_FECS] = &acr_r375_ls_fecs_func,
-		[NVKM_SECBOOT_FALCON_GPCCS] = &acr_r375_ls_gpccs_func,
+		[NVKM_SECBOOT_FALCON_FECS] = &acr_r370_ls_fecs_func,
+		[NVKM_SECBOOT_FALCON_GPCCS] = &acr_r370_ls_gpccs_func,
 		[NVKM_SECBOOT_FALCON_PMU] = &acr_r375_ls_pmu_func,
 	},
 };
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp102.c
index f3b3c66..1f7a3c1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp102.c
@@ -133,7 +133,7 @@ gp102_secboot_run_blob(struct nvkm_secboot *sb, struct nvkm_gpuobj *blob,
 	return gm200_secboot_run_blob(sb, blob, falcon);
 }
 
-static const struct nvkm_secboot_func
+const struct nvkm_secboot_func
 gp102_secboot = {
 	.dtor = gm200_secboot_dtor,
 	.oneinit = gm200_secboot_oneinit,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp108.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp108.c
new file mode 100644
index 0000000..e8c27ec
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp108.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2017 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "gm200.h"
+#include "acr.h"
+
+int
+gp108_secboot_new(struct nvkm_device *device, int index,
+		  struct nvkm_secboot **psb)
+{
+	struct gm200_secboot *gsb;
+	struct nvkm_acr *acr;
+
+	acr = acr_r370_new(NVKM_SECBOOT_FALCON_SEC2,
+			   BIT(NVKM_SECBOOT_FALCON_FECS) |
+			   BIT(NVKM_SECBOOT_FALCON_GPCCS) |
+			   BIT(NVKM_SECBOOT_FALCON_SEC2));
+	if (IS_ERR(acr))
+		return PTR_ERR(acr);
+
+	if (!(gsb = kzalloc(sizeof(*gsb), GFP_KERNEL))) {
+		acr->func->dtor(acr);
+		return -ENOMEM;
+	}
+	*psb = &gsb->base;
+
+	return nvkm_secboot_ctor(&gp102_secboot, acr, device, index, &gsb->base);
+}
+
+MODULE_FIRMWARE("nvidia/gp108/acr/bl.bin");
+MODULE_FIRMWARE("nvidia/gp108/acr/unload_bl.bin");
+MODULE_FIRMWARE("nvidia/gp108/acr/ucode_load.bin");
+MODULE_FIRMWARE("nvidia/gp108/acr/ucode_unload.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/fecs_bl.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/fecs_inst.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/fecs_data.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/fecs_sig.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/gpccs_bl.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/gpccs_inst.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/gpccs_data.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/gpccs_sig.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/sw_ctx.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/sw_nonctx.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/sw_bundle_init.bin");
+MODULE_FIRMWARE("nvidia/gp108/gr/sw_method_init.bin");
+MODULE_FIRMWARE("nvidia/gp108/nvdec/scrubber.bin");
+MODULE_FIRMWARE("nvidia/gp108/sec2/desc.bin");
+MODULE_FIRMWARE("nvidia/gp108/sec2/image.bin");
+MODULE_FIRMWARE("nvidia/gp108/sec2/sig.bin");
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h
index d9091f0..959a7b2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/priv.h
@@ -40,6 +40,8 @@ int nvkm_secboot_ctor(const struct nvkm_secboot_func *, struct nvkm_acr *,
 int nvkm_secboot_falcon_reset(struct nvkm_secboot *);
 int nvkm_secboot_falcon_run(struct nvkm_secboot *);
 
+extern const struct nvkm_secboot_func gp102_secboot;
+
 struct flcn_u64 {
 	u32 lo;
 	u32 hi;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
index 7ba56b1..550702e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild
@@ -9,7 +9,9 @@
 nvkm-y += nvkm/subdev/therm/nv50.o
 nvkm-y += nvkm/subdev/therm/g84.o
 nvkm-y += nvkm/subdev/therm/gt215.o
+nvkm-y += nvkm/subdev/therm/gf100.o
 nvkm-y += nvkm/subdev/therm/gf119.o
+nvkm-y += nvkm/subdev/therm/gk104.o
 nvkm-y += nvkm/subdev/therm/gm107.o
 nvkm-y += nvkm/subdev/therm/gm200.o
 nvkm-y += nvkm/subdev/therm/gp100.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
index f27fc6d..bf62303 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
@@ -21,6 +21,7 @@
  *
  * Authors: Martin Peres
  */
+#include <nvkm/core/option.h>
 #include "priv.h"
 
 int
@@ -297,6 +298,38 @@ nvkm_therm_attr_set(struct nvkm_therm *therm,
 	return -EINVAL;
 }
 
+void
+nvkm_therm_clkgate_enable(struct nvkm_therm *therm)
+{
+	if (!therm->func->clkgate_enable || !therm->clkgating_enabled)
+		return;
+
+	nvkm_debug(&therm->subdev,
+		   "Enabling clockgating\n");
+	therm->func->clkgate_enable(therm);
+}
+
+void
+nvkm_therm_clkgate_fini(struct nvkm_therm *therm, bool suspend)
+{
+	if (!therm->func->clkgate_fini || !therm->clkgating_enabled)
+		return;
+
+	nvkm_debug(&therm->subdev,
+		   "Preparing clockgating for %s\n",
+		   suspend ? "suspend" : "fini");
+	therm->func->clkgate_fini(therm, suspend);
+}
+
+static void
+nvkm_therm_clkgate_oneinit(struct nvkm_therm *therm)
+{
+	if (!therm->func->clkgate_enable || !therm->clkgating_enabled)
+		return;
+
+	nvkm_info(&therm->subdev, "Clockgating enabled\n");
+}
+
 static void
 nvkm_therm_intr(struct nvkm_subdev *subdev)
 {
@@ -333,6 +366,7 @@ nvkm_therm_oneinit(struct nvkm_subdev *subdev)
 	nvkm_therm_fan_ctor(therm);
 	nvkm_therm_fan_mode(therm, NVKM_THERM_CTRL_AUTO);
 	nvkm_therm_sensor_preinit(therm);
+	nvkm_therm_clkgate_oneinit(therm);
 	return 0;
 }
 
@@ -357,6 +391,16 @@ nvkm_therm_init(struct nvkm_subdev *subdev)
 	return 0;
 }
 
+void
+nvkm_therm_clkgate_init(struct nvkm_therm *therm,
+			const struct nvkm_therm_clkgate_pack *p)
+{
+	if (!therm->func->clkgate_init || !therm->clkgating_enabled)
+		return;
+
+	therm->func->clkgate_init(therm, p);
+}
+
 static void *
 nvkm_therm_dtor(struct nvkm_subdev *subdev)
 {
@@ -374,15 +418,10 @@ nvkm_therm = {
 	.intr = nvkm_therm_intr,
 };
 
-int
-nvkm_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device,
-		int index, struct nvkm_therm **ptherm)
+void
+nvkm_therm_ctor(struct nvkm_therm *therm, struct nvkm_device *device,
+		int index, const struct nvkm_therm_func *func)
 {
-	struct nvkm_therm *therm;
-
-	if (!(therm = *ptherm = kzalloc(sizeof(*therm), GFP_KERNEL)))
-		return -ENOMEM;
-
 	nvkm_subdev_ctor(&nvkm_therm, device, index, &therm->subdev);
 	therm->func = func;
 
@@ -395,5 +434,20 @@ nvkm_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device,
 	therm->attr_get = nvkm_therm_attr_get;
 	therm->attr_set = nvkm_therm_attr_set;
 	therm->mode = therm->suspend = -1; /* undefined */
+
+	therm->clkgating_enabled = nvkm_boolopt(device->cfgopt,
+						"NvPmEnableGating", false);
+}
+
+int
+nvkm_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device,
+		int index, struct nvkm_therm **ptherm)
+{
+	struct nvkm_therm *therm;
+
+	if (!(therm = *ptherm = kzalloc(sizeof(*therm), GFP_KERNEL)))
+		return -ENOMEM;
+
+	nvkm_therm_ctor(therm, device, index, func);
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.c
new file mode 100644
index 0000000..5ae6913
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Lyude Paul
+ */
+#include <core/device.h>
+
+#include "priv.h"
+
+#define pack_for_each_init(init, pack, head)                          \
+	for (pack = head; pack && pack->init; pack++)                 \
+		  for (init = pack->init; init && init->count; init++)
+void
+gf100_clkgate_init(struct nvkm_therm *therm,
+		   const struct nvkm_therm_clkgate_pack *p)
+{
+	struct nvkm_device *device = therm->subdev.device;
+	const struct nvkm_therm_clkgate_pack *pack;
+	const struct nvkm_therm_clkgate_init *init;
+	u32 next, addr;
+
+	pack_for_each_init(init, pack, p) {
+		next = init->addr + init->count * 8;
+		addr = init->addr;
+
+		nvkm_trace(&therm->subdev, "{ 0x%06x, %d, 0x%08x }\n",
+			   init->addr, init->count, init->data);
+		while (addr < next) {
+			nvkm_trace(&therm->subdev, "\t0x%06x = 0x%08x\n",
+				   addr, init->data);
+			nvkm_wr32(device, addr, init->data);
+			addr += 8;
+		}
+	}
+}
+
+/*
+ * TODO: Fermi clockgating isn't understood fully yet, so we don't specify any
+ * clockgate functions to use
+ */
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.h
new file mode 100644
index 0000000..cfb25af
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf100.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Lyude Paul
+ */
+
+#ifndef __GF100_THERM_H__
+#define __GF100_THERM_H__
+
+#include <core/device.h>
+
+struct gf100_idle_filter {
+	u32 fecs;
+	u32 hubmmu;
+};
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf119.c
index 06dcfd6e..0981b02 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gf119.c
@@ -49,7 +49,7 @@ pwm_info(struct nvkm_therm *therm, int line)
 	return -ENODEV;
 }
 
-static int
+int
 gf119_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable)
 {
 	struct nvkm_device *device = therm->subdev.device;
@@ -63,7 +63,7 @@ gf119_fan_pwm_ctrl(struct nvkm_therm *therm, int line, bool enable)
 	return 0;
 }
 
-static int
+int
 gf119_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty)
 {
 	struct nvkm_device *device = therm->subdev.device;
@@ -85,7 +85,7 @@ gf119_fan_pwm_get(struct nvkm_therm *therm, int line, u32 *divs, u32 *duty)
 	return -EINVAL;
 }
 
-static int
+int
 gf119_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty)
 {
 	struct nvkm_device *device = therm->subdev.device;
@@ -102,7 +102,7 @@ gf119_fan_pwm_set(struct nvkm_therm *therm, int line, u32 divs, u32 duty)
 	return 0;
 }
 
-static int
+int
 gf119_fan_pwm_clock(struct nvkm_therm *therm, int line)
 {
 	struct nvkm_device *device = therm->subdev.device;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c
new file mode 100644
index 0000000..4e03971
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2018 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Lyude Paul
+ */
+#include <core/device.h>
+
+#include "priv.h"
+#include "gk104.h"
+
+void
+gk104_clkgate_enable(struct nvkm_therm *base)
+{
+	struct gk104_therm *therm = gk104_therm(base);
+	struct nvkm_device *dev = therm->base.subdev.device;
+	const struct gk104_clkgate_engine_info *order = therm->clkgate_order;
+	int i;
+
+	/* Program ENG_MANT, ENG_FILTER */
+	for (i = 0; order[i].engine != NVKM_SUBDEV_NR; i++) {
+		if (!nvkm_device_subdev(dev, order[i].engine))
+			continue;
+
+		nvkm_mask(dev, 0x20200 + order[i].offset, 0xff00, 0x4500);
+	}
+
+	/* magic */
+	nvkm_wr32(dev, 0x020288, therm->idle_filter->fecs);
+	nvkm_wr32(dev, 0x02028c, therm->idle_filter->hubmmu);
+
+	/* Enable clockgating (ENG_CLK = RUN->AUTO) */
+	for (i = 0; order[i].engine != NVKM_SUBDEV_NR; i++) {
+		if (!nvkm_device_subdev(dev, order[i].engine))
+			continue;
+
+		nvkm_mask(dev, 0x20200 + order[i].offset, 0x00ff, 0x0045);
+	}
+}
+
+void
+gk104_clkgate_fini(struct nvkm_therm *base, bool suspend)
+{
+	struct gk104_therm *therm = gk104_therm(base);
+	struct nvkm_device *dev = therm->base.subdev.device;
+	const struct gk104_clkgate_engine_info *order = therm->clkgate_order;
+	int i;
+
+	/* ENG_CLK = AUTO->RUN, ENG_PWR = RUN->AUTO */
+	for (i = 0; order[i].engine != NVKM_SUBDEV_NR; i++) {
+		if (!nvkm_device_subdev(dev, order[i].engine))
+			continue;
+
+		nvkm_mask(dev, 0x20200 + order[i].offset, 0xff, 0x54);
+	}
+}
+
+const struct gk104_clkgate_engine_info gk104_clkgate_engine_info[] = {
+	{ NVKM_ENGINE_GR,     0x00 },
+	{ NVKM_ENGINE_MSPDEC, 0x04 },
+	{ NVKM_ENGINE_MSPPP,  0x08 },
+	{ NVKM_ENGINE_MSVLD,  0x0c },
+	{ NVKM_ENGINE_CE0,    0x10 },
+	{ NVKM_ENGINE_CE1,    0x14 },
+	{ NVKM_ENGINE_MSENC,  0x18 },
+	{ NVKM_ENGINE_CE2,    0x1c },
+	{ NVKM_SUBDEV_NR, 0 },
+};
+
+const struct gf100_idle_filter gk104_idle_filter = {
+	.fecs = 0x00001000,
+	.hubmmu = 0x00001000,
+};
+
+static const struct nvkm_therm_func
+gk104_therm_func = {
+	.init = gf119_therm_init,
+	.fini = g84_therm_fini,
+	.pwm_ctrl = gf119_fan_pwm_ctrl,
+	.pwm_get = gf119_fan_pwm_get,
+	.pwm_set = gf119_fan_pwm_set,
+	.pwm_clock = gf119_fan_pwm_clock,
+	.temp_get = g84_temp_get,
+	.fan_sense = gt215_therm_fan_sense,
+	.program_alarms = nvkm_therm_program_alarms_polling,
+	.clkgate_init = gf100_clkgate_init,
+	.clkgate_enable = gk104_clkgate_enable,
+	.clkgate_fini = gk104_clkgate_fini,
+};
+
+static int
+gk104_therm_new_(const struct nvkm_therm_func *func,
+		 struct nvkm_device *device,
+		 int index,
+		 const struct gk104_clkgate_engine_info *clkgate_order,
+		 const struct gf100_idle_filter *idle_filter,
+		 struct nvkm_therm **ptherm)
+{
+	struct gk104_therm *therm = kzalloc(sizeof(*therm), GFP_KERNEL);
+
+	if (!therm)
+		return -ENOMEM;
+
+	nvkm_therm_ctor(&therm->base, device, index, func);
+	*ptherm = &therm->base;
+	therm->clkgate_order = clkgate_order;
+	therm->idle_filter = idle_filter;
+
+	return 0;
+}
+
+int
+gk104_therm_new(struct nvkm_device *device,
+		int index, struct nvkm_therm **ptherm)
+{
+	return gk104_therm_new_(&gk104_therm_func, device, index,
+				gk104_clkgate_engine_info, &gk104_idle_filter,
+				ptherm);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h
new file mode 100644
index 0000000..293e774
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2018 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Lyude Paul
+ */
+
+#ifndef __GK104_THERM_H__
+#define __GK104_THERM_H__
+#define gk104_therm(p) (container_of((p), struct gk104_therm, base))
+
+#include <subdev/therm.h>
+#include "priv.h"
+#include "gf100.h"
+
+struct gk104_clkgate_engine_info {
+	enum nvkm_devidx engine;
+	u8 offset;
+};
+
+struct gk104_therm {
+	struct nvkm_therm base;
+
+	const struct gk104_clkgate_engine_info *clkgate_order;
+	const struct gf100_idle_filter *idle_filter;
+};
+
+extern const struct gk104_clkgate_engine_info gk104_clkgate_engine_info[];
+extern const struct gf100_idle_filter gk104_idle_filter;
+
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c
index c08097f..4caf401 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gt215.c
@@ -36,7 +36,7 @@ gt215_therm_fan_sense(struct nvkm_therm *therm)
 	return -ENODEV;
 }
 
-static void
+void
 gt215_therm_init(struct nvkm_therm *therm)
 {
 	struct nvkm_device *device = therm->subdev.device;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
index 1f46e37..21659da 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h
@@ -32,6 +32,8 @@
 
 int nvkm_therm_new_(const struct nvkm_therm_func *, struct nvkm_device *,
 		    int index, struct nvkm_therm **);
+void nvkm_therm_ctor(struct nvkm_therm *therm, struct nvkm_device *device,
+		     int index, const struct nvkm_therm_func *func);
 
 struct nvkm_fan {
 	struct nvkm_therm *parent;
@@ -66,8 +68,6 @@ int nvkm_therm_fan_set(struct nvkm_therm *, bool now, int percent);
 int nvkm_therm_fan_user_get(struct nvkm_therm *);
 int nvkm_therm_fan_user_set(struct nvkm_therm *, int percent);
 
-int nvkm_therm_preinit(struct nvkm_therm *);
-
 int  nvkm_therm_sensor_init(struct nvkm_therm *);
 int  nvkm_therm_sensor_fini(struct nvkm_therm *, bool suspend);
 void nvkm_therm_sensor_preinit(struct nvkm_therm *);
@@ -96,6 +96,11 @@ struct nvkm_therm_func {
 	int (*fan_sense)(struct nvkm_therm *);
 
 	void (*program_alarms)(struct nvkm_therm *);
+
+	void (*clkgate_init)(struct nvkm_therm *,
+			     const struct nvkm_therm_clkgate_pack *);
+	void (*clkgate_enable)(struct nvkm_therm *);
+	void (*clkgate_fini)(struct nvkm_therm *, bool);
 };
 
 void nv40_therm_intr(struct nvkm_therm *);
@@ -111,9 +116,21 @@ void g84_therm_fini(struct nvkm_therm *);
 
 int gt215_therm_fan_sense(struct nvkm_therm *);
 
+void gf100_clkgate_init(struct nvkm_therm *,
+			const struct nvkm_therm_clkgate_pack *);
+
 void g84_therm_init(struct nvkm_therm *);
+
+int gf119_fan_pwm_ctrl(struct nvkm_therm *, int, bool);
+int gf119_fan_pwm_get(struct nvkm_therm *, int, u32 *, u32 *);
+int gf119_fan_pwm_set(struct nvkm_therm *, int, u32, u32);
+int gf119_fan_pwm_clock(struct nvkm_therm *, int);
 void gf119_therm_init(struct nvkm_therm *);
 
+void gk104_therm_init(struct nvkm_therm *);
+void gk104_clkgate_enable(struct nvkm_therm *);
+void gk104_clkgate_fini(struct nvkm_therm *, bool);
+
 int nvkm_fanpwm_create(struct nvkm_therm *, struct dcb_gpio_func *);
 int nvkm_fantog_create(struct nvkm_therm *, struct dcb_gpio_func *);
 int nvkm_fannil_create(struct nvkm_therm *);
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c
index d34d1cf..95f4db7 100644
--- a/drivers/gpu/drm/radeon/radeon_uvd.c
+++ b/drivers/gpu/drm/radeon/radeon_uvd.c
@@ -995,7 +995,7 @@ int radeon_uvd_calc_upll_dividers(struct radeon_device *rdev,
 		/* calc dclk divider with current vco freq */
 		dclk_div = radeon_uvd_calc_upll_post_div(vco_freq, dclk,
 							 pd_min, pd_even);
-		if (vclk_div > pd_max)
+		if (dclk_div > pd_max)
 			break; /* vco is too big, it has to stop */
 
 		/* calc score with current vco freq */
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 893003f..2fef09a5 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1727,7 +1727,7 @@ int ttm_bo_swapout(struct ttm_bo_global *glob, struct ttm_operation_ctx *ctx)
 	kref_get(&bo->list_kref);
 
 	if (!list_empty(&bo->ddestroy)) {
-		ret = ttm_bo_cleanup_refs(bo, false, false, true);
+		ret = ttm_bo_cleanup_refs(bo, false, false, locked);
 		kref_put(&bo->list_kref, ttm_bo_release_list);
 		return ret;
 	}
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index 08a3c32..60fcef1 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -316,7 +316,7 @@ static void ttm_bo_vm_close(struct vm_area_struct *vma)
 
 static int ttm_bo_vm_access_kmap(struct ttm_buffer_object *bo,
 				 unsigned long offset,
-				 void *buf, int len, int write)
+				 uint8_t *buf, int len, int write)
 {
 	unsigned long page = offset >> PAGE_SHIFT;
 	unsigned long bytes_left = len;
@@ -345,6 +345,7 @@ static int ttm_bo_vm_access_kmap(struct ttm_buffer_object *bo,
 		ttm_bo_kunmap(&map);
 
 		page++;
+		buf += bytes;
 		bytes_left -= bytes;
 		offset = 0;
 	} while (bytes_left);
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index 8755df3..3300dac 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -239,8 +239,9 @@ static u8 sl82c105_bridge_revision(struct pci_dev *dev)
 	/*
 	 * The bridge should be part of the same device, but function 0.
 	 */
-	bridge = pci_get_bus_and_slot(dev->bus->number,
-			       PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+	bridge = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus),
+					dev->bus->number,
+					PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
 	if (!bridge)
 		return -1;
 
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 5cd7004..8517d6e 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -20,7 +20,8 @@
 	  Userspace InfiniBand Management Datagram (MAD) support.  This
 	  is the kernel side of the userspace MAD support, which allows
 	  userspace processes to send and receive MADs. You will also
-	  need libibumad from <http://www.openfabrics.org/downloads/management/>.
+	  need libibumad from rdma-core
+	  <https://github.com/linux-rdma/rdma-core>.
 
 config INFINIBAND_USER_ACCESS
 	tristate "InfiniBand userspace access (verbs and CM)"
@@ -32,10 +33,10 @@
 	  to set up connections and directly access InfiniBand
 	  hardware for fast-path operations.  You will also need
 	  libibverbs, libibcm and a hardware driver library from
-	  <http://www.openfabrics.org/git/>.
+	  rdma-core <https://github.com/linux-rdma/rdma-core>.
 
 config INFINIBAND_EXP_USER_ACCESS
-	bool "Allow experimental support for Infiniband ABI"
+	bool "Enable the full uverbs ioctl interface (EXPERIMENTAL)"
 	depends on INFINIBAND_USER_ACCESS
 	---help---
 	  IOCTL based ABI support for Infiniband. This allows userspace
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
index fa8655e..5326a68 100644
--- a/drivers/infiniband/core/nldev.c
+++ b/drivers/infiniband/core/nldev.c
@@ -499,8 +499,10 @@ static int nldev_res_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return -EINVAL;
 
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-	if (!msg)
+	if (!msg) {
+		ret = -ENOMEM;
 		goto err;
+	}
 
 	nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
 			RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_GET),
diff --git a/drivers/infiniband/core/uverbs_std_types.c b/drivers/infiniband/core/uverbs_std_types.c
index b571176..cab0ac3 100644
--- a/drivers/infiniband/core/uverbs_std_types.c
+++ b/drivers/infiniband/core/uverbs_std_types.c
@@ -316,7 +316,7 @@ static int uverbs_create_cq_handler(struct ib_device *ib_dev,
 	cq->uobject       = &obj->uobject;
 	cq->comp_handler  = ib_uverbs_comp_handler;
 	cq->event_handler = ib_uverbs_cq_event_handler;
-	cq->cq_context    = &ev_file->ev_queue;
+	cq->cq_context    = ev_file ? &ev_file->ev_queue : NULL;
 	obj->uobject.object = cq;
 	obj->uobject.user_handle = user_handle;
 	atomic_set(&cq->usecnt, 0);
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 9b8fa77..ae9e9ff5 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1314,7 +1314,7 @@ int bnxt_re_destroy_srq(struct ib_srq *ib_srq)
 		return rc;
 	}
 
-	if (srq->umem && !IS_ERR(srq->umem))
+	if (srq->umem)
 		ib_umem_release(srq->umem);
 	kfree(srq);
 	atomic_dec(&rdev->srq_count);
@@ -1430,11 +1430,8 @@ struct ib_srq *bnxt_re_create_srq(struct ib_pd *ib_pd,
 	return &srq->ib_srq;
 
 fail:
-	if (udata && srq->umem && !IS_ERR(srq->umem)) {
+	if (srq->umem)
 		ib_umem_release(srq->umem);
-		srq->umem = NULL;
-	}
-
 	kfree(srq);
 exit:
 	return ERR_PTR(rc);
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 8b5f11a..1b0e946 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -557,8 +557,10 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
 
 	srq->swq = kcalloc(srq->hwq.max_elements, sizeof(*srq->swq),
 			   GFP_KERNEL);
-	if (!srq->swq)
+	if (!srq->swq) {
+		rc = -ENOMEM;
 		goto fail;
+	}
 
 	RCFW_CMD_PREP(req, CREATE_SRQ, cmd_flags);
 
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c
index ad37d54..539a5d4 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_res.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c
@@ -705,12 +705,8 @@ static int bnxt_qplib_alloc_dpi_tbl(struct bnxt_qplib_res     *res,
 	dpit->max = dbr_len / PAGE_SIZE;
 
 	dpit->app_tbl = kcalloc(dpit->max, sizeof(void *), GFP_KERNEL);
-	if (!dpit->app_tbl) {
-		pci_iounmap(res->pdev, dpit->dbr_bar_reg_iomem);
-		dev_err(&res->pdev->dev,
-			"QPLIB: DPI app tbl allocation failed");
-		return -ENOMEM;
-	}
+	if (!dpit->app_tbl)
+		goto unmap_io;
 
 	bytes = dpit->max >> 3;
 	if (!bytes)
@@ -718,18 +714,18 @@ static int bnxt_qplib_alloc_dpi_tbl(struct bnxt_qplib_res     *res,
 
 	dpit->tbl = kmalloc(bytes, GFP_KERNEL);
 	if (!dpit->tbl) {
-		pci_iounmap(res->pdev, dpit->dbr_bar_reg_iomem);
 		kfree(dpit->app_tbl);
 		dpit->app_tbl = NULL;
-		dev_err(&res->pdev->dev,
-			"QPLIB: DPI tbl allocation failed for size = %d",
-			bytes);
-		return -ENOMEM;
+		goto unmap_io;
 	}
 
 	memset((u8 *)dpit->tbl, 0xFF, bytes);
 
 	return 0;
+
+unmap_io:
+	pci_iounmap(res->pdev, dpit->dbr_bar_reg_iomem);
+	return -ENOMEM;
 }
 
 /* PKEYs */
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
index 6660f920..e6a60fa 100644
--- a/drivers/infiniband/hw/hfi1/chip.c
+++ b/drivers/infiniband/hw/hfi1/chip.c
@@ -1083,6 +1083,7 @@ static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp,
 static void clear_full_mgmt_pkey(struct hfi1_pportdata *ppd);
 static int wait_link_transfer_active(struct hfi1_devdata *dd, int wait_ms);
 static void clear_rsm_rule(struct hfi1_devdata *dd, u8 rule_index);
+static void update_xmit_counters(struct hfi1_pportdata *ppd, u16 link_width);
 
 /*
  * Error interrupt table entry.  This is used as input to the interrupt
@@ -6905,6 +6906,32 @@ void handle_freeze(struct work_struct *work)
 	/* no longer frozen */
 }
 
+/**
+ * update_xmit_counters - update PortXmitWait/PortVlXmitWait
+ * counters.
+ * @ppd: info of physical Hfi port
+ * @link_width: new link width after link up or downgrade
+ *
+ * Update the PortXmitWait and PortVlXmitWait counters after
+ * a link up or downgrade event to reflect a link width change.
+ */
+static void update_xmit_counters(struct hfi1_pportdata *ppd, u16 link_width)
+{
+	int i;
+	u16 tx_width;
+	u16 link_speed;
+
+	tx_width = tx_link_width(link_width);
+	link_speed = get_link_speed(ppd->link_speed_active);
+
+	/*
+	 * There are C_VL_COUNT number of PortVLXmitWait counters.
+	 * Adding 1 to C_VL_COUNT to include the PortXmitWait counter.
+	 */
+	for (i = 0; i < C_VL_COUNT + 1; i++)
+		get_xmit_wait_counters(ppd, tx_width, link_speed, i);
+}
+
 /*
  * Handle a link up interrupt from the 8051.
  *
@@ -7526,18 +7553,29 @@ void handle_verify_cap(struct work_struct *work)
 	set_link_state(ppd, HLS_GOING_UP);
 }
 
-/*
- * Apply the link width downgrade enabled policy against the current active
- * link widths.
+/**
+ * apply_link_downgrade_policy - Apply the link width downgrade enabled
+ * policy against the current active link widths.
+ * @ppd: info of physical Hfi port
+ * @refresh_widths: True indicates link downgrade event
+ * @return: True indicates a successful link downgrade. False indicates
+ *	    link downgrade event failed and the link will bounce back to
+ *	    default link width.
  *
- * Called when the enabled policy changes or the active link widths change.
+ * Called when the enabled policy changes or the active link widths
+ * change.
+ * Refresh_widths indicates that a link downgrade occurred. The
+ * link_downgraded variable is set by refresh_widths and
+ * determines the success/failure of the policy application.
  */
-void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths)
+bool apply_link_downgrade_policy(struct hfi1_pportdata *ppd,
+				 bool refresh_widths)
 {
 	int do_bounce = 0;
 	int tries;
 	u16 lwde;
 	u16 tx, rx;
+	bool link_downgraded = refresh_widths;
 
 	/* use the hls lock to avoid a race with actual link up */
 	tries = 0;
@@ -7571,6 +7609,7 @@ void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths)
 	    ppd->link_width_downgrade_rx_active == 0) {
 		/* the 8051 reported a dead link as a downgrade */
 		dd_dev_err(ppd->dd, "Link downgrade is really a link down, ignoring\n");
+		link_downgraded = false;
 	} else if (lwde == 0) {
 		/* downgrade is disabled */
 
@@ -7587,6 +7626,7 @@ void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths)
 				   ppd->link_width_downgrade_tx_active,
 				   ppd->link_width_downgrade_rx_active);
 			do_bounce = 1;
+			link_downgraded = false;
 		}
 	} else if ((lwde & ppd->link_width_downgrade_tx_active) == 0 ||
 		   (lwde & ppd->link_width_downgrade_rx_active) == 0) {
@@ -7598,6 +7638,7 @@ void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths)
 			   lwde, ppd->link_width_downgrade_tx_active,
 			   ppd->link_width_downgrade_rx_active);
 		do_bounce = 1;
+		link_downgraded = false;
 	}
 
 done:
@@ -7609,6 +7650,8 @@ void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths)
 		set_link_state(ppd, HLS_DN_OFFLINE);
 		start_link(ppd);
 	}
+
+	return link_downgraded;
 }
 
 /*
@@ -7622,7 +7665,8 @@ void handle_link_downgrade(struct work_struct *work)
 							link_downgrade_work);
 
 	dd_dev_info(ppd->dd, "8051: Link width downgrade\n");
-	apply_link_downgrade_policy(ppd, 1);
+	if (apply_link_downgrade_policy(ppd, true))
+		update_xmit_counters(ppd, ppd->link_width_downgrade_tx_active);
 }
 
 static char *dcc_err_string(char *buf, int buf_len, u64 flags)
@@ -8264,8 +8308,8 @@ static irqreturn_t sdma_interrupt(int irq, void *data)
 		/* handle the interrupt(s) */
 		sdma_engine_interrupt(sde, status);
 	} else {
-		dd_dev_err_ratelimited(dd, "SDMA engine %u interrupt, but no status bits set\n",
-				       sde->this_idx);
+		dd_dev_info_ratelimited(dd, "SDMA engine %u interrupt, but no status bits set\n",
+					sde->this_idx);
 	}
 	return IRQ_HANDLED;
 }
@@ -10597,6 +10641,14 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
 		add_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
 
 		handle_linkup_change(dd, 1);
+
+		/*
+		 * After link up, a new link width will have been set.
+		 * Update the xmit counters with regards to the new
+		 * link width.
+		 */
+		update_xmit_counters(ppd, ppd->link_width_active);
+
 		ppd->host_link_state = HLS_UP_INIT;
 		update_statusp(ppd, IB_PORT_INIT);
 		break;
@@ -12960,7 +13012,14 @@ static void disable_intx(struct pci_dev *pdev)
 	pci_intx(pdev, 0);
 }
 
-static void clean_up_interrupts(struct hfi1_devdata *dd)
+/**
+ * hfi1_clean_up_interrupts() - Free all IRQ resources
+ * @dd: valid device data data structure
+ *
+ * Free the MSI or INTx IRQs and assoicated PCI resources,
+ * if they have been allocated.
+ */
+void hfi1_clean_up_interrupts(struct hfi1_devdata *dd)
 {
 	int i;
 
@@ -13321,7 +13380,7 @@ static int set_up_interrupts(struct hfi1_devdata *dd)
 	return 0;
 
 fail:
-	clean_up_interrupts(dd);
+	hfi1_clean_up_interrupts(dd);
 	return ret;
 }
 
@@ -14748,7 +14807,6 @@ void hfi1_start_cleanup(struct hfi1_devdata *dd)
 	aspm_exit(dd);
 	free_cntrs(dd);
 	free_rcverr(dd);
-	clean_up_interrupts(dd);
 	finish_chip_resources(dd);
 }
 
@@ -15204,7 +15262,7 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
 bail_free_cntrs:
 	free_cntrs(dd);
 bail_clear_intr:
-	clean_up_interrupts(dd);
+	hfi1_clean_up_interrupts(dd);
 bail_cleanup:
 	hfi1_pcie_ddcleanup(dd);
 bail_free:
diff --git a/drivers/infiniband/hw/hfi1/chip.h b/drivers/infiniband/hw/hfi1/chip.h
index 21fca8e..c0d70f2 100644
--- a/drivers/infiniband/hw/hfi1/chip.h
+++ b/drivers/infiniband/hw/hfi1/chip.h
@@ -736,8 +736,8 @@ int read_8051_config(struct hfi1_devdata *, u8, u8, u32 *);
 int start_link(struct hfi1_pportdata *ppd);
 int bringup_serdes(struct hfi1_pportdata *ppd);
 void set_intr_state(struct hfi1_devdata *dd, u32 enable);
-void apply_link_downgrade_policy(struct hfi1_pportdata *ppd,
-				 int refresh_widths);
+bool apply_link_downgrade_policy(struct hfi1_pportdata *ppd,
+				 bool refresh_widths);
 void update_usrhead(struct hfi1_ctxtdata *rcd, u32 hd, u32 updegr, u32 egrhd,
 		    u32 intr_adjust, u32 npkts);
 int stop_drain_data_vls(struct hfi1_devdata *dd);
diff --git a/drivers/infiniband/hw/hfi1/debugfs.c b/drivers/infiniband/hw/hfi1/debugfs.c
index 2e6e0c5..852173b 100644
--- a/drivers/infiniband/hw/hfi1/debugfs.c
+++ b/drivers/infiniband/hw/hfi1/debugfs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2015-2017 Intel Corporation.
+ * Copyright(c) 2015-2018 Intel Corporation.
  *
  * This file is provided under a dual BSD/GPLv2 license.  When using or
  * redistributing this file, you may do so under either license.
@@ -1201,6 +1201,13 @@ static int _fault_stats_seq_show(struct seq_file *s, void *v)
 		}
 		hfi1_rcd_put(rcd);
 	}
+	for_each_possible_cpu(j) {
+		struct hfi1_opcode_stats_perctx *sp =
+			per_cpu_ptr(dd->tx_opstats, j);
+
+		n_packets += sp->stats[i].n_packets;
+		n_bytes += sp->stats[i].n_bytes;
+	}
 	if (!n_packets && !n_bytes)
 		return SEQ_SKIP;
 	if (!ibd->fault_opcode->n_rxfaults[i] &&
diff --git a/drivers/infiniband/hw/hfi1/driver.c b/drivers/infiniband/hw/hfi1/driver.c
index 067b29f..addc68e 100644
--- a/drivers/infiniband/hw/hfi1/driver.c
+++ b/drivers/infiniband/hw/hfi1/driver.c
@@ -256,7 +256,12 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
 	u32 mlid_base;
 	struct hfi1_ibport *ibp = rcd_to_iport(rcd);
 	struct hfi1_devdata *dd = ppd->dd;
-	struct rvt_dev_info *rdi = &dd->verbs_dev.rdi;
+	struct hfi1_ibdev *verbs_dev = &dd->verbs_dev;
+	struct rvt_dev_info *rdi = &verbs_dev->rdi;
+
+	if ((packet->rhf & RHF_DC_ERR) &&
+	    hfi1_dbg_fault_suppress_err(verbs_dev))
+		return;
 
 	if (packet->rhf & (RHF_VCRC_ERR | RHF_ICRC_ERR))
 		return;
@@ -634,9 +639,10 @@ static void __prescan_rxq(struct hfi1_packet *packet)
 	}
 }
 
-static void process_rcv_qp_work(struct hfi1_ctxtdata *rcd)
+static void process_rcv_qp_work(struct hfi1_packet *packet)
 {
 	struct rvt_qp *qp, *nqp;
+	struct hfi1_ctxtdata *rcd = packet->rcd;
 
 	/*
 	 * Iterate over all QPs waiting to respond.
@@ -646,7 +652,8 @@ static void process_rcv_qp_work(struct hfi1_ctxtdata *rcd)
 		list_del_init(&qp->rspwait);
 		if (qp->r_flags & RVT_R_RSP_NAK) {
 			qp->r_flags &= ~RVT_R_RSP_NAK;
-			hfi1_send_rc_ack(rcd, qp, 0);
+			packet->qp = qp;
+			hfi1_send_rc_ack(packet, 0);
 		}
 		if (qp->r_flags & RVT_R_RSP_SEND) {
 			unsigned long flags;
@@ -667,7 +674,7 @@ static noinline int max_packet_exceeded(struct hfi1_packet *packet, int thread)
 	if (thread) {
 		if ((packet->numpkt & (MAX_PKT_RECV_THREAD - 1)) == 0)
 			/* allow defered processing */
-			process_rcv_qp_work(packet->rcd);
+			process_rcv_qp_work(packet);
 		cond_resched();
 		return RCV_PKT_OK;
 	} else {
@@ -809,7 +816,7 @@ int handle_receive_interrupt_nodma_rtail(struct hfi1_ctxtdata *rcd, int thread)
 			last = RCV_PKT_DONE;
 		process_rcv_update(last, &packet);
 	}
-	process_rcv_qp_work(rcd);
+	process_rcv_qp_work(&packet);
 	rcd->head = packet.rhqoff;
 bail:
 	finish_packet(&packet);
@@ -838,7 +845,7 @@ int handle_receive_interrupt_dma_rtail(struct hfi1_ctxtdata *rcd, int thread)
 			last = RCV_PKT_DONE;
 		process_rcv_update(last, &packet);
 	}
-	process_rcv_qp_work(rcd);
+	process_rcv_qp_work(&packet);
 	rcd->head = packet.rhqoff;
 bail:
 	finish_packet(&packet);
@@ -1068,7 +1075,7 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread)
 		process_rcv_update(last, &packet);
 	}
 
-	process_rcv_qp_work(rcd);
+	process_rcv_qp_work(&packet);
 	rcd->head = packet.rhqoff;
 
 bail:
@@ -1438,8 +1445,8 @@ static int hfi1_setup_9B_packet(struct hfi1_packet *packet)
 	packet->sc = hfi1_9B_get_sc5(hdr, packet->rhf);
 	packet->pad = ib_bth_get_pad(packet->ohdr);
 	packet->extra_byte = 0;
-	packet->fecn = ib_bth_get_fecn(packet->ohdr);
-	packet->becn = ib_bth_get_becn(packet->ohdr);
+	packet->pkey = ib_bth_get_pkey(packet->ohdr);
+	packet->migrated = ib_bth_is_migration(packet->ohdr);
 
 	return 0;
 drop:
@@ -1492,8 +1499,10 @@ static int hfi1_setup_bypass_packet(struct hfi1_packet *packet)
 
 	/* Query commonly used fields from packet header */
 	packet->opcode = ib_bth_get_opcode(packet->ohdr);
-	packet->hlen = hdr_len_by_opcode[packet->opcode] + 8 + grh_len;
-	packet->payload = packet->ebuf + packet->hlen - (4 * sizeof(u32));
+	/* hdr_len_by_opcode already has an IB LRH factored in */
+	packet->hlen = hdr_len_by_opcode[packet->opcode] +
+		(LRH_16B_BYTES - LRH_9B_BYTES) + grh_len;
+	packet->payload = packet->ebuf + packet->hlen - LRH_16B_BYTES;
 	packet->slid = hfi1_16B_get_slid(packet->hdr);
 	packet->dlid = hfi1_16B_get_dlid(packet->hdr);
 	if (unlikely(hfi1_is_16B_mcast(packet->dlid)))
@@ -1504,8 +1513,8 @@ static int hfi1_setup_bypass_packet(struct hfi1_packet *packet)
 	packet->sl = ibp->sc_to_sl[packet->sc];
 	packet->pad = hfi1_16B_bth_get_pad(packet->ohdr);
 	packet->extra_byte = SIZE_OF_LT;
-	packet->fecn = hfi1_16B_get_fecn(packet->hdr);
-	packet->becn = hfi1_16B_get_becn(packet->hdr);
+	packet->pkey = hfi1_16B_get_pkey(packet->hdr);
+	packet->migrated = opa_bth_is_migration(packet->ohdr);
 
 	if (hfi1_bypass_ingress_pkt_check(packet))
 		goto drop;
@@ -1550,19 +1559,7 @@ int process_receive_ib(struct hfi1_packet *packet)
 	if (hfi1_setup_9B_packet(packet))
 		return RHF_RCV_CONTINUE;
 
-	trace_hfi1_rcvhdr(packet->rcd->ppd->dd,
-			  packet->rcd->ctxt,
-			  rhf_err_flags(packet->rhf),
-			  RHF_RCV_TYPE_IB,
-			  packet->hlen,
-			  packet->tlen,
-			  packet->updegr,
-			  rhf_egr_index(packet->rhf));
-
-	if (unlikely(
-		 (hfi1_dbg_fault_suppress_err(&packet->rcd->dd->verbs_dev) &&
-		 (packet->rhf & RHF_DC_ERR))))
-		return RHF_RCV_CONTINUE;
+	trace_hfi1_rcvhdr(packet);
 
 	if (unlikely(rhf_err_flags(packet->rhf))) {
 		handle_eflags(packet);
@@ -1598,6 +1595,8 @@ int process_receive_bypass(struct hfi1_packet *packet)
 	if (hfi1_setup_bypass_packet(packet))
 		return RHF_RCV_CONTINUE;
 
+	trace_hfi1_rcvhdr(packet);
+
 	if (unlikely(rhf_err_flags(packet->rhf))) {
 		handle_eflags(packet);
 		return RHF_RCV_CONTINUE;
diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c
index bd6f03c..d9a0f25 100644
--- a/drivers/infiniband/hw/hfi1/file_ops.c
+++ b/drivers/infiniband/hw/hfi1/file_ops.c
@@ -196,9 +196,6 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
 	if (!atomic_inc_not_zero(&dd->user_refcount))
 		return -ENXIO;
 
-	/* Just take a ref now. Not all opens result in a context assign */
-	kobject_get(&dd->kobj);
-
 	/* The real work is performed later in assign_ctxt() */
 
 	fd = kzalloc(sizeof(*fd), GFP_KERNEL);
@@ -208,6 +205,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
 		fd->mm = current->mm;
 		mmgrab(fd->mm);
 		fd->dd = dd;
+		kobject_get(&fd->dd->kobj);
 		fp->private_data = fd;
 	} else {
 		fp->private_data = NULL;
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h
index b42c222..90bc8c7 100644
--- a/drivers/infiniband/hw/hfi1/hfi.h
+++ b/drivers/infiniband/hw/hfi1/hfi.h
@@ -341,6 +341,7 @@ struct hfi1_packet {
 	u32 slid;
 	u16 tlen;
 	s16 etail;
+	u16 pkey;
 	u8 hlen;
 	u8 numpkt;
 	u8 rsize;
@@ -351,8 +352,7 @@ struct hfi1_packet {
 	u8 sc;
 	u8 sl;
 	u8 opcode;
-	bool becn;
-	bool fecn;
+	bool migrated;
 };
 
 /* Packet types */
@@ -858,6 +858,13 @@ struct hfi1_pportdata {
 	struct work_struct linkstate_active_work;
 	/* Does this port need to prescan for FECNs */
 	bool cc_prescan;
+	/*
+	 * Sample sendWaitCnt & sendWaitVlCnt during link transition
+	 * and counter request.
+	 */
+	u64 port_vl_xmit_wait_last[C_VL_COUNT + 1];
+	u16 prev_link_width;
+	u64 vl_xmit_flit_cnt[C_VL_COUNT + 1];
 };
 
 typedef int (*rhf_rcv_function_ptr)(struct hfi1_packet *packet);
@@ -1779,19 +1786,15 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt,
 static inline bool process_ecn(struct rvt_qp *qp, struct hfi1_packet *pkt,
 			       bool do_cnp)
 {
-	struct ib_other_headers *ohdr = pkt->ohdr;
-
-	u32 bth1;
-	bool becn = false;
-	bool fecn = false;
+	bool becn;
+	bool fecn;
 
 	if (pkt->etype == RHF_RCV_TYPE_BYPASS) {
 		fecn = hfi1_16B_get_fecn(pkt->hdr);
 		becn = hfi1_16B_get_becn(pkt->hdr);
 	} else {
-		bth1 = be32_to_cpu(ohdr->bth[1]);
-		fecn = bth1 & IB_FECN_SMASK;
-		becn = bth1 & IB_BECN_SMASK;
+		fecn = ib_bth_get_fecn(pkt->ohdr);
+		becn = ib_bth_get_becn(pkt->ohdr);
 	}
 	if (unlikely(fecn || becn)) {
 		hfi1_process_ecn_slowpath(qp, pkt, do_cnp);
@@ -1957,6 +1960,7 @@ void hfi1_verbs_unregister_sysfs(struct hfi1_devdata *dd);
 int qsfp_dump(struct hfi1_pportdata *ppd, char *buf, int len);
 
 int hfi1_pcie_init(struct pci_dev *pdev, const struct pci_device_id *ent);
+void hfi1_clean_up_interrupts(struct hfi1_devdata *dd);
 void hfi1_pcie_cleanup(struct pci_dev *pdev);
 int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev);
 void hfi1_pcie_ddcleanup(struct hfi1_devdata *);
@@ -2416,7 +2420,7 @@ static inline void hfi1_make_ib_hdr(struct ib_header *hdr,
 static inline void hfi1_make_16b_hdr(struct hfi1_16b_header *hdr,
 				     u32 slid, u32 dlid,
 				     u16 len, u16 pkey,
-				     u8 becn, u8 fecn, u8 l4,
+				     bool becn, bool fecn, u8 l4,
 				     u8 sc)
 {
 	u32 lrh0 = 0;
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c
index 9b128268..33eba23 100644
--- a/drivers/infiniband/hw/hfi1/init.c
+++ b/drivers/infiniband/hw/hfi1/init.c
@@ -172,7 +172,7 @@ int hfi1_create_kctxts(struct hfi1_devdata *dd)
 	u16 i;
 	int ret;
 
-	dd->rcd = kzalloc_node(dd->num_rcv_contexts * sizeof(*dd->rcd),
+	dd->rcd = kcalloc_node(dd->num_rcv_contexts, sizeof(*dd->rcd),
 			       GFP_KERNEL, dd->node);
 	if (!dd->rcd)
 		return -ENOMEM;
@@ -439,15 +439,16 @@ int hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, int numa,
 		 * The resulting value will be rounded down to the closest
 		 * multiple of dd->rcv_entries.group_size.
 		 */
-		rcd->egrbufs.buffers = kzalloc_node(
-			rcd->egrbufs.count * sizeof(*rcd->egrbufs.buffers),
-			GFP_KERNEL, numa);
+		rcd->egrbufs.buffers =
+			kcalloc_node(rcd->egrbufs.count,
+				     sizeof(*rcd->egrbufs.buffers),
+				     GFP_KERNEL, numa);
 		if (!rcd->egrbufs.buffers)
 			goto bail;
-		rcd->egrbufs.rcvtids = kzalloc_node(
-				rcd->egrbufs.count *
-				sizeof(*rcd->egrbufs.rcvtids),
-				GFP_KERNEL, numa);
+		rcd->egrbufs.rcvtids =
+			kcalloc_node(rcd->egrbufs.count,
+				     sizeof(*rcd->egrbufs.rcvtids),
+				     GFP_KERNEL, numa);
 		if (!rcd->egrbufs.rcvtids)
 			goto bail;
 		rcd->egrbufs.size = eager_buffer_size;
@@ -637,6 +638,15 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd,
 	ppd->dd = dd;
 	ppd->hw_pidx = hw_pidx;
 	ppd->port = port; /* IB port number, not index */
+	ppd->prev_link_width = LINK_WIDTH_DEFAULT;
+	/*
+	 * There are C_VL_COUNT number of PortVLXmitWait counters.
+	 * Adding 1 to C_VL_COUNT to include the PortXmitWait counter.
+	 */
+	for (i = 0; i < C_VL_COUNT + 1; i++) {
+		ppd->port_vl_xmit_wait_last[i] = 0;
+		ppd->vl_xmit_flit_cnt[i] = 0;
+	}
 
 	default_pkey_idx = 1;
 
@@ -1058,8 +1068,9 @@ static void shutdown_device(struct hfi1_devdata *dd)
 	}
 	dd->flags &= ~HFI1_INITTED;
 
-	/* mask interrupts, but not errors */
+	/* mask and clean up interrupts, but not errors */
 	set_intr_state(dd, 0);
+	hfi1_clean_up_interrupts(dd);
 
 	for (pidx = 0; pidx < dd->num_pports; ++pidx) {
 		ppd = dd->pport + pidx;
@@ -1218,6 +1229,7 @@ static void __hfi1_free_devdata(struct kobject *kobj)
 	free_percpu(dd->rcv_limit);
 	free_percpu(dd->send_schedule);
 	free_percpu(dd->tx_opstats);
+	sdma_clean(dd, dd->num_sdma);
 	rvt_dealloc_device(&dd->verbs_dev.rdi);
 }
 
@@ -1704,6 +1716,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		dd_dev_err(dd, "Failed to create /dev devices: %d\n", -j);
 
 	if (initfail || ret) {
+		hfi1_clean_up_interrupts(dd);
 		stop_timers(dd);
 		flush_workqueue(ib_wq);
 		for (pidx = 0; pidx < dd->num_pports; ++pidx) {
diff --git a/drivers/infiniband/hw/hfi1/iowait.h b/drivers/infiniband/hw/hfi1/iowait.h
index 591697d..3d9c32c 100644
--- a/drivers/infiniband/hw/hfi1/iowait.h
+++ b/drivers/infiniband/hw/hfi1/iowait.h
@@ -371,4 +371,13 @@ static inline void iowait_starve_find_max(struct iowait *w, u8 *max,
 	}
 }
 
+/**
+ * iowait_packet_queued() - determine if a packet is already built
+ * @wait: the wait structure
+ */
+static inline bool iowait_packet_queued(struct iowait *wait)
+{
+	return !list_empty(&wait->tx_head);
+}
+
 #endif
diff --git a/drivers/infiniband/hw/hfi1/mad.c b/drivers/infiniband/hw/hfi1/mad.c
index 34547a4..e9962c6 100644
--- a/drivers/infiniband/hw/hfi1/mad.c
+++ b/drivers/infiniband/hw/hfi1/mad.c
@@ -2649,6 +2649,79 @@ static void a0_portstatus(struct hfi1_pportdata *ppd,
 	}
 }
 
+/**
+ * tx_link_width - convert link width bitmask to integer
+ * value representing actual link width.
+ * @link_width: width of active link
+ * @return: return index of the bit set in link_width var
+ *
+ * The function convert and return the index of bit set
+ * that indicate the current link width.
+ */
+u16 tx_link_width(u16 link_width)
+{
+	int n = LINK_WIDTH_DEFAULT;
+	u16 tx_width = n;
+
+	while (link_width && n) {
+		if (link_width & (1 << (n - 1))) {
+			tx_width = n;
+			break;
+		}
+		n--;
+	}
+
+	return tx_width;
+}
+
+/**
+ * get_xmit_wait_counters - Convert HFI 's SendWaitCnt/SendWaitVlCnt
+ * counter in unit of TXE cycle times to flit times.
+ * @ppd: info of physical Hfi port
+ * @link_width: width of active link
+ * @link_speed: speed of active link
+ * @vl: represent VL0-VL7, VL15 for PortVLXmitWait counters request
+ * and if vl value is C_VL_COUNT, it represent SendWaitCnt
+ * counter request
+ * @return: return SendWaitCnt/SendWaitVlCnt counter value per vl.
+ *
+ * Convert SendWaitCnt/SendWaitVlCnt counter from TXE cycle times to
+ * flit times. Call this function to samples these counters. This
+ * function will calculate for previous state transition and update
+ * current state at end of function using ppd->prev_link_width and
+ * ppd->port_vl_xmit_wait_last to port_vl_xmit_wait_curr and link_width.
+ */
+u64 get_xmit_wait_counters(struct hfi1_pportdata *ppd,
+			   u16 link_width, u16 link_speed, int vl)
+{
+	u64 port_vl_xmit_wait_curr;
+	u64 delta_vl_xmit_wait;
+	u64 xmit_wait_val;
+
+	if (vl > C_VL_COUNT)
+		return  0;
+	if (vl < C_VL_COUNT)
+		port_vl_xmit_wait_curr =
+			read_port_cntr(ppd, C_TX_WAIT_VL, vl);
+	else
+		port_vl_xmit_wait_curr =
+			read_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL);
+
+	xmit_wait_val =
+		port_vl_xmit_wait_curr -
+		ppd->port_vl_xmit_wait_last[vl];
+	delta_vl_xmit_wait =
+		convert_xmit_counter(xmit_wait_val,
+				     ppd->prev_link_width,
+				     link_speed);
+
+	ppd->vl_xmit_flit_cnt[vl] += delta_vl_xmit_wait;
+	ppd->port_vl_xmit_wait_last[vl] = port_vl_xmit_wait_curr;
+	ppd->prev_link_width = link_width;
+
+	return ppd->vl_xmit_flit_cnt[vl];
+}
+
 static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
 				  struct ib_device *ibdev,
 				  u8 port, u32 *resp_len)
@@ -2668,6 +2741,8 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
 	struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
 	int vfi;
 	u64 tmp, tmp2;
+	u16 link_width;
+	u16 link_speed;
 
 	response_data_size = sizeof(struct opa_port_status_rsp) +
 				num_vls * sizeof(struct _vls_pctrs);
@@ -2711,8 +2786,16 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
 	rsp->port_multicast_rcv_pkts =
 		cpu_to_be64(read_dev_cntr(dd, C_DC_MC_RCV_PKTS,
 					  CNTR_INVALID_VL));
+	/*
+	 * Convert PortXmitWait counter from TXE cycle times
+	 * to flit times.
+	 */
+	link_width =
+		tx_link_width(ppd->link_width_downgrade_tx_active);
+	link_speed = get_link_speed(ppd->link_speed_active);
 	rsp->port_xmit_wait =
-		cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL));
+		cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
+						   link_speed, C_VL_COUNT));
 	rsp->port_rcv_fecn =
 		cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN, CNTR_INVALID_VL));
 	rsp->port_rcv_becn =
@@ -2777,10 +2860,14 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
 		rsp->vls[vfi].port_vl_xmit_pkts =
 			cpu_to_be64(read_port_cntr(ppd, C_TX_PKT_VL,
 						   idx_from_vl(vl)));
-
+		/*
+		 * Convert PortVlXmitWait counter from TXE cycle
+		 * times to flit times.
+		 */
 		rsp->vls[vfi].port_vl_xmit_wait =
-			cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT_VL,
-						   idx_from_vl(vl)));
+			cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
+							   link_speed,
+							   idx_from_vl(vl)));
 
 		rsp->vls[vfi].port_vl_rcv_fecn =
 			cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN_VL,
@@ -2910,6 +2997,8 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
 	unsigned long vl;
 	u32 vl_select_mask;
 	int vfi;
+	u16 link_width;
+	u16 link_speed;
 
 	num_ports = be32_to_cpu(pmp->mad_hdr.attr_mod) >> 24;
 	num_vls = hweight32(be32_to_cpu(req->vl_select_mask));
@@ -2959,8 +3048,16 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
 	rsp->link_quality_indicator = cpu_to_be32((u32)lq);
 	pma_get_opa_port_dctrs(ibdev, rsp);
 
+	/*
+	 * Convert PortXmitWait counter from TXE
+	 * cycle times to flit times.
+	 */
+	link_width =
+		tx_link_width(ppd->link_width_downgrade_tx_active);
+	link_speed = get_link_speed(ppd->link_speed_active);
 	rsp->port_xmit_wait =
-		cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL));
+		cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
+						   link_speed, C_VL_COUNT));
 	rsp->port_rcv_fecn =
 		cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN, CNTR_INVALID_VL));
 	rsp->port_rcv_becn =
@@ -2996,9 +3093,14 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
 			cpu_to_be64(read_dev_cntr(dd, C_DC_RX_PKT_VL,
 						  idx_from_vl(vl)));
 
+		/*
+		 * Convert PortVlXmitWait counter from TXE
+		 * cycle times to flit times.
+		 */
 		rsp->vls[vfi].port_vl_xmit_wait =
-			cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT_VL,
-						   idx_from_vl(vl)));
+			cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
+							   link_speed,
+							   idx_from_vl(vl)));
 
 		rsp->vls[vfi].port_vl_rcv_fecn =
 			cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN_VL,
@@ -3416,9 +3518,11 @@ static int pma_set_opa_portstatus(struct opa_pma_mad *pmp,
 	if (counter_select & CS_PORT_MCAST_RCV_PKTS)
 		write_dev_cntr(dd, C_DC_MC_RCV_PKTS, CNTR_INVALID_VL, 0);
 
-	if (counter_select & CS_PORT_XMIT_WAIT)
+	if (counter_select & CS_PORT_XMIT_WAIT) {
 		write_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL, 0);
-
+		ppd->port_vl_xmit_wait_last[C_VL_COUNT] = 0;
+		ppd->vl_xmit_flit_cnt[C_VL_COUNT] = 0;
+	}
 	/* ignore cs_sw_portCongestion for HFIs */
 
 	if (counter_select & CS_PORT_RCV_FECN)
@@ -3491,8 +3595,11 @@ static int pma_set_opa_portstatus(struct opa_pma_mad *pmp,
 		if (counter_select & CS_PORT_RCV_PKTS)
 			write_dev_cntr(dd, C_DC_RX_PKT_VL, idx_from_vl(vl), 0);
 
-		if (counter_select & CS_PORT_XMIT_WAIT)
+		if (counter_select & CS_PORT_XMIT_WAIT) {
 			write_port_cntr(ppd, C_TX_WAIT_VL, idx_from_vl(vl), 0);
+			ppd->port_vl_xmit_wait_last[idx_from_vl(vl)] = 0;
+			ppd->vl_xmit_flit_cnt[idx_from_vl(vl)] = 0;
+		}
 
 		/* sw_port_vl_congestion is 0 for HFIs */
 		if (counter_select & CS_PORT_RCV_FECN)
diff --git a/drivers/infiniband/hw/hfi1/mad.h b/drivers/infiniband/hw/hfi1/mad.h
index c4938f3..2f48e69 100644
--- a/drivers/infiniband/hw/hfi1/mad.h
+++ b/drivers/infiniband/hw/hfi1/mad.h
@@ -180,6 +180,15 @@ struct opa_mad_notice_attr {
 #define OPA_VLARB_PREEMPT_MATRIX     3
 
 #define IB_PMA_PORT_COUNTERS_CONG       cpu_to_be16(0xFF00)
+#define LINK_SPEED_25G		1
+#define LINK_SPEED_12_5G	2
+#define LINK_WIDTH_DEFAULT	4
+#define DECIMAL_FACTORING	1000
+/*
+ * The default link width is multiplied by 1000
+ * to get accurate value after division.
+ */
+#define FACTOR_LINK_WIDTH	(LINK_WIDTH_DEFAULT * DECIMAL_FACTORING)
 
 struct ib_pma_portcounters_cong {
 	u8 reserved;
@@ -429,5 +438,41 @@ struct sc2vlnt {
 
 void hfi1_event_pkey_change(struct hfi1_devdata *dd, u8 port);
 void hfi1_handle_trap_timer(struct timer_list *t);
+u16 tx_link_width(u16 link_width);
+u64 get_xmit_wait_counters(struct hfi1_pportdata *ppd, u16 link_width,
+			   u16 link_speed, int vl);
+/**
+ * get_link_speed - determine whether 12.5G or 25G speed
+ * @link_speed: the speed of active link
+ * @return: Return 2 if link speed identified as 12.5G
+ * or return 1 if link speed is 25G.
+ *
+ * The function indirectly calculate required link speed
+ * value for convert_xmit_counter function. If the link
+ * speed is 25G, the function return as 1 as it is required
+ * by xmit counter conversion formula :-( 25G / link_speed).
+ * This conversion will provide value 1 if current
+ * link speed is 25G or 2 if 12.5G.This is done to avoid
+ * 12.5 float number conversion.
+ */
+static inline u16 get_link_speed(u16 link_speed)
+{
+	return (link_speed == 1) ?
+		 LINK_SPEED_12_5G : LINK_SPEED_25G;
+}
 
+/**
+ * convert_xmit_counter - calculate flit times for given xmit counter
+ * value
+ * @xmit_wait_val: current xmit counter value
+ * @link_width: width of active link
+ * @link_speed: speed of active link
+ * @return: return xmit counter value in flit times.
+ */
+static inline u64 convert_xmit_counter(u64 xmit_wait_val, u16 link_width,
+				       u16 link_speed)
+{
+	return (xmit_wait_val * 2 * (FACTOR_LINK_WIDTH / link_width)
+		 * link_speed) / DECIMAL_FACTORING;
+}
 #endif				/* _HFI1_MAD_H */
diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c
index 8c7e7a6..83d66e8 100644
--- a/drivers/infiniband/hw/hfi1/pcie.c
+++ b/drivers/infiniband/hw/hfi1/pcie.c
@@ -1034,6 +1034,7 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd)
 	int do_retry, retry_count = 0;
 	int intnum = 0;
 	uint default_pset;
+	uint pset = pcie_pset;
 	u16 target_vector, target_speed;
 	u16 lnkctl2, vendor;
 	u8 div;
@@ -1201,16 +1202,16 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd)
 	 *
 	 * Set Gen3EqPsetReqVec, leave other fields 0.
 	 */
-	if (pcie_pset == UNSET_PSET)
-		pcie_pset = default_pset;
-	if (pcie_pset > 10) {	/* valid range is 0-10, inclusive */
+	if (pset == UNSET_PSET)
+		pset = default_pset;
+	if (pset > 10) {	/* valid range is 0-10, inclusive */
 		dd_dev_err(dd, "%s: Invalid Eq Pset %u, setting to %d\n",
-			   __func__, pcie_pset, default_pset);
-		pcie_pset = default_pset;
+			   __func__, pset, default_pset);
+		pset = default_pset;
 	}
-	dd_dev_info(dd, "%s: using EQ Pset %u\n", __func__, pcie_pset);
+	dd_dev_info(dd, "%s: using EQ Pset %u\n", __func__, pset);
 	pci_write_config_dword(dd->pcidev, PCIE_CFG_REG_PL106,
-			       ((1 << pcie_pset) <<
+			       ((1 << pset) <<
 			PCIE_CFG_REG_PL106_GEN3_EQ_PSET_REQ_VEC_SHIFT) |
 			PCIE_CFG_REG_PL106_GEN3_EQ_EVAL2MS_DISABLE_SMASK |
 			PCIE_CFG_REG_PL106_GEN3_EQ_PHASE23_EXIT_MODE_SMASK);
@@ -1240,10 +1241,10 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd)
 		/* apply static CTLE tunings */
 		u8 pcie_dc, pcie_lf, pcie_hf, pcie_bw;
 
-		pcie_dc = ctle_tunings[pcie_pset][0];
-		pcie_lf = ctle_tunings[pcie_pset][1];
-		pcie_hf = ctle_tunings[pcie_pset][2];
-		pcie_bw = ctle_tunings[pcie_pset][3];
+		pcie_dc = ctle_tunings[pset][0];
+		pcie_lf = ctle_tunings[pset][1];
+		pcie_hf = ctle_tunings[pset][2];
+		pcie_bw = ctle_tunings[pset][3];
 		write_gasket_interrupt(dd, intnum++, 0x0026, 0x0200 | pcie_dc);
 		write_gasket_interrupt(dd, intnum++, 0x0026, 0x0100 | pcie_lf);
 		write_gasket_interrupt(dd, intnum++, 0x0026, 0x0000 | pcie_hf);
diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c
index 4c1198b..40dac4d 100644
--- a/drivers/infiniband/hw/hfi1/pio.c
+++ b/drivers/infiniband/hw/hfi1/pio.c
@@ -455,8 +455,8 @@ int init_send_contexts(struct hfi1_devdata *dd)
 	dd->hw_to_sw = kmalloc_array(TXE_NUM_CONTEXTS, sizeof(u8),
 					GFP_KERNEL);
 	dd->send_contexts = kcalloc(dd->num_send_contexts,
-					sizeof(struct send_context_info),
-					GFP_KERNEL);
+				    sizeof(struct send_context_info),
+				    GFP_KERNEL);
 	if (!dd->send_contexts || !dd->hw_to_sw) {
 		kfree(dd->hw_to_sw);
 		kfree(dd->send_contexts);
@@ -856,8 +856,9 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type,
 		 * so head == tail can mean empty.
 		 */
 		sc->sr_size = sci->credits + 1;
-		sc->sr = kzalloc_node(sizeof(union pio_shadow_ring) *
-				sc->sr_size, GFP_KERNEL, numa);
+		sc->sr = kcalloc_node(sc->sr_size,
+				      sizeof(union pio_shadow_ring),
+				      GFP_KERNEL, numa);
 		if (!sc->sr) {
 			sc_free(sc);
 			return NULL;
@@ -1958,9 +1959,9 @@ int init_pervl_scs(struct hfi1_devdata *dd)
 	hfi1_init_ctxt(dd->vld[15].sc);
 	dd->vld[15].mtu = enum_to_mtu(OPA_MTU_2048);
 
-	dd->kernel_send_context = kzalloc_node(dd->num_send_contexts *
-					sizeof(struct send_context *),
-					GFP_KERNEL, dd->node);
+	dd->kernel_send_context = kcalloc_node(dd->num_send_contexts,
+					       sizeof(struct send_context *),
+					       GFP_KERNEL, dd->node);
 	if (!dd->kernel_send_context)
 		goto freesc15;
 
diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c
index 5507910..d30dd1a 100644
--- a/drivers/infiniband/hw/hfi1/qp.c
+++ b/drivers/infiniband/hw/hfi1/qp.c
@@ -565,7 +565,7 @@ void qp_iter_print(struct seq_file *s, struct rvt_qp_iter *iter)
 	if (qp->s_ack_queue)
 		e = &qp->s_ack_queue[qp->s_tail_ack_queue];
 	seq_printf(s,
-		   "N %d %s QP %x R %u %s %u %u %u f=%x %u %u %u %u %u %u SPSN %x %x %x %x %x RPSN %x S(%u %u %u %u %u %u %u) R(%u %u %u) RQP %x LID %x SL %u MTU %u %u %u %u %u SDE %p,%u SC %p,%u SCQ %u %u PID %d OS %x %x E %x %x %x RNR %d %s %d\n",
+		   "N %d %s QP %x R %u %s %u %u f=%x %u %u %u %u %u %u SPSN %x %x %x %x %x RPSN %x S(%u %u %u %u %u %u %u) R(%u %u %u) RQP %x LID %x SL %u MTU %u %u %u %u %u SDE %p,%u SC %p,%u SCQ %u %u PID %d OS %x %x E %x %x %x RNR %d %s %d\n",
 		   iter->n,
 		   qp_idle(qp) ? "I" : "B",
 		   qp->ibqp.qp_num,
@@ -573,7 +573,6 @@ void qp_iter_print(struct seq_file *s, struct rvt_qp_iter *iter)
 		   qp_type_str[qp->ibqp.qp_type],
 		   qp->state,
 		   wqe ? wqe->wr.opcode : 0,
-		   qp->s_hdrwords,
 		   qp->s_flags,
 		   iowait_sdma_pending(&priv->s_iowait),
 		   iowait_pio_pending(&priv->s_iowait),
@@ -795,7 +794,6 @@ void notify_error_qp(struct rvt_qp *qp)
 	}
 
 	if (!(qp->s_flags & RVT_S_BUSY)) {
-		qp->s_hdrwords = 0;
 		if (qp->s_rdma_mr) {
 			rvt_put_mr(qp->s_rdma_mr);
 			qp->s_rdma_mr = NULL;
diff --git a/drivers/infiniband/hw/hfi1/qp.h b/drivers/infiniband/hw/hfi1/qp.h
index c06d2f8..b2d4cba 100644
--- a/drivers/infiniband/hw/hfi1/qp.h
+++ b/drivers/infiniband/hw/hfi1/qp.h
@@ -51,12 +51,25 @@
 #include <rdma/rdmavt_qp.h>
 #include "verbs.h"
 #include "sdma.h"
+#include "verbs_txreq.h"
 
 extern unsigned int hfi1_qp_table_size;
 
 extern const struct rvt_operation_params hfi1_post_parms[];
 
 /*
+ * Send if not busy or waiting for I/O and either
+ * a RC response is pending or we can process send work requests.
+ */
+static inline int hfi1_send_ok(struct rvt_qp *qp)
+{
+	return !(qp->s_flags & (RVT_S_BUSY | RVT_S_ANY_WAIT_IO)) &&
+		(verbs_txreq_queued(qp) ||
+		(qp->s_flags & RVT_S_RESP_PENDING) ||
+		 !(qp->s_flags & RVT_S_ANY_WAIT_SEND));
+}
+
+/*
  * free_ahg - clear ahg from QP
  */
 static inline void clear_ahg(struct rvt_qp *qp)
diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c
index 14cc212..da58046 100644
--- a/drivers/infiniband/hw/hfi1/rc.c
+++ b/drivers/infiniband/hw/hfi1/rc.c
@@ -226,12 +226,10 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp,
 		bth2 = mask_psn(qp->s_ack_psn);
 	}
 	qp->s_rdma_ack_cnt++;
-	qp->s_hdrwords = hwords;
 	ps->s_txreq->sde = priv->s_sde;
 	ps->s_txreq->s_cur_size = len;
+	ps->s_txreq->hdr_dwords = hwords;
 	hfi1_make_ruc_header(qp, ohdr, bth0, bth2, middle, ps);
-	/* pbc */
-	ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
 	return 1;
 
 bail:
@@ -385,7 +383,6 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
 						       : IB_WC_SUCCESS);
 				if (local_ops)
 					atomic_dec(&qp->local_ops_pending);
-				qp->s_hdrwords = 0;
 				goto done_free_tx;
 			}
 
@@ -688,7 +685,7 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
 		bth2 |= IB_BTH_REQ_ACK;
 	}
 	qp->s_len -= len;
-	qp->s_hdrwords = hwords;
+	ps->s_txreq->hdr_dwords = hwords;
 	ps->s_txreq->sde = priv->s_sde;
 	ps->s_txreq->ss = ss;
 	ps->s_txreq->s_cur_size = len;
@@ -699,8 +696,6 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
 		bth2,
 		middle,
 		ps);
-	/* pbc */
-	ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
 	return 1;
 
 done_free_tx:
@@ -714,7 +709,6 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
 bail_no_tx:
 	ps->s_txreq = NULL;
 	qp->s_flags &= ~RVT_S_BUSY;
-	qp->s_hdrwords = 0;
 	return 0;
 }
 
@@ -734,14 +728,16 @@ static inline void hfi1_make_bth_aeth(struct rvt_qp *qp,
 	ohdr->bth[2] = cpu_to_be32(mask_psn(qp->r_ack_psn));
 }
 
-static inline void hfi1_queue_rc_ack(struct rvt_qp *qp, bool is_fecn)
+static inline void hfi1_queue_rc_ack(struct hfi1_packet *packet, bool is_fecn)
 {
-	struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+	struct rvt_qp *qp = packet->qp;
+	struct hfi1_ibport *ibp;
 	unsigned long flags;
 
 	spin_lock_irqsave(&qp->s_lock, flags);
 	if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK))
 		goto unlock;
+	ibp = rcd_to_iport(packet->rcd);
 	this_cpu_inc(*ibp->rvp.rc_qacks);
 	qp->s_flags |= RVT_S_ACK_PENDING | RVT_S_RESP_PENDING;
 	qp->s_nak_state = qp->r_nak_state;
@@ -755,13 +751,14 @@ static inline void hfi1_queue_rc_ack(struct rvt_qp *qp, bool is_fecn)
 	spin_unlock_irqrestore(&qp->s_lock, flags);
 }
 
-static inline void hfi1_make_rc_ack_9B(struct rvt_qp *qp,
+static inline void hfi1_make_rc_ack_9B(struct hfi1_packet *packet,
 				       struct hfi1_opa_header *opa_hdr,
 				       u8 sc5, bool is_fecn,
 				       u64 *pbc_flags, u32 *hwords,
 				       u32 *nwords)
 {
-	struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+	struct rvt_qp *qp = packet->qp;
+	struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd);
 	struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
 	struct ib_header *hdr = &opa_hdr->ibh;
 	struct ib_other_headers *ohdr;
@@ -802,19 +799,20 @@ static inline void hfi1_make_rc_ack_9B(struct rvt_qp *qp,
 	hfi1_make_bth_aeth(qp, ohdr, bth0, bth1);
 }
 
-static inline void hfi1_make_rc_ack_16B(struct rvt_qp *qp,
+static inline void hfi1_make_rc_ack_16B(struct hfi1_packet *packet,
 					struct hfi1_opa_header *opa_hdr,
 					u8 sc5, bool is_fecn,
 					u64 *pbc_flags, u32 *hwords,
 					u32 *nwords)
 {
-	struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+	struct rvt_qp *qp = packet->qp;
+	struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd);
 	struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
 	struct hfi1_16b_header *hdr = &opa_hdr->opah;
 	struct ib_other_headers *ohdr;
 	u32 bth0, bth1 = 0;
 	u16 len, pkey;
-	u8 becn = !!is_fecn;
+	bool becn = is_fecn;
 	u8 l4 = OPA_16B_L4_IB_LOCAL;
 	u8 extra_bytes;
 
@@ -854,7 +852,7 @@ static inline void hfi1_make_rc_ack_16B(struct rvt_qp *qp,
 	hfi1_make_bth_aeth(qp, ohdr, bth0, bth1);
 }
 
-typedef void (*hfi1_make_rc_ack)(struct rvt_qp *qp,
+typedef void (*hfi1_make_rc_ack)(struct hfi1_packet *packet,
 				 struct hfi1_opa_header *opa_hdr,
 				 u8 sc5, bool is_fecn,
 				 u64 *pbc_flags, u32 *hwords,
@@ -874,9 +872,10 @@ static const hfi1_make_rc_ack hfi1_make_rc_ack_tbl[2] = {
  * Note that RDMA reads and atomics are handled in the
  * send side QP state and send engine.
  */
-void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,
-		      struct rvt_qp *qp, bool is_fecn)
+void hfi1_send_rc_ack(struct hfi1_packet *packet, bool is_fecn)
 {
+	struct hfi1_ctxtdata *rcd = packet->rcd;
+	struct rvt_qp *qp = packet->qp;
 	struct hfi1_ibport *ibp = rcd_to_iport(rcd);
 	struct hfi1_qp_priv *priv = qp->priv;
 	struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
@@ -893,13 +892,13 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,
 
 	/* Don't send ACK or NAK if a RDMA read or atomic is pending. */
 	if (qp->s_flags & RVT_S_RESP_PENDING) {
-		hfi1_queue_rc_ack(qp, is_fecn);
+		hfi1_queue_rc_ack(packet, is_fecn);
 		return;
 	}
 
 	/* Ensure s_rdma_ack_cnt changes are committed */
 	if (qp->s_rdma_ack_cnt) {
-		hfi1_queue_rc_ack(qp, is_fecn);
+		hfi1_queue_rc_ack(packet, is_fecn);
 		return;
 	}
 
@@ -908,7 +907,7 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,
 		return;
 
 	/* Make the appropriate header */
-	hfi1_make_rc_ack_tbl[priv->hdr_type](qp, &opa_hdr, sc5, is_fecn,
+	hfi1_make_rc_ack_tbl[priv->hdr_type](packet, &opa_hdr, sc5, is_fecn,
 					     &pbc_flags, &hwords, &nwords);
 
 	plen = 2 /* PBC */ + hwords + nwords;
@@ -922,7 +921,7 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,
 		 * so that when enough buffer space becomes available,
 		 * the ACK is sent ahead of other outgoing packets.
 		 */
-		hfi1_queue_rc_ack(qp, is_fecn);
+		hfi1_queue_rc_ack(packet, is_fecn);
 		return;
 	}
 	trace_ack_output_ibhdr(dd_from_ibdev(qp->ibqp.device),
@@ -1540,7 +1539,7 @@ static void rc_rcv_resp(struct hfi1_packet *packet)
 	void *data = packet->payload;
 	u32 tlen = packet->tlen;
 	struct rvt_qp *qp = packet->qp;
-	struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+	struct hfi1_ibport *ibp;
 	struct ib_other_headers *ohdr = packet->ohdr;
 	struct rvt_swqe *wqe;
 	enum ib_wc_status status;
@@ -1697,6 +1696,7 @@ static void rc_rcv_resp(struct hfi1_packet *packet)
 	goto ack_err;
 
 ack_seq_err:
+	ibp = rcd_to_iport(rcd);
 	rdma_seq_err(qp, ibp, psn, rcd);
 	goto ack_done;
 
@@ -2037,7 +2037,6 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
 	struct rvt_qp *qp = packet->qp;
 	struct hfi1_ibport *ibp = rcd_to_iport(rcd);
 	struct ib_other_headers *ohdr = packet->ohdr;
-	u32 bth0 = be32_to_cpu(ohdr->bth[0]);
 	u32 opcode = packet->opcode;
 	u32 hdrsize = packet->hlen;
 	u32 psn = ib_bth_get_psn(packet->ohdr);
@@ -2235,7 +2234,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
 		wc.port_num = 0;
 		/* Signal completion event if the solicited bit is set. */
 		rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
-			     (bth0 & IB_BTH_SOLICITED) != 0);
+			     ib_bth_is_solicited(ohdr));
 		break;
 
 	case OP(RDMA_WRITE_ONLY):
@@ -2479,7 +2478,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
 	qp->r_nak_state = IB_NAK_REMOTE_ACCESS_ERROR;
 	qp->r_ack_psn = qp->r_psn;
 send_ack:
-	hfi1_send_rc_ack(rcd, qp, is_fecn);
+	hfi1_send_rc_ack(packet, is_fecn);
 }
 
 void hfi1_rc_hdrerr(
diff --git a/drivers/infiniband/hw/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c
index 13b9947..3daa94b 100644
--- a/drivers/infiniband/hw/hfi1/ruc.c
+++ b/drivers/infiniband/hw/hfi1/ruc.c
@@ -225,19 +225,8 @@ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_packet *packet)
 	u32 dlid = packet->dlid;
 	u32 slid = packet->slid;
 	u32 sl = packet->sl;
-	int migrated;
-	u32 bth0, bth1;
-	u16 pkey;
-
-	bth0 = be32_to_cpu(packet->ohdr->bth[0]);
-	bth1 = be32_to_cpu(packet->ohdr->bth[1]);
-	if (packet->etype == RHF_RCV_TYPE_BYPASS) {
-		pkey = hfi1_16B_get_pkey(packet->hdr);
-		migrated = bth1 & OPA_BTH_MIG_REQ;
-	} else {
-		pkey = ib_bth_get_pkey(packet->ohdr);
-		migrated = bth0 & IB_BTH_MIG_REQ;
-	}
+	bool migrated = packet->migrated;
+	u16 pkey = packet->pkey;
 
 	if (qp->s_mig_state == IB_MIG_ARMED && migrated) {
 		if (!packet->grh) {
@@ -756,19 +745,18 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,
 	u32 slid;
 	u16 pkey = hfi1_get_pkey(ibp, qp->s_pkey_index);
 	u8 l4 = OPA_16B_L4_IB_LOCAL;
-	u8 extra_bytes = hfi1_get_16b_padding((qp->s_hdrwords << 2),
-				   ps->s_txreq->s_cur_size);
+	u8 extra_bytes = hfi1_get_16b_padding(
+				(ps->s_txreq->hdr_dwords << 2),
+				ps->s_txreq->s_cur_size);
 	u32 nwords = SIZE_OF_CRC + ((ps->s_txreq->s_cur_size +
 				 extra_bytes + SIZE_OF_LT) >> 2);
-	u8 becn = 0;
+	bool becn = false;
 
 	if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH) &&
 	    hfi1_check_mcast(rdma_ah_get_dlid(&qp->remote_ah_attr))) {
 		struct ib_grh *grh;
 		struct ib_global_route *grd =
 			rdma_ah_retrieve_grh(&qp->remote_ah_attr);
-		int hdrwords;
-
 		/*
 		 * Ensure OPA GIDs are transformed to IB gids
 		 * before creating the GRH.
@@ -777,9 +765,10 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,
 			grd->sgid_index = 0;
 		grh = &ps->s_txreq->phdr.hdr.opah.u.l.grh;
 		l4 = OPA_16B_L4_IB_GLOBAL;
-		hdrwords = qp->s_hdrwords - 4;
-		qp->s_hdrwords += hfi1_make_grh(ibp, grh, grd,
-						hdrwords, nwords);
+		ps->s_txreq->hdr_dwords +=
+			hfi1_make_grh(ibp, grh, grd,
+				      ps->s_txreq->hdr_dwords - LRH_16B_DWORDS,
+				      nwords);
 		middle = 0;
 	}
 
@@ -798,7 +787,7 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,
 	if (qp->s_flags & RVT_S_ECN) {
 		qp->s_flags &= ~RVT_S_ECN;
 		/* we recently received a FECN, so return a BECN */
-		becn = 1;
+		becn = true;
 	}
 	hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2);
 
@@ -813,7 +802,7 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,
 			  slid,
 			  opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr),
 				      16B),
-			  (qp->s_hdrwords + nwords) >> 1,
+			  (ps->s_txreq->hdr_dwords + nwords) >> 1,
 			  pkey, becn, 0, l4, priv->s_sc);
 }
 
@@ -833,13 +822,13 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp,
 
 	if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)) {
 		struct ib_grh *grh = &ps->s_txreq->phdr.hdr.ibh.u.l.grh;
-		int hdrwords = qp->s_hdrwords - 2;
 
 		lrh0 = HFI1_LRH_GRH;
-		qp->s_hdrwords +=
+		ps->s_txreq->hdr_dwords +=
 			hfi1_make_grh(ibp, grh,
 				      rdma_ah_read_grh(&qp->remote_ah_attr),
-				      hdrwords, nwords);
+				      ps->s_txreq->hdr_dwords - LRH_9B_DWORDS,
+				      nwords);
 		middle = 0;
 	}
 	lrh0 |= (priv->s_sc & 0xf) << 12 |
@@ -865,7 +854,7 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp,
 	hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2);
 	hfi1_make_ib_hdr(&ps->s_txreq->phdr.hdr.ibh,
 			 lrh0,
-			 qp->s_hdrwords + nwords,
+			 ps->s_txreq->hdr_dwords + nwords,
 			 opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr), 9B),
 			 ppd_from_ibp(ibp)->lid |
 				rdma_ah_get_path_bits(&qp->remote_ah_attr));
@@ -1030,7 +1019,7 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread)
 	ps.s_txreq = get_waiting_verbs_txreq(qp);
 	do {
 		/* Check for a constructed packet to be sent. */
-		if (qp->s_hdrwords != 0) {
+		if (ps.s_txreq) {
 			spin_unlock_irqrestore(&qp->s_lock, ps.flags);
 			/*
 			 * If the packet cannot be sent now, return and
@@ -1038,8 +1027,6 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread)
 			 */
 			if (hfi1_verbs_send(qp, &ps))
 				return;
-			/* Record that s_ahg is empty. */
-			qp->s_hdrwords = 0;
 			/* allow other tasks to run */
 			if (schedule_send_yield(qp, &ps))
 				return;
diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c
index 61c130d..1f20330 100644
--- a/drivers/infiniband/hw/hfi1/sdma.c
+++ b/drivers/infiniband/hw/hfi1/sdma.c
@@ -1275,13 +1275,15 @@ int sdma_map_init(struct hfi1_devdata *dd, u8 port, u8 num_vls, u8 *vl_engines)
 	return -ENOMEM;
 }
 
-/*
- * Clean up allocated memory.
+/**
+ * sdma_clean()  Clean up allocated memory
+ * @dd:          struct hfi1_devdata
+ * @num_engines: num sdma engines
  *
- * This routine is can be called regardless of the success of sdma_init()
- *
+ * This routine can be called regardless of the success of
+ * sdma_init()
  */
-static void sdma_clean(struct hfi1_devdata *dd, size_t num_engines)
+void sdma_clean(struct hfi1_devdata *dd, size_t num_engines)
 {
 	size_t i;
 	struct sdma_engine *sde;
@@ -1386,7 +1388,8 @@ int sdma_init(struct hfi1_devdata *dd, u8 port)
 		    num_engines, descq_cnt);
 
 	/* alloc memory for array of send engines */
-	dd->per_sdma = kcalloc(num_engines, sizeof(*dd->per_sdma), GFP_KERNEL);
+	dd->per_sdma = kcalloc_node(num_engines, sizeof(*dd->per_sdma),
+				    GFP_KERNEL, dd->node);
 	if (!dd->per_sdma)
 		return ret;
 
@@ -1617,7 +1620,6 @@ void sdma_exit(struct hfi1_devdata *dd)
 		 */
 		sdma_finalput(&sde->state);
 	}
-	sdma_clean(dd, dd->num_sdma);
 }
 
 /*
diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h
index 374c597..46c775f 100644
--- a/drivers/infiniband/hw/hfi1/sdma.h
+++ b/drivers/infiniband/hw/hfi1/sdma.h
@@ -420,6 +420,7 @@ struct sdma_engine {
 int sdma_init(struct hfi1_devdata *dd, u8 port);
 void sdma_start(struct hfi1_devdata *dd);
 void sdma_exit(struct hfi1_devdata *dd);
+void sdma_clean(struct hfi1_devdata *dd, size_t num_engines);
 void sdma_all_running(struct hfi1_devdata *dd);
 void sdma_all_idle(struct hfi1_devdata *dd);
 void sdma_freeze_notify(struct hfi1_devdata *dd, int go_idle);
diff --git a/drivers/infiniband/hw/hfi1/trace.c b/drivers/infiniband/hw/hfi1/trace.c
index 959a804..89bd985 100644
--- a/drivers/infiniband/hw/hfi1/trace.c
+++ b/drivers/infiniband/hw/hfi1/trace.c
@@ -138,7 +138,7 @@ static const char *parse_syndrome(u8 syndrome)
 }
 
 void hfi1_trace_parse_9b_bth(struct ib_other_headers *ohdr,
-			     u8 *ack, u8 *becn, u8 *fecn, u8 *mig,
+			     u8 *ack, bool *becn, bool *fecn, u8 *mig,
 			     u8 *se, u8 *pad, u8 *opcode, u8 *tver,
 			     u16 *pkey, u32 *psn, u32 *qpn)
 {
@@ -184,7 +184,7 @@ void hfi1_trace_parse_9b_hdr(struct ib_header *hdr, bool sc5,
 }
 
 void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr,
-			      u8 *age, u8 *becn, u8 *fecn,
+			      u8 *age, bool *becn, bool *fecn,
 			      u8 *l4, u8 *rc, u8 *sc,
 			      u16 *entropy, u16 *len, u16 *pkey,
 			      u32 *dlid, u32 *slid)
@@ -207,7 +207,7 @@ void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr,
 #define LRH_16B_PRN "age:%d becn:%d fecn:%d l4:%d " \
 		    "rc:%d sc:%d pkey:0x%.4x entropy:0x%.4x"
 const char *hfi1_trace_fmt_lrh(struct trace_seq *p, bool bypass,
-			       u8 age, u8 becn, u8 fecn, u8 l4,
+			       u8 age, bool becn, bool fecn, u8 l4,
 			       u8 lnh, const char *lnh_name, u8 lver,
 			       u8 rc, u8 sc, u8 sl, u16 entropy,
 			       u16 len, u16 pkey, u32 dlid, u32 slid)
@@ -235,7 +235,7 @@ const char *hfi1_trace_fmt_lrh(struct trace_seq *p, bool bypass,
 	"op:0x%.2x,%s se:%d m:%d pad:%d tver:%d " \
 	"qpn:0x%.6x a:%d psn:0x%.8x"
 const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass,
-			       u8 ack, u8 becn, u8 fecn, u8 mig,
+			       u8 ack, bool becn, bool fecn, u8 mig,
 			       u8 se, u8 pad, u8 opcode, const char *opname,
 			       u8 tver, u16 pkey, u32 psn, u32 qpn)
 {
diff --git a/drivers/infiniband/hw/hfi1/trace_ibhdrs.h b/drivers/infiniband/hw/hfi1/trace_ibhdrs.h
index fb63127..2847626 100644
--- a/drivers/infiniband/hw/hfi1/trace_ibhdrs.h
+++ b/drivers/infiniband/hw/hfi1/trace_ibhdrs.h
@@ -101,7 +101,7 @@ u8 hfi1_trace_opa_hdr_len(struct hfi1_opa_header *opah);
 u8 hfi1_trace_packet_hdr_len(struct hfi1_packet *packet);
 const char *hfi1_trace_get_packet_l4_str(u8 l4);
 void hfi1_trace_parse_9b_bth(struct ib_other_headers *ohdr,
-			     u8 *ack, u8 *becn, u8 *fecn, u8 *mig,
+			     u8 *ack, bool *becn, bool *fecn, u8 *mig,
 			     u8 *se, u8 *pad, u8 *opcode, u8 *tver,
 			     u16 *pkey, u32 *psn, u32 *qpn);
 void hfi1_trace_parse_9b_hdr(struct ib_header *hdr, bool sc5,
@@ -112,19 +112,19 @@ void hfi1_trace_parse_16b_bth(struct ib_other_headers *ohdr,
 			      u8 *pad, u8 *se, u8 *tver,
 			      u32 *psn, u32 *qpn);
 void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr,
-			      u8 *age, u8 *becn, u8 *fecn,
+			      u8 *age, bool *becn, bool *fecn,
 			      u8 *l4, u8 *rc, u8 *sc,
 			      u16 *entropy, u16 *len, u16 *pkey,
 			      u32 *dlid, u32 *slid);
 
 const char *hfi1_trace_fmt_lrh(struct trace_seq *p, bool bypass,
-			       u8 age, u8 becn, u8 fecn, u8 l4,
+			       u8 age, bool becn, bool fecn, u8 l4,
 			       u8 lnh, const char *lnh_name, u8 lver,
 			       u8 rc, u8 sc, u8 sl, u16 entropy,
 			       u16 len, u16 pkey, u32 dlid, u32 slid);
 
 const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass,
-			       u8 ack, u8 becn, u8 fecn, u8 mig,
+			       u8 ack, bool becn, bool fecn, u8 mig,
 			       u8 se, u8 pad, u8 opcode, const char *opname,
 			       u8 tver, u16 pkey, u32 psn, u32 qpn);
 
@@ -148,8 +148,8 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template,
 			__field(u8, etype)
 			__field(u8, ack)
 			__field(u8, age)
-			__field(u8, becn)
-			__field(u8, fecn)
+			__field(bool, becn)
+			__field(bool, fecn)
 			__field(u8, l2)
 			__field(u8, l4)
 			__field(u8, lnh)
@@ -290,8 +290,8 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template,
 			__field(u8, hdr_type)
 			__field(u8, ack)
 			__field(u8, age)
-			__field(u8, becn)
-			__field(u8, fecn)
+			__field(bool, becn)
+			__field(bool, fecn)
 			__field(u8, l4)
 			__field(u8, lnh)
 			__field(u8, lver)
diff --git a/drivers/infiniband/hw/hfi1/trace_rx.h b/drivers/infiniband/hw/hfi1/trace_rx.h
index 4d487fe..7eceb57 100644
--- a/drivers/infiniband/hw/hfi1/trace_rx.h
+++ b/drivers/infiniband/hw/hfi1/trace_rx.h
@@ -63,17 +63,9 @@ __print_symbolic(type,                       \
 #define TRACE_SYSTEM hfi1_rx
 
 TRACE_EVENT(hfi1_rcvhdr,
-	    TP_PROTO(struct hfi1_devdata *dd,
-		     u32 ctxt,
-		     u64 eflags,
-		     u32 etype,
-		     u32 hlen,
-		     u32 tlen,
-		     u32 updegr,
-		     u32 etail
-		    ),
-	    TP_ARGS(dd, ctxt, eflags, etype, hlen, tlen, updegr, etail),
-	    TP_STRUCT__entry(DD_DEV_ENTRY(dd)
+	    TP_PROTO(struct hfi1_packet *packet),
+	    TP_ARGS(packet),
+	    TP_STRUCT__entry(DD_DEV_ENTRY(packet->rcd->dd)
 			     __field(u64, eflags)
 			     __field(u32, ctxt)
 			     __field(u32, etype)
@@ -82,14 +74,14 @@ TRACE_EVENT(hfi1_rcvhdr,
 			     __field(u32, updegr)
 			     __field(u32, etail)
 			     ),
-	     TP_fast_assign(DD_DEV_ASSIGN(dd);
-			    __entry->eflags = eflags;
-			    __entry->ctxt = ctxt;
-			    __entry->etype = etype;
-			    __entry->hlen = hlen;
-			    __entry->tlen = tlen;
-			    __entry->updegr = updegr;
-			    __entry->etail = etail;
+	     TP_fast_assign(DD_DEV_ASSIGN(packet->rcd->dd);
+			    __entry->eflags = rhf_err_flags(packet->rhf);
+			    __entry->ctxt = packet->rcd->ctxt;
+			    __entry->etype = packet->etype;
+			    __entry->hlen = packet->hlen;
+			    __entry->tlen = packet->tlen;
+			    __entry->updegr = packet->updegr;
+			    __entry->etail = rhf_egr_index(packet->rhf);
 			    ),
 	     TP_printk(
 		"[%s] ctxt %d eflags 0x%llx etype %d,%s hlen %d tlen %d updegr %d etail %d",
diff --git a/drivers/infiniband/hw/hfi1/uc.c b/drivers/infiniband/hw/hfi1/uc.c
index 132b63e..9d7a311 100644
--- a/drivers/infiniband/hw/hfi1/uc.c
+++ b/drivers/infiniband/hw/hfi1/uc.c
@@ -144,7 +144,6 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
 							: IB_WC_SUCCESS);
 			if (local_ops)
 				atomic_dec(&qp->local_ops_pending);
-			qp->s_hdrwords = 0;
 			goto done_free_tx;
 		}
 		/*
@@ -267,14 +266,12 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
 		break;
 	}
 	qp->s_len -= len;
-	qp->s_hdrwords = hwords;
+	ps->s_txreq->hdr_dwords = hwords;
 	ps->s_txreq->sde = priv->s_sde;
 	ps->s_txreq->ss = &qp->s_sge;
 	ps->s_txreq->s_cur_size = len;
 	hfi1_make_ruc_header(qp, ohdr, bth0 | (qp->s_state << 24),
 			     mask_psn(qp->s_psn++), middle, ps);
-	/* pbc */
-	ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
 	return 1;
 
 done_free_tx:
@@ -288,7 +285,6 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
 bail_no_tx:
 	ps->s_txreq = NULL;
 	qp->s_flags &= ~RVT_S_BUSY;
-	qp->s_hdrwords = 0;
 	return 0;
 }
 
@@ -480,8 +476,7 @@ void hfi1_uc_rcv(struct hfi1_packet *packet)
 		wc.port_num = 0;
 		/* Signal completion event if the solicited bit is set. */
 		rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
-			     (ohdr->bth[0] &
-			      cpu_to_be32(IB_BTH_SOLICITED)) != 0);
+			     ib_bth_is_solicited(ohdr));
 		break;
 
 	case OP(RDMA_WRITE_FIRST):
diff --git a/drivers/infiniband/hw/hfi1/ud.c b/drivers/infiniband/hw/hfi1/ud.c
index deb1845..bcf3b0b 100644
--- a/drivers/infiniband/hw/hfi1/ud.c
+++ b/drivers/infiniband/hw/hfi1/ud.c
@@ -340,15 +340,16 @@ void hfi1_make_ud_req_9B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
 	extra_bytes = -wqe->length & 3;
 	nwords = ((wqe->length + extra_bytes) >> 2) + SIZE_OF_CRC;
 	/* header size in dwords LRH+BTH+DETH = (8+12+8)/4. */
-	qp->s_hdrwords = 7;
+	ps->s_txreq->hdr_dwords = 7;
 	if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM)
-		qp->s_hdrwords++;
+		ps->s_txreq->hdr_dwords++;
 
 	if (rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) {
 		grh = &ps->s_txreq->phdr.hdr.ibh.u.l.grh;
-		qp->s_hdrwords += hfi1_make_grh(ibp, grh,
-						rdma_ah_read_grh(ah_attr),
-						qp->s_hdrwords - 2, nwords);
+		ps->s_txreq->hdr_dwords +=
+			hfi1_make_grh(ibp, grh, rdma_ah_read_grh(ah_attr),
+				      ps->s_txreq->hdr_dwords - LRH_9B_DWORDS,
+				      nwords);
 		lrh0 = HFI1_LRH_GRH;
 		ohdr = &ps->s_txreq->phdr.hdr.ibh.u.l.oth;
 	} else {
@@ -381,7 +382,7 @@ void hfi1_make_ud_req_9B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
 		}
 	}
 	hfi1_make_bth_deth(qp, wqe, ohdr, &pkey, extra_bytes, false);
-	len = qp->s_hdrwords + nwords;
+	len = ps->s_txreq->hdr_dwords + nwords;
 
 	/* Setup the packet */
 	ps->s_txreq->phdr.hdr.hdr_type = HFI1_PKT_TYPE_9B;
@@ -405,12 +406,12 @@ void hfi1_make_ud_req_16B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
 	ppd = ppd_from_ibp(ibp);
 	ah_attr = &ibah_to_rvtah(wqe->ud_wr.ah)->attr;
 	/* header size in dwords 16B LRH+BTH+DETH = (16+12+8)/4. */
-	qp->s_hdrwords = 9;
+	ps->s_txreq->hdr_dwords = 9;
 	if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM)
-		qp->s_hdrwords++;
+		ps->s_txreq->hdr_dwords++;
 
 	/* SW provides space for CRC and LT for bypass packets. */
-	extra_bytes = hfi1_get_16b_padding((qp->s_hdrwords << 2),
+	extra_bytes = hfi1_get_16b_padding((ps->s_txreq->hdr_dwords << 2),
 					   wqe->length);
 	nwords = ((wqe->length + extra_bytes + SIZE_OF_LT) >> 2) + SIZE_OF_CRC;
 
@@ -428,8 +429,10 @@ void hfi1_make_ud_req_16B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
 			grd->sgid_index = 0;
 		}
 		grh = &ps->s_txreq->phdr.hdr.opah.u.l.grh;
-		qp->s_hdrwords += hfi1_make_grh(ibp, grh, grd,
-					qp->s_hdrwords - 4, nwords);
+		ps->s_txreq->hdr_dwords += hfi1_make_grh(
+			ibp, grh, grd,
+			ps->s_txreq->hdr_dwords - LRH_16B_DWORDS,
+			nwords);
 		ohdr = &ps->s_txreq->phdr.hdr.opah.u.l.oth;
 		l4 = OPA_16B_L4_IB_GLOBAL;
 	} else {
@@ -452,7 +455,7 @@ void hfi1_make_ud_req_16B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
 
 	hfi1_make_bth_deth(qp, wqe, ohdr, &pkey, extra_bytes, true);
 	/* Convert dwords to flits */
-	len = (qp->s_hdrwords + nwords) >> 1;
+	len = (ps->s_txreq->hdr_dwords + nwords) >> 1;
 
 	/* Setup the packet */
 	ps->s_txreq->phdr.hdr.hdr_type = HFI1_PKT_TYPE_16B;
@@ -562,8 +565,6 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
 	priv->s_ahg->ahgcount = 0;
 	priv->s_ahg->ahgidx = 0;
 	priv->s_ahg->tx_flags = 0;
-	/* pbc */
-	ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
 
 	return 1;
 
@@ -578,7 +579,6 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
 bail_no_tx:
 	ps->s_txreq = NULL;
 	qp->s_flags &= ~RVT_S_BUSY;
-	qp->s_hdrwords = 0;
 	return 0;
 }
 
@@ -649,7 +649,8 @@ void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp,
 		struct ib_grh *grh = &hdr.u.l.grh;
 
 		grh->version_tclass_flow = old_grh->version_tclass_flow;
-		grh->paylen = cpu_to_be16((hwords - 4 + nwords) << 2);
+		grh->paylen = cpu_to_be16(
+			(hwords - LRH_16B_DWORDS + nwords) << 2);
 		grh->hop_limit = 0xff;
 		grh->sgid = old_grh->dgid;
 		grh->dgid = old_grh->sgid;
@@ -703,7 +704,8 @@ void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn,
 		struct ib_grh *grh = &hdr.u.l.grh;
 
 		grh->version_tclass_flow = old_grh->version_tclass_flow;
-		grh->paylen = cpu_to_be16((hwords - 2 + SIZE_OF_CRC) << 2);
+		grh->paylen = cpu_to_be16(
+			(hwords - LRH_9B_DWORDS + SIZE_OF_CRC) << 2);
 		grh->hop_limit = 0xff;
 		grh->sgid = old_grh->dgid;
 		grh->dgid = old_grh->sgid;
@@ -1046,8 +1048,7 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
 	wc.port_num = qp->port_num;
 	/* Signal completion event if the solicited bit is set. */
 	rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
-		     (ohdr->bth[0] &
-		      cpu_to_be32(IB_BTH_SOLICITED)) != 0);
+		     ib_bth_is_solicited(ohdr));
 	return;
 
 drop:
diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c
index b8776a3..471d55c 100644
--- a/drivers/infiniband/hw/hfi1/verbs.c
+++ b/drivers/infiniband/hw/hfi1/verbs.c
@@ -835,7 +835,7 @@ static int build_verbs_tx_desc(
 {
 	int ret = 0;
 	struct hfi1_sdma_header *phdr = &tx->phdr;
-	u16 hdrbytes = tx->hdr_dwords << 2;
+	u16 hdrbytes = (tx->hdr_dwords + sizeof(pbc) / 4) << 2;
 	u8 extra_bytes = 0;
 
 	if (tx->phdr.hdr.hdr_type) {
@@ -901,7 +901,7 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
 {
 	struct hfi1_qp_priv *priv = qp->priv;
 	struct hfi1_ahg_info *ahg_info = priv->s_ahg;
-	u32 hdrwords = qp->s_hdrwords;
+	u32 hdrwords = ps->s_txreq->hdr_dwords;
 	u32 len = ps->s_txreq->s_cur_size;
 	u32 plen;
 	struct hfi1_ibdev *dev = ps->dev;
@@ -919,7 +919,7 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
 	} else {
 		dwords = (len + 3) >> 2;
 	}
-	plen = hdrwords + dwords + 2;
+	plen = hdrwords + dwords + sizeof(pbc) / 4;
 
 	tx = ps->s_txreq;
 	if (!sdma_txreq_built(&tx->txreq)) {
@@ -1038,7 +1038,7 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
 			u64 pbc)
 {
 	struct hfi1_qp_priv *priv = qp->priv;
-	u32 hdrwords = qp->s_hdrwords;
+	u32 hdrwords = ps->s_txreq->hdr_dwords;
 	struct rvt_sge_state *ss = ps->s_txreq->ss;
 	u32 len = ps->s_txreq->s_cur_size;
 	u32 dwords;
@@ -1064,7 +1064,7 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
 		dwords = (len + 3) >> 2;
 		hdr = (u32 *)&ps->s_txreq->phdr.hdr.ibh;
 	}
-	plen = hdrwords + dwords + 2;
+	plen = hdrwords + dwords + sizeof(pbc) / 4;
 
 	/* only RC/UC use complete */
 	switch (qp->ibqp.qp_type) {
diff --git a/drivers/infiniband/hw/hfi1/verbs.h b/drivers/infiniband/hw/hfi1/verbs.h
index 87d1285..2d787b8 100644
--- a/drivers/infiniband/hw/hfi1/verbs.h
+++ b/drivers/infiniband/hw/hfi1/verbs.h
@@ -105,6 +105,11 @@ enum {
 	HFI1_HAS_GRH = (1 << 0),
 };
 
+#define LRH_16B_BYTES (FIELD_SIZEOF(struct hfi1_16b_header, lrh))
+#define LRH_16B_DWORDS (LRH_16B_BYTES / sizeof(u32))
+#define LRH_9B_BYTES (FIELD_SIZEOF(struct ib_header, lrh))
+#define LRH_9B_DWORDS (LRH_9B_BYTES / sizeof(u32))
+
 struct hfi1_16b_header {
 	u32 lrh[4];
 	union {
@@ -246,17 +251,6 @@ static inline struct rvt_qp *iowait_to_qp(struct  iowait *s_iowait)
 }
 
 /*
- * Send if not busy or waiting for I/O and either
- * a RC response is pending or we can process send work requests.
- */
-static inline int hfi1_send_ok(struct rvt_qp *qp)
-{
-	return !(qp->s_flags & (RVT_S_BUSY | RVT_S_ANY_WAIT_IO)) &&
-		(qp->s_hdrwords || (qp->s_flags & RVT_S_RESP_PENDING) ||
-		 !(qp->s_flags & RVT_S_ANY_WAIT_SEND));
-}
-
-/*
  * This must be called with s_lock held.
  */
 void hfi1_bad_pkey(struct hfi1_ibport *ibp, u32 key, u32 sl,
@@ -369,8 +363,7 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread);
 void hfi1_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
 			enum ib_wc_status status);
 
-void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, struct rvt_qp *qp,
-		      bool is_fecn);
+void hfi1_send_rc_ack(struct hfi1_packet *packet, bool is_fecn);
 
 int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps);
 
@@ -416,6 +409,11 @@ static inline void cacheless_memcpy(void *dst, void *src, size_t n)
 	__copy_user_nocache(dst, (void __user *)src, n, 0);
 }
 
+static inline bool opa_bth_is_migration(struct ib_other_headers *ohdr)
+{
+	return ohdr->bth[1] & cpu_to_be32(OPA_BTH_MIG_REQ);
+}
+
 extern const enum ib_wc_opcode ib_hfi1_wc_opcode[];
 
 extern const u8 hdr_len_by_opcode[];
diff --git a/drivers/infiniband/hw/hfi1/verbs_txreq.h b/drivers/infiniband/hw/hfi1/verbs_txreq.h
index cec7a4b..729244c 100644
--- a/drivers/infiniband/hw/hfi1/verbs_txreq.h
+++ b/drivers/infiniband/hw/hfi1/verbs_txreq.h
@@ -113,6 +113,13 @@ static inline struct verbs_txreq *get_waiting_verbs_txreq(struct rvt_qp *qp)
 	return NULL;
 }
 
+static inline bool verbs_txreq_queued(struct rvt_qp *qp)
+{
+	struct hfi1_qp_priv *priv = qp->priv;
+
+	return iowait_packet_queued(&priv->s_iowait);
+}
+
 void hfi1_put_txreq(struct verbs_txreq *tx);
 int verbs_txreq_init(struct hfi1_ibdev *dev);
 void verbs_txreq_exit(struct hfi1_ibdev *dev);
diff --git a/drivers/infiniband/hw/hns/hns_roce_common.h b/drivers/infiniband/hw/hns/hns_roce_common.h
index dd67faf..319cb74 100644
--- a/drivers/infiniband/hw/hns/hns_roce_common.h
+++ b/drivers/infiniband/hw/hns/hns_roce_common.h
@@ -43,15 +43,15 @@
 	__raw_writel((__force u32)cpu_to_le32(value), (addr))
 
 #define roce_get_field(origin, mask, shift) \
-	(((origin) & (mask)) >> (shift))
+	(((le32_to_cpu(origin)) & (mask)) >> (shift))
 
 #define roce_get_bit(origin, shift) \
 	roce_get_field((origin), (1ul << (shift)), (shift))
 
 #define roce_set_field(origin, mask, shift, val) \
 	do { \
-		(origin) &= (~(mask)); \
-		(origin) |= (((u32)(val) << (shift)) & (mask)); \
+		(origin) &= ~cpu_to_le32(mask); \
+		(origin) |= cpu_to_le32(((u32)(val) << (shift)) & (mask)); \
 	} while (0)
 
 #define roce_set_bit(origin, shift, val) \
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
index 42c3b5a..165a09b3 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -345,8 +345,8 @@ struct hns_roce_cq {
 	struct hns_roce_cq_buf		hr_buf;
 	spinlock_t			lock;
 	struct ib_umem			*umem;
-	void (*comp)(struct hns_roce_cq *);
-	void (*event)(struct hns_roce_cq *, enum hns_roce_event);
+	void (*comp)(struct hns_roce_cq *cq);
+	void (*event)(struct hns_roce_cq *cq, enum hns_roce_event event_type);
 
 	struct hns_roce_uar		*uar;
 	u32				cq_depth;
@@ -466,7 +466,7 @@ struct hns_roce_qp {
 	struct ib_qp		ibqp;
 	struct hns_roce_buf	hr_buf;
 	struct hns_roce_wq	rq;
-	__le64			doorbell_qpn;
+	u32			doorbell_qpn;
 	__le32			sq_signal_bits;
 	u32			sq_next_wqe;
 	int			sq_max_wqes_per_wr;
@@ -486,8 +486,8 @@ struct hns_roce_qp {
 	u32                     atomic_rd_en;
 	u32			pkey_index;
 	u32			qkey;
-	void			(*event)(struct hns_roce_qp *,
-					 enum hns_roce_event);
+	void			(*event)(struct hns_roce_qp *qp,
+					 enum hns_roce_event event_type);
 	unsigned long		qpn;
 
 	atomic_t		refcount;
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 21ca9fa..da13bd7 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -195,23 +195,47 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 
 			memcpy(&ud_sq_wqe->dgid[0], &ah->av.dgid[0], GID_LEN);
 
-			ud_sq_wqe->va0_l = (u32)wr->sg_list[0].addr;
-			ud_sq_wqe->va0_h = (wr->sg_list[0].addr) >> 32;
-			ud_sq_wqe->l_key0 = wr->sg_list[0].lkey;
+			ud_sq_wqe->va0_l =
+				       cpu_to_le32((u32)wr->sg_list[0].addr);
+			ud_sq_wqe->va0_h =
+				       cpu_to_le32((wr->sg_list[0].addr) >> 32);
+			ud_sq_wqe->l_key0 =
+				       cpu_to_le32(wr->sg_list[0].lkey);
 
-			ud_sq_wqe->va1_l = (u32)wr->sg_list[1].addr;
-			ud_sq_wqe->va1_h = (wr->sg_list[1].addr) >> 32;
-			ud_sq_wqe->l_key1 = wr->sg_list[1].lkey;
+			ud_sq_wqe->va1_l =
+				       cpu_to_le32((u32)wr->sg_list[1].addr);
+			ud_sq_wqe->va1_h =
+				       cpu_to_le32((wr->sg_list[1].addr) >> 32);
+			ud_sq_wqe->l_key1 =
+				       cpu_to_le32(wr->sg_list[1].lkey);
 			ind++;
 		} else if (ibqp->qp_type == IB_QPT_RC) {
+			u32 tmp_len = 0;
+
 			ctrl = wqe;
 			memset(ctrl, 0, sizeof(struct hns_roce_wqe_ctrl_seg));
 			for (i = 0; i < wr->num_sge; i++)
-				ctrl->msg_length += wr->sg_list[i].length;
+				tmp_len += wr->sg_list[i].length;
+
+			ctrl->msg_length =
+			  cpu_to_le32(le32_to_cpu(ctrl->msg_length) + tmp_len);
 
 			ctrl->sgl_pa_h = 0;
 			ctrl->flag = 0;
-			ctrl->imm_data = send_ieth(wr);
+
+			switch (wr->opcode) {
+			case IB_WR_SEND_WITH_IMM:
+			case IB_WR_RDMA_WRITE_WITH_IMM:
+				ctrl->imm_data = wr->ex.imm_data;
+				break;
+			case IB_WR_SEND_WITH_INV:
+				ctrl->inv_key =
+					cpu_to_le32(wr->ex.invalidate_rkey);
+				break;
+			default:
+				ctrl->imm_data = 0;
+				break;
+			}
 
 			/*Ctrl field, ctrl set type: sig, solic, imm, fence */
 			/* SO wait for conforming application scenarios */
@@ -258,8 +282,8 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 
 			dseg = wqe;
 			if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) {
-				if (ctrl->msg_length >
-					hr_dev->caps.max_sq_inline) {
+				if (le32_to_cpu(ctrl->msg_length) >
+				    hr_dev->caps.max_sq_inline) {
 					ret = -EINVAL;
 					*bad_wr = wr;
 					dev_err(dev, "inline len(1-%d)=%d, illegal",
@@ -273,7 +297,7 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 					       wr->sg_list[i].length);
 					wqe += wr->sg_list[i].length;
 				}
-				ctrl->flag |= HNS_ROCE_WQE_INLINE;
+				ctrl->flag |= cpu_to_le32(HNS_ROCE_WQE_INLINE);
 			} else {
 				/*sqe num is two */
 				for (i = 0; i < wr->num_sge; i++)
@@ -306,8 +330,8 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 			       SQ_DOORBELL_U32_8_QPN_S, qp->doorbell_qpn);
 		roce_set_bit(sq_db.u32_8, SQ_DOORBELL_HW_SYNC_S, 1);
 
-		doorbell[0] = sq_db.u32_4;
-		doorbell[1] = sq_db.u32_8;
+		doorbell[0] = le32_to_cpu(sq_db.u32_4);
+		doorbell[1] = le32_to_cpu(sq_db.u32_8);
 
 		hns_roce_write64_k(doorbell, qp->sq.db_reg_l);
 		qp->sq_next_wqe = ind;
@@ -403,8 +427,8 @@ static int hns_roce_v1_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
 			roce_set_bit(rq_db.u32_8, RQ_DOORBELL_U32_8_HW_SYNC_S,
 				     1);
 
-			doorbell[0] = rq_db.u32_4;
-			doorbell[1] = rq_db.u32_8;
+			doorbell[0] = le32_to_cpu(rq_db.u32_4);
+			doorbell[1] = le32_to_cpu(rq_db.u32_8);
 
 			hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l);
 		}
@@ -2261,7 +2285,7 @@ static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq,
 						CQE_BYTE_4_WQE_INDEX_M,
 						CQE_BYTE_4_WQE_INDEX_S)&
 						((*cur_qp)->sq.wqe_cnt-1));
-		switch (sq_wqe->flag & HNS_ROCE_WQE_OPCODE_MASK) {
+		switch (le32_to_cpu(sq_wqe->flag) & HNS_ROCE_WQE_OPCODE_MASK) {
 		case HNS_ROCE_WQE_OPCODE_SEND:
 			wc->opcode = IB_WC_SEND;
 			break;
@@ -2282,7 +2306,7 @@ static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq,
 			wc->status = IB_WC_GENERAL_ERR;
 			break;
 		}
-		wc->wc_flags = (sq_wqe->flag & HNS_ROCE_WQE_IMM ?
+		wc->wc_flags = (le32_to_cpu(sq_wqe->flag) & HNS_ROCE_WQE_IMM ?
 				IB_WC_WITH_IMM : 0);
 
 		wq = &(*cur_qp)->sq;
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
index b44ddd2..e9a2717 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
@@ -200,14 +200,14 @@
 #define HNS_ROCE_AEQE_EVENT_CE_EVENT_CEQE_CEQN_M GENMASK(4, 0)
 
 struct hns_roce_cq_context {
-	u32 cqc_byte_4;
-	u32 cq_bt_l;
-	u32 cqc_byte_12;
-	u32 cur_cqe_ba0_l;
-	u32 cqc_byte_20;
-	u32 cqe_tptr_addr_l;
-	u32 cur_cqe_ba1_l;
-	u32 cqc_byte_32;
+	__le32 cqc_byte_4;
+	__le32 cq_bt_l;
+	__le32 cqc_byte_12;
+	__le32 cur_cqe_ba0_l;
+	__le32 cqc_byte_20;
+	__le32 cqe_tptr_addr_l;
+	__le32 cur_cqe_ba1_l;
+	__le32 cqc_byte_32;
 };
 
 #define CQ_CONTEXT_CQC_BYTE_4_CQC_STATE_S 0
@@ -257,17 +257,17 @@ struct hns_roce_cq_context {
 	(((1UL << 16) - 1) << CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_S)
 
 struct hns_roce_cqe {
-	u32 cqe_byte_4;
+	__le32 cqe_byte_4;
 	union {
-		u32 r_key;
-		u32 immediate_data;
+		__le32 r_key;
+		__be32 immediate_data;
 	};
-	u32 byte_cnt;
-	u32 cqe_byte_16;
-	u32 cqe_byte_20;
-	u32 s_mac_l;
-	u32 cqe_byte_28;
-	u32 reserved;
+	__le32 byte_cnt;
+	__le32 cqe_byte_16;
+	__le32 cqe_byte_20;
+	__le32 s_mac_l;
+	__le32 cqe_byte_28;
+	__le32 reserved;
 };
 
 #define CQE_BYTE_4_OWNER_S 7
@@ -308,22 +308,22 @@ struct hns_roce_cqe {
 #define CQ_DB_REQ_NOT		(1 << 16)
 
 struct hns_roce_v1_mpt_entry {
-	u32  mpt_byte_4;
-	u32  pbl_addr_l;
-	u32  mpt_byte_12;
-	u32  virt_addr_l;
-	u32  virt_addr_h;
-	u32  length;
-	u32  mpt_byte_28;
-	u32  pa0_l;
-	u32  mpt_byte_36;
-	u32  mpt_byte_40;
-	u32  mpt_byte_44;
-	u32  mpt_byte_48;
-	u32  pa4_l;
-	u32  mpt_byte_56;
-	u32  mpt_byte_60;
-	u32  mpt_byte_64;
+	__le32  mpt_byte_4;
+	__le32  pbl_addr_l;
+	__le32  mpt_byte_12;
+	__le32  virt_addr_l;
+	__le32  virt_addr_h;
+	__le32  length;
+	__le32  mpt_byte_28;
+	__le32  pa0_l;
+	__le32  mpt_byte_36;
+	__le32  mpt_byte_40;
+	__le32  mpt_byte_44;
+	__le32  mpt_byte_48;
+	__le32  pa4_l;
+	__le32  mpt_byte_56;
+	__le32  mpt_byte_60;
+	__le32  mpt_byte_64;
 };
 
 #define MPT_BYTE_4_KEY_STATE_S 0
@@ -408,30 +408,32 @@ struct hns_roce_v1_mpt_entry {
 	(((1UL << 8) - 1) << MPT_BYTE_64_L_KEY_IDX_H_S)
 
 struct hns_roce_wqe_ctrl_seg {
-	__be32 sgl_pa_h;
-	__be32 flag;
-	__be32 imm_data;
-	__be32 msg_length;
+	__le32 sgl_pa_h;
+	__le32 flag;
+	union {
+		__be32 imm_data;
+		__le32 inv_key;
+	};
+	__le32 msg_length;
 };
 
 struct hns_roce_wqe_data_seg {
-	__be64    addr;
-	__be32    lkey;
-	__be32    len;
+	__le64    addr;
+	__le32    lkey;
+	__le32    len;
 };
 
 struct hns_roce_wqe_raddr_seg {
-	__be32 rkey;
-	__be32 len;/* reserved */
-	__be64 raddr;
+	__le32 rkey;
+	__le32 len;/* reserved */
+	__le64 raddr;
 };
 
 struct hns_roce_rq_wqe_ctrl {
-
-	u32 rwqe_byte_4;
-	u32 rocee_sgl_ba_l;
-	u32 rwqe_byte_12;
-	u32 reserved[5];
+	__le32 rwqe_byte_4;
+	__le32 rocee_sgl_ba_l;
+	__le32 rwqe_byte_12;
+	__le32 reserved[5];
 };
 
 #define RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_S 16
@@ -443,31 +445,31 @@ struct hns_roce_rq_wqe_ctrl {
 #define GID_LEN					16
 
 struct hns_roce_ud_send_wqe {
-	u32 dmac_h;
-	u32 u32_8;
-	u32 immediate_data;
+	__le32 dmac_h;
+	__le32 u32_8;
+	__le32 immediate_data;
 
-	u32 u32_16;
+	__le32 u32_16;
 	union {
 		unsigned char dgid[GID_LEN];
 		struct {
-			u32 u32_20;
-			u32 u32_24;
-			u32 u32_28;
-			u32 u32_32;
+			__le32 u32_20;
+			__le32 u32_24;
+			__le32 u32_28;
+			__le32 u32_32;
 		};
 	};
 
-	u32 u32_36;
-	u32 u32_40;
+	__le32 u32_36;
+	__le32 u32_40;
 
-	u32 va0_l;
-	u32 va0_h;
-	u32 l_key0;
+	__le32 va0_l;
+	__le32 va0_h;
+	__le32 l_key0;
 
-	u32 va1_l;
-	u32 va1_h;
-	u32 l_key1;
+	__le32 va1_l;
+	__le32 va1_h;
+	__le32 l_key1;
 };
 
 #define UD_SEND_WQE_U32_4_DMAC_0_S 0
@@ -535,16 +537,16 @@ struct hns_roce_ud_send_wqe {
 	(((1UL << 8) - 1) << UD_SEND_WQE_U32_40_TRAFFIC_CLASS_S)
 
 struct hns_roce_sqp_context {
-	u32 qp1c_bytes_4;
-	u32 sq_rq_bt_l;
-	u32 qp1c_bytes_12;
-	u32 qp1c_bytes_16;
-	u32 qp1c_bytes_20;
-	u32 cur_rq_wqe_ba_l;
-	u32 qp1c_bytes_28;
-	u32 qp1c_bytes_32;
-	u32 cur_sq_wqe_ba_l;
-	u32 qp1c_bytes_40;
+	__le32 qp1c_bytes_4;
+	__le32 sq_rq_bt_l;
+	__le32 qp1c_bytes_12;
+	__le32 qp1c_bytes_16;
+	__le32 qp1c_bytes_20;
+	__le32 cur_rq_wqe_ba_l;
+	__le32 qp1c_bytes_28;
+	__le32 qp1c_bytes_32;
+	__le32 cur_sq_wqe_ba_l;
+	__le32 qp1c_bytes_40;
 };
 
 #define QP1C_BYTES_4_QP_STATE_S 0
@@ -626,64 +628,64 @@ struct hns_roce_sqp_context {
 #define HNS_ROCE_WQE_OPCODE_MASK	(15<<16)
 
 struct hns_roce_qp_context {
-	u32 qpc_bytes_4;
-	u32 qpc_bytes_8;
-	u32 qpc_bytes_12;
-	u32 qpc_bytes_16;
-	u32 sq_rq_bt_l;
-	u32 qpc_bytes_24;
-	u32 irrl_ba_l;
-	u32 qpc_bytes_32;
-	u32 qpc_bytes_36;
-	u32 dmac_l;
-	u32 qpc_bytes_44;
-	u32 qpc_bytes_48;
-	u8 dgid[16];
-	u32 qpc_bytes_68;
-	u32 cur_rq_wqe_ba_l;
-	u32 qpc_bytes_76;
-	u32 rx_rnr_time;
-	u32 qpc_bytes_84;
-	u32 qpc_bytes_88;
+	__le32 qpc_bytes_4;
+	__le32 qpc_bytes_8;
+	__le32 qpc_bytes_12;
+	__le32 qpc_bytes_16;
+	__le32 sq_rq_bt_l;
+	__le32 qpc_bytes_24;
+	__le32 irrl_ba_l;
+	__le32 qpc_bytes_32;
+	__le32 qpc_bytes_36;
+	__le32 dmac_l;
+	__le32 qpc_bytes_44;
+	__le32 qpc_bytes_48;
+	u8     dgid[16];
+	__le32 qpc_bytes_68;
+	__le32 cur_rq_wqe_ba_l;
+	__le32 qpc_bytes_76;
+	__le32 rx_rnr_time;
+	__le32 qpc_bytes_84;
+	__le32 qpc_bytes_88;
 	union {
-		u32 rx_sge_len;
-		u32 dma_length;
+		__le32 rx_sge_len;
+		__le32 dma_length;
 	};
 	union {
-		u32 rx_sge_num;
-		u32 rx_send_pktn;
-		u32 r_key;
+		__le32 rx_sge_num;
+		__le32 rx_send_pktn;
+		__le32 r_key;
 	};
-	u32 va_l;
-	u32 va_h;
-	u32 qpc_bytes_108;
-	u32 qpc_bytes_112;
-	u32 rx_cur_sq_wqe_ba_l;
-	u32 qpc_bytes_120;
-	u32 qpc_bytes_124;
-	u32 qpc_bytes_128;
-	u32 qpc_bytes_132;
-	u32 qpc_bytes_136;
-	u32 qpc_bytes_140;
-	u32 qpc_bytes_144;
-	u32 qpc_bytes_148;
+	__le32 va_l;
+	__le32 va_h;
+	__le32 qpc_bytes_108;
+	__le32 qpc_bytes_112;
+	__le32 rx_cur_sq_wqe_ba_l;
+	__le32 qpc_bytes_120;
+	__le32 qpc_bytes_124;
+	__le32 qpc_bytes_128;
+	__le32 qpc_bytes_132;
+	__le32 qpc_bytes_136;
+	__le32 qpc_bytes_140;
+	__le32 qpc_bytes_144;
+	__le32 qpc_bytes_148;
 	union {
-		u32 rnr_retry;
-		u32 ack_time;
+		__le32 rnr_retry;
+		__le32 ack_time;
 	};
-	u32 qpc_bytes_156;
-	u32 pkt_use_len;
-	u32 qpc_bytes_164;
-	u32 qpc_bytes_168;
+	__le32 qpc_bytes_156;
+	__le32 pkt_use_len;
+	__le32 qpc_bytes_164;
+	__le32 qpc_bytes_168;
 	union {
-		u32 sge_use_len;
-		u32 pa_use_len;
+		__le32 sge_use_len;
+		__le32 pa_use_len;
 	};
-	u32 qpc_bytes_176;
-	u32 qpc_bytes_180;
-	u32 tx_cur_sq_wqe_ba_l;
-	u32 qpc_bytes_188;
-	u32 rvd21;
+	__le32 qpc_bytes_176;
+	__le32 qpc_bytes_180;
+	__le32 tx_cur_sq_wqe_ba_l;
+	__le32 qpc_bytes_188;
+	__le32 rvd21;
 };
 
 #define QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_S 0
@@ -996,8 +998,8 @@ struct hns_roce_qp_context {
 #define HCR_GO_BIT		15
 
 struct hns_roce_rq_db {
-	u32    u32_4;
-	u32    u32_8;
+	__le32    u32_4;
+	__le32    u32_8;
 };
 
 #define RQ_DOORBELL_U32_4_RQ_HEAD_S 0
@@ -1013,8 +1015,8 @@ struct hns_roce_rq_db {
 #define RQ_DOORBELL_U32_8_HW_SYNC_S 31
 
 struct hns_roce_sq_db {
-	u32    u32_4;
-	u32    u32_8;
+	__le32    u32_4;
+	__le32    u32_8;
 };
 
 #define SQ_DOORBELL_U32_4_SQ_HEAD_S 0
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
index 256fe11..db2ff35 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -63,7 +63,8 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, struct ib_send_wr *wr,
 	int i;
 
 	if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) {
-		if (rc_sq_wqe->msg_len > hr_dev->caps.max_sq_inline) {
+		if (le32_to_cpu(rc_sq_wqe->msg_len) >
+		    hr_dev->caps.max_sq_inline) {
 			*bad_wr = wr;
 			dev_err(hr_dev->dev, "inline len(1-%d)=%d, illegal",
 				rc_sq_wqe->msg_len, hr_dev->caps.max_sq_inline);
@@ -136,6 +137,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 	unsigned long flags;
 	unsigned int ind;
 	void *wqe = NULL;
+	u32 tmp_len = 0;
 	bool loopback;
 	int ret = 0;
 	u8 *smac;
@@ -218,9 +220,20 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 				       HNS_ROCE_V2_WQE_OP_SEND);
 
 			for (i = 0; i < wr->num_sge; i++)
-				ud_sq_wqe->msg_len += wr->sg_list[i].length;
+				tmp_len += wr->sg_list[i].length;
 
-			ud_sq_wqe->immtdata = send_ieth(wr);
+			ud_sq_wqe->msg_len =
+			 cpu_to_le32(le32_to_cpu(ud_sq_wqe->msg_len) + tmp_len);
+
+			switch (wr->opcode) {
+			case IB_WR_SEND_WITH_IMM:
+			case IB_WR_RDMA_WRITE_WITH_IMM:
+				ud_sq_wqe->immtdata = wr->ex.imm_data;
+				break;
+			default:
+				ud_sq_wqe->immtdata = 0;
+				break;
+			}
 
 			/* Set sig attr */
 			roce_set_bit(ud_sq_wqe->byte_4,
@@ -254,8 +267,8 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 				       V2_UD_SEND_WQE_BYTE_24_UDPSPN_M,
 				       V2_UD_SEND_WQE_BYTE_24_UDPSPN_S, 0);
 			ud_sq_wqe->qkey =
-			     cpu_to_be32(ud_wr(wr)->remote_qkey & 0x80000000) ?
-			     qp->qkey : ud_wr(wr)->remote_qkey;
+			     cpu_to_le32(ud_wr(wr)->remote_qkey & 0x80000000 ?
+			     qp->qkey : ud_wr(wr)->remote_qkey);
 			roce_set_field(ud_sq_wqe->byte_32,
 				       V2_UD_SEND_WQE_BYTE_32_DQPN_M,
 				       V2_UD_SEND_WQE_BYTE_32_DQPN_S,
@@ -264,7 +277,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 			roce_set_field(ud_sq_wqe->byte_36,
 				       V2_UD_SEND_WQE_BYTE_36_VLAN_M,
 				       V2_UD_SEND_WQE_BYTE_36_VLAN_S,
-				       ah->av.vlan);
+				       le16_to_cpu(ah->av.vlan));
 			roce_set_field(ud_sq_wqe->byte_36,
 				       V2_UD_SEND_WQE_BYTE_36_HOPLIMIT_M,
 				       V2_UD_SEND_WQE_BYTE_36_HOPLIMIT_S,
@@ -283,8 +296,8 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 			roce_set_field(ud_sq_wqe->byte_40,
 				       V2_UD_SEND_WQE_BYTE_40_SL_M,
 				       V2_UD_SEND_WQE_BYTE_40_SL_S,
-				       ah->av.sl_tclass_flowlabel >>
-				       HNS_ROCE_SL_SHIFT);
+				      le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
+				      HNS_ROCE_SL_SHIFT);
 			roce_set_field(ud_sq_wqe->byte_40,
 				       V2_UD_SEND_WQE_BYTE_40_PORTN_M,
 				       V2_UD_SEND_WQE_BYTE_40_PORTN_S,
@@ -311,9 +324,24 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 			rc_sq_wqe = wqe;
 			memset(rc_sq_wqe, 0, sizeof(*rc_sq_wqe));
 			for (i = 0; i < wr->num_sge; i++)
-				rc_sq_wqe->msg_len += wr->sg_list[i].length;
+				tmp_len += wr->sg_list[i].length;
 
-			rc_sq_wqe->inv_key_immtdata = send_ieth(wr);
+			rc_sq_wqe->msg_len =
+			 cpu_to_le32(le32_to_cpu(rc_sq_wqe->msg_len) + tmp_len);
+
+			switch (wr->opcode) {
+			case IB_WR_SEND_WITH_IMM:
+			case IB_WR_RDMA_WRITE_WITH_IMM:
+				rc_sq_wqe->immtdata = wr->ex.imm_data;
+				break;
+			case IB_WR_SEND_WITH_INV:
+				rc_sq_wqe->inv_key =
+					cpu_to_le32(wr->ex.invalidate_rkey);
+				break;
+			default:
+				rc_sq_wqe->immtdata = 0;
+				break;
+			}
 
 			roce_set_bit(rc_sq_wqe->byte_4,
 				     V2_RC_SEND_WQE_BYTE_4_FENCE_S,
@@ -451,7 +479,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
 		roce_set_field(sq_db.parameter, V2_DB_PARAMETER_SL_M,
 			       V2_DB_PARAMETER_SL_S, qp->sl);
 
-		hns_roce_write64_k((__be32 *)&sq_db, qp->sq.db_reg_l);
+		hns_roce_write64_k((__le32 *)&sq_db, qp->sq.db_reg_l);
 
 		qp->sq_next_wqe = ind;
 		qp->next_sge = sge_ind;
@@ -513,7 +541,7 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
 		}
 
 		if (i < hr_qp->rq.max_gs) {
-			dseg[i].lkey = cpu_to_be32(HNS_ROCE_INVALID_LKEY);
+			dseg[i].lkey = cpu_to_le32(HNS_ROCE_INVALID_LKEY);
 			dseg[i].addr = 0;
 		}
 
@@ -546,7 +574,7 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
 		roce_set_field(rq_db.parameter, V2_DB_PARAMETER_CONS_IDX_M,
 			       V2_DB_PARAMETER_CONS_IDX_S, hr_qp->rq.head);
 
-		hns_roce_write64_k((__be32 *)&rq_db, hr_qp->rq.db_reg_l);
+		hns_roce_write64_k((__le32 *)&rq_db, hr_qp->rq.db_reg_l);
 	}
 	spin_unlock_irqrestore(&hr_qp->rq.lock, flags);
 
@@ -2123,10 +2151,10 @@ static void set_access_flags(struct hns_roce_qp *hr_qp,
 	u8 dest_rd_atomic;
 	u32 access_flags;
 
-	dest_rd_atomic = !!(attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) ?
+	dest_rd_atomic = (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) ?
 			 attr->max_dest_rd_atomic : hr_qp->resp_depth;
 
-	access_flags = !!(attr_mask & IB_QP_ACCESS_FLAGS) ?
+	access_flags = (attr_mask & IB_QP_ACCESS_FLAGS) ?
 		       attr->qp_access_flags : hr_qp->atomic_rd_en;
 
 	if (!dest_rd_atomic)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
index 960df09..2bf8a47 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
@@ -224,22 +224,22 @@ enum hns_roce_sgid_type {
 };
 
 struct hns_roce_v2_cq_context {
-	u32	byte_4_pg_ceqn;
-	u32	byte_8_cqn;
-	u32	cqe_cur_blk_addr;
-	u32	byte_16_hop_addr;
-	u32	cqe_nxt_blk_addr;
-	u32	byte_24_pgsz_addr;
-	u32	byte_28_cq_pi;
-	u32	byte_32_cq_ci;
-	u32	cqe_ba;
-	u32	byte_40_cqe_ba;
-	u32	byte_44_db_record;
-	u32	db_record_addr;
-	u32	byte_52_cqe_cnt;
-	u32	byte_56_cqe_period_maxcnt;
-	u32	cqe_report_timer;
-	u32	byte_64_se_cqe_idx;
+	__le32	byte_4_pg_ceqn;
+	__le32	byte_8_cqn;
+	__le32	cqe_cur_blk_addr;
+	__le32	byte_16_hop_addr;
+	__le32	cqe_nxt_blk_addr;
+	__le32	byte_24_pgsz_addr;
+	__le32	byte_28_cq_pi;
+	__le32	byte_32_cq_ci;
+	__le32	cqe_ba;
+	__le32	byte_40_cqe_ba;
+	__le32	byte_44_db_record;
+	__le32	db_record_addr;
+	__le32	byte_52_cqe_cnt;
+	__le32	byte_56_cqe_period_maxcnt;
+	__le32	cqe_report_timer;
+	__le32	byte_64_se_cqe_idx;
 };
 #define HNS_ROCE_V2_CQ_DEFAULT_BURST_NUM 0x0
 #define HNS_ROCE_V2_CQ_DEFAULT_INTERVAL	0x0
@@ -328,66 +328,66 @@ enum hns_roce_v2_qp_state {
 };
 
 struct hns_roce_v2_qp_context {
-	u32	byte_4_sqpn_tst;
-	u32	wqe_sge_ba;
-	u32	byte_12_sq_hop;
-	u32	byte_16_buf_ba_pg_sz;
-	u32	byte_20_smac_sgid_idx;
-	u32	byte_24_mtu_tc;
-	u32	byte_28_at_fl;
+	__le32	byte_4_sqpn_tst;
+	__le32	wqe_sge_ba;
+	__le32	byte_12_sq_hop;
+	__le32	byte_16_buf_ba_pg_sz;
+	__le32	byte_20_smac_sgid_idx;
+	__le32	byte_24_mtu_tc;
+	__le32	byte_28_at_fl;
 	u8	dgid[GID_LEN_V2];
-	u32	dmac;
-	u32	byte_52_udpspn_dmac;
-	u32	byte_56_dqpn_err;
-	u32	byte_60_qpst_mapid;
-	u32	qkey_xrcd;
-	u32	byte_68_rq_db;
-	u32	rq_db_record_addr;
-	u32	byte_76_srqn_op_en;
-	u32	byte_80_rnr_rx_cqn;
-	u32	byte_84_rq_ci_pi;
-	u32	rq_cur_blk_addr;
-	u32	byte_92_srq_info;
-	u32	byte_96_rx_reqmsn;
-	u32	rq_nxt_blk_addr;
-	u32	byte_104_rq_sge;
-	u32	byte_108_rx_reqepsn;
-	u32	rq_rnr_timer;
-	u32	rx_msg_len;
-	u32	rx_rkey_pkt_info;
-	u64	rx_va;
-	u32	byte_132_trrl;
-	u32	trrl_ba;
-	u32	byte_140_raq;
-	u32	byte_144_raq;
-	u32	byte_148_raq;
-	u32	byte_152_raq;
-	u32	byte_156_raq;
-	u32	byte_160_sq_ci_pi;
-	u32	sq_cur_blk_addr;
-	u32	byte_168_irrl_idx;
-	u32	byte_172_sq_psn;
-	u32	byte_176_msg_pktn;
-	u32	sq_cur_sge_blk_addr;
-	u32	byte_184_irrl_idx;
-	u32	cur_sge_offset;
-	u32	byte_192_ext_sge;
-	u32	byte_196_sq_psn;
-	u32	byte_200_sq_max;
-	u32	irrl_ba;
-	u32	byte_208_irrl;
-	u32	byte_212_lsn;
-	u32	sq_timer;
-	u32	byte_220_retry_psn_msn;
-	u32	byte_224_retry_msg;
-	u32	rx_sq_cur_blk_addr;
-	u32	byte_232_irrl_sge;
-	u32	irrl_cur_sge_offset;
-	u32	byte_240_irrl_tail;
-	u32	byte_244_rnr_rxack;
-	u32	byte_248_ack_psn;
-	u32	byte_252_err_txcqn;
-	u32	byte_256_sqflush_rqcqe;
+	__le32	dmac;
+	__le32	byte_52_udpspn_dmac;
+	__le32	byte_56_dqpn_err;
+	__le32	byte_60_qpst_mapid;
+	__le32	qkey_xrcd;
+	__le32	byte_68_rq_db;
+	__le32	rq_db_record_addr;
+	__le32	byte_76_srqn_op_en;
+	__le32	byte_80_rnr_rx_cqn;
+	__le32	byte_84_rq_ci_pi;
+	__le32	rq_cur_blk_addr;
+	__le32	byte_92_srq_info;
+	__le32	byte_96_rx_reqmsn;
+	__le32	rq_nxt_blk_addr;
+	__le32	byte_104_rq_sge;
+	__le32	byte_108_rx_reqepsn;
+	__le32	rq_rnr_timer;
+	__le32	rx_msg_len;
+	__le32	rx_rkey_pkt_info;
+	__le64	rx_va;
+	__le32	byte_132_trrl;
+	__le32	trrl_ba;
+	__le32	byte_140_raq;
+	__le32	byte_144_raq;
+	__le32	byte_148_raq;
+	__le32	byte_152_raq;
+	__le32	byte_156_raq;
+	__le32	byte_160_sq_ci_pi;
+	__le32	sq_cur_blk_addr;
+	__le32	byte_168_irrl_idx;
+	__le32	byte_172_sq_psn;
+	__le32	byte_176_msg_pktn;
+	__le32	sq_cur_sge_blk_addr;
+	__le32	byte_184_irrl_idx;
+	__le32	cur_sge_offset;
+	__le32	byte_192_ext_sge;
+	__le32	byte_196_sq_psn;
+	__le32	byte_200_sq_max;
+	__le32	irrl_ba;
+	__le32	byte_208_irrl;
+	__le32	byte_212_lsn;
+	__le32	sq_timer;
+	__le32	byte_220_retry_psn_msn;
+	__le32	byte_224_retry_msg;
+	__le32	rx_sq_cur_blk_addr;
+	__le32	byte_232_irrl_sge;
+	__le32	irrl_cur_sge_offset;
+	__le32	byte_240_irrl_tail;
+	__le32	byte_244_rnr_rxack;
+	__le32	byte_248_ack_psn;
+	__le32	byte_252_err_txcqn;
+	__le32	byte_256_sqflush_rqcqe;
 };
 
 #define	V2_QPC_BYTE_4_TST_S 0
@@ -761,17 +761,17 @@ struct hns_roce_v2_qp_context {
 #define V2_QPC_BYTE_256_SQ_FLUSH_IDX_M GENMASK(31, 16)
 
 struct hns_roce_v2_cqe {
-	u32	byte_4;
+	__le32	byte_4;
 	union {
 		__le32 rkey;
 		__be32 immtdata;
 	};
-	u32	byte_12;
-	u32	byte_16;
-	u32	byte_cnt;
+	__le32	byte_12;
+	__le32	byte_16;
+	__le32	byte_cnt;
 	u8	smac[4];
-	u32	byte_28;
-	u32	byte_32;
+	__le32	byte_28;
+	__le32	byte_32;
 };
 
 #define	V2_CQE_BYTE_4_OPCODE_S 0
@@ -901,8 +901,8 @@ struct hns_roce_v2_mpt_entry {
 #define V2_DB_PARAMETER_SL_M GENMASK(18, 16)
 
 struct hns_roce_v2_cq_db {
-	u32	byte_4;
-	u32	parameter;
+	__le32	byte_4;
+	__le32	parameter;
 };
 
 #define	V2_CQ_DB_BYTE_4_TAG_S 0
@@ -920,18 +920,18 @@ struct hns_roce_v2_cq_db {
 #define V2_CQ_DB_PARAMETER_NOTIFY_S 24
 
 struct hns_roce_v2_ud_send_wqe {
-	u32	byte_4;
-	u32	msg_len;
-	u32	immtdata;
-	u32	byte_16;
-	u32	byte_20;
-	u32	byte_24;
-	u32	qkey;
-	u32	byte_32;
-	u32	byte_36;
-	u32	byte_40;
-	u32	dmac;
-	u32	byte_48;
+	__le32	byte_4;
+	__le32	msg_len;
+	__be32	immtdata;
+	__le32	byte_16;
+	__le32	byte_20;
+	__le32	byte_24;
+	__le32	qkey;
+	__le32	byte_32;
+	__le32	byte_36;
+	__le32	byte_40;
+	__le32	dmac;
+	__le32	byte_48;
 	u8	dgid[GID_LEN_V2];
 
 };
@@ -1004,13 +1004,16 @@ struct hns_roce_v2_ud_send_wqe {
 #define V2_UD_SEND_WQE_BYTE_48_SMAC_INDX_M GENMASK(31, 24)
 
 struct hns_roce_v2_rc_send_wqe {
-	u32		byte_4;
-	u32		msg_len;
-	u32		inv_key_immtdata;
-	u32		byte_16;
-	u32		byte_20;
-	u32		rkey;
-	u64		va;
+	__le32		byte_4;
+	__le32		msg_len;
+	union {
+		__le32  inv_key;
+		__be32  immtdata;
+	};
+	__le32		byte_16;
+	__le32		byte_20;
+	__le32		rkey;
+	__le64		va;
 };
 
 #define	V2_RC_SEND_WQE_BYTE_4_OPCODE_S 0
@@ -1038,14 +1041,14 @@ struct hns_roce_v2_rc_send_wqe {
 #define V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M GENMASK(23, 0)
 
 struct hns_roce_v2_wqe_data_seg {
-	__be32    len;
-	__be32    lkey;
-	__be64    addr;
+	__le32    len;
+	__le32    lkey;
+	__le64    addr;
 };
 
 struct hns_roce_v2_db {
-	u32	byte_4;
-	u32	parameter;
+	__le32	byte_4;
+	__le32	parameter;
 };
 
 struct hns_roce_query_version {
@@ -1105,12 +1108,12 @@ struct hns_roce_pf_res {
 #define PF_RES_DATA_5_PF_EQC_BT_NUM_M GENMASK(25, 16)
 
 struct hns_roce_vf_res_a {
-	u32 vf_id;
-	u32 vf_qpc_bt_idx_num;
-	u32 vf_srqc_bt_idx_num;
-	u32 vf_cqc_bt_idx_num;
-	u32 vf_mpt_bt_idx_num;
-	u32 vf_eqc_bt_idx_num;
+	__le32 vf_id;
+	__le32 vf_qpc_bt_idx_num;
+	__le32 vf_srqc_bt_idx_num;
+	__le32 vf_cqc_bt_idx_num;
+	__le32 vf_mpt_bt_idx_num;
+	__le32 vf_eqc_bt_idx_num;
 };
 
 #define VF_RES_A_DATA_1_VF_QPC_BT_IDX_S 0
@@ -1144,11 +1147,11 @@ struct hns_roce_vf_res_a {
 #define VF_RES_A_DATA_5_VF_EQC_NUM_M GENMASK(25, 16)
 
 struct hns_roce_vf_res_b {
-	u32 rsv0;
-	u32 vf_smac_idx_num;
-	u32 vf_sgid_idx_num;
-	u32 vf_qid_idx_sl_num;
-	u32 rsv[2];
+	__le32 rsv0;
+	__le32 vf_smac_idx_num;
+	__le32 vf_sgid_idx_num;
+	__le32 vf_qid_idx_sl_num;
+	__le32 rsv[2];
 };
 
 #define VF_RES_B_DATA_0_VF_ID_S 0
@@ -1180,11 +1183,11 @@ struct hns_roce_vf_res_b {
 #define ROCEE_VF_SGID_CFG4_SGID_TYPE_M GENMASK(1, 0)
 
 struct hns_roce_cfg_bt_attr {
-	u32 vf_qpc_cfg;
-	u32 vf_srqc_cfg;
-	u32 vf_cqc_cfg;
-	u32 vf_mpt_cfg;
-	u32 rsv[2];
+	__le32 vf_qpc_cfg;
+	__le32 vf_srqc_cfg;
+	__le32 vf_cqc_cfg;
+	__le32 vf_mpt_cfg;
+	__le32 rsv[2];
 };
 
 #define CFG_BT_ATTR_DATA_0_VF_QPC_BA_PGSZ_S 0
@@ -1224,11 +1227,11 @@ struct hns_roce_cfg_bt_attr {
 #define CFG_BT_ATTR_DATA_3_VF_MPT_HOPNUM_M GENMASK(9, 8)
 
 struct hns_roce_cmq_desc {
-	u16 opcode;
-	u16 flag;
-	u16 retval;
-	u16 rsv;
-	u32 data[6];
+	__le16 opcode;
+	__le16 flag;
+	__le16 retval;
+	__le16 rsv;
+	__le32 data[6];
 };
 
 #define HNS_ROCE_V2_GO_BIT_TIMEOUT_MSECS	10000
@@ -1274,18 +1277,18 @@ struct hns_roce_v2_priv {
 };
 
 struct hns_roce_eq_context {
-	u32	byte_4;
-	u32	byte_8;
-	u32	byte_12;
-	u32	eqe_report_timer;
-	u32	eqe_ba0;
-	u32	eqe_ba1;
-	u32	byte_28;
-	u32	byte_32;
-	u32	byte_36;
-	u32	nxt_eqe_ba0;
-	u32	nxt_eqe_ba1;
-	u32	rsv[5];
+	__le32	byte_4;
+	__le32	byte_8;
+	__le32	byte_12;
+	__le32	eqe_report_timer;
+	__le32	eqe_ba0;
+	__le32	eqe_ba1;
+	__le32	byte_28;
+	__le32	byte_32;
+	__le32	byte_36;
+	__le32	nxt_eqe_ba0;
+	__le32	nxt_eqe_ba1;
+	__le32	rsv[5];
 };
 
 #define HNS_ROCE_AEQ_DEFAULT_BURST_NUM	0x0
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
index aa0c242..eb9a69f 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -200,7 +200,7 @@ static int hns_roce_query_device(struct ib_device *ib_dev,
 
 	memset(props, 0, sizeof(*props));
 
-	props->sys_image_guid = hr_dev->sys_image_guid;
+	props->sys_image_guid = cpu_to_be32(hr_dev->sys_image_guid);
 	props->max_mr_size = (u64)(~(0ULL));
 	props->page_size_cap = hr_dev->caps.page_size_cap;
 	props->vendor_id = hr_dev->vendor_id;
@@ -636,7 +636,6 @@ static int hns_roce_init_hem(struct hns_roce_dev *hr_dev)
 	hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtpt_table);
 
 err_unmap_mtt:
-	hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtt_table);
 	if (hns_roce_check_whether_mhop(hr_dev, HEM_TYPE_CQE))
 		hns_roce_cleanup_hem_table(hr_dev,
 					   &hr_dev->mr_table.mtt_cqe_table);
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
index 4414cea..088973a 100644
--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
+++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
@@ -512,9 +512,9 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
 	hr_qp->ibqp.qp_type = init_attr->qp_type;
 
 	if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
-		hr_qp->sq_signal_bits = IB_SIGNAL_ALL_WR;
+		hr_qp->sq_signal_bits = cpu_to_le32(IB_SIGNAL_ALL_WR);
 	else
-		hr_qp->sq_signal_bits = IB_SIGNAL_REQ_WR;
+		hr_qp->sq_signal_bits = cpu_to_le32(IB_SIGNAL_REQ_WR);
 
 	ret = hns_roce_set_rq_size(hr_dev, &init_attr->cap, !!ib_pd->uobject,
 				   !!init_attr->srq, hr_qp);
@@ -937,20 +937,6 @@ void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq,
 }
 EXPORT_SYMBOL_GPL(hns_roce_unlock_cqs);
 
-__be32 send_ieth(struct ib_send_wr *wr)
-{
-	switch (wr->opcode) {
-	case IB_WR_SEND_WITH_IMM:
-	case IB_WR_RDMA_WRITE_WITH_IMM:
-		return cpu_to_le32(wr->ex.imm_data);
-	case IB_WR_SEND_WITH_INV:
-		return cpu_to_le32(wr->ex.invalidate_rkey);
-	default:
-		return 0;
-	}
-}
-EXPORT_SYMBOL_GPL(send_ieth);
-
 static void *get_wqe(struct hns_roce_qp *hr_qp, int offset)
 {
 
diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c
index a9c3378..db4bf97 100644
--- a/drivers/infiniband/hw/qedr/main.c
+++ b/drivers/infiniband/hw/qedr/main.c
@@ -430,59 +430,16 @@ static void qedr_remove_sysfiles(struct qedr_dev *dev)
 
 static void qedr_pci_set_atomic(struct qedr_dev *dev, struct pci_dev *pdev)
 {
-	struct pci_dev *bridge;
-	u32 ctl2, cap2;
-	u16 flags;
-	int rc;
+	int rc = pci_enable_atomic_ops_to_root(pdev,
+					       PCI_EXP_DEVCAP2_ATOMIC_COMP64);
 
-	bridge = pdev->bus->self;
-	if (!bridge)
-		goto disable;
-
-	/* Check atomic routing support all the way to root complex */
-	while (bridge->bus->parent) {
-		rc = pcie_capability_read_word(bridge, PCI_EXP_FLAGS, &flags);
-		if (rc || ((flags & PCI_EXP_FLAGS_VERS) < 2))
-			goto disable;
-
-		rc = pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap2);
-		if (rc)
-			goto disable;
-
-		rc = pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, &ctl2);
-		if (rc)
-			goto disable;
-
-		if (!(cap2 & PCI_EXP_DEVCAP2_ATOMIC_ROUTE) ||
-		    (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK))
-			goto disable;
-		bridge = bridge->bus->parent->self;
+	if (rc) {
+		dev->atomic_cap = IB_ATOMIC_NONE;
+		DP_DEBUG(dev, QEDR_MSG_INIT, "Atomic capability disabled\n");
+	} else {
+		dev->atomic_cap = IB_ATOMIC_GLOB;
+		DP_DEBUG(dev, QEDR_MSG_INIT, "Atomic capability enabled\n");
 	}
-
-	rc = pcie_capability_read_word(bridge, PCI_EXP_FLAGS, &flags);
-	if (rc || ((flags & PCI_EXP_FLAGS_VERS) < 2))
-		goto disable;
-
-	rc = pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap2);
-	if (rc || !(cap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP64))
-		goto disable;
-
-	/* Set atomic operations */
-	pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2,
-				 PCI_EXP_DEVCTL2_ATOMIC_REQ);
-	dev->atomic_cap = IB_ATOMIC_GLOB;
-
-	DP_DEBUG(dev, QEDR_MSG_INIT, "Atomic capability enabled\n");
-
-	return;
-
-disable:
-	pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL2,
-				   PCI_EXP_DEVCTL2_ATOMIC_REQ);
-	dev->atomic_cap = IB_ATOMIC_NONE;
-
-	DP_DEBUG(dev, QEDR_MSG_INIT, "Atomic capability disabled\n");
-
 }
 
 static const struct qed_rdma_ops *qed_ops;
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c
index cfddff4..c9955d4 100644
--- a/drivers/infiniband/hw/qib/qib_rc.c
+++ b/drivers/infiniband/hw/qib/qib_rc.c
@@ -1913,8 +1913,7 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct ib_header *hdr,
 		wc.port_num = 0;
 		/* Signal completion event if the solicited bit is set. */
 		rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
-			     (ohdr->bth[0] &
-			      cpu_to_be32(IB_BTH_SOLICITED)) != 0);
+			     ib_bth_is_solicited(ohdr));
 		break;
 
 	case OP(RDMA_WRITE_FIRST):
diff --git a/drivers/infiniband/hw/qib/qib_uc.c b/drivers/infiniband/hw/qib/qib_uc.c
index 70c58b8..840eec6e 100644
--- a/drivers/infiniband/hw/qib/qib_uc.c
+++ b/drivers/infiniband/hw/qib/qib_uc.c
@@ -401,8 +401,7 @@ void qib_uc_rcv(struct qib_ibport *ibp, struct ib_header *hdr,
 		wc.port_num = 0;
 		/* Signal completion event if the solicited bit is set. */
 		rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
-			     (ohdr->bth[0] &
-				cpu_to_be32(IB_BTH_SOLICITED)) != 0);
+			     ib_bth_is_solicited(ohdr));
 		break;
 
 	case OP(RDMA_WRITE_FIRST):
diff --git a/drivers/infiniband/hw/qib/qib_ud.c b/drivers/infiniband/hw/qib/qib_ud.c
index 386c3c4..3e4ff77 100644
--- a/drivers/infiniband/hw/qib/qib_ud.c
+++ b/drivers/infiniband/hw/qib/qib_ud.c
@@ -579,8 +579,7 @@ void qib_ud_rcv(struct qib_ibport *ibp, struct ib_header *hdr,
 	wc.port_num = qp->port_num;
 	/* Signal completion event if the solicited bit is set. */
 	rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
-		     (ohdr->bth[0] &
-			cpu_to_be32(IB_BTH_SOLICITED)) != 0);
+		     ib_bth_is_solicited(ohdr));
 	return;
 
 drop:
diff --git a/drivers/infiniband/sw/rxe/rxe_av.c b/drivers/infiniband/sw/rxe/rxe_av.c
index 1cc9e2e..7522d1a 100644
--- a/drivers/infiniband/sw/rxe/rxe_av.c
+++ b/drivers/infiniband/sw/rxe/rxe_av.c
@@ -52,28 +52,24 @@ int rxe_av_chk_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr)
 	return 0;
 }
 
-int rxe_av_from_attr(struct rxe_dev *rxe, u8 port_num,
-		     struct rxe_av *av, struct rdma_ah_attr *attr)
+void rxe_av_from_attr(u8 port_num, struct rxe_av *av,
+		     struct rdma_ah_attr *attr)
 {
 	memset(av, 0, sizeof(*av));
 	memcpy(&av->grh, rdma_ah_read_grh(attr),
 	       sizeof(*rdma_ah_read_grh(attr)));
 	av->port_num = port_num;
-	return 0;
 }
 
-int rxe_av_to_attr(struct rxe_dev *rxe, struct rxe_av *av,
-		   struct rdma_ah_attr *attr)
+void rxe_av_to_attr(struct rxe_av *av, struct rdma_ah_attr *attr)
 {
 	attr->type = RDMA_AH_ATTR_TYPE_ROCE;
 	memcpy(rdma_ah_retrieve_grh(attr), &av->grh, sizeof(av->grh));
 	rdma_ah_set_ah_flags(attr, IB_AH_GRH);
 	rdma_ah_set_port_num(attr, av->port_num);
-	return 0;
 }
 
-int rxe_av_fill_ip_info(struct rxe_dev *rxe,
-			struct rxe_av *av,
+void rxe_av_fill_ip_info(struct rxe_av *av,
 			struct rdma_ah_attr *attr,
 			struct ib_gid_attr *sgid_attr,
 			union ib_gid *sgid)
@@ -81,8 +77,6 @@ int rxe_av_fill_ip_info(struct rxe_dev *rxe,
 	rdma_gid2ip(&av->sgid_addr._sockaddr, sgid);
 	rdma_gid2ip(&av->dgid_addr._sockaddr, &rdma_ah_read_grh(attr)->dgid);
 	av->network_type = ib_gid_to_network_type(sgid_attr->gid_type, sgid);
-
-	return 0;
 }
 
 struct rxe_av *rxe_get_av(struct rxe_pkt_info *pkt)
diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
index 96c3a6c..4ef75d5 100644
--- a/drivers/infiniband/sw/rxe/rxe_loc.h
+++ b/drivers/infiniband/sw/rxe/rxe_loc.h
@@ -38,14 +38,12 @@
 
 int rxe_av_chk_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr);
 
-int rxe_av_from_attr(struct rxe_dev *rxe, u8 port_num,
-		     struct rxe_av *av, struct rdma_ah_attr *attr);
+void rxe_av_from_attr(u8 port_num, struct rxe_av *av,
+		     struct rdma_ah_attr *attr);
 
-int rxe_av_to_attr(struct rxe_dev *rxe, struct rxe_av *av,
-		   struct rdma_ah_attr *attr);
+void rxe_av_to_attr(struct rxe_av *av, struct rdma_ah_attr *attr);
 
-int rxe_av_fill_ip_info(struct rxe_dev *rxe,
-			struct rxe_av *av,
+void rxe_av_fill_ip_info(struct rxe_av *av,
 			struct rdma_ah_attr *attr,
 			struct ib_gid_attr *sgid_attr,
 			union ib_gid *sgid);
diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
index 137d6c0..2fcf1ca 100644
--- a/drivers/infiniband/sw/rxe/rxe_qp.c
+++ b/drivers/infiniband/sw/rxe/rxe_qp.c
@@ -633,9 +633,8 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask,
 		ib_get_cached_gid(&rxe->ib_dev, 1,
 				  rdma_ah_read_grh(&attr->ah_attr)->sgid_index,
 				  &sgid, &sgid_attr);
-		rxe_av_from_attr(rxe, attr->port_num, &qp->pri_av,
-				 &attr->ah_attr);
-		rxe_av_fill_ip_info(rxe, &qp->pri_av, &attr->ah_attr,
+		rxe_av_from_attr(attr->port_num, &qp->pri_av, &attr->ah_attr);
+		rxe_av_fill_ip_info(&qp->pri_av, &attr->ah_attr,
 				    &sgid_attr, &sgid);
 		if (sgid_attr.ndev)
 			dev_put(sgid_attr.ndev);
@@ -648,9 +647,9 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask,
 		ib_get_cached_gid(&rxe->ib_dev, 1, sgid_index,
 				  &sgid, &sgid_attr);
 
-		rxe_av_from_attr(rxe, attr->alt_port_num, &qp->alt_av,
+		rxe_av_from_attr(attr->alt_port_num, &qp->alt_av,
 				 &attr->alt_ah_attr);
-		rxe_av_fill_ip_info(rxe, &qp->alt_av, &attr->alt_ah_attr,
+		rxe_av_fill_ip_info(&qp->alt_av, &attr->alt_ah_attr,
 				    &sgid_attr, &sgid);
 		if (sgid_attr.ndev)
 			dev_put(sgid_attr.ndev);
@@ -765,8 +764,6 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask,
 /* called by the query qp verb */
 int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask)
 {
-	struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
-
 	*attr = qp->attr;
 
 	attr->rq_psn				= qp->resp.psn;
@@ -781,8 +778,8 @@ int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask)
 		attr->cap.max_recv_sge		= qp->rq.max_sge;
 	}
 
-	rxe_av_to_attr(rxe, &qp->pri_av, &attr->ah_attr);
-	rxe_av_to_attr(rxe, &qp->alt_av, &attr->alt_ah_attr);
+	rxe_av_to_attr(&qp->pri_av, &attr->ah_attr);
+	rxe_av_to_attr(&qp->alt_av, &attr->alt_ah_attr);
 
 	if (qp->req.state == QP_STATE_DRAIN) {
 		attr->sq_draining = 1;
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 7210a784..f4bab2c 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -271,13 +271,12 @@ static int rxe_init_av(struct rxe_dev *rxe, struct rdma_ah_attr *attr,
 		return err;
 	}
 
-	err = rxe_av_from_attr(rxe, rdma_ah_get_port_num(attr), av, attr);
-	if (!err)
-		err = rxe_av_fill_ip_info(rxe, av, attr, &sgid_attr, &sgid);
+	rxe_av_from_attr(rdma_ah_get_port_num(attr), av, attr);
+	rxe_av_fill_ip_info(av, attr, &sgid_attr, &sgid);
 
 	if (sgid_attr.ndev)
 		dev_put(sgid_attr.ndev);
-	return err;
+	return 0;
 }
 
 static struct ib_ah *rxe_create_ah(struct ib_pd *ibpd,
@@ -335,12 +334,11 @@ static int rxe_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
 
 static int rxe_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
 {
-	struct rxe_dev *rxe = to_rdev(ibah->device);
 	struct rxe_ah *ah = to_rah(ibah);
 
 	memset(attr, 0, sizeof(*attr));
 	attr->type = ibah->type;
-	rxe_av_to_attr(rxe, &ah->av, attr);
+	rxe_av_to_attr(&ah->av, attr);
 	return 0;
 }
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 5930c7d..161ba8c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -2306,6 +2306,9 @@ static struct net_device *ipoib_add_port(const char *format,
 			      priv->ca, ipoib_event);
 	ib_register_event_handler(&priv->event_handler);
 
+	/* call event handler to ensure pkey in sync */
+	queue_work(ipoib_workqueue, &priv->flush_heavy);
+
 	result = register_netdev(priv->dev);
 	if (result) {
 		pr_warn("%s: couldn't register ipoib port %d; error %d\n",
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 97baf88..74788fd 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -527,7 +527,8 @@ static void amd_iommu_report_page_fault(u16 devid, u16 domain_id,
 	struct iommu_dev_data *dev_data = NULL;
 	struct pci_dev *pdev;
 
-	pdev = pci_get_bus_and_slot(PCI_BUS_NUM(devid), devid & 0xff);
+	pdev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(devid),
+					   devid & 0xff);
 	if (pdev)
 		dev_data = get_dev_data(&pdev->dev);
 
@@ -616,7 +617,9 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
 		       address, flags);
 		break;
 	default:
-		printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type);
+		printk(KERN_ERR "UNKNOWN type=0x%02x event[0]=0x%08x "
+		       "event[1]=0x%08x event[2]=0x%08x event[3]=0x%08x\n",
+		       type, event[0], event[1], event[2], event[3]);
 	}
 
 	memset(__evt, 0, 4 * sizeof(u32));
@@ -1815,7 +1818,8 @@ static bool dma_ops_domain(struct protection_domain *domain)
 	return domain->flags & PD_DMA_OPS_MASK;
 }
 
-static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
+static void set_dte_entry(u16 devid, struct protection_domain *domain,
+			  bool ats, bool ppr)
 {
 	u64 pte_root = 0;
 	u64 flags = 0;
@@ -1832,6 +1836,13 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
 	if (ats)
 		flags |= DTE_FLAG_IOTLB;
 
+	if (ppr) {
+		struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
+
+		if (iommu_feature(iommu, FEATURE_EPHSUP))
+			pte_root |= 1ULL << DEV_ENTRY_PPR;
+	}
+
 	if (domain->flags & PD_IOMMUV2_MASK) {
 		u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
 		u64 glx  = domain->glx;
@@ -1894,9 +1905,9 @@ static void do_attach(struct iommu_dev_data *dev_data,
 	domain->dev_cnt                 += 1;
 
 	/* Update device table */
-	set_dte_entry(dev_data->devid, domain, ats);
+	set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2);
 	if (alias != dev_data->devid)
-		set_dte_entry(alias, domain, ats);
+		set_dte_entry(alias, domain, ats, dev_data->iommu_v2);
 
 	device_flush_dte(dev_data);
 }
@@ -2275,13 +2286,15 @@ static void update_device_table(struct protection_domain *domain)
 	struct iommu_dev_data *dev_data;
 
 	list_for_each_entry(dev_data, &domain->dev_list, list) {
-		set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
+		set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled,
+			      dev_data->iommu_v2);
 
 		if (dev_data->devid == dev_data->alias)
 			continue;
 
 		/* There is an alias, update device table entry for it */
-		set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled);
+		set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled,
+			      dev_data->iommu_v2);
 	}
 }
 
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 6fe2d03..4e4a615 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -1697,8 +1697,8 @@ static int iommu_init_pci(struct amd_iommu *iommu)
 	u32 range, misc, low, high;
 	int ret;
 
-	iommu->dev = pci_get_bus_and_slot(PCI_BUS_NUM(iommu->devid),
-					  iommu->devid & 0xff);
+	iommu->dev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(iommu->devid),
+						 iommu->devid & 0xff);
 	if (!iommu->dev)
 		return -ENODEV;
 
@@ -1764,8 +1764,9 @@ static int iommu_init_pci(struct amd_iommu *iommu)
 	if (is_rd890_iommu(iommu->dev)) {
 		int i, j;
 
-		iommu->root_pdev = pci_get_bus_and_slot(iommu->dev->bus->number,
-				PCI_DEVFN(0, 0));
+		iommu->root_pdev =
+			pci_get_domain_bus_and_slot(0, iommu->dev->bus->number,
+						    PCI_DEVFN(0, 0));
 
 		/*
 		 * Some rd890 systems may not be fully reconfigured by the
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index f6b24c7..6a877eb 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -98,6 +98,7 @@
 #define FEATURE_HE		(1ULL<<8)
 #define FEATURE_PC		(1ULL<<9)
 #define FEATURE_GAM_VAPIC	(1ULL<<21)
+#define FEATURE_EPHSUP		(1ULL<<50)
 
 #define FEATURE_PASID_SHIFT	32
 #define FEATURE_PASID_MASK	(0x1fULL << FEATURE_PASID_SHIFT)
@@ -192,6 +193,7 @@
 /* macros and definitions for device table entries */
 #define DEV_ENTRY_VALID         0x00
 #define DEV_ENTRY_TRANSLATION   0x01
+#define DEV_ENTRY_PPR           0x34
 #define DEV_ENTRY_IR            0x3d
 #define DEV_ENTRY_IW            0x3e
 #define DEV_ENTRY_NO_PAGE_FAULT	0x62
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c
index df72493..1d0b53a0 100644
--- a/drivers/iommu/amd_iommu_v2.c
+++ b/drivers/iommu/amd_iommu_v2.c
@@ -565,7 +565,8 @@ static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data)
 	finish      = (iommu_fault->tag >> 9) & 1;
 
 	devid = iommu_fault->device_id;
-	pdev = pci_get_bus_and_slot(PCI_BUS_NUM(devid), devid & 0xff);
+	pdev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(devid),
+					   devid & 0xff);
 	if (!pdev)
 		return -ENODEV;
 	dev_data = get_dev_data(&pdev->dev);
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 744592d..3f2f1fc6 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2971,7 +2971,7 @@ static struct platform_driver arm_smmu_driver = {
 };
 module_platform_driver(arm_smmu_driver);
 
-IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3", NULL);
+IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3");
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
 MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 78d4c6b..69e7c60 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -2211,12 +2211,12 @@ static struct platform_driver arm_smmu_driver = {
 };
 module_platform_driver(arm_smmu_driver);
 
-IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1", NULL);
-IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2", NULL);
-IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400", NULL);
-IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401", NULL);
-IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500", NULL);
-IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2", NULL);
+IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1");
+IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2");
+IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400");
+IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401");
+IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500");
+IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2");
 
 MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
 MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>");
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 79c4565..2138102 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -1353,8 +1353,15 @@ static const struct iommu_ops exynos_iommu_ops = {
 
 static int __init exynos_iommu_init(void)
 {
+	struct device_node *np;
 	int ret;
 
+	np = of_find_matching_node(NULL, sysmmu_of_match);
+	if (!np)
+		return 0;
+
+	of_node_put(np);
+
 	lv2table_kmem_cache = kmem_cache_create("exynos-iommu-lv2table",
 				LV2TABLE_SIZE, LV2TABLE_SIZE, 0, NULL);
 	if (!lv2table_kmem_cache) {
@@ -1394,4 +1401,4 @@ static int __init exynos_iommu_init(void)
 }
 core_initcall(exynos_iommu_init);
 
-IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu", NULL);
+IOMMU_OF_DECLARE(exynos_iommu_of, "samsung,exynos-sysmmu");
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a1373cf..582fd01 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -64,7 +64,7 @@
 #define IOAPIC_RANGE_END	(0xfeefffff)
 #define IOVA_START_ADDR		(0x1000)
 
-#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
+#define DEFAULT_DOMAIN_ADDRESS_WIDTH 57
 
 #define MAX_AGAW_WIDTH 64
 #define MAX_AGAW_PFN_WIDTH	(MAX_AGAW_WIDTH - VTD_PAGE_SHIFT)
@@ -1601,8 +1601,7 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
 	 * flush. However, device IOTLB doesn't need to be flushed in this case.
 	 */
 	if (!cap_caching_mode(iommu->cap) || !map)
-		iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
-				      addr, mask);
+		iommu_flush_dev_iotlb(domain, addr, mask);
 }
 
 static void iommu_flush_iova(struct iova_domain *iovad)
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 0a826eb..35a408d 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -26,6 +26,10 @@
 #include <linux/interrupt.h>
 #include <asm/page.h>
 
+#define PASID_ENTRY_P		BIT_ULL(0)
+#define PASID_ENTRY_FLPM_5LP	BIT_ULL(9)
+#define PASID_ENTRY_SRE		BIT_ULL(11)
+
 static irqreturn_t prq_event_thread(int irq, void *d);
 
 struct pasid_entry {
@@ -41,6 +45,14 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
 	struct page *pages;
 	int order;
 
+	if (cpu_feature_enabled(X86_FEATURE_GBPAGES) &&
+			!cap_fl1gp_support(iommu->cap))
+		return -EINVAL;
+
+	if (cpu_feature_enabled(X86_FEATURE_LA57) &&
+			!cap_5lp_support(iommu->cap))
+		return -EINVAL;
+
 	/* Start at 2 because it's defined as 2^(1+PSS) */
 	iommu->pasid_max = 2 << ecap_pss(iommu->ecap);
 
@@ -129,6 +141,7 @@ int intel_svm_enable_prq(struct intel_iommu *iommu)
 		pr_err("IOMMU: %s: Failed to request IRQ for page request queue\n",
 		       iommu->name);
 		dmar_free_hwirq(irq);
+		iommu->pr_irq = 0;
 		goto err;
 	}
 	dmar_writeq(iommu->reg + DMAR_PQH_REG, 0ULL);
@@ -144,9 +157,11 @@ int intel_svm_finish_prq(struct intel_iommu *iommu)
 	dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL);
 	dmar_writeq(iommu->reg + DMAR_PQA_REG, 0ULL);
 
-	free_irq(iommu->pr_irq, iommu);
-	dmar_free_hwirq(iommu->pr_irq);
-	iommu->pr_irq = 0;
+	if (iommu->pr_irq) {
+		free_irq(iommu->pr_irq, iommu);
+		dmar_free_hwirq(iommu->pr_irq);
+		iommu->pr_irq = 0;
+	}
 
 	free_pages((unsigned long)iommu->prq, PRQ_ORDER);
 	iommu->prq = NULL;
@@ -290,6 +305,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
 	struct intel_svm_dev *sdev;
 	struct intel_svm *svm = NULL;
 	struct mm_struct *mm = NULL;
+	u64 pasid_entry_val;
 	int pasid_max;
 	int ret;
 
@@ -396,9 +412,15 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
 				kfree(sdev);
 				goto out;
 			}
-			iommu->pasid_table[svm->pasid].val = (u64)__pa(mm->pgd) | 1;
+			pasid_entry_val = (u64)__pa(mm->pgd) | PASID_ENTRY_P;
 		} else
-			iommu->pasid_table[svm->pasid].val = (u64)__pa(init_mm.pgd) | 1 | (1ULL << 11);
+			pasid_entry_val = (u64)__pa(init_mm.pgd) |
+					  PASID_ENTRY_P | PASID_ENTRY_SRE;
+		if (cpu_feature_enabled(X86_FEATURE_LA57))
+			pasid_entry_val |= PASID_ENTRY_FLPM_5LP;
+
+		iommu->pasid_table[svm->pasid].val = pasid_entry_val;
+
 		wmb();
 		/* In caching mode, we still have to flush with PASID 0 when
 		 * a PASID table entry becomes present. Not entirely clear
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 3de5c0b..69fef99 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1303,6 +1303,9 @@ int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
 	int ret;
 
 	group = iommu_group_get(dev);
+	if (!group)
+		return -ENODEV;
+
 	/*
 	 * Lock the group to make sure the device-count doesn't
 	 * change while we are attaching
@@ -1341,6 +1344,8 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
 	struct iommu_group *group;
 
 	group = iommu_group_get(dev);
+	if (!group)
+		return;
 
 	mutex_lock(&group->mutex);
 	if (iommu_group_device_count(group) != 1) {
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 8dce3a9..40ae6e8 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -1108,18 +1108,8 @@ static void __exit ipmmu_exit(void)
 subsys_initcall(ipmmu_init);
 module_exit(ipmmu_exit);
 
-#ifdef CONFIG_IOMMU_DMA
-static int __init ipmmu_vmsa_iommu_of_setup(struct device_node *np)
-{
-	ipmmu_init();
-	return 0;
-}
-
-IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa",
-		 ipmmu_vmsa_iommu_of_setup);
-IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795",
-		 ipmmu_vmsa_iommu_of_setup);
-#endif
+IOMMU_OF_DECLARE(ipmmu_vmsa_iommu_of, "renesas,ipmmu-vmsa");
+IOMMU_OF_DECLARE(ipmmu_r8a7795_iommu_of, "renesas,ipmmu-r8a7795");
 
 MODULE_DESCRIPTION("IOMMU API for Renesas VMSA-compatible IPMMU");
 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 04f4d51..0d33504 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -823,6 +823,8 @@ static int msm_iommu_probe(struct platform_device *pdev)
 		goto fail;
 	}
 
+	bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
+
 	pr_info("device mapped at %p, irq %d with %d ctx banks\n",
 		iommu->base, iommu->irq, iommu->ncb);
 
@@ -875,19 +877,7 @@ static void __exit msm_iommu_driver_exit(void)
 subsys_initcall(msm_iommu_driver_init);
 module_exit(msm_iommu_driver_exit);
 
-static int __init msm_iommu_init(void)
-{
-	bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
-	return 0;
-}
-
-static int __init msm_iommu_of_setup(struct device_node *np)
-{
-	msm_iommu_init();
-	return 0;
-}
-
-IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu", msm_iommu_of_setup);
+IOMMU_OF_DECLARE(msm_iommu_of, "qcom,apq8064-iommu");
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 50947eb..5c36a8b 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -231,19 +231,3 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
 
 	return ops;
 }
-
-static int __init of_iommu_init(void)
-{
-	struct device_node *np;
-	const struct of_device_id *match, *matches = &__iommu_of_table;
-
-	for_each_matching_node_and_match(np, matches, &match) {
-		const of_iommu_init_fn init_fn = match->data;
-
-		if (init_fn && init_fn(np))
-			pr_err("Failed to initialise IOMMU %pOF\n", np);
-	}
-
-	return 0;
-}
-postcore_initcall_sync(of_iommu_init);
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
index 505548a..5021754 100644
--- a/drivers/iommu/omap-iommu-debug.c
+++ b/drivers/iommu/omap-iommu-debug.c
@@ -274,8 +274,8 @@ void omap_iommu_debugfs_add(struct omap_iommu *obj)
 	if (!obj->debug_dir)
 		return;
 
-	d = debugfs_create_u8("nr_tlb_entries", 0400, obj->debug_dir,
-			      (u8 *)&obj->nr_tlb_entries);
+	d = debugfs_create_u32("nr_tlb_entries", 0400, obj->debug_dir,
+			       &obj->nr_tlb_entries);
 	if (!d)
 		return;
 
diff --git a/drivers/iommu/qcom_iommu.c b/drivers/iommu/qcom_iommu.c
index e07f02d..65b9c99 100644
--- a/drivers/iommu/qcom_iommu.c
+++ b/drivers/iommu/qcom_iommu.c
@@ -947,7 +947,7 @@ static void __exit qcom_iommu_exit(void)
 module_init(qcom_iommu_init);
 module_exit(qcom_iommu_exit);
 
-IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1", NULL);
+IOMMU_OF_DECLARE(qcom_iommu_dev, "qcom,msm-iommu-v1");
 
 MODULE_DESCRIPTION("IOMMU API for QCOM IOMMU v1 implementations");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/irqchip/irq-i8259.c b/drivers/irqchip/irq-i8259.c
index 7aafbb0..b0d4aab 100644
--- a/drivers/irqchip/irq-i8259.c
+++ b/drivers/irqchip/irq-i8259.c
@@ -289,14 +289,14 @@ static struct resource pic1_io_resource = {
 	.name = "pic1",
 	.start = PIC_MASTER_CMD,
 	.end = PIC_MASTER_IMR,
-	.flags = IORESOURCE_BUSY
+	.flags = IORESOURCE_IO | IORESOURCE_BUSY
 };
 
 static struct resource pic2_io_resource = {
 	.name = "pic2",
 	.start = PIC_SLAVE_CMD,
 	.end = PIC_SLAVE_IMR,
-	.flags = IORESOURCE_BUSY
+	.flags = IORESOURCE_IO | IORESOURCE_BUSY
 };
 
 static int i8259A_irq_domain_map(struct irq_domain *d, unsigned int virq,
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index e8b29fc..08849e3 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -1799,7 +1799,7 @@ static int powerbook_sleep_grackle(void)
 	struct adb_request req;
 	struct pci_dev *grackle;
 
-	grackle = pci_get_bus_and_slot(0, 0);
+	grackle = pci_get_domain_bus_and_slot(0, 0, 0);
 	if (!grackle)
 		return -ENODEV;
 
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index edfe99b..145e12b 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -80,11 +80,11 @@
 config MEDIA_CEC_SUPPORT
        bool "HDMI CEC support"
        ---help---
-         Enable support for HDMI CEC (Consumer Electronics Control),
-         which is an optional HDMI feature.
+	 Enable support for HDMI CEC (Consumer Electronics Control),
+	 which is an optional HDMI feature.
 
-         Say Y when you have an HDMI receiver, transmitter or a USB CEC
-         adapter that supports HDMI CEC.
+	 Say Y when you have an HDMI receiver, transmitter or a USB CEC
+	 adapter that supports HDMI CEC.
 
 source "drivers/media/cec/Kconfig"
 
@@ -144,6 +144,18 @@
 	default y
 	select CRC32
 
+config DVB_MMAP
+	bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
+	depends on DVB_CORE
+	default n
+	help
+	  This option enables DVB experimental memory-mapped API, with
+	  reduces the number of context switches to read DVB buffers, as
+	  the buffers can use mmap() syscalls.
+
+	  Support for it is experimental. Use with care. If unsure,
+	  say N.
+
 config DVB_NET
 	bool "DVB Network Support"
 	default (NET && INET)
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index 98f88c4..2b1e540 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -540,7 +540,7 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
 	unsigned int attempts_made = arb_lost_cnt + nack_cnt +
 				     low_drive_cnt + error_cnt;
 
-	dprintk(2, "%s: status %02x\n", __func__, status);
+	dprintk(2, "%s: status 0x%02x\n", __func__, status);
 	if (attempts_made < 1)
 		attempts_made = 1;
 
@@ -1788,9 +1788,6 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
 	int la_idx = cec_log_addr2idx(adap, dest_laddr);
 	bool from_unregistered = init_laddr == 0xf;
 	struct cec_msg tx_cec_msg = { };
-#ifdef CONFIG_MEDIA_CEC_RC
-	int scancode;
-#endif
 
 	dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
 
@@ -1886,9 +1883,11 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
 		 */
 		case 0x60:
 			if (msg->len == 2)
-				scancode = msg->msg[2];
+				rc_keydown(adap->rc, RC_PROTO_CEC,
+					   msg->msg[2], 0);
 			else
-				scancode = msg->msg[2] << 8 | msg->msg[3];
+				rc_keydown(adap->rc, RC_PROTO_CEC,
+					   msg->msg[2] << 8 | msg->msg[3], 0);
 			break;
 		/*
 		 * Other function messages that are not handled.
@@ -1901,54 +1900,11 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
 		 */
 		case 0x56: case 0x57:
 		case 0x67: case 0x68: case 0x69: case 0x6a:
-			scancode = -1;
 			break;
 		default:
-			scancode = msg->msg[2];
+			rc_keydown(adap->rc, RC_PROTO_CEC, msg->msg[2], 0);
 			break;
 		}
-
-		/* Was repeating, but keypress timed out */
-		if (adap->rc_repeating && !adap->rc->keypressed) {
-			adap->rc_repeating = false;
-			adap->rc_last_scancode = -1;
-		}
-		/* Different keypress from last time, ends repeat mode */
-		if (adap->rc_last_scancode != scancode) {
-			rc_keyup(adap->rc);
-			adap->rc_repeating = false;
-		}
-		/* We can't handle this scancode */
-		if (scancode < 0) {
-			adap->rc_last_scancode = scancode;
-			break;
-		}
-
-		/* Send key press */
-		rc_keydown(adap->rc, RC_PROTO_CEC, scancode, 0);
-
-		/* When in repeating mode, we're done */
-		if (adap->rc_repeating)
-			break;
-
-		/*
-		 * We are not repeating, but the new scancode is
-		 * the same as the last one, and this second key press is
-		 * within 550 ms (the 'Follower Safety Timeout') from the
-		 * previous key press, so we now enable the repeating mode.
-		 */
-		if (adap->rc_last_scancode == scancode &&
-		    msg->rx_ts - adap->rc_last_keypress < 550 * NSEC_PER_MSEC) {
-			adap->rc_repeating = true;
-			break;
-		}
-		/*
-		 * Not in repeating mode, so avoid triggering repeat mode
-		 * by calling keyup.
-		 */
-		rc_keyup(adap->rc);
-		adap->rc_last_scancode = scancode;
-		adap->rc_last_keypress = msg->rx_ts;
 #endif
 		break;
 
@@ -1958,8 +1914,6 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
 			break;
 #ifdef CONFIG_MEDIA_CEC_RC
 		rc_keyup(adap->rc);
-		adap->rc_repeating = false;
-		adap->rc_last_scancode = -1;
 #endif
 		break;
 
@@ -2053,6 +2007,29 @@ void cec_monitor_all_cnt_dec(struct cec_adapter *adap)
 		WARN_ON(call_op(adap, adap_monitor_all_enable, 0));
 }
 
+/*
+ * Helper functions to keep track of the 'monitor pin' use count.
+ *
+ * These functions are called with adap->lock held.
+ */
+int cec_monitor_pin_cnt_inc(struct cec_adapter *adap)
+{
+	int ret = 0;
+
+	if (adap->monitor_pin_cnt == 0)
+		ret = call_op(adap, adap_monitor_pin_enable, 1);
+	if (ret == 0)
+		adap->monitor_pin_cnt++;
+	return ret;
+}
+
+void cec_monitor_pin_cnt_dec(struct cec_adapter *adap)
+{
+	adap->monitor_pin_cnt--;
+	if (adap->monitor_pin_cnt == 0)
+		WARN_ON(call_op(adap, adap_monitor_pin_enable, 0));
+}
+
 #ifdef CONFIG_DEBUG_FS
 /*
  * Log the current state of the CEC adapter.
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index 9d6c496..ecc89d9 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -46,12 +46,11 @@ static inline struct cec_devnode *cec_devnode_data(struct file *filp)
 static __poll_t cec_poll(struct file *filp,
 			     struct poll_table_struct *poll)
 {
-	struct cec_devnode *devnode = cec_devnode_data(filp);
 	struct cec_fh *fh = filp->private_data;
 	struct cec_adapter *adap = fh->adap;
 	__poll_t res = 0;
 
-	if (!devnode->registered)
+	if (!cec_is_registered(adap))
 		return POLLERR | POLLHUP;
 	mutex_lock(&adap->lock);
 	if (adap->is_configured &&
@@ -354,6 +353,7 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
 	u32 mode;
 	u8 mode_initiator;
 	u8 mode_follower;
+	bool send_pin_event = false;
 	long err = 0;
 
 	if (copy_from_user(&mode, parg, sizeof(mode)))
@@ -433,6 +433,19 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
 		}
 	}
 
+	if (!err) {
+		bool old_mon_pin = fh->mode_follower == CEC_MODE_MONITOR_PIN;
+		bool new_mon_pin = mode_follower == CEC_MODE_MONITOR_PIN;
+
+		if (old_mon_pin != new_mon_pin) {
+			send_pin_event = new_mon_pin;
+			if (new_mon_pin)
+				err = cec_monitor_pin_cnt_inc(adap);
+			else
+				cec_monitor_pin_cnt_dec(adap);
+		}
+	}
+
 	if (err) {
 		mutex_unlock(&adap->lock);
 		return err;
@@ -440,11 +453,9 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
 
 	if (fh->mode_follower == CEC_MODE_FOLLOWER)
 		adap->follower_cnt--;
-	if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
-		adap->monitor_pin_cnt--;
 	if (mode_follower == CEC_MODE_FOLLOWER)
 		adap->follower_cnt++;
-	if (mode_follower == CEC_MODE_MONITOR_PIN) {
+	if (send_pin_event) {
 		struct cec_event ev = {
 			.flags = CEC_EVENT_FL_INITIAL_STATE,
 		};
@@ -452,7 +463,6 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
 		ev.event = adap->cec_pin_is_high ? CEC_EVENT_PIN_CEC_HIGH :
 						   CEC_EVENT_PIN_CEC_LOW;
 		cec_queue_event_fh(fh, &ev, 0);
-		adap->monitor_pin_cnt++;
 	}
 	if (mode_follower == CEC_MODE_EXCL_FOLLOWER ||
 	    mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) {
@@ -475,13 +485,12 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
 
 static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
-	struct cec_devnode *devnode = cec_devnode_data(filp);
 	struct cec_fh *fh = filp->private_data;
 	struct cec_adapter *adap = fh->adap;
 	bool block = !(filp->f_flags & O_NONBLOCK);
 	void __user *parg = (void __user *)arg;
 
-	if (!devnode->registered)
+	if (!cec_is_registered(adap))
 		return -ENODEV;
 
 	switch (cmd) {
@@ -608,16 +617,15 @@ static int cec_release(struct inode *inode, struct file *filp)
 	if (fh->mode_follower == CEC_MODE_FOLLOWER)
 		adap->follower_cnt--;
 	if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
-		adap->monitor_pin_cnt--;
+		cec_monitor_pin_cnt_dec(adap);
 	if (fh->mode_follower == CEC_MODE_MONITOR_ALL)
 		cec_monitor_all_cnt_dec(adap);
 	mutex_unlock(&adap->lock);
 
 	mutex_lock(&devnode->lock);
 	list_del(&fh->list);
-	if (list_empty(&devnode->fhs) &&
-	    !adap->needs_hpd &&
-	    adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
+	if (cec_is_registered(adap) && list_empty(&devnode->fhs) &&
+	    !adap->needs_hpd && adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
 		WARN_ON(adap->ops->adap_enable(adap, false));
 	}
 	mutex_unlock(&devnode->lock);
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index 5870da6..a9f9525 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -160,8 +160,9 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode,
  * This function can safely be called if the device node has never been
  * registered or has already been unregistered.
  */
-static void cec_devnode_unregister(struct cec_devnode *devnode)
+static void cec_devnode_unregister(struct cec_adapter *adap)
 {
+	struct cec_devnode *devnode = &adap->devnode;
 	struct cec_fh *fh;
 
 	mutex_lock(&devnode->lock);
@@ -179,6 +180,11 @@ static void cec_devnode_unregister(struct cec_devnode *devnode)
 	devnode->unregistered = true;
 	mutex_unlock(&devnode->lock);
 
+	mutex_lock(&adap->lock);
+	__cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
+	__cec_s_log_addrs(adap, NULL, false);
+	mutex_unlock(&adap->lock);
+
 	cdev_device_del(&devnode->cdev, &devnode->dev);
 	put_device(&devnode->dev);
 }
@@ -192,7 +198,7 @@ static void cec_cec_notify(struct cec_adapter *adap, u16 pa)
 void cec_register_cec_notifier(struct cec_adapter *adap,
 			       struct cec_notifier *notifier)
 {
-	if (WARN_ON(!adap->devnode.registered))
+	if (WARN_ON(!cec_is_registered(adap)))
 		return;
 
 	adap->notifier = notifier;
@@ -280,7 +286,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
 	adap->rc->priv = adap;
 	adap->rc->map_name = RC_MAP_CEC;
 	adap->rc->timeout = MS_TO_NS(100);
-	adap->rc_last_scancode = -1;
 #endif
 	return adap;
 }
@@ -312,17 +317,6 @@ int cec_register_adapter(struct cec_adapter *adap,
 			adap->rc = NULL;
 			return res;
 		}
-		/*
-		 * The REP_DELAY for CEC is really the time between the initial
-		 * 'User Control Pressed' message and the second. The first
-		 * keypress is always seen as non-repeating, the second
-		 * (provided it has the same UI Command) will start the 'Press
-		 * and Hold' (aka repeat) behavior. By setting REP_DELAY to the
-		 * same value as REP_PERIOD the expected CEC behavior is
-		 * reproduced.
-		 */
-		adap->rc->input_dev->rep[REP_DELAY] =
-			adap->rc->input_dev->rep[REP_PERIOD];
 	}
 #endif
 
@@ -373,7 +367,7 @@ void cec_unregister_adapter(struct cec_adapter *adap)
 	if (adap->notifier)
 		cec_notifier_unregister(adap->notifier);
 #endif
-	cec_devnode_unregister(&adap->devnode);
+	cec_devnode_unregister(adap);
 }
 EXPORT_SYMBOL_GPL(cec_unregister_adapter);
 
@@ -381,9 +375,6 @@ void cec_delete_adapter(struct cec_adapter *adap)
 {
 	if (IS_ERR_OR_NULL(adap))
 		return;
-	mutex_lock(&adap->lock);
-	__cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
-	mutex_unlock(&adap->lock);
 	kthread_stop(adap->kthread);
 	if (adap->kthread_config)
 		kthread_stop(adap->kthread_config);
diff --git a/drivers/media/cec/cec-priv.h b/drivers/media/cec/cec-priv.h
index 70767a7..daf5976 100644
--- a/drivers/media/cec/cec-priv.h
+++ b/drivers/media/cec/cec-priv.h
@@ -40,6 +40,8 @@ void cec_put_device(struct cec_devnode *devnode);
 /* cec-adap.c */
 int cec_monitor_all_cnt_inc(struct cec_adapter *adap);
 void cec_monitor_all_cnt_dec(struct cec_adapter *adap);
+int cec_monitor_pin_cnt_inc(struct cec_adapter *adap);
+void cec_monitor_pin_cnt_dec(struct cec_adapter *adap);
 int cec_adap_status(struct seq_file *file, void *priv);
 int cec_thread_func(void *_adap);
 void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block);
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index 326df0a..0cb7d81 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -16,6 +16,7 @@
 	tristate "Cypress firmware helper routines"
 	depends on USB
 
+source "drivers/media/common/videobuf2/Kconfig"
 source "drivers/media/common/b2c2/Kconfig"
 source "drivers/media/common/saa7146/Kconfig"
 source "drivers/media/common/siano/Kconfig"
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index 2d1b0a0..e7bc17a 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1,4 +1,4 @@
-obj-y += b2c2/ saa7146/ siano/ v4l2-tpg/
+obj-y += b2c2/ saa7146/ siano/ v4l2-tpg/ videobuf2/
 obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
 obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
 obj-$(CONFIG_CYPRESS_FIRMWARE) += cypress_firmware.o
diff --git a/drivers/media/common/b2c2/Makefile b/drivers/media/common/b2c2/Makefile
index 73df4a33..aa2dc24 100644
--- a/drivers/media/common/b2c2/Makefile
+++ b/drivers/media/common/b2c2/Makefile
@@ -4,6 +4,5 @@
 b2c2-flexcop-objs += flexcop-hw-filter.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
 
-ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/dvb-frontends/
 ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/media/common/b2c2/flexcop-common.h b/drivers/media/common/b2c2/flexcop-common.h
index b7e5e4c..f944c59 100644
--- a/drivers/media/common/b2c2/flexcop-common.h
+++ b/drivers/media/common/b2c2/flexcop-common.h
@@ -13,10 +13,10 @@
 
 #include "flexcop-reg.h"
 
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dvb_frontend.h"
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dvb_frontend.h>
 
 #define FC_MAX_FEED 256
 
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
index 2b631ea..0dfa0c0 100644
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ b/drivers/media/common/saa7146/saa7146_video.c
@@ -4,6 +4,7 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-ctrls.h>
 #include <linux/module.h>
+#include <linux/kernel.h>
 
 static int max_memory = 32;
 
@@ -86,13 +87,11 @@ static struct saa7146_format formats[] = {
    due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped
    (like V4L2_PIX_FMT_YUYV) ... 8-( */
 
-static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
-
 struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc)
 {
-	int i, j = NUM_FORMATS;
+	int i;
 
-	for (i = 0; i < j; i++) {
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
 		if (formats[i].pixelformat == fourcc) {
 			return formats+i;
 		}
@@ -524,7 +523,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuf
 
 static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
 {
-	if (f->index >= NUM_FORMATS)
+	if (f->index >= ARRAY_SIZE(formats))
 		return -EINVAL;
 	strlcpy((char *)f->description, formats[f->index].name,
 			sizeof(f->description));
@@ -1002,9 +1001,9 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
 	.vidioc_try_fmt_vid_overlay  = vidioc_try_fmt_vid_overlay,
 	.vidioc_s_fmt_vid_overlay    = vidioc_s_fmt_vid_overlay,
 
-	.vidioc_overlay 	     = vidioc_overlay,
-	.vidioc_g_fbuf  	     = vidioc_g_fbuf,
-	.vidioc_s_fbuf  	     = vidioc_s_fbuf,
+	.vidioc_overlay		     = vidioc_overlay,
+	.vidioc_g_fbuf		     = vidioc_g_fbuf,
+	.vidioc_s_fbuf		     = vidioc_s_fbuf,
 	.vidioc_reqbufs              = vidioc_reqbufs,
 	.vidioc_querybuf             = vidioc_querybuf,
 	.vidioc_qbuf                 = vidioc_qbuf,
@@ -1013,7 +1012,7 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
 	.vidioc_s_std                = vidioc_s_std,
 	.vidioc_streamon             = vidioc_streamon,
 	.vidioc_streamoff            = vidioc_streamoff,
-	.vidioc_g_parm 		     = vidioc_g_parm,
+	.vidioc_g_parm		     = vidioc_g_parm,
 	.vidioc_subscribe_event      = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event    = v4l2_event_unsubscribe,
 };
diff --git a/drivers/media/common/siano/Makefile b/drivers/media/common/siano/Makefile
index 88e2b7f..b33022e 100644
--- a/drivers/media/common/siano/Makefile
+++ b/drivers/media/common/siano/Makefile
@@ -11,7 +11,3 @@
 ifeq ($(CONFIG_SMS_SIANO_DEBUGFS),y)
   smsdvb-objs += smsdvb-debugfs.o
 endif
-
-ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
-
diff --git a/drivers/media/common/siano/smsdvb-debugfs.c b/drivers/media/common/siano/smsdvb-debugfs.c
index 0c0878b..403645f 100644
--- a/drivers/media/common/siano/smsdvb-debugfs.c
+++ b/drivers/media/common/siano/smsdvb-debugfs.c
@@ -1,21 +1,6 @@
-/***********************************************************************
- *
- * Copyright(c) 2013 Mauro Carvalho Chehab
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
-
- *  This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- ***********************************************************************/
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright(c) 2013 Mauro Carvalho Chehab
 
 #include "smscoreapi.h"
 
@@ -26,10 +11,10 @@
 #include <linux/spinlock.h>
 #include <linux/usb.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
 
 #include "smsdvb.h"
 
diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c
index affde14..c0faad1 100644
--- a/drivers/media/common/siano/smsdvb-main.c
+++ b/drivers/media/common/siano/smsdvb-main.c
@@ -26,10 +26,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <linux/init.h>
 #include <asm/div64.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
 
 #include "sms-cards.h"
 
@@ -271,7 +271,7 @@ static void smsdvb_update_per_slices(struct smsdvb_client_t *client,
 	c->post_bit_count.stat[0].uvalue += p->ber_bit_count;
 
 	/* Legacy PER/BER */
-	tmp = p->ets_packets * 65535;
+	tmp = p->ets_packets * 65535ULL;
 	if (p->ts_packets + p->ets_packets)
 		do_div(tmp, p->ts_packets + p->ets_packets);
 	client->legacy_per = tmp;
diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c
index e77bb0c..56db0a94 100644
--- a/drivers/media/common/siano/smsir.c
+++ b/drivers/media/common/siano/smsir.c
@@ -1,28 +1,13 @@
-/****************************************************************
-
- Siano Mobile Silicon, Inc.
- MDTV receiver kernel modules.
- Copyright (C) 2006-2009, Uri Shkolnik
-
- Copyright (c) 2010 - Mauro Carvalho Chehab
-	- Ported the driver to use rc-core
-	- IR raw event decoding is now done at rc-core
-	- Code almost re-written
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
- ****************************************************************/
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Siano Mobile Silicon, Inc.
+// MDTV receiver kernel modules.
+// Copyright (C) 2006-2009, Uri Shkolnik
+//
+// Copyright (c) 2010 - Mauro Carvalho Chehab
+//	- Ported the driver to use rc-core
+//	- IR raw event decoding is now done at rc-core
+//	- Code almost re-written
 
 
 #include "smscoreapi.h"
diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h
index d9abd96..b2c54c2 100644
--- a/drivers/media/common/siano/smsir.h
+++ b/drivers/media/common/siano/smsir.h
@@ -1,28 +1,15 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2009, Uri Shkolnik
-
- Copyright (c) 2010 - Mauro Carvalho Chehab
-	- Ported the driver to use rc-core
-	- IR raw event decoding is now done at rc-core
-	- Code almost re-written
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Siano Mobile Silicon, Inc.
+ * MDTV receiver kernel modules.
+ * Copyright (C) 2006-2009, Uri Shkolnik
+ *
+ * Copyright (c) 2010 - Mauro Carvalho Chehab
+ *	- Ported the driver to use rc-core
+ *	- IR raw event decoding is now done at rc-core
+ *	- Code almost re-written
+ */
 
 #ifndef __SMS_IR_H__
 #define __SMS_IR_H__
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c
index 5b5f95c..4318020 100644
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c
@@ -36,10 +36,10 @@
  */
 
 #include <linux/videodev2.h>
-#include <media/v4l2-tpg-colors.h>
+#include <media/tpg/v4l2-tpg.h>
 
 /* sRGB colors with range [0-255] */
-const struct color tpg_colors[TPG_COLOR_MAX] = {
+const struct tpg_rbg_color8 tpg_colors[TPG_COLOR_MAX] = {
 	/*
 	 * Colors to test colorspace conversion: converting these colors
 	 * to other colorspaces will never lead to out-of-gamut colors.
@@ -597,7 +597,7 @@ const unsigned short tpg_linear_to_rec709[255 * 16 + 1] = {
 };
 
 /* Generated table */
-const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_SMPTE2084 + 1][TPG_COLOR_CSC_BLACK + 1] = {
+const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_SMPTE2084 + 1][TPG_COLOR_CSC_BLACK + 1] = {
 	[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
 	[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][1] = { 2953, 2963, 586 },
 	[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][2] = { 0, 2967, 2937 },
@@ -1392,7 +1392,7 @@ int main(int argc, char **argv)
 	printf("\n};\n\n");
 
 	printf("/* Generated table */\n");
-	printf("const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_SMPTE2084 + 1][TPG_COLOR_CSC_BLACK + 1] = {\n");
+	printf("const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_SMPTE2084 + 1][TPG_COLOR_CSC_BLACK + 1] = {\n");
 	for (c = 0; c <= V4L2_COLORSPACE_DCI_P3; c++) {
 		for (x = 1; x <= V4L2_XFER_FUNC_SMPTE2084; x++) {
 			for (i = 0; i <= TPG_COLOR_CSC_BLACK; i++) {
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
index f96968c..2b3d4ac 100644
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
@@ -21,7 +21,7 @@
  */
 
 #include <linux/module.h>
-#include <media/v4l2-tpg.h>
+#include <media/tpg/v4l2-tpg.h>
 
 /* Must remain in sync with enum tpg_pattern */
 const char * const tpg_pattern_strings[] = {
diff --git a/drivers/media/common/videobuf2/Kconfig b/drivers/media/common/videobuf2/Kconfig
new file mode 100644
index 0000000..5df0525
--- /dev/null
+++ b/drivers/media/common/videobuf2/Kconfig
@@ -0,0 +1,31 @@
+# Used by drivers that need Videobuf2 modules
+config VIDEOBUF2_CORE
+	select DMA_SHARED_BUFFER
+	tristate
+
+config VIDEOBUF2_MEMOPS
+	tristate
+	select FRAME_VECTOR
+
+config VIDEOBUF2_DMA_CONTIG
+	tristate
+	depends on HAS_DMA
+	select VIDEOBUF2_CORE
+	select VIDEOBUF2_MEMOPS
+	select DMA_SHARED_BUFFER
+
+config VIDEOBUF2_VMALLOC
+	tristate
+	select VIDEOBUF2_CORE
+	select VIDEOBUF2_MEMOPS
+	select DMA_SHARED_BUFFER
+
+config VIDEOBUF2_DMA_SG
+	tristate
+	depends on HAS_DMA
+	select VIDEOBUF2_CORE
+	select VIDEOBUF2_MEMOPS
+
+config VIDEOBUF2_DVB
+	tristate
+	select VIDEOBUF2_CORE
diff --git a/drivers/media/common/videobuf2/Makefile b/drivers/media/common/videobuf2/Makefile
new file mode 100644
index 0000000..19de5cc
--- /dev/null
+++ b/drivers/media/common/videobuf2/Makefile
@@ -0,0 +1,7 @@
+
+obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o
+obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
+obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
+obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
+obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o
+obj-$(CONFIG_VIDEOBUF2_DVB) += videobuf2-dvb.o
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
similarity index 97%
rename from drivers/media/v4l2-core/videobuf2-core.c
rename to drivers/media/common/videobuf2/videobuf2-core.c
index 0d9f772..9a84c70 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -14,6 +14,8 @@
  * the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -32,10 +34,10 @@
 static int debug;
 module_param(debug, int, 0644);
 
-#define dprintk(level, fmt, arg...)					      \
-	do {								      \
-		if (debug >= level)					      \
-			pr_info("vb2-core: %s: " fmt, __func__, ## arg); \
+#define dprintk(level, fmt, arg...)				\
+	do {							\
+		if (debug >= level)				\
+			pr_info("%s: " fmt, __func__, ## arg);	\
 	} while (0)
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -332,6 +334,10 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory,
 	struct vb2_buffer *vb;
 	int ret;
 
+	/* Ensure that q->num_buffers+num_buffers is below VB2_MAX_FRAME */
+	num_buffers = min_t(unsigned int, num_buffers,
+			    VB2_MAX_FRAME - q->num_buffers);
+
 	for (buffer = 0; buffer < num_buffers; ++buffer) {
 		/* Allocate videobuf buffer structures */
 		vb = kzalloc(q->buf_struct_size, GFP_KERNEL);
@@ -460,12 +466,12 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
 				  q->cnt_wait_prepare != q->cnt_wait_finish;
 
 		if (unbalanced || debug) {
-			pr_info("vb2: counters for queue %p:%s\n", q,
+			pr_info("counters for queue %p:%s\n", q,
 				unbalanced ? " UNBALANCED!" : "");
-			pr_info("vb2:     setup: %u start_streaming: %u stop_streaming: %u\n",
+			pr_info("     setup: %u start_streaming: %u stop_streaming: %u\n",
 				q->cnt_queue_setup, q->cnt_start_streaming,
 				q->cnt_stop_streaming);
-			pr_info("vb2:     wait_prepare: %u wait_finish: %u\n",
+			pr_info("     wait_prepare: %u wait_finish: %u\n",
 				q->cnt_wait_prepare, q->cnt_wait_finish);
 		}
 		q->cnt_queue_setup = 0;
@@ -486,23 +492,23 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
 				  vb->cnt_buf_init != vb->cnt_buf_cleanup;
 
 		if (unbalanced || debug) {
-			pr_info("vb2:   counters for queue %p, buffer %d:%s\n",
+			pr_info("   counters for queue %p, buffer %d:%s\n",
 				q, buffer, unbalanced ? " UNBALANCED!" : "");
-			pr_info("vb2:     buf_init: %u buf_cleanup: %u buf_prepare: %u buf_finish: %u\n",
+			pr_info("     buf_init: %u buf_cleanup: %u buf_prepare: %u buf_finish: %u\n",
 				vb->cnt_buf_init, vb->cnt_buf_cleanup,
 				vb->cnt_buf_prepare, vb->cnt_buf_finish);
-			pr_info("vb2:     buf_queue: %u buf_done: %u\n",
+			pr_info("     buf_queue: %u buf_done: %u\n",
 				vb->cnt_buf_queue, vb->cnt_buf_done);
-			pr_info("vb2:     alloc: %u put: %u prepare: %u finish: %u mmap: %u\n",
+			pr_info("     alloc: %u put: %u prepare: %u finish: %u mmap: %u\n",
 				vb->cnt_mem_alloc, vb->cnt_mem_put,
 				vb->cnt_mem_prepare, vb->cnt_mem_finish,
 				vb->cnt_mem_mmap);
-			pr_info("vb2:     get_userptr: %u put_userptr: %u\n",
+			pr_info("     get_userptr: %u put_userptr: %u\n",
 				vb->cnt_mem_get_userptr, vb->cnt_mem_put_userptr);
-			pr_info("vb2:     attach_dmabuf: %u detach_dmabuf: %u map_dmabuf: %u unmap_dmabuf: %u\n",
+			pr_info("     attach_dmabuf: %u detach_dmabuf: %u map_dmabuf: %u unmap_dmabuf: %u\n",
 				vb->cnt_mem_attach_dmabuf, vb->cnt_mem_detach_dmabuf,
 				vb->cnt_mem_map_dmabuf, vb->cnt_mem_unmap_dmabuf);
-			pr_info("vb2:     get_dmabuf: %u num_users: %u vaddr: %u cookie: %u\n",
+			pr_info("     get_dmabuf: %u num_users: %u vaddr: %u cookie: %u\n",
 				vb->cnt_mem_get_dmabuf,
 				vb->cnt_mem_num_users,
 				vb->cnt_mem_vaddr,
@@ -520,7 +526,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
 
 	q->num_buffers -= buffers;
 	if (!q->num_buffers) {
-		q->memory = 0;
+		q->memory = VB2_MEMORY_UNKNOWN;
 		INIT_LIST_HEAD(&q->queued_list);
 	}
 	return 0;
@@ -662,7 +668,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
 		return -EBUSY;
 	}
 
-	if (*count == 0 || q->num_buffers != 0 || q->memory != memory) {
+	if (*count == 0 || q->num_buffers != 0 ||
+	    (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) {
 		/*
 		 * We already have buffers allocated, so first check if they
 		 * are not in use and can be freed.
@@ -696,8 +703,9 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
 	/*
 	 * Make sure the requested values and current defaults are sane.
 	 */
-	num_buffers = min_t(unsigned int, *count, VB2_MAX_FRAME);
-	num_buffers = max_t(unsigned int, num_buffers, q->min_buffers_needed);
+	WARN_ON(q->min_buffers_needed > VB2_MAX_FRAME);
+	num_buffers = max_t(unsigned int, *count, q->min_buffers_needed);
+	num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME);
 	memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
 	q->memory = memory;
 
@@ -1650,8 +1658,11 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
 	 */
 	if (WARN_ON(atomic_read(&q->owned_by_drv_count))) {
 		for (i = 0; i < q->num_buffers; ++i)
-			if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE)
+			if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) {
+				pr_warn("driver bug: stop_streaming operation is leaving buf %p in active state\n",
+					q->bufs[i]);
 				vb2_buffer_done(q->bufs[i], VB2_BUF_STATE_ERROR);
+			}
 		/* Must be zero now */
 		WARN_ON(atomic_read(&q->owned_by_drv_count));
 	}
@@ -1994,6 +2005,8 @@ int vb2_core_queue_init(struct vb2_queue *q)
 	mutex_init(&q->mmap_lock);
 	init_waitqueue_head(&q->done_wq);
 
+	q->memory = VB2_MEMORY_UNKNOWN;
+
 	if (q->buf_struct_size == 0)
 		q->buf_struct_size = sizeof(struct vb2_buffer);
 
@@ -2522,7 +2535,7 @@ static int vb2_thread(void *data)
 				break;
 		call_void_qop(q, wait_finish, q);
 		if (copy_timestamp)
-			vb->timestamp = ktime_get_ns();;
+			vb->timestamp = ktime_get_ns();
 		if (!threadio->stop)
 			ret = vb2_core_qbuf(q, vb->index, NULL);
 		call_void_qop(q, wait_prepare, q);
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
similarity index 98%
rename from drivers/media/v4l2-core/videobuf2-dma-contig.c
rename to drivers/media/common/videobuf2/videobuf2-dma-contig.c
index a9806ba..f1178f6 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -434,8 +434,10 @@ static void vb2_dc_put_userptr(void *buf_priv)
 		pages = frame_vector_pages(buf->vec);
 		/* sgt should exist only if vector contains pages... */
 		BUG_ON(IS_ERR(pages));
-		for (i = 0; i < frame_vector_count(buf->vec); i++)
-			set_page_dirty_lock(pages[i]);
+		if (buf->dma_dir == DMA_FROM_DEVICE ||
+		    buf->dma_dir == DMA_BIDIRECTIONAL)
+			for (i = 0; i < frame_vector_count(buf->vec); i++)
+				set_page_dirty_lock(pages[i]);
 		sg_free_table(sgt);
 		kfree(sgt);
 	}
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
similarity index 98%
rename from drivers/media/v4l2-core/videobuf2-dma-sg.c
rename to drivers/media/common/videobuf2/videobuf2-dma-sg.c
index 6808231..753ed31 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
@@ -292,11 +292,10 @@ static void vb2_dma_sg_put_userptr(void *buf_priv)
 	if (buf->vaddr)
 		vm_unmap_ram(buf->vaddr, buf->num_pages);
 	sg_free_table(buf->dma_sgt);
-	while (--i >= 0) {
-		if (buf->dma_dir == DMA_FROM_DEVICE ||
-		    buf->dma_dir == DMA_BIDIRECTIONAL)
+	if (buf->dma_dir == DMA_FROM_DEVICE ||
+	    buf->dma_dir == DMA_BIDIRECTIONAL)
+		while (--i >= 0)
 			set_page_dirty_lock(buf->pages[i]);
-	}
 	vb2_destroy_framevec(buf->vec);
 	kfree(buf);
 }
diff --git a/drivers/media/v4l2-core/videobuf2-dvb.c b/drivers/media/common/videobuf2/videobuf2-dvb.c
similarity index 100%
rename from drivers/media/v4l2-core/videobuf2-dvb.c
rename to drivers/media/common/videobuf2/videobuf2-dvb.c
diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/common/videobuf2/videobuf2-memops.c
similarity index 100%
rename from drivers/media/v4l2-core/videobuf2-memops.c
rename to drivers/media/common/videobuf2/videobuf2-memops.c
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
similarity index 99%
rename from drivers/media/v4l2-core/videobuf2-v4l2.c
rename to drivers/media/common/videobuf2/videobuf2-v4l2.c
index a49f7eb..d9a487a 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -434,6 +434,8 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb,
 	} else {
 		/* Zero any output buffer flags as this is a capture buffer */
 		vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS;
+		/* Zero last flag, this is a signal from driver to userspace */
+		vbuf->flags &= ~V4L2_BUF_FLAG_LAST;
 	}
 
 	return 0;
diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c
similarity index 100%
rename from drivers/media/v4l2-core/videobuf2-vmalloc.c
rename to drivers/media/common/videobuf2/videobuf2-vmalloc.c
diff --git a/drivers/media/dvb-core/Kconfig b/drivers/media/dvb-core/Kconfig
index eeef94a..f004aea 100644
--- a/drivers/media/dvb-core/Kconfig
+++ b/drivers/media/dvb-core/Kconfig
@@ -40,3 +40,16 @@
 	  be very verbose.
 
 	  If you are unsure about this, say N here.
+
+config DVB_ULE_DEBUG
+	bool "Enable DVB net ULE packet debug messages"
+	depends on DVB_CORE
+	default n
+	help
+	  Enable extra log messages meant to detect problems while
+	  handling DVB network ULE packet loss inside the Kernel.
+
+	  Should not be enabled on normal cases, as logs can
+	  be very verbose.
+
+	  If you are unsure about this, say N here.
diff --git a/drivers/media/dvb-core/Makefile b/drivers/media/dvb-core/Makefile
index 47e2e39..3a105d8 100644
--- a/drivers/media/dvb-core/Makefile
+++ b/drivers/media/dvb-core/Makefile
@@ -4,9 +4,10 @@
 #
 
 dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
+dvb-vb2-$(CONFIG_DVB_MMSP) := dvb_vb2.o
 
-dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o		 	\
-		 dvb_ca_en50221.o dvb_frontend.o 		\
-		 $(dvb-net-y) dvb_ringbuffer.o dvb_math.o
+dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o			\
+		 dvb_ca_en50221.o dvb_frontend.o		\
+		 $(dvb-net-y) dvb_ringbuffer.o $(dvb-vb2-y) dvb_math.o
 
 obj-$(CONFIG_DVB_CORE) += dvb-core.o
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index 3fe0eb7..bc198f8 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -27,7 +27,8 @@
 #include <linux/ioctl.h>
 #include <linux/wait.h>
 #include <linux/uaccess.h>
-#include "dmxdev.h"
+#include <media/dmxdev.h>
+#include <media/dvb_vb2.h>
 
 static int debug;
 
@@ -127,6 +128,11 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
 	struct dvb_device *dvbdev = file->private_data;
 	struct dmxdev *dmxdev = dvbdev->priv;
 	struct dmx_frontend *front;
+#ifndef DVB_MMAP
+	bool need_ringbuffer = false;
+#else
+	const bool need_ringbuffer = true;
+#endif
 
 	dprintk("%s\n", __func__);
 
@@ -138,14 +144,19 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
 		return -ENODEV;
 	}
 
+#ifndef DVB_MMAP
+	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+		need_ringbuffer = true;
+#else
 	if ((file->f_flags & O_ACCMODE) == O_RDWR) {
 		if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
 			mutex_unlock(&dmxdev->mutex);
 			return -EOPNOTSUPP;
 		}
 	}
+#endif
 
-	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+	if (need_ringbuffer) {
 		void *mem;
 
 		if (!dvbdev->readers) {
@@ -158,6 +169,8 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
 			return -ENOMEM;
 		}
 		dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
+		dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",
+			     file->f_flags & O_NONBLOCK);
 		dvbdev->readers--;
 	}
 
@@ -187,6 +200,11 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dmxdev *dmxdev = dvbdev->priv;
+#ifndef DVB_MMAP
+	bool need_ringbuffer = false;
+#else
+	const bool need_ringbuffer = true;
+#endif
 
 	mutex_lock(&dmxdev->mutex);
 
@@ -195,7 +213,15 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
 		dmxdev->demux->connect_frontend(dmxdev->demux,
 						dmxdev->dvr_orig_fe);
 	}
-	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+#ifndef DVB_MMAP
+	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+		need_ringbuffer = true;
+#endif
+
+	if (need_ringbuffer) {
+		if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
+			dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx);
+		dvb_vb2_release(&dmxdev->dvr_vb2_ctx);
 		dvbdev->readers++;
 		if (dmxdev->dvr_buffer.data) {
 			void *mem = dmxdev->dvr_buffer.data;
@@ -359,7 +385,8 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
 	struct dmxdev_filter *dmxdevfilter = filter->priv;
 	int ret;
 
-	if (dmxdevfilter->buffer.error) {
+	if (!dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx) &&
+	    dmxdevfilter->buffer.error) {
 		wake_up(&dmxdevfilter->buffer.queue);
 		return 0;
 	}
@@ -370,11 +397,19 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
 	}
 	del_timer(&dmxdevfilter->timer);
 	dprintk("section callback %*ph\n", 6, buffer1);
-	ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1,
-				      buffer1_len);
-	if (ret == buffer1_len) {
-		ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
-					      buffer2_len);
+	if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {
+		ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
+					  buffer1, buffer1_len);
+		if (ret == buffer1_len)
+			ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
+						  buffer2, buffer2_len);
+	} else {
+		ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
+					      buffer1, buffer1_len);
+		if (ret == buffer1_len) {
+			ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
+						      buffer2, buffer2_len);
+		}
 	}
 	if (ret < 0)
 		dmxdevfilter->buffer.error = ret;
@@ -391,6 +426,9 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
 {
 	struct dmxdev_filter *dmxdevfilter = feed->priv;
 	struct dvb_ringbuffer *buffer;
+#ifdef DVB_MMAP
+	struct dvb_vb2_ctx *ctx;
+#endif
 	int ret;
 
 	spin_lock(&dmxdevfilter->dev->lock);
@@ -399,19 +437,34 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
 		return 0;
 	}
 
-	if (dmxdevfilter->params.pes.output == DMX_OUT_TAP
-	    || dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP)
+	if (dmxdevfilter->params.pes.output == DMX_OUT_TAP ||
+	    dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) {
 		buffer = &dmxdevfilter->buffer;
-	else
+#ifdef DVB_MMAP
+		ctx = &dmxdevfilter->vb2_ctx;
+#endif
+	} else {
 		buffer = &dmxdevfilter->dev->dvr_buffer;
-	if (buffer->error) {
-		spin_unlock(&dmxdevfilter->dev->lock);
-		wake_up(&buffer->queue);
-		return 0;
+#ifdef DVB_MMAP
+		ctx = &dmxdevfilter->dev->dvr_vb2_ctx;
+#endif
 	}
-	ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
-	if (ret == buffer1_len)
-		ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
+
+	if (dvb_vb2_is_streaming(ctx)) {
+		ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len);
+		if (ret == buffer1_len)
+			ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len);
+	} else {
+		if (buffer->error) {
+			spin_unlock(&dmxdevfilter->dev->lock);
+			wake_up(&buffer->queue);
+			return 0;
+		}
+		ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
+		if (ret == buffer1_len)
+			ret = dvb_dmxdev_buffer_write(buffer,
+						      buffer2, buffer2_len);
+	}
 	if (ret < 0)
 		buffer->error = ret;
 	spin_unlock(&dmxdevfilter->dev->lock);
@@ -750,6 +803,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
 	file->private_data = dmxdevfilter;
 
 	dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
+	dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter",
+		     file->f_flags & O_NONBLOCK);
 	dmxdevfilter->type = DMXDEV_TYPE_NONE;
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
 	timer_setup(&dmxdevfilter->timer, dvb_dmxdev_filter_timeout, 0);
@@ -765,6 +820,10 @@ static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev,
 {
 	mutex_lock(&dmxdev->mutex);
 	mutex_lock(&dmxdevfilter->mutex);
+	if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx))
+		dvb_vb2_stream_off(&dmxdevfilter->vb2_ctx);
+	dvb_vb2_release(&dmxdevfilter->vb2_ctx);
+
 
 	dvb_dmxdev_filter_stop(dmxdevfilter);
 	dvb_dmxdev_filter_reset(dmxdevfilter);
@@ -1052,6 +1111,54 @@ static int dvb_demux_do_ioctl(struct file *file,
 		mutex_unlock(&dmxdevfilter->mutex);
 		break;
 
+#ifdef DVB_MMAP
+	case DMX_REQBUFS:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			mutex_unlock(&dmxdev->mutex);
+			return -ERESTARTSYS;
+		}
+		ret = dvb_vb2_reqbufs(&dmxdevfilter->vb2_ctx, parg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
+	case DMX_QUERYBUF:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			mutex_unlock(&dmxdev->mutex);
+			return -ERESTARTSYS;
+		}
+		ret = dvb_vb2_querybuf(&dmxdevfilter->vb2_ctx, parg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
+	case DMX_EXPBUF:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			mutex_unlock(&dmxdev->mutex);
+			return -ERESTARTSYS;
+		}
+		ret = dvb_vb2_expbuf(&dmxdevfilter->vb2_ctx, parg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
+	case DMX_QBUF:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			mutex_unlock(&dmxdev->mutex);
+			return -ERESTARTSYS;
+		}
+		ret = dvb_vb2_qbuf(&dmxdevfilter->vb2_ctx, parg);
+		if (ret == 0 && !dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx))
+			ret = dvb_vb2_stream_on(&dmxdevfilter->vb2_ctx);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
+	case DMX_DQBUF:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			mutex_unlock(&dmxdev->mutex);
+			return -ERESTARTSYS;
+		}
+		ret = dvb_vb2_dqbuf(&dmxdevfilter->vb2_ctx, parg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+#endif
 	default:
 		ret = -EINVAL;
 		break;
@@ -1073,6 +1180,8 @@ static __poll_t dvb_demux_poll(struct file *file, poll_table *wait)
 
 	if ((!dmxdevfilter) || dmxdevfilter->dev->exit)
 		return POLLERR;
+	if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx))
+		return dvb_vb2_poll(&dmxdevfilter->vb2_ctx, file, wait);
 
 	poll_wait(file, &dmxdevfilter->buffer.queue, wait);
 
@@ -1090,11 +1199,33 @@ static __poll_t dvb_demux_poll(struct file *file, poll_table *wait)
 	return mask;
 }
 
+#ifdef DVB_MMAP
+static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct dmxdev_filter *dmxdevfilter = file->private_data;
+	struct dmxdev *dmxdev = dmxdevfilter->dev;
+	int ret;
+
+	if (mutex_lock_interruptible(&dmxdev->mutex))
+		return -ERESTARTSYS;
+
+	if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+		mutex_unlock(&dmxdev->mutex);
+		return -ERESTARTSYS;
+	}
+	ret = dvb_vb2_mmap(&dmxdevfilter->vb2_ctx, vma);
+
+	mutex_unlock(&dmxdevfilter->mutex);
+	mutex_unlock(&dmxdev->mutex);
+
+	return ret;
+}
+#endif
+
 static int dvb_demux_release(struct inode *inode, struct file *file)
 {
 	struct dmxdev_filter *dmxdevfilter = file->private_data;
 	struct dmxdev *dmxdev = dmxdevfilter->dev;
-
 	int ret;
 
 	ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
@@ -1118,6 +1249,9 @@ static const struct file_operations dvb_demux_fops = {
 	.release = dvb_demux_release,
 	.poll = dvb_demux_poll,
 	.llseek = default_llseek,
+#ifdef DVB_MMAP
+	.mmap = dvb_demux_mmap,
+#endif
 };
 
 static const struct dvb_device dvbdev_demux = {
@@ -1146,6 +1280,29 @@ static int dvb_dvr_do_ioctl(struct file *file,
 		ret = dvb_dvr_set_buffer_size(dmxdev, arg);
 		break;
 
+#ifdef DVB_MMAP
+	case DMX_REQBUFS:
+		ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg);
+		break;
+
+	case DMX_QUERYBUF:
+		ret = dvb_vb2_querybuf(&dmxdev->dvr_vb2_ctx, parg);
+		break;
+
+	case DMX_EXPBUF:
+		ret = dvb_vb2_expbuf(&dmxdev->dvr_vb2_ctx, parg);
+		break;
+
+	case DMX_QBUF:
+		ret = dvb_vb2_qbuf(&dmxdev->dvr_vb2_ctx, parg);
+		if (ret == 0 && !dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
+			ret = dvb_vb2_stream_on(&dmxdev->dvr_vb2_ctx);
+		break;
+
+	case DMX_DQBUF:
+		ret = dvb_vb2_dqbuf(&dmxdev->dvr_vb2_ctx, parg);
+		break;
+#endif
 	default:
 		ret = -EINVAL;
 		break;
@@ -1165,15 +1322,26 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
 	struct dvb_device *dvbdev = file->private_data;
 	struct dmxdev *dmxdev = dvbdev->priv;
 	__poll_t mask = 0;
+#ifndef DVB_MMAP
+	bool need_ringbuffer = false;
+#else
+	const bool need_ringbuffer = true;
+#endif
 
 	dprintk("%s\n", __func__);
 
 	if (dmxdev->exit)
 		return POLLERR;
+	if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
+		return dvb_vb2_poll(&dmxdev->dvr_vb2_ctx, file, wait);
 
 	poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
 
-	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+#ifndef DVB_MMAP
+	if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+		need_ringbuffer = true;
+#endif
+	if (need_ringbuffer) {
 		if (dmxdev->dvr_buffer.error)
 			mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
 
@@ -1185,6 +1353,25 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
 	return mask;
 }
 
+#ifdef DVB_MMAP
+static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct dvb_device *dvbdev = file->private_data;
+	struct dmxdev *dmxdev = dvbdev->priv;
+	int ret;
+
+	if (dmxdev->exit)
+		return -ENODEV;
+
+	if (mutex_lock_interruptible(&dmxdev->mutex))
+		return -ERESTARTSYS;
+
+	ret = dvb_vb2_mmap(&dmxdev->dvr_vb2_ctx, vma);
+	mutex_unlock(&dmxdev->mutex);
+	return ret;
+}
+#endif
+
 static const struct file_operations dvb_dvr_fops = {
 	.owner = THIS_MODULE,
 	.read = dvb_dvr_read,
@@ -1194,6 +1381,9 @@ static const struct file_operations dvb_dvr_fops = {
 	.release = dvb_dvr_release,
 	.poll = dvb_dvr_poll,
 	.llseek = default_llseek,
+#ifdef DVB_MMAP
+	.mmap = dvb_dvr_mmap,
+#endif
 };
 
 static const struct dvb_device dvbdev_dvr = {
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
index 3f6c8bd..b462ebc 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
@@ -37,8 +37,8 @@
 #include <linux/sched/signal.h>
 #include <linux/kthread.h>
 
-#include "dvb_ca_en50221.h"
-#include "dvb_ringbuffer.h"
+#include <media/dvb_ca_en50221.h>
+#include <media/dvb_ringbuffer.h>
 
 static int dvb_ca_en50221_debug;
 
@@ -786,7 +786,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
  * @ca: CA instance.
  * @slot: Slot to write to.
  * @buf: The data in this buffer is treated as a complete link-level packet to
- * 	 be written.
+ *	 be written.
  * @bytes_write: Size of ebuf.
  *
  * return: Number of bytes written, or < 0 on error.
@@ -1473,6 +1473,9 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
 		return -EFAULT;
 	buf += 2;
 	count -= 2;
+
+	if (slot >= ca->slot_count)
+		return -EINVAL;
 	sl = &ca->slot_info[slot];
 
 	/* check if the slot is actually running */
diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c
index acade75..210eed0 100644
--- a/drivers/media/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb-core/dvb_demux.c
@@ -30,7 +30,7 @@
 #include <linux/uaccess.h>
 #include <asm/div64.h>
 
-#include "dvb_demux.h"
+#include <media/dvb_demux.h>
 
 static int dvb_demux_tscheck;
 module_param(dvb_demux_tscheck, int, 0644);
@@ -119,7 +119,8 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
 	ccok = ((feed->cc + 1) & 0x0f) == cc;
 	feed->cc = cc;
 	if (!ccok)
-		dprintk("missed packet!\n");
+		dprintk("missed packet: %d instead of %d!\n",
+			cc, (feed->cc + 1) & 0x0f);
 #endif
 
 	if (buf[1] & 0x40)	// PUSI ?
@@ -188,7 +189,7 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
 
 #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
 	if (sec->secbufp < sec->tsfeedp) {
-		int i, n = sec->tsfeedp - sec->secbufp;
+		int n = sec->tsfeedp - sec->secbufp;
 
 		/*
 		 * Section padding is done with 0xff bytes entirely.
@@ -196,12 +197,9 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
 		 * but just first and last.
 		 */
 		if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
-			dprintk("dvb_demux.c section ts padding loss: %d/%d\n",
+			dprintk("section ts padding loss: %d/%d\n",
 			       n, sec->tsfeedp);
-			dprintk("dvb_demux.c pad data:");
-			for (i = 0; i < n; i++)
-				pr_cont(" %02x", sec->secbuf[i]);
-			pr_cont("\n");
+			dprintk("pad data: %*ph\n", n, sec->secbuf);
 		}
 	}
 #endif
@@ -240,9 +238,9 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
 
 	if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
 #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
-		dprintk("dvb_demux.c section buffer full loss: %d/%d\n",
-		       sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
-		       DMX_MAX_SECFEED_SIZE);
+		dprintk("section buffer full loss: %d/%d\n",
+			sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
+			DMX_MAX_SECFEED_SIZE);
 #endif
 		len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
 	}
@@ -275,7 +273,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
 			dvb_dmx_swfilter_section_feed(feed);
 #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
 		else
-			dprintk("dvb_demux.c pusi not seen, discarding section data\n");
+			dprintk("pusi not seen, discarding section data\n");
 #endif
 		sec->secbufp += seclen;	/* secbufp and secbuf moving together is */
 		sec->secbuf += seclen;	/* redundant but saves pointer arithmetic */
@@ -310,8 +308,12 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
 
 	if (!ccok || dc_i) {
 #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
-		dprintk("dvb_demux.c discontinuity detected %d bytes lost\n",
-			count);
+		if (dc_i)
+			dprintk("%d frame with disconnect indicator\n",
+				cc);
+		else
+			dprintk("discontinuity: %d instead of %d. %d bytes lost\n",
+				cc, (feed->cc + 1) & 0x0f, count + 4);
 		/*
 		 * those bytes under sume circumstances will again be reported
 		 * in the following dvb_dmx_swfilter_section_new
@@ -320,6 +322,9 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
 		/*
 		 * Discontinuity detected. Reset pusi_seen to
 		 * stop feeding of suspicious data until next PUSI=1 arrives
+		 *
+		 * FIXME: does it make sense if the MPEG-TS is the one
+		 *	reporting discontinuity?
 		 */
 		feed->pusi_seen = false;
 		dvb_dmx_swfilter_section_new(feed);
@@ -343,8 +348,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
 		}
 #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
 		else if (count > 0)
-			dprintk("dvb_demux.c PUSI=1 but %d bytes lost\n",
-				count);
+			dprintk("PUSI=1 but %d bytes lost\n", count);
 #endif
 	} else {
 		/* PUSI=0 (is not set), no section boundary */
@@ -414,9 +418,10 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
 						1024);
 				speed_timedelta = ktime_ms_delta(cur_time,
 							demux->speed_last_time);
-				dprintk("TS speed %llu Kbits/sec \n",
-					div64_u64(speed_bytes,
-						  speed_timedelta));
+				if (speed_timedelta)
+					dprintk("TS speed %llu Kbits/sec \n",
+						div64_u64(speed_bytes,
+							  speed_timedelta));
 			}
 
 			demux->speed_last_time = cur_time;
@@ -441,8 +446,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
 
 				if ((buf[3] & 0xf) != demux->cnt_storage[pid]) {
 					dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
-						pid, demux->cnt_storage[pid],
-						buf[3] & 0xf);
+							pid, demux->cnt_storage[pid],
+							buf[3] & 0xf);
 					demux->cnt_storage[pid] = buf[3] & 0xf;
 				}
 			}
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 48e16fd..87fc1bc 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -40,10 +40,11 @@
 #include <linux/jiffies.h>
 #include <linux/kthread.h>
 #include <linux/ktime.h>
+#include <linux/compat.h>
 #include <asm/processor.h>
 
-#include "dvb_frontend.h"
-#include "dvbdev.h"
+#include <media/dvb_frontend.h>
+#include <media/dvbdev.h>
 #include <linux/dvb/version.h>
 
 static int dvb_frontend_debug;
@@ -150,8 +151,7 @@ static void __dvb_frontend_free(struct dvb_frontend *fe)
 
 	dvb_frontend_invoke_release(fe, fe->ops.release);
 
-	if (fepriv)
-		kfree(fepriv);
+	kfree(fepriv);
 }
 
 static void dvb_frontend_free(struct kref *ref)
@@ -982,6 +982,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
 	}
 
 	c->stream_id = NO_STREAM_ID_FILTER;
+	c->scrambling_sequence_index = 0;/* default sequence */
 
 	switch (c->delivery_system) {
 	case SYS_DVBS:
@@ -1072,6 +1073,7 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
 
 	_DTV_CMD(DTV_STREAM_ID, 1, 0),
 	_DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0),
+	_DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, 1, 0),
 	_DTV_CMD(DTV_LNA, 1, 0),
 
 	/* Get */
@@ -1417,6 +1419,11 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
 		tvp->u.data = c->stream_id;
 		break;
 
+	/* Physical layer scrambling support */
+	case DTV_SCRAMBLING_SEQUENCE_INDEX:
+		tvp->u.data = c->scrambling_sequence_index;
+		break;
+
 	/* ATSC-MH */
 	case DTV_ATSCMH_FIC_VER:
 		tvp->u.data = fe->dtv_property_cache.atscmh_fic_ver;
@@ -1900,6 +1907,11 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
 		c->stream_id = data;
 		break;
 
+	/* Physical layer scrambling support */
+	case DTV_SCRAMBLING_SEQUENCE_INDEX:
+		c->scrambling_sequence_index = data;
+		break;
+
 	/* ATSC-MH */
 	case DTV_ATSCMH_PARADE_ID:
 		fe->dtv_property_cache.atscmh_parade_id = data;
@@ -1923,7 +1935,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
 	return r;
 }
 
-static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg)
+static int dvb_frontend_do_ioctl(struct file *file, unsigned int cmd,
+				 void *parg)
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend *fe = dvbdev->priv;
@@ -1966,6 +1979,156 @@ static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg)
 	return err;
 }
 
+static long dvb_frontend_ioctl(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	struct dvb_device *dvbdev = file->private_data;
+
+	if (!dvbdev)
+		return -ENODEV;
+
+	return dvb_usercopy(file, cmd, arg, dvb_frontend_do_ioctl);
+}
+
+#ifdef CONFIG_COMPAT
+struct compat_dtv_property {
+	__u32 cmd;
+	__u32 reserved[3];
+	union {
+		__u32 data;
+		struct dtv_fe_stats st;
+		struct {
+			__u8 data[32];
+			__u32 len;
+			__u32 reserved1[3];
+			compat_uptr_t reserved2;
+		} buffer;
+	} u;
+	int result;
+} __attribute__ ((packed));
+
+struct compat_dtv_properties {
+	__u32 num;
+	compat_uptr_t props;
+};
+
+#define COMPAT_FE_SET_PROPERTY	   _IOW('o', 82, struct compat_dtv_properties)
+#define COMPAT_FE_GET_PROPERTY	   _IOR('o', 83, struct compat_dtv_properties)
+
+static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd,
+					    unsigned long arg)
+{
+	struct dvb_device *dvbdev = file->private_data;
+	struct dvb_frontend *fe = dvbdev->priv;
+	struct dvb_frontend_private *fepriv = fe->frontend_priv;
+	int i, err = 0;
+
+	if (cmd == COMPAT_FE_SET_PROPERTY) {
+		struct compat_dtv_properties prop, *tvps = NULL;
+		struct compat_dtv_property *tvp = NULL;
+
+		if (copy_from_user(&prop, compat_ptr(arg), sizeof(prop)))
+			return -EFAULT;
+
+		tvps = &prop;
+
+		/*
+		 * Put an arbitrary limit on the number of messages that can
+		 * be sent at once
+		 */
+		if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
+			return -EINVAL;
+
+		tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp));
+		if (IS_ERR(tvp))
+			return PTR_ERR(tvp);
+
+		for (i = 0; i < tvps->num; i++) {
+			err = dtv_property_process_set(fe, file,
+							(tvp + i)->cmd,
+							(tvp + i)->u.data);
+			if (err < 0) {
+				kfree(tvp);
+				return err;
+			}
+		}
+		kfree(tvp);
+	} else if (cmd == COMPAT_FE_GET_PROPERTY) {
+		struct compat_dtv_properties prop, *tvps = NULL;
+		struct compat_dtv_property *tvp = NULL;
+		struct dtv_frontend_properties getp = fe->dtv_property_cache;
+
+		if (copy_from_user(&prop, compat_ptr(arg), sizeof(prop)))
+			return -EFAULT;
+
+		tvps = &prop;
+
+		/*
+		 * Put an arbitrary limit on the number of messages that can
+		 * be sent at once
+		 */
+		if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
+			return -EINVAL;
+
+		tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp));
+		if (IS_ERR(tvp))
+			return PTR_ERR(tvp);
+
+		/*
+		 * Let's use our own copy of property cache, in order to
+		 * avoid mangling with DTV zigzag logic, as drivers might
+		 * return crap, if they don't check if the data is available
+		 * before updating the properties cache.
+		 */
+		if (fepriv->state != FESTATE_IDLE) {
+			err = dtv_get_frontend(fe, &getp, NULL);
+			if (err < 0) {
+				kfree(tvp);
+				return err;
+			}
+		}
+		for (i = 0; i < tvps->num; i++) {
+			err = dtv_property_process_get(
+			    fe, &getp, (struct dtv_property *)tvp + i, file);
+			if (err < 0) {
+				kfree(tvp);
+				return err;
+			}
+		}
+
+		if (copy_to_user((void __user *)compat_ptr(tvps->props), tvp,
+				 tvps->num * sizeof(struct compat_dtv_property))) {
+			kfree(tvp);
+			return -EFAULT;
+		}
+		kfree(tvp);
+	}
+
+	return err;
+}
+
+static long dvb_frontend_compat_ioctl(struct file *file, unsigned int cmd,
+				      unsigned long arg)
+{
+	struct dvb_device *dvbdev = file->private_data;
+	struct dvb_frontend *fe = dvbdev->priv;
+	struct dvb_frontend_private *fepriv = fe->frontend_priv;
+	int err;
+
+	if (cmd == COMPAT_FE_SET_PROPERTY || cmd == COMPAT_FE_GET_PROPERTY) {
+		if (down_interruptible(&fepriv->sem))
+			return -ERESTARTSYS;
+
+		err = dvb_frontend_handle_compat_ioctl(file, cmd, arg);
+
+		up(&fepriv->sem);
+		return err;
+	}
+
+	return dvb_frontend_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
+
 static int dtv_set_frontend(struct dvb_frontend *fe)
 {
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
@@ -2110,7 +2273,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
 	struct dvb_frontend *fe = dvbdev->priv;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-	int i, err;
+	int i, err = -ENOTSUPP;
 
 	dev_dbg(fe->dvb->device, "%s:\n", __func__);
 
@@ -2145,6 +2308,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
 			}
 		}
 		kfree(tvp);
+		err = 0;
 		break;
 	}
 	case FE_GET_PROPERTY: {
@@ -2196,6 +2360,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
 			return -EFAULT;
 		}
 		kfree(tvp);
+		err = 0;
 		break;
 	}
 
@@ -2647,7 +2812,10 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
 
 static const struct file_operations dvb_frontend_fops = {
 	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= dvb_generic_ioctl,
+	.unlocked_ioctl	= dvb_frontend_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= dvb_frontend_compat_ioctl,
+#endif
 	.poll		= dvb_frontend_poll,
 	.open		= dvb_frontend_open,
 	.release	= dvb_frontend_release,
@@ -2715,7 +2883,6 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
 #if defined(CONFIG_MEDIA_CONTROLLER_DVB)
 		.name = fe->ops.info.name,
 #endif
-		.kernel_ioctl = dvb_frontend_ioctl
 	};
 
 	dev_dbg(dvb->device, "%s:\n", __func__);
diff --git a/drivers/media/dvb-core/dvb_math.c b/drivers/media/dvb-core/dvb_math.c
index a2e1810..dc90564 100644
--- a/drivers/media/dvb-core/dvb_math.c
+++ b/drivers/media/dvb-core/dvb_math.c
@@ -19,7 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <asm/bug.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
 
 static const unsigned short logtable[256] = {
 	0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7,
diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c
index c018e3c..b6c7eec 100644
--- a/drivers/media/dvb-core/dvb_net.c
+++ b/drivers/media/dvb-core/dvb_net.c
@@ -38,7 +38,7 @@
  *                       Competence Center for Advanced Satellite Communications.
  *                     Bugfixes and robustness improvements.
  *                     Filtering on dest MAC addresses, if present (D-Bit = 0)
- *                     ULE_DEBUG compile-time option.
+ *                     DVB_ULE_DEBUG compile-time option.
  * Apr 2006: cp v3:    Bugfixes and compliency with RFC 4326 (ULE) by
  *                       Christian Praehauser <cpraehaus@cosy.sbg.ac.at>,
  *                       Paris Lodron University of Salzburg.
@@ -64,8 +64,8 @@
 #include <linux/mutex.h>
 #include <linux/sched.h>
 
-#include "dvb_demux.h"
-#include "dvb_net.h"
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
 
 static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
 {
@@ -78,15 +78,18 @@ static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
 
 #define DVB_NET_MULTICAST_MAX 10
 
-#undef ULE_DEBUG
-
-#ifdef ULE_DEBUG
+#ifdef DVB_ULE_DEBUG
+/*
+ * The code inside DVB_ULE_DEBUG keeps a history of the
+ * last 100 TS cells processed.
+ */
+static unsigned char ule_hist[100*TS_SZ] = { 0 };
+static unsigned char *ule_where = ule_hist, ule_dump;
 
 static void hexdump(const unsigned char *buf, unsigned short len)
 {
 	print_hex_dump_debug("", DUMP_PREFIX_OFFSET, 16, 1, buf, len, true);
 }
-
 #endif
 
 struct dvb_net_priv {
@@ -280,11 +283,9 @@ static int handle_ule_extensions( struct dvb_net_priv *p )
 		if (l < 0)
 			return l;	/* Stop extension header processing and discard SNDU. */
 		total_ext_len += l;
-#ifdef ULE_DEBUG
 		pr_debug("ule_next_hdr=%p, ule_sndu_type=%i, l=%i, total_ext_len=%i\n",
 			 p->ule_next_hdr, (int)p->ule_sndu_type,
 			 l, total_ext_len);
-#endif
 
 	} while (p->ule_sndu_type < ETH_P_802_3_MIN);
 
@@ -320,29 +321,21 @@ struct dvb_net_ule_handle {
 	const u8 *ts, *ts_end, *from_where;
 	u8 ts_remain, how_much, new_ts;
 	bool error;
-#ifdef ULE_DEBUG
-	/*
-	 * The code inside ULE_DEBUG keeps a history of the
-	 * last 100 TS cells processed.
-	 */
-	static unsigned char ule_hist[100*TS_SZ];
-	static unsigned char *ule_where = ule_hist, ule_dump;
-#endif
 };
 
 static int dvb_net_ule_new_ts_cell(struct dvb_net_ule_handle *h)
 {
 	/* We are about to process a new TS cell. */
 
-#ifdef ULE_DEBUG
-	if (h->ule_where >= &h->ule_hist[100*TS_SZ])
-		h->ule_where = h->ule_hist;
-	memcpy(h->ule_where, h->ts, TS_SZ);
-	if (h->ule_dump) {
-		hexdump(h->ule_where, TS_SZ);
-		h->ule_dump = 0;
+#ifdef DVB_ULE_DEBUG
+	if (ule_where >= &ule_hist[100*TS_SZ])
+		ule_where = ule_hist;
+	memcpy(ule_where, h->ts, TS_SZ);
+	if (ule_dump) {
+		hexdump(ule_where, TS_SZ);
+		ule_dump = 0;
 	}
-	h->ule_where += TS_SZ;
+	ule_where += TS_SZ;
 #endif
 
 	/*
@@ -660,6 +653,7 @@ static int dvb_net_ule_should_drop(struct dvb_net_ule_handle *h)
 
 
 static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
+				  struct kvec iov[3],
 				  u32 ule_crc, u32 expected_crc)
 {
 	u8 dest_addr[ETH_ALEN];
@@ -672,22 +666,22 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
 			h->ts_remain > 2 ?
 				*(unsigned short *)h->from_where : 0);
 
-	#ifdef ULE_DEBUG
+	#ifdef DVB_ULE_DEBUG
 		hexdump(iov[0].iov_base, iov[0].iov_len);
 		hexdump(iov[1].iov_base, iov[1].iov_len);
 		hexdump(iov[2].iov_base, iov[2].iov_len);
 
-		if (h->ule_where == h->ule_hist) {
-			hexdump(&h->ule_hist[98*TS_SZ], TS_SZ);
-			hexdump(&h->ule_hist[99*TS_SZ], TS_SZ);
-		} else if (h->ule_where == &h->ule_hist[TS_SZ]) {
-			hexdump(&h->ule_hist[99*TS_SZ], TS_SZ);
-			hexdump(h->ule_hist, TS_SZ);
+		if (ule_where == ule_hist) {
+			hexdump(&ule_hist[98*TS_SZ], TS_SZ);
+			hexdump(&ule_hist[99*TS_SZ], TS_SZ);
+		} else if (ule_where == &ule_hist[TS_SZ]) {
+			hexdump(&ule_hist[99*TS_SZ], TS_SZ);
+			hexdump(ule_hist, TS_SZ);
 		} else {
-			hexdump(h->ule_where - TS_SZ - TS_SZ, TS_SZ);
-			hexdump(h->ule_where - TS_SZ, TS_SZ);
+			hexdump(ule_where - TS_SZ - TS_SZ, TS_SZ);
+			hexdump(ule_where - TS_SZ, TS_SZ);
 		}
-		h->ule_dump = 1;
+		ule_dump = 1;
 	#endif
 
 		h->dev->stats.rx_errors++;
@@ -705,11 +699,9 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
 
 	if (!h->priv->ule_dbit) {
 		if (dvb_net_ule_should_drop(h)) {
-#ifdef ULE_DEBUG
 			netdev_dbg(h->dev,
 				   "Dropping SNDU: MAC destination address does not match: dest addr: %pM, h->dev addr: %pM\n",
 				   h->priv->ule_skb->data, h->dev->dev_addr);
-#endif
 			dev_kfree_skb(h->priv->ule_skb);
 			return;
 		}
@@ -779,6 +771,8 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
 	int ret;
 	struct dvb_net_ule_handle h = {
 		.dev = dev,
+		.priv = netdev_priv(dev),
+		.ethh = NULL,
 		.buf = buf,
 		.buf_len = buf_len,
 		.skipped = 0L,
@@ -788,11 +782,7 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
 		.ts_remain = 0,
 		.how_much = 0,
 		.new_ts = 1,
-		.ethh = NULL,
 		.error = false,
-#ifdef ULE_DEBUG
-		.ule_where = ule_hist,
-#endif
 	};
 
 	/*
@@ -860,7 +850,7 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
 				       *(tail - 2) << 8 |
 				       *(tail - 1);
 
-			dvb_net_ule_check_crc(&h, ule_crc, expected_crc);
+			dvb_net_ule_check_crc(&h, iov, ule_crc, expected_crc);
 
 			/* Prepare for next SNDU. */
 			reset_ule(h.priv);
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb-core/dvb_ringbuffer.c
index 5301162..4330b6f 100644
--- a/drivers/media/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb-core/dvb_ringbuffer.c
@@ -29,7 +29,7 @@
 #include <linux/string.h>
 #include <linux/uaccess.h>
 
-#include "dvb_ringbuffer.h"
+#include <media/dvb_ringbuffer.h>
 
 #define PKT_READY 0
 #define PKT_DISPOSED 1
diff --git a/drivers/media/dvb-core/dvb_vb2.c b/drivers/media/dvb-core/dvb_vb2.c
new file mode 100644
index 0000000..763145d
--- /dev/null
+++ b/drivers/media/dvb-core/dvb_vb2.c
@@ -0,0 +1,430 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dvb-vb2.c - dvb-vb2
+ *
+ * Copyright (C) 2015 Samsung Electronics
+ *
+ * Author: jh1009.sung@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+
+#include <media/dvbdev.h>
+#include <media/dvb_vb2.h>
+
+#define DVB_V2_MAX_SIZE		(4096 * 188)
+
+static int vb2_debug;
+module_param(vb2_debug, int, 0644);
+
+#define dprintk(level, fmt, arg...)					      \
+	do {								      \
+		if (vb2_debug >= level)					      \
+			pr_info("vb2: %s: " fmt, __func__, ## arg); \
+	} while (0)
+
+static int _queue_setup(struct vb2_queue *vq,
+			unsigned int *nbuffers, unsigned int *nplanes,
+			unsigned int sizes[], struct device *alloc_devs[])
+{
+	struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
+
+	ctx->buf_cnt = *nbuffers;
+	*nplanes = 1;
+	sizes[0] = ctx->buf_siz;
+
+	/*
+	 * videobuf2-vmalloc allocator is context-less so no need to set
+	 * alloc_ctxs array.
+	 */
+
+	dprintk(3, "[%s] count=%d, size=%d\n", ctx->name,
+		*nbuffers, sizes[0]);
+
+	return 0;
+}
+
+static int _buffer_prepare(struct vb2_buffer *vb)
+{
+	struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned long size = ctx->buf_siz;
+
+	if (vb2_plane_size(vb, 0) < size) {
+		dprintk(1, "[%s] data will not fit into plane (%lu < %lu)\n",
+			ctx->name, vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+
+	vb2_set_plane_payload(vb, 0, size);
+	dprintk(3, "[%s]\n", ctx->name);
+
+	return 0;
+}
+
+static void _buffer_queue(struct vb2_buffer *vb)
+{
+	struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	struct dvb_buffer *buf = container_of(vb, struct dvb_buffer, vb);
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&ctx->slock, flags);
+	list_add_tail(&buf->list, &ctx->dvb_q);
+	spin_unlock_irqrestore(&ctx->slock, flags);
+
+	dprintk(3, "[%s]\n", ctx->name);
+}
+
+static int _start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
+
+	dprintk(3, "[%s] count=%d\n", ctx->name, count);
+	return 0;
+}
+
+static void _stop_streaming(struct vb2_queue *vq)
+{
+	struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
+	struct dvb_buffer *buf;
+	unsigned long flags = 0;
+
+	dprintk(3, "[%s]\n", ctx->name);
+
+	spin_lock_irqsave(&ctx->slock, flags);
+	while (!list_empty(&ctx->dvb_q)) {
+		buf = list_entry(ctx->dvb_q.next,
+				 struct dvb_buffer, list);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+		list_del(&buf->list);
+	}
+	spin_unlock_irqrestore(&ctx->slock, flags);
+}
+
+static void _dmxdev_lock(struct vb2_queue *vq)
+{
+	struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
+
+	mutex_lock(&ctx->mutex);
+	dprintk(3, "[%s]\n", ctx->name);
+}
+
+static void _dmxdev_unlock(struct vb2_queue *vq)
+{
+	struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
+
+	if (mutex_is_locked(&ctx->mutex))
+		mutex_unlock(&ctx->mutex);
+	dprintk(3, "[%s]\n", ctx->name);
+}
+
+static const struct vb2_ops dvb_vb2_qops = {
+	.queue_setup		= _queue_setup,
+	.buf_prepare		= _buffer_prepare,
+	.buf_queue		= _buffer_queue,
+	.start_streaming	= _start_streaming,
+	.stop_streaming		= _stop_streaming,
+	.wait_prepare		= _dmxdev_unlock,
+	.wait_finish		= _dmxdev_lock,
+};
+
+static void _fill_dmx_buffer(struct vb2_buffer *vb, void *pb)
+{
+	struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+	struct dmx_buffer *b = pb;
+
+	b->index = vb->index;
+	b->length = vb->planes[0].length;
+	b->bytesused = vb->planes[0].bytesused;
+	b->offset = vb->planes[0].m.offset;
+	dprintk(3, "[%s]\n", ctx->name);
+}
+
+static int _fill_vb2_buffer(struct vb2_buffer *vb,
+			    const void *pb, struct vb2_plane *planes)
+{
+	struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+	planes[0].bytesused = 0;
+	dprintk(3, "[%s]\n", ctx->name);
+
+	return 0;
+}
+
+static const struct vb2_buf_ops dvb_vb2_buf_ops = {
+	.fill_user_buffer	= _fill_dmx_buffer,
+	.fill_vb2_buffer	= _fill_vb2_buffer,
+};
+
+/*
+ * Videobuf operations
+ */
+int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking)
+{
+	struct vb2_queue *q = &ctx->vb_q;
+	int ret;
+
+	memset(ctx, 0, sizeof(struct dvb_vb2_ctx));
+	q->type = DVB_BUF_TYPE_CAPTURE;
+	/**capture type*/
+	q->is_output = 0;
+	/**only mmap is supported currently*/
+	q->io_modes = VB2_MMAP;
+	q->drv_priv = ctx;
+	q->buf_struct_size = sizeof(struct dvb_buffer);
+	q->min_buffers_needed = 1;
+	q->ops = &dvb_vb2_qops;
+	q->mem_ops = &vb2_vmalloc_memops;
+	q->buf_ops = &dvb_vb2_buf_ops;
+	q->num_buffers = 0;
+	ret = vb2_core_queue_init(q);
+	if (ret) {
+		ctx->state = DVB_VB2_STATE_NONE;
+		dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+		return ret;
+	}
+
+	mutex_init(&ctx->mutex);
+	spin_lock_init(&ctx->slock);
+	INIT_LIST_HEAD(&ctx->dvb_q);
+
+	strlcpy(ctx->name, name, DVB_VB2_NAME_MAX);
+	ctx->nonblocking = nonblocking;
+	ctx->state = DVB_VB2_STATE_INIT;
+
+	dprintk(3, "[%s]\n", ctx->name);
+
+	return 0;
+}
+
+int dvb_vb2_release(struct dvb_vb2_ctx *ctx)
+{
+	struct vb2_queue *q = (struct vb2_queue *)&ctx->vb_q;
+
+	if (ctx->state & DVB_VB2_STATE_INIT)
+		vb2_core_queue_release(q);
+
+	ctx->state = DVB_VB2_STATE_NONE;
+	dprintk(3, "[%s]\n", ctx->name);
+
+	return 0;
+}
+
+int dvb_vb2_stream_on(struct dvb_vb2_ctx *ctx)
+{
+	struct vb2_queue *q = &ctx->vb_q;
+	int ret;
+
+	ret = vb2_core_streamon(q, q->type);
+	if (ret) {
+		ctx->state = DVB_VB2_STATE_NONE;
+		dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+		return ret;
+	}
+	ctx->state |= DVB_VB2_STATE_STREAMON;
+	dprintk(3, "[%s]\n", ctx->name);
+
+	return 0;
+}
+
+int dvb_vb2_stream_off(struct dvb_vb2_ctx *ctx)
+{
+	struct vb2_queue *q = (struct vb2_queue *)&ctx->vb_q;
+	int ret;
+
+	ctx->state &= ~DVB_VB2_STATE_STREAMON;
+	ret = vb2_core_streamoff(q, q->type);
+	if (ret) {
+		ctx->state = DVB_VB2_STATE_NONE;
+		dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+		return ret;
+	}
+	dprintk(3, "[%s]\n", ctx->name);
+
+	return 0;
+}
+
+int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx)
+{
+	return (ctx->state & DVB_VB2_STATE_STREAMON);
+}
+
+int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
+			const unsigned char *src, int len)
+{
+	unsigned long flags = 0;
+	void *vbuf = NULL;
+	int todo = len;
+	unsigned char *psrc = (unsigned char *)src;
+	int ll = 0;
+
+	dprintk(3, "[%s] %d bytes are rcvd\n", ctx->name, len);
+	if (!src) {
+		dprintk(3, "[%s]:NULL pointer src\n", ctx->name);
+		/**normal case: This func is called twice from demux driver
+		 * once with valid src pointer, second time with NULL pointer
+		 */
+		return 0;
+	}
+	spin_lock_irqsave(&ctx->slock, flags);
+	while (todo) {
+		if (!ctx->buf) {
+			if (list_empty(&ctx->dvb_q)) {
+				dprintk(3, "[%s] Buffer overflow!!!\n",
+					ctx->name);
+				break;
+			}
+
+			ctx->buf = list_entry(ctx->dvb_q.next,
+					      struct dvb_buffer, list);
+			ctx->remain = vb2_plane_size(&ctx->buf->vb, 0);
+			ctx->offset = 0;
+		}
+
+		if (!dvb_vb2_is_streaming(ctx)) {
+			vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_ERROR);
+			list_del(&ctx->buf->list);
+			ctx->buf = NULL;
+			break;
+		}
+
+		/* Fill buffer */
+		ll = min(todo, ctx->remain);
+		vbuf = vb2_plane_vaddr(&ctx->buf->vb, 0);
+		memcpy(vbuf + ctx->offset, psrc, ll);
+		todo -= ll;
+		psrc += ll;
+
+		ctx->remain -= ll;
+		ctx->offset += ll;
+
+		if (ctx->remain == 0) {
+			vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_DONE);
+			list_del(&ctx->buf->list);
+			ctx->buf = NULL;
+		}
+	}
+
+	if (ctx->nonblocking && ctx->buf) {
+		vb2_set_plane_payload(&ctx->buf->vb, 0, ll);
+		vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_DONE);
+		list_del(&ctx->buf->list);
+		ctx->buf = NULL;
+	}
+	spin_unlock_irqrestore(&ctx->slock, flags);
+
+	if (todo)
+		dprintk(1, "[%s] %d bytes are dropped.\n", ctx->name, todo);
+	else
+		dprintk(3, "[%s]\n", ctx->name);
+
+	dprintk(3, "[%s] %d bytes are copied\n", ctx->name, len - todo);
+	return (len - todo);
+}
+
+int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req)
+{
+	int ret;
+
+	/* Adjust size to a sane value */
+	if (req->size > DVB_V2_MAX_SIZE)
+		req->size = DVB_V2_MAX_SIZE;
+
+	/* FIXME: round req->size to a 188 or 204 multiple */
+
+	ctx->buf_siz = req->size;
+	ctx->buf_cnt = req->count;
+	ret = vb2_core_reqbufs(&ctx->vb_q, VB2_MEMORY_MMAP, &req->count);
+	if (ret) {
+		ctx->state = DVB_VB2_STATE_NONE;
+		dprintk(1, "[%s] count=%d size=%d errno=%d\n", ctx->name,
+			ctx->buf_cnt, ctx->buf_siz, ret);
+		return ret;
+	}
+	ctx->state |= DVB_VB2_STATE_REQBUFS;
+	dprintk(3, "[%s] count=%d size=%d\n", ctx->name,
+		ctx->buf_cnt, ctx->buf_siz);
+
+	return 0;
+}
+
+int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
+{
+	vb2_core_querybuf(&ctx->vb_q, b->index, b);
+	dprintk(3, "[%s] index=%d\n", ctx->name, b->index);
+	return 0;
+}
+
+int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp)
+{
+	struct vb2_queue *q = &ctx->vb_q;
+	int ret;
+
+	ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, exp->index,
+			      0, exp->flags);
+	if (ret) {
+		dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
+			exp->index, ret);
+		return ret;
+	}
+	dprintk(3, "[%s] index=%d fd=%d\n", ctx->name, exp->index, exp->fd);
+
+	return 0;
+}
+
+int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
+{
+	int ret;
+
+	ret = vb2_core_qbuf(&ctx->vb_q, b->index, b);
+	if (ret) {
+		dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
+			b->index, ret);
+		return ret;
+	}
+	dprintk(5, "[%s] index=%d\n", ctx->name, b->index);
+
+	return 0;
+}
+
+int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
+{
+	int ret;
+
+	ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking);
+	if (ret) {
+		dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+		return ret;
+	}
+	dprintk(5, "[%s] index=%d\n", ctx->name, b->index);
+
+	return 0;
+}
+
+int dvb_vb2_mmap(struct dvb_vb2_ctx *ctx, struct vm_area_struct *vma)
+{
+	int ret;
+
+	ret = vb2_mmap(&ctx->vb_q, vma);
+	if (ret) {
+		dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+		return ret;
+	}
+	dprintk(3, "[%s] ret=%d\n", ctx->name, ret);
+
+	return 0;
+}
+
+__poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file,
+		      poll_table *wait)
+{
+	dprintk(3, "[%s]\n", ctx->name);
+	return vb2_core_poll(&ctx->vb_q, file, wait);
+}
+
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 060c60d..60e9c2b 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -30,7 +30,7 @@
 #include <linux/fs.h>
 #include <linux/cdev.h>
 #include <linux/mutex.h>
-#include "dvbdev.h"
+#include <media/dvbdev.h>
 
 /* Due to enum tuner_pad_index */
 #include <media/tuner.h>
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index d025eb3..4be59fe 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -3,7 +3,6 @@
 # Makefile for the kernel DVB frontend device drivers.
 #
 
-ccflags-y += -I$(srctree)/drivers/media/dvb-core/
 ccflags-y += -I$(srctree)/drivers/media/tuners/
 
 # FIXME: RTL2832 SDR driver uses power management directly from USB IF driver
diff --git a/drivers/media/dvb-frontends/a8293.h b/drivers/media/dvb-frontends/a8293.h
index 7b90a03..bc6f74f 100644
--- a/drivers/media/dvb-frontends/a8293.h
+++ b/drivers/media/dvb-frontends/a8293.h
@@ -17,7 +17,7 @@
 #ifndef A8293_H
 #define A8293_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /*
  * I2C address
diff --git a/drivers/media/dvb-frontends/af9013_priv.h b/drivers/media/dvb-frontends/af9013_priv.h
index 35ca5c9..688fc34 100644
--- a/drivers/media/dvb-frontends/af9013_priv.h
+++ b/drivers/media/dvb-frontends/af9013_priv.h
@@ -21,7 +21,7 @@
 #ifndef AF9013_PRIV_H
 #define AF9013_PRIV_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "af9013.h"
 #include <linux/firmware.h>
 #include <linux/math64.h>
diff --git a/drivers/media/dvb-frontends/af9033_priv.h b/drivers/media/dvb-frontends/af9033_priv.h
index 8799cda..f269abf 100644
--- a/drivers/media/dvb-frontends/af9033_priv.h
+++ b/drivers/media/dvb-frontends/af9033_priv.h
@@ -18,12 +18,12 @@
 #ifndef AF9033_PRIV_H
 #define AF9033_PRIV_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "af9033.h"
 #include <linux/math64.h>
 #include <linux/regmap.h>
 #include <linux/kernel.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
 
 struct reg_val {
 	u32 reg;
diff --git a/drivers/media/dvb-frontends/as102_fe.c b/drivers/media/dvb-frontends/as102_fe.c
index b1c84ee..9b2f2da 100644
--- a/drivers/media/dvb-frontends/as102_fe.c
+++ b/drivers/media/dvb-frontends/as102_fe.c
@@ -14,7 +14,7 @@
  * GNU General Public License for more details.
  */
 
-#include <dvb_frontend.h>
+#include <media/dvb_frontend.h>
 
 #include "as102_fe.h"
 
diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c
index 0ee0df5..9746c6d 100644
--- a/drivers/media/dvb-frontends/ascot2e.c
+++ b/drivers/media/dvb-frontends/ascot2e.c
@@ -24,7 +24,7 @@
 #include <linux/dvb/frontend.h>
 #include <linux/types.h>
 #include "ascot2e.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #define MAX_WRITE_REGSIZE 10
 
@@ -155,7 +155,9 @@ static int ascot2e_write_regs(struct ascot2e_priv *priv,
 
 static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val)
 {
-	return ascot2e_write_regs(priv, reg, &val, 1);
+	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+	return ascot2e_write_regs(priv, reg, &tmp, 1);
 }
 
 static int ascot2e_read_regs(struct ascot2e_priv *priv,
diff --git a/drivers/media/dvb-frontends/atbm8830.c b/drivers/media/dvb-frontends/atbm8830.c
index 05850b3..7b0f323 100644
--- a/drivers/media/dvb-frontends/atbm8830.c
+++ b/drivers/media/dvb-frontends/atbm8830.c
@@ -16,7 +16,7 @@
  */
 
 #include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "atbm8830.h"
 #include "atbm8830_priv.h"
diff --git a/drivers/media/dvb-frontends/au8522_common.c b/drivers/media/dvb-frontends/au8522_common.c
index 6722838..56605de 100644
--- a/drivers/media/dvb-frontends/au8522_common.c
+++ b/drivers/media/dvb-frontends/au8522_common.c
@@ -23,7 +23,7 @@
 */
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "au8522_priv.h"
 
 static int debug;
diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
index 3f3635f..8f659bd 100644
--- a/drivers/media/dvb-frontends/au8522_dig.c
+++ b/drivers/media/dvb-frontends/au8522_dig.c
@@ -24,7 +24,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "au8522.h"
 #include "au8522_priv.h"
 
diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h
index f5a9438..2043c17 100644
--- a/drivers/media/dvb-frontends/au8522_priv.h
+++ b/drivers/media/dvb-frontends/au8522_priv.h
@@ -32,7 +32,7 @@
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-mc.h>
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "au8522.h"
 #include "tuner-i2c.h"
 
@@ -99,7 +99,7 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H		0x0A5
 #define AU8522_AGC_CONTROL_RANGE_REG0A6H		0x0A6
 #define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H		0x0A7
-#define AU8522_TUNER_AGC_RF_STOP_REG0A8H  		0x0A8
+#define AU8522_TUNER_AGC_RF_STOP_REG0A8H		0x0A8
 #define AU8522_TUNER_AGC_RF_START_REG0A9H		0x0A9
 #define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH		0x0AA
 #define AU8522_TUNER_AGC_IF_STOP_REG0ABH		0x0AB
@@ -110,18 +110,18 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
 
 /* Receiver registers */
 #define AU8522_FRMREGTHRD1_REG0B0H			0x0B0
-#define AU8522_FRMREGAGC1H_REG0B1H 			0x0B1
-#define AU8522_FRMREGSHIFT1_REG0B2H 			0x0B2
-#define AU8522_TOREGAGC1_REG0B3H 			0x0B3
-#define AU8522_TOREGASHIFT1_REG0B4H 			0x0B4
+#define AU8522_FRMREGAGC1H_REG0B1H			0x0B1
+#define AU8522_FRMREGSHIFT1_REG0B2H			0x0B2
+#define AU8522_TOREGAGC1_REG0B3H			0x0B3
+#define AU8522_TOREGASHIFT1_REG0B4H			0x0B4
 #define AU8522_FRMREGBBH_REG0B5H			0x0B5
-#define AU8522_FRMREGBBM_REG0B6H 			0x0B6
-#define AU8522_FRMREGBBL_REG0B7H     			0x0B7
+#define AU8522_FRMREGBBM_REG0B6H			0x0B6
+#define AU8522_FRMREGBBL_REG0B7H			0x0B7
 /* 0xB8 TO 0xD7 are the filter coefficients */
-#define AU8522_FRMREGTHRD2_REG0D8H 			0x0D8
-#define AU8522_FRMREGAGC2H_REG0D9H 			0x0D9
-#define AU8522_TOREGAGC2_REG0DAH 			0x0DA
-#define AU8522_TOREGSHIFT2_REG0DBH 			0x0DB
+#define AU8522_FRMREGTHRD2_REG0D8H			0x0D8
+#define AU8522_FRMREGAGC2H_REG0D9H			0x0D9
+#define AU8522_TOREGAGC2_REG0DAH			0x0DA
+#define AU8522_TOREGSHIFT2_REG0DBH			0x0DB
 #define AU8522_FRMREGPILOTH_REG0DCH			0x0DC
 #define AU8522_FRMREGPILOTM_REG0DDH			0x0DD
 #define AU8522_FRMREGPILOTL_REG0DEH			0x0DE
@@ -134,9 +134,9 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
 #define AU8522_CHIP_MODE_REG0FEH			0x0FE
 
 /* I2C bus control registers */
-#define AU8522_I2C_CONTROL_REG0_REG090H    		0x090
-#define AU8522_I2C_CONTROL_REG1_REG091H    		0x091
-#define AU8522_I2C_STATUS_REG092H          		0x092
+#define AU8522_I2C_CONTROL_REG0_REG090H			0x090
+#define AU8522_I2C_CONTROL_REG1_REG091H			0x091
+#define AU8522_I2C_STATUS_REG092H			0x092
 #define AU8522_I2C_WR_DATA0_REG093H			0x093
 #define AU8522_I2C_WR_DATA1_REG094H			0x094
 #define AU8522_I2C_WR_DATA2_REG095H			0x095
@@ -156,48 +156,48 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
 
 #define AU8522_ENA_USB_REG101H				0x101
 
-#define AU8522_I2S_CTRL_0_REG110H  			0x110
-#define AU8522_I2S_CTRL_1_REG111H 			0x111
-#define AU8522_I2S_CTRL_2_REG112H 			0x112
+#define AU8522_I2S_CTRL_0_REG110H			0x110
+#define AU8522_I2S_CTRL_1_REG111H			0x111
+#define AU8522_I2S_CTRL_2_REG112H			0x112
 
-#define AU8522_FRMREGFFECONTROL_REG121H    		0x121
-#define AU8522_FRMREGDFECONTROL_REG122H    		0x122
+#define AU8522_FRMREGFFECONTROL_REG121H			0x121
+#define AU8522_FRMREGDFECONTROL_REG122H			0x122
 
-#define AU8522_CARRFREQOFFSET0_REG201H 			0x201
+#define AU8522_CARRFREQOFFSET0_REG201H			0x201
 #define AU8522_CARRFREQOFFSET1_REG202H			0x202
 
 #define AU8522_DECIMATION_GAIN_REG21AH			0x21A
-#define AU8522_FRMREGIFSLP_REG21BH 			0x21B
-#define AU8522_FRMREGTHRDL2_REG21CH 			0x21C
-#define AU8522_FRMREGSTEP3DB_REG21DH 			0x21D
+#define AU8522_FRMREGIFSLP_REG21BH			0x21B
+#define AU8522_FRMREGTHRDL2_REG21CH			0x21C
+#define AU8522_FRMREGSTEP3DB_REG21DH			0x21D
 #define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH		0x21E
-#define AU8522_FRMREGPLLMODE_REG21FH 			0x21F
-#define AU8522_FRMREGCSTHRD_REG220H 			0x220
-#define AU8522_FRMREGCRLOCKDMAX_REG221H 		0x221
-#define AU8522_FRMREGCRPERIODMASK_REG222H 		0x222
-#define AU8522_FRMREGCRLOCK0THH_REG223H 		0x223
-#define AU8522_FRMREGCRLOCK1THH_REG224H 		0x224
-#define AU8522_FRMREGCRLOCK0THL_REG225H 		0x225
-#define AU8522_FRMREGCRLOCK1THL_REG226H 		0x226
+#define AU8522_FRMREGPLLMODE_REG21FH			0x21F
+#define AU8522_FRMREGCSTHRD_REG220H			0x220
+#define AU8522_FRMREGCRLOCKDMAX_REG221H			0x221
+#define AU8522_FRMREGCRPERIODMASK_REG222H		0x222
+#define AU8522_FRMREGCRLOCK0THH_REG223H			0x223
+#define AU8522_FRMREGCRLOCK1THH_REG224H			0x224
+#define AU8522_FRMREGCRLOCK0THL_REG225H			0x225
+#define AU8522_FRMREGCRLOCK1THL_REG226H			0x226
 #define AU_FRMREGPLLACQPHASESCL_REG227H			0x227
-#define AU8522_FRMREGFREQFBCTRL_REG228H 		0x228
+#define AU8522_FRMREGFREQFBCTRL_REG228H			0x228
 
 /* Analog TV Decoder */
 #define AU8522_TVDEC_STATUS_REG000H			0x000
 #define AU8522_TVDEC_INT_STATUS_REG001H			0x001
-#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 	0x002
+#define AU8522_TVDEC_MACROVISION_STATUS_REG002H		0x002
 #define AU8522_TVDEC_SHARPNESSREG009H			0x009
 #define AU8522_TVDEC_BRIGHTNESS_REG00AH			0x00A
 #define AU8522_TVDEC_CONTRAST_REG00BH			0x00B
 #define AU8522_TVDEC_SATURATION_CB_REG00CH		0x00C
 #define AU8522_TVDEC_SATURATION_CR_REG00DH		0x00D
 #define AU8522_TVDEC_HUE_H_REG00EH			0x00E
-#define AU8522_TVDEC_HUE_L_REG00FH                   	0x00F
+#define AU8522_TVDEC_HUE_L_REG00FH			0x00F
 #define AU8522_TVDEC_INT_MASK_REG010H			0x010
 #define AU8522_VIDEO_MODE_REG011H			0x011
 #define AU8522_TVDEC_PGA_REG012H			0x012
 #define AU8522_TVDEC_COMB_MODE_REG015H			0x015
-#define AU8522_REG016H                            	0x016
+#define AU8522_REG016H					0x016
 #define AU8522_TVDED_DBG_MODE_REG060H			0x060
 #define AU8522_TVDEC_FORMAT_CTRL1_REG061H		0x061
 #define AU8522_TVDEC_FORMAT_CTRL2_REG062H		0x062
@@ -207,13 +207,13 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
 #define AU8522_TVDEC_COMB_VDIF_THR2_REG066H		0x066
 #define AU8522_TVDEC_COMB_VDIF_THR3_REG067H		0x067
 #define AU8522_TVDEC_COMB_NOTCH_THR_REG068H		0x068
-#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H   		0x069
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H		0x069
 #define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH		0x06A
-#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH   		0x06B
-#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH  		0x06C
-#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 		0x06D
-#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH       	0x06E
-#define AU8522_TVDEC_UV_SEP_THR_REG06FH  		0x06F
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH		0x06B
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH		0x06C
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH		0x06D
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH		0x06E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH			0x06F
 #define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H		0x070
 #define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H		0x073
 #define AU8522_TVDEC_DCAGC_CTRL_REG077H			0x077
@@ -229,42 +229,42 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
 
 #define AU8522_TVDEC_CHROMA_AGC_REG401H		0x401
 #define AU8522_TVDEC_CHROMA_SFT_REG402H		0x402
-#define AU8522_FILTER_COEF_R410     		0x410
-#define AU8522_FILTER_COEF_R411     		0x411
-#define AU8522_FILTER_COEF_R412     		0x412
-#define AU8522_FILTER_COEF_R413     		0x413
-#define AU8522_FILTER_COEF_R414     		0x414
-#define AU8522_FILTER_COEF_R415     		0x415
-#define AU8522_FILTER_COEF_R416     		0x416
-#define AU8522_FILTER_COEF_R417     		0x417
-#define AU8522_FILTER_COEF_R418     		0x418
-#define AU8522_FILTER_COEF_R419     		0x419
-#define AU8522_FILTER_COEF_R41A     		0x41A
-#define AU8522_FILTER_COEF_R41B     		0x41B
-#define AU8522_FILTER_COEF_R41C     		0x41C
-#define AU8522_FILTER_COEF_R41D     		0x41D
-#define AU8522_FILTER_COEF_R41E     		0x41E
-#define AU8522_FILTER_COEF_R41F     		0x41F
-#define AU8522_FILTER_COEF_R420     		0x420
-#define AU8522_FILTER_COEF_R421     		0x421
-#define AU8522_FILTER_COEF_R422     		0x422
-#define AU8522_FILTER_COEF_R423     		0x423
-#define AU8522_FILTER_COEF_R424     		0x424
-#define AU8522_FILTER_COEF_R425     		0x425
-#define AU8522_FILTER_COEF_R426     		0x426
-#define AU8522_FILTER_COEF_R427     		0x427
-#define AU8522_FILTER_COEF_R428     		0x428
-#define AU8522_FILTER_COEF_R429     		0x429
-#define AU8522_FILTER_COEF_R42A     		0x42A
-#define AU8522_FILTER_COEF_R42B     		0x42B
-#define AU8522_FILTER_COEF_R42C     		0x42C
-#define AU8522_FILTER_COEF_R42D     		0x42D
+#define AU8522_FILTER_COEF_R410			0x410
+#define AU8522_FILTER_COEF_R411			0x411
+#define AU8522_FILTER_COEF_R412			0x412
+#define AU8522_FILTER_COEF_R413			0x413
+#define AU8522_FILTER_COEF_R414			0x414
+#define AU8522_FILTER_COEF_R415			0x415
+#define AU8522_FILTER_COEF_R416			0x416
+#define AU8522_FILTER_COEF_R417			0x417
+#define AU8522_FILTER_COEF_R418			0x418
+#define AU8522_FILTER_COEF_R419			0x419
+#define AU8522_FILTER_COEF_R41A			0x41A
+#define AU8522_FILTER_COEF_R41B			0x41B
+#define AU8522_FILTER_COEF_R41C			0x41C
+#define AU8522_FILTER_COEF_R41D			0x41D
+#define AU8522_FILTER_COEF_R41E			0x41E
+#define AU8522_FILTER_COEF_R41F			0x41F
+#define AU8522_FILTER_COEF_R420			0x420
+#define AU8522_FILTER_COEF_R421			0x421
+#define AU8522_FILTER_COEF_R422			0x422
+#define AU8522_FILTER_COEF_R423			0x423
+#define AU8522_FILTER_COEF_R424			0x424
+#define AU8522_FILTER_COEF_R425			0x425
+#define AU8522_FILTER_COEF_R426			0x426
+#define AU8522_FILTER_COEF_R427			0x427
+#define AU8522_FILTER_COEF_R428			0x428
+#define AU8522_FILTER_COEF_R429			0x429
+#define AU8522_FILTER_COEF_R42A			0x42A
+#define AU8522_FILTER_COEF_R42B			0x42B
+#define AU8522_FILTER_COEF_R42C			0x42C
+#define AU8522_FILTER_COEF_R42D			0x42D
 
 /* VBI Control Registers */
-#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H  	0x004
-#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H  	0x005
-#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H      	0x006
-#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H       	0x007
+#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H	0x004
+#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H	0x005
+#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H		0x006
+#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H		0x007
 #define AU8522_TVDEC_VBI_CTRL_H_REG017H			0x017
 #define AU8522_TVDEC_VBI_CTRL_L_REG018H			0x018
 #define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H	0x019
@@ -272,10 +272,10 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
 #define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH		0x01B
 #define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH		0x01C
 #define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH	0x01E
-#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH   	0x01F
-#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H   	0x020
-#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 	0x021
-#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H  	0x022
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH	0x01F
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H	0x020
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H	0x021
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H	0x022
 #define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H	0x023
 
 #define AU8522_REG071H					0x071
@@ -315,17 +315,17 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
 #define AU8522_GPIO_DATA_REG0E2H			0x0E2
 
 /* Audio Control Registers */
-#define AU8522_AUDIOAGC_REG0EEH 			0x0EE
-#define AU8522_AUDIO_STATUS_REG0F0H 			0x0F0
-#define AU8522_AUDIO_MODE_REG0F1H 			0x0F1
-#define AU8522_AUDIO_VOLUME_L_REG0F2H 			0x0F2
-#define AU8522_AUDIO_VOLUME_R_REG0F3H 			0x0F3
-#define AU8522_AUDIO_VOLUME_REG0F4H 			0x0F4
-#define AU8522_FRMREGAUPHASE_REG0F7H 			0x0F7
+#define AU8522_AUDIOAGC_REG0EEH				0x0EE
+#define AU8522_AUDIO_STATUS_REG0F0H			0x0F0
+#define AU8522_AUDIO_MODE_REG0F1H			0x0F1
+#define AU8522_AUDIO_VOLUME_L_REG0F2H			0x0F2
+#define AU8522_AUDIO_VOLUME_R_REG0F3H			0x0F3
+#define AU8522_AUDIO_VOLUME_REG0F4H			0x0F4
+#define AU8522_FRMREGAUPHASE_REG0F7H			0x0F7
 #define AU8522_REG0F9H					0x0F9
 
-#define AU8522_AUDIOAGC2_REG605H 			0x605
-#define AU8522_AUDIOFREQ_REG606H 			0x606
+#define AU8522_AUDIOAGC2_REG605H			0x605
+#define AU8522_AUDIOFREQ_REG606H			0x606
 
 
 /**************************************************************/
@@ -356,53 +356,53 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
 #define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_PAL_M		0x02
 
 
-#define AU8522_INPUT_CONTROL_REG081H_ATSC               	0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATSC			0xC4
 #define AU8522_INPUT_CONTROL_REG081H_ATVRF			0xC4
 #define AU8522_INPUT_CONTROL_REG081H_ATVRF13			0xC4
-#define AU8522_INPUT_CONTROL_REG081H_J83B64             	0xC4
-#define AU8522_INPUT_CONTROL_REG081H_J83B256            	0xC4
-#define AU8522_INPUT_CONTROL_REG081H_CVBS               	0x20
+#define AU8522_INPUT_CONTROL_REG081H_J83B64			0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B256			0xC4
+#define AU8522_INPUT_CONTROL_REG081H_CVBS			0x20
 #define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1			0xA2
 #define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2			0xA0
 #define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3			0x69
 #define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4			0x68
-#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF        	0x28
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF		0x28
 /* CH1 AS Y,CH3 AS C */
-#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13        	0x23
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13		0x23
 /* CH2 AS Y,CH4 AS C */
-#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24        	0x20
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC        	0x0C
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64      	0x09
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256    		0x09
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS        	0x12
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF       	0x1A
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24		0x20
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC		0x0C
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64		0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256		0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS		0x12
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF		0x1A
 #define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13		0x1A
 #define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO		0x02
 
 #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR		0x00
 #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO		0x9C
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS     	0x9D
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS		0x9D
 #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC		0xE8
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 		0xCA
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64  		0xCA
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF   		0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256		0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64		0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF		0xDD
 #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13		0xDD
 #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL		0xDD
 #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM		0xDD
 
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC		0x80
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 		0x80
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64  		0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256		0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64		0x80
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC	0x40
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256	0x40
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64	0x40
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR	0x00
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF		0x01
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13		0x01
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO  		0x04
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO		0x04
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS		0x01
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM     		0x03
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS      	0x09
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM		0x03
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS		0x09
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL		0x01
 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM		0x01
 
diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c
index ba63ad1..05df133 100644
--- a/drivers/media/dvb-frontends/bcm3510.c
+++ b/drivers/media/dvb-frontends/bcm3510.c
@@ -40,7 +40,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "bcm3510.h"
 #include "bcm3510_priv.h"
 
diff --git a/drivers/media/dvb-frontends/cx22700.c b/drivers/media/dvb-frontends/cx22700.c
index 2b629e2..9ffd2c7 100644
--- a/drivers/media/dvb-frontends/cx22700.c
+++ b/drivers/media/dvb-frontends/cx22700.c
@@ -25,7 +25,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "cx22700.h"
 
 
diff --git a/drivers/media/dvb-frontends/cx22702.c b/drivers/media/dvb-frontends/cx22702.c
index c0e54c5..e8b1e6b 100644
--- a/drivers/media/dvb-frontends/cx22702.c
+++ b/drivers/media/dvb-frontends/cx22702.c
@@ -31,7 +31,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "cx22702.h"
 
 struct cx22702_state {
diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c
index cf1bc99..2f3a1c2 100644
--- a/drivers/media/dvb-frontends/cx24110.c
+++ b/drivers/media/dvb-frontends/cx24110.c
@@ -27,7 +27,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "cx24110.h"
 
 
diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c
index ee1f704..037db3e 100644
--- a/drivers/media/dvb-frontends/cx24113.c
+++ b/drivers/media/dvb-frontends/cx24113.c
@@ -22,7 +22,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "cx24113.h"
 
 static int debug;
diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c
index 8fb3f09..786c56a 100644
--- a/drivers/media/dvb-frontends/cx24116.c
+++ b/drivers/media/dvb-frontends/cx24116.c
@@ -41,7 +41,7 @@
 #include <linux/init.h>
 #include <linux/firmware.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "cx24116.h"
 
 static int debug;
@@ -963,7 +963,7 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
 
 	/* Validate length */
 	if (d->msg_len > sizeof(d->msg))
-                return -EINVAL;
+		return -EINVAL;
 
 	/* Dump DiSEqC message */
 	if (debug) {
diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c
index d37cb77..8935114 100644
--- a/drivers/media/dvb-frontends/cx24117.c
+++ b/drivers/media/dvb-frontends/cx24117.c
@@ -32,7 +32,7 @@
 #include <linux/firmware.h>
 
 #include "tuner-i2c.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "cx24117.h"
 
 
diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c
index 7f11dcc..810f68a 100644
--- a/drivers/media/dvb-frontends/cx24120.c
+++ b/drivers/media/dvb-frontends/cx24120.c
@@ -29,7 +29,7 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/firmware.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "cx24120.h"
 
 #define CX24120_SEARCH_RANGE_KHZ 5000
diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c
index 1d59d1d..228ba1f 100644
--- a/drivers/media/dvb-frontends/cx24123.c
+++ b/drivers/media/dvb-frontends/cx24123.c
@@ -24,7 +24,7 @@
 #include <linux/init.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "cx24123.h"
 
 #define XTAL 10111000
diff --git a/drivers/media/dvb-frontends/cxd2820r_priv.h b/drivers/media/dvb-frontends/cxd2820r_priv.h
index 0d09620..61adde4 100644
--- a/drivers/media/dvb-frontends/cxd2820r_priv.h
+++ b/drivers/media/dvb-frontends/cxd2820r_priv.h
@@ -23,8 +23,8 @@
 #define CXD2820R_PRIV_H
 
 #include <linux/dvb/version.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
 #include "cxd2820r.h"
 #include <linux/gpio.h>
 #include <linux/math64.h>
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index 48ee9bc..85905d3 100644
--- a/drivers/media/dvb-frontends/cxd2841er.c
+++ b/drivers/media/dvb-frontends/cxd2841er.c
@@ -29,9 +29,10 @@
 #include <linux/math64.h>
 #include <linux/log2.h>
 #include <linux/dynamic_debug.h>
+#include <linux/kernel.h>
 
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_math.h>
+#include <media/dvb_frontend.h>
 #include "cxd2841er.h"
 #include "cxd2841er_priv.h"
 
@@ -257,7 +258,9 @@ static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
 static int cxd2841er_write_reg(struct cxd2841er_priv *priv,
 			       u8 addr, u8 reg, u8 val)
 {
-	return cxd2841er_write_regs(priv, addr, reg, &val, 1);
+	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+	return cxd2841er_write_regs(priv, addr, reg, &tmp, 1);
 }
 
 static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
@@ -1696,12 +1699,10 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
 		min_index = 0;
 		if (delsys == SYS_DVBS) {
 			cn_data = s_cn_data;
-			max_index = sizeof(s_cn_data) /
-				sizeof(s_cn_data[0]) - 1;
+			max_index = ARRAY_SIZE(s_cn_data) - 1;
 		} else {
 			cn_data = s2_cn_data;
-			max_index = sizeof(s2_cn_data) /
-				sizeof(s2_cn_data[0]) - 1;
+			max_index = ARRAY_SIZE(s2_cn_data) - 1;
 		}
 		if (value >= cn_data[min_index].value) {
 			res = cn_data[min_index].cnr_x1000;
@@ -3340,13 +3341,17 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
 
 	cxd2841er_tune_done(priv);
 	timeout = ((3000000 + (symbol_rate - 1)) / symbol_rate) + 150;
-	for (i = 0; i < timeout / CXD2841ER_DVBS_POLLING_INVL; i++) {
+
+	i = 0;
+	do {
 		usleep_range(CXD2841ER_DVBS_POLLING_INVL*1000,
 			(CXD2841ER_DVBS_POLLING_INVL + 2) * 1000);
 		cxd2841er_read_status_s(fe, &status);
 		if (status & FE_HAS_LOCK)
 			break;
-	}
+		i++;
+	} while (i < timeout / CXD2841ER_DVBS_POLLING_INVL);
+
 	if (status & FE_HAS_LOCK) {
 		if (cxd2841er_get_carrier_offset_s_s2(
 				priv, &carr_offset)) {
diff --git a/drivers/media/dvb-frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c
index d7614b8..932d235 100644
--- a/drivers/media/dvb-frontends/dib0070.c
+++ b/drivers/media/dvb-frontends/dib0070.c
@@ -27,7 +27,7 @@
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "dib0070.h"
 #include "dibx000_common.h"
diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c
index d9d730d..64f49c8 100644
--- a/drivers/media/dvb-frontends/dib0090.c
+++ b/drivers/media/dvb-frontends/dib0090.c
@@ -27,7 +27,7 @@
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "dib0090.h"
 #include "dibx000_common.h"
diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c
index 068bec1..de3ce27 100644
--- a/drivers/media/dvb-frontends/dib3000mb.c
+++ b/drivers/media/dvb-frontends/dib3000mb.c
@@ -30,7 +30,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "dib3000.h"
 #include "dib3000mb_priv.h"
diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c
index 4d086a7..7e5d4748 100644
--- a/drivers/media/dvb-frontends/dib3000mc.c
+++ b/drivers/media/dvb-frontends/dib3000mc.c
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "dib3000mc.h"
 
diff --git a/drivers/media/dvb-frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c
index 5ce9f93a..6a1d357 100644
--- a/drivers/media/dvb-frontends/dib7000m.c
+++ b/drivers/media/dvb-frontends/dib7000m.c
@@ -16,7 +16,7 @@
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "dib7000m.h"
 
diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c
index 0fbaabe..90ace70 100644
--- a/drivers/media/dvb-frontends/dib7000p.c
+++ b/drivers/media/dvb-frontends/dib7000p.c
@@ -16,8 +16,8 @@
 #include <linux/mutex.h>
 #include <asm/div64.h>
 
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_math.h>
+#include <media/dvb_frontend.h>
 
 #include "dib7000p.h"
 
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index 5d93815..e64014f 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -16,9 +16,9 @@
 #include <linux/mutex.h>
 #include <asm/div64.h>
 
-#include "dvb_math.h"
+#include <media/dvb_math.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "dib8000.h"
 
diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c
index 1b7a433..f9289f4 100644
--- a/drivers/media/dvb-frontends/dib9000.c
+++ b/drivers/media/dvb-frontends/dib9000.c
@@ -14,8 +14,8 @@
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_math.h>
+#include <media/dvb_frontend.h>
 
 #include "dib9000.h"
 #include "dibx000_common.h"
diff --git a/drivers/media/dvb-frontends/dibx000_common.c b/drivers/media/dvb-frontends/dibx000_common.c
index bc28184..d981233 100644
--- a/drivers/media/dvb-frontends/dibx000_common.c
+++ b/drivers/media/dvb-frontends/dibx000_common.c
@@ -288,8 +288,8 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
 	int ret;
 
 	if (num > 32) {
-		dprintk("%s: too much I2C message to be transmitted (%i).\
-				Maximum is 32", __func__, num);
+		dprintk("%s: too much I2C message to be transmitted (%i). Maximum is 32",
+			__func__, num);
 		return -ENOMEM;
 	}
 
@@ -335,8 +335,8 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
 	int ret;
 
 	if (num > 32) {
-		dprintk("%s: too much I2C message to be transmitted (%i).\
-				Maximum is 32", __func__, num);
+		dprintk("%s: too much I2C message to be transmitted (%i). Maximum is 32",
+			__func__, num);
 		return -ENOMEM;
 	}
 
diff --git a/drivers/media/dvb-frontends/drx39xyj/Makefile b/drivers/media/dvb-frontends/drx39xyj/Makefile
index 672e077..87f6edd 100644
--- a/drivers/media/dvb-frontends/drx39xyj/Makefile
+++ b/drivers/media/dvb-frontends/drx39xyj/Makefile
@@ -2,5 +2,4 @@
 
 obj-$(CONFIG_DVB_DRX39XYJ) += drx39xyj.o
 
-ccflags-y += -I$(srctree)/drivers/media/dvb-core/
 ccflags-y += -I$(srctree)/drivers/media/tuners/
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h b/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
index 11e1dde..c0c66ed6 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
+++ b/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
@@ -19,7 +19,7 @@
 #define DRX39XXJ_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "drx_driver.h"
 
 struct drx39xxj_state {
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
index 855685b..1ec20ee 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
+++ b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
@@ -932,7 +932,7 @@ STRUCTS
  * Used by DRX_CTRL_LOAD_UCODE and DRX_CTRL_VERIFY_UCODE
  */
 struct drxu_code_info {
-	char 			*mc_file;
+	char			*mc_file;
 };
 
 /*
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index 8cbd8cc..5706898 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -61,7 +61,7 @@ INCLUDE FILES
 #include <linux/slab.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "drx39xxj.h"
 
 #include "drxj.h"
@@ -2151,9 +2151,13 @@ int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
 	if (read_flag) {
 		/* read data from buffer */
 		for (i = 0; i < (datasize / 2); i++) {
-			drxj_dap_read_reg16(dev_addr,
-					    (DRXJ_HI_ATOMIC_BUF_START + i),
-					   &word, 0);
+			rc = drxj_dap_read_reg16(dev_addr,
+						 (DRXJ_HI_ATOMIC_BUF_START + i),
+						 &word, 0);
+			if (rc) {
+				pr_err("error %d\n", rc);
+				goto rw_error;
+			}
 			data[2 * i] = (u8) (word & 0xFF);
 			data[(2 * i) + 1] = (u8) (word >> 8);
 		}
@@ -11074,7 +11078,7 @@ ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
 		}
 	}
 
-	if ((*mode == DRX_POWER_UP)) {
+	if (*mode == DRX_POWER_UP) {
 		/* Restore analog & pin configuration */
 
 		/* Initialize default AFE configuration for VSB */
@@ -11723,7 +11727,7 @@ static int drx_check_firmware(struct drx_demod_instance *demod, u8 *mc_data,
  *		- In case of UCODE_UPLOAD: I2C error.
  *		- In case of UCODE_VERIFY: I2C error or image on device
  *		  is not equal to image provided to this control function.
- * 	-EINVAL:
+ *	-EINVAL:
  *		- Invalid arguments.
  *		- Provided image is corrupt
  */
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c
index 0696bc6..3b7d31a 100644
--- a/drivers/media/dvb-frontends/drxd_hard.c
+++ b/drivers/media/dvb-frontends/drxd_hard.c
@@ -26,7 +26,7 @@
 #include <linux/i2c.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "drxd.h"
 #include "drxd_firm.h"
 
@@ -972,7 +972,6 @@ static int DownloadMicrocode(struct drxd_state *state,
 static int HI_Command(struct drxd_state *state, u16 cmd, u16 * pResult)
 {
 	u32 nrRetries = 0;
-	u16 waitCmd;
 	int status;
 
 	status = Write16(state, HI_RA_RAM_SRV_CMD__A, cmd, 0);
@@ -985,8 +984,8 @@ static int HI_Command(struct drxd_state *state, u16 cmd, u16 * pResult)
 			status = -1;
 			break;
 		}
-		status = Read16(state, HI_RA_RAM_SRV_CMD__A, &waitCmd, 0);
-	} while (waitCmd != 0);
+		status = Read16(state, HI_RA_RAM_SRV_CMD__A, NULL, 0);
+	} while (status != 0);
 
 	if (status >= 0)
 		status = Read16(state, HI_RA_RAM_SRV_RES__A, pResult, 0);
@@ -1298,12 +1297,11 @@ static int InitFT(struct drxd_state *state)
 
 static int SC_WaitForReady(struct drxd_state *state)
 {
-	u16 curCmd;
 	int i;
 
 	for (i = 0; i < DRXD_MAX_RETRIES; i += 1) {
-		int status = Read16(state, SC_RA_RAM_CMD__A, &curCmd, 0);
-		if (status == 0 || curCmd == 0)
+		int status = Read16(state, SC_RA_RAM_CMD__A, NULL, 0);
+		if (status == 0)
 			return status;
 	}
 	return -1;
@@ -1311,15 +1309,15 @@ static int SC_WaitForReady(struct drxd_state *state)
 
 static int SC_SendCommand(struct drxd_state *state, u16 cmd)
 {
-	int status = 0;
+	int status = 0, ret;
 	u16 errCode;
 
 	Write16(state, SC_RA_RAM_CMD__A, cmd, 0);
 	SC_WaitForReady(state);
 
-	Read16(state, SC_RA_RAM_CMD_ADDR__A, &errCode, 0);
+	ret = Read16(state, SC_RA_RAM_CMD_ADDR__A, &errCode, 0);
 
-	if (errCode == 0xFFFF) {
+	if (ret < 0 || errCode == 0xFFFF) {
 		printk(KERN_ERR "Command Error\n");
 		status = -1;
 	}
@@ -1330,13 +1328,13 @@ static int SC_SendCommand(struct drxd_state *state, u16 cmd)
 static int SC_ProcStartCommand(struct drxd_state *state,
 			       u16 subCmd, u16 param0, u16 param1)
 {
-	int status = 0;
+	int ret, status = 0;
 	u16 scExec;
 
 	mutex_lock(&state->mutex);
 	do {
-		Read16(state, SC_COMM_EXEC__A, &scExec, 0);
-		if (scExec != 1) {
+		ret = Read16(state, SC_COMM_EXEC__A, &scExec, 0);
+		if (ret < 0 || scExec != 1) {
 			status = -1;
 			break;
 		}
@@ -2140,7 +2138,6 @@ static int DRX_Start(struct drxd_state *state, s32 off)
 			}
 			break;
 		}
-		status = status;
 		if (status < 0)
 			break;
 
@@ -2251,7 +2248,6 @@ static int DRX_Start(struct drxd_state *state, s32 off)
 			break;
 
 		}
-		status = status;
 		if (status < 0)
 			break;
 
@@ -2318,7 +2314,6 @@ static int DRX_Start(struct drxd_state *state, s32 off)
 			}
 			break;
 		}
-		status = status;
 		if (status < 0)
 			break;
 
diff --git a/drivers/media/dvb-frontends/drxk.h b/drivers/media/dvb-frontends/drxk.h
index b16fedb..76466f7 100644
--- a/drivers/media/dvb-frontends/drxk.h
+++ b/drivers/media/dvb-frontends/drxk.h
@@ -10,7 +10,7 @@
  *
  * @adr:		I2C address of the DRX-K
  * @parallel_ts:	True means that the device uses parallel TS,
- * 			Serial otherwise.
+ *			Serial otherwise.
  * @dynamic_clk:	True means that the clock will be dynamically
  *			adjusted. Static clock otherwise.
  * @enable_merr_cfg:	Enable SIO_PDR_PERR_CFG/SIO_PDR_MVAL_CFG.
@@ -67,8 +67,8 @@ extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
 static inline struct dvb_frontend *drxk_attach(const struct drxk_config *config,
 					struct i2c_adapter *i2c)
 {
-        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-        return NULL;
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
 }
 #endif
 
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index f59ac2e..5a26ad9 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -29,10 +29,10 @@
 #include <linux/hardirq.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "drxk.h"
 #include "drxk_hard.h"
-#include "dvb_math.h"
+#include <media/dvb_math.h>
 
 static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
 static int power_down_qam(struct drxk_state *state);
@@ -6062,7 +6062,7 @@ static int init_drxk(struct drxk_state *state)
 	u16 driver_version;
 
 	dprintk(1, "\n");
-	if ((state->m_drxk_state == DRXK_UNINITIALIZED)) {
+	if (state->m_drxk_state == DRXK_UNINITIALIZED) {
 		drxk_i2c_lock(state);
 		status = power_up_device(state);
 		if (status < 0)
diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c
index bd4f827..2ff90e5 100644
--- a/drivers/media/dvb-frontends/ds3000.c
+++ b/drivers/media/dvb-frontends/ds3000.c
@@ -26,7 +26,7 @@
 #include <linux/init.h>
 #include <linux/firmware.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "ts2020.h"
 #include "ds3000.h"
 
diff --git a/drivers/media/dvb-frontends/dvb-pll.h b/drivers/media/dvb-frontends/dvb-pll.h
index 212e073..ca885e7 100644
--- a/drivers/media/dvb-frontends/dvb-pll.h
+++ b/drivers/media/dvb-frontends/dvb-pll.h
@@ -7,7 +7,7 @@
 #define __DVB_PLL_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #define DVB_PLL_UNDEFINED               0
 #define DVB_PLL_THOMSON_DTT7579         1
diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.c b/drivers/media/dvb-frontends/dvb_dummy_fe.c
index 50b2b66..6650d4f 100644
--- a/drivers/media/dvb-frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb-frontends/dvb_dummy_fe.c
@@ -20,7 +20,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "dvb_dummy_fe.h"
 
 
diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.h b/drivers/media/dvb-frontends/dvb_dummy_fe.h
index 86dd7b9..7aacef4 100644
--- a/drivers/media/dvb-frontends/dvb_dummy_fe.h
+++ b/drivers/media/dvb-frontends/dvb_dummy_fe.h
@@ -19,7 +19,7 @@
 #define DVB_DUMMY_FE_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #if IS_REACHABLE(CONFIG_DVB_DUMMY_FE)
 extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
diff --git a/drivers/media/dvb-frontends/ec100.c b/drivers/media/dvb-frontends/ec100.c
index fa2a96d..c2575fd 100644
--- a/drivers/media/dvb-frontends/ec100.c
+++ b/drivers/media/dvb-frontends/ec100.c
@@ -15,7 +15,7 @@
  *
  */
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "ec100.h"
 
 struct ec100_state {
diff --git a/drivers/media/dvb-frontends/gp8psk-fe.c b/drivers/media/dvb-frontends/gp8psk-fe.c
index efe015df..a772ef8 100644
--- a/drivers/media/dvb-frontends/gp8psk-fe.c
+++ b/drivers/media/dvb-frontends/gp8psk-fe.c
@@ -16,7 +16,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include "gp8psk-fe.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 static int debug;
 module_param(debug, int, 0644);
diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c
index 4bf5a55..a0d0b53 100644
--- a/drivers/media/dvb-frontends/helene.c
+++ b/drivers/media/dvb-frontends/helene.c
@@ -23,7 +23,7 @@
 #include <linux/dvb/frontend.h>
 #include <linux/types.h>
 #include "helene.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #define MAX_WRITE_REGSIZE 20
 
@@ -331,7 +331,9 @@ static int helene_write_regs(struct helene_priv *priv,
 
 static int helene_write_reg(struct helene_priv *priv, u8 reg, u8 val)
 {
-	return helene_write_regs(priv, reg, &val, 1);
+	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+	return helene_write_regs(priv, reg, &tmp, 1);
 }
 
 static int helene_read_regs(struct helene_priv *priv,
diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c
index 68d759c..5e7e265 100644
--- a/drivers/media/dvb-frontends/horus3a.c
+++ b/drivers/media/dvb-frontends/horus3a.c
@@ -24,7 +24,7 @@
 #include <linux/dvb/frontend.h>
 #include <linux/types.h>
 #include "horus3a.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #define MAX_WRITE_REGSIZE      5
 
@@ -89,7 +89,9 @@ static int horus3a_write_regs(struct horus3a_priv *priv,
 
 static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val)
 {
-	return horus3a_write_regs(priv, reg, &val, 1);
+	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+	return horus3a_write_regs(priv, reg, &tmp, 1);
 }
 
 static int horus3a_enter_power_save(struct horus3a_priv *priv)
diff --git a/drivers/media/dvb-frontends/isl6405.c b/drivers/media/dvb-frontends/isl6405.c
index 2fc8d3c..3bc78f8 100644
--- a/drivers/media/dvb-frontends/isl6405.c
+++ b/drivers/media/dvb-frontends/isl6405.c
@@ -29,7 +29,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "isl6405.h"
 
 struct isl6405 {
diff --git a/drivers/media/dvb-frontends/isl6421.c b/drivers/media/dvb-frontends/isl6421.c
index 3f34878..ae8ec59 100644
--- a/drivers/media/dvb-frontends/isl6421.c
+++ b/drivers/media/dvb-frontends/isl6421.c
@@ -29,7 +29,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "isl6421.h"
 
 struct isl6421 {
diff --git a/drivers/media/dvb-frontends/isl6423.c b/drivers/media/dvb-frontends/isl6423.c
index dca5beb..3dd2465 100644
--- a/drivers/media/dvb-frontends/isl6423.c
+++ b/drivers/media/dvb-frontends/isl6423.c
@@ -26,7 +26,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "isl6423.h"
 
 static unsigned int verbose;
diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c
index 5bb1e73..04f7f68 100644
--- a/drivers/media/dvb-frontends/itd1000.c
+++ b/drivers/media/dvb-frontends/itd1000.c
@@ -22,7 +22,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "itd1000.h"
 #include "itd1000_priv.h"
@@ -95,8 +95,9 @@ static int itd1000_read_reg(struct itd1000_state *state, u8 reg)
 
 static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
 {
-	int ret = itd1000_write_regs(state, r, &v, 1);
-	state->shadow[r] = v;
+	u8 tmp = v; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+	int ret = itd1000_write_regs(state, r, &tmp, 1);
+	state->shadow[r] = tmp;
 	return ret;
 }
 
diff --git a/drivers/media/dvb-frontends/ix2505v.h b/drivers/media/dvb-frontends/ix2505v.h
index 49ed93e..20b1eb3 100644
--- a/drivers/media/dvb-frontends/ix2505v.h
+++ b/drivers/media/dvb-frontends/ix2505v.h
@@ -17,7 +17,7 @@
 #define DVB_IX2505V_H
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /**
  * struct ix2505v_config - ix2505 attachment configuration
diff --git a/drivers/media/dvb-frontends/l64781.c b/drivers/media/dvb-frontends/l64781.c
index e5a6c17..e056f36 100644
--- a/drivers/media/dvb-frontends/l64781.c
+++ b/drivers/media/dvb-frontends/l64781.c
@@ -25,7 +25,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "l64781.h"
 
 
diff --git a/drivers/media/dvb-frontends/lg2160.h b/drivers/media/dvb-frontends/lg2160.h
index ba99125..df817ae 100644
--- a/drivers/media/dvb-frontends/lg2160.h
+++ b/drivers/media/dvb-frontends/lg2160.h
@@ -19,7 +19,7 @@
 #define _LG2160_H_
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 enum lg_chip_type {
 	LG2160 = 0,
diff --git a/drivers/media/dvb-frontends/lgdt3305.c b/drivers/media/dvb-frontends/lgdt3305.c
index 0af4d91..735d730 100644
--- a/drivers/media/dvb-frontends/lgdt3305.c
+++ b/drivers/media/dvb-frontends/lgdt3305.c
@@ -20,7 +20,7 @@
 #include <asm/div64.h>
 #include <linux/dvb/frontend.h>
 #include <linux/slab.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
 #include "lgdt3305.h"
 
 static int debug;
diff --git a/drivers/media/dvb-frontends/lgdt3305.h b/drivers/media/dvb-frontends/lgdt3305.h
index 2fb60d9..a54daae 100644
--- a/drivers/media/dvb-frontends/lgdt3305.h
+++ b/drivers/media/dvb-frontends/lgdt3305.h
@@ -19,7 +19,7 @@
 #define _LGDT3305_H_
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 
 enum lgdt3305_mpeg_mode {
diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c
index 724e9aac..6356815 100644
--- a/drivers/media/dvb-frontends/lgdt3306a.c
+++ b/drivers/media/dvb-frontends/lgdt3306a.c
@@ -21,7 +21,7 @@
 #include <asm/div64.h>
 #include <linux/kernel.h>
 #include <linux/dvb/frontend.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
 #include "lgdt3306a.h"
 #include <linux/i2c-mux.h>
 
diff --git a/drivers/media/dvb-frontends/lgdt3306a.h b/drivers/media/dvb-frontends/lgdt3306a.h
index 6ce337e..8b53044f 100644
--- a/drivers/media/dvb-frontends/lgdt3306a.h
+++ b/drivers/media/dvb-frontends/lgdt3306a.h
@@ -19,7 +19,7 @@
 #define _LGDT3306A_H_
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 
 enum lgdt3306a_mpeg_mode {
diff --git a/drivers/media/dvb-frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c
index 06f47dc..8ad03bd 100644
--- a/drivers/media/dvb-frontends/lgdt330x.c
+++ b/drivers/media/dvb-frontends/lgdt330x.c
@@ -37,8 +37,8 @@
 #include <linux/slab.h>
 #include <asm/byteorder.h>
 
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
 #include "lgdt330x_priv.h"
 #include "lgdt330x.h"
 
diff --git a/drivers/media/dvb-frontends/lgs8gl5.c b/drivers/media/dvb-frontends/lgs8gl5.c
index 970e42f..f47e5a1 100644
--- a/drivers/media/dvb-frontends/lgs8gl5.c
+++ b/drivers/media/dvb-frontends/lgs8gl5.c
@@ -25,7 +25,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "lgs8gl5.h"
 
 
diff --git a/drivers/media/dvb-frontends/lgs8gxx.c b/drivers/media/dvb-frontends/lgs8gxx.c
index e6bf60e..84af8a1 100644
--- a/drivers/media/dvb-frontends/lgs8gxx.c
+++ b/drivers/media/dvb-frontends/lgs8gxx.c
@@ -22,7 +22,7 @@
 #include <asm/div64.h>
 #include <linux/firmware.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "lgs8gxx.h"
 #include "lgs8gxx_priv.h"
diff --git a/drivers/media/dvb-frontends/lnbh25.c b/drivers/media/dvb-frontends/lnbh25.c
index cb486e8..0b38850 100644
--- a/drivers/media/dvb-frontends/lnbh25.c
+++ b/drivers/media/dvb-frontends/lnbh25.c
@@ -23,7 +23,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "lnbh25.h"
 
 /**
diff --git a/drivers/media/dvb-frontends/lnbp21.c b/drivers/media/dvb-frontends/lnbp21.c
index 392d7be..d9966a3 100644
--- a/drivers/media/dvb-frontends/lnbp21.c
+++ b/drivers/media/dvb-frontends/lnbp21.c
@@ -29,7 +29,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "lnbp21.h"
 #include "lnbh24.h"
 
diff --git a/drivers/media/dvb-frontends/lnbp22.c b/drivers/media/dvb-frontends/lnbp22.c
index 39326a2..a62e82bf 100644
--- a/drivers/media/dvb-frontends/lnbp22.c
+++ b/drivers/media/dvb-frontends/lnbp22.c
@@ -30,7 +30,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "lnbp22.h"
 
 static int debug;
diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h
index 07f20c2..1ba0b79 100644
--- a/drivers/media/dvb-frontends/m88ds3103_priv.h
+++ b/drivers/media/dvb-frontends/m88ds3103_priv.h
@@ -17,9 +17,9 @@
 #ifndef M88DS3103_PRIV_H
 #define M88DS3103_PRIV_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "m88ds3103.h"
-#include "dvb_math.h"
+#include <media/dvb_math.h>
 #include <linux/firmware.h>
 #include <linux/i2c-mux.h>
 #include <linux/regmap.h>
diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c
index ce6c21d..496ce27 100644
--- a/drivers/media/dvb-frontends/m88rs2000.c
+++ b/drivers/media/dvb-frontends/m88rs2000.c
@@ -31,7 +31,7 @@
 #include <linux/types.h>
 
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "m88rs2000.h"
 
 struct m88rs2000_state {
@@ -630,13 +630,16 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
 	if (ret < 0)
 		return -ENODEV;
 
-	if (fe->ops.tuner_ops.get_frequency)
+	if (fe->ops.tuner_ops.get_frequency) {
 		ret = fe->ops.tuner_ops.get_frequency(fe, &tuner_freq);
 
-	if (ret < 0)
-		return -ENODEV;
+		if (ret < 0)
+			return -ENODEV;
 
-	offset = (s16)((s32)tuner_freq - c->frequency);
+		offset = (s16)((s32)tuner_freq - c->frequency);
+	} else {
+		offset = 0;
+	}
 
 	/* default mclk value 96.4285 * 2 * 1000 = 192857 */
 	if (((c->frequency % 192857) >= (192857 - 3000)) ||
diff --git a/drivers/media/dvb-frontends/m88rs2000.h b/drivers/media/dvb-frontends/m88rs2000.h
index 1a313b0f..b015872 100644
--- a/drivers/media/dvb-frontends/m88rs2000.h
+++ b/drivers/media/dvb-frontends/m88rs2000.h
@@ -21,7 +21,7 @@
 #define M88RS2000_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct m88rs2000_config {
 	/* Demodulator i2c address */
diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c
index dfe322e..2969ba6 100644
--- a/drivers/media/dvb-frontends/mb86a16.c
+++ b/drivers/media/dvb-frontends/mb86a16.c
@@ -24,7 +24,7 @@
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mb86a16.h"
 #include "mb86a16_priv.h"
 
@@ -635,6 +635,7 @@ static int sync_chk(struct mb86a16_state *state,
 	return sync;
 err:
 	dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+	*VIRM = 0;
 	return -EREMOTEIO;
 
 }
@@ -1676,15 +1677,15 @@ static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
 			 * the deinterleaver output.
 			 * monitored BER is expressed as a 20 bit output in total
 			 */
-			ber_rst = ber_mon >> 3;
+			ber_rst = (ber_mon >> 3) & 0x03;
 			*ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
 			if (ber_rst == 0)
 				timer =  12500000;
-			if (ber_rst == 1)
+			else if (ber_rst == 1)
 				timer =  25000000;
-			if (ber_rst == 2)
+			else if (ber_rst == 2)
 				timer =  50000000;
-			if (ber_rst == 3)
+			else /* ber_rst == 3 */
 				timer = 100000000;
 
 			*ber /= timer;
@@ -1696,11 +1697,11 @@ static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
 			 * QPSK demodulator output.
 			 * monitored BER is expressed as a 24 bit output in total
 			 */
-			ber_tim = ber_mon >> 1;
+			ber_tim = (ber_mon >> 1) & 0x01;
 			*ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
 			if (ber_tim == 0)
 				timer = 16;
-			if (ber_tim == 1)
+			else /* ber_tim == 1 */
 				timer = 24;
 
 			*ber /= 2 ^ timer;
diff --git a/drivers/media/dvb-frontends/mb86a16.h b/drivers/media/dvb-frontends/mb86a16.h
index dbd5f43..f13820b 100644
--- a/drivers/media/dvb-frontends/mb86a16.h
+++ b/drivers/media/dvb-frontends/mb86a16.h
@@ -22,7 +22,7 @@
 #define __MB86A16_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 
 struct mb86a16_config {
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index bdaf9d2..36e9519 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -17,7 +17,7 @@
 #include <linux/kernel.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mb86a20s.h"
 
 #define NUM_LAYERS 3
@@ -2057,7 +2057,7 @@ static void mb86a20s_release(struct dvb_frontend *fe)
 
 static int mb86a20s_get_frontend_algo(struct dvb_frontend *fe)
 {
-        return DVBFE_ALGO_HW;
+	return DVBFE_ALGO_HW;
 }
 
 static const struct dvb_frontend_ops mb86a20s_ops;
diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h
index fb50f56..2ec126a 100644
--- a/drivers/media/dvb-frontends/mn88472_priv.h
+++ b/drivers/media/dvb-frontends/mn88472_priv.h
@@ -17,8 +17,8 @@
 #ifndef MN88472_PRIV_H
 #define MN88472_PRIV_H
 
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
 #include "mn88472.h"
 #include <linux/firmware.h>
 #include <linux/regmap.h>
diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c
index 5824743..ca72208 100644
--- a/drivers/media/dvb-frontends/mn88473.c
+++ b/drivers/media/dvb-frontends/mn88473.c
@@ -764,7 +764,7 @@ MODULE_DEVICE_TABLE(i2c, mn88473_id_table);
 
 static struct i2c_driver mn88473_driver = {
 	.driver = {
-		.name	             = "mn88473",
+		.name		     = "mn88473",
 		.suppress_bind_attrs = true,
 	},
 	.probe		= mn88473_probe,
diff --git a/drivers/media/dvb-frontends/mn88473_priv.h b/drivers/media/dvb-frontends/mn88473_priv.h
index 5fc463d..d89a863 100644
--- a/drivers/media/dvb-frontends/mn88473_priv.h
+++ b/drivers/media/dvb-frontends/mn88473_priv.h
@@ -17,8 +17,8 @@
 #ifndef MN88473_PRIV_H
 #define MN88473_PRIV_H
 
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
 #include "mn88473.h"
 #include <linux/math64.h>
 #include <linux/firmware.h>
diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c
index 961b9a2..e2a3fc5 100644
--- a/drivers/media/dvb-frontends/mt312.c
+++ b/drivers/media/dvb-frontends/mt312.c
@@ -32,7 +32,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mt312_priv.h"
 #include "mt312.h"
 
@@ -142,7 +142,10 @@ static inline int mt312_readreg(struct mt312_state *state,
 static inline int mt312_writereg(struct mt312_state *state,
 				 const enum mt312_reg_addr reg, const u8 val)
 {
-	return mt312_write(state, reg, &val, 1);
+	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+
+	return mt312_write(state, reg, &tmp, 1);
 }
 
 static inline u32 mt312_div(u32 a, u32 b)
diff --git a/drivers/media/dvb-frontends/mt352.c b/drivers/media/dvb-frontends/mt352.c
index d5fa96f..a440b76 100644
--- a/drivers/media/dvb-frontends/mt352.c
+++ b/drivers/media/dvb-frontends/mt352.c
@@ -33,7 +33,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mt352_priv.h"
 #include "mt352.h"
 
diff --git a/drivers/media/dvb-frontends/mxl5xx.c b/drivers/media/dvb-frontends/mxl5xx.c
index 53064e1..e899821 100644
--- a/drivers/media/dvb-frontends/mxl5xx.c
+++ b/drivers/media/dvb-frontends/mxl5xx.c
@@ -33,7 +33,7 @@
 #include <asm/div64.h>
 #include <asm/unaligned.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mxl5xx.h"
 #include "mxl5xx_regs.h"
 #include "mxl5xx_defs.h"
@@ -636,16 +636,9 @@ static int tune(struct dvb_frontend *fe, bool re_tune,
 		if (r)
 			return r;
 		state->tune_time = jiffies;
-		return 0;
 	}
-	if (*status & FE_HAS_LOCK)
-		return 0;
 
-	r = read_status(fe, status);
-	if (r)
-		return r;
-
-	return 0;
+	return read_status(fe, status);
 }
 
 static enum fe_code_rate conv_fec(enum MXL_HYDRA_FEC_E fec)
diff --git a/drivers/media/dvb-frontends/mxl5xx.h b/drivers/media/dvb-frontends/mxl5xx.h
index 532e0811..ad4c218 100644
--- a/drivers/media/dvb-frontends/mxl5xx.h
+++ b/drivers/media/dvb-frontends/mxl5xx.h
@@ -4,7 +4,7 @@
 #include <linux/types.h>
 #include <linux/i2c.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct mxl5xx_cfg {
 	u8   adr;
diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c
index bf6e5cd..7aa7440 100644
--- a/drivers/media/dvb-frontends/nxt200x.c
+++ b/drivers/media/dvb-frontends/nxt200x.c
@@ -48,7 +48,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "nxt200x.h"
 
 struct nxt200x_state {
diff --git a/drivers/media/dvb-frontends/nxt6000.c b/drivers/media/dvb-frontends/nxt6000.c
index 1ce5ea2..109a635 100644
--- a/drivers/media/dvb-frontends/nxt6000.c
+++ b/drivers/media/dvb-frontends/nxt6000.c
@@ -27,7 +27,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "nxt6000_priv.h"
 #include "nxt6000.h"
 
diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c
index 5f2549c..b4c9aad 100644
--- a/drivers/media/dvb-frontends/or51132.c
+++ b/drivers/media/dvb-frontends/or51132.c
@@ -38,8 +38,8 @@
 #include <linux/slab.h>
 #include <asm/byteorder.h>
 
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_math.h>
+#include <media/dvb_frontend.h>
 #include "or51132.h"
 
 static int debug;
diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c
index d14fa97..a1b7c30 100644
--- a/drivers/media/dvb-frontends/or51211.c
+++ b/drivers/media/dvb-frontends/or51211.c
@@ -36,8 +36,8 @@
 #include <linux/slab.h>
 #include <asm/byteorder.h>
 
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_math.h>
+#include <media/dvb_frontend.h>
 #include "or51211.h"
 
 static int debug;
diff --git a/drivers/media/dvb-frontends/rtl2830_priv.h b/drivers/media/dvb-frontends/rtl2830_priv.h
index 8ec4721..72d3f35 100644
--- a/drivers/media/dvb-frontends/rtl2830_priv.h
+++ b/drivers/media/dvb-frontends/rtl2830_priv.h
@@ -18,8 +18,8 @@
 #ifndef RTL2830_PRIV_H
 #define RTL2830_PRIV_H
 
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
 #include "rtl2830.h"
 #include <linux/i2c-mux.h>
 #include <linux/math64.h>
diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h
index 9a6d01a..bd13d9a 100644
--- a/drivers/media/dvb-frontends/rtl2832_priv.h
+++ b/drivers/media/dvb-frontends/rtl2832_priv.h
@@ -26,8 +26,8 @@
 #include <linux/math64.h>
 #include <linux/bitops.h>
 
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
 #include "rtl2832.h"
 
 struct rtl2832_dev {
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.h b/drivers/media/dvb-frontends/rtl2832_sdr.h
index 8f88c2f..d28735c 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.h
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.h
@@ -27,7 +27,7 @@
 
 #include <linux/i2c.h>
 #include <media/v4l2-subdev.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /**
  * struct rtl2832_sdr_platform_data - Platform data for the rtl2832_sdr driver
diff --git a/drivers/media/dvb-frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c
index f370c6d..aced6a9 100644
--- a/drivers/media/dvb-frontends/s5h1409.c
+++ b/drivers/media/dvb-frontends/s5h1409.c
@@ -25,7 +25,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "s5h1409.h"
 
 struct s5h1409_state {
diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c
index dd09336..c4b1e97 100644
--- a/drivers/media/dvb-frontends/s5h1411.c
+++ b/drivers/media/dvb-frontends/s5h1411.c
@@ -25,7 +25,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "s5h1411.h"
 
 struct s5h1411_state {
diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c
index fd427a29..8b22225 100644
--- a/drivers/media/dvb-frontends/s5h1420.c
+++ b/drivers/media/dvb-frontends/s5h1420.c
@@ -30,7 +30,7 @@
 #include <linux/i2c.h>
 
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "s5h1420.h"
 #include "s5h1420_priv.h"
 
diff --git a/drivers/media/dvb-frontends/s5h1432.c b/drivers/media/dvb-frontends/s5h1432.c
index 4de50fe..740a60d 100644
--- a/drivers/media/dvb-frontends/s5h1432.c
+++ b/drivers/media/dvb-frontends/s5h1432.c
@@ -20,7 +20,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "s5h1432.h"
 
 struct s5h1432_state {
diff --git a/drivers/media/dvb-frontends/s921.c b/drivers/media/dvb-frontends/s921.c
index 274544a..2d75ede 100644
--- a/drivers/media/dvb-frontends/s921.c
+++ b/drivers/media/dvb-frontends/s921.c
@@ -25,7 +25,7 @@
 #include <linux/kernel.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "s921.h"
 
 static int debug = 1;
diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c
index 528b82a..2dd336f 100644
--- a/drivers/media/dvb-frontends/si2165.c
+++ b/drivers/media/dvb-frontends/si2165.c
@@ -1,7 +1,7 @@
 /*
  *  Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator
  *
- *  Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
+ *  Copyright (C) 2013-2017 Matthias Schwarzott <zzam@gentoo.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -27,8 +27,8 @@
 #include <linux/firmware.h>
 #include <linux/regmap.h>
 
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
 #include "si2165_priv.h"
 #include "si2165.h"
 
@@ -57,63 +57,21 @@ struct si2165_state {
 	u32 sys_clk;
 	u32 adc_clk;
 
+	/* DVBv3 stats */
+	u64 ber_prev;
+
 	bool has_dvbc;
 	bool has_dvbt;
 	bool firmware_loaded;
 };
 
-#define DEBUG_OTHER	0x01
-#define DEBUG_I2C_WRITE	0x02
-#define DEBUG_I2C_READ	0x04
-#define DEBUG_REG_READ	0x08
-#define DEBUG_REG_WRITE	0x10
-#define DEBUG_FW_LOAD	0x20
-
-static int debug = 0x00;
-
-#define dprintk(args...) \
-	do { \
-		if (debug & DEBUG_OTHER) \
-			printk(KERN_DEBUG "si2165: " args); \
-	} while (0)
-
-#define deb_i2c_write(args...) \
-	do { \
-		if (debug & DEBUG_I2C_WRITE) \
-			printk(KERN_DEBUG "si2165: i2c write: " args); \
-	} while (0)
-
-#define deb_i2c_read(args...) \
-	do { \
-		if (debug & DEBUG_I2C_READ) \
-			printk(KERN_DEBUG "si2165: i2c read: " args); \
-	} while (0)
-
-#define deb_readreg(args...) \
-	do { \
-		if (debug & DEBUG_REG_READ) \
-			printk(KERN_DEBUG "si2165: reg read: " args); \
-	} while (0)
-
-#define deb_writereg(args...) \
-	do { \
-		if (debug & DEBUG_REG_WRITE) \
-			printk(KERN_DEBUG "si2165: reg write: " args); \
-	} while (0)
-
-#define deb_fw_load(args...) \
-	do { \
-		if (debug & DEBUG_FW_LOAD) \
-			printk(KERN_DEBUG "si2165: fw load: " args); \
-	} while (0)
-
 static int si2165_write(struct si2165_state *state, const u16 reg,
-		       const u8 *src, const int count)
+			const u8 *src, const int count)
 {
 	int ret;
 
-	if (debug & DEBUG_I2C_WRITE)
-		deb_i2c_write("reg: 0x%04x, data: %*ph\n", reg, count, src);
+	dev_dbg(&state->client->dev, "i2c write: reg: 0x%04x, data: %*ph\n",
+		reg, count, src);
 
 	ret = regmap_bulk_write(state->regmap, reg, src, count);
 
@@ -134,30 +92,41 @@ static int si2165_read(struct si2165_state *state,
 		return ret;
 	}
 
-	if (debug & DEBUG_I2C_READ)
-		deb_i2c_read("reg: 0x%04x, data: %*ph\n", reg, count, val);
+	dev_dbg(&state->client->dev, "i2c read: reg: 0x%04x, data: %*ph\n",
+		reg, count, val);
 
 	return 0;
 }
 
 static int si2165_readreg8(struct si2165_state *state,
-		       const u16 reg, u8 *val)
+			   const u16 reg, u8 *val)
 {
 	unsigned int val_tmp;
 	int ret = regmap_read(state->regmap, reg, &val_tmp);
 	*val = (u8)val_tmp;
-	deb_readreg("R(0x%04x)=0x%02x\n", reg, *val);
+	dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%02x\n", reg, *val);
 	return ret;
 }
 
 static int si2165_readreg16(struct si2165_state *state,
-		       const u16 reg, u16 *val)
+			    const u16 reg, u16 *val)
 {
 	u8 buf[2];
 
 	int ret = si2165_read(state, reg, buf, 2);
 	*val = buf[0] | buf[1] << 8;
-	deb_readreg("R(0x%04x)=0x%04x\n", reg, *val);
+	dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%04x\n", reg, *val);
+	return ret;
+}
+
+static int si2165_readreg24(struct si2165_state *state,
+			    const u16 reg, u32 *val)
+{
+	u8 buf[3];
+
+	int ret = si2165_read(state, reg, buf, 3);
+	*val = buf[0] | buf[1] << 8 | buf[2] << 16;
+	dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%06x\n", reg, *val);
 	return ret;
 }
 
@@ -208,7 +177,9 @@ static int si2165_writereg_mask8(struct si2165_state *state, const u16 reg,
 	return si2165_writereg8(state, reg, val);
 }
 
-#define REG16(reg, val) { (reg), (val) & 0xff }, { (reg)+1, (val)>>8 & 0xff }
+#define REG16(reg, val) \
+	{ (reg), (val) & 0xff }, \
+	{ (reg) + 1, (val) >> 8 & 0xff }
 struct si2165_reg_value_pair {
 	u16 reg;
 	u8 val;
@@ -238,7 +209,7 @@ static int si2165_get_tune_settings(struct dvb_frontend *fe,
 
 static int si2165_init_pll(struct si2165_state *state)
 {
-	u32 ref_freq_Hz = state->config.ref_freq_Hz;
+	u32 ref_freq_hz = state->config.ref_freq_hz;
 	u8 divr = 1; /* 1..7 */
 	u8 divp = 1; /* only 1 or 4 */
 	u8 divn = 56; /* 1..63 */
@@ -250,7 +221,7 @@ static int si2165_init_pll(struct si2165_state *state)
 	 * hardcoded values can be deleted if calculation is verified
 	 * or it yields the same values as the windows driver
 	 */
-	switch (ref_freq_Hz) {
+	switch (ref_freq_hz) {
 	case 16000000u:
 		divn = 56;
 		break;
@@ -261,39 +232,39 @@ static int si2165_init_pll(struct si2165_state *state)
 		break;
 	default:
 		/* ref_freq / divr must be between 4 and 16 MHz */
-		if (ref_freq_Hz > 16000000u)
+		if (ref_freq_hz > 16000000u)
 			divr = 2;
 
 		/*
 		 * now select divn and divp such that
 		 * fvco is in 1624..1824 MHz
 		 */
-		if (1624000000u * divr > ref_freq_Hz * 2u * 63u)
+		if (1624000000u * divr > ref_freq_hz * 2u * 63u)
 			divp = 4;
 
 		/* is this already correct regarding rounding? */
-		divn = 1624000000u * divr / (ref_freq_Hz * 2u * divp);
+		divn = 1624000000u * divr / (ref_freq_hz * 2u * divp);
 		break;
 	}
 
 	/* adc_clk and sys_clk depend on xtal and pll settings */
-	state->fvco_hz = ref_freq_Hz / divr
+	state->fvco_hz = ref_freq_hz / divr
 			* 2u * divn * divp;
 	state->adc_clk = state->fvco_hz / (divm * 4u);
 	state->sys_clk = state->fvco_hz / (divl * 2u);
 
-	/* write pll registers 0x00a0..0x00a3 at once */
+	/* write all 4 pll registers 0x00a0..0x00a3 at once */
 	buf[0] = divl;
 	buf[1] = divm;
 	buf[2] = (divn & 0x3f) | ((divp == 1) ? 0x40 : 0x00) | 0x80;
 	buf[3] = divr;
-	return si2165_write(state, 0x00a0, buf, 4);
+	return si2165_write(state, REG_PLL_DIVL, buf, 4);
 }
 
 static int si2165_adjust_pll_divl(struct si2165_state *state, u8 divl)
 {
 	state->sys_clk = state->fvco_hz / (divl * 2u);
-	return si2165_writereg8(state, 0x00a0, divl); /* pll_divl */
+	return si2165_writereg8(state, REG_PLL_DIVL, divl);
 }
 
 static u32 si2165_get_fe_clk(struct si2165_state *state)
@@ -309,18 +280,18 @@ static int si2165_wait_init_done(struct si2165_state *state)
 	int i;
 
 	for (i = 0; i < 3; ++i) {
-		si2165_readreg8(state, 0x0054, &val);
+		si2165_readreg8(state, REG_INIT_DONE, &val);
 		if (val == 0x01)
 			return 0;
 		usleep_range(1000, 50000);
 	}
-	dev_err(&state->client->dev, "%s: init_done was not set\n",
-		KBUILD_MODNAME);
+	dev_err(&state->client->dev, "init_done was not set\n");
 	return ret;
 }
 
 static int si2165_upload_firmware_block(struct si2165_state *state,
-	const u8 *data, u32 len, u32 *poffset, u32 block_count)
+					const u8 *data, u32 len, u32 *poffset,
+					u32 block_count)
 {
 	int ret;
 	u8 buf_ctrl[4] = { 0x00, 0x00, 0x00, 0xc0 };
@@ -333,42 +304,43 @@ static int si2165_upload_firmware_block(struct si2165_state *state,
 	if (len % 4 != 0)
 		return -EINVAL;
 
-	deb_fw_load(
-		"si2165_upload_firmware_block called with len=0x%x offset=0x%x blockcount=0x%x\n",
-				len, offset, block_count);
-	while (offset+12 <= len && cur_block < block_count) {
-		deb_fw_load(
-			"si2165_upload_firmware_block in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
-					len, offset, cur_block, block_count);
+	dev_dbg(&state->client->dev,
+		"fw load: %s: called with len=0x%x offset=0x%x blockcount=0x%x\n",
+		__func__, len, offset, block_count);
+	while (offset + 12 <= len && cur_block < block_count) {
+		dev_dbg(&state->client->dev,
+			"fw load: %s: in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
+			__func__, len, offset, cur_block, block_count);
 		wordcount = data[offset];
-		if (wordcount < 1 || data[offset+1] ||
-		    data[offset+2] || data[offset+3]) {
+		if (wordcount < 1 || data[offset + 1] ||
+		    data[offset + 2] || data[offset + 3]) {
 			dev_warn(&state->client->dev,
-				 "%s: bad fw data[0..3] = %*ph\n",
-				KBUILD_MODNAME, 4, data);
+				 "bad fw data[0..3] = %*ph\n",
+				 4, data);
 			return -EINVAL;
 		}
 
 		if (offset + 8 + wordcount * 4 > len) {
 			dev_warn(&state->client->dev,
-				 "%s: len is too small for block len=%d, wordcount=%d\n",
-				KBUILD_MODNAME, len, wordcount);
+				 "len is too small for block len=%d, wordcount=%d\n",
+				len, wordcount);
 			return -EINVAL;
 		}
 
 		buf_ctrl[0] = wordcount - 1;
 
-		ret = si2165_write(state, 0x0364, buf_ctrl, 4);
+		ret = si2165_write(state, REG_DCOM_CONTROL_BYTE, buf_ctrl, 4);
 		if (ret < 0)
 			goto error;
-		ret = si2165_write(state, 0x0368, data+offset+4, 4);
+		ret = si2165_write(state, REG_DCOM_ADDR, data + offset + 4, 4);
 		if (ret < 0)
 			goto error;
 
 		offset += 8;
 
 		while (wordcount > 0) {
-			ret = si2165_write(state, 0x36c, data+offset, 4);
+			ret = si2165_write(state, REG_DCOM_DATA,
+					   data + offset, 4);
 			if (ret < 0)
 				goto error;
 			wordcount--;
@@ -377,15 +349,16 @@ static int si2165_upload_firmware_block(struct si2165_state *state,
 		cur_block++;
 	}
 
-	deb_fw_load(
-		"si2165_upload_firmware_block after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
-				len, offset, cur_block, block_count);
+	dev_dbg(&state->client->dev,
+		"fw load: %s: after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
+		__func__, len, offset, cur_block, block_count);
 
 	if (poffset)
 		*poffset = offset;
 
-	deb_fw_load("si2165_upload_firmware_block returned offset=0x%x\n",
-				offset);
+	dev_dbg(&state->client->dev,
+		"fw load: %s: returned offset=0x%x\n",
+		__func__, offset);
 
 	return 0;
 error:
@@ -413,43 +386,40 @@ static int si2165_upload_firmware(struct si2165_state *state)
 		fw_file = SI2165_FIRMWARE_REV_D;
 		break;
 	default:
-		dev_info(&state->client->dev, "%s: no firmware file for revision=%d\n",
-			KBUILD_MODNAME, state->chip_revcode);
+		dev_info(&state->client->dev, "no firmware file for revision=%d\n",
+			 state->chip_revcode);
 		return 0;
 	}
 
 	/* request the firmware, this will block and timeout */
 	ret = request_firmware(&fw, fw_file, &state->client->dev);
 	if (ret) {
-		dev_warn(&state->client->dev, "%s: firmware file '%s' not found\n",
-				KBUILD_MODNAME, fw_file);
+		dev_warn(&state->client->dev, "firmware file '%s' not found\n",
+			 fw_file);
 		goto error;
 	}
 
 	data = fw->data;
 	len = fw->size;
 
-	dev_info(&state->client->dev, "%s: downloading firmware from file '%s' size=%d\n",
-			KBUILD_MODNAME, fw_file, len);
+	dev_info(&state->client->dev, "downloading firmware from file '%s' size=%d\n",
+		 fw_file, len);
 
 	if (len % 4 != 0) {
-		dev_warn(&state->client->dev, "%s: firmware size is not multiple of 4\n",
-				KBUILD_MODNAME);
+		dev_warn(&state->client->dev, "firmware size is not multiple of 4\n");
 		ret = -EINVAL;
 		goto error;
 	}
 
 	/* check header (8 bytes) */
 	if (len < 8) {
-		dev_warn(&state->client->dev, "%s: firmware header is missing\n",
-				KBUILD_MODNAME);
+		dev_warn(&state->client->dev, "firmware header is missing\n");
 		ret = -EINVAL;
 		goto error;
 	}
 
 	if (data[0] != 1 || data[1] != 0) {
-		dev_warn(&state->client->dev, "%s: firmware file version is wrong\n",
-				KBUILD_MODNAME);
+		dev_warn(&state->client->dev, "firmware file version is wrong\n");
 		ret = -EINVAL;
 		goto error;
 	}
@@ -460,45 +430,45 @@ static int si2165_upload_firmware(struct si2165_state *state)
 
 	/* start uploading fw */
 	/* boot/wdog status */
-	ret = si2165_writereg8(state, 0x0341, 0x00);
+	ret = si2165_writereg8(state, REG_WDOG_AND_BOOT, 0x00);
 	if (ret < 0)
 		goto error;
 	/* reset */
-	ret = si2165_writereg8(state, 0x00c0, 0x00);
+	ret = si2165_writereg8(state, REG_RST_ALL, 0x00);
 	if (ret < 0)
 		goto error;
 	/* boot/wdog status */
-	ret = si2165_readreg8(state, 0x0341, val);
+	ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, val);
 	if (ret < 0)
 		goto error;
 
 	/* enable reset on error */
-	ret = si2165_readreg8(state, 0x035c, val);
+	ret = si2165_readreg8(state, REG_EN_RST_ERROR, val);
 	if (ret < 0)
 		goto error;
-	ret = si2165_readreg8(state, 0x035c, val);
+	ret = si2165_readreg8(state, REG_EN_RST_ERROR, val);
 	if (ret < 0)
 		goto error;
-	ret = si2165_writereg8(state, 0x035c, 0x02);
+	ret = si2165_writereg8(state, REG_EN_RST_ERROR, 0x02);
 	if (ret < 0)
 		goto error;
 
 	/* start right after the header */
 	offset = 8;
 
-	dev_info(&state->client->dev, "%s: si2165_upload_firmware extracted patch_version=0x%02x, block_count=0x%02x, crc_expected=0x%04x\n",
-		KBUILD_MODNAME, patch_version, block_count, crc_expected);
+	dev_info(&state->client->dev, "%s: extracted patch_version=0x%02x, block_count=0x%02x, crc_expected=0x%04x\n",
+		 __func__, patch_version, block_count, crc_expected);
 
 	ret = si2165_upload_firmware_block(state, data, len, &offset, 1);
 	if (ret < 0)
 		goto error;
 
-	ret = si2165_writereg8(state, 0x0344, patch_version);
+	ret = si2165_writereg8(state, REG_PATCH_VERSION, patch_version);
 	if (ret < 0)
 		goto error;
 
 	/* reset crc */
-	ret = si2165_writereg8(state, 0x0379, 0x01);
+	ret = si2165_writereg8(state, REG_RST_CRC, 0x01);
 	if (ret)
 		goto error;
 
@@ -506,20 +476,19 @@ static int si2165_upload_firmware(struct si2165_state *state)
 					   &offset, block_count);
 	if (ret < 0) {
 		dev_err(&state->client->dev,
-			"%s: firmware could not be uploaded\n",
-			KBUILD_MODNAME);
+			"firmware could not be uploaded\n");
 		goto error;
 	}
 
 	/* read crc */
-	ret = si2165_readreg16(state, 0x037a, &val16);
+	ret = si2165_readreg16(state, REG_CRC, &val16);
 	if (ret)
 		goto error;
 
 	if (val16 != crc_expected) {
 		dev_err(&state->client->dev,
-			"%s: firmware crc mismatch %04x != %04x\n",
-			KBUILD_MODNAME, val16, crc_expected);
+			"firmware crc mismatch %04x != %04x\n",
+			val16, crc_expected);
 		ret = -EINVAL;
 		goto error;
 	}
@@ -530,23 +499,23 @@ static int si2165_upload_firmware(struct si2165_state *state)
 
 	if (len != offset) {
 		dev_err(&state->client->dev,
-			"%s: firmware len mismatch %04x != %04x\n",
-			KBUILD_MODNAME, len, offset);
+			"firmware len mismatch %04x != %04x\n",
+			len, offset);
 		ret = -EINVAL;
 		goto error;
 	}
 
 	/* reset watchdog error register */
-	ret = si2165_writereg_mask8(state, 0x0341, 0x02, 0x02);
+	ret = si2165_writereg_mask8(state, REG_WDOG_AND_BOOT, 0x02, 0x02);
 	if (ret < 0)
 		goto error;
 
 	/* enable reset on error */
-	ret = si2165_writereg_mask8(state, 0x035c, 0x01, 0x01);
+	ret = si2165_writereg_mask8(state, REG_EN_RST_ERROR, 0x01, 0x01);
 	if (ret < 0)
 		goto error;
 
-	dev_info(&state->client->dev, "%s: fw load finished\n", KBUILD_MODNAME);
+	dev_info(&state->client->dev, "fw load finished\n");
 
 	ret = 0;
 	state->firmware_loaded = true;
@@ -563,46 +532,47 @@ static int si2165_init(struct dvb_frontend *fe)
 {
 	int ret = 0;
 	struct si2165_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	u8 val;
 	u8 patch_version = 0x00;
 
-	dprintk("%s: called\n", __func__);
+	dev_dbg(&state->client->dev, "%s: called\n", __func__);
 
 	/* powerup */
-	ret = si2165_writereg8(state, 0x0000, state->config.chip_mode);
+	ret = si2165_writereg8(state, REG_CHIP_MODE, state->config.chip_mode);
 	if (ret < 0)
 		goto error;
 	/* dsp_clock_enable */
-	ret = si2165_writereg8(state, 0x0104, 0x01);
+	ret = si2165_writereg8(state, REG_DSP_CLOCK, 0x01);
 	if (ret < 0)
 		goto error;
-	ret = si2165_readreg8(state, 0x0000, &val); /* verify chip_mode */
+	/* verify chip_mode */
+	ret = si2165_readreg8(state, REG_CHIP_MODE, &val);
 	if (ret < 0)
 		goto error;
 	if (val != state->config.chip_mode) {
-		dev_err(&state->client->dev, "%s: could not set chip_mode\n",
-			KBUILD_MODNAME);
+		dev_err(&state->client->dev, "could not set chip_mode\n");
 		return -EINVAL;
 	}
 
 	/* agc */
-	ret = si2165_writereg8(state, 0x018b, 0x00);
+	ret = si2165_writereg8(state, REG_AGC_IF_TRI, 0x00);
 	if (ret < 0)
 		goto error;
-	ret = si2165_writereg8(state, 0x0190, 0x01);
+	ret = si2165_writereg8(state, REG_AGC_IF_SLR, 0x01);
 	if (ret < 0)
 		goto error;
-	ret = si2165_writereg8(state, 0x0170, 0x00);
+	ret = si2165_writereg8(state, REG_AGC2_OUTPUT, 0x00);
 	if (ret < 0)
 		goto error;
-	ret = si2165_writereg8(state, 0x0171, 0x07);
+	ret = si2165_writereg8(state, REG_AGC2_CLKDIV, 0x07);
 	if (ret < 0)
 		goto error;
 	/* rssi pad */
-	ret = si2165_writereg8(state, 0x0646, 0x00);
+	ret = si2165_writereg8(state, REG_RSSI_PAD_CTRL, 0x00);
 	if (ret < 0)
 		goto error;
-	ret = si2165_writereg8(state, 0x0641, 0x00);
+	ret = si2165_writereg8(state, REG_RSSI_ENABLE, 0x00);
 	if (ret < 0)
 		goto error;
 
@@ -611,11 +581,11 @@ static int si2165_init(struct dvb_frontend *fe)
 		goto error;
 
 	/* enable chip_init */
-	ret = si2165_writereg8(state, 0x0050, 0x01);
+	ret = si2165_writereg8(state, REG_CHIP_INIT, 0x01);
 	if (ret < 0)
 		goto error;
 	/* set start_init */
-	ret = si2165_writereg8(state, 0x0096, 0x01);
+	ret = si2165_writereg8(state, REG_START_INIT, 0x01);
 	if (ret < 0)
 		goto error;
 	ret = si2165_wait_init_done(state);
@@ -623,29 +593,30 @@ static int si2165_init(struct dvb_frontend *fe)
 		goto error;
 
 	/* disable chip_init */
-	ret = si2165_writereg8(state, 0x0050, 0x00);
+	ret = si2165_writereg8(state, REG_CHIP_INIT, 0x00);
 	if (ret < 0)
 		goto error;
 
-	/* ber_pkt */
-	ret = si2165_writereg16(state, 0x0470, 0x7530);
+	/* ber_pkt - default 65535 */
+	ret = si2165_writereg16(state, REG_BER_PKT,
+				STATISTICS_PERIOD_PKT_COUNT);
 	if (ret < 0)
 		goto error;
 
-	ret = si2165_readreg8(state, 0x0344, &patch_version);
+	ret = si2165_readreg8(state, REG_PATCH_VERSION, &patch_version);
 	if (ret < 0)
 		goto error;
 
-	ret = si2165_writereg8(state, 0x00cb, 0x00);
+	ret = si2165_writereg8(state, REG_AUTO_RESET, 0x00);
 	if (ret < 0)
 		goto error;
 
 	/* dsp_addr_jump */
-	ret = si2165_writereg32(state, 0x0348, 0xf4000000);
+	ret = si2165_writereg32(state, REG_ADDR_JUMP, 0xf4000000);
 	if (ret < 0)
 		goto error;
 	/* boot/wdog status */
-	ret = si2165_readreg8(state, 0x0341, &val);
+	ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, &val);
 	if (ret < 0)
 		goto error;
 
@@ -656,18 +627,29 @@ static int si2165_init(struct dvb_frontend *fe)
 	}
 
 	/* ts output config */
-	ret = si2165_writereg8(state, 0x04e4, 0x20);
+	ret = si2165_writereg8(state, REG_TS_DATA_MODE, 0x20);
 	if (ret < 0)
 		return ret;
-	ret = si2165_writereg16(state, 0x04ef, 0x00fe);
+	ret = si2165_writereg16(state, REG_TS_TRI, 0x00fe);
 	if (ret < 0)
 		return ret;
-	ret = si2165_writereg24(state, 0x04f4, 0x555555);
+	ret = si2165_writereg24(state, REG_TS_SLR, 0x555555);
 	if (ret < 0)
 		return ret;
-	ret = si2165_writereg8(state, 0x04e5, 0x01);
+	ret = si2165_writereg8(state, REG_TS_CLK_MODE, 0x01);
 	if (ret < 0)
 		return ret;
+	ret = si2165_writereg8(state, REG_TS_PARALLEL_MODE, 0x00);
+	if (ret < 0)
+		return ret;
+
+	c = &state->fe.dtv_property_cache;
+	c->cnr.len = 1;
+	c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->post_bit_error.len = 1;
+	c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->post_bit_count.len = 1;
+	c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
 
 	return 0;
 error:
@@ -680,11 +662,11 @@ static int si2165_sleep(struct dvb_frontend *fe)
 	struct si2165_state *state = fe->demodulator_priv;
 
 	/* dsp clock disable */
-	ret = si2165_writereg8(state, 0x0104, 0x00);
+	ret = si2165_writereg8(state, REG_DSP_CLOCK, 0x00);
 	if (ret < 0)
 		return ret;
 	/* chip mode */
-	ret = si2165_writereg8(state, 0x0000, SI2165_MODE_OFF);
+	ret = si2165_writereg8(state, REG_CHIP_MODE, SI2165_MODE_OFF);
 	if (ret < 0)
 		return ret;
 	return 0;
@@ -693,18 +675,48 @@ static int si2165_sleep(struct dvb_frontend *fe)
 static int si2165_read_status(struct dvb_frontend *fe, enum fe_status *status)
 {
 	int ret;
-	u8 fec_lock = 0;
+	u8 u8tmp;
+	u32 u32tmp;
 	struct si2165_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u32 delsys = c->delivery_system;
 
-	if (!state->has_dvbt)
-		return -EINVAL;
+	*status = 0;
+
+	switch (delsys) {
+	case SYS_DVBT:
+		/* check fast signal type */
+		ret = si2165_readreg8(state, REG_CHECK_SIGNAL, &u8tmp);
+		if (ret < 0)
+			return ret;
+		switch (u8tmp & 0x3) {
+		case 0: /* searching */
+		case 1: /* nothing */
+			break;
+		case 2: /* digital signal */
+			*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+			break;
+		}
+		break;
+	case SYS_DVBC_ANNEX_A:
+		/* check packet sync lock */
+		ret = si2165_readreg8(state, REG_PS_LOCK, &u8tmp);
+		if (ret < 0)
+			return ret;
+		if (u8tmp & 0x01) {
+			*status |= FE_HAS_SIGNAL;
+			*status |= FE_HAS_CARRIER;
+			*status |= FE_HAS_VITERBI;
+			*status |= FE_HAS_SYNC;
+		}
+		break;
+	}
 
 	/* check fec_lock */
-	ret = si2165_readreg8(state, 0x4e0, &fec_lock);
+	ret = si2165_readreg8(state, REG_FEC_LOCK, &u8tmp);
 	if (ret < 0)
 		return ret;
-	*status = 0;
-	if (fec_lock & 0x01) {
+	if (u8tmp & 0x01) {
 		*status |= FE_HAS_SIGNAL;
 		*status |= FE_HAS_CARRIER;
 		*status |= FE_HAS_VITERBI;
@@ -712,6 +724,109 @@ static int si2165_read_status(struct dvb_frontend *fe, enum fe_status *status)
 		*status |= FE_HAS_LOCK;
 	}
 
+	/* CNR */
+	if (delsys == SYS_DVBC_ANNEX_A && *status & FE_HAS_VITERBI) {
+		ret = si2165_readreg24(state, REG_C_N, &u32tmp);
+		if (ret < 0)
+			return ret;
+		/*
+		 * svalue =
+		 * 1000 * c_n/dB =
+		 * 1000 * 10 * log10(2^24 / regval) =
+		 * 1000 * 10 * (log10(2^24) - log10(regval)) =
+		 * 1000 * 10 * (intlog10(2^24) - intlog10(regval)) / 2^24
+		 *
+		 * intlog10(x) = log10(x) * 2^24
+		 * intlog10(2^24) = log10(2^24) * 2^24 = 121210686
+		 */
+		u32tmp = (1000 * 10 * (121210686 - (u64)intlog10(u32tmp)))
+				>> 24;
+		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+		c->cnr.stat[0].svalue = u32tmp;
+	} else
+		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+	/* BER */
+	if (*status & FE_HAS_VITERBI) {
+		if (c->post_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
+			/* start new sampling period to get rid of old data*/
+			ret = si2165_writereg8(state, REG_BER_RST, 0x01);
+			if (ret < 0)
+				return ret;
+
+			/* set scale to enter read code on next call */
+			c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+			c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+			c->post_bit_error.stat[0].uvalue = 0;
+			c->post_bit_count.stat[0].uvalue = 0;
+
+			/*
+			 * reset DVBv3 value to deliver a good result
+			 * for the first call
+			 */
+			state->ber_prev = 0;
+
+		} else {
+			ret = si2165_readreg8(state, REG_BER_AVAIL, &u8tmp);
+			if (ret < 0)
+				return ret;
+
+			if (u8tmp & 1) {
+				u32 biterrcnt;
+
+				ret = si2165_readreg24(state, REG_BER_BIT,
+							&biterrcnt);
+				if (ret < 0)
+					return ret;
+
+				c->post_bit_error.stat[0].uvalue +=
+					biterrcnt;
+				c->post_bit_count.stat[0].uvalue +=
+					STATISTICS_PERIOD_BIT_COUNT;
+
+				/* start new sampling period */
+				ret = si2165_writereg8(state,
+							REG_BER_RST, 0x01);
+				if (ret < 0)
+					return ret;
+
+				dev_dbg(&state->client->dev,
+					"post_bit_error=%u post_bit_count=%u\n",
+					biterrcnt, STATISTICS_PERIOD_BIT_COUNT);
+			}
+		}
+	} else {
+		c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+		c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	}
+
+	return 0;
+}
+
+static int si2165_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+	if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
+		*snr = div_s64(c->cnr.stat[0].svalue, 100);
+	else
+		*snr = 0;
+	return 0;
+}
+
+static int si2165_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct si2165_state *state = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+	if (c->post_bit_error.stat[0].scale != FE_SCALE_COUNTER) {
+		*ber = 0;
+		return 0;
+	}
+
+	*ber = c->post_bit_error.stat[0].uvalue - state->ber_prev;
+	state->ber_prev = c->post_bit_error.stat[0].uvalue;
+
 	return 0;
 }
 
@@ -728,8 +843,8 @@ static int si2165_set_oversamp(struct si2165_state *state, u32 dvb_rate)
 	do_div(oversamp, dvb_rate);
 	reg_value = oversamp & 0x3fffffff;
 
-	dprintk("%s: Write oversamp=%#x\n", __func__, reg_value);
-	return si2165_writereg32(state, 0x00e4, reg_value);
+	dev_dbg(&state->client->dev, "Write oversamp=%#x\n", reg_value);
+	return si2165_writereg32(state, REG_OVERSAMP, reg_value);
 }
 
 static int si2165_set_if_freq_shift(struct si2165_state *state)
@@ -742,8 +857,7 @@ static int si2165_set_if_freq_shift(struct si2165_state *state)
 
 	if (!fe->ops.tuner_ops.get_if_frequency) {
 		dev_err(&state->client->dev,
-			"%s: Error: get_if_frequency() not defined at tuner. Can't work without it!\n",
-			KBUILD_MODNAME);
+			"Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
 		return -EINVAL;
 	}
 
@@ -763,30 +877,29 @@ static int si2165_set_if_freq_shift(struct si2165_state *state)
 	reg_value = reg_value & 0x1fffffff;
 
 	/* if_freq_shift, usbdump contained 0x023ee08f; */
-	return si2165_writereg32(state, 0x00e8, reg_value);
+	return si2165_writereg32(state, REG_IF_FREQ_SHIFT, reg_value);
 }
 
 static const struct si2165_reg_value_pair dvbt_regs[] = {
 	/* standard = DVB-T */
-	{ 0x00ec, 0x01 },
-	{ 0x08f8, 0x00 },
+	{ REG_DVB_STANDARD, 0x01 },
 	/* impulsive_noise_remover */
-	{ 0x031c, 0x01 },
-	{ 0x00cb, 0x00 },
+	{ REG_IMPULSIVE_NOISE_REM, 0x01 },
+	{ REG_AUTO_RESET, 0x00 },
 	/* agc2 */
-	{ 0x016e, 0x41 },
-	{ 0x016c, 0x0e },
-	{ 0x016d, 0x10 },
+	{ REG_AGC2_MIN, 0x41 },
+	{ REG_AGC2_KACQ, 0x0e },
+	{ REG_AGC2_KLOC, 0x10 },
 	/* agc */
-	{ 0x015b, 0x03 },
-	{ 0x0150, 0x78 },
+	{ REG_AGC_UNFREEZE_THR, 0x03 },
+	{ REG_AGC_CRESTF_DBX8, 0x78 },
 	/* agc */
-	{ 0x01a0, 0x78 },
-	{ 0x01c8, 0x68 },
+	{ REG_AAF_CRESTF_DBX8, 0x78 },
+	{ REG_ACI_CRESTF_DBX8, 0x68 },
 	/* freq_sync_range */
-	REG16(0x030c, 0x0064),
+	REG16(REG_FREQ_SYNC_RANGE, 0x0064),
 	/* gp_reg0 */
-	{ 0x0387, 0x00 }
+	{ REG_GP_REG0_MSB, 0x00 }
 };
 
 static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
@@ -798,7 +911,7 @@ static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
 	u16 bw10k;
 	u32 bw_hz = p->bandwidth_hz;
 
-	dprintk("%s: called\n", __func__);
+	dev_dbg(&state->client->dev, "%s: called\n", __func__);
 
 	if (!state->has_dvbt)
 		return -EINVAL;
@@ -815,7 +928,7 @@ static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
 		return ret;
 
 	/* bandwidth in 10KHz steps */
-	ret = si2165_writereg16(state, 0x0308, bw10k);
+	ret = si2165_writereg16(state, REG_T_BANDWIDTH, bw10k);
 	if (ret < 0)
 		return ret;
 	ret = si2165_set_oversamp(state, dvb_rate);
@@ -831,33 +944,30 @@ static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
 
 static const struct si2165_reg_value_pair dvbc_regs[] = {
 	/* standard = DVB-C */
-	{ 0x00ec, 0x05 },
-	{ 0x08f8, 0x00 },
+	{ REG_DVB_STANDARD, 0x05 },
 
 	/* agc2 */
-	{ 0x016e, 0x50 },
-	{ 0x016c, 0x0e },
-	{ 0x016d, 0x10 },
+	{ REG_AGC2_MIN, 0x50 },
+	{ REG_AGC2_KACQ, 0x0e },
+	{ REG_AGC2_KLOC, 0x10 },
 	/* agc */
-	{ 0x015b, 0x03 },
-	{ 0x0150, 0x68 },
+	{ REG_AGC_UNFREEZE_THR, 0x03 },
+	{ REG_AGC_CRESTF_DBX8, 0x68 },
 	/* agc */
-	{ 0x01a0, 0x68 },
-	{ 0x01c8, 0x50 },
+	{ REG_AAF_CRESTF_DBX8, 0x68 },
+	{ REG_ACI_CRESTF_DBX8, 0x50 },
 
-	{ 0x0278, 0x0d },
+	{ REG_EQ_AUTO_CONTROL, 0x0d },
 
-	{ 0x023a, 0x05 },
-	{ 0x0261, 0x09 },
-	REG16(0x0350, 0x3e80),
-	{ 0x02f4, 0x00 },
+	{ REG_KP_LOCK, 0x05 },
+	{ REG_CENTRAL_TAP, 0x09 },
+	REG16(REG_UNKNOWN_350, 0x3e80),
 
-	{ 0x00cb, 0x01 },
-	REG16(0x024c, 0x0000),
-	REG16(0x027c, 0x0000),
-	{ 0x0232, 0x03 },
-	{ 0x02f4, 0x0b },
-	{ 0x018b, 0x00 },
+	{ REG_AUTO_RESET, 0x01 },
+	REG16(REG_UNKNOWN_24C, 0x0000),
+	REG16(REG_UNKNOWN_27C, 0x0000),
+	{ REG_SWEEP_STEP, 0x03 },
+	{ REG_AGC_IF_TRI, 0x00 },
 };
 
 static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
@@ -866,7 +976,7 @@ static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
 	int ret;
 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 	const u32 dvb_rate = p->symbol_rate;
-	const u32 bw_hz = p->bandwidth_hz;
+	u8 u8tmp;
 
 	if (!state->has_dvbc)
 		return -EINVAL;
@@ -883,7 +993,32 @@ static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
 	if (ret < 0)
 		return ret;
 
-	ret = si2165_writereg32(state, 0x00c4, bw_hz);
+	switch (p->modulation) {
+	case QPSK:
+		u8tmp = 0x3;
+		break;
+	case QAM_16:
+		u8tmp = 0x7;
+		break;
+	case QAM_32:
+		u8tmp = 0x8;
+		break;
+	case QAM_64:
+		u8tmp = 0x9;
+		break;
+	case QAM_128:
+		u8tmp = 0xa;
+		break;
+	case QAM_256:
+	default:
+		u8tmp = 0xb;
+		break;
+	}
+	ret = si2165_writereg8(state, REG_REQ_CONSTELLATION, u8tmp);
+	if (ret < 0)
+		return ret;
+
+	ret = si2165_writereg32(state, REG_LOCK_TIMEOUT, 0x007a1200);
 	if (ret < 0)
 		return ret;
 
@@ -894,12 +1029,12 @@ static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
 	return 0;
 }
 
-static const struct si2165_reg_value_pair agc_rewrite[] = {
-	{ 0x012a, 0x46 },
-	{ 0x012c, 0x00 },
-	{ 0x012e, 0x0a },
-	{ 0x012f, 0xff },
-	{ 0x0123, 0x70 }
+static const struct si2165_reg_value_pair adc_rewrite[] = {
+	{ REG_ADC_RI1, 0x46 },
+	{ REG_ADC_RI3, 0x00 },
+	{ REG_ADC_RI5, 0x0a },
+	{ REG_ADC_RI6, 0xff },
+	{ REG_ADC_RI8, 0x70 }
 };
 
 static int si2165_set_frontend(struct dvb_frontend *fe)
@@ -931,7 +1066,7 @@ static int si2165_set_frontend(struct dvb_frontend *fe)
 	}
 
 	/* dsp_addr_jump */
-	ret = si2165_writereg32(state, 0x0348, 0xf4000000);
+	ret = si2165_writereg32(state, REG_ADDR_JUMP, 0xf4000000);
 	if (ret < 0)
 		return ret;
 
@@ -944,34 +1079,34 @@ static int si2165_set_frontend(struct dvb_frontend *fe)
 		return ret;
 
 	/* boot/wdog status */
-	ret = si2165_readreg8(state, 0x0341, val);
+	ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, val);
 	if (ret < 0)
 		return ret;
-	ret = si2165_writereg8(state, 0x0341, 0x00);
+	ret = si2165_writereg8(state, REG_WDOG_AND_BOOT, 0x00);
 	if (ret < 0)
 		return ret;
 
 	/* reset all */
-	ret = si2165_writereg8(state, 0x00c0, 0x00);
+	ret = si2165_writereg8(state, REG_RST_ALL, 0x00);
 	if (ret < 0)
 		return ret;
 	/* gp_reg0 */
-	ret = si2165_writereg32(state, 0x0384, 0x00000000);
+	ret = si2165_writereg32(state, REG_GP_REG0_LSB, 0x00000000);
 	if (ret < 0)
 		return ret;
 
 	/* write adc values after each reset*/
-	ret = si2165_write_reg_list(state, agc_rewrite,
-				    ARRAY_SIZE(agc_rewrite));
+	ret = si2165_write_reg_list(state, adc_rewrite,
+				    ARRAY_SIZE(adc_rewrite));
 	if (ret < 0)
 		return ret;
 
 	/* start_synchro */
-	ret = si2165_writereg8(state, 0x02e0, 0x01);
+	ret = si2165_writereg8(state, REG_START_SYNCHRO, 0x01);
 	if (ret < 0)
 		return ret;
 	/* boot/wdog status */
-	ret = si2165_readreg8(state, 0x0341, val);
+	ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, val);
 	if (ret < 0)
 		return ret;
 
@@ -998,7 +1133,6 @@ static const struct dvb_frontend_ops si2165_ops = {
 			FE_CAN_QAM_64 |
 			FE_CAN_QAM_128 |
 			FE_CAN_QAM_256 |
-			FE_CAN_QAM_AUTO |
 			FE_CAN_GUARD_INTERVAL_AUTO |
 			FE_CAN_HIERARCHY_AUTO |
 			FE_CAN_MUTE_TS |
@@ -1013,10 +1147,12 @@ static const struct dvb_frontend_ops si2165_ops = {
 
 	.set_frontend      = si2165_set_frontend,
 	.read_status       = si2165_read_status,
+	.read_snr          = si2165_read_snr,
+	.read_ber          = si2165_read_ber,
 };
 
 static int si2165_probe(struct i2c_client *client,
-		const struct i2c_device_id *id)
+			const struct i2c_device_id *id)
 {
 	struct si2165_state *state = NULL;
 	struct si2165_platform_data *pdata = client->dev.platform_data;
@@ -1032,8 +1168,8 @@ static int si2165_probe(struct i2c_client *client,
 	};
 
 	/* allocate memory for the internal state */
-	state = kzalloc(sizeof(struct si2165_state), GFP_KERNEL);
-	if (state == NULL) {
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state) {
 		ret = -ENOMEM;
 		goto error;
 	}
@@ -1049,45 +1185,45 @@ static int si2165_probe(struct i2c_client *client,
 	state->client = client;
 	state->config.i2c_addr = client->addr;
 	state->config.chip_mode = pdata->chip_mode;
-	state->config.ref_freq_Hz = pdata->ref_freq_Hz;
+	state->config.ref_freq_hz = pdata->ref_freq_hz;
 	state->config.inversion = pdata->inversion;
 
-	if (state->config.ref_freq_Hz < 4000000
-	    || state->config.ref_freq_Hz > 27000000) {
-		dev_err(&state->client->dev, "%s: ref_freq of %d Hz not supported by this driver\n",
-			 KBUILD_MODNAME, state->config.ref_freq_Hz);
+	if (state->config.ref_freq_hz < 4000000 ||
+	    state->config.ref_freq_hz > 27000000) {
+		dev_err(&state->client->dev, "ref_freq of %d Hz not supported by this driver\n",
+			state->config.ref_freq_hz);
 		ret = -EINVAL;
 		goto error;
 	}
 
 	/* create dvb_frontend */
 	memcpy(&state->fe.ops, &si2165_ops,
-		sizeof(struct dvb_frontend_ops));
+	       sizeof(struct dvb_frontend_ops));
 	state->fe.ops.release = NULL;
 	state->fe.demodulator_priv = state;
 	i2c_set_clientdata(client, state);
 
 	/* powerup */
-	ret = si2165_writereg8(state, 0x0000, state->config.chip_mode);
+	ret = si2165_writereg8(state, REG_CHIP_MODE, state->config.chip_mode);
 	if (ret < 0)
 		goto nodev_error;
 
-	ret = si2165_readreg8(state, 0x0000, &val);
+	ret = si2165_readreg8(state, REG_CHIP_MODE, &val);
 	if (ret < 0)
 		goto nodev_error;
 	if (val != state->config.chip_mode)
 		goto nodev_error;
 
-	ret = si2165_readreg8(state, 0x0023, &state->chip_revcode);
+	ret = si2165_readreg8(state, REG_CHIP_REVCODE, &state->chip_revcode);
 	if (ret < 0)
 		goto nodev_error;
 
-	ret = si2165_readreg8(state, 0x0118, &state->chip_type);
+	ret = si2165_readreg8(state, REV_CHIP_TYPE, &state->chip_type);
 	if (ret < 0)
 		goto nodev_error;
 
 	/* powerdown */
-	ret = si2165_writereg8(state, 0x0000, SI2165_MODE_OFF);
+	ret = si2165_writereg8(state, REG_CHIP_MODE, SI2165_MODE_OFF);
 	if (ret < 0)
 		goto nodev_error;
 
@@ -1107,18 +1243,18 @@ static int si2165_probe(struct i2c_client *client,
 		state->has_dvbc = true;
 		break;
 	default:
-		dev_err(&state->client->dev, "%s: Unsupported Silicon Labs chip (type %d, rev %d)\n",
-			KBUILD_MODNAME, state->chip_type, state->chip_revcode);
+		dev_err(&state->client->dev, "Unsupported Silicon Labs chip (type %d, rev %d)\n",
+			state->chip_type, state->chip_revcode);
 		goto nodev_error;
 	}
 
 	dev_info(&state->client->dev,
-		"%s: Detected Silicon Labs %s-%c (type %d, rev %d)\n",
-		KBUILD_MODNAME, chip_name, rev_char, state->chip_type,
+		 "Detected Silicon Labs %s-%c (type %d, rev %d)\n",
+		chip_name, rev_char, state->chip_type,
 		state->chip_revcode);
 
 	strlcat(state->fe.ops.info.name, chip_name,
-			sizeof(state->fe.ops.info.name));
+		sizeof(state->fe.ops.info.name));
 
 	n = 0;
 	if (state->has_dvbt) {
@@ -1173,9 +1309,6 @@ static struct i2c_driver si2165_driver = {
 
 module_i2c_driver(si2165_driver);
 
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
 MODULE_DESCRIPTION("Silicon Labs Si2165 DVB-C/-T Demodulator driver");
 MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/si2165.h b/drivers/media/dvb-frontends/si2165.h
index 76c2ca7..74a57b7 100644
--- a/drivers/media/dvb-frontends/si2165.h
+++ b/drivers/media/dvb-frontends/si2165.h
@@ -1,21 +1,22 @@
 /*
-    Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
-
-    Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    References:
-    http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
-*/
+ * Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
+ *
+ * Copyright (C) 2013-2017 Matthias Schwarzott <zzam@gentoo.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ * References:
+ *   http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
+ *
+ */
 
 #ifndef _DVB_SI2165_H
 #define _DVB_SI2165_H
@@ -44,7 +45,7 @@ struct si2165_platform_data {
 	/* frequency of external clock or xtal in Hz
 	 * possible values: 4000000, 16000000, 20000000, 240000000, 27000000
 	 */
-	u32 ref_freq_Hz;
+	u32 ref_freq_hz;
 
 	/* invert the spectrum */
 	bool inversion;
diff --git a/drivers/media/dvb-frontends/si2165_priv.h b/drivers/media/dvb-frontends/si2165_priv.h
index e593211..8c6fbfe 100644
--- a/drivers/media/dvb-frontends/si2165_priv.h
+++ b/drivers/media/dvb-frontends/si2165_priv.h
@@ -1,19 +1,19 @@
 /*
-    Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
-
-    Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-*/
+ * Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
+ *
+ * Copyright (C) 2013-2017 Matthias Schwarzott <zzam@gentoo.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ */
 
 #ifndef _DVB_SI2165_PRIV
 #define _DVB_SI2165_PRIV
@@ -22,7 +22,8 @@
 
 struct si2165_config {
 	/* i2c addr
-	 * possible values: 0x64,0x65,0x66,0x67 */
+	 * possible values: 0x64,0x65,0x66,0x67
+	 */
 	u8 i2c_addr;
 
 	/* external clock or XTAL */
@@ -31,10 +32,89 @@ struct si2165_config {
 	/* frequency of external clock or xtal in Hz
 	 * possible values: 4000000, 16000000, 20000000, 240000000, 27000000
 	 */
-	u32 ref_freq_Hz;
+	u32 ref_freq_hz;
 
 	/* invert the spectrum */
 	bool inversion;
 };
 
+#define STATISTICS_PERIOD_PKT_COUNT	30000u
+#define STATISTICS_PERIOD_BIT_COUNT	(STATISTICS_PERIOD_PKT_COUNT * 204 * 8)
+
+#define REG_CHIP_MODE			0x0000
+#define REG_CHIP_REVCODE		0x0023
+#define REV_CHIP_TYPE			0x0118
+#define REG_CHIP_INIT			0x0050
+#define REG_INIT_DONE			0x0054
+#define REG_START_INIT			0x0096
+#define REG_PLL_DIVL			0x00a0
+#define REG_RST_ALL			0x00c0
+#define REG_LOCK_TIMEOUT		0x00c4
+#define REG_AUTO_RESET			0x00cb
+#define REG_OVERSAMP			0x00e4
+#define REG_IF_FREQ_SHIFT		0x00e8
+#define REG_DVB_STANDARD		0x00ec
+#define REG_DSP_CLOCK			0x0104
+#define REG_ADC_RI8			0x0123
+#define REG_ADC_RI1			0x012a
+#define REG_ADC_RI2			0x012b
+#define REG_ADC_RI3			0x012c
+#define REG_ADC_RI4			0x012d
+#define REG_ADC_RI5			0x012e
+#define REG_ADC_RI6			0x012f
+#define REG_AGC_CRESTF_DBX8		0x0150
+#define REG_AGC_UNFREEZE_THR		0x015b
+#define REG_AGC2_MIN			0x016e
+#define REG_AGC2_KACQ			0x016c
+#define REG_AGC2_KLOC			0x016d
+#define REG_AGC2_OUTPUT			0x0170
+#define REG_AGC2_CLKDIV			0x0171
+#define REG_AGC_IF_TRI			0x018b
+#define REG_AGC_IF_SLR			0x0190
+#define REG_AAF_CRESTF_DBX8		0x01a0
+#define REG_ACI_CRESTF_DBX8		0x01c8
+#define REG_SWEEP_STEP			0x0232
+#define REG_KP_LOCK			0x023a
+#define REG_UNKNOWN_24C			0x024c
+#define REG_CENTRAL_TAP			0x0261
+#define REG_C_N				0x026c
+#define REG_EQ_AUTO_CONTROL		0x0278
+#define REG_UNKNOWN_27C			0x027c
+#define REG_START_SYNCHRO		0x02e0
+#define REG_REQ_CONSTELLATION		0x02f4
+#define REG_T_BANDWIDTH			0x0308
+#define REG_FREQ_SYNC_RANGE		0x030c
+#define REG_IMPULSIVE_NOISE_REM		0x031c
+#define REG_WDOG_AND_BOOT		0x0341
+#define REG_PATCH_VERSION		0x0344
+#define REG_ADDR_JUMP			0x0348
+#define REG_UNKNOWN_350			0x0350
+#define REG_EN_RST_ERROR		0x035c
+#define REG_DCOM_CONTROL_BYTE		0x0364
+#define REG_DCOM_ADDR			0x0368
+#define REG_DCOM_DATA			0x036c
+#define REG_RST_CRC			0x0379
+#define REG_GP_REG0_LSB			0x0384
+#define REG_GP_REG0_MSB			0x0387
+#define REG_CRC				0x037a
+#define REG_CHECK_SIGNAL		0x03a8
+#define REG_CBER_RST			0x0424
+#define REG_CBER_BIT			0x0428
+#define REG_CBER_ERR			0x0430
+#define REG_CBER_AVAIL			0x0434
+#define REG_PS_LOCK			0x0440
+#define REG_UNCOR_CNT			0x0468
+#define REG_BER_RST			0x046c
+#define REG_BER_PKT			0x0470
+#define REG_BER_BIT			0x0478
+#define REG_BER_AVAIL			0x047c
+#define REG_FEC_LOCK			0x04e0
+#define REG_TS_DATA_MODE		0x04e4
+#define REG_TS_CLK_MODE			0x04e5
+#define REG_TS_TRI			0x04ef
+#define REG_TS_SLR			0x04f4
+#define REG_RSSI_ENABLE			0x0641
+#define REG_RSSI_PAD_CTRL		0x0646
+#define REG_TS_PARALLEL_MODE		0x08f8
+
 #endif /* _DVB_SI2165_PRIV */
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 41d9c51..539399d 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -14,6 +14,8 @@
  *    GNU General Public License for more details.
  */
 
+#include <linux/delay.h>
+
 #include "si2168_priv.h"
 
 static const struct dvb_frontend_ops si2168_ops;
@@ -435,6 +437,7 @@ static int si2168_init(struct dvb_frontend *fe)
 		if (ret)
 			goto err;
 
+		udelay(100);
 		memcpy(cmd.args, "\x85", 1);
 		cmd.wlen = 1;
 		cmd.rlen = 1;
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h
index 737cf416..3c8746a 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -18,7 +18,7 @@
 #define SI2168_PRIV_H
 
 #include "si2168.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include <linux/firmware.h>
 #include <linux/i2c-mux.h>
 #include <linux/kernel.h>
diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c
index 4e8c3ac..9b32a1b 100644
--- a/drivers/media/dvb-frontends/si21xx.c
+++ b/drivers/media/dvb-frontends/si21xx.c
@@ -16,7 +16,7 @@
 #include <linux/jiffies.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "si21xx.h"
 
 #define	REVISION_REG			0x00
diff --git a/drivers/media/dvb-frontends/si21xx.h b/drivers/media/dvb-frontends/si21xx.h
index 43d480b..12fa1d5 100644
--- a/drivers/media/dvb-frontends/si21xx.h
+++ b/drivers/media/dvb-frontends/si21xx.h
@@ -3,7 +3,7 @@
 #define SI21XX_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct si21xx_config {
 	/* the demodulator's i2c address */
diff --git a/drivers/media/dvb-frontends/sp2.h b/drivers/media/dvb-frontends/sp2.h
index 3901cd7..1bf60b8 100644
--- a/drivers/media/dvb-frontends/sp2.h
+++ b/drivers/media/dvb-frontends/sp2.h
@@ -17,7 +17,7 @@
 #ifndef SP2_H
 #define SP2_H
 
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 
 /*
  * I2C address
diff --git a/drivers/media/dvb-frontends/sp2_priv.h b/drivers/media/dvb-frontends/sp2_priv.h
index 37fef7b..c9ee530 100644
--- a/drivers/media/dvb-frontends/sp2_priv.h
+++ b/drivers/media/dvb-frontends/sp2_priv.h
@@ -18,7 +18,7 @@
 #define SP2_PRIV_H
 
 #include "sp2.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /* state struct */
 struct sp2 {
diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c
index 04454cb78..9a726f3 100644
--- a/drivers/media/dvb-frontends/sp8870.c
+++ b/drivers/media/dvb-frontends/sp8870.c
@@ -35,7 +35,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "sp8870.h"
 
 
diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c
index d2c402b..572a297 100644
--- a/drivers/media/dvb-frontends/sp887x.c
+++ b/drivers/media/dvb-frontends/sp887x.c
@@ -17,7 +17,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "sp887x.h"
 
 
diff --git a/drivers/media/dvb-frontends/stb0899_algo.c b/drivers/media/dvb-frontends/stb0899_algo.c
index 3012f19..bd2defd 100644
--- a/drivers/media/dvb-frontends/stb0899_algo.c
+++ b/drivers/media/dvb-frontends/stb0899_algo.c
@@ -925,8 +925,7 @@ static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state)
 		wn = (4 * zeta * zeta) + 1000000;
 		wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn;  /*wn =wn 10^-8*/
 
-		k_indirect = (wn * wn) / K;
-		k_indirect = k_indirect;	  /*kindirect = kindirect 10^-6*/
+		k_indirect = (wn * wn) / K;	/*kindirect = kindirect 10^-6*/
 		k_direct   = (2 * wn * zeta) / K;	/*kDirect = kDirect 10^-2*/
 		k_direct  *= 100;
 
diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
index 0234759..3c654ae 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.c
+++ b/drivers/media/dvb-frontends/stb0899_drv.c
@@ -27,7 +27,7 @@
 #include <linux/string.h>
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "stb0899_drv.h"
 #include "stb0899_priv.h"
@@ -539,7 +539,8 @@ int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data,
 
 int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
 {
-	return stb0899_write_regs(state, reg, &data, 1);
+	u8 tmp = data;
+	return stb0899_write_regs(state, reg, &tmp, 1);
 }
 
 /*
@@ -1582,15 +1583,15 @@ static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe)
 static const struct dvb_frontend_ops stb0899_ops = {
 	.delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
 	.info = {
-		.name 			= "STB0899 Multistandard",
+		.name			= "STB0899 Multistandard",
 		.frequency_min		= 950000,
-		.frequency_max 		= 2150000,
+		.frequency_max		= 2150000,
 		.frequency_stepsize	= 0,
 		.frequency_tolerance	= 0,
-		.symbol_rate_min 	=  5000000,
-		.symbol_rate_max 	= 45000000,
+		.symbol_rate_min	=  5000000,
+		.symbol_rate_max	= 45000000,
 
-		.caps 			= FE_CAN_INVERSION_AUTO	|
+		.caps			= FE_CAN_INVERSION_AUTO	|
 					  FE_CAN_FEC_AUTO	|
 					  FE_CAN_2G_MODULATION	|
 					  FE_CAN_QPSK
diff --git a/drivers/media/dvb-frontends/stb0899_drv.h b/drivers/media/dvb-frontends/stb0899_drv.h
index 0a72131..f65f9a8 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.h
+++ b/drivers/media/dvb-frontends/stb0899_drv.h
@@ -25,7 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #define STB0899_TSMODE_SERIAL		1
 #define STB0899_CLKPOL_FALLING		2
@@ -82,7 +82,7 @@ enum stb0899_inversion {
  * 1. POWER ON/OFF		(index 0)
  * 2. FE_HAS_LOCK/LOCK_LOSS	(index 1)
  *
- * @gpio 	= one of the above listed GPIO's
+ * @gpio	= one of the above listed GPIO's
  * @level	= output state: pulled up or low
  */
 struct stb0899_postproc {
diff --git a/drivers/media/dvb-frontends/stb0899_priv.h b/drivers/media/dvb-frontends/stb0899_priv.h
index 82395b9..3285cd1 100644
--- a/drivers/media/dvb-frontends/stb0899_priv.h
+++ b/drivers/media/dvb-frontends/stb0899_priv.h
@@ -22,7 +22,7 @@
 #ifndef __STB0899_PRIV_H
 #define __STB0899_PRIV_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "stb0899_drv.h"
 
 #define FE_ERROR				0
@@ -252,7 +252,7 @@ extern int stb0899_write_s2reg(struct stb0899_state *state,
 extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
 
 
-#define STB0899_READ_S2REG(DEVICE, REG) 	(_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
+#define STB0899_READ_S2REG(DEVICE, REG)		(_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
 //#define STB0899_WRITE_S2REG(DEVICE, REG, DATA)	(_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA))
 
 /* stb0899_algo.c	*/
diff --git a/drivers/media/dvb-frontends/stb6000.h b/drivers/media/dvb-frontends/stb6000.h
index e94a3d5f..1adda72 100644
--- a/drivers/media/dvb-frontends/stb6000.h
+++ b/drivers/media/dvb-frontends/stb6000.h
@@ -24,7 +24,7 @@
 #define __DVB_STB6000_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #if IS_REACHABLE(CONFIG_DVB_STB6000)
 /**
diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c
index 17a955d..3a851f5 100644
--- a/drivers/media/dvb-frontends/stb6100.c
+++ b/drivers/media/dvb-frontends/stb6100.c
@@ -25,7 +25,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "stb6100.h"
 
 static unsigned int verbose;
@@ -226,12 +226,14 @@ static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int st
 
 static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
 {
+	u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
 	if (unlikely(reg >= STB6100_NUMREGS)) {
 		dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
 		return -EREMOTEIO;
 	}
-	data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set;
-	return stb6100_write_reg_range(state, &data, reg, 1);
+	tmp = (tmp & stb6100_template[reg].mask) | stb6100_template[reg].set;
+	return stb6100_write_reg_range(state, &tmp, reg, 1);
 }
 
 
diff --git a/drivers/media/dvb-frontends/stb6100.h b/drivers/media/dvb-frontends/stb6100.h
index f7b468b..6cdae68 100644
--- a/drivers/media/dvb-frontends/stb6100.h
+++ b/drivers/media/dvb-frontends/stb6100.h
@@ -23,7 +23,7 @@
 #define __STB_6100_REG_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #define STB6100_LD			0x00
 #define STB6100_LD_LOCK			(1 << 0)
diff --git a/drivers/media/dvb-frontends/stb6100_cfg.h b/drivers/media/dvb-frontends/stb6100_cfg.h
index 2ef67aa..203f9b3 100644
--- a/drivers/media/dvb-frontends/stb6100_cfg.h
+++ b/drivers/media/dvb-frontends/stb6100_cfg.h
@@ -20,7 +20,7 @@
 */
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 {
diff --git a/drivers/media/dvb-frontends/stb6100_proc.h b/drivers/media/dvb-frontends/stb6100_proc.h
index 50ffa21..fad877b 100644
--- a/drivers/media/dvb-frontends/stb6100_proc.h
+++ b/drivers/media/dvb-frontends/stb6100_proc.h
@@ -18,7 +18,7 @@
 */
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
 {
diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c
index 67f91814..f947ed9 100644
--- a/drivers/media/dvb-frontends/stv0288.c
+++ b/drivers/media/dvb-frontends/stv0288.c
@@ -33,7 +33,7 @@
 #include <linux/jiffies.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "stv0288.h"
 
 struct stv0288_state {
diff --git a/drivers/media/dvb-frontends/stv0288.h b/drivers/media/dvb-frontends/stv0288.h
index 803acb9..c10227a 100644
--- a/drivers/media/dvb-frontends/stv0288.h
+++ b/drivers/media/dvb-frontends/stv0288.h
@@ -28,7 +28,7 @@
 #define STV0288_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct stv0288_config {
 	/* the demodulator's i2c address */
diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c
index db94d4d..b823c04 100644
--- a/drivers/media/dvb-frontends/stv0297.c
+++ b/drivers/media/dvb-frontends/stv0297.c
@@ -27,7 +27,7 @@
 #include <linux/jiffies.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "stv0297.h"
 
 struct stv0297_state {
diff --git a/drivers/media/dvb-frontends/stv0297.h b/drivers/media/dvb-frontends/stv0297.h
index b30632a..8fa5ac7 100644
--- a/drivers/media/dvb-frontends/stv0297.h
+++ b/drivers/media/dvb-frontends/stv0297.h
@@ -22,7 +22,7 @@
 #define STV0297_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct stv0297_config
 {
diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c
index b1f3d67..633b90e 100644
--- a/drivers/media/dvb-frontends/stv0299.c
+++ b/drivers/media/dvb-frontends/stv0299.c
@@ -51,7 +51,7 @@
 #include <linux/jiffies.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "stv0299.h"
 
 struct stv0299_state {
diff --git a/drivers/media/dvb-frontends/stv0299.h b/drivers/media/dvb-frontends/stv0299.h
index 0aca30a..700c124 100644
--- a/drivers/media/dvb-frontends/stv0299.h
+++ b/drivers/media/dvb-frontends/stv0299.h
@@ -46,7 +46,7 @@
 #define STV0299_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #define STV0299_LOCKOUTPUT_0  0
 #define STV0299_LOCKOUTPUT_1  1
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index f3529df..5435c90 100644
--- a/drivers/media/dvb-frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
@@ -25,7 +25,7 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 
-#include "dvb_math.h"
+#include <media/dvb_math.h>
 
 #include "stv0367.h"
 #include "stv0367_defs.h"
@@ -166,7 +166,9 @@ int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
 
 static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
 {
-	return stv0367_writeregs(state, reg, &data, 1);
+	u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+	return stv0367_writeregs(state, reg, &tmp, 1);
 }
 
 static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
@@ -1547,7 +1549,6 @@ static int stv0367ter_read_ber(struct dvb_frontend *fe, u32 *ber)
 	} else if (abc == 0x7) {
 		if (Errors <= 4) {
 			temporary = (Errors * 1000000000) / (8 * (1 << 14));
-			temporary =  temporary;
 		} else if (Errors <= 42) {
 			temporary = (Errors * 100000000) / (8 * (1 << 14));
 			temporary = temporary * 10;
@@ -1625,7 +1626,6 @@ static u32 stv0367ter_get_per(struct stv0367_state *state)
 	else if (abc == 0x9) {
 		if (Errors <= 4) {
 			temporary = (Errors * 1000000000) / (8 * (1 << 8));
-			temporary =  temporary;
 		} else if (Errors <= 42) {
 			temporary = (Errors * 100000000) / (8 * (1 << 8));
 			temporary = temporary * 10;
diff --git a/drivers/media/dvb-frontends/stv0367.h b/drivers/media/dvb-frontends/stv0367.h
index 8f7a314..14a50ec 100644
--- a/drivers/media/dvb-frontends/stv0367.h
+++ b/drivers/media/dvb-frontends/stv0367.h
@@ -23,7 +23,7 @@
 #define STV0367_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #define STV0367_ICSPEED_53125	53125000
 #define STV0367_ICSPEED_58000	58000000
diff --git a/drivers/media/dvb-frontends/stv0900.h b/drivers/media/dvb-frontends/stv0900.h
index 1571a46..5dbe1e5 100644
--- a/drivers/media/dvb-frontends/stv0900.h
+++ b/drivers/media/dvb-frontends/stv0900.h
@@ -23,7 +23,7 @@
 #define STV0900_H
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct stv0900_reg {
 	u16 addr;
diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c
index 0b73972..72f17b9 100644
--- a/drivers/media/dvb-frontends/stv0900_core.c
+++ b/drivers/media/dvb-frontends/stv0900_core.c
@@ -1929,7 +1929,7 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
 	switch (demod) {
 	case 0:
 	case 1:
-		init_params.dmd_ref_clk  	= config->xtal;
+		init_params.dmd_ref_clk		= config->xtal;
 		init_params.demod_mode		= config->demod_mode;
 		init_params.rolloff		= STV0900_35;
 		init_params.path1_ts_clock	= config->path1_mode;
diff --git a/drivers/media/dvb-frontends/stv0900_init.h b/drivers/media/dvb-frontends/stv0900_init.h
index 4119414..550ef4a 100644
--- a/drivers/media/dvb-frontends/stv0900_init.h
+++ b/drivers/media/dvb-frontends/stv0900_init.h
@@ -148,8 +148,8 @@ struct stv0900_short_frames_car_loop_optim_vs_mod {
 
 /* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
 static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
-	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
-				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	/*Modcod		2MPon	2MPoff	5MPon	5MPoff	10MPon
+				10MPoff	20MPon	20MPoff	30MPon	30MPoff */
 	{ STV0900_QPSK_12,	0x1C,	0x0D,	0x1B,	0x2C,	0x3A,
 				0x1C,	0x2A,	0x3B,	0x2A,	0x1B },
 	{ STV0900_QPSK_35,	0x2C,	0x0D,	0x2B,	0x2C,	0x3A,
@@ -176,15 +176,15 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
 				0x0B,	0x39,	0x1A,	0x19,	0x0A },
 	{ STV0900_8PSK_89,	0x3B,	0x3B,	0x0B,	0x2B,	0x2A,
 				0x0B,	0x39,	0x1A,	0x29,	0x39 },
-	{ STV0900_8PSK_910,	0x3B,	0x3B, 	0x0B,	0x2B, 	0x2A,
+	{ STV0900_8PSK_910,	0x3B,	0x3B,	0x0B,	0x2B,	0x2A,
 				0x0B,	0x39,	0x1A,	0x29,	0x39 }
 };
 
 
 /* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
 static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
-	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
-				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	/* Modcod		2MPon	2MPoff	5MPon	5MPoff	10MPon
+				10MPoff	20MPon	20MPoff	30MPon	30MPoff */
 	{ STV0900_QPSK_12,	0x1F,	0x3F,	0x1E,	0x3F,	0x3D,
 				0x1F,	0x3D,	0x3E,	0x3D,	0x1E },
 	{ STV0900_QPSK_35,	0x2F,	0x3F,	0x2E,	0x2F,	0x3D,
@@ -211,7 +211,7 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
 				0x1e,	0x3c,	0x2d,	0x2c,	0x1d },
 	{ STV0900_8PSK_89,	0x3e,	0x3e,	0x1e,	0x2e,	0x3d,
 				0x1e,	0x0d,	0x2d,	0x3c,	0x1d },
-	{ STV0900_8PSK_910,	0x3e,	0x3e, 	0x1e,	0x2e, 	0x3d,
+	{ STV0900_8PSK_910,	0x3e,	0x3e,	0x1e,	0x2e,	0x3d,
 				0x1e,	0x1d,	0x2d,	0x0d,	0x1d },
 };
 
@@ -219,8 +219,8 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
 
 /* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
 static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
-	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
-				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	/* Modcod		2MPon	2MPoff	5MPon	5MPoff	10MPon
+				10MPoff	20MPon	20MPoff	30MPon	30MPoff */
 	{ STV0900_16APSK_23,	0x0C,	0x0C,	0x0C,	0x0C,	0x1D,
 				0x0C,	0x3C,	0x0C,	0x2C,	0x0C },
 	{ STV0900_16APSK_34,	0x0C,	0x0C,	0x0C,	0x0C,	0x0E,
@@ -248,8 +248,8 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
 
 /* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
 static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
-	/* Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
-				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff */
+	/* Modcod		2MPon	2MPoff	5MPon	5MPoff	10MPon
+				10MPoff	20MPon	20MPoff	30MPon	30MPoff */
 	{ STV0900_QPSK_14,	0x0F,	0x3F,	0x0E,	0x3F,	0x2D,
 				0x2F,	0x2D,	0x1F,	0x3D,	0x3E },
 	{ STV0900_QPSK_13,	0x0F,	0x3F,	0x0E,	0x3F,	0x2D,
@@ -275,10 +275,10 @@ struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
 };
 
 static	const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = {
-	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
-				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff	*/
+	/*Modcod		2MPon	2MPoff	5MPon	5MPoff	10MPon
+				10MPoff	20MPon	20MPoff	30MPon	30MPoff	*/
 	{ STV0900_QPSK_12,	0x3C,	0x2C,	0x0C,	0x2C,	0x1B,
-				0x2C,	0x1B,	0x1C,	0x0B, 	0x3B },
+				0x2C,	0x1B,	0x1C,	0x0B,	0x3B },
 	{ STV0900_QPSK_35,	0x0D,	0x0D,	0x0C,	0x0D,	0x1B,
 				0x3C,	0x1B,	0x1C,	0x0B,	0x3B },
 	{ STV0900_QPSK_23,	0x1D,	0x0D,	0x0C,	0x1D,	0x2B,
@@ -309,8 +309,8 @@ static	const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = {
 
 static	const
 struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = {
-	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
-				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff	*/
+	/*Modcod		2MPon	2MPoff	5MPon	5MPoff	10MPon
+				10MPoff	20MPon	20MPoff	30MPon	30MPoff	*/
 	{ STV0900_16APSK_23,	0x0A,	0x0A,	0x0A,	0x0A,	0x1A,
 				0x0A,	0x3A,	0x0A,	0x2A,	0x0A },
 	{ STV0900_16APSK_34,	0x0A,	0x0A,	0x0A,	0x0A,	0x0B,
@@ -337,8 +337,8 @@ struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = {
 
 static	const
 struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut30[3] = {
-	/*Modcod		2MPon 	2MPoff	5MPon 	5MPoff	10MPon
-				10MPoff	20MPon 	20MPoff	30MPon 	30MPoff*/
+	/*Modcod		2MPon	2MPoff	5MPon	5MPoff	10MPon
+				10MPoff	20MPon	20MPoff	30MPon	30MPoff*/
 	{ STV0900_QPSK_14,	0x0C,	0x3C,	0x0B,	0x3C,	0x2A,
 				0x2C,	0x2A,	0x1C,	0x3A,	0x3B },
 	{ STV0900_QPSK_13,	0x0C,	0x3C,	0x0B,	0x3C,	0x2A,
diff --git a/drivers/media/dvb-frontends/stv0900_priv.h b/drivers/media/dvb-frontends/stv0900_priv.h
index 7a95f95..d1fc06f 100644
--- a/drivers/media/dvb-frontends/stv0900_priv.h
+++ b/drivers/media/dvb-frontends/stv0900_priv.h
@@ -243,7 +243,7 @@ struct stv0900_init_params{
 
 	u8	tun1_maddress;
 	int	tuner1_adc;
-	int 	tuner1_type;
+	int	tuner1_type;
 
 	/* IQ from the tuner1 to the demod */
 	enum stv0900_iq_inversion	tun1_iq_inv;
diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
index 7ef469c..9133f65 100644
--- a/drivers/media/dvb-frontends/stv090x.c
+++ b/drivers/media/dvb-frontends/stv090x.c
@@ -27,7 +27,7 @@
 #include <linux/mutex.h>
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "stv6110x.h" /* for demodulator internal modes */
 
@@ -677,7 +677,7 @@ static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = {
 
 /* Cut 3.0 Short Frame Tracking CR Loop */
 static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = {
-	/* MODCOD  	  2M	5M    10M   20M	  30M */
+	/* MODCOD	  2M	5M    10M   20M	  30M */
 	{ STV090x_QPSK,   0x2C, 0x2B, 0x0B, 0x0B, 0x3A },
 	{ STV090x_8PSK,   0x3B, 0x0B, 0x2A, 0x0A, 0x39 },
 	{ STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
@@ -701,7 +701,7 @@ static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg)
 	u8 buf;
 
 	struct i2c_msg msg[] = {
-		{ .addr	= config->address, .flags	= 0, 		.buf = b0,   .len = 2 },
+		{ .addr	= config->address, .flags	= 0,		.buf = b0,   .len = 2 },
 		{ .addr	= config->address, .flags	= I2C_M_RD,	.buf = &buf, .len = 1 }
 	};
 
@@ -755,7 +755,9 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8
 
 static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
 {
-	return stv090x_write_regs(state, reg, &data, 1);
+	u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+	return stv090x_write_regs(state, reg, &tmp, 1);
 }
 
 static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
@@ -2215,13 +2217,12 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
 		if (state->config->tuner_get_status) {
 			if (state->config->tuner_get_status(fe, &reg) < 0)
 				goto err_gateoff;
+			if (reg)
+				dprintk(FE_DEBUG, 1, "Tuner phase locked");
+			else
+				dprintk(FE_DEBUG, 1, "Tuner unlocked");
 		}
 
-		if (reg)
-			dprintk(FE_DEBUG, 1, "Tuner phase locked");
-		else
-			dprintk(FE_DEBUG, 1, "Tuner unlocked");
-
 		if (stv090x_i2c_gate_ctrl(state, 0) < 0)
 			goto err;
 
@@ -3429,6 +3430,21 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
 	return -1;
 }
 
+static int stv090x_set_pls(struct stv090x_state *state, u32 pls_code)
+{
+	dprintk(FE_DEBUG, 1, "Set Gold PLS code %d", pls_code);
+	if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code & 0xff) < 0)
+		goto err;
+	if (STV090x_WRITE_DEMOD(state, PLROOT1, (pls_code >> 8) & 0xff) < 0)
+		goto err;
+	if (STV090x_WRITE_DEMOD(state, PLROOT2, 0x04 | (pls_code >> 16)) < 0)
+		goto err;
+	return 0;
+err:
+	dprintk(FE_ERROR, 1, "I/O error");
+	return -1;
+}
+
 static int stv090x_set_mis(struct stv090x_state *state, int mis)
 {
 	u32 reg;
@@ -3491,6 +3507,7 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)
 		state->search_range = 5000000;
 	}
 
+	stv090x_set_pls(state, props->scrambling_sequence_index);
 	stv090x_set_mis(state, props->stream_id);
 
 	if (stv090x_algo(state) == STV090x_RANGEOK) {
@@ -4889,11 +4906,11 @@ static const struct dvb_frontend_ops stv090x_ops = {
 	.info = {
 		.name			= "STV090x Multistandard",
 		.frequency_min		= 950000,
-		.frequency_max 		= 2150000,
+		.frequency_max		= 2150000,
 		.frequency_stepsize	= 0,
 		.frequency_tolerance	= 0,
-		.symbol_rate_min 	= 1000000,
-		.symbol_rate_max 	= 45000000,
+		.symbol_rate_min	= 1000000,
+		.symbol_rate_max	= 45000000,
 		.caps			= FE_CAN_INVERSION_AUTO |
 					  FE_CAN_FEC_AUTO       |
 					  FE_CAN_QPSK           |
@@ -4936,7 +4953,7 @@ struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
 	state->frontend.ops			= stv090x_ops;
 	state->frontend.demodulator_priv	= state;
 	state->demod				= demod;
-	state->demod_mode 			= config->demod_mode; /* Single or Dual mode */
+	state->demod_mode			= config->demod_mode; /* Single or Dual mode */
 	state->device				= config->device;
 	state->rolloff				= STV090x_RO_35; /* default */
 
diff --git a/drivers/media/dvb-frontends/stv090x_priv.h b/drivers/media/dvb-frontends/stv090x_priv.h
index 5b780c8..fdda218 100644
--- a/drivers/media/dvb-frontends/stv090x_priv.h
+++ b/drivers/media/dvb-frontends/stv090x_priv.h
@@ -22,7 +22,7 @@
 #ifndef __STV090x_PRIV_H
 #define __STV090x_PRIV_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #define FE_ERROR				0
 #define FE_NOTICE				1
@@ -231,7 +231,7 @@ struct stv090x_tab {
 };
 
 struct stv090x_internal {
-	struct i2c_adapter 	*i2c_adap;
+	struct i2c_adapter	*i2c_adap;
 	u8			i2c_addr;
 
 	struct mutex		demod_lock; /* Lock access to shared register */
diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c
index 8bf855c..a2f7c0c 100644
--- a/drivers/media/dvb-frontends/stv0910.c
+++ b/drivers/media/dvb-frontends/stv0910.c
@@ -24,8 +24,7 @@
 #include <linux/i2c.h>
 #include <asm/div64.h>
 
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "stv0910.h"
 #include "stv0910_regs.h"
 
@@ -138,33 +137,21 @@ struct slookup {
 	u32  reg_value;
 };
 
-static inline int i2c_write(struct i2c_adapter *adap, u8 adr,
-			    u8 *data, int len)
+static int write_reg(struct stv *state, u16 reg, u8 val)
 {
-	struct i2c_msg msg = {.addr = adr, .flags = 0,
-			      .buf = data, .len = len};
+	struct i2c_adapter *adap = state->base->i2c;
+	u8 data[3] = {reg >> 8, reg & 0xff, val};
+	struct i2c_msg msg = {.addr = state->base->adr, .flags = 0,
+			      .buf = data, .len = 3};
 
 	if (i2c_transfer(adap, &msg, 1) != 1) {
 		dev_warn(&adap->dev, "i2c write error ([%02x] %04x: %02x)\n",
-			 adr, (data[0] << 8) | data[1],
-			 (len > 2 ? data[2] : 0));
-		return -EREMOTEIO;
+			 state->base->adr, reg, val);
+		return -EIO;
 	}
 	return 0;
 }
 
-static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, u16 reg, u8 val)
-{
-	u8 msg[3] = {reg >> 8, reg & 0xff, val};
-
-	return i2c_write(adap, adr, msg, 3);
-}
-
-static int write_reg(struct stv *state, u16 reg, u8 val)
-{
-	return i2c_write_reg16(state->base->i2c, state->base->adr, reg, val);
-}
-
 static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr,
 				  u16 reg, u8 *val, int count)
 {
@@ -177,7 +164,7 @@ static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr,
 	if (i2c_transfer(adapter, msgs, 2) != 2) {
 		dev_warn(&adapter->dev, "i2c read error ([%02x] %04x)\n",
 			 adr, reg);
-		return -EREMOTEIO;
+		return -EIO;
 	}
 	return 0;
 }
@@ -207,6 +194,34 @@ static int write_shared_reg(struct stv *state, u16 reg, u8 mask, u8 val)
 	return status;
 }
 
+static int write_field(struct stv *state, u32 field, u8 val)
+{
+	int status;
+	u8 shift, mask, old, new;
+
+	status = read_reg(state, field >> 16, &old);
+	if (status)
+		return status;
+	mask = field & 0xff;
+	shift = (field >> 12) & 0xf;
+	new = ((val << shift) & mask) | (old & ~mask);
+	if (new == old)
+		return 0;
+	return write_reg(state, field >> 16, new);
+}
+
+#define SET_FIELD(_reg, _val)					\
+	write_field(state, state->nr ? FSTV0910_P2_##_reg :	\
+		    FSTV0910_P1_##_reg, _val)
+
+#define SET_REG(_reg, _val)					\
+	write_reg(state, state->nr ? RSTV0910_P2_##_reg :	\
+		  RSTV0910_P1_##_reg, _val)
+
+#define GET_REG(_reg, _val)					\
+	read_reg(state, state->nr ? RSTV0910_P2_##_reg :	\
+		 RSTV0910_P1_##_reg, _val)
+
 static const struct slookup s1_sn_lookup[] = {
 	{   0,    9242  }, /* C/N=   0dB */
 	{   5,    9105  }, /* C/N= 0.5dB */
@@ -533,10 +548,8 @@ static int get_signal_parameters(struct stv *state)
 
 static int tracking_optimization(struct stv *state)
 {
-	u32 symbol_rate = 0;
 	u8 tmp;
 
-	get_cur_symbol_rate(state, &symbol_rate);
 	read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, &tmp);
 	tmp &= ~0xC0;
 
@@ -867,71 +880,90 @@ static int stop(struct stv *state)
 	return 0;
 }
 
-static int init_search_param(struct stv *state)
+static void set_pls(struct stv *state, u32 pls_code)
 {
-	u8 tmp;
+	if (pls_code == state->cur_scrambling_code)
+		return;
 
-	read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp);
-	tmp |= 0x20; /* Filter_en (no effect if SIS=non-MIS */
-	write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp);
+	/* PLROOT2 bit 2 = gold code */
+	write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff,
+		  pls_code & 0xff);
+	write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff,
+		  (pls_code >> 8) & 0xff);
+	write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff,
+		  0x04 | ((pls_code >> 16) & 0x03));
+	state->cur_scrambling_code = pls_code;
+}
 
-	read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, &tmp);
-	tmp &= ~0x02; /* frame mode = 0 */
-	write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, tmp);
+static void set_isi(struct stv *state, u32 isi)
+{
+	if (isi == NO_STREAM_ID_FILTER)
+		return;
+	if (isi == 0x80000000) {
+		SET_FIELD(FORCE_CONTINUOUS, 1);
+		SET_FIELD(TSOUT_NOSYNC, 1);
+	} else {
+		SET_FIELD(FILTER_EN, 1);
+		write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff,
+			  isi & 0xff);
+		write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0xff);
+	}
+	SET_FIELD(ALGOSWRST, 1);
+	SET_FIELD(ALGOSWRST, 0);
+}
 
-	write_reg(state, RSTV0910_P2_UPLCCST0 + state->regoff, 0xe0);
-	write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0x00);
+static void set_stream_modes(struct stv *state,
+			     struct dtv_frontend_properties *p)
+{
+	set_isi(state, p->stream_id);
+	set_pls(state, p->scrambling_sequence_index);
+}
 
-	read_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, &tmp);
-	tmp &= ~0x01; /* nosync = 0, in case next signal is standard TS */
-	write_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, tmp);
+static int init_search_param(struct stv *state,
+			     struct dtv_frontend_properties *p)
+{
+	SET_FIELD(FORCE_CONTINUOUS, 0);
+	SET_FIELD(FRAME_MODE, 0);
+	SET_FIELD(FILTER_EN, 0);
+	SET_FIELD(TSOUT_NOSYNC, 0);
+	SET_FIELD(TSFIFO_EMBINDVB, 0);
+	SET_FIELD(TSDEL_SYNCBYTE, 0);
+	SET_REG(UPLCCST0, 0xe0);
+	SET_FIELD(TSINS_TOKEN, 0);
+	SET_FIELD(HYSTERESIS_THRESHOLD, 0);
+	SET_FIELD(ISIOBS_MODE, 1);
 
-	read_reg(state, RSTV0910_P2_TSCFGL + state->regoff, &tmp);
-	tmp &= ~0x04; /* embindvb = 0 */
-	write_reg(state, RSTV0910_P2_TSCFGL + state->regoff, tmp);
-
-	read_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, &tmp);
-	tmp &= ~0x80; /* syncbyte = 0 */
-	write_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, tmp);
-
-	read_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, &tmp);
-	tmp &= ~0x08; /* token = 0 */
-	write_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, tmp);
-
-	read_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, &tmp);
-	tmp &= ~0x30; /* hysteresis threshold = 0 */
-	write_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, tmp);
-
-	read_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, &tmp);
-	tmp = (tmp & ~0x30) | 0x10; /* isi obs mode = 1, observe min ISI */
-	write_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, tmp);
-
+	set_stream_modes(state, p);
 	return 0;
 }
 
 static int enable_puncture_rate(struct stv *state, enum fe_code_rate rate)
 {
+	u8 val;
+
 	switch (rate) {
 	case FEC_1_2:
-		return write_reg(state,
-				 RSTV0910_P2_PRVIT + state->regoff, 0x01);
+		val = 0x01;
+		break;
 	case FEC_2_3:
-		return write_reg(state,
-				 RSTV0910_P2_PRVIT + state->regoff, 0x02);
+		val = 0x02;
+		break;
 	case FEC_3_4:
-		return write_reg(state,
-				 RSTV0910_P2_PRVIT + state->regoff, 0x04);
+		val = 0x04;
+		break;
 	case FEC_5_6:
-		return write_reg(state,
-				 RSTV0910_P2_PRVIT + state->regoff, 0x08);
+		val = 0x08;
+		break;
 	case FEC_7_8:
-		return write_reg(state,
-				 RSTV0910_P2_PRVIT + state->regoff, 0x20);
+		val = 0x20;
+		break;
 	case FEC_NONE:
 	default:
-		return write_reg(state,
-				 RSTV0910_P2_PRVIT + state->regoff, 0x2f);
+		val = 0x2f;
+		break;
 	}
+
+	return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, val);
 }
 
 static int set_vth_default(struct stv *state)
@@ -988,7 +1020,6 @@ static int start(struct stv *state, struct dtv_frontend_properties *p)
 	s32 freq;
 	u8  reg_dmdcfgmd;
 	u16 symb;
-	u32 scrambling_code = 1;
 
 	if (p->symbol_rate < 100000 || p->symbol_rate > 70000000)
 		return -EINVAL;
@@ -1000,30 +1031,7 @@ static int start(struct stv *state, struct dtv_frontend_properties *p)
 	if (state->started)
 		write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5C);
 
-	init_search_param(state);
-
-	if (p->stream_id != NO_STREAM_ID_FILTER) {
-		/*
-		 * Backwards compatibility to "crazy" API.
-		 * PRBS X root cannot be 0, so this should always work.
-		 */
-		if (p->stream_id & 0xffffff00)
-			scrambling_code = p->stream_id >> 8;
-		write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff,
-			  p->stream_id & 0xff);
-		write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff,
-			  0xff);
-	}
-
-	if (scrambling_code != state->cur_scrambling_code) {
-		write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff,
-			  scrambling_code & 0xff);
-		write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff,
-			  (scrambling_code >> 8) & 0xff);
-		write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff,
-			  (scrambling_code >> 16) & 0x0f);
-		state->cur_scrambling_code = scrambling_code;
-	}
+	init_search_param(state, p);
 
 	if (p->symbol_rate <= 1000000) { /* SR <=1Msps */
 		state->demod_timeout = 3000;
@@ -1241,7 +1249,8 @@ static int gate_ctrl(struct dvb_frontend *fe, int enable)
 	if (write_reg(state, state->nr ? RSTV0910_P2_I2CRPT :
 		      RSTV0910_P1_I2CRPT, i2crpt) < 0) {
 		/* don't hold the I2C bus lock on failure */
-		mutex_unlock(&state->base->i2c_lock);
+		if (!WARN_ON(!mutex_is_locked(&state->base->i2c_lock)))
+			mutex_unlock(&state->base->i2c_lock);
 		dev_err(&state->base->i2c->dev,
 			"%s() write_reg failure (enable=%d)\n",
 			__func__, enable);
@@ -1251,7 +1260,8 @@ static int gate_ctrl(struct dvb_frontend *fe, int enable)
 	state->i2crpt = i2crpt;
 
 	if (!enable)
-		mutex_unlock(&state->base->i2c_lock);
+		if (!WARN_ON(!mutex_is_locked(&state->base->i2c_lock)))
+			mutex_unlock(&state->base->i2c_lock);
 	return 0;
 }
 
@@ -1271,14 +1281,11 @@ static int set_parameters(struct dvb_frontend *fe)
 {
 	int stat = 0;
 	struct stv *state = fe->demodulator_priv;
-	u32 iffreq;
 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 
 	stop(state);
 	if (fe->ops.tuner_ops.set_params)
 		fe->ops.tuner_ops.set_params(fe);
-	if (fe->ops.tuner_ops.get_if_frequency)
-		fe->ops.tuner_ops.get_if_frequency(fe, &iffreq);
 	state->symbol_rate = p->symbol_rate;
 	stat = start(state, p);
 	return stat;
@@ -1498,6 +1505,19 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status)
 				enable_puncture_rate(state,
 						     state->puncture_rate);
 		}
+
+		/* Use highest signaled ModCod for quality */
+		if (state->is_vcm) {
+			u8 tmp;
+			enum fe_stv0910_mod_cod mod_cod;
+
+			read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff,
+				 &tmp);
+			mod_cod = (enum fe_stv0910_mod_cod)((tmp & 0x7c) >> 2);
+
+			if (mod_cod > state->mod_cod)
+				state->mod_cod = mod_cod;
+		}
 	}
 
 	/* read signal statistics */
@@ -1527,6 +1547,7 @@ static int get_frontend(struct dvb_frontend *fe,
 {
 	struct stv *state = fe->demodulator_priv;
 	u8 tmp;
+	u32 symbolrate;
 
 	if (state->receive_mode == RCVMODE_DVBS2) {
 		u32 mc;
@@ -1580,6 +1601,10 @@ static int get_frontend(struct dvb_frontend *fe,
 		p->rolloff = ROLLOFF_35;
 	}
 
+	if (state->receive_mode != RCVMODE_NONE) {
+		get_cur_symbol_rate(state, &symbolrate);
+		p->symbol_rate = symbolrate;
+	}
 	return 0;
 }
 
diff --git a/drivers/media/dvb-frontends/stv0910_regs.h b/drivers/media/dvb-frontends/stv0910_regs.h
index 32ced4e..f0eb91509 100644
--- a/drivers/media/dvb-frontends/stv0910_regs.h
+++ b/drivers/media/dvb-frontends/stv0910_regs.h
@@ -7,15 +7,15 @@
  * Registers Declaration (Internal ST, All Applications )
  * -------------------------
  * Each register (RSTV0910__XXXXX) is defined by its address (2 bytes).
- *
- * Each field (FSTV0910__XXXXX)is defined as follow:
- * [register address -- 2bytes][field sign -- 1byte][field mask -- 1byte]
- *  ======================================================================
+ * Each field (FSTV0910__XXXXX) is defined as follow:
+ * [register address -- 2bytes][field offset -- 4 bits][unused -- 3 bits]
+ * [field sign -- 1 bit][field mask -- 1byte]
+ * =======================================================================
  */
 
 /* MID */
 #define RSTV0910_MID  0xf100
-#define FSTV0910_MCHIP_IDENT  0xf10000f0
+#define FSTV0910_MCHIP_IDENT  0xf10040f0
 #define FSTV0910_MRELEASE  0xf100000f
 
 /* DID */
@@ -24,7 +24,7 @@
 
 /* DACR1 */
 #define RSTV0910_DACR1  0xf113
-#define FSTV0910_DAC_MODE  0xf11300e0
+#define FSTV0910_DAC_MODE  0xf11350e0
 #define FSTV0910_DAC_VALUE1  0xf113000f
 
 /* DACR2 */
@@ -33,283 +33,283 @@
 
 /* PADCFG */
 #define RSTV0910_PADCFG  0xf11a
-#define FSTV0910_AGCRF2_OPD  0xf11a0008
-#define FSTV0910_AGCRF2_XOR  0xf11a0004
-#define FSTV0910_AGCRF1_OPD  0xf11a0002
+#define FSTV0910_AGCRF2_OPD  0xf11a3008
+#define FSTV0910_AGCRF2_XOR  0xf11a2004
+#define FSTV0910_AGCRF1_OPD  0xf11a1002
 #define FSTV0910_AGCRF1_XOR  0xf11a0001
 
 /* OUTCFG2 */
 #define RSTV0910_OUTCFG2  0xf11b
-#define FSTV0910_TS2_ERROR_XOR  0xf11b0080
-#define FSTV0910_TS2_DPN_XOR  0xf11b0040
-#define FSTV0910_TS2_STROUT_XOR  0xf11b0020
-#define FSTV0910_TS2_CLOCKOUT_XOR  0xf11b0010
-#define FSTV0910_TS1_ERROR_XOR  0xf11b0008
-#define FSTV0910_TS1_DPN_XOR  0xf11b0004
-#define FSTV0910_TS1_STROUT_XOR  0xf11b0002
+#define FSTV0910_TS2_ERROR_XOR  0xf11b7080
+#define FSTV0910_TS2_DPN_XOR  0xf11b6040
+#define FSTV0910_TS2_STROUT_XOR  0xf11b5020
+#define FSTV0910_TS2_CLOCKOUT_XOR  0xf11b4010
+#define FSTV0910_TS1_ERROR_XOR  0xf11b3008
+#define FSTV0910_TS1_DPN_XOR  0xf11b2004
+#define FSTV0910_TS1_STROUT_XOR  0xf11b1002
 #define FSTV0910_TS1_CLOCKOUT_XOR  0xf11b0001
 
 /* OUTCFG */
 #define RSTV0910_OUTCFG  0xf11c
-#define FSTV0910_TS2_OUTSER_HZ  0xf11c0020
-#define FSTV0910_TS1_OUTSER_HZ  0xf11c0010
-#define FSTV0910_TS2_OUTPAR_HZ  0xf11c0008
-#define FSTV0910_TS1_OUTPAR_HZ  0xf11c0004
-#define FSTV0910_TS_SERDATA0  0xf11c0002
+#define FSTV0910_TS2_OUTSER_HZ  0xf11c5020
+#define FSTV0910_TS1_OUTSER_HZ  0xf11c4010
+#define FSTV0910_TS2_OUTPAR_HZ  0xf11c3008
+#define FSTV0910_TS1_OUTPAR_HZ  0xf11c2004
+#define FSTV0910_TS_SERDATA0  0xf11c1002
 
 /* IRQSTATUS3 */
 #define RSTV0910_IRQSTATUS3  0xf120
-#define FSTV0910_SPLL_LOCK  0xf1200020
-#define FSTV0910_SSTREAM_LCK_1  0xf1200010
-#define FSTV0910_SSTREAM_LCK_2  0xf1200008
-#define FSTV0910_SDVBS1_PRF_2  0xf1200002
+#define FSTV0910_SPLL_LOCK  0xf1205020
+#define FSTV0910_SSTREAM_LCK_1  0xf1204010
+#define FSTV0910_SSTREAM_LCK_2  0xf1203008
+#define FSTV0910_SDVBS1_PRF_2  0xf1201002
 #define FSTV0910_SDVBS1_PRF_1  0xf1200001
 
 /* IRQSTATUS2 */
 #define RSTV0910_IRQSTATUS2  0xf121
-#define FSTV0910_SSPY_ENDSIM_1  0xf1210080
-#define FSTV0910_SSPY_ENDSIM_2  0xf1210040
-#define FSTV0910_SPKTDEL_ERROR_2  0xf1210010
-#define FSTV0910_SPKTDEL_LOCKB_2  0xf1210008
-#define FSTV0910_SPKTDEL_LOCK_2  0xf1210004
-#define FSTV0910_SPKTDEL_ERROR_1  0xf1210002
+#define FSTV0910_SSPY_ENDSIM_1  0xf1217080
+#define FSTV0910_SSPY_ENDSIM_2  0xf1216040
+#define FSTV0910_SPKTDEL_ERROR_2  0xf1214010
+#define FSTV0910_SPKTDEL_LOCKB_2  0xf1213008
+#define FSTV0910_SPKTDEL_LOCK_2  0xf1212004
+#define FSTV0910_SPKTDEL_ERROR_1  0xf1211002
 #define FSTV0910_SPKTDEL_LOCKB_1  0xf1210001
 
 /* IRQSTATUS1 */
 #define RSTV0910_IRQSTATUS1  0xf122
-#define FSTV0910_SPKTDEL_LOCK_1  0xf1220080
-#define FSTV0910_SFEC_LOCKB_2  0xf1220040
-#define FSTV0910_SFEC_LOCK_2  0xf1220020
-#define FSTV0910_SFEC_LOCKB_1  0xf1220010
-#define FSTV0910_SFEC_LOCK_1  0xf1220008
-#define FSTV0910_SDEMOD_LOCKB_2  0xf1220004
-#define FSTV0910_SDEMOD_LOCK_2  0xf1220002
+#define FSTV0910_SPKTDEL_LOCK_1  0xf1227080
+#define FSTV0910_SFEC_LOCKB_2  0xf1226040
+#define FSTV0910_SFEC_LOCK_2  0xf1225020
+#define FSTV0910_SFEC_LOCKB_1  0xf1224010
+#define FSTV0910_SFEC_LOCK_1  0xf1223008
+#define FSTV0910_SDEMOD_LOCKB_2  0xf1222004
+#define FSTV0910_SDEMOD_LOCK_2  0xf1221002
 #define FSTV0910_SDEMOD_IRQ_2  0xf1220001
 
 /* IRQSTATUS0 */
 #define RSTV0910_IRQSTATUS0  0xf123
-#define FSTV0910_SDEMOD_LOCKB_1  0xf1230080
-#define FSTV0910_SDEMOD_LOCK_1  0xf1230040
-#define FSTV0910_SDEMOD_IRQ_1  0xf1230020
-#define FSTV0910_SBCH_ERRFLAG  0xf1230010
-#define FSTV0910_SDISEQC2_IRQ  0xf1230004
+#define FSTV0910_SDEMOD_LOCKB_1  0xf1237080
+#define FSTV0910_SDEMOD_LOCK_1  0xf1236040
+#define FSTV0910_SDEMOD_IRQ_1  0xf1235020
+#define FSTV0910_SBCH_ERRFLAG  0xf1234010
+#define FSTV0910_SDISEQC2_IRQ  0xf1232004
 #define FSTV0910_SDISEQC1_IRQ  0xf1230001
 
 /* IRQMASK3 */
 #define RSTV0910_IRQMASK3  0xf124
-#define FSTV0910_MPLL_LOCK  0xf1240020
-#define FSTV0910_MSTREAM_LCK_1  0xf1240010
-#define FSTV0910_MSTREAM_LCK_2  0xf1240008
-#define FSTV0910_MDVBS1_PRF_2  0xf1240002
+#define FSTV0910_MPLL_LOCK  0xf1245020
+#define FSTV0910_MSTREAM_LCK_1  0xf1244010
+#define FSTV0910_MSTREAM_LCK_2  0xf1243008
+#define FSTV0910_MDVBS1_PRF_2  0xf1241002
 #define FSTV0910_MDVBS1_PRF_1  0xf1240001
 
 /* IRQMASK2 */
 #define RSTV0910_IRQMASK2  0xf125
-#define FSTV0910_MSPY_ENDSIM_1  0xf1250080
-#define FSTV0910_MSPY_ENDSIM_2  0xf1250040
-#define FSTV0910_MPKTDEL_ERROR_2  0xf1250010
-#define FSTV0910_MPKTDEL_LOCKB_2  0xf1250008
-#define FSTV0910_MPKTDEL_LOCK_2  0xf1250004
-#define FSTV0910_MPKTDEL_ERROR_1  0xf1250002
+#define FSTV0910_MSPY_ENDSIM_1  0xf1257080
+#define FSTV0910_MSPY_ENDSIM_2  0xf1256040
+#define FSTV0910_MPKTDEL_ERROR_2  0xf1254010
+#define FSTV0910_MPKTDEL_LOCKB_2  0xf1253008
+#define FSTV0910_MPKTDEL_LOCK_2  0xf1252004
+#define FSTV0910_MPKTDEL_ERROR_1  0xf1251002
 #define FSTV0910_MPKTDEL_LOCKB_1  0xf1250001
 
 /* IRQMASK1 */
 #define RSTV0910_IRQMASK1  0xf126
-#define FSTV0910_MPKTDEL_LOCK_1  0xf1260080
-#define FSTV0910_MFEC_LOCKB_2  0xf1260040
-#define FSTV0910_MFEC_LOCK_2  0xf1260020
-#define FSTV0910_MFEC_LOCKB_1  0xf1260010
-#define FSTV0910_MFEC_LOCK_1  0xf1260008
-#define FSTV0910_MDEMOD_LOCKB_2  0xf1260004
-#define FSTV0910_MDEMOD_LOCK_2  0xf1260002
+#define FSTV0910_MPKTDEL_LOCK_1  0xf1267080
+#define FSTV0910_MFEC_LOCKB_2  0xf1266040
+#define FSTV0910_MFEC_LOCK_2  0xf1265020
+#define FSTV0910_MFEC_LOCKB_1  0xf1264010
+#define FSTV0910_MFEC_LOCK_1  0xf1263008
+#define FSTV0910_MDEMOD_LOCKB_2  0xf1262004
+#define FSTV0910_MDEMOD_LOCK_2  0xf1261002
 #define FSTV0910_MDEMOD_IRQ_2  0xf1260001
 
 /* IRQMASK0 */
 #define RSTV0910_IRQMASK0  0xf127
-#define FSTV0910_MDEMOD_LOCKB_1  0xf1270080
-#define FSTV0910_MDEMOD_LOCK_1  0xf1270040
-#define FSTV0910_MDEMOD_IRQ_1  0xf1270020
-#define FSTV0910_MBCH_ERRFLAG  0xf1270010
-#define FSTV0910_MDISEQC2_IRQ  0xf1270004
+#define FSTV0910_MDEMOD_LOCKB_1  0xf1277080
+#define FSTV0910_MDEMOD_LOCK_1  0xf1276040
+#define FSTV0910_MDEMOD_IRQ_1  0xf1275020
+#define FSTV0910_MBCH_ERRFLAG  0xf1274010
+#define FSTV0910_MDISEQC2_IRQ  0xf1272004
 #define FSTV0910_MDISEQC1_IRQ  0xf1270001
 
 /* I2CCFG */
 #define RSTV0910_I2CCFG  0xf129
-#define FSTV0910_I2C_FASTMODE  0xf1290008
+#define FSTV0910_I2C_FASTMODE  0xf1293008
 #define FSTV0910_I2CADDR_INC  0xf1290003
 
 /* P1_I2CRPT */
 #define RSTV0910_P1_I2CRPT  0xf12a
-#define FSTV0910_P1_I2CT_ON  0xf12a0080
-#define FSTV0910_P1_ENARPT_LEVEL  0xf12a0070
-#define FSTV0910_P1_SCLT_DELAY  0xf12a0008
-#define FSTV0910_P1_STOP_ENABLE  0xf12a0004
-#define FSTV0910_P1_STOP_SDAT2SDA  0xf12a0002
+#define FSTV0910_P1_I2CT_ON  0xf12a7080
+#define FSTV0910_P1_ENARPT_LEVEL  0xf12a4070
+#define FSTV0910_P1_SCLT_DELAY  0xf12a3008
+#define FSTV0910_P1_STOP_ENABLE  0xf12a2004
+#define FSTV0910_P1_STOP_SDAT2SDA  0xf12a1002
 
 /* P2_I2CRPT */
 #define RSTV0910_P2_I2CRPT  0xf12b
-#define FSTV0910_P2_I2CT_ON  0xf12b0080
-#define FSTV0910_P2_ENARPT_LEVEL  0xf12b0070
-#define FSTV0910_P2_SCLT_DELAY  0xf12b0008
-#define FSTV0910_P2_STOP_ENABLE  0xf12b0004
-#define FSTV0910_P2_STOP_SDAT2SDA  0xf12b0002
+#define FSTV0910_P2_I2CT_ON  0xf12b7080
+#define FSTV0910_P2_ENARPT_LEVEL  0xf12b4070
+#define FSTV0910_P2_SCLT_DELAY  0xf12b3008
+#define FSTV0910_P2_STOP_ENABLE  0xf12b2004
+#define FSTV0910_P2_STOP_SDAT2SDA  0xf12b1002
 
 /* GPIO0CFG */
 #define RSTV0910_GPIO0CFG  0xf140
-#define FSTV0910_GPIO0_OPD  0xf1400080
-#define FSTV0910_GPIO0_CONFIG  0xf140007e
+#define FSTV0910_GPIO0_OPD  0xf1407080
+#define FSTV0910_GPIO0_CONFIG  0xf140107e
 #define FSTV0910_GPIO0_XOR  0xf1400001
 
 /* GPIO1CFG */
 #define RSTV0910_GPIO1CFG  0xf141
-#define FSTV0910_GPIO1_OPD  0xf1410080
-#define FSTV0910_GPIO1_CONFIG  0xf141007e
+#define FSTV0910_GPIO1_OPD  0xf1417080
+#define FSTV0910_GPIO1_CONFIG  0xf141107e
 #define FSTV0910_GPIO1_XOR  0xf1410001
 
 /* GPIO2CFG */
 #define RSTV0910_GPIO2CFG  0xf142
-#define FSTV0910_GPIO2_OPD  0xf1420080
-#define FSTV0910_GPIO2_CONFIG  0xf142007e
+#define FSTV0910_GPIO2_OPD  0xf1427080
+#define FSTV0910_GPIO2_CONFIG  0xf142107e
 #define FSTV0910_GPIO2_XOR  0xf1420001
 
 /* GPIO3CFG */
 #define RSTV0910_GPIO3CFG  0xf143
-#define FSTV0910_GPIO3_OPD  0xf1430080
-#define FSTV0910_GPIO3_CONFIG  0xf143007e
+#define FSTV0910_GPIO3_OPD  0xf1437080
+#define FSTV0910_GPIO3_CONFIG  0xf143107e
 #define FSTV0910_GPIO3_XOR  0xf1430001
 
 /* GPIO4CFG */
 #define RSTV0910_GPIO4CFG  0xf144
-#define FSTV0910_GPIO4_OPD  0xf1440080
-#define FSTV0910_GPIO4_CONFIG  0xf144007e
+#define FSTV0910_GPIO4_OPD  0xf1447080
+#define FSTV0910_GPIO4_CONFIG  0xf144107e
 #define FSTV0910_GPIO4_XOR  0xf1440001
 
 /* GPIO5CFG */
 #define RSTV0910_GPIO5CFG  0xf145
-#define FSTV0910_GPIO5_OPD  0xf1450080
-#define FSTV0910_GPIO5_CONFIG  0xf145007e
+#define FSTV0910_GPIO5_OPD  0xf1457080
+#define FSTV0910_GPIO5_CONFIG  0xf145107e
 #define FSTV0910_GPIO5_XOR  0xf1450001
 
 /* GPIO6CFG */
 #define RSTV0910_GPIO6CFG  0xf146
-#define FSTV0910_GPIO6_OPD  0xf1460080
-#define FSTV0910_GPIO6_CONFIG  0xf146007e
+#define FSTV0910_GPIO6_OPD  0xf1467080
+#define FSTV0910_GPIO6_CONFIG  0xf146107e
 #define FSTV0910_GPIO6_XOR  0xf1460001
 
 /* GPIO7CFG */
 #define RSTV0910_GPIO7CFG  0xf147
-#define FSTV0910_GPIO7_OPD  0xf1470080
-#define FSTV0910_GPIO7_CONFIG  0xf147007e
+#define FSTV0910_GPIO7_OPD  0xf1477080
+#define FSTV0910_GPIO7_CONFIG  0xf147107e
 #define FSTV0910_GPIO7_XOR  0xf1470001
 
 /* GPIO8CFG */
 #define RSTV0910_GPIO8CFG  0xf148
-#define FSTV0910_GPIO8_OPD  0xf1480080
-#define FSTV0910_GPIO8_CONFIG  0xf148007e
+#define FSTV0910_GPIO8_OPD  0xf1487080
+#define FSTV0910_GPIO8_CONFIG  0xf148107e
 #define FSTV0910_GPIO8_XOR  0xf1480001
 
 /* GPIO9CFG */
 #define RSTV0910_GPIO9CFG  0xf149
-#define FSTV0910_GPIO9_OPD  0xf1490080
-#define FSTV0910_GPIO9_CONFIG  0xf149007e
+#define FSTV0910_GPIO9_OPD  0xf1497080
+#define FSTV0910_GPIO9_CONFIG  0xf149107e
 #define FSTV0910_GPIO9_XOR  0xf1490001
 
 /* GPIO10CFG */
 #define RSTV0910_GPIO10CFG  0xf14a
-#define FSTV0910_GPIO10_OPD  0xf14a0080
-#define FSTV0910_GPIO10_CONFIG  0xf14a007e
+#define FSTV0910_GPIO10_OPD  0xf14a7080
+#define FSTV0910_GPIO10_CONFIG  0xf14a107e
 #define FSTV0910_GPIO10_XOR  0xf14a0001
 
 /* GPIO11CFG */
 #define RSTV0910_GPIO11CFG  0xf14b
-#define FSTV0910_GPIO11_OPD  0xf14b0080
-#define FSTV0910_GPIO11_CONFIG  0xf14b007e
+#define FSTV0910_GPIO11_OPD  0xf14b7080
+#define FSTV0910_GPIO11_CONFIG  0xf14b107e
 #define FSTV0910_GPIO11_XOR  0xf14b0001
 
 /* GPIO12CFG */
 #define RSTV0910_GPIO12CFG  0xf14c
-#define FSTV0910_GPIO12_OPD  0xf14c0080
-#define FSTV0910_GPIO12_CONFIG  0xf14c007e
+#define FSTV0910_GPIO12_OPD  0xf14c7080
+#define FSTV0910_GPIO12_CONFIG  0xf14c107e
 #define FSTV0910_GPIO12_XOR  0xf14c0001
 
 /* GPIO13CFG */
 #define RSTV0910_GPIO13CFG  0xf14d
-#define FSTV0910_GPIO13_OPD  0xf14d0080
-#define FSTV0910_GPIO13_CONFIG  0xf14d007e
+#define FSTV0910_GPIO13_OPD  0xf14d7080
+#define FSTV0910_GPIO13_CONFIG  0xf14d107e
 #define FSTV0910_GPIO13_XOR  0xf14d0001
 
 /* GPIO14CFG */
 #define RSTV0910_GPIO14CFG  0xf14e
-#define FSTV0910_GPIO14_OPD  0xf14e0080
-#define FSTV0910_GPIO14_CONFIG  0xf14e007e
+#define FSTV0910_GPIO14_OPD  0xf14e7080
+#define FSTV0910_GPIO14_CONFIG  0xf14e107e
 #define FSTV0910_GPIO14_XOR  0xf14e0001
 
 /* GPIO15CFG */
 #define RSTV0910_GPIO15CFG  0xf14f
-#define FSTV0910_GPIO15_OPD  0xf14f0080
-#define FSTV0910_GPIO15_CONFIG  0xf14f007e
+#define FSTV0910_GPIO15_OPD  0xf14f7080
+#define FSTV0910_GPIO15_CONFIG  0xf14f107e
 #define FSTV0910_GPIO15_XOR  0xf14f0001
 
 /* GPIO16CFG */
 #define RSTV0910_GPIO16CFG  0xf150
-#define FSTV0910_GPIO16_OPD  0xf1500080
-#define FSTV0910_GPIO16_CONFIG  0xf150007e
+#define FSTV0910_GPIO16_OPD  0xf1507080
+#define FSTV0910_GPIO16_CONFIG  0xf150107e
 #define FSTV0910_GPIO16_XOR  0xf1500001
 
 /* GPIO17CFG */
 #define RSTV0910_GPIO17CFG  0xf151
-#define FSTV0910_GPIO17_OPD  0xf1510080
-#define FSTV0910_GPIO17_CONFIG  0xf151007e
+#define FSTV0910_GPIO17_OPD  0xf1517080
+#define FSTV0910_GPIO17_CONFIG  0xf151107e
 #define FSTV0910_GPIO17_XOR  0xf1510001
 
 /* GPIO18CFG */
 #define RSTV0910_GPIO18CFG  0xf152
-#define FSTV0910_GPIO18_OPD  0xf1520080
-#define FSTV0910_GPIO18_CONFIG  0xf152007e
+#define FSTV0910_GPIO18_OPD  0xf1527080
+#define FSTV0910_GPIO18_CONFIG  0xf152107e
 #define FSTV0910_GPIO18_XOR  0xf1520001
 
 /* GPIO19CFG */
 #define RSTV0910_GPIO19CFG  0xf153
-#define FSTV0910_GPIO19_OPD  0xf1530080
-#define FSTV0910_GPIO19_CONFIG  0xf153007e
+#define FSTV0910_GPIO19_OPD  0xf1537080
+#define FSTV0910_GPIO19_CONFIG  0xf153107e
 #define FSTV0910_GPIO19_XOR  0xf1530001
 
 /* GPIO20CFG */
 #define RSTV0910_GPIO20CFG  0xf154
-#define FSTV0910_GPIO20_OPD  0xf1540080
-#define FSTV0910_GPIO20_CONFIG  0xf154007e
+#define FSTV0910_GPIO20_OPD  0xf1547080
+#define FSTV0910_GPIO20_CONFIG  0xf154107e
 #define FSTV0910_GPIO20_XOR  0xf1540001
 
 /* GPIO21CFG */
 #define RSTV0910_GPIO21CFG  0xf155
-#define FSTV0910_GPIO21_OPD  0xf1550080
-#define FSTV0910_GPIO21_CONFIG  0xf155007e
+#define FSTV0910_GPIO21_OPD  0xf1557080
+#define FSTV0910_GPIO21_CONFIG  0xf155107e
 #define FSTV0910_GPIO21_XOR  0xf1550001
 
 /* GPIO22CFG */
 #define RSTV0910_GPIO22CFG  0xf156
-#define FSTV0910_GPIO22_OPD  0xf1560080
-#define FSTV0910_GPIO22_CONFIG  0xf156007e
+#define FSTV0910_GPIO22_OPD  0xf1567080
+#define FSTV0910_GPIO22_CONFIG  0xf156107e
 #define FSTV0910_GPIO22_XOR  0xf1560001
 
 /* STRSTATUS1 */
 #define RSTV0910_STRSTATUS1  0xf16a
-#define FSTV0910_STRSTATUS_SEL2  0xf16a00f0
+#define FSTV0910_STRSTATUS_SEL2  0xf16a40f0
 #define FSTV0910_STRSTATUS_SEL1  0xf16a000f
 
 /* STRSTATUS2 */
 #define RSTV0910_STRSTATUS2  0xf16b
-#define FSTV0910_STRSTATUS_SEL4  0xf16b00f0
+#define FSTV0910_STRSTATUS_SEL4  0xf16b40f0
 #define FSTV0910_STRSTATUS_SEL3  0xf16b000f
 
 /* STRSTATUS3 */
 #define RSTV0910_STRSTATUS3  0xf16c
-#define FSTV0910_STRSTATUS_SEL6  0xf16c00f0
+#define FSTV0910_STRSTATUS_SEL6  0xf16c40f0
 #define FSTV0910_STRSTATUS_SEL5  0xf16c000f
 
 /* FSKTFC2 */
 #define RSTV0910_FSKTFC2  0xf170
-#define FSTV0910_FSKT_KMOD  0xf17000fc
+#define FSTV0910_FSKT_KMOD  0xf17020fc
 #define FSTV0910_FSKT_CAR2  0xf1700003
 
 /* FSKTFC1 */
@@ -330,17 +330,17 @@
 
 /* FSKTCTRL */
 #define RSTV0910_FSKTCTRL  0xf175
-#define FSTV0910_FSKT_PINSEL  0xf1750080
-#define FSTV0910_FSKT_EN_SGN  0xf1750040
-#define FSTV0910_FSKT_MOD_SGN  0xf1750020
-#define FSTV0910_FSKT_MOD_EN  0xf175001c
+#define FSTV0910_FSKT_PINSEL  0xf1757080
+#define FSTV0910_FSKT_EN_SGN  0xf1756040
+#define FSTV0910_FSKT_MOD_SGN  0xf1755020
+#define FSTV0910_FSKT_MOD_EN  0xf175201c
 #define FSTV0910_FSKT_DACMODE  0xf1750003
 
 /* FSKRFC2 */
 #define RSTV0910_FSKRFC2  0xf176
-#define FSTV0910_FSKR_DETSGN  0xf1760040
-#define FSTV0910_FSKR_OUTSGN  0xf1760020
-#define FSTV0910_FSKR_KAGC  0xf176001c
+#define FSTV0910_FSKR_DETSGN  0xf1766040
+#define FSTV0910_FSKR_OUTSGN  0xf1765020
+#define FSTV0910_FSKR_KAGC  0xf176201c
 #define FSTV0910_FSKR_CAR2  0xf1760003
 
 /* FSKRFC1 */
@@ -353,17 +353,17 @@
 
 /* FSKRK1 */
 #define RSTV0910_FSKRK1  0xf179
-#define FSTV0910_FSKR_K1_EXP  0xf17900e0
+#define FSTV0910_FSKR_K1_EXP  0xf17950e0
 #define FSTV0910_FSKR_K1_MANT  0xf179001f
 
 /* FSKRK2 */
 #define RSTV0910_FSKRK2  0xf17a
-#define FSTV0910_FSKR_K2_EXP  0xf17a00e0
+#define FSTV0910_FSKR_K2_EXP  0xf17a50e0
 #define FSTV0910_FSKR_K2_MANT  0xf17a001f
 
 /* FSKRAGCR */
 #define RSTV0910_FSKRAGCR  0xf17b
-#define FSTV0910_FSKR_OUTCTL  0xf17b00c0
+#define FSTV0910_FSKR_OUTCTL  0xf17b60c0
 #define FSTV0910_FSKR_AGC_REF  0xf17b003f
 
 /* FSKRAGC */
@@ -372,12 +372,12 @@
 
 /* FSKRALPHA */
 #define RSTV0910_FSKRALPHA  0xf17d
-#define FSTV0910_FSKR_ALPHA_EXP  0xf17d001c
+#define FSTV0910_FSKR_ALPHA_EXP  0xf17d201c
 #define FSTV0910_FSKR_ALPHA_M  0xf17d0003
 
 /* FSKRPLTH1 */
 #define RSTV0910_FSKRPLTH1  0xf17e
-#define FSTV0910_FSKR_BETA  0xf17e00f0
+#define FSTV0910_FSKR_BETA  0xf17e40f0
 #define FSTV0910_FSKR_PLL_TRESH1  0xf17e000f
 
 /* FSKRPLTH0 */
@@ -386,8 +386,8 @@
 
 /* FSKRDF1 */
 #define RSTV0910_FSKRDF1  0xf180
-#define FSTV0910_FSKR_OUT  0xf1800080
-#define FSTV0910_FSKR_STATE  0xf1800060
+#define FSTV0910_FSKR_OUT  0xf1807080
+#define FSTV0910_FSKR_STATE  0xf1805060
 #define FSTV0910_FSKR_DELTAF1  0xf180001f
 
 /* FSKRDF0 */
@@ -404,7 +404,7 @@
 
 /* FSKRDET1 */
 #define RSTV0910_FSKRDET1  0xf184
-#define FSTV0910_FSKR_DETECT  0xf1840080
+#define FSTV0910_FSKR_DETECT  0xf1847080
 #define FSTV0910_FSKR_CARDET_ACCU1  0xf184000f
 
 /* FSKRDET0 */
@@ -413,7 +413,7 @@
 
 /* FSKRDTH1 */
 #define RSTV0910_FSKRDTH1  0xf186
-#define FSTV0910_FSKR_CARLOSS_THRESH1  0xf18600f0
+#define FSTV0910_FSKR_CARLOSS_THRESH1  0xf18640f0
 #define FSTV0910_FSKR_CARDET_THRESH1  0xf186000f
 
 /* FSKRDTH0 */
@@ -426,7 +426,7 @@
 
 /* NCOARSE */
 #define RSTV0910_NCOARSE  0xf1b3
-#define FSTV0910_CP  0xf1b300f8
+#define FSTV0910_CP  0xf1b330f8
 #define FSTV0910_IDF  0xf1b30007
 
 /* NCOARSE1 */
@@ -439,14 +439,14 @@
 
 /* SYNTCTRL */
 #define RSTV0910_SYNTCTRL  0xf1b6
-#define FSTV0910_STANDBY  0xf1b60080
-#define FSTV0910_BYPASSPLLCORE  0xf1b60040
-#define FSTV0910_STOP_PLL  0xf1b60008
-#define FSTV0910_OSCI_E  0xf1b60002
+#define FSTV0910_STANDBY  0xf1b67080
+#define FSTV0910_BYPASSPLLCORE  0xf1b66040
+#define FSTV0910_STOP_PLL  0xf1b63008
+#define FSTV0910_OSCI_E  0xf1b61002
 
 /* FILTCTRL */
 #define RSTV0910_FILTCTRL  0xf1b7
-#define FSTV0910_INV_CLKFSK  0xf1b70002
+#define FSTV0910_INV_CLKFSK  0xf1b71002
 #define FSTV0910_BYPASS_APPLI  0xf1b70001
 
 /* PLLSTAT */
@@ -455,48 +455,48 @@
 
 /* STOPCLK1 */
 #define RSTV0910_STOPCLK1  0xf1c2
-#define FSTV0910_INV_CLKADCI2  0xf1c20004
+#define FSTV0910_INV_CLKADCI2  0xf1c22004
 #define FSTV0910_INV_CLKADCI1  0xf1c20001
 
 /* STOPCLK2 */
 #define RSTV0910_STOPCLK2  0xf1c3
-#define FSTV0910_STOP_DVBS2FEC2  0xf1c30020
-#define FSTV0910_STOP_DVBS2FEC  0xf1c30010
-#define FSTV0910_STOP_DVBS1FEC2  0xf1c30008
-#define FSTV0910_STOP_DVBS1FEC  0xf1c30004
-#define FSTV0910_STOP_DEMOD2  0xf1c30002
+#define FSTV0910_STOP_DVBS2FEC2  0xf1c35020
+#define FSTV0910_STOP_DVBS2FEC  0xf1c34010
+#define FSTV0910_STOP_DVBS1FEC2  0xf1c33008
+#define FSTV0910_STOP_DVBS1FEC  0xf1c32004
+#define FSTV0910_STOP_DEMOD2  0xf1c31002
 #define FSTV0910_STOP_DEMOD  0xf1c30001
 
 /* PREGCTL */
 #define RSTV0910_PREGCTL  0xf1c8
-#define FSTV0910_REG3V3TO2V5_POFF  0xf1c80080
+#define FSTV0910_REG3V3TO2V5_POFF  0xf1c87080
 
 /* TSTTNR0 */
 #define RSTV0910_TSTTNR0  0xf1df
-#define FSTV0910_FSK_PON  0xf1df0004
+#define FSTV0910_FSK_PON  0xf1df2004
 
 /* TSTTNR1 */
 #define RSTV0910_TSTTNR1  0xf1e0
-#define FSTV0910_ADC1_PON  0xf1e00002
+#define FSTV0910_ADC1_PON  0xf1e01002
 
 /* TSTTNR2 */
 #define RSTV0910_TSTTNR2  0xf1e1
-#define FSTV0910_I2C_DISEQC_PON  0xf1e10020
+#define FSTV0910_I2C_DISEQC_PON  0xf1e15020
 #define FSTV0910_DISEQC_CLKDIV  0xf1e1000f
 
 /* TSTTNR3 */
 #define RSTV0910_TSTTNR3  0xf1e2
-#define FSTV0910_ADC2_PON  0xf1e20002
+#define FSTV0910_ADC2_PON  0xf1e21002
 
 /* P2_IQCONST */
 #define RSTV0910_P2_IQCONST  0xf200
-#define FSTV0910_P2_CONSTEL_SELECT  0xf2000060
+#define FSTV0910_P2_CONSTEL_SELECT  0xf2005060
 #define FSTV0910_P2_IQSYMB_SEL  0xf200001f
 
 /* P2_NOSCFG */
 #define RSTV0910_P2_NOSCFG  0xf201
-#define FSTV0910_P2_DUMMYPL_NOSDATA  0xf2010020
-#define FSTV0910_P2_NOSPLH_BETA  0xf2010018
+#define FSTV0910_P2_DUMMYPL_NOSDATA  0xf2015020
+#define FSTV0910_P2_NOSPLH_BETA  0xf2013018
 #define FSTV0910_P2_NOSDATA_BETA  0xf2010007
 
 /* P2_ISYMB */
@@ -509,18 +509,18 @@
 
 /* P2_AGC1CFG */
 #define RSTV0910_P2_AGC1CFG  0xf204
-#define FSTV0910_P2_DC_FROZEN  0xf2040080
-#define FSTV0910_P2_DC_CORRECT  0xf2040040
-#define FSTV0910_P2_AMM_FROZEN  0xf2040020
-#define FSTV0910_P2_AMM_CORRECT  0xf2040010
-#define FSTV0910_P2_QUAD_FROZEN  0xf2040008
-#define FSTV0910_P2_QUAD_CORRECT  0xf2040004
+#define FSTV0910_P2_DC_FROZEN  0xf2047080
+#define FSTV0910_P2_DC_CORRECT  0xf2046040
+#define FSTV0910_P2_AMM_FROZEN  0xf2045020
+#define FSTV0910_P2_AMM_CORRECT  0xf2044010
+#define FSTV0910_P2_QUAD_FROZEN  0xf2043008
+#define FSTV0910_P2_QUAD_CORRECT  0xf2042004
 
 /* P2_AGC1CN */
 #define RSTV0910_P2_AGC1CN  0xf206
-#define FSTV0910_P2_AGC1_LOCKED  0xf2060080
-#define FSTV0910_P2_AGC1_MINPOWER  0xf2060010
-#define FSTV0910_P2_AGCOUT_FAST  0xf2060008
+#define FSTV0910_P2_AGC1_LOCKED  0xf2067080
+#define FSTV0910_P2_AGC1_MINPOWER  0xf2064010
+#define FSTV0910_P2_AGCOUT_FAST  0xf2063008
 #define FSTV0910_P2_AGCIQ_BETA  0xf2060007
 
 /* P2_AGC1REF */
@@ -561,50 +561,50 @@
 
 /* P2_DEMOD */
 #define RSTV0910_P2_DEMOD  0xf210
-#define FSTV0910_P2_MANUALS2_ROLLOFF  0xf2100080
-#define FSTV0910_P2_SPECINV_CONTROL  0xf2100030
-#define FSTV0910_P2_MANUALSX_ROLLOFF  0xf2100004
+#define FSTV0910_P2_MANUALS2_ROLLOFF  0xf2107080
+#define FSTV0910_P2_SPECINV_CONTROL  0xf2104030
+#define FSTV0910_P2_MANUALSX_ROLLOFF  0xf2102004
 #define FSTV0910_P2_ROLLOFF_CONTROL  0xf2100003
 
 /* P2_DMDMODCOD */
 #define RSTV0910_P2_DMDMODCOD  0xf211
-#define FSTV0910_P2_MANUAL_MODCOD  0xf2110080
-#define FSTV0910_P2_DEMOD_MODCOD  0xf211007c
+#define FSTV0910_P2_MANUAL_MODCOD  0xf2117080
+#define FSTV0910_P2_DEMOD_MODCOD  0xf211207c
 #define FSTV0910_P2_DEMOD_TYPE  0xf2110003
 
 /* P2_DSTATUS */
 #define RSTV0910_P2_DSTATUS  0xf212
-#define FSTV0910_P2_CAR_LOCK  0xf2120080
-#define FSTV0910_P2_TMGLOCK_QUALITY  0xf2120060
-#define FSTV0910_P2_LOCK_DEFINITIF  0xf2120008
+#define FSTV0910_P2_CAR_LOCK  0xf2127080
+#define FSTV0910_P2_TMGLOCK_QUALITY  0xf2125060
+#define FSTV0910_P2_LOCK_DEFINITIF  0xf2123008
 #define FSTV0910_P2_OVADC_DETECT  0xf2120001
 
 /* P2_DSTATUS2 */
 #define RSTV0910_P2_DSTATUS2  0xf213
-#define FSTV0910_P2_DEMOD_DELOCK  0xf2130080
-#define FSTV0910_P2_MODCODRQ_SYNCTAG  0xf2130020
-#define FSTV0910_P2_POLYPH_SATEVENT  0xf2130010
-#define FSTV0910_P2_AGC1_NOSIGNALACK  0xf2130008
-#define FSTV0910_P2_AGC2_OVERFLOW  0xf2130004
-#define FSTV0910_P2_CFR_OVERFLOW  0xf2130002
+#define FSTV0910_P2_DEMOD_DELOCK  0xf2137080
+#define FSTV0910_P2_MODCODRQ_SYNCTAG  0xf2135020
+#define FSTV0910_P2_POLYPH_SATEVENT  0xf2134010
+#define FSTV0910_P2_AGC1_NOSIGNALACK  0xf2133008
+#define FSTV0910_P2_AGC2_OVERFLOW  0xf2132004
+#define FSTV0910_P2_CFR_OVERFLOW  0xf2131002
 #define FSTV0910_P2_GAMMA_OVERUNDER  0xf2130001
 
 /* P2_DMDCFGMD */
 #define RSTV0910_P2_DMDCFGMD  0xf214
-#define FSTV0910_P2_DVBS2_ENABLE  0xf2140080
-#define FSTV0910_P2_DVBS1_ENABLE  0xf2140040
-#define FSTV0910_P2_SCAN_ENABLE  0xf2140010
-#define FSTV0910_P2_CFR_AUTOSCAN  0xf2140008
+#define FSTV0910_P2_DVBS2_ENABLE  0xf2147080
+#define FSTV0910_P2_DVBS1_ENABLE  0xf2146040
+#define FSTV0910_P2_SCAN_ENABLE  0xf2144010
+#define FSTV0910_P2_CFR_AUTOSCAN  0xf2143008
 #define FSTV0910_P2_TUN_RNG  0xf2140003
 
 /* P2_DMDCFG2 */
 #define RSTV0910_P2_DMDCFG2  0xf215
-#define FSTV0910_P2_S1S2_SEQUENTIAL  0xf2150040
-#define FSTV0910_P2_INFINITE_RELOCK  0xf2150010
+#define FSTV0910_P2_S1S2_SEQUENTIAL  0xf2156040
+#define FSTV0910_P2_INFINITE_RELOCK  0xf2154010
 
 /* P2_DMDISTATE */
 #define RSTV0910_P2_DMDISTATE  0xf216
-#define FSTV0910_P2_I2C_NORESETDMODE  0xf2160080
+#define FSTV0910_P2_I2C_NORESETDMODE  0xf2167080
 #define FSTV0910_P2_I2C_DEMOD_MODE  0xf216001f
 
 /* P2_DMDT0M */
@@ -613,27 +613,27 @@
 
 /* P2_DMDSTATE */
 #define RSTV0910_P2_DMDSTATE  0xf21b
-#define FSTV0910_P2_HEADER_MODE  0xf21b0060
+#define FSTV0910_P2_HEADER_MODE  0xf21b5060
 
 /* P2_DMDFLYW */
 #define RSTV0910_P2_DMDFLYW  0xf21c
-#define FSTV0910_P2_I2C_IRQVAL  0xf21c00f0
+#define FSTV0910_P2_I2C_IRQVAL  0xf21c40f0
 #define FSTV0910_P2_FLYWHEEL_CPT  0xf21c000f
 
 /* P2_DSTATUS3 */
 #define RSTV0910_P2_DSTATUS3  0xf21d
-#define FSTV0910_P2_CFR_ZIGZAG  0xf21d0080
-#define FSTV0910_P2_DEMOD_CFGMODE  0xf21d0060
-#define FSTV0910_P2_GAMMA_LOWBAUDRATE  0xf21d0010
+#define FSTV0910_P2_CFR_ZIGZAG  0xf21d7080
+#define FSTV0910_P2_DEMOD_CFGMODE  0xf21d5060
+#define FSTV0910_P2_GAMMA_LOWBAUDRATE  0xf21d4010
 
 /* P2_DMDCFG3 */
 #define RSTV0910_P2_DMDCFG3  0xf21e
-#define FSTV0910_P2_NOSTOP_FIFOFULL  0xf21e0008
+#define FSTV0910_P2_NOSTOP_FIFOFULL  0xf21e3008
 
 /* P2_DMDCFG4 */
 #define RSTV0910_P2_DMDCFG4  0xf21f
-#define FSTV0910_P2_DIS_VITLOCK  0xf21f0080
-#define FSTV0910_P2_DIS_CLKENABLE  0xf21f0004
+#define FSTV0910_P2_DIS_VITLOCK  0xf21f7080
+#define FSTV0910_P2_DIS_CLKENABLE  0xf21f2004
 
 /* P2_CORRELMANT */
 #define RSTV0910_P2_CORRELMANT  0xf220
@@ -645,13 +645,13 @@
 
 /* P2_CORRELEXP */
 #define RSTV0910_P2_CORRELEXP  0xf222
-#define FSTV0910_P2_CORREL_ABSEXP  0xf22200f0
+#define FSTV0910_P2_CORREL_ABSEXP  0xf22240f0
 #define FSTV0910_P2_CORREL_EXP  0xf222000f
 
 /* P2_PLHMODCOD */
 #define RSTV0910_P2_PLHMODCOD  0xf224
-#define FSTV0910_P2_SPECINV_DEMOD  0xf2240080
-#define FSTV0910_P2_PLH_MODCOD  0xf224007c
+#define FSTV0910_P2_SPECINV_DEMOD  0xf2247080
+#define FSTV0910_P2_PLH_MODCOD  0xf224207c
 #define FSTV0910_P2_PLH_TYPE  0xf2240003
 
 /* P2_DMDREG */
@@ -660,19 +660,19 @@
 
 /* P2_AGCNADJ */
 #define RSTV0910_P2_AGCNADJ  0xf226
-#define FSTV0910_P2_RADJOFF_AGC2  0xf2260080
-#define FSTV0910_P2_RADJOFF_AGC1  0xf2260040
+#define FSTV0910_P2_RADJOFF_AGC2  0xf2267080
+#define FSTV0910_P2_RADJOFF_AGC1  0xf2266040
 #define FSTV0910_P2_AGC_NADJ  0xf226013f
 
 /* P2_AGCKS */
 #define RSTV0910_P2_AGCKS  0xf227
-#define FSTV0910_P2_RSADJ_MANUALCFG  0xf2270080
-#define FSTV0910_P2_RSADJ_CCMMODE  0xf2270040
+#define FSTV0910_P2_RSADJ_MANUALCFG  0xf2277080
+#define FSTV0910_P2_RSADJ_CCMMODE  0xf2276040
 #define FSTV0910_P2_RADJ_SPSK  0xf227013f
 
 /* P2_AGCKQ */
 #define RSTV0910_P2_AGCKQ  0xf228
-#define FSTV0910_P2_RADJON_DVBS1  0xf2280040
+#define FSTV0910_P2_RADJON_DVBS1  0xf2286040
 #define FSTV0910_P2_RADJ_QPSK  0xf228013f
 
 /* P2_AGCK8 */
@@ -681,20 +681,20 @@
 
 /* P2_AGCK16 */
 #define RSTV0910_P2_AGCK16  0xf22a
-#define FSTV0910_P2_R2ADJOFF_16APSK  0xf22a0040
-#define FSTV0910_P2_R1ADJOFF_16APSK  0xf22a0020
+#define FSTV0910_P2_R2ADJOFF_16APSK  0xf22a6040
+#define FSTV0910_P2_R1ADJOFF_16APSK  0xf22a5020
 #define FSTV0910_P2_RADJ_16APSK  0xf22a011f
 
 /* P2_AGCK32 */
 #define RSTV0910_P2_AGCK32  0xf22b
-#define FSTV0910_P2_R3ADJOFF_32APSK  0xf22b0080
-#define FSTV0910_P2_R2ADJOFF_32APSK  0xf22b0040
-#define FSTV0910_P2_R1ADJOFF_32APSK  0xf22b0020
+#define FSTV0910_P2_R3ADJOFF_32APSK  0xf22b7080
+#define FSTV0910_P2_R2ADJOFF_32APSK  0xf22b6040
+#define FSTV0910_P2_R1ADJOFF_32APSK  0xf22b5020
 #define FSTV0910_P2_RADJ_32APSK  0xf22b011f
 
 /* P2_AGC2O */
 #define RSTV0910_P2_AGC2O  0xf22c
-#define FSTV0910_P2_CSTENV_MODE  0xf22c00c0
+#define FSTV0910_P2_CSTENV_MODE  0xf22c60c0
 #define FSTV0910_P2_AGC2_COEF  0xf22c0007
 
 /* P2_AGC2REF */
@@ -743,32 +743,32 @@
 
 /* P2_CARCFG */
 #define RSTV0910_P2_CARCFG  0xf238
-#define FSTV0910_P2_ROTAON  0xf2380004
+#define FSTV0910_P2_ROTAON  0xf2382004
 #define FSTV0910_P2_PH_DET_ALGO  0xf2380003
 
 /* P2_ACLC */
 #define RSTV0910_P2_ACLC  0xf239
-#define FSTV0910_P2_CAR_ALPHA_MANT  0xf2390030
+#define FSTV0910_P2_CAR_ALPHA_MANT  0xf2394030
 #define FSTV0910_P2_CAR_ALPHA_EXP  0xf239000f
 
 /* P2_BCLC */
 #define RSTV0910_P2_BCLC  0xf23a
-#define FSTV0910_P2_CAR_BETA_MANT  0xf23a0030
+#define FSTV0910_P2_CAR_BETA_MANT  0xf23a4030
 #define FSTV0910_P2_CAR_BETA_EXP  0xf23a000f
 
 /* P2_ACLCS2 */
 #define RSTV0910_P2_ACLCS2  0xf23b
-#define FSTV0910_P2_CARS2_APLHA_MANTISSE  0xf23b0030
+#define FSTV0910_P2_CARS2_APLHA_MANTISSE  0xf23b4030
 #define FSTV0910_P2_CARS2_ALPHA_EXP  0xf23b000f
 
 /* P2_BCLCS2 */
 #define RSTV0910_P2_BCLCS2  0xf23c
-#define FSTV0910_P2_CARS2_BETA_MANTISSE  0xf23c0030
+#define FSTV0910_P2_CARS2_BETA_MANTISSE  0xf23c4030
 #define FSTV0910_P2_CARS2_BETA_EXP  0xf23c000f
 
 /* P2_CARFREQ */
 #define RSTV0910_P2_CARFREQ  0xf23d
-#define FSTV0910_P2_KC_COARSE_EXP  0xf23d00f0
+#define FSTV0910_P2_KC_COARSE_EXP  0xf23d40f0
 #define FSTV0910_P2_BETA_FREQ  0xf23d000f
 
 /* P2_CARHDR */
@@ -821,7 +821,7 @@
 
 /* P2_CFRINC1 */
 #define RSTV0910_P2_CFRINC1  0xf24a
-#define FSTV0910_P2_MANUAL_CFRINC  0xf24a0080
+#define FSTV0910_P2_MANUAL_CFRINC  0xf24a7080
 #define FSTV0910_P2_CFR_INC1  0xf24a003f
 
 /* P2_CFRINC0 */
@@ -846,18 +846,18 @@
 
 /* P2_TMGCFG */
 #define RSTV0910_P2_TMGCFG  0xf250
-#define FSTV0910_P2_TMGLOCK_BETA  0xf25000c0
-#define FSTV0910_P2_DO_TIMING_CORR  0xf2500010
+#define FSTV0910_P2_TMGLOCK_BETA  0xf25060c0
+#define FSTV0910_P2_DO_TIMING_CORR  0xf2504010
 #define FSTV0910_P2_TMG_MINFREQ  0xf2500003
 
 /* P2_RTC */
 #define RSTV0910_P2_RTC  0xf251
-#define FSTV0910_P2_TMGALPHA_EXP  0xf25100f0
+#define FSTV0910_P2_TMGALPHA_EXP  0xf25140f0
 #define FSTV0910_P2_TMGBETA_EXP  0xf251000f
 
 /* P2_RTCS2 */
 #define RSTV0910_P2_RTCS2  0xf252
-#define FSTV0910_P2_TMGALPHAS2_EXP  0xf25200f0
+#define FSTV0910_P2_TMGALPHAS2_EXP  0xf25240f0
 #define FSTV0910_P2_TMGBETAS2_EXP  0xf252000f
 
 /* P2_TMGTHRISE */
@@ -878,7 +878,7 @@
 
 /* P2_KTTMG */
 #define RSTV0910_P2_KTTMG  0xf257
-#define FSTV0910_P2_KT_TMG_EXP  0xf25700f0
+#define FSTV0910_P2_KT_TMG_EXP  0xf25740f0
 
 /* P2_KREFTMG */
 #define RSTV0910_P2_KREFTMG  0xf258
@@ -886,12 +886,12 @@
 
 /* P2_SFRSTEP */
 #define RSTV0910_P2_SFRSTEP  0xf259
-#define FSTV0910_P2_SFR_SCANSTEP  0xf25900f0
+#define FSTV0910_P2_SFR_SCANSTEP  0xf25940f0
 #define FSTV0910_P2_SFR_CENTERSTEP  0xf259000f
 
 /* P2_TMGCFG2 */
 #define RSTV0910_P2_TMGCFG2  0xf25a
-#define FSTV0910_P2_DIS_AUTOSAMP  0xf25a0008
+#define FSTV0910_P2_DIS_AUTOSAMP  0xf25a3008
 #define FSTV0910_P2_SFRRATIO_FINE  0xf25a0001
 
 /* P2_KREFTMG2 */
@@ -900,9 +900,9 @@
 
 /* P2_TMGCFG3 */
 #define RSTV0910_P2_TMGCFG3  0xf25d
-#define FSTV0910_P2_CONT_TMGCENTER  0xf25d0008
-#define FSTV0910_P2_AUTO_GUP  0xf25d0004
-#define FSTV0910_P2_AUTO_GLOW  0xf25d0002
+#define FSTV0910_P2_CONT_TMGCENTER  0xf25d3008
+#define FSTV0910_P2_AUTO_GUP  0xf25d2004
+#define FSTV0910_P2_AUTO_GLOW  0xf25d1002
 
 /* P2_SFRINIT1 */
 #define RSTV0910_P2_SFRINIT1  0xf25e
@@ -966,11 +966,11 @@
 
 /* P2_TMGOBS */
 #define RSTV0910_P2_TMGOBS  0xf26d
-#define FSTV0910_P2_ROLLOFF_STATUS  0xf26d00c0
+#define FSTV0910_P2_ROLLOFF_STATUS  0xf26d60c0
 
 /* P2_EQUALCFG */
 #define RSTV0910_P2_EQUALCFG  0xf26f
-#define FSTV0910_P2_EQUAL_ON  0xf26f0040
+#define FSTV0910_P2_EQUAL_ON  0xf26f6040
 #define FSTV0910_P2_MU_EQUALDFE  0xf26f0007
 
 /* P2_EQUAI1 */
@@ -1095,33 +1095,33 @@
 
 /* P2_NOSCFGF1 */
 #define RSTV0910_P2_NOSCFGF1  0xf28e
-#define FSTV0910_P2_LOWNOISE_MESURE  0xf28e0080
-#define FSTV0910_P2_NOS_DELFRAME  0xf28e0040
-#define FSTV0910_P2_NOSDATA_MODE  0xf28e0030
-#define FSTV0910_P2_FRAMESEL_TYPESEL  0xf28e000c
+#define FSTV0910_P2_LOWNOISE_MESURE  0xf28e7080
+#define FSTV0910_P2_NOS_DELFRAME  0xf28e6040
+#define FSTV0910_P2_NOSDATA_MODE  0xf28e4030
+#define FSTV0910_P2_FRAMESEL_TYPESEL  0xf28e200c
 #define FSTV0910_P2_FRAMESEL_TYPE  0xf28e0003
 
 /* P2_NOSCFGF2 */
 #define RSTV0910_P2_NOSCFGF2  0xf28f
-#define FSTV0910_P2_DIS_NOSPILOTS  0xf28f0080
-#define FSTV0910_P2_FRAMESEL_MODCODSEL  0xf28f0060
+#define FSTV0910_P2_DIS_NOSPILOTS  0xf28f7080
+#define FSTV0910_P2_FRAMESEL_MODCODSEL  0xf28f5060
 #define FSTV0910_P2_FRAMESEL_MODCOD  0xf28f001f
 
 /* P2_CAR2CFG */
 #define RSTV0910_P2_CAR2CFG  0xf290
-#define FSTV0910_P2_ROTA2ON  0xf2900004
+#define FSTV0910_P2_ROTA2ON  0xf2902004
 #define FSTV0910_P2_PH_DET_ALGO2  0xf2900003
 
 /* P2_CFR2CFR1 */
 #define RSTV0910_P2_CFR2CFR1  0xf291
-#define FSTV0910_P2_EN_S2CAR2CENTER  0xf2910020
+#define FSTV0910_P2_EN_S2CAR2CENTER  0xf2915020
 #define FSTV0910_P2_CFR2TOCFR1_BETA  0xf2910007
 
 /* P2_CAR3CFG */
 #define RSTV0910_P2_CAR3CFG  0xf292
-#define FSTV0910_P2_CARRIER23_MODE  0xf29200c0
-#define FSTV0910_P2_CAR3INTERM_DVBS1  0xf2920020
-#define FSTV0910_P2_ABAMPLIF_MODE  0xf2920018
+#define FSTV0910_P2_CARRIER23_MODE  0xf29260c0
+#define FSTV0910_P2_CAR3INTERM_DVBS1  0xf2925020
+#define FSTV0910_P2_ABAMPLIF_MODE  0xf2923018
 #define FSTV0910_P2_CARRIER3_ALPHA3DL  0xf2920007
 
 /* P2_CFR22 */
@@ -1138,50 +1138,50 @@
 
 /* P2_ACLC2S2Q */
 #define RSTV0910_P2_ACLC2S2Q  0xf297
-#define FSTV0910_P2_ENAB_SPSKSYMB  0xf2970080
-#define FSTV0910_P2_CAR2S2_Q_ALPH_M  0xf2970030
+#define FSTV0910_P2_ENAB_SPSKSYMB  0xf2977080
+#define FSTV0910_P2_CAR2S2_Q_ALPH_M  0xf2974030
 #define FSTV0910_P2_CAR2S2_Q_ALPH_E  0xf297000f
 
 /* P2_ACLC2S28 */
 #define RSTV0910_P2_ACLC2S28  0xf298
-#define FSTV0910_P2_CAR2S2_8_ALPH_M  0xf2980030
+#define FSTV0910_P2_CAR2S2_8_ALPH_M  0xf2984030
 #define FSTV0910_P2_CAR2S2_8_ALPH_E  0xf298000f
 
 /* P2_ACLC2S216A */
 #define RSTV0910_P2_ACLC2S216A  0xf299
-#define FSTV0910_P2_CAR2S2_16A_ALPH_M  0xf2990030
+#define FSTV0910_P2_CAR2S2_16A_ALPH_M  0xf2994030
 #define FSTV0910_P2_CAR2S2_16A_ALPH_E  0xf299000f
 
 /* P2_ACLC2S232A */
 #define RSTV0910_P2_ACLC2S232A  0xf29a
-#define FSTV0910_P2_CAR2S2_32A_ALPH_M  0xf29a0030
+#define FSTV0910_P2_CAR2S2_32A_ALPH_M  0xf29a4030
 #define FSTV0910_P2_CAR2S2_32A_ALPH_E  0xf29a000f
 
 /* P2_BCLC2S2Q */
 #define RSTV0910_P2_BCLC2S2Q  0xf29c
-#define FSTV0910_P2_CAR2S2_Q_BETA_M  0xf29c0030
+#define FSTV0910_P2_CAR2S2_Q_BETA_M  0xf29c4030
 #define FSTV0910_P2_CAR2S2_Q_BETA_E  0xf29c000f
 
 /* P2_BCLC2S28 */
 #define RSTV0910_P2_BCLC2S28  0xf29d
-#define FSTV0910_P2_CAR2S2_8_BETA_M  0xf29d0030
+#define FSTV0910_P2_CAR2S2_8_BETA_M  0xf29d4030
 #define FSTV0910_P2_CAR2S2_8_BETA_E  0xf29d000f
 
 /* P2_BCLC2S216A */
 #define RSTV0910_P2_BCLC2S216A  0xf29e
-#define FSTV0910_P2_DVBS2S216A_NIP  0xf29e0080
-#define FSTV0910_P2_CAR2S2_16A_BETA_M  0xf29e0030
+#define FSTV0910_P2_DVBS2S216A_NIP  0xf29e7080
+#define FSTV0910_P2_CAR2S2_16A_BETA_M  0xf29e4030
 #define FSTV0910_P2_CAR2S2_16A_BETA_E  0xf29e000f
 
 /* P2_BCLC2S232A */
 #define RSTV0910_P2_BCLC2S232A  0xf29f
-#define FSTV0910_P2_DVBS2S232A_NIP  0xf29f0080
-#define FSTV0910_P2_CAR2S2_32A_BETA_M  0xf29f0030
+#define FSTV0910_P2_DVBS2S232A_NIP  0xf29f7080
+#define FSTV0910_P2_CAR2S2_32A_BETA_M  0xf29f4030
 #define FSTV0910_P2_CAR2S2_32A_BETA_E  0xf29f000f
 
 /* P2_PLROOT2 */
 #define RSTV0910_P2_PLROOT2  0xf2ac
-#define FSTV0910_P2_PLSCRAMB_MODE  0xf2ac000c
+#define FSTV0910_P2_PLSCRAMB_MODE  0xf2ac200c
 #define FSTV0910_P2_PLSCRAMB_ROOT2  0xf2ac0003
 
 /* P2_PLROOT1 */
@@ -1198,100 +1198,100 @@
 
 /* P2_MODCODLST1 */
 #define RSTV0910_P2_MODCODLST1  0xf2b1
-#define FSTV0910_P2_SYMBRATE_FILTER  0xf2b10008
-#define FSTV0910_P2_NRESET_MODCODLST  0xf2b10004
+#define FSTV0910_P2_SYMBRATE_FILTER  0xf2b13008
+#define FSTV0910_P2_NRESET_MODCODLST  0xf2b12004
 #define FSTV0910_P2_DIS_32PSK_9_10  0xf2b10003
 
 /* P2_MODCODLST2 */
 #define RSTV0910_P2_MODCODLST2  0xf2b2
-#define FSTV0910_P2_DIS_32PSK_8_9  0xf2b200f0
+#define FSTV0910_P2_DIS_32PSK_8_9  0xf2b240f0
 #define FSTV0910_P2_DIS_32PSK_5_6  0xf2b2000f
 
 /* P2_MODCODLST3 */
 #define RSTV0910_P2_MODCODLST3  0xf2b3
-#define FSTV0910_P2_DIS_32PSK_4_5  0xf2b300f0
+#define FSTV0910_P2_DIS_32PSK_4_5  0xf2b340f0
 #define FSTV0910_P2_DIS_32PSK_3_4  0xf2b3000f
 
 /* P2_MODCODLST4 */
 #define RSTV0910_P2_MODCODLST4  0xf2b4
-#define FSTV0910_P2_DUMMYPL_PILOT  0xf2b40080
-#define FSTV0910_P2_DUMMYPL_NOPILOT  0xf2b40040
-#define FSTV0910_P2_DIS_16PSK_9_10  0xf2b40030
+#define FSTV0910_P2_DUMMYPL_PILOT  0xf2b47080
+#define FSTV0910_P2_DUMMYPL_NOPILOT  0xf2b46040
+#define FSTV0910_P2_DIS_16PSK_9_10  0xf2b44030
 #define FSTV0910_P2_DIS_16PSK_8_9  0xf2b4000f
 
 /* P2_MODCODLST5 */
 #define RSTV0910_P2_MODCODLST5  0xf2b5
-#define FSTV0910_P2_DIS_16PSK_5_6  0xf2b500f0
+#define FSTV0910_P2_DIS_16PSK_5_6  0xf2b540f0
 #define FSTV0910_P2_DIS_16PSK_4_5  0xf2b5000f
 
 /* P2_MODCODLST6 */
 #define RSTV0910_P2_MODCODLST6  0xf2b6
-#define FSTV0910_P2_DIS_16PSK_3_4  0xf2b600f0
+#define FSTV0910_P2_DIS_16PSK_3_4  0xf2b640f0
 #define FSTV0910_P2_DIS_16PSK_2_3  0xf2b6000f
 
 /* P2_MODCODLST7 */
 #define RSTV0910_P2_MODCODLST7  0xf2b7
-#define FSTV0910_P2_MODCOD_NNOSFILTER  0xf2b70080
-#define FSTV0910_P2_DIS_8PSK_9_10  0xf2b70030
+#define FSTV0910_P2_MODCOD_NNOSFILTER  0xf2b77080
+#define FSTV0910_P2_DIS_8PSK_9_10  0xf2b74030
 #define FSTV0910_P2_DIS_8PSK_8_9  0xf2b7000f
 
 /* P2_MODCODLST8 */
 #define RSTV0910_P2_MODCODLST8  0xf2b8
-#define FSTV0910_P2_DIS_8PSK_5_6  0xf2b800f0
+#define FSTV0910_P2_DIS_8PSK_5_6  0xf2b840f0
 #define FSTV0910_P2_DIS_8PSK_3_4  0xf2b8000f
 
 /* P2_MODCODLST9 */
 #define RSTV0910_P2_MODCODLST9  0xf2b9
-#define FSTV0910_P2_DIS_8PSK_2_3  0xf2b900f0
+#define FSTV0910_P2_DIS_8PSK_2_3  0xf2b940f0
 #define FSTV0910_P2_DIS_8PSK_3_5  0xf2b9000f
 
 /* P2_MODCODLSTA */
 #define RSTV0910_P2_MODCODLSTA  0xf2ba
-#define FSTV0910_P2_NOSFILTER_LIMITE  0xf2ba0080
-#define FSTV0910_P2_DIS_QPSK_9_10  0xf2ba0030
+#define FSTV0910_P2_NOSFILTER_LIMITE  0xf2ba7080
+#define FSTV0910_P2_DIS_QPSK_9_10  0xf2ba4030
 #define FSTV0910_P2_DIS_QPSK_8_9  0xf2ba000f
 
 /* P2_MODCODLSTB */
 #define RSTV0910_P2_MODCODLSTB  0xf2bb
-#define FSTV0910_P2_DIS_QPSK_5_6  0xf2bb00f0
+#define FSTV0910_P2_DIS_QPSK_5_6  0xf2bb40f0
 #define FSTV0910_P2_DIS_QPSK_4_5  0xf2bb000f
 
 /* P2_MODCODLSTC */
 #define RSTV0910_P2_MODCODLSTC  0xf2bc
-#define FSTV0910_P2_DIS_QPSK_3_4  0xf2bc00f0
+#define FSTV0910_P2_DIS_QPSK_3_4  0xf2bc40f0
 #define FSTV0910_P2_DIS_QPSK_2_3  0xf2bc000f
 
 /* P2_MODCODLSTD */
 #define RSTV0910_P2_MODCODLSTD  0xf2bd
-#define FSTV0910_P2_DIS_QPSK_3_5  0xf2bd00f0
+#define FSTV0910_P2_DIS_QPSK_3_5  0xf2bd40f0
 #define FSTV0910_P2_DIS_QPSK_1_2  0xf2bd000f
 
 /* P2_MODCODLSTE */
 #define RSTV0910_P2_MODCODLSTE  0xf2be
-#define FSTV0910_P2_DIS_QPSK_2_5  0xf2be00f0
+#define FSTV0910_P2_DIS_QPSK_2_5  0xf2be40f0
 #define FSTV0910_P2_DIS_QPSK_1_3  0xf2be000f
 
 /* P2_MODCODLSTF */
 #define RSTV0910_P2_MODCODLSTF  0xf2bf
-#define FSTV0910_P2_DIS_QPSK_1_4  0xf2bf00f0
-#define FSTV0910_P2_DEMOD_INVMODLST  0xf2bf0008
-#define FSTV0910_P2_DEMODOUT_ENABLE  0xf2bf0004
-#define FSTV0910_P2_DDEMOD_NSET  0xf2bf0002
+#define FSTV0910_P2_DIS_QPSK_1_4  0xf2bf40f0
+#define FSTV0910_P2_DEMOD_INVMODLST  0xf2bf3008
+#define FSTV0910_P2_DEMODOUT_ENABLE  0xf2bf2004
+#define FSTV0910_P2_DDEMOD_NSET  0xf2bf1002
 #define FSTV0910_P2_MODCOD_NSTOCK  0xf2bf0001
 
 /* P2_GAUSSR0 */
 #define RSTV0910_P2_GAUSSR0  0xf2c0
-#define FSTV0910_P2_EN_CCIMODE  0xf2c00080
+#define FSTV0910_P2_EN_CCIMODE  0xf2c07080
 #define FSTV0910_P2_R0_GAUSSIEN  0xf2c0007f
 
 /* P2_CCIR0 */
 #define RSTV0910_P2_CCIR0  0xf2c1
-#define FSTV0910_P2_CCIDETECT_PLHONLY  0xf2c10080
+#define FSTV0910_P2_CCIDETECT_PLHONLY  0xf2c17080
 #define FSTV0910_P2_R0_CCI  0xf2c1007f
 
 /* P2_CCIQUANT */
 #define RSTV0910_P2_CCIQUANT  0xf2c2
-#define FSTV0910_P2_CCI_BETA  0xf2c200e0
+#define FSTV0910_P2_CCI_BETA  0xf2c250e0
 #define FSTV0910_P2_CCI_QUANT  0xf2c2001f
 
 /* P2_CCITHRES */
@@ -1304,24 +1304,24 @@
 
 /* P2_DSTATUS4 */
 #define RSTV0910_P2_DSTATUS4  0xf2c5
-#define FSTV0910_P2_RAINFADE_DETECT  0xf2c50080
-#define FSTV0910_P2_NOTHRES2_FAIL  0xf2c50040
-#define FSTV0910_P2_NOTHRES1_FAIL  0xf2c50020
-#define FSTV0910_P2_DMDPROG_ERROR  0xf2c50004
-#define FSTV0910_P2_CSTENV_DETECT  0xf2c50002
+#define FSTV0910_P2_RAINFADE_DETECT  0xf2c57080
+#define FSTV0910_P2_NOTHRES2_FAIL  0xf2c56040
+#define FSTV0910_P2_NOTHRES1_FAIL  0xf2c55020
+#define FSTV0910_P2_DMDPROG_ERROR  0xf2c52004
+#define FSTV0910_P2_CSTENV_DETECT  0xf2c51002
 #define FSTV0910_P2_DETECTION_TRIAX  0xf2c50001
 
 /* P2_DMDRESCFG */
 #define RSTV0910_P2_DMDRESCFG  0xf2c6
-#define FSTV0910_P2_DMDRES_RESET  0xf2c60080
-#define FSTV0910_P2_DMDRES_STRALL  0xf2c60008
-#define FSTV0910_P2_DMDRES_NEWONLY  0xf2c60004
-#define FSTV0910_P2_DMDRES_NOSTORE  0xf2c60002
+#define FSTV0910_P2_DMDRES_RESET  0xf2c67080
+#define FSTV0910_P2_DMDRES_STRALL  0xf2c63008
+#define FSTV0910_P2_DMDRES_NEWONLY  0xf2c62004
+#define FSTV0910_P2_DMDRES_NOSTORE  0xf2c61002
 
 /* P2_DMDRESADR */
 #define RSTV0910_P2_DMDRESADR  0xf2c7
-#define FSTV0910_P2_DMDRES_VALIDCFR  0xf2c70040
-#define FSTV0910_P2_DMDRES_MEMFULL  0xf2c70030
+#define FSTV0910_P2_DMDRES_VALIDCFR  0xf2c76040
+#define FSTV0910_P2_DMDRES_MEMFULL  0xf2c74030
 #define FSTV0910_P2_DMDRES_RESNBR  0xf2c7000f
 
 /* P2_DMDRESDATA7 */
@@ -1390,29 +1390,29 @@
 
 /* P2_FFECFG */
 #define RSTV0910_P2_FFECFG  0xf2d8
-#define FSTV0910_P2_EQUALFFE_ON  0xf2d80040
-#define FSTV0910_P2_EQUAL_USEDSYMB  0xf2d80030
+#define FSTV0910_P2_EQUALFFE_ON  0xf2d86040
+#define FSTV0910_P2_EQUAL_USEDSYMB  0xf2d84030
 #define FSTV0910_P2_MU_EQUALFFE  0xf2d80007
 
 /* P2_TNRCFG2 */
 #define RSTV0910_P2_TNRCFG2  0xf2e1
-#define FSTV0910_P2_TUN_IQSWAP  0xf2e10080
+#define FSTV0910_P2_TUN_IQSWAP  0xf2e17080
 
 /* P2_SMAPCOEF7 */
 #define RSTV0910_P2_SMAPCOEF7  0xf300
-#define FSTV0910_P2_DIS_QSCALE  0xf3000080
+#define FSTV0910_P2_DIS_QSCALE  0xf3007080
 #define FSTV0910_P2_SMAPCOEF_Q_LLR12  0xf300017f
 
 /* P2_SMAPCOEF6 */
 #define RSTV0910_P2_SMAPCOEF6  0xf301
-#define FSTV0910_P2_DIS_AGC2SCALE  0xf3010080
-#define FSTV0910_P2_ADJ_8PSKLLR1  0xf3010004
-#define FSTV0910_P2_OLD_8PSKLLR1  0xf3010002
+#define FSTV0910_P2_DIS_AGC2SCALE  0xf3017080
+#define FSTV0910_P2_ADJ_8PSKLLR1  0xf3012004
+#define FSTV0910_P2_OLD_8PSKLLR1  0xf3011002
 #define FSTV0910_P2_DIS_AB8PSK  0xf3010001
 
 /* P2_SMAPCOEF5 */
 #define RSTV0910_P2_SMAPCOEF5  0xf302
-#define FSTV0910_P2_DIS_8SCALE  0xf3020080
+#define FSTV0910_P2_DIS_8SCALE  0xf3027080
 #define FSTV0910_P2_SMAPCOEF_8P_LLR23  0xf302017f
 
 /* P2_SMAPCOEF4 */
@@ -1425,17 +1425,17 @@
 
 /* P2_SMAPCOEF2 */
 #define RSTV0910_P2_SMAPCOEF2  0xf305
-#define FSTV0910_P2_SMAPCOEF_32APSK_R2R3  0xf30501f0
+#define FSTV0910_P2_SMAPCOEF_32APSK_R2R3  0xf30541f0
 #define FSTV0910_P2_SMAPCOEF_32APSK_LLR2  0xf305010f
 
 /* P2_SMAPCOEF1 */
 #define RSTV0910_P2_SMAPCOEF1  0xf306
-#define FSTV0910_P2_DIS_16SCALE  0xf3060080
+#define FSTV0910_P2_DIS_16SCALE  0xf3067080
 #define FSTV0910_P2_SMAPCOEF_32_LLR34  0xf306017f
 
 /* P2_SMAPCOEF0 */
 #define RSTV0910_P2_SMAPCOEF0  0xf307
-#define FSTV0910_P2_DIS_32SCALE  0xf3070080
+#define FSTV0910_P2_DIS_32SCALE  0xf3077080
 #define FSTV0910_P2_SMAPCOEF_32_LLR15  0xf307017f
 
 /* P2_NOSTHRES1 */
@@ -1452,20 +1452,20 @@
 
 /* P2_RAINFADE */
 #define RSTV0910_P2_RAINFADE  0xf30c
-#define FSTV0910_P2_NOSTHRES_DATAT  0xf30c0080
-#define FSTV0910_P2_RAINFADE_CNLIMIT  0xf30c0070
+#define FSTV0910_P2_NOSTHRES_DATAT  0xf30c7080
+#define FSTV0910_P2_RAINFADE_CNLIMIT  0xf30c4070
 #define FSTV0910_P2_RAINFADE_TIMEOUT  0xf30c0007
 
 /* P2_NOSRAMCFG */
 #define RSTV0910_P2_NOSRAMCFG  0xf30d
-#define FSTV0910_P2_NOSRAM_ACTIVATION  0xf30d0030
-#define FSTV0910_P2_NOSRAM_CNRONLY  0xf30d0008
+#define FSTV0910_P2_NOSRAM_ACTIVATION  0xf30d4030
+#define FSTV0910_P2_NOSRAM_CNRONLY  0xf30d3008
 #define FSTV0910_P2_NOSRAM_LGNCNR1  0xf30d0007
 
 /* P2_NOSRAMPOS */
 #define RSTV0910_P2_NOSRAMPOS  0xf30e
-#define FSTV0910_P2_NOSRAM_LGNCNR0  0xf30e00f0
-#define FSTV0910_P2_NOSRAM_VALIDE  0xf30e0004
+#define FSTV0910_P2_NOSRAM_LGNCNR0  0xf30e40f0
+#define FSTV0910_P2_NOSRAM_VALIDE  0xf30e2004
 #define FSTV0910_P2_NOSRAM_CNRVAL1  0xf30e0003
 
 /* P2_NOSRAMVAL */
@@ -1494,16 +1494,16 @@
 
 /* P2_VITSCALE */
 #define RSTV0910_P2_VITSCALE  0xf332
-#define FSTV0910_P2_NVTH_NOSRANGE  0xf3320080
-#define FSTV0910_P2_VERROR_MAXMODE  0xf3320040
-#define FSTV0910_P2_NSLOWSN_LOCKED  0xf3320008
-#define FSTV0910_P2_DIS_RSFLOCK  0xf3320002
+#define FSTV0910_P2_NVTH_NOSRANGE  0xf3327080
+#define FSTV0910_P2_VERROR_MAXMODE  0xf3326040
+#define FSTV0910_P2_NSLOWSN_LOCKED  0xf3323008
+#define FSTV0910_P2_DIS_RSFLOCK  0xf3321002
 
 /* P2_FECM */
 #define RSTV0910_P2_FECM  0xf333
-#define FSTV0910_P2_DSS_DVB  0xf3330080
-#define FSTV0910_P2_DSS_SRCH  0xf3330010
-#define FSTV0910_P2_SYNCVIT  0xf3330002
+#define FSTV0910_P2_DSS_DVB  0xf3337080
+#define FSTV0910_P2_DSS_SRCH  0xf3334010
+#define FSTV0910_P2_SYNCVIT  0xf3331002
 #define FSTV0910_P2_IQINV  0xf3330001
 
 /* P2_VTH12 */
@@ -1540,26 +1540,26 @@
 
 /* P2_PRVIT */
 #define RSTV0910_P2_PRVIT  0xf33c
-#define FSTV0910_P2_DIS_VTHLOCK  0xf33c0040
-#define FSTV0910_P2_E7_8VIT  0xf33c0020
-#define FSTV0910_P2_E6_7VIT  0xf33c0010
-#define FSTV0910_P2_E5_6VIT  0xf33c0008
-#define FSTV0910_P2_E3_4VIT  0xf33c0004
-#define FSTV0910_P2_E2_3VIT  0xf33c0002
+#define FSTV0910_P2_DIS_VTHLOCK  0xf33c6040
+#define FSTV0910_P2_E7_8VIT  0xf33c5020
+#define FSTV0910_P2_E6_7VIT  0xf33c4010
+#define FSTV0910_P2_E5_6VIT  0xf33c3008
+#define FSTV0910_P2_E3_4VIT  0xf33c2004
+#define FSTV0910_P2_E2_3VIT  0xf33c1002
 #define FSTV0910_P2_E1_2VIT  0xf33c0001
 
 /* P2_VAVSRVIT */
 #define RSTV0910_P2_VAVSRVIT  0xf33d
-#define FSTV0910_P2_AMVIT  0xf33d0080
-#define FSTV0910_P2_FROZENVIT  0xf33d0040
-#define FSTV0910_P2_SNVIT  0xf33d0030
-#define FSTV0910_P2_TOVVIT  0xf33d000c
+#define FSTV0910_P2_AMVIT  0xf33d7080
+#define FSTV0910_P2_FROZENVIT  0xf33d6040
+#define FSTV0910_P2_SNVIT  0xf33d4030
+#define FSTV0910_P2_TOVVIT  0xf33d200c
 #define FSTV0910_P2_HYPVIT  0xf33d0003
 
 /* P2_VSTATUSVIT */
 #define RSTV0910_P2_VSTATUSVIT  0xf33e
-#define FSTV0910_P2_PRFVIT  0xf33e0010
-#define FSTV0910_P2_LOCKEDVIT  0xf33e0008
+#define FSTV0910_P2_PRFVIT  0xf33e4010
+#define FSTV0910_P2_LOCKEDVIT  0xf33e3008
 
 /* P2_VTHINUSE */
 #define RSTV0910_P2_VTHINUSE  0xf33f
@@ -1599,32 +1599,32 @@
 
 /* P2_PDELCTRL0 */
 #define RSTV0910_P2_PDELCTRL0  0xf34f
-#define FSTV0910_P2_ISIOBS_MODE  0xf34f0030
+#define FSTV0910_P2_ISIOBS_MODE  0xf34f4030
 
 /* P2_PDELCTRL1 */
 #define RSTV0910_P2_PDELCTRL1  0xf350
-#define FSTV0910_P2_INV_MISMASK  0xf3500080
-#define FSTV0910_P2_FILTER_EN  0xf3500020
-#define FSTV0910_P2_HYSTEN  0xf3500008
-#define FSTV0910_P2_HYSTSWRST  0xf3500004
-#define FSTV0910_P2_EN_MIS00  0xf3500002
+#define FSTV0910_P2_INV_MISMASK  0xf3507080
+#define FSTV0910_P2_FILTER_EN  0xf3505020
+#define FSTV0910_P2_HYSTEN  0xf3503008
+#define FSTV0910_P2_HYSTSWRST  0xf3502004
+#define FSTV0910_P2_EN_MIS00  0xf3501002
 #define FSTV0910_P2_ALGOSWRST  0xf3500001
 
 /* P2_PDELCTRL2 */
 #define RSTV0910_P2_PDELCTRL2  0xf351
-#define FSTV0910_P2_FORCE_CONTINUOUS  0xf3510080
-#define FSTV0910_P2_RESET_UPKO_COUNT  0xf3510040
-#define FSTV0910_P2_USER_PKTDELIN_NB  0xf3510020
-#define FSTV0910_P2_FRAME_MODE  0xf3510002
+#define FSTV0910_P2_FORCE_CONTINUOUS  0xf3517080
+#define FSTV0910_P2_RESET_UPKO_COUNT  0xf3516040
+#define FSTV0910_P2_USER_PKTDELIN_NB  0xf3515020
+#define FSTV0910_P2_FRAME_MODE  0xf3511002
 
 /* P2_HYSTTHRESH */
 #define RSTV0910_P2_HYSTTHRESH  0xf354
-#define FSTV0910_P2_DELIN_LOCKTHRES  0xf35400f0
+#define FSTV0910_P2_DELIN_LOCKTHRES  0xf35440f0
 #define FSTV0910_P2_DELIN_UNLOCKTHRES  0xf354000f
 
 /* P2_UPLCCST0 */
 #define RSTV0910_P2_UPLCCST0  0xf358
-#define FSTV0910_P2_UPL_CST0  0xf35800f8
+#define FSTV0910_P2_UPL_CST0  0xf35830f8
 #define FSTV0910_P2_UPL_MODE  0xf3580007
 
 /* P2_ISIENTRY */
@@ -1673,16 +1673,16 @@
 
 /* P2_PDELSTATUS1 */
 #define RSTV0910_P2_PDELSTATUS1  0xf369
-#define FSTV0910_P2_PKTDELIN_DELOCK  0xf3690080
-#define FSTV0910_P2_SYNCDUPDFL_BADDFL  0xf3690040
-#define FSTV0910_P2_UNACCEPTED_STREAM  0xf3690010
-#define FSTV0910_P2_BCH_ERROR_FLAG  0xf3690008
-#define FSTV0910_P2_PKTDELIN_LOCK  0xf3690002
+#define FSTV0910_P2_PKTDELIN_DELOCK  0xf3697080
+#define FSTV0910_P2_SYNCDUPDFL_BADDFL  0xf3696040
+#define FSTV0910_P2_UNACCEPTED_STREAM  0xf3694010
+#define FSTV0910_P2_BCH_ERROR_FLAG  0xf3693008
+#define FSTV0910_P2_PKTDELIN_LOCK  0xf3691002
 #define FSTV0910_P2_FIRST_LOCK  0xf3690001
 
 /* P2_PDELSTATUS2 */
 #define RSTV0910_P2_PDELSTATUS2  0xf36a
-#define FSTV0910_P2_FRAME_MODCOD  0xf36a007c
+#define FSTV0910_P2_FRAME_MODCOD  0xf36a207c
 #define FSTV0910_P2_FRAME_TYPE  0xf36a0003
 
 /* P2_BBFCRCKO1 */
@@ -1703,92 +1703,92 @@
 
 /* P2_PDELCTRL3 */
 #define RSTV0910_P2_PDELCTRL3  0xf36f
-#define FSTV0910_P2_NOFIFO_BCHERR  0xf36f0020
-#define FSTV0910_P2_PKTDELIN_DELACMERR  0xf36f0010
+#define FSTV0910_P2_NOFIFO_BCHERR  0xf36f5020
+#define FSTV0910_P2_PKTDELIN_DELACMERR  0xf36f4010
 
 /* P2_TSSTATEM */
 #define RSTV0910_P2_TSSTATEM  0xf370
-#define FSTV0910_P2_TSDIL_ON  0xf3700080
-#define FSTV0910_P2_TSRS_ON  0xf3700020
-#define FSTV0910_P2_TSDESCRAMB_ON  0xf3700010
-#define FSTV0910_P2_TSFRAME_MODE  0xf3700008
-#define FSTV0910_P2_TS_DISABLE  0xf3700004
-#define FSTV0910_P2_TSACM_MODE  0xf3700002
+#define FSTV0910_P2_TSDIL_ON  0xf3707080
+#define FSTV0910_P2_TSRS_ON  0xf3705020
+#define FSTV0910_P2_TSDESCRAMB_ON  0xf3704010
+#define FSTV0910_P2_TSFRAME_MODE  0xf3703008
+#define FSTV0910_P2_TS_DISABLE  0xf3702004
+#define FSTV0910_P2_TSACM_MODE  0xf3701002
 #define FSTV0910_P2_TSOUT_NOSYNC  0xf3700001
 
 /* P2_TSSTATEL */
 #define RSTV0910_P2_TSSTATEL  0xf371
-#define FSTV0910_P2_TSNOSYNCBYTE  0xf3710080
-#define FSTV0910_P2_TSPARITY_ON  0xf3710040
-#define FSTV0910_P2_TSISSYI_ON  0xf3710008
-#define FSTV0910_P2_TSNPD_ON  0xf3710004
-#define FSTV0910_P2_TSCRC8_ON  0xf3710002
+#define FSTV0910_P2_TSNOSYNCBYTE  0xf3717080
+#define FSTV0910_P2_TSPARITY_ON  0xf3716040
+#define FSTV0910_P2_TSISSYI_ON  0xf3713008
+#define FSTV0910_P2_TSNPD_ON  0xf3712004
+#define FSTV0910_P2_TSCRC8_ON  0xf3711002
 #define FSTV0910_P2_TSDSS_PACKET  0xf3710001
 
 /* P2_TSCFGH */
 #define RSTV0910_P2_TSCFGH  0xf372
-#define FSTV0910_P2_TSFIFO_DVBCI  0xf3720080
-#define FSTV0910_P2_TSFIFO_SERIAL  0xf3720040
-#define FSTV0910_P2_TSFIFO_TEIUPDATE  0xf3720020
-#define FSTV0910_P2_TSFIFO_DUTY50  0xf3720010
-#define FSTV0910_P2_TSFIFO_HSGNLOUT  0xf3720008
-#define FSTV0910_P2_TSFIFO_ERRMODE  0xf3720006
+#define FSTV0910_P2_TSFIFO_DVBCI  0xf3727080
+#define FSTV0910_P2_TSFIFO_SERIAL  0xf3726040
+#define FSTV0910_P2_TSFIFO_TEIUPDATE  0xf3725020
+#define FSTV0910_P2_TSFIFO_DUTY50  0xf3724010
+#define FSTV0910_P2_TSFIFO_HSGNLOUT  0xf3723008
+#define FSTV0910_P2_TSFIFO_ERRMODE  0xf3721006
 #define FSTV0910_P2_RST_HWARE  0xf3720001
 
 /* P2_TSCFGM */
 #define RSTV0910_P2_TSCFGM  0xf373
-#define FSTV0910_P2_TSFIFO_MANSPEED  0xf37300c0
-#define FSTV0910_P2_TSFIFO_PERMDATA  0xf3730020
-#define FSTV0910_P2_TSFIFO_NONEWSGNL  0xf3730010
+#define FSTV0910_P2_TSFIFO_MANSPEED  0xf37360c0
+#define FSTV0910_P2_TSFIFO_PERMDATA  0xf3735020
+#define FSTV0910_P2_TSFIFO_NONEWSGNL  0xf3734010
 #define FSTV0910_P2_TSFIFO_INVDATA  0xf3730001
 
 /* P2_TSCFGL */
 #define RSTV0910_P2_TSCFGL  0xf374
-#define FSTV0910_P2_TSFIFO_BCLKDEL1CK  0xf37400c0
-#define FSTV0910_P2_BCHERROR_MODE  0xf3740030
-#define FSTV0910_P2_TSFIFO_NSGNL2DATA  0xf3740008
-#define FSTV0910_P2_TSFIFO_EMBINDVB  0xf3740004
+#define FSTV0910_P2_TSFIFO_BCLKDEL1CK  0xf37460c0
+#define FSTV0910_P2_BCHERROR_MODE  0xf3744030
+#define FSTV0910_P2_TSFIFO_NSGNL2DATA  0xf3743008
+#define FSTV0910_P2_TSFIFO_EMBINDVB  0xf3742004
 #define FSTV0910_P2_TSFIFO_BITSPEED  0xf3740003
 
 /* P2_TSSYNC */
 #define RSTV0910_P2_TSSYNC  0xf375
-#define FSTV0910_P2_TSFIFO_SYNCMODE  0xf3750018
+#define FSTV0910_P2_TSFIFO_SYNCMODE  0xf3753018
 
 /* P2_TSINSDELH */
 #define RSTV0910_P2_TSINSDELH  0xf376
-#define FSTV0910_P2_TSDEL_SYNCBYTE  0xf3760080
-#define FSTV0910_P2_TSDEL_XXHEADER  0xf3760040
-#define FSTV0910_P2_TSDEL_DATAFIELD  0xf3760010
-#define FSTV0910_P2_TSINSDEL_RSPARITY  0xf3760002
+#define FSTV0910_P2_TSDEL_SYNCBYTE  0xf3767080
+#define FSTV0910_P2_TSDEL_XXHEADER  0xf3766040
+#define FSTV0910_P2_TSDEL_DATAFIELD  0xf3764010
+#define FSTV0910_P2_TSINSDEL_RSPARITY  0xf3761002
 #define FSTV0910_P2_TSINSDEL_CRC8  0xf3760001
 
 /* P2_TSINSDELM */
 #define RSTV0910_P2_TSINSDELM  0xf377
-#define FSTV0910_P2_TSINS_EMODCOD  0xf3770010
-#define FSTV0910_P2_TSINS_TOKEN  0xf3770008
-#define FSTV0910_P2_TSINS_XXXERR  0xf3770004
-#define FSTV0910_P2_TSINS_MATYPE  0xf3770002
+#define FSTV0910_P2_TSINS_EMODCOD  0xf3774010
+#define FSTV0910_P2_TSINS_TOKEN  0xf3773008
+#define FSTV0910_P2_TSINS_XXXERR  0xf3772004
+#define FSTV0910_P2_TSINS_MATYPE  0xf3771002
 #define FSTV0910_P2_TSINS_UPL  0xf3770001
 
 /* P2_TSINSDELL */
 #define RSTV0910_P2_TSINSDELL  0xf378
-#define FSTV0910_P2_TSINS_DFL  0xf3780080
-#define FSTV0910_P2_TSINS_SYNCD  0xf3780040
-#define FSTV0910_P2_TSINS_BLOCLEN  0xf3780020
-#define FSTV0910_P2_TSINS_SIGPCOUNT  0xf3780010
-#define FSTV0910_P2_TSINS_FIFO  0xf3780008
-#define FSTV0910_P2_TSINS_REALPACK  0xf3780004
-#define FSTV0910_P2_TSINS_TSCONFIG  0xf3780002
+#define FSTV0910_P2_TSINS_DFL  0xf3787080
+#define FSTV0910_P2_TSINS_SYNCD  0xf3786040
+#define FSTV0910_P2_TSINS_BLOCLEN  0xf3785020
+#define FSTV0910_P2_TSINS_SIGPCOUNT  0xf3784010
+#define FSTV0910_P2_TSINS_FIFO  0xf3783008
+#define FSTV0910_P2_TSINS_REALPACK  0xf3782004
+#define FSTV0910_P2_TSINS_TSCONFIG  0xf3781002
 #define FSTV0910_P2_TSINS_LATENCY  0xf3780001
 
 /* P2_TSDIVN */
 #define RSTV0910_P2_TSDIVN  0xf379
-#define FSTV0910_P2_TSFIFO_SPEEDMODE  0xf37900c0
+#define FSTV0910_P2_TSFIFO_SPEEDMODE  0xf37960c0
 #define FSTV0910_P2_TSFIFO_RISEOK  0xf3790007
 
 /* P2_TSCFG4 */
 #define RSTV0910_P2_TSCFG4  0xf37a
-#define FSTV0910_P2_TSFIFO_TSSPEEDMODE  0xf37a00c0
+#define FSTV0910_P2_TSFIFO_TSSPEEDMODE  0xf37a60c0
 
 /* P2_TSSPEED */
 #define RSTV0910_P2_TSSPEED  0xf380
@@ -1796,18 +1796,18 @@
 
 /* P2_TSSTATUS */
 #define RSTV0910_P2_TSSTATUS  0xf381
-#define FSTV0910_P2_TSFIFO_LINEOK  0xf3810080
-#define FSTV0910_P2_TSFIFO_ERROR  0xf3810040
-#define FSTV0910_P2_TSFIFO_NOSYNC  0xf3810010
-#define FSTV0910_P2_TSREGUL_ERROR  0xf3810004
+#define FSTV0910_P2_TSFIFO_LINEOK  0xf3817080
+#define FSTV0910_P2_TSFIFO_ERROR  0xf3816040
+#define FSTV0910_P2_TSFIFO_NOSYNC  0xf3814010
+#define FSTV0910_P2_TSREGUL_ERROR  0xf3812004
 #define FSTV0910_P2_DIL_READY  0xf3810001
 
 /* P2_TSSTATUS2 */
 #define RSTV0910_P2_TSSTATUS2  0xf382
-#define FSTV0910_P2_TSFIFO_DEMODSEL  0xf3820080
-#define FSTV0910_P2_TSFIFOSPEED_STORE  0xf3820040
-#define FSTV0910_P2_DILXX_RESET  0xf3820020
-#define FSTV0910_P2_SCRAMBDETECT  0xf3820002
+#define FSTV0910_P2_TSFIFO_DEMODSEL  0xf3827080
+#define FSTV0910_P2_TSFIFOSPEED_STORE  0xf3826040
+#define FSTV0910_P2_DILXX_RESET  0xf3825020
+#define FSTV0910_P2_SCRAMBDETECT  0xf3821002
 
 /* P2_TSBITRATE1 */
 #define RSTV0910_P2_TSBITRATE1  0xf383
@@ -1819,7 +1819,7 @@
 
 /* P2_TSPACKLEN1 */
 #define RSTV0910_P2_TSPACKLEN1  0xf385
-#define FSTV0910_P2_TSFIFO_PACKCPT  0xf38500e0
+#define FSTV0910_P2_TSFIFO_PACKCPT  0xf38550e0
 
 /* P2_TSDLY2 */
 #define RSTV0910_P2_TSDLY2  0xf389
@@ -1839,8 +1839,8 @@
 
 /* P2_TSBUFSTAT2 */
 #define RSTV0910_P2_TSBUFSTAT2  0xf38d
-#define FSTV0910_P2_TSISCR_3BYTES  0xf38d0080
-#define FSTV0910_P2_TSISCR_NEWDATA  0xf38d0040
+#define FSTV0910_P2_TSISCR_3BYTES  0xf38d7080
+#define FSTV0910_P2_TSISCR_NEWDATA  0xf38d6040
 #define FSTV0910_P2_TSISCR_BUFSTAT2  0xf38d003f
 
 /* P2_TSBUFSTAT1 */
@@ -1853,13 +1853,13 @@
 
 /* P2_TSDEBUGL */
 #define RSTV0910_P2_TSDEBUGL  0xf391
-#define FSTV0910_P2_TSFIFO_ERROR_EVNT  0xf3910004
+#define FSTV0910_P2_TSFIFO_ERROR_EVNT  0xf3912004
 #define FSTV0910_P2_TSFIFO_OVERFLOWM  0xf3910001
 
 /* P2_TSDLYSET2 */
 #define RSTV0910_P2_TSDLYSET2  0xf392
-#define FSTV0910_P2_SOFFIFO_OFFSET  0xf39200c0
-#define FSTV0910_P2_HYSTERESIS_THRESHOLD  0xf3920030
+#define FSTV0910_P2_SOFFIFO_OFFSET  0xf39260c0
+#define FSTV0910_P2_HYSTERESIS_THRESHOLD  0xf3924030
 #define FSTV0910_P2_SOFFIFO_SYMBOFFS2  0xf392000f
 
 /* P2_TSDLYSET1 */
@@ -1872,12 +1872,12 @@
 
 /* P2_ERRCTRL1 */
 #define RSTV0910_P2_ERRCTRL1  0xf398
-#define FSTV0910_P2_ERR_SOURCE1  0xf39800f0
+#define FSTV0910_P2_ERR_SOURCE1  0xf39840f0
 #define FSTV0910_P2_NUM_EVENT1  0xf3980007
 
 /* P2_ERRCNT12 */
 #define RSTV0910_P2_ERRCNT12  0xf399
-#define FSTV0910_P2_ERRCNT1_OLDVALUE  0xf3990080
+#define FSTV0910_P2_ERRCNT1_OLDVALUE  0xf3997080
 #define FSTV0910_P2_ERR_CNT12  0xf399007f
 
 /* P2_ERRCNT11 */
@@ -1890,12 +1890,12 @@
 
 /* P2_ERRCTRL2 */
 #define RSTV0910_P2_ERRCTRL2  0xf39c
-#define FSTV0910_P2_ERR_SOURCE2  0xf39c00f0
+#define FSTV0910_P2_ERR_SOURCE2  0xf39c40f0
 #define FSTV0910_P2_NUM_EVENT2  0xf39c0007
 
 /* P2_ERRCNT22 */
 #define RSTV0910_P2_ERRCNT22  0xf39d
-#define FSTV0910_P2_ERRCNT2_OLDVALUE  0xf39d0080
+#define FSTV0910_P2_ERRCNT2_OLDVALUE  0xf39d7080
 #define FSTV0910_P2_ERR_CNT22  0xf39d007f
 
 /* P2_ERRCNT21 */
@@ -1908,39 +1908,39 @@
 
 /* P2_FECSPY */
 #define RSTV0910_P2_FECSPY  0xf3a0
-#define FSTV0910_P2_SPY_ENABLE  0xf3a00080
-#define FSTV0910_P2_NO_SYNCBYTE  0xf3a00040
-#define FSTV0910_P2_SERIAL_MODE  0xf3a00020
-#define FSTV0910_P2_UNUSUAL_PACKET  0xf3a00010
-#define FSTV0910_P2_BERMETER_DATAMODE  0xf3a0000c
-#define FSTV0910_P2_BERMETER_LMODE  0xf3a00002
+#define FSTV0910_P2_SPY_ENABLE  0xf3a07080
+#define FSTV0910_P2_NO_SYNCBYTE  0xf3a06040
+#define FSTV0910_P2_SERIAL_MODE  0xf3a05020
+#define FSTV0910_P2_UNUSUAL_PACKET  0xf3a04010
+#define FSTV0910_P2_BERMETER_DATAMODE  0xf3a0200c
+#define FSTV0910_P2_BERMETER_LMODE  0xf3a01002
 #define FSTV0910_P2_BERMETER_RESET  0xf3a00001
 
 /* P2_FSPYCFG */
 #define RSTV0910_P2_FSPYCFG  0xf3a1
-#define FSTV0910_P2_FECSPY_INPUT  0xf3a100c0
-#define FSTV0910_P2_RST_ON_ERROR  0xf3a10020
-#define FSTV0910_P2_ONE_SHOT  0xf3a10010
-#define FSTV0910_P2_I2C_MODE  0xf3a1000c
+#define FSTV0910_P2_FECSPY_INPUT  0xf3a160c0
+#define FSTV0910_P2_RST_ON_ERROR  0xf3a15020
+#define FSTV0910_P2_ONE_SHOT  0xf3a14010
+#define FSTV0910_P2_I2C_MODE  0xf3a1200c
 #define FSTV0910_P2_SPY_HYSTERESIS  0xf3a10003
 
 /* P2_FSPYDATA */
 #define RSTV0910_P2_FSPYDATA  0xf3a2
-#define FSTV0910_P2_SPY_STUFFING  0xf3a20080
-#define FSTV0910_P2_SPY_CNULLPKT  0xf3a20020
+#define FSTV0910_P2_SPY_STUFFING  0xf3a27080
+#define FSTV0910_P2_SPY_CNULLPKT  0xf3a25020
 #define FSTV0910_P2_SPY_OUTDATA_MODE  0xf3a2001f
 
 /* P2_FSPYOUT */
 #define RSTV0910_P2_FSPYOUT  0xf3a3
-#define FSTV0910_P2_FSPY_DIRECT  0xf3a30080
+#define FSTV0910_P2_FSPY_DIRECT  0xf3a37080
 #define FSTV0910_P2_STUFF_MODE  0xf3a30007
 
 /* P2_FSTATUS */
 #define RSTV0910_P2_FSTATUS  0xf3a4
-#define FSTV0910_P2_SPY_ENDSIM  0xf3a40080
-#define FSTV0910_P2_VALID_SIM  0xf3a40040
-#define FSTV0910_P2_FOUND_SIGNAL  0xf3a40020
-#define FSTV0910_P2_DSS_SYNCBYTE  0xf3a40010
+#define FSTV0910_P2_SPY_ENDSIM  0xf3a47080
+#define FSTV0910_P2_VALID_SIM  0xf3a46040
+#define FSTV0910_P2_FOUND_SIGNAL  0xf3a45020
+#define FSTV0910_P2_DSS_SYNCBYTE  0xf3a44010
 #define FSTV0910_P2_RESULT_STATE  0xf3a4000f
 
 /* P2_FBERCPT4 */
@@ -1977,8 +1977,8 @@
 
 /* P2_FSPYBER */
 #define RSTV0910_P2_FSPYBER  0xf3b2
-#define FSTV0910_P2_FSPYBER_SYNCBYTE  0xf3b20010
-#define FSTV0910_P2_FSPYBER_UNSYNC  0xf3b20008
+#define FSTV0910_P2_FSPYBER_SYNCBYTE  0xf3b24010
+#define FSTV0910_P2_FSPYBER_UNSYNC  0xf3b23008
 #define FSTV0910_P2_FSPYBER_CTIME  0xf3b20007
 
 /* P2_SFERROR */
@@ -1987,60 +1987,60 @@
 
 /* P2_SFECSTATUS */
 #define RSTV0910_P2_SFECSTATUS  0xf3c3
-#define FSTV0910_P2_SFEC_ON  0xf3c30080
-#define FSTV0910_P2_SFEC_OFF  0xf3c30040
-#define FSTV0910_P2_LOCKEDSFEC  0xf3c30008
-#define FSTV0910_P2_SFEC_DELOCK  0xf3c30004
-#define FSTV0910_P2_SFEC_DEMODSEL  0xf3c30002
+#define FSTV0910_P2_SFEC_ON  0xf3c37080
+#define FSTV0910_P2_SFEC_OFF  0xf3c36040
+#define FSTV0910_P2_LOCKEDSFEC  0xf3c33008
+#define FSTV0910_P2_SFEC_DELOCK  0xf3c32004
+#define FSTV0910_P2_SFEC_DEMODSEL  0xf3c31002
 #define FSTV0910_P2_SFEC_OVFON  0xf3c30001
 
 /* P2_SFKDIV12 */
 #define RSTV0910_P2_SFKDIV12  0xf3c4
-#define FSTV0910_P2_SFECKDIV12_MAN  0xf3c40080
+#define FSTV0910_P2_SFECKDIV12_MAN  0xf3c47080
 
 /* P2_SFKDIV23 */
 #define RSTV0910_P2_SFKDIV23  0xf3c5
-#define FSTV0910_P2_SFECKDIV23_MAN  0xf3c50080
+#define FSTV0910_P2_SFECKDIV23_MAN  0xf3c57080
 
 /* P2_SFKDIV34 */
 #define RSTV0910_P2_SFKDIV34  0xf3c6
-#define FSTV0910_P2_SFECKDIV34_MAN  0xf3c60080
+#define FSTV0910_P2_SFECKDIV34_MAN  0xf3c67080
 
 /* P2_SFKDIV56 */
 #define RSTV0910_P2_SFKDIV56  0xf3c7
-#define FSTV0910_P2_SFECKDIV56_MAN  0xf3c70080
+#define FSTV0910_P2_SFECKDIV56_MAN  0xf3c77080
 
 /* P2_SFKDIV67 */
 #define RSTV0910_P2_SFKDIV67  0xf3c8
-#define FSTV0910_P2_SFECKDIV67_MAN  0xf3c80080
+#define FSTV0910_P2_SFECKDIV67_MAN  0xf3c87080
 
 /* P2_SFKDIV78 */
 #define RSTV0910_P2_SFKDIV78  0xf3c9
-#define FSTV0910_P2_SFECKDIV78_MAN  0xf3c90080
+#define FSTV0910_P2_SFECKDIV78_MAN  0xf3c97080
 
 /* P2_SFSTATUS */
 #define RSTV0910_P2_SFSTATUS  0xf3cc
-#define FSTV0910_P2_SFEC_LINEOK  0xf3cc0080
-#define FSTV0910_P2_SFEC_ERROR  0xf3cc0040
-#define FSTV0910_P2_SFEC_DATA7  0xf3cc0020
-#define FSTV0910_P2_SFEC_PKTDNBRFAIL  0xf3cc0010
-#define FSTV0910_P2_TSSFEC_DEMODSEL  0xf3cc0008
-#define FSTV0910_P2_SFEC_NOSYNC  0xf3cc0004
-#define FSTV0910_P2_SFEC_UNREGULA  0xf3cc0002
+#define FSTV0910_P2_SFEC_LINEOK  0xf3cc7080
+#define FSTV0910_P2_SFEC_ERROR  0xf3cc6040
+#define FSTV0910_P2_SFEC_DATA7  0xf3cc5020
+#define FSTV0910_P2_SFEC_PKTDNBRFAIL  0xf3cc4010
+#define FSTV0910_P2_TSSFEC_DEMODSEL  0xf3cc3008
+#define FSTV0910_P2_SFEC_NOSYNC  0xf3cc2004
+#define FSTV0910_P2_SFEC_UNREGULA  0xf3cc1002
 #define FSTV0910_P2_SFEC_READY  0xf3cc0001
 
 /* P2_SFDLYSET2 */
 #define RSTV0910_P2_SFDLYSET2  0xf3d0
-#define FSTV0910_P2_SFEC_DISABLE  0xf3d00002
+#define FSTV0910_P2_SFEC_DISABLE  0xf3d01002
 
 /* P2_SFERRCTRL */
 #define RSTV0910_P2_SFERRCTRL  0xf3d8
-#define FSTV0910_P2_SFEC_ERR_SOURCE  0xf3d800f0
+#define FSTV0910_P2_SFEC_ERR_SOURCE  0xf3d840f0
 #define FSTV0910_P2_SFEC_NUM_EVENT  0xf3d80007
 
 /* P2_SFERRCNT2 */
 #define RSTV0910_P2_SFERRCNT2  0xf3d9
-#define FSTV0910_P2_SFERRC_OLDVALUE  0xf3d90080
+#define FSTV0910_P2_SFERRC_OLDVALUE  0xf3d97080
 #define FSTV0910_P2_SFEC_ERR_CNT2  0xf3d9007f
 
 /* P2_SFERRCNT1 */
@@ -2053,13 +2053,13 @@
 
 /* P1_IQCONST */
 #define RSTV0910_P1_IQCONST  0xf400
-#define FSTV0910_P1_CONSTEL_SELECT  0xf4000060
+#define FSTV0910_P1_CONSTEL_SELECT  0xf4005060
 #define FSTV0910_P1_IQSYMB_SEL  0xf400001f
 
 /* P1_NOSCFG */
 #define RSTV0910_P1_NOSCFG  0xf401
-#define FSTV0910_P1_DUMMYPL_NOSDATA  0xf4010020
-#define FSTV0910_P1_NOSPLH_BETA  0xf4010018
+#define FSTV0910_P1_DUMMYPL_NOSDATA  0xf4015020
+#define FSTV0910_P1_NOSPLH_BETA  0xf4013018
 #define FSTV0910_P1_NOSDATA_BETA  0xf4010007
 
 /* P1_ISYMB */
@@ -2072,18 +2072,18 @@
 
 /* P1_AGC1CFG */
 #define RSTV0910_P1_AGC1CFG  0xf404
-#define FSTV0910_P1_DC_FROZEN  0xf4040080
-#define FSTV0910_P1_DC_CORRECT  0xf4040040
-#define FSTV0910_P1_AMM_FROZEN  0xf4040020
-#define FSTV0910_P1_AMM_CORRECT  0xf4040010
-#define FSTV0910_P1_QUAD_FROZEN  0xf4040008
-#define FSTV0910_P1_QUAD_CORRECT  0xf4040004
+#define FSTV0910_P1_DC_FROZEN  0xf4047080
+#define FSTV0910_P1_DC_CORRECT  0xf4046040
+#define FSTV0910_P1_AMM_FROZEN  0xf4045020
+#define FSTV0910_P1_AMM_CORRECT  0xf4044010
+#define FSTV0910_P1_QUAD_FROZEN  0xf4043008
+#define FSTV0910_P1_QUAD_CORRECT  0xf4042004
 
 /* P1_AGC1CN */
 #define RSTV0910_P1_AGC1CN  0xf406
-#define FSTV0910_P1_AGC1_LOCKED  0xf4060080
-#define FSTV0910_P1_AGC1_MINPOWER  0xf4060010
-#define FSTV0910_P1_AGCOUT_FAST  0xf4060008
+#define FSTV0910_P1_AGC1_LOCKED  0xf4067080
+#define FSTV0910_P1_AGC1_MINPOWER  0xf4064010
+#define FSTV0910_P1_AGCOUT_FAST  0xf4063008
 #define FSTV0910_P1_AGCIQ_BETA  0xf4060007
 
 /* P1_AGC1REF */
@@ -2124,50 +2124,50 @@
 
 /* P1_DEMOD */
 #define RSTV0910_P1_DEMOD  0xf410
-#define FSTV0910_P1_MANUALS2_ROLLOFF  0xf4100080
-#define FSTV0910_P1_SPECINV_CONTROL  0xf4100030
-#define FSTV0910_P1_MANUALSX_ROLLOFF  0xf4100004
+#define FSTV0910_P1_MANUALS2_ROLLOFF  0xf4107080
+#define FSTV0910_P1_SPECINV_CONTROL  0xf4104030
+#define FSTV0910_P1_MANUALSX_ROLLOFF  0xf4102004
 #define FSTV0910_P1_ROLLOFF_CONTROL  0xf4100003
 
 /* P1_DMDMODCOD */
 #define RSTV0910_P1_DMDMODCOD  0xf411
-#define FSTV0910_P1_MANUAL_MODCOD  0xf4110080
-#define FSTV0910_P1_DEMOD_MODCOD  0xf411007c
+#define FSTV0910_P1_MANUAL_MODCOD  0xf4117080
+#define FSTV0910_P1_DEMOD_MODCOD  0xf411207c
 #define FSTV0910_P1_DEMOD_TYPE  0xf4110003
 
 /* P1_DSTATUS */
 #define RSTV0910_P1_DSTATUS  0xf412
-#define FSTV0910_P1_CAR_LOCK  0xf4120080
-#define FSTV0910_P1_TMGLOCK_QUALITY  0xf4120060
-#define FSTV0910_P1_LOCK_DEFINITIF  0xf4120008
+#define FSTV0910_P1_CAR_LOCK  0xf4127080
+#define FSTV0910_P1_TMGLOCK_QUALITY  0xf4125060
+#define FSTV0910_P1_LOCK_DEFINITIF  0xf4123008
 #define FSTV0910_P1_OVADC_DETECT  0xf4120001
 
 /* P1_DSTATUS2 */
 #define RSTV0910_P1_DSTATUS2  0xf413
-#define FSTV0910_P1_DEMOD_DELOCK  0xf4130080
-#define FSTV0910_P1_MODCODRQ_SYNCTAG  0xf4130020
-#define FSTV0910_P1_POLYPH_SATEVENT  0xf4130010
-#define FSTV0910_P1_AGC1_NOSIGNALACK  0xf4130008
-#define FSTV0910_P1_AGC2_OVERFLOW  0xf4130004
-#define FSTV0910_P1_CFR_OVERFLOW  0xf4130002
+#define FSTV0910_P1_DEMOD_DELOCK  0xf4137080
+#define FSTV0910_P1_MODCODRQ_SYNCTAG  0xf4135020
+#define FSTV0910_P1_POLYPH_SATEVENT  0xf4134010
+#define FSTV0910_P1_AGC1_NOSIGNALACK  0xf4133008
+#define FSTV0910_P1_AGC2_OVERFLOW  0xf4132004
+#define FSTV0910_P1_CFR_OVERFLOW  0xf4131002
 #define FSTV0910_P1_GAMMA_OVERUNDER  0xf4130001
 
 /* P1_DMDCFGMD */
 #define RSTV0910_P1_DMDCFGMD  0xf414
-#define FSTV0910_P1_DVBS2_ENABLE  0xf4140080
-#define FSTV0910_P1_DVBS1_ENABLE  0xf4140040
-#define FSTV0910_P1_SCAN_ENABLE  0xf4140010
-#define FSTV0910_P1_CFR_AUTOSCAN  0xf4140008
+#define FSTV0910_P1_DVBS2_ENABLE  0xf4147080
+#define FSTV0910_P1_DVBS1_ENABLE  0xf4146040
+#define FSTV0910_P1_SCAN_ENABLE  0xf4144010
+#define FSTV0910_P1_CFR_AUTOSCAN  0xf4143008
 #define FSTV0910_P1_TUN_RNG  0xf4140003
 
 /* P1_DMDCFG2 */
 #define RSTV0910_P1_DMDCFG2  0xf415
-#define FSTV0910_P1_S1S2_SEQUENTIAL  0xf4150040
-#define FSTV0910_P1_INFINITE_RELOCK  0xf4150010
+#define FSTV0910_P1_S1S2_SEQUENTIAL  0xf4156040
+#define FSTV0910_P1_INFINITE_RELOCK  0xf4154010
 
 /* P1_DMDISTATE */
 #define RSTV0910_P1_DMDISTATE  0xf416
-#define FSTV0910_P1_I2C_NORESETDMODE  0xf4160080
+#define FSTV0910_P1_I2C_NORESETDMODE  0xf4167080
 #define FSTV0910_P1_I2C_DEMOD_MODE  0xf416001f
 
 /* P1_DMDT0M */
@@ -2176,27 +2176,27 @@
 
 /* P1_DMDSTATE */
 #define RSTV0910_P1_DMDSTATE  0xf41b
-#define FSTV0910_P1_HEADER_MODE  0xf41b0060
+#define FSTV0910_P1_HEADER_MODE  0xf41b5060
 
 /* P1_DMDFLYW */
 #define RSTV0910_P1_DMDFLYW  0xf41c
-#define FSTV0910_P1_I2C_IRQVAL  0xf41c00f0
+#define FSTV0910_P1_I2C_IRQVAL  0xf41c40f0
 #define FSTV0910_P1_FLYWHEEL_CPT  0xf41c000f
 
 /* P1_DSTATUS3 */
 #define RSTV0910_P1_DSTATUS3  0xf41d
-#define FSTV0910_P1_CFR_ZIGZAG  0xf41d0080
-#define FSTV0910_P1_DEMOD_CFGMODE  0xf41d0060
-#define FSTV0910_P1_GAMMA_LOWBAUDRATE  0xf41d0010
+#define FSTV0910_P1_CFR_ZIGZAG  0xf41d7080
+#define FSTV0910_P1_DEMOD_CFGMODE  0xf41d5060
+#define FSTV0910_P1_GAMMA_LOWBAUDRATE  0xf41d4010
 
 /* P1_DMDCFG3 */
 #define RSTV0910_P1_DMDCFG3  0xf41e
-#define FSTV0910_P1_NOSTOP_FIFOFULL  0xf41e0008
+#define FSTV0910_P1_NOSTOP_FIFOFULL  0xf41e3008
 
 /* P1_DMDCFG4 */
 #define RSTV0910_P1_DMDCFG4  0xf41f
-#define FSTV0910_P1_DIS_VITLOCK  0xf41f0080
-#define FSTV0910_P1_DIS_CLKENABLE  0xf41f0004
+#define FSTV0910_P1_DIS_VITLOCK  0xf41f7080
+#define FSTV0910_P1_DIS_CLKENABLE  0xf41f2004
 
 /* P1_CORRELMANT */
 #define RSTV0910_P1_CORRELMANT  0xf420
@@ -2208,13 +2208,13 @@
 
 /* P1_CORRELEXP */
 #define RSTV0910_P1_CORRELEXP  0xf422
-#define FSTV0910_P1_CORREL_ABSEXP  0xf42200f0
+#define FSTV0910_P1_CORREL_ABSEXP  0xf42240f0
 #define FSTV0910_P1_CORREL_EXP  0xf422000f
 
 /* P1_PLHMODCOD */
 #define RSTV0910_P1_PLHMODCOD  0xf424
-#define FSTV0910_P1_SPECINV_DEMOD  0xf4240080
-#define FSTV0910_P1_PLH_MODCOD  0xf424007c
+#define FSTV0910_P1_SPECINV_DEMOD  0xf4247080
+#define FSTV0910_P1_PLH_MODCOD  0xf424207c
 #define FSTV0910_P1_PLH_TYPE  0xf4240003
 
 /* P1_DMDREG */
@@ -2223,19 +2223,19 @@
 
 /* P1_AGCNADJ */
 #define RSTV0910_P1_AGCNADJ  0xf426
-#define FSTV0910_P1_RADJOFF_AGC2  0xf4260080
-#define FSTV0910_P1_RADJOFF_AGC1  0xf4260040
+#define FSTV0910_P1_RADJOFF_AGC2  0xf4267080
+#define FSTV0910_P1_RADJOFF_AGC1  0xf4266040
 #define FSTV0910_P1_AGC_NADJ  0xf426013f
 
 /* P1_AGCKS */
 #define RSTV0910_P1_AGCKS  0xf427
-#define FSTV0910_P1_RSADJ_MANUALCFG  0xf4270080
-#define FSTV0910_P1_RSADJ_CCMMODE  0xf4270040
+#define FSTV0910_P1_RSADJ_MANUALCFG  0xf4277080
+#define FSTV0910_P1_RSADJ_CCMMODE  0xf4276040
 #define FSTV0910_P1_RADJ_SPSK  0xf427013f
 
 /* P1_AGCKQ */
 #define RSTV0910_P1_AGCKQ  0xf428
-#define FSTV0910_P1_RADJON_DVBS1  0xf4280040
+#define FSTV0910_P1_RADJON_DVBS1  0xf4286040
 #define FSTV0910_P1_RADJ_QPSK  0xf428013f
 
 /* P1_AGCK8 */
@@ -2244,20 +2244,20 @@
 
 /* P1_AGCK16 */
 #define RSTV0910_P1_AGCK16  0xf42a
-#define FSTV0910_P1_R2ADJOFF_16APSK  0xf42a0040
-#define FSTV0910_P1_R1ADJOFF_16APSK  0xf42a0020
+#define FSTV0910_P1_R2ADJOFF_16APSK  0xf42a6040
+#define FSTV0910_P1_R1ADJOFF_16APSK  0xf42a5020
 #define FSTV0910_P1_RADJ_16APSK  0xf42a011f
 
 /* P1_AGCK32 */
 #define RSTV0910_P1_AGCK32  0xf42b
-#define FSTV0910_P1_R3ADJOFF_32APSK  0xf42b0080
-#define FSTV0910_P1_R2ADJOFF_32APSK  0xf42b0040
-#define FSTV0910_P1_R1ADJOFF_32APSK  0xf42b0020
+#define FSTV0910_P1_R3ADJOFF_32APSK  0xf42b7080
+#define FSTV0910_P1_R2ADJOFF_32APSK  0xf42b6040
+#define FSTV0910_P1_R1ADJOFF_32APSK  0xf42b5020
 #define FSTV0910_P1_RADJ_32APSK  0xf42b011f
 
 /* P1_AGC2O */
 #define RSTV0910_P1_AGC2O  0xf42c
-#define FSTV0910_P1_CSTENV_MODE  0xf42c00c0
+#define FSTV0910_P1_CSTENV_MODE  0xf42c60c0
 #define FSTV0910_P1_AGC2_COEF  0xf42c0007
 
 /* P1_AGC2REF */
@@ -2306,32 +2306,32 @@
 
 /* P1_CARCFG */
 #define RSTV0910_P1_CARCFG  0xf438
-#define FSTV0910_P1_ROTAON  0xf4380004
+#define FSTV0910_P1_ROTAON  0xf4382004
 #define FSTV0910_P1_PH_DET_ALGO  0xf4380003
 
 /* P1_ACLC */
 #define RSTV0910_P1_ACLC  0xf439
-#define FSTV0910_P1_CAR_ALPHA_MANT  0xf4390030
+#define FSTV0910_P1_CAR_ALPHA_MANT  0xf4394030
 #define FSTV0910_P1_CAR_ALPHA_EXP  0xf439000f
 
 /* P1_BCLC */
 #define RSTV0910_P1_BCLC  0xf43a
-#define FSTV0910_P1_CAR_BETA_MANT  0xf43a0030
+#define FSTV0910_P1_CAR_BETA_MANT  0xf43a4030
 #define FSTV0910_P1_CAR_BETA_EXP  0xf43a000f
 
 /* P1_ACLCS2 */
 #define RSTV0910_P1_ACLCS2  0xf43b
-#define FSTV0910_P1_CARS2_APLHA_MANTISSE  0xf43b0030
+#define FSTV0910_P1_CARS2_APLHA_MANTISSE  0xf43b4030
 #define FSTV0910_P1_CARS2_ALPHA_EXP  0xf43b000f
 
 /* P1_BCLCS2 */
 #define RSTV0910_P1_BCLCS2  0xf43c
-#define FSTV0910_P1_CARS2_BETA_MANTISSE  0xf43c0030
+#define FSTV0910_P1_CARS2_BETA_MANTISSE  0xf43c4030
 #define FSTV0910_P1_CARS2_BETA_EXP  0xf43c000f
 
 /* P1_CARFREQ */
 #define RSTV0910_P1_CARFREQ  0xf43d
-#define FSTV0910_P1_KC_COARSE_EXP  0xf43d00f0
+#define FSTV0910_P1_KC_COARSE_EXP  0xf43d40f0
 #define FSTV0910_P1_BETA_FREQ  0xf43d000f
 
 /* P1_CARHDR */
@@ -2384,7 +2384,7 @@
 
 /* P1_CFRINC1 */
 #define RSTV0910_P1_CFRINC1  0xf44a
-#define FSTV0910_P1_MANUAL_CFRINC  0xf44a0080
+#define FSTV0910_P1_MANUAL_CFRINC  0xf44a7080
 #define FSTV0910_P1_CFR_INC1  0xf44a003f
 
 /* P1_CFRINC0 */
@@ -2409,18 +2409,18 @@
 
 /* P1_TMGCFG */
 #define RSTV0910_P1_TMGCFG  0xf450
-#define FSTV0910_P1_TMGLOCK_BETA  0xf45000c0
-#define FSTV0910_P1_DO_TIMING_CORR  0xf4500010
+#define FSTV0910_P1_TMGLOCK_BETA  0xf45060c0
+#define FSTV0910_P1_DO_TIMING_CORR  0xf4504010
 #define FSTV0910_P1_TMG_MINFREQ  0xf4500003
 
 /* P1_RTC */
 #define RSTV0910_P1_RTC  0xf451
-#define FSTV0910_P1_TMGALPHA_EXP  0xf45100f0
+#define FSTV0910_P1_TMGALPHA_EXP  0xf45140f0
 #define FSTV0910_P1_TMGBETA_EXP  0xf451000f
 
 /* P1_RTCS2 */
 #define RSTV0910_P1_RTCS2  0xf452
-#define FSTV0910_P1_TMGALPHAS2_EXP  0xf45200f0
+#define FSTV0910_P1_TMGALPHAS2_EXP  0xf45240f0
 #define FSTV0910_P1_TMGBETAS2_EXP  0xf452000f
 
 /* P1_TMGTHRISE */
@@ -2441,7 +2441,7 @@
 
 /* P1_KTTMG */
 #define RSTV0910_P1_KTTMG  0xf457
-#define FSTV0910_P1_KT_TMG_EXP  0xf45700f0
+#define FSTV0910_P1_KT_TMG_EXP  0xf45740f0
 
 /* P1_KREFTMG */
 #define RSTV0910_P1_KREFTMG  0xf458
@@ -2449,12 +2449,12 @@
 
 /* P1_SFRSTEP */
 #define RSTV0910_P1_SFRSTEP  0xf459
-#define FSTV0910_P1_SFR_SCANSTEP  0xf45900f0
+#define FSTV0910_P1_SFR_SCANSTEP  0xf45940f0
 #define FSTV0910_P1_SFR_CENTERSTEP  0xf459000f
 
 /* P1_TMGCFG2 */
 #define RSTV0910_P1_TMGCFG2  0xf45a
-#define FSTV0910_P1_DIS_AUTOSAMP  0xf45a0008
+#define FSTV0910_P1_DIS_AUTOSAMP  0xf45a3008
 #define FSTV0910_P1_SFRRATIO_FINE  0xf45a0001
 
 /* P1_KREFTMG2 */
@@ -2463,9 +2463,9 @@
 
 /* P1_TMGCFG3 */
 #define RSTV0910_P1_TMGCFG3  0xf45d
-#define FSTV0910_P1_CONT_TMGCENTER  0xf45d0008
-#define FSTV0910_P1_AUTO_GUP  0xf45d0004
-#define FSTV0910_P1_AUTO_GLOW  0xf45d0002
+#define FSTV0910_P1_CONT_TMGCENTER  0xf45d3008
+#define FSTV0910_P1_AUTO_GUP  0xf45d2004
+#define FSTV0910_P1_AUTO_GLOW  0xf45d1002
 
 /* P1_SFRINIT1 */
 #define RSTV0910_P1_SFRINIT1  0xf45e
@@ -2529,11 +2529,11 @@
 
 /* P1_TMGOBS */
 #define RSTV0910_P1_TMGOBS  0xf46d
-#define FSTV0910_P1_ROLLOFF_STATUS  0xf46d00c0
+#define FSTV0910_P1_ROLLOFF_STATUS  0xf46d60c0
 
 /* P1_EQUALCFG */
 #define RSTV0910_P1_EQUALCFG  0xf46f
-#define FSTV0910_P1_EQUAL_ON  0xf46f0040
+#define FSTV0910_P1_EQUAL_ON  0xf46f6040
 #define FSTV0910_P1_MU_EQUALDFE  0xf46f0007
 
 /* P1_EQUAI1 */
@@ -2658,33 +2658,33 @@
 
 /* P1_NOSCFGF1 */
 #define RSTV0910_P1_NOSCFGF1  0xf48e
-#define FSTV0910_P1_LOWNOISE_MESURE  0xf48e0080
-#define FSTV0910_P1_NOS_DELFRAME  0xf48e0040
-#define FSTV0910_P1_NOSDATA_MODE  0xf48e0030
-#define FSTV0910_P1_FRAMESEL_TYPESEL  0xf48e000c
+#define FSTV0910_P1_LOWNOISE_MESURE  0xf48e7080
+#define FSTV0910_P1_NOS_DELFRAME  0xf48e6040
+#define FSTV0910_P1_NOSDATA_MODE  0xf48e4030
+#define FSTV0910_P1_FRAMESEL_TYPESEL  0xf48e200c
 #define FSTV0910_P1_FRAMESEL_TYPE  0xf48e0003
 
 /* P1_NOSCFGF2 */
 #define RSTV0910_P1_NOSCFGF2  0xf48f
-#define FSTV0910_P1_DIS_NOSPILOTS  0xf48f0080
-#define FSTV0910_P1_FRAMESEL_MODCODSEL  0xf48f0060
+#define FSTV0910_P1_DIS_NOSPILOTS  0xf48f7080
+#define FSTV0910_P1_FRAMESEL_MODCODSEL  0xf48f5060
 #define FSTV0910_P1_FRAMESEL_MODCOD  0xf48f001f
 
 /* P1_CAR2CFG */
 #define RSTV0910_P1_CAR2CFG  0xf490
-#define FSTV0910_P1_ROTA2ON  0xf4900004
+#define FSTV0910_P1_ROTA2ON  0xf4902004
 #define FSTV0910_P1_PH_DET_ALGO2  0xf4900003
 
 /* P1_CFR2CFR1 */
 #define RSTV0910_P1_CFR2CFR1  0xf491
-#define FSTV0910_P1_EN_S2CAR2CENTER  0xf4910020
+#define FSTV0910_P1_EN_S2CAR2CENTER  0xf4915020
 #define FSTV0910_P1_CFR2TOCFR1_BETA  0xf4910007
 
 /* P1_CAR3CFG */
 #define RSTV0910_P1_CAR3CFG  0xf492
-#define FSTV0910_P1_CARRIER23_MODE  0xf49200c0
-#define FSTV0910_P1_CAR3INTERM_DVBS1  0xf4920020
-#define FSTV0910_P1_ABAMPLIF_MODE  0xf4920018
+#define FSTV0910_P1_CARRIER23_MODE  0xf49260c0
+#define FSTV0910_P1_CAR3INTERM_DVBS1  0xf4925020
+#define FSTV0910_P1_ABAMPLIF_MODE  0xf4923018
 #define FSTV0910_P1_CARRIER3_ALPHA3DL  0xf4920007
 
 /* P1_CFR22 */
@@ -2701,50 +2701,50 @@
 
 /* P1_ACLC2S2Q */
 #define RSTV0910_P1_ACLC2S2Q  0xf497
-#define FSTV0910_P1_ENAB_SPSKSYMB  0xf4970080
-#define FSTV0910_P1_CAR2S2_Q_ALPH_M  0xf4970030
+#define FSTV0910_P1_ENAB_SPSKSYMB  0xf4977080
+#define FSTV0910_P1_CAR2S2_Q_ALPH_M  0xf4974030
 #define FSTV0910_P1_CAR2S2_Q_ALPH_E  0xf497000f
 
 /* P1_ACLC2S28 */
 #define RSTV0910_P1_ACLC2S28  0xf498
-#define FSTV0910_P1_CAR2S2_8_ALPH_M  0xf4980030
+#define FSTV0910_P1_CAR2S2_8_ALPH_M  0xf4984030
 #define FSTV0910_P1_CAR2S2_8_ALPH_E  0xf498000f
 
 /* P1_ACLC2S216A */
 #define RSTV0910_P1_ACLC2S216A  0xf499
-#define FSTV0910_P1_CAR2S2_16A_ALPH_M  0xf4990030
+#define FSTV0910_P1_CAR2S2_16A_ALPH_M  0xf4994030
 #define FSTV0910_P1_CAR2S2_16A_ALPH_E  0xf499000f
 
 /* P1_ACLC2S232A */
 #define RSTV0910_P1_ACLC2S232A  0xf49a
-#define FSTV0910_P1_CAR2S2_32A_ALPH_M  0xf49a0030
+#define FSTV0910_P1_CAR2S2_32A_ALPH_M  0xf49a4030
 #define FSTV0910_P1_CAR2S2_32A_ALPH_E  0xf49a000f
 
 /* P1_BCLC2S2Q */
 #define RSTV0910_P1_BCLC2S2Q  0xf49c
-#define FSTV0910_P1_CAR2S2_Q_BETA_M  0xf49c0030
+#define FSTV0910_P1_CAR2S2_Q_BETA_M  0xf49c4030
 #define FSTV0910_P1_CAR2S2_Q_BETA_E  0xf49c000f
 
 /* P1_BCLC2S28 */
 #define RSTV0910_P1_BCLC2S28  0xf49d
-#define FSTV0910_P1_CAR2S2_8_BETA_M  0xf49d0030
+#define FSTV0910_P1_CAR2S2_8_BETA_M  0xf49d4030
 #define FSTV0910_P1_CAR2S2_8_BETA_E  0xf49d000f
 
 /* P1_BCLC2S216A */
 #define RSTV0910_P1_BCLC2S216A  0xf49e
-#define FSTV0910_P1_DVBS2S216A_NIP  0xf49e0080
-#define FSTV0910_P1_CAR2S2_16A_BETA_M  0xf49e0030
+#define FSTV0910_P1_DVBS2S216A_NIP  0xf49e7080
+#define FSTV0910_P1_CAR2S2_16A_BETA_M  0xf49e4030
 #define FSTV0910_P1_CAR2S2_16A_BETA_E  0xf49e000f
 
 /* P1_BCLC2S232A */
 #define RSTV0910_P1_BCLC2S232A  0xf49f
-#define FSTV0910_P1_DVBS2S232A_NIP  0xf49f0080
-#define FSTV0910_P1_CAR2S2_32A_BETA_M  0xf49f0030
+#define FSTV0910_P1_DVBS2S232A_NIP  0xf49f7080
+#define FSTV0910_P1_CAR2S2_32A_BETA_M  0xf49f4030
 #define FSTV0910_P1_CAR2S2_32A_BETA_E  0xf49f000f
 
 /* P1_PLROOT2 */
 #define RSTV0910_P1_PLROOT2  0xf4ac
-#define FSTV0910_P1_PLSCRAMB_MODE  0xf4ac000c
+#define FSTV0910_P1_PLSCRAMB_MODE  0xf4ac200c
 #define FSTV0910_P1_PLSCRAMB_ROOT2  0xf4ac0003
 
 /* P1_PLROOT1 */
@@ -2761,100 +2761,100 @@
 
 /* P1_MODCODLST1 */
 #define RSTV0910_P1_MODCODLST1  0xf4b1
-#define FSTV0910_P1_SYMBRATE_FILTER  0xf4b10008
-#define FSTV0910_P1_NRESET_MODCODLST  0xf4b10004
+#define FSTV0910_P1_SYMBRATE_FILTER  0xf4b13008
+#define FSTV0910_P1_NRESET_MODCODLST  0xf4b12004
 #define FSTV0910_P1_DIS_32PSK_9_10  0xf4b10003
 
 /* P1_MODCODLST2 */
 #define RSTV0910_P1_MODCODLST2  0xf4b2
-#define FSTV0910_P1_DIS_32PSK_8_9  0xf4b200f0
+#define FSTV0910_P1_DIS_32PSK_8_9  0xf4b240f0
 #define FSTV0910_P1_DIS_32PSK_5_6  0xf4b2000f
 
 /* P1_MODCODLST3 */
 #define RSTV0910_P1_MODCODLST3  0xf4b3
-#define FSTV0910_P1_DIS_32PSK_4_5  0xf4b300f0
+#define FSTV0910_P1_DIS_32PSK_4_5  0xf4b340f0
 #define FSTV0910_P1_DIS_32PSK_3_4  0xf4b3000f
 
 /* P1_MODCODLST4 */
 #define RSTV0910_P1_MODCODLST4  0xf4b4
-#define FSTV0910_P1_DUMMYPL_PILOT  0xf4b40080
-#define FSTV0910_P1_DUMMYPL_NOPILOT  0xf4b40040
-#define FSTV0910_P1_DIS_16PSK_9_10  0xf4b40030
+#define FSTV0910_P1_DUMMYPL_PILOT  0xf4b47080
+#define FSTV0910_P1_DUMMYPL_NOPILOT  0xf4b46040
+#define FSTV0910_P1_DIS_16PSK_9_10  0xf4b44030
 #define FSTV0910_P1_DIS_16PSK_8_9  0xf4b4000f
 
 /* P1_MODCODLST5 */
 #define RSTV0910_P1_MODCODLST5  0xf4b5
-#define FSTV0910_P1_DIS_16PSK_5_6  0xf4b500f0
+#define FSTV0910_P1_DIS_16PSK_5_6  0xf4b540f0
 #define FSTV0910_P1_DIS_16PSK_4_5  0xf4b5000f
 
 /* P1_MODCODLST6 */
 #define RSTV0910_P1_MODCODLST6  0xf4b6
-#define FSTV0910_P1_DIS_16PSK_3_4  0xf4b600f0
+#define FSTV0910_P1_DIS_16PSK_3_4  0xf4b640f0
 #define FSTV0910_P1_DIS_16PSK_2_3  0xf4b6000f
 
 /* P1_MODCODLST7 */
 #define RSTV0910_P1_MODCODLST7  0xf4b7
-#define FSTV0910_P1_MODCOD_NNOSFILTER  0xf4b70080
-#define FSTV0910_P1_DIS_8PSK_9_10  0xf4b70030
+#define FSTV0910_P1_MODCOD_NNOSFILTER  0xf4b77080
+#define FSTV0910_P1_DIS_8PSK_9_10  0xf4b74030
 #define FSTV0910_P1_DIS_8PSK_8_9  0xf4b7000f
 
 /* P1_MODCODLST8 */
 #define RSTV0910_P1_MODCODLST8  0xf4b8
-#define FSTV0910_P1_DIS_8PSK_5_6  0xf4b800f0
+#define FSTV0910_P1_DIS_8PSK_5_6  0xf4b840f0
 #define FSTV0910_P1_DIS_8PSK_3_4  0xf4b8000f
 
 /* P1_MODCODLST9 */
 #define RSTV0910_P1_MODCODLST9  0xf4b9
-#define FSTV0910_P1_DIS_8PSK_2_3  0xf4b900f0
+#define FSTV0910_P1_DIS_8PSK_2_3  0xf4b940f0
 #define FSTV0910_P1_DIS_8PSK_3_5  0xf4b9000f
 
 /* P1_MODCODLSTA */
 #define RSTV0910_P1_MODCODLSTA  0xf4ba
-#define FSTV0910_P1_NOSFILTER_LIMITE  0xf4ba0080
-#define FSTV0910_P1_DIS_QPSK_9_10  0xf4ba0030
+#define FSTV0910_P1_NOSFILTER_LIMITE  0xf4ba7080
+#define FSTV0910_P1_DIS_QPSK_9_10  0xf4ba4030
 #define FSTV0910_P1_DIS_QPSK_8_9  0xf4ba000f
 
 /* P1_MODCODLSTB */
 #define RSTV0910_P1_MODCODLSTB  0xf4bb
-#define FSTV0910_P1_DIS_QPSK_5_6  0xf4bb00f0
+#define FSTV0910_P1_DIS_QPSK_5_6  0xf4bb40f0
 #define FSTV0910_P1_DIS_QPSK_4_5  0xf4bb000f
 
 /* P1_MODCODLSTC */
 #define RSTV0910_P1_MODCODLSTC  0xf4bc
-#define FSTV0910_P1_DIS_QPSK_3_4  0xf4bc00f0
+#define FSTV0910_P1_DIS_QPSK_3_4  0xf4bc40f0
 #define FSTV0910_P1_DIS_QPSK_2_3  0xf4bc000f
 
 /* P1_MODCODLSTD */
 #define RSTV0910_P1_MODCODLSTD  0xf4bd
-#define FSTV0910_P1_DIS_QPSK_3_5  0xf4bd00f0
+#define FSTV0910_P1_DIS_QPSK_3_5  0xf4bd40f0
 #define FSTV0910_P1_DIS_QPSK_1_2  0xf4bd000f
 
 /* P1_MODCODLSTE */
 #define RSTV0910_P1_MODCODLSTE  0xf4be
-#define FSTV0910_P1_DIS_QPSK_2_5  0xf4be00f0
+#define FSTV0910_P1_DIS_QPSK_2_5  0xf4be40f0
 #define FSTV0910_P1_DIS_QPSK_1_3  0xf4be000f
 
 /* P1_MODCODLSTF */
 #define RSTV0910_P1_MODCODLSTF  0xf4bf
-#define FSTV0910_P1_DIS_QPSK_1_4  0xf4bf00f0
-#define FSTV0910_P1_DEMOD_INVMODLST  0xf4bf0008
-#define FSTV0910_P1_DEMODOUT_ENABLE  0xf4bf0004
-#define FSTV0910_P1_DDEMOD_NSET  0xf4bf0002
+#define FSTV0910_P1_DIS_QPSK_1_4  0xf4bf40f0
+#define FSTV0910_P1_DEMOD_INVMODLST  0xf4bf3008
+#define FSTV0910_P1_DEMODOUT_ENABLE  0xf4bf2004
+#define FSTV0910_P1_DDEMOD_NSET  0xf4bf1002
 #define FSTV0910_P1_MODCOD_NSTOCK  0xf4bf0001
 
 /* P1_GAUSSR0 */
 #define RSTV0910_P1_GAUSSR0  0xf4c0
-#define FSTV0910_P1_EN_CCIMODE  0xf4c00080
+#define FSTV0910_P1_EN_CCIMODE  0xf4c07080
 #define FSTV0910_P1_R0_GAUSSIEN  0xf4c0007f
 
 /* P1_CCIR0 */
 #define RSTV0910_P1_CCIR0  0xf4c1
-#define FSTV0910_P1_CCIDETECT_PLHONLY  0xf4c10080
+#define FSTV0910_P1_CCIDETECT_PLHONLY  0xf4c17080
 #define FSTV0910_P1_R0_CCI  0xf4c1007f
 
 /* P1_CCIQUANT */
 #define RSTV0910_P1_CCIQUANT  0xf4c2
-#define FSTV0910_P1_CCI_BETA  0xf4c200e0
+#define FSTV0910_P1_CCI_BETA  0xf4c250e0
 #define FSTV0910_P1_CCI_QUANT  0xf4c2001f
 
 /* P1_CCITHRES */
@@ -2867,24 +2867,24 @@
 
 /* P1_DSTATUS4 */
 #define RSTV0910_P1_DSTATUS4  0xf4c5
-#define FSTV0910_P1_RAINFADE_DETECT  0xf4c50080
-#define FSTV0910_P1_NOTHRES2_FAIL  0xf4c50040
-#define FSTV0910_P1_NOTHRES1_FAIL  0xf4c50020
-#define FSTV0910_P1_DMDPROG_ERROR  0xf4c50004
-#define FSTV0910_P1_CSTENV_DETECT  0xf4c50002
+#define FSTV0910_P1_RAINFADE_DETECT  0xf4c57080
+#define FSTV0910_P1_NOTHRES2_FAIL  0xf4c56040
+#define FSTV0910_P1_NOTHRES1_FAIL  0xf4c55020
+#define FSTV0910_P1_DMDPROG_ERROR  0xf4c52004
+#define FSTV0910_P1_CSTENV_DETECT  0xf4c51002
 #define FSTV0910_P1_DETECTION_TRIAX  0xf4c50001
 
 /* P1_DMDRESCFG */
 #define RSTV0910_P1_DMDRESCFG  0xf4c6
-#define FSTV0910_P1_DMDRES_RESET  0xf4c60080
-#define FSTV0910_P1_DMDRES_STRALL  0xf4c60008
-#define FSTV0910_P1_DMDRES_NEWONLY  0xf4c60004
-#define FSTV0910_P1_DMDRES_NOSTORE  0xf4c60002
+#define FSTV0910_P1_DMDRES_RESET  0xf4c67080
+#define FSTV0910_P1_DMDRES_STRALL  0xf4c63008
+#define FSTV0910_P1_DMDRES_NEWONLY  0xf4c62004
+#define FSTV0910_P1_DMDRES_NOSTORE  0xf4c61002
 
 /* P1_DMDRESADR */
 #define RSTV0910_P1_DMDRESADR  0xf4c7
-#define FSTV0910_P1_DMDRES_VALIDCFR  0xf4c70040
-#define FSTV0910_P1_DMDRES_MEMFULL  0xf4c70030
+#define FSTV0910_P1_DMDRES_VALIDCFR  0xf4c76040
+#define FSTV0910_P1_DMDRES_MEMFULL  0xf4c74030
 #define FSTV0910_P1_DMDRES_RESNBR  0xf4c7000f
 
 /* P1_DMDRESDATA7 */
@@ -2953,29 +2953,29 @@
 
 /* P1_FFECFG */
 #define RSTV0910_P1_FFECFG  0xf4d8
-#define FSTV0910_P1_EQUALFFE_ON  0xf4d80040
-#define FSTV0910_P1_EQUAL_USEDSYMB  0xf4d80030
+#define FSTV0910_P1_EQUALFFE_ON  0xf4d86040
+#define FSTV0910_P1_EQUAL_USEDSYMB  0xf4d84030
 #define FSTV0910_P1_MU_EQUALFFE  0xf4d80007
 
 /* P1_TNRCFG2 */
 #define RSTV0910_P1_TNRCFG2  0xf4e1
-#define FSTV0910_P1_TUN_IQSWAP  0xf4e10080
+#define FSTV0910_P1_TUN_IQSWAP  0xf4e17080
 
 /* P1_SMAPCOEF7 */
 #define RSTV0910_P1_SMAPCOEF7  0xf500
-#define FSTV0910_P1_DIS_QSCALE  0xf5000080
+#define FSTV0910_P1_DIS_QSCALE  0xf5007080
 #define FSTV0910_P1_SMAPCOEF_Q_LLR12  0xf500017f
 
 /* P1_SMAPCOEF6 */
 #define RSTV0910_P1_SMAPCOEF6  0xf501
-#define FSTV0910_P1_DIS_AGC2SCALE  0xf5010080
-#define FSTV0910_P1_ADJ_8PSKLLR1  0xf5010004
-#define FSTV0910_P1_OLD_8PSKLLR1  0xf5010002
+#define FSTV0910_P1_DIS_AGC2SCALE  0xf5017080
+#define FSTV0910_P1_ADJ_8PSKLLR1  0xf5012004
+#define FSTV0910_P1_OLD_8PSKLLR1  0xf5011002
 #define FSTV0910_P1_DIS_AB8PSK  0xf5010001
 
 /* P1_SMAPCOEF5 */
 #define RSTV0910_P1_SMAPCOEF5  0xf502
-#define FSTV0910_P1_DIS_8SCALE  0xf5020080
+#define FSTV0910_P1_DIS_8SCALE  0xf5027080
 #define FSTV0910_P1_SMAPCOEF_8P_LLR23  0xf502017f
 
 /* P1_SMAPCOEF4 */
@@ -2988,17 +2988,17 @@
 
 /* P1_SMAPCOEF2 */
 #define RSTV0910_P1_SMAPCOEF2  0xf505
-#define FSTV0910_P1_SMAPCOEF_32APSK_R2R3  0xf50501f0
+#define FSTV0910_P1_SMAPCOEF_32APSK_R2R3  0xf50541f0
 #define FSTV0910_P1_SMAPCOEF_32APSK_LLR2  0xf505010f
 
 /* P1_SMAPCOEF1 */
 #define RSTV0910_P1_SMAPCOEF1  0xf506
-#define FSTV0910_P1_DIS_16SCALE  0xf5060080
+#define FSTV0910_P1_DIS_16SCALE  0xf5067080
 #define FSTV0910_P1_SMAPCOEF_32_LLR34  0xf506017f
 
 /* P1_SMAPCOEF0 */
 #define RSTV0910_P1_SMAPCOEF0  0xf507
-#define FSTV0910_P1_DIS_32SCALE  0xf5070080
+#define FSTV0910_P1_DIS_32SCALE  0xf5077080
 #define FSTV0910_P1_SMAPCOEF_32_LLR15  0xf507017f
 
 /* P1_NOSTHRES1 */
@@ -3015,20 +3015,20 @@
 
 /* P1_RAINFADE */
 #define RSTV0910_P1_RAINFADE  0xf50c
-#define FSTV0910_P1_NOSTHRES_DATAT  0xf50c0080
-#define FSTV0910_P1_RAINFADE_CNLIMIT  0xf50c0070
+#define FSTV0910_P1_NOSTHRES_DATAT  0xf50c7080
+#define FSTV0910_P1_RAINFADE_CNLIMIT  0xf50c4070
 #define FSTV0910_P1_RAINFADE_TIMEOUT  0xf50c0007
 
 /* P1_NOSRAMCFG */
 #define RSTV0910_P1_NOSRAMCFG  0xf50d
-#define FSTV0910_P1_NOSRAM_ACTIVATION  0xf50d0030
-#define FSTV0910_P1_NOSRAM_CNRONLY  0xf50d0008
+#define FSTV0910_P1_NOSRAM_ACTIVATION  0xf50d4030
+#define FSTV0910_P1_NOSRAM_CNRONLY  0xf50d3008
 #define FSTV0910_P1_NOSRAM_LGNCNR1  0xf50d0007
 
 /* P1_NOSRAMPOS */
 #define RSTV0910_P1_NOSRAMPOS  0xf50e
-#define FSTV0910_P1_NOSRAM_LGNCNR0  0xf50e00f0
-#define FSTV0910_P1_NOSRAM_VALIDE  0xf50e0004
+#define FSTV0910_P1_NOSRAM_LGNCNR0  0xf50e40f0
+#define FSTV0910_P1_NOSRAM_VALIDE  0xf50e2004
 #define FSTV0910_P1_NOSRAM_CNRVAL1  0xf50e0003
 
 /* P1_NOSRAMVAL */
@@ -3057,16 +3057,16 @@
 
 /* P1_VITSCALE */
 #define RSTV0910_P1_VITSCALE  0xf532
-#define FSTV0910_P1_NVTH_NOSRANGE  0xf5320080
-#define FSTV0910_P1_VERROR_MAXMODE  0xf5320040
-#define FSTV0910_P1_NSLOWSN_LOCKED  0xf5320008
-#define FSTV0910_P1_DIS_RSFLOCK  0xf5320002
+#define FSTV0910_P1_NVTH_NOSRANGE  0xf5327080
+#define FSTV0910_P1_VERROR_MAXMODE  0xf5326040
+#define FSTV0910_P1_NSLOWSN_LOCKED  0xf5323008
+#define FSTV0910_P1_DIS_RSFLOCK  0xf5321002
 
 /* P1_FECM */
 #define RSTV0910_P1_FECM  0xf533
-#define FSTV0910_P1_DSS_DVB  0xf5330080
-#define FSTV0910_P1_DSS_SRCH  0xf5330010
-#define FSTV0910_P1_SYNCVIT  0xf5330002
+#define FSTV0910_P1_DSS_DVB  0xf5337080
+#define FSTV0910_P1_DSS_SRCH  0xf5334010
+#define FSTV0910_P1_SYNCVIT  0xf5331002
 #define FSTV0910_P1_IQINV  0xf5330001
 
 /* P1_VTH12 */
@@ -3103,26 +3103,26 @@
 
 /* P1_PRVIT */
 #define RSTV0910_P1_PRVIT  0xf53c
-#define FSTV0910_P1_DIS_VTHLOCK  0xf53c0040
-#define FSTV0910_P1_E7_8VIT  0xf53c0020
-#define FSTV0910_P1_E6_7VIT  0xf53c0010
-#define FSTV0910_P1_E5_6VIT  0xf53c0008
-#define FSTV0910_P1_E3_4VIT  0xf53c0004
-#define FSTV0910_P1_E2_3VIT  0xf53c0002
+#define FSTV0910_P1_DIS_VTHLOCK  0xf53c6040
+#define FSTV0910_P1_E7_8VIT  0xf53c5020
+#define FSTV0910_P1_E6_7VIT  0xf53c4010
+#define FSTV0910_P1_E5_6VIT  0xf53c3008
+#define FSTV0910_P1_E3_4VIT  0xf53c2004
+#define FSTV0910_P1_E2_3VIT  0xf53c1002
 #define FSTV0910_P1_E1_2VIT  0xf53c0001
 
 /* P1_VAVSRVIT */
 #define RSTV0910_P1_VAVSRVIT  0xf53d
-#define FSTV0910_P1_AMVIT  0xf53d0080
-#define FSTV0910_P1_FROZENVIT  0xf53d0040
-#define FSTV0910_P1_SNVIT  0xf53d0030
-#define FSTV0910_P1_TOVVIT  0xf53d000c
+#define FSTV0910_P1_AMVIT  0xf53d7080
+#define FSTV0910_P1_FROZENVIT  0xf53d6040
+#define FSTV0910_P1_SNVIT  0xf53d4030
+#define FSTV0910_P1_TOVVIT  0xf53d200c
 #define FSTV0910_P1_HYPVIT  0xf53d0003
 
 /* P1_VSTATUSVIT */
 #define RSTV0910_P1_VSTATUSVIT  0xf53e
-#define FSTV0910_P1_PRFVIT  0xf53e0010
-#define FSTV0910_P1_LOCKEDVIT  0xf53e0008
+#define FSTV0910_P1_PRFVIT  0xf53e4010
+#define FSTV0910_P1_LOCKEDVIT  0xf53e3008
 
 /* P1_VTHINUSE */
 #define RSTV0910_P1_VTHINUSE  0xf53f
@@ -3162,32 +3162,32 @@
 
 /* P1_PDELCTRL0 */
 #define RSTV0910_P1_PDELCTRL0  0xf54f
-#define FSTV0910_P1_ISIOBS_MODE  0xf54f0030
+#define FSTV0910_P1_ISIOBS_MODE  0xf54f4030
 
 /* P1_PDELCTRL1 */
 #define RSTV0910_P1_PDELCTRL1  0xf550
-#define FSTV0910_P1_INV_MISMASK  0xf5500080
-#define FSTV0910_P1_FILTER_EN  0xf5500020
-#define FSTV0910_P1_HYSTEN  0xf5500008
-#define FSTV0910_P1_HYSTSWRST  0xf5500004
-#define FSTV0910_P1_EN_MIS00  0xf5500002
+#define FSTV0910_P1_INV_MISMASK  0xf5507080
+#define FSTV0910_P1_FILTER_EN  0xf5505020
+#define FSTV0910_P1_HYSTEN  0xf5503008
+#define FSTV0910_P1_HYSTSWRST  0xf5502004
+#define FSTV0910_P1_EN_MIS00  0xf5501002
 #define FSTV0910_P1_ALGOSWRST  0xf5500001
 
 /* P1_PDELCTRL2 */
 #define RSTV0910_P1_PDELCTRL2  0xf551
-#define FSTV0910_P1_FORCE_CONTINUOUS  0xf5510080
-#define FSTV0910_P1_RESET_UPKO_COUNT  0xf5510040
-#define FSTV0910_P1_USER_PKTDELIN_NB  0xf5510020
-#define FSTV0910_P1_FRAME_MODE  0xf5510002
+#define FSTV0910_P1_FORCE_CONTINUOUS  0xf5517080
+#define FSTV0910_P1_RESET_UPKO_COUNT  0xf5516040
+#define FSTV0910_P1_USER_PKTDELIN_NB  0xf5515020
+#define FSTV0910_P1_FRAME_MODE  0xf5511002
 
 /* P1_HYSTTHRESH */
 #define RSTV0910_P1_HYSTTHRESH  0xf554
-#define FSTV0910_P1_DELIN_LOCKTHRES  0xf55400f0
+#define FSTV0910_P1_DELIN_LOCKTHRES  0xf55440f0
 #define FSTV0910_P1_DELIN_UNLOCKTHRES  0xf554000f
 
 /* P1_UPLCCST0 */
 #define RSTV0910_P1_UPLCCST0  0xf558
-#define FSTV0910_P1_UPL_CST0  0xf55800f8
+#define FSTV0910_P1_UPL_CST0  0xf55830f8
 #define FSTV0910_P1_UPL_MODE  0xf5580007
 
 /* P1_ISIENTRY */
@@ -3236,16 +3236,16 @@
 
 /* P1_PDELSTATUS1 */
 #define RSTV0910_P1_PDELSTATUS1  0xf569
-#define FSTV0910_P1_PKTDELIN_DELOCK  0xf5690080
-#define FSTV0910_P1_SYNCDUPDFL_BADDFL  0xf5690040
-#define FSTV0910_P1_UNACCEPTED_STREAM  0xf5690010
-#define FSTV0910_P1_BCH_ERROR_FLAG  0xf5690008
-#define FSTV0910_P1_PKTDELIN_LOCK  0xf5690002
+#define FSTV0910_P1_PKTDELIN_DELOCK  0xf5697080
+#define FSTV0910_P1_SYNCDUPDFL_BADDFL  0xf5696040
+#define FSTV0910_P1_UNACCEPTED_STREAM  0xf5694010
+#define FSTV0910_P1_BCH_ERROR_FLAG  0xf5693008
+#define FSTV0910_P1_PKTDELIN_LOCK  0xf5691002
 #define FSTV0910_P1_FIRST_LOCK  0xf5690001
 
 /* P1_PDELSTATUS2 */
 #define RSTV0910_P1_PDELSTATUS2  0xf56a
-#define FSTV0910_P1_FRAME_MODCOD  0xf56a007c
+#define FSTV0910_P1_FRAME_MODCOD  0xf56a207c
 #define FSTV0910_P1_FRAME_TYPE  0xf56a0003
 
 /* P1_BBFCRCKO1 */
@@ -3266,92 +3266,92 @@
 
 /* P1_PDELCTRL3 */
 #define RSTV0910_P1_PDELCTRL3  0xf56f
-#define FSTV0910_P1_NOFIFO_BCHERR  0xf56f0020
-#define FSTV0910_P1_PKTDELIN_DELACMERR  0xf56f0010
+#define FSTV0910_P1_NOFIFO_BCHERR  0xf56f5020
+#define FSTV0910_P1_PKTDELIN_DELACMERR  0xf56f4010
 
 /* P1_TSSTATEM */
 #define RSTV0910_P1_TSSTATEM  0xf570
-#define FSTV0910_P1_TSDIL_ON  0xf5700080
-#define FSTV0910_P1_TSRS_ON  0xf5700020
-#define FSTV0910_P1_TSDESCRAMB_ON  0xf5700010
-#define FSTV0910_P1_TSFRAME_MODE  0xf5700008
-#define FSTV0910_P1_TS_DISABLE  0xf5700004
-#define FSTV0910_P1_TSACM_MODE  0xf5700002
+#define FSTV0910_P1_TSDIL_ON  0xf5707080
+#define FSTV0910_P1_TSRS_ON  0xf5705020
+#define FSTV0910_P1_TSDESCRAMB_ON  0xf5704010
+#define FSTV0910_P1_TSFRAME_MODE  0xf5703008
+#define FSTV0910_P1_TS_DISABLE  0xf5702004
+#define FSTV0910_P1_TSACM_MODE  0xf5701002
 #define FSTV0910_P1_TSOUT_NOSYNC  0xf5700001
 
 /* P1_TSSTATEL */
 #define RSTV0910_P1_TSSTATEL  0xf571
-#define FSTV0910_P1_TSNOSYNCBYTE  0xf5710080
-#define FSTV0910_P1_TSPARITY_ON  0xf5710040
-#define FSTV0910_P1_TSISSYI_ON  0xf5710008
-#define FSTV0910_P1_TSNPD_ON  0xf5710004
-#define FSTV0910_P1_TSCRC8_ON  0xf5710002
+#define FSTV0910_P1_TSNOSYNCBYTE  0xf5717080
+#define FSTV0910_P1_TSPARITY_ON  0xf5716040
+#define FSTV0910_P1_TSISSYI_ON  0xf5713008
+#define FSTV0910_P1_TSNPD_ON  0xf5712004
+#define FSTV0910_P1_TSCRC8_ON  0xf5711002
 #define FSTV0910_P1_TSDSS_PACKET  0xf5710001
 
 /* P1_TSCFGH */
 #define RSTV0910_P1_TSCFGH  0xf572
-#define FSTV0910_P1_TSFIFO_DVBCI  0xf5720080
-#define FSTV0910_P1_TSFIFO_SERIAL  0xf5720040
-#define FSTV0910_P1_TSFIFO_TEIUPDATE  0xf5720020
-#define FSTV0910_P1_TSFIFO_DUTY50  0xf5720010
-#define FSTV0910_P1_TSFIFO_HSGNLOUT  0xf5720008
-#define FSTV0910_P1_TSFIFO_ERRMODE  0xf5720006
+#define FSTV0910_P1_TSFIFO_DVBCI  0xf5727080
+#define FSTV0910_P1_TSFIFO_SERIAL  0xf5726040
+#define FSTV0910_P1_TSFIFO_TEIUPDATE  0xf5725020
+#define FSTV0910_P1_TSFIFO_DUTY50  0xf5724010
+#define FSTV0910_P1_TSFIFO_HSGNLOUT  0xf5723008
+#define FSTV0910_P1_TSFIFO_ERRMODE  0xf5721006
 #define FSTV0910_P1_RST_HWARE  0xf5720001
 
 /* P1_TSCFGM */
 #define RSTV0910_P1_TSCFGM  0xf573
-#define FSTV0910_P1_TSFIFO_MANSPEED  0xf57300c0
-#define FSTV0910_P1_TSFIFO_PERMDATA  0xf5730020
-#define FSTV0910_P1_TSFIFO_NONEWSGNL  0xf5730010
+#define FSTV0910_P1_TSFIFO_MANSPEED  0xf57360c0
+#define FSTV0910_P1_TSFIFO_PERMDATA  0xf5735020
+#define FSTV0910_P1_TSFIFO_NONEWSGNL  0xf5734010
 #define FSTV0910_P1_TSFIFO_INVDATA  0xf5730001
 
 /* P1_TSCFGL */
 #define RSTV0910_P1_TSCFGL  0xf574
-#define FSTV0910_P1_TSFIFO_BCLKDEL1CK  0xf57400c0
-#define FSTV0910_P1_BCHERROR_MODE  0xf5740030
-#define FSTV0910_P1_TSFIFO_NSGNL2DATA  0xf5740008
-#define FSTV0910_P1_TSFIFO_EMBINDVB  0xf5740004
+#define FSTV0910_P1_TSFIFO_BCLKDEL1CK  0xf57460c0
+#define FSTV0910_P1_BCHERROR_MODE  0xf5744030
+#define FSTV0910_P1_TSFIFO_NSGNL2DATA  0xf5743008
+#define FSTV0910_P1_TSFIFO_EMBINDVB  0xf5742004
 #define FSTV0910_P1_TSFIFO_BITSPEED  0xf5740003
 
 /* P1_TSSYNC */
 #define RSTV0910_P1_TSSYNC  0xf575
-#define FSTV0910_P1_TSFIFO_SYNCMODE  0xf5750018
+#define FSTV0910_P1_TSFIFO_SYNCMODE  0xf5753018
 
 /* P1_TSINSDELH */
 #define RSTV0910_P1_TSINSDELH  0xf576
-#define FSTV0910_P1_TSDEL_SYNCBYTE  0xf5760080
-#define FSTV0910_P1_TSDEL_XXHEADER  0xf5760040
-#define FSTV0910_P1_TSDEL_DATAFIELD  0xf5760010
-#define FSTV0910_P1_TSINSDEL_RSPARITY  0xf5760002
+#define FSTV0910_P1_TSDEL_SYNCBYTE  0xf5767080
+#define FSTV0910_P1_TSDEL_XXHEADER  0xf5766040
+#define FSTV0910_P1_TSDEL_DATAFIELD  0xf5764010
+#define FSTV0910_P1_TSINSDEL_RSPARITY  0xf5761002
 #define FSTV0910_P1_TSINSDEL_CRC8  0xf5760001
 
 /* P1_TSINSDELM */
 #define RSTV0910_P1_TSINSDELM  0xf577
-#define FSTV0910_P1_TSINS_EMODCOD  0xf5770010
-#define FSTV0910_P1_TSINS_TOKEN  0xf5770008
-#define FSTV0910_P1_TSINS_XXXERR  0xf5770004
-#define FSTV0910_P1_TSINS_MATYPE  0xf5770002
+#define FSTV0910_P1_TSINS_EMODCOD  0xf5774010
+#define FSTV0910_P1_TSINS_TOKEN  0xf5773008
+#define FSTV0910_P1_TSINS_XXXERR  0xf5772004
+#define FSTV0910_P1_TSINS_MATYPE  0xf5771002
 #define FSTV0910_P1_TSINS_UPL  0xf5770001
 
 /* P1_TSINSDELL */
 #define RSTV0910_P1_TSINSDELL  0xf578
-#define FSTV0910_P1_TSINS_DFL  0xf5780080
-#define FSTV0910_P1_TSINS_SYNCD  0xf5780040
-#define FSTV0910_P1_TSINS_BLOCLEN  0xf5780020
-#define FSTV0910_P1_TSINS_SIGPCOUNT  0xf5780010
-#define FSTV0910_P1_TSINS_FIFO  0xf5780008
-#define FSTV0910_P1_TSINS_REALPACK  0xf5780004
-#define FSTV0910_P1_TSINS_TSCONFIG  0xf5780002
+#define FSTV0910_P1_TSINS_DFL  0xf5787080
+#define FSTV0910_P1_TSINS_SYNCD  0xf5786040
+#define FSTV0910_P1_TSINS_BLOCLEN  0xf5785020
+#define FSTV0910_P1_TSINS_SIGPCOUNT  0xf5784010
+#define FSTV0910_P1_TSINS_FIFO  0xf5783008
+#define FSTV0910_P1_TSINS_REALPACK  0xf5782004
+#define FSTV0910_P1_TSINS_TSCONFIG  0xf5781002
 #define FSTV0910_P1_TSINS_LATENCY  0xf5780001
 
 /* P1_TSDIVN */
 #define RSTV0910_P1_TSDIVN  0xf579
-#define FSTV0910_P1_TSFIFO_SPEEDMODE  0xf57900c0
+#define FSTV0910_P1_TSFIFO_SPEEDMODE  0xf57960c0
 #define FSTV0910_P1_TSFIFO_RISEOK  0xf5790007
 
 /* P1_TSCFG4 */
 #define RSTV0910_P1_TSCFG4  0xf57a
-#define FSTV0910_P1_TSFIFO_TSSPEEDMODE  0xf57a00c0
+#define FSTV0910_P1_TSFIFO_TSSPEEDMODE  0xf57a60c0
 
 /* P1_TSSPEED */
 #define RSTV0910_P1_TSSPEED  0xf580
@@ -3359,18 +3359,18 @@
 
 /* P1_TSSTATUS */
 #define RSTV0910_P1_TSSTATUS  0xf581
-#define FSTV0910_P1_TSFIFO_LINEOK  0xf5810080
-#define FSTV0910_P1_TSFIFO_ERROR  0xf5810040
-#define FSTV0910_P1_TSFIFO_NOSYNC  0xf5810010
-#define FSTV0910_P1_TSREGUL_ERROR  0xf5810004
+#define FSTV0910_P1_TSFIFO_LINEOK  0xf5817080
+#define FSTV0910_P1_TSFIFO_ERROR  0xf5816040
+#define FSTV0910_P1_TSFIFO_NOSYNC  0xf5814010
+#define FSTV0910_P1_TSREGUL_ERROR  0xf5812004
 #define FSTV0910_P1_DIL_READY  0xf5810001
 
 /* P1_TSSTATUS2 */
 #define RSTV0910_P1_TSSTATUS2  0xf582
-#define FSTV0910_P1_TSFIFO_DEMODSEL  0xf5820080
-#define FSTV0910_P1_TSFIFOSPEED_STORE  0xf5820040
-#define FSTV0910_P1_DILXX_RESET  0xf5820020
-#define FSTV0910_P1_SCRAMBDETECT  0xf5820002
+#define FSTV0910_P1_TSFIFO_DEMODSEL  0xf5827080
+#define FSTV0910_P1_TSFIFOSPEED_STORE  0xf5826040
+#define FSTV0910_P1_DILXX_RESET  0xf5825020
+#define FSTV0910_P1_SCRAMBDETECT  0xf5821002
 
 /* P1_TSBITRATE1 */
 #define RSTV0910_P1_TSBITRATE1  0xf583
@@ -3382,7 +3382,7 @@
 
 /* P1_TSPACKLEN1 */
 #define RSTV0910_P1_TSPACKLEN1  0xf585
-#define FSTV0910_P1_TSFIFO_PACKCPT  0xf58500e0
+#define FSTV0910_P1_TSFIFO_PACKCPT  0xf58550e0
 
 /* P1_TSDLY2 */
 #define RSTV0910_P1_TSDLY2  0xf589
@@ -3402,8 +3402,8 @@
 
 /* P1_TSBUFSTAT2 */
 #define RSTV0910_P1_TSBUFSTAT2  0xf58d
-#define FSTV0910_P1_TSISCR_3BYTES  0xf58d0080
-#define FSTV0910_P1_TSISCR_NEWDATA  0xf58d0040
+#define FSTV0910_P1_TSISCR_3BYTES  0xf58d7080
+#define FSTV0910_P1_TSISCR_NEWDATA  0xf58d6040
 #define FSTV0910_P1_TSISCR_BUFSTAT2  0xf58d003f
 
 /* P1_TSBUFSTAT1 */
@@ -3416,13 +3416,13 @@
 
 /* P1_TSDEBUGL */
 #define RSTV0910_P1_TSDEBUGL  0xf591
-#define FSTV0910_P1_TSFIFO_ERROR_EVNT  0xf5910004
+#define FSTV0910_P1_TSFIFO_ERROR_EVNT  0xf5912004
 #define FSTV0910_P1_TSFIFO_OVERFLOWM  0xf5910001
 
 /* P1_TSDLYSET2 */
 #define RSTV0910_P1_TSDLYSET2  0xf592
-#define FSTV0910_P1_SOFFIFO_OFFSET  0xf59200c0
-#define FSTV0910_P1_HYSTERESIS_THRESHOLD  0xf5920030
+#define FSTV0910_P1_SOFFIFO_OFFSET  0xf59260c0
+#define FSTV0910_P1_HYSTERESIS_THRESHOLD  0xf5924030
 #define FSTV0910_P1_SOFFIFO_SYMBOFFS2  0xf592000f
 
 /* P1_TSDLYSET1 */
@@ -3435,12 +3435,12 @@
 
 /* P1_ERRCTRL1 */
 #define RSTV0910_P1_ERRCTRL1  0xf598
-#define FSTV0910_P1_ERR_SOURCE1  0xf59800f0
+#define FSTV0910_P1_ERR_SOURCE1  0xf59840f0
 #define FSTV0910_P1_NUM_EVENT1  0xf5980007
 
 /* P1_ERRCNT12 */
 #define RSTV0910_P1_ERRCNT12  0xf599
-#define FSTV0910_P1_ERRCNT1_OLDVALUE  0xf5990080
+#define FSTV0910_P1_ERRCNT1_OLDVALUE  0xf5997080
 #define FSTV0910_P1_ERR_CNT12  0xf599007f
 
 /* P1_ERRCNT11 */
@@ -3453,12 +3453,12 @@
 
 /* P1_ERRCTRL2 */
 #define RSTV0910_P1_ERRCTRL2  0xf59c
-#define FSTV0910_P1_ERR_SOURCE2  0xf59c00f0
+#define FSTV0910_P1_ERR_SOURCE2  0xf59c40f0
 #define FSTV0910_P1_NUM_EVENT2  0xf59c0007
 
 /* P1_ERRCNT22 */
 #define RSTV0910_P1_ERRCNT22  0xf59d
-#define FSTV0910_P1_ERRCNT2_OLDVALUE  0xf59d0080
+#define FSTV0910_P1_ERRCNT2_OLDVALUE  0xf59d7080
 #define FSTV0910_P1_ERR_CNT22  0xf59d007f
 
 /* P1_ERRCNT21 */
@@ -3471,39 +3471,39 @@
 
 /* P1_FECSPY */
 #define RSTV0910_P1_FECSPY  0xf5a0
-#define FSTV0910_P1_SPY_ENABLE  0xf5a00080
-#define FSTV0910_P1_NO_SYNCBYTE  0xf5a00040
-#define FSTV0910_P1_SERIAL_MODE  0xf5a00020
-#define FSTV0910_P1_UNUSUAL_PACKET  0xf5a00010
-#define FSTV0910_P1_BERMETER_DATAMODE  0xf5a0000c
-#define FSTV0910_P1_BERMETER_LMODE  0xf5a00002
+#define FSTV0910_P1_SPY_ENABLE  0xf5a07080
+#define FSTV0910_P1_NO_SYNCBYTE  0xf5a06040
+#define FSTV0910_P1_SERIAL_MODE  0xf5a05020
+#define FSTV0910_P1_UNUSUAL_PACKET  0xf5a04010
+#define FSTV0910_P1_BERMETER_DATAMODE  0xf5a0200c
+#define FSTV0910_P1_BERMETER_LMODE  0xf5a01002
 #define FSTV0910_P1_BERMETER_RESET  0xf5a00001
 
 /* P1_FSPYCFG */
 #define RSTV0910_P1_FSPYCFG  0xf5a1
-#define FSTV0910_P1_FECSPY_INPUT  0xf5a100c0
-#define FSTV0910_P1_RST_ON_ERROR  0xf5a10020
-#define FSTV0910_P1_ONE_SHOT  0xf5a10010
-#define FSTV0910_P1_I2C_MODE  0xf5a1000c
+#define FSTV0910_P1_FECSPY_INPUT  0xf5a160c0
+#define FSTV0910_P1_RST_ON_ERROR  0xf5a15020
+#define FSTV0910_P1_ONE_SHOT  0xf5a14010
+#define FSTV0910_P1_I2C_MODE  0xf5a1200c
 #define FSTV0910_P1_SPY_HYSTERESIS  0xf5a10003
 
 /* P1_FSPYDATA */
 #define RSTV0910_P1_FSPYDATA  0xf5a2
-#define FSTV0910_P1_SPY_STUFFING  0xf5a20080
-#define FSTV0910_P1_SPY_CNULLPKT  0xf5a20020
+#define FSTV0910_P1_SPY_STUFFING  0xf5a27080
+#define FSTV0910_P1_SPY_CNULLPKT  0xf5a25020
 #define FSTV0910_P1_SPY_OUTDATA_MODE  0xf5a2001f
 
 /* P1_FSPYOUT */
 #define RSTV0910_P1_FSPYOUT  0xf5a3
-#define FSTV0910_P1_FSPY_DIRECT  0xf5a30080
+#define FSTV0910_P1_FSPY_DIRECT  0xf5a37080
 #define FSTV0910_P1_STUFF_MODE  0xf5a30007
 
 /* P1_FSTATUS */
 #define RSTV0910_P1_FSTATUS  0xf5a4
-#define FSTV0910_P1_SPY_ENDSIM  0xf5a40080
-#define FSTV0910_P1_VALID_SIM  0xf5a40040
-#define FSTV0910_P1_FOUND_SIGNAL  0xf5a40020
-#define FSTV0910_P1_DSS_SYNCBYTE  0xf5a40010
+#define FSTV0910_P1_SPY_ENDSIM  0xf5a47080
+#define FSTV0910_P1_VALID_SIM  0xf5a46040
+#define FSTV0910_P1_FOUND_SIGNAL  0xf5a45020
+#define FSTV0910_P1_DSS_SYNCBYTE  0xf5a44010
 #define FSTV0910_P1_RESULT_STATE  0xf5a4000f
 
 /* P1_FBERCPT4 */
@@ -3540,8 +3540,8 @@
 
 /* P1_FSPYBER */
 #define RSTV0910_P1_FSPYBER  0xf5b2
-#define FSTV0910_P1_FSPYBER_SYNCBYTE  0xf5b20010
-#define FSTV0910_P1_FSPYBER_UNSYNC  0xf5b20008
+#define FSTV0910_P1_FSPYBER_SYNCBYTE  0xf5b24010
+#define FSTV0910_P1_FSPYBER_UNSYNC  0xf5b23008
 #define FSTV0910_P1_FSPYBER_CTIME  0xf5b20007
 
 /* P1_SFERROR */
@@ -3550,60 +3550,60 @@
 
 /* P1_SFECSTATUS */
 #define RSTV0910_P1_SFECSTATUS  0xf5c3
-#define FSTV0910_P1_SFEC_ON  0xf5c30080
-#define FSTV0910_P1_SFEC_OFF  0xf5c30040
-#define FSTV0910_P1_LOCKEDSFEC  0xf5c30008
-#define FSTV0910_P1_SFEC_DELOCK  0xf5c30004
-#define FSTV0910_P1_SFEC_DEMODSEL  0xf5c30002
+#define FSTV0910_P1_SFEC_ON  0xf5c37080
+#define FSTV0910_P1_SFEC_OFF  0xf5c36040
+#define FSTV0910_P1_LOCKEDSFEC  0xf5c33008
+#define FSTV0910_P1_SFEC_DELOCK  0xf5c32004
+#define FSTV0910_P1_SFEC_DEMODSEL  0xf5c31002
 #define FSTV0910_P1_SFEC_OVFON  0xf5c30001
 
 /* P1_SFKDIV12 */
 #define RSTV0910_P1_SFKDIV12  0xf5c4
-#define FSTV0910_P1_SFECKDIV12_MAN  0xf5c40080
+#define FSTV0910_P1_SFECKDIV12_MAN  0xf5c47080
 
 /* P1_SFKDIV23 */
 #define RSTV0910_P1_SFKDIV23  0xf5c5
-#define FSTV0910_P1_SFECKDIV23_MAN  0xf5c50080
+#define FSTV0910_P1_SFECKDIV23_MAN  0xf5c57080
 
 /* P1_SFKDIV34 */
 #define RSTV0910_P1_SFKDIV34  0xf5c6
-#define FSTV0910_P1_SFECKDIV34_MAN  0xf5c60080
+#define FSTV0910_P1_SFECKDIV34_MAN  0xf5c67080
 
 /* P1_SFKDIV56 */
 #define RSTV0910_P1_SFKDIV56  0xf5c7
-#define FSTV0910_P1_SFECKDIV56_MAN  0xf5c70080
+#define FSTV0910_P1_SFECKDIV56_MAN  0xf5c77080
 
 /* P1_SFKDIV67 */
 #define RSTV0910_P1_SFKDIV67  0xf5c8
-#define FSTV0910_P1_SFECKDIV67_MAN  0xf5c80080
+#define FSTV0910_P1_SFECKDIV67_MAN  0xf5c87080
 
 /* P1_SFKDIV78 */
 #define RSTV0910_P1_SFKDIV78  0xf5c9
-#define FSTV0910_P1_SFECKDIV78_MAN  0xf5c90080
+#define FSTV0910_P1_SFECKDIV78_MAN  0xf5c97080
 
 /* P1_SFSTATUS */
 #define RSTV0910_P1_SFSTATUS  0xf5cc
-#define FSTV0910_P1_SFEC_LINEOK  0xf5cc0080
-#define FSTV0910_P1_SFEC_ERROR  0xf5cc0040
-#define FSTV0910_P1_SFEC_DATA7  0xf5cc0020
-#define FSTV0910_P1_SFEC_PKTDNBRFAIL  0xf5cc0010
-#define FSTV0910_P1_TSSFEC_DEMODSEL  0xf5cc0008
-#define FSTV0910_P1_SFEC_NOSYNC  0xf5cc0004
-#define FSTV0910_P1_SFEC_UNREGULA  0xf5cc0002
+#define FSTV0910_P1_SFEC_LINEOK  0xf5cc7080
+#define FSTV0910_P1_SFEC_ERROR  0xf5cc6040
+#define FSTV0910_P1_SFEC_DATA7  0xf5cc5020
+#define FSTV0910_P1_SFEC_PKTDNBRFAIL  0xf5cc4010
+#define FSTV0910_P1_TSSFEC_DEMODSEL  0xf5cc3008
+#define FSTV0910_P1_SFEC_NOSYNC  0xf5cc2004
+#define FSTV0910_P1_SFEC_UNREGULA  0xf5cc1002
 #define FSTV0910_P1_SFEC_READY  0xf5cc0001
 
 /* P1_SFDLYSET2 */
 #define RSTV0910_P1_SFDLYSET2  0xf5d0
-#define FSTV0910_P1_SFEC_DISABLE  0xf5d00002
+#define FSTV0910_P1_SFEC_DISABLE  0xf5d01002
 
 /* P1_SFERRCTRL */
 #define RSTV0910_P1_SFERRCTRL  0xf5d8
-#define FSTV0910_P1_SFEC_ERR_SOURCE  0xf5d800f0
+#define FSTV0910_P1_SFEC_ERR_SOURCE  0xf5d840f0
 #define FSTV0910_P1_SFEC_NUM_EVENT  0xf5d80007
 
 /* P1_SFERRCNT2 */
 #define RSTV0910_P1_SFERRCNT2  0xf5d9
-#define FSTV0910_P1_SFERRC_OLDVALUE  0xf5d90080
+#define FSTV0910_P1_SFERRC_OLDVALUE  0xf5d97080
 #define FSTV0910_P1_SFEC_ERR_CNT2  0xf5d9007f
 
 /* P1_SFERRCNT1 */
@@ -3616,66 +3616,66 @@
 
 /* RCCFG2 */
 #define RSTV0910_RCCFG2  0xf600
-#define FSTV0910_TSRCFIFO_DVBCI  0xf6000080
-#define FSTV0910_TSRCFIFO_SERIAL  0xf6000040
-#define FSTV0910_TSRCFIFO_DISABLE  0xf6000020
-#define FSTV0910_TSFIFO_2TORC  0xf6000010
-#define FSTV0910_TSRCFIFO_HSGNLOUT  0xf6000008
-#define FSTV0910_TSRCFIFO_ERRMODE  0xf6000006
+#define FSTV0910_TSRCFIFO_DVBCI  0xf6007080
+#define FSTV0910_TSRCFIFO_SERIAL  0xf6006040
+#define FSTV0910_TSRCFIFO_DISABLE  0xf6005020
+#define FSTV0910_TSFIFO_2TORC  0xf6004010
+#define FSTV0910_TSRCFIFO_HSGNLOUT  0xf6003008
+#define FSTV0910_TSRCFIFO_ERRMODE  0xf6001006
 
 /* RCCFG1 */
 #define RSTV0910_RCCFG1  0xf601
-#define FSTV0910_TSRCFIFO_MANSPEED  0xf60100c0
-#define FSTV0910_TSRCFIFO_PERMDATA  0xf6010020
-#define FSTV0910_TSRCFIFO_NONEWSGNL  0xf6010010
+#define FSTV0910_TSRCFIFO_MANSPEED  0xf60160c0
+#define FSTV0910_TSRCFIFO_PERMDATA  0xf6015020
+#define FSTV0910_TSRCFIFO_NONEWSGNL  0xf6014010
 #define FSTV0910_TSRCFIFO_INVDATA  0xf6010001
 
 /* RCCFG0 */
 #define RSTV0910_RCCFG0  0xf602
-#define FSTV0910_TSRCFIFO_BCLKDEL1CK  0xf60200c0
-#define FSTV0910_TSRCFIFO_DUTY50  0xf6020010
-#define FSTV0910_TSRCFIFO_NSGNL2DATA  0xf6020008
-#define FSTV0910_TSRCFIFO_NPDSGNL  0xf6020004
+#define FSTV0910_TSRCFIFO_BCLKDEL1CK  0xf60260c0
+#define FSTV0910_TSRCFIFO_DUTY50  0xf6024010
+#define FSTV0910_TSRCFIFO_NSGNL2DATA  0xf6023008
+#define FSTV0910_TSRCFIFO_NPDSGNL  0xf6022004
 
 /* RCINSDEL2 */
 #define RSTV0910_RCINSDEL2  0xf603
-#define FSTV0910_TSRCDEL_SYNCBYTE  0xf6030080
-#define FSTV0910_TSRCDEL_XXHEADER  0xf6030040
-#define FSTV0910_TSRCDEL_BBHEADER  0xf6030020
-#define FSTV0910_TSRCDEL_DATAFIELD  0xf6030010
-#define FSTV0910_TSRCINSDEL_ISCR  0xf6030008
-#define FSTV0910_TSRCINSDEL_NPD  0xf6030004
-#define FSTV0910_TSRCINSDEL_RSPARITY  0xf6030002
+#define FSTV0910_TSRCDEL_SYNCBYTE  0xf6037080
+#define FSTV0910_TSRCDEL_XXHEADER  0xf6036040
+#define FSTV0910_TSRCDEL_BBHEADER  0xf6035020
+#define FSTV0910_TSRCDEL_DATAFIELD  0xf6034010
+#define FSTV0910_TSRCINSDEL_ISCR  0xf6033008
+#define FSTV0910_TSRCINSDEL_NPD  0xf6032004
+#define FSTV0910_TSRCINSDEL_RSPARITY  0xf6031002
 #define FSTV0910_TSRCINSDEL_CRC8  0xf6030001
 
 /* RCINSDEL1 */
 #define RSTV0910_RCINSDEL1  0xf604
-#define FSTV0910_TSRCINS_BBPADDING  0xf6040080
-#define FSTV0910_TSRCINS_BCHFEC  0xf6040040
-#define FSTV0910_TSRCINS_EMODCOD  0xf6040010
-#define FSTV0910_TSRCINS_TOKEN  0xf6040008
-#define FSTV0910_TSRCINS_XXXERR  0xf6040004
-#define FSTV0910_TSRCINS_MATYPE  0xf6040002
+#define FSTV0910_TSRCINS_BBPADDING  0xf6047080
+#define FSTV0910_TSRCINS_BCHFEC  0xf6046040
+#define FSTV0910_TSRCINS_EMODCOD  0xf6044010
+#define FSTV0910_TSRCINS_TOKEN  0xf6043008
+#define FSTV0910_TSRCINS_XXXERR  0xf6042004
+#define FSTV0910_TSRCINS_MATYPE  0xf6041002
 #define FSTV0910_TSRCINS_UPL  0xf6040001
 
 /* RCINSDEL0 */
 #define RSTV0910_RCINSDEL0  0xf605
-#define FSTV0910_TSRCINS_DFL  0xf6050080
-#define FSTV0910_TSRCINS_SYNCD  0xf6050040
-#define FSTV0910_TSRCINS_BLOCLEN  0xf6050020
-#define FSTV0910_TSRCINS_SIGPCOUNT  0xf6050010
-#define FSTV0910_TSRCINS_FIFO  0xf6050008
-#define FSTV0910_TSRCINS_REALPACK  0xf6050004
-#define FSTV0910_TSRCINS_TSCONFIG  0xf6050002
+#define FSTV0910_TSRCINS_DFL  0xf6057080
+#define FSTV0910_TSRCINS_SYNCD  0xf6056040
+#define FSTV0910_TSRCINS_BLOCLEN  0xf6055020
+#define FSTV0910_TSRCINS_SIGPCOUNT  0xf6054010
+#define FSTV0910_TSRCINS_FIFO  0xf6053008
+#define FSTV0910_TSRCINS_REALPACK  0xf6052004
+#define FSTV0910_TSRCINS_TSCONFIG  0xf6051002
 #define FSTV0910_TSRCINS_LATENCY  0xf6050001
 
 /* RCSTATUS */
 #define RSTV0910_RCSTATUS  0xf606
-#define FSTV0910_TSRCFIFO_LINEOK  0xf6060080
-#define FSTV0910_TSRCFIFO_ERROR  0xf6060040
-#define FSTV0910_TSRCREGUL_ERROR  0xf6060010
-#define FSTV0910_TSRCFIFO_DEMODSEL  0xf6060008
-#define FSTV0910_TSRCFIFOSPEED_STORE  0xf6060004
+#define FSTV0910_TSRCFIFO_LINEOK  0xf6067080
+#define FSTV0910_TSRCFIFO_ERROR  0xf6066040
+#define FSTV0910_TSRCREGUL_ERROR  0xf6064010
+#define FSTV0910_TSRCFIFO_DEMODSEL  0xf6063008
+#define FSTV0910_TSRCFIFOSPEED_STORE  0xf6062004
 #define FSTV0910_TSRCSPEED_IMPOSSIBLE  0xf6060001
 
 /* RCSPEED */
@@ -3684,47 +3684,47 @@
 
 /* TSGENERAL */
 #define RSTV0910_TSGENERAL  0xf630
-#define FSTV0910_TSFIFO_DISTS2PAR  0xf6300040
-#define FSTV0910_MUXSTREAM_OUTMODE  0xf6300008
-#define FSTV0910_TSFIFO_PERMPARAL  0xf6300006
+#define FSTV0910_TSFIFO_DISTS2PAR  0xf6306040
+#define FSTV0910_MUXSTREAM_OUTMODE  0xf6303008
+#define FSTV0910_TSFIFO_PERMPARAL  0xf6301006
 
 /* P1_DISIRQCFG */
 #define RSTV0910_P1_DISIRQCFG  0xf700
-#define FSTV0910_P1_ENRXEND  0xf7000040
-#define FSTV0910_P1_ENRXFIFO8B  0xf7000020
-#define FSTV0910_P1_ENTRFINISH  0xf7000010
-#define FSTV0910_P1_ENTIMEOUT  0xf7000008
-#define FSTV0910_P1_ENTXEND  0xf7000004
-#define FSTV0910_P1_ENTXFIFO64B  0xf7000002
+#define FSTV0910_P1_ENRXEND  0xf7006040
+#define FSTV0910_P1_ENRXFIFO8B  0xf7005020
+#define FSTV0910_P1_ENTRFINISH  0xf7004010
+#define FSTV0910_P1_ENTIMEOUT  0xf7003008
+#define FSTV0910_P1_ENTXEND  0xf7002004
+#define FSTV0910_P1_ENTXFIFO64B  0xf7001002
 #define FSTV0910_P1_ENGAPBURST  0xf7000001
 
 /* P1_DISIRQSTAT */
 #define RSTV0910_P1_DISIRQSTAT  0xf701
-#define FSTV0910_P1_IRQRXEND  0xf7010040
-#define FSTV0910_P1_IRQRXFIFO8B  0xf7010020
-#define FSTV0910_P1_IRQTRFINISH  0xf7010010
-#define FSTV0910_P1_IRQTIMEOUT  0xf7010008
-#define FSTV0910_P1_IRQTXEND  0xf7010004
-#define FSTV0910_P1_IRQTXFIFO64B  0xf7010002
+#define FSTV0910_P1_IRQRXEND  0xf7016040
+#define FSTV0910_P1_IRQRXFIFO8B  0xf7015020
+#define FSTV0910_P1_IRQTRFINISH  0xf7014010
+#define FSTV0910_P1_IRQTIMEOUT  0xf7013008
+#define FSTV0910_P1_IRQTXEND  0xf7012004
+#define FSTV0910_P1_IRQTXFIFO64B  0xf7011002
 #define FSTV0910_P1_IRQGAPBURST  0xf7010001
 
 /* P1_DISTXCFG */
 #define RSTV0910_P1_DISTXCFG  0xf702
-#define FSTV0910_P1_DISTX_RESET  0xf7020080
-#define FSTV0910_P1_TIM_OFF  0xf7020040
-#define FSTV0910_P1_TIM_CMD  0xf7020030
-#define FSTV0910_P1_ENVELOP  0xf7020008
-#define FSTV0910_P1_DIS_PRECHARGE  0xf7020004
+#define FSTV0910_P1_DISTX_RESET  0xf7027080
+#define FSTV0910_P1_TIM_OFF  0xf7026040
+#define FSTV0910_P1_TIM_CMD  0xf7024030
+#define FSTV0910_P1_ENVELOP  0xf7023008
+#define FSTV0910_P1_DIS_PRECHARGE  0xf7022004
 #define FSTV0910_P1_DISEQC_MODE  0xf7020003
 
 /* P1_DISTXSTATUS */
 #define RSTV0910_P1_DISTXSTATUS  0xf703
-#define FSTV0910_P1_TX_FIFO_FULL  0xf7030040
-#define FSTV0910_P1_TX_IDLE  0xf7030020
-#define FSTV0910_P1_GAP_BURST  0xf7030010
-#define FSTV0910_P1_TX_FIFO64B  0xf7030008
-#define FSTV0910_P1_TX_END  0xf7030004
-#define FSTV0910_P1_TR_TIMEOUT  0xf7030002
+#define FSTV0910_P1_TX_FIFO_FULL  0xf7036040
+#define FSTV0910_P1_TX_IDLE  0xf7035020
+#define FSTV0910_P1_GAP_BURST  0xf7034010
+#define FSTV0910_P1_TX_FIFO64B  0xf7033008
+#define FSTV0910_P1_TX_END  0xf7032004
+#define FSTV0910_P1_TR_TIMEOUT  0xf7031002
 #define FSTV0910_P1_TR_FINISH  0xf7030001
 
 /* P1_DISTXBYTES */
@@ -3741,7 +3741,7 @@
 
 /* P1_DISTIMEOCFG */
 #define RSTV0910_P1_DISTIMEOCFG  0xf708
-#define FSTV0910_P1_RXCHOICE  0xf7080006
+#define FSTV0910_P1_RXCHOICE  0xf7081006
 #define FSTV0910_P1_TIMEOUT_OFF  0xf7080001
 
 /* P1_DISTIMEOUT */
@@ -3750,30 +3750,30 @@
 
 /* P1_DISRXCFG */
 #define RSTV0910_P1_DISRXCFG  0xf70a
-#define FSTV0910_P1_DISRX_RESET  0xf70a0080
-#define FSTV0910_P1_EXTENVELOP  0xf70a0040
-#define FSTV0910_P1_PINSELECT  0xf70a0038
-#define FSTV0910_P1_IGNORE_SHORT22K  0xf70a0004
-#define FSTV0910_P1_SIGNED_RXIN  0xf70a0002
+#define FSTV0910_P1_DISRX_RESET  0xf70a7080
+#define FSTV0910_P1_EXTENVELOP  0xf70a6040
+#define FSTV0910_P1_PINSELECT  0xf70a3038
+#define FSTV0910_P1_IGNORE_SHORT22K  0xf70a2004
+#define FSTV0910_P1_SIGNED_RXIN  0xf70a1002
 #define FSTV0910_P1_DISRX_ON  0xf70a0001
 
 /* P1_DISRXSTAT1 */
 #define RSTV0910_P1_DISRXSTAT1  0xf70b
-#define FSTV0910_P1_RXEND  0xf70b0080
-#define FSTV0910_P1_RXACTIVE  0xf70b0040
-#define FSTV0910_P1_RXDETECT  0xf70b0020
-#define FSTV0910_P1_CONTTONE  0xf70b0010
-#define FSTV0910_P1_8BFIFOREADY  0xf70b0008
-#define FSTV0910_P1_FIFOEMPTY  0xf70b0004
+#define FSTV0910_P1_RXEND  0xf70b7080
+#define FSTV0910_P1_RXACTIVE  0xf70b6040
+#define FSTV0910_P1_RXDETECT  0xf70b5020
+#define FSTV0910_P1_CONTTONE  0xf70b4010
+#define FSTV0910_P1_8BFIFOREADY  0xf70b3008
+#define FSTV0910_P1_FIFOEMPTY  0xf70b2004
 
 /* P1_DISRXSTAT0 */
 #define RSTV0910_P1_DISRXSTAT0  0xf70c
-#define FSTV0910_P1_RXFAIL  0xf70c0080
-#define FSTV0910_P1_FIFOPFAIL  0xf70c0040
-#define FSTV0910_P1_RXNONBYTE  0xf70c0020
-#define FSTV0910_P1_FIFOOVF  0xf70c0010
-#define FSTV0910_P1_SHORT22K  0xf70c0008
-#define FSTV0910_P1_RXMSGLOST  0xf70c0004
+#define FSTV0910_P1_RXFAIL  0xf70c7080
+#define FSTV0910_P1_FIFOPFAIL  0xf70c6040
+#define FSTV0910_P1_RXNONBYTE  0xf70c5020
+#define FSTV0910_P1_FIFOOVF  0xf70c4010
+#define FSTV0910_P1_SHORT22K  0xf70c3008
+#define FSTV0910_P1_RXMSGLOST  0xf70c2004
 
 /* P1_DISRXBYTES */
 #define RSTV0910_P1_DISRXBYTES  0xf70d
@@ -3825,41 +3825,41 @@
 
 /* P2_DISIRQCFG */
 #define RSTV0910_P2_DISIRQCFG  0xf740
-#define FSTV0910_P2_ENRXEND  0xf7400040
-#define FSTV0910_P2_ENRXFIFO8B  0xf7400020
-#define FSTV0910_P2_ENTRFINISH  0xf7400010
-#define FSTV0910_P2_ENTIMEOUT  0xf7400008
-#define FSTV0910_P2_ENTXEND  0xf7400004
-#define FSTV0910_P2_ENTXFIFO64B  0xf7400002
+#define FSTV0910_P2_ENRXEND  0xf7406040
+#define FSTV0910_P2_ENRXFIFO8B  0xf7405020
+#define FSTV0910_P2_ENTRFINISH  0xf7404010
+#define FSTV0910_P2_ENTIMEOUT  0xf7403008
+#define FSTV0910_P2_ENTXEND  0xf7402004
+#define FSTV0910_P2_ENTXFIFO64B  0xf7401002
 #define FSTV0910_P2_ENGAPBURST  0xf7400001
 
 /* P2_DISIRQSTAT */
 #define RSTV0910_P2_DISIRQSTAT  0xf741
-#define FSTV0910_P2_IRQRXEND  0xf7410040
-#define FSTV0910_P2_IRQRXFIFO8B  0xf7410020
-#define FSTV0910_P2_IRQTRFINISH  0xf7410010
-#define FSTV0910_P2_IRQTIMEOUT  0xf7410008
-#define FSTV0910_P2_IRQTXEND  0xf7410004
-#define FSTV0910_P2_IRQTXFIFO64B  0xf7410002
+#define FSTV0910_P2_IRQRXEND  0xf7416040
+#define FSTV0910_P2_IRQRXFIFO8B  0xf7415020
+#define FSTV0910_P2_IRQTRFINISH  0xf7414010
+#define FSTV0910_P2_IRQTIMEOUT  0xf7413008
+#define FSTV0910_P2_IRQTXEND  0xf7412004
+#define FSTV0910_P2_IRQTXFIFO64B  0xf7411002
 #define FSTV0910_P2_IRQGAPBURST  0xf7410001
 
 /* P2_DISTXCFG */
 #define RSTV0910_P2_DISTXCFG  0xf742
-#define FSTV0910_P2_DISTX_RESET  0xf7420080
-#define FSTV0910_P2_TIM_OFF  0xf7420040
-#define FSTV0910_P2_TIM_CMD  0xf7420030
-#define FSTV0910_P2_ENVELOP  0xf7420008
-#define FSTV0910_P2_DIS_PRECHARGE  0xf7420004
+#define FSTV0910_P2_DISTX_RESET  0xf7427080
+#define FSTV0910_P2_TIM_OFF  0xf7426040
+#define FSTV0910_P2_TIM_CMD  0xf7424030
+#define FSTV0910_P2_ENVELOP  0xf7423008
+#define FSTV0910_P2_DIS_PRECHARGE  0xf7422004
 #define FSTV0910_P2_DISEQC_MODE  0xf7420003
 
 /* P2_DISTXSTATUS */
 #define RSTV0910_P2_DISTXSTATUS  0xf743
-#define FSTV0910_P2_TX_FIFO_FULL  0xf7430040
-#define FSTV0910_P2_TX_IDLE  0xf7430020
-#define FSTV0910_P2_GAP_BURST  0xf7430010
-#define FSTV0910_P2_TX_FIFO64B  0xf7430008
-#define FSTV0910_P2_TX_END  0xf7430004
-#define FSTV0910_P2_TR_TIMEOUT  0xf7430002
+#define FSTV0910_P2_TX_FIFO_FULL  0xf7436040
+#define FSTV0910_P2_TX_IDLE  0xf7435020
+#define FSTV0910_P2_GAP_BURST  0xf7434010
+#define FSTV0910_P2_TX_FIFO64B  0xf7433008
+#define FSTV0910_P2_TX_END  0xf7432004
+#define FSTV0910_P2_TR_TIMEOUT  0xf7431002
 #define FSTV0910_P2_TR_FINISH  0xf7430001
 
 /* P2_DISTXBYTES */
@@ -3876,7 +3876,7 @@
 
 /* P2_DISTIMEOCFG */
 #define RSTV0910_P2_DISTIMEOCFG  0xf748
-#define FSTV0910_P2_RXCHOICE  0xf7480006
+#define FSTV0910_P2_RXCHOICE  0xf7481006
 #define FSTV0910_P2_TIMEOUT_OFF  0xf7480001
 
 /* P2_DISTIMEOUT */
@@ -3885,30 +3885,30 @@
 
 /* P2_DISRXCFG */
 #define RSTV0910_P2_DISRXCFG  0xf74a
-#define FSTV0910_P2_DISRX_RESET  0xf74a0080
-#define FSTV0910_P2_EXTENVELOP  0xf74a0040
-#define FSTV0910_P2_PINSELECT  0xf74a0038
-#define FSTV0910_P2_IGNORE_SHORT22K  0xf74a0004
-#define FSTV0910_P2_SIGNED_RXIN  0xf74a0002
+#define FSTV0910_P2_DISRX_RESET  0xf74a7080
+#define FSTV0910_P2_EXTENVELOP  0xf74a6040
+#define FSTV0910_P2_PINSELECT  0xf74a3038
+#define FSTV0910_P2_IGNORE_SHORT22K  0xf74a2004
+#define FSTV0910_P2_SIGNED_RXIN  0xf74a1002
 #define FSTV0910_P2_DISRX_ON  0xf74a0001
 
 /* P2_DISRXSTAT1 */
 #define RSTV0910_P2_DISRXSTAT1  0xf74b
-#define FSTV0910_P2_RXEND  0xf74b0080
-#define FSTV0910_P2_RXACTIVE  0xf74b0040
-#define FSTV0910_P2_RXDETECT  0xf74b0020
-#define FSTV0910_P2_CONTTONE  0xf74b0010
-#define FSTV0910_P2_8BFIFOREADY  0xf74b0008
-#define FSTV0910_P2_FIFOEMPTY  0xf74b0004
+#define FSTV0910_P2_RXEND  0xf74b7080
+#define FSTV0910_P2_RXACTIVE  0xf74b6040
+#define FSTV0910_P2_RXDETECT  0xf74b5020
+#define FSTV0910_P2_CONTTONE  0xf74b4010
+#define FSTV0910_P2_8BFIFOREADY  0xf74b3008
+#define FSTV0910_P2_FIFOEMPTY  0xf74b2004
 
 /* P2_DISRXSTAT0 */
 #define RSTV0910_P2_DISRXSTAT0  0xf74c
-#define FSTV0910_P2_RXFAIL  0xf74c0080
-#define FSTV0910_P2_FIFOPFAIL  0xf74c0040
-#define FSTV0910_P2_RXNONBYTE  0xf74c0020
-#define FSTV0910_P2_FIFOOVF  0xf74c0010
-#define FSTV0910_P2_SHORT22K  0xf74c0008
-#define FSTV0910_P2_RXMSGLOST  0xf74c0004
+#define FSTV0910_P2_RXFAIL  0xf74c7080
+#define FSTV0910_P2_FIFOPFAIL  0xf74c6040
+#define FSTV0910_P2_RXNONBYTE  0xf74c5020
+#define FSTV0910_P2_FIFOOVF  0xf74c4010
+#define FSTV0910_P2_SHORT22K  0xf74c3008
+#define FSTV0910_P2_RXMSGLOST  0xf74c2004
 
 /* P2_DISRXBYTES */
 #define RSTV0910_P2_DISRXBYTES  0xf74d
@@ -4168,75 +4168,75 @@
 
 /* SELSATUR6 */
 #define RSTV0910_SELSATUR6  0xfa34
-#define FSTV0910_SSAT_SF27  0xfa340008
-#define FSTV0910_SSAT_SF26  0xfa340004
-#define FSTV0910_SSAT_SF25  0xfa340002
+#define FSTV0910_SSAT_SF27  0xfa343008
+#define FSTV0910_SSAT_SF26  0xfa342004
+#define FSTV0910_SSAT_SF25  0xfa341002
 #define FSTV0910_SSAT_SF24  0xfa340001
 
 /* SELSATUR5 */
 #define RSTV0910_SELSATUR5  0xfa35
-#define FSTV0910_SSAT_SF22  0xfa350080
-#define FSTV0910_SSAT_SF21  0xfa350040
-#define FSTV0910_SSAT_SF20  0xfa350020
-#define FSTV0910_SSAT_SF19  0xfa350010
-#define FSTV0910_SSAT_SF18  0xfa350008
-#define FSTV0910_SSAT_SF16  0xfa350004
-#define FSTV0910_SSAT_SF15  0xfa350002
+#define FSTV0910_SSAT_SF22  0xfa357080
+#define FSTV0910_SSAT_SF21  0xfa356040
+#define FSTV0910_SSAT_SF20  0xfa355020
+#define FSTV0910_SSAT_SF19  0xfa354010
+#define FSTV0910_SSAT_SF18  0xfa353008
+#define FSTV0910_SSAT_SF16  0xfa352004
+#define FSTV0910_SSAT_SF15  0xfa351002
 #define FSTV0910_SSAT_SF14  0xfa350001
 
 /* SELSATUR4 */
 #define RSTV0910_SELSATUR4  0xfa36
-#define FSTV0910_SSAT_SF13  0xfa360080
-#define FSTV0910_SSAT_SF12  0xfa360040
-#define FSTV0910_SSAT_SF10  0xfa360020
-#define FSTV0910_SSAT_SF9  0xfa360010
-#define FSTV0910_SSAT_SF8  0xfa360008
-#define FSTV0910_SSAT_SF7  0xfa360004
-#define FSTV0910_SSAT_SF6  0xfa360002
+#define FSTV0910_SSAT_SF13  0xfa367080
+#define FSTV0910_SSAT_SF12  0xfa366040
+#define FSTV0910_SSAT_SF10  0xfa365020
+#define FSTV0910_SSAT_SF9  0xfa364010
+#define FSTV0910_SSAT_SF8  0xfa363008
+#define FSTV0910_SSAT_SF7  0xfa362004
+#define FSTV0910_SSAT_SF6  0xfa361002
 #define FSTV0910_SSAT_SF5  0xfa360001
 
 /* SELSATUR3 */
 #define RSTV0910_SELSATUR3  0xfa37
-#define FSTV0910_SSAT_SF4  0xfa370080
-#define FSTV0910_SSAT_SF3  0xfa370040
-#define FSTV0910_SSAT_SF2  0xfa370020
-#define FSTV0910_SSAT_SF1  0xfa370010
-#define FSTV0910_SSAT_NF28  0xfa370008
-#define FSTV0910_SSAT_NF27  0xfa370004
-#define FSTV0910_SSAT_NF26  0xfa370002
+#define FSTV0910_SSAT_SF4  0xfa377080
+#define FSTV0910_SSAT_SF3  0xfa376040
+#define FSTV0910_SSAT_SF2  0xfa375020
+#define FSTV0910_SSAT_SF1  0xfa374010
+#define FSTV0910_SSAT_NF28  0xfa373008
+#define FSTV0910_SSAT_NF27  0xfa372004
+#define FSTV0910_SSAT_NF26  0xfa371002
 #define FSTV0910_SSAT_NF25  0xfa370001
 
 /* SELSATUR2 */
 #define RSTV0910_SELSATUR2  0xfa38
-#define FSTV0910_SSAT_NF24  0xfa380080
-#define FSTV0910_SSAT_NF23  0xfa380040
-#define FSTV0910_SSAT_NF22  0xfa380020
-#define FSTV0910_SSAT_NF21  0xfa380010
-#define FSTV0910_SSAT_NF20  0xfa380008
-#define FSTV0910_SSAT_NF19  0xfa380004
-#define FSTV0910_SSAT_NF18  0xfa380002
+#define FSTV0910_SSAT_NF24  0xfa387080
+#define FSTV0910_SSAT_NF23  0xfa386040
+#define FSTV0910_SSAT_NF22  0xfa385020
+#define FSTV0910_SSAT_NF21  0xfa384010
+#define FSTV0910_SSAT_NF20  0xfa383008
+#define FSTV0910_SSAT_NF19  0xfa382004
+#define FSTV0910_SSAT_NF18  0xfa381002
 #define FSTV0910_SSAT_NF17  0xfa380001
 
 /* SELSATUR1 */
 #define RSTV0910_SELSATUR1  0xfa39
-#define FSTV0910_SSAT_NF16  0xfa390080
-#define FSTV0910_SSAT_NF15  0xfa390040
-#define FSTV0910_SSAT_NF14  0xfa390020
-#define FSTV0910_SSAT_NF13  0xfa390010
-#define FSTV0910_SSAT_NF12  0xfa390008
-#define FSTV0910_SSAT_NF11  0xfa390004
-#define FSTV0910_SSAT_NF10  0xfa390002
+#define FSTV0910_SSAT_NF16  0xfa397080
+#define FSTV0910_SSAT_NF15  0xfa396040
+#define FSTV0910_SSAT_NF14  0xfa395020
+#define FSTV0910_SSAT_NF13  0xfa394010
+#define FSTV0910_SSAT_NF12  0xfa393008
+#define FSTV0910_SSAT_NF11  0xfa392004
+#define FSTV0910_SSAT_NF10  0xfa391002
 #define FSTV0910_SSAT_NF9  0xfa390001
 
 /* SELSATUR0 */
 #define RSTV0910_SELSATUR0  0xfa3a
-#define FSTV0910_SSAT_NF8  0xfa3a0080
-#define FSTV0910_SSAT_NF7  0xfa3a0040
-#define FSTV0910_SSAT_NF6  0xfa3a0020
-#define FSTV0910_SSAT_NF5  0xfa3a0010
-#define FSTV0910_SSAT_NF4  0xfa3a0008
-#define FSTV0910_SSAT_NF3  0xfa3a0004
-#define FSTV0910_SSAT_NF2  0xfa3a0002
+#define FSTV0910_SSAT_NF8  0xfa3a7080
+#define FSTV0910_SSAT_NF7  0xfa3a6040
+#define FSTV0910_SSAT_NF6  0xfa3a5020
+#define FSTV0910_SSAT_NF5  0xfa3a4010
+#define FSTV0910_SSAT_NF4  0xfa3a3008
+#define FSTV0910_SSAT_NF3  0xfa3a2004
+#define FSTV0910_SSAT_NF2  0xfa3a1002
 #define FSTV0910_SSAT_NF1  0xfa3a0001
 
 /* GAINLLR_NF1 */
@@ -4449,14 +4449,14 @@
 
 /* CFGEXT */
 #define RSTV0910_CFGEXT  0xfa80
-#define FSTV0910_BYPBCH  0xfa800040
-#define FSTV0910_BYPLDPC  0xfa800020
-#define FSTV0910_SHORTMULT  0xfa800004
+#define FSTV0910_BYPBCH  0xfa806040
+#define FSTV0910_BYPLDPC  0xfa805020
+#define FSTV0910_SHORTMULT  0xfa802004
 
 /* GENCFG */
 #define RSTV0910_GENCFG  0xfa86
-#define FSTV0910_BROADCAST  0xfa860010
-#define FSTV0910_CROSSINPUT  0xfa860002
+#define FSTV0910_BROADCAST  0xfa864010
+#define FSTV0910_CROSSINPUT  0xfa861002
 #define FSTV0910_DDEMOD  0xfa860001
 
 /* LDPCERR1 */
@@ -4469,7 +4469,7 @@
 
 /* BCHERR */
 #define RSTV0910_BCHERR  0xfa98
-#define FSTV0910_ERRORFLAG  0xfa980010
+#define FSTV0910_ERRORFLAG  0xfa984010
 #define FSTV0910_BCH_ERRORS_COUNTER  0xfa98000f
 
 /* P1_MAXEXTRAITER */
@@ -4706,22 +4706,22 @@
 
 /* TSTRES0 */
 #define RSTV0910_TSTRES0  0xff11
-#define FSTV0910_FRESFEC  0xff110080
-#define FSTV0910_FRESSYM1  0xff110008
-#define FSTV0910_FRESSYM2  0xff110004
+#define FSTV0910_FRESFEC  0xff117080
+#define FSTV0910_FRESSYM1  0xff113008
+#define FSTV0910_FRESSYM2  0xff112004
 
 /* TSTOUT */
 #define RSTV0910_TSTOUT  0xff12
-#define FSTV0910_TS  0xff12003e
+#define FSTV0910_TS  0xff12103e
 #define FSTV0910_TEST_OUT  0xff120001
 
 /* TSTIN */
 #define RSTV0910_TSTIN  0xff13
-#define FSTV0910_TEST_IN  0xff130080
+#define FSTV0910_TEST_IN  0xff137080
 
 /* P2_TSTDMD */
 #define RSTV0910_P2_TSTDMD  0xff20
-#define FSTV0910_P2_CFRINIT_INVZIGZAG  0xff200008
+#define FSTV0910_P2_CFRINIT_INVZIGZAG  0xff203008
 
 /* P2_TCTL1 */
 #define RSTV0910_P2_TCTL1  0xff24
@@ -4729,15 +4729,15 @@
 
 /* P2_TCTL4 */
 #define RSTV0910_P2_TCTL4  0xff28
-#define FSTV0910_P2_CFR2TOCFR1_DVBS1  0xff2800c0
+#define FSTV0910_P2_CFR2TOCFR1_DVBS1  0xff2860c0
 
 /* P2_TPKTDELIN */
 #define RSTV0910_P2_TPKTDELIN  0xff37
-#define FSTV0910_P2_CFG_RSPARITYON  0xff370080
+#define FSTV0910_P2_CFG_RSPARITYON  0xff377080
 
 /* P1_TSTDMD */
 #define RSTV0910_P1_TSTDMD  0xff40
-#define FSTV0910_P1_CFRINIT_INVZIGZAG  0xff400008
+#define FSTV0910_P1_CFRINIT_INVZIGZAG  0xff403008
 
 /* P1_TCTL1 */
 #define RSTV0910_P1_TCTL1  0xff44
@@ -4745,16 +4745,16 @@
 
 /* P1_TCTL4 */
 #define RSTV0910_P1_TCTL4  0xff48
-#define FSTV0910_P1_CFR2TOCFR1_DVBS1  0xff4800c0
+#define FSTV0910_P1_CFR2TOCFR1_DVBS1  0xff4860c0
 
 /* P1_TPKTDELIN */
 #define RSTV0910_P1_TPKTDELIN  0xff57
-#define FSTV0910_P1_CFG_RSPARITYON  0xff570080
+#define FSTV0910_P1_CFG_RSPARITYON  0xff577080
 
 /* TSTTSRS */
 #define RSTV0910_TSTTSRS  0xff6d
-#define FSTV0910_TSTRS_DISRS2  0xff6d0002
+#define FSTV0910_TSTRS_DISRS2  0xff6d1002
 #define FSTV0910_TSTRS_DISRS1  0xff6d0001
 
-#define STV0910_NBREGS		975
-#define STV0910_NBFIELDS		1818
+#define STV0910_NBREGS  975
+#define STV0910_NBFIELDS  1818
diff --git a/drivers/media/dvb-frontends/stv6110.h b/drivers/media/dvb-frontends/stv6110.h
index ab73124..ecfc1fa 100644
--- a/drivers/media/dvb-frontends/stv6110.h
+++ b/drivers/media/dvb-frontends/stv6110.h
@@ -22,7 +22,7 @@
 #define __DVB_STV6110_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /* registers */
 #define RSTV6110_CTRL1		0
diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c
index 66eba38..d895002 100644
--- a/drivers/media/dvb-frontends/stv6110x.c
+++ b/drivers/media/dvb-frontends/stv6110x.c
@@ -26,7 +26,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "stv6110x_reg.h"
 #include "stv6110x.h"
@@ -46,7 +46,7 @@ static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
 	u8 b0[] = { reg };
 	u8 b1[] = { 0 };
 	struct i2c_msg msg[] = {
-		{ .addr = config->addr, .flags = 0, 	   .buf = b0, .len = 1 },
+		{ .addr = config->addr, .flags = 0,	   .buf = b0, .len = 1 },
 		{ .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }
 	};
 
@@ -97,7 +97,9 @@ static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 da
 
 static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
 {
-	return stv6110x_write_regs(stv6110x, reg, &data, 1);
+	u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+	return stv6110x_write_regs(stv6110x, reg, &tmp, 1);
 }
 
 static int stv6110x_init(struct dvb_frontend *fe)
diff --git a/drivers/media/dvb-frontends/stv6110x_priv.h b/drivers/media/dvb-frontends/stv6110x_priv.h
index a993aba..109dfaf 100644
--- a/drivers/media/dvb-frontends/stv6110x_priv.h
+++ b/drivers/media/dvb-frontends/stv6110x_priv.h
@@ -48,11 +48,11 @@
 
 #define STV6110x_SETFIELD(mask, bitf, val)				\
 	(mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) <<	\
-				  STV6110x_OFFST_##bitf))) | 		\
+				  STV6110x_OFFST_##bitf))) |		\
 			  (val << STV6110x_OFFST_##bitf))
 
 #define STV6110x_GETFIELD(bitf, val)					\
-	((val >> STV6110x_OFFST_##bitf) & 				\
+	((val >> STV6110x_OFFST_##bitf) &				\
 	((1 << STV6110x_WIDTH_##bitf) - 1))
 
 #define MAKEWORD16(a, b)			(((a) << 8) | (b))
@@ -68,7 +68,7 @@
 struct stv6110x_state {
 	struct i2c_adapter		*i2c;
 	const struct stv6110x_config	*config;
-	u8 				regs[8];
+	u8				regs[8];
 
 	const struct stv6110x_devctl	*devctl;
 };
diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c
index e3e9007..9b715b6 100644
--- a/drivers/media/dvb-frontends/stv6111.c
+++ b/drivers/media/dvb-frontends/stv6111.c
@@ -25,7 +25,7 @@
 
 #include "stv6111.h"
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct stv {
 	struct i2c_adapter *i2c;
@@ -424,6 +424,7 @@ static int set_bandwidth(struct dvb_frontend *fe, u32 cutoff_frequency)
 {
 	struct stv *state = fe->tuner_priv;
 	u32 index = (cutoff_frequency + 999999) / 1000000;
+	int stat = 0;
 
 	if (index < 6)
 		index = 6;
@@ -435,12 +436,14 @@ static int set_bandwidth(struct dvb_frontend *fe, u32 cutoff_frequency)
 	state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index - 6) << 2);
 	state->reg[0x09] = (state->reg[0x09] & ~0x0C) | 0x08;
 	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	write_regs(state, 0x08, 2);
-	wait_for_call_done(state, 0x08);
-	if (fe->ops.i2c_gate_ctrl)
+		stat = fe->ops.i2c_gate_ctrl(fe, 1);
+	if (!stat) {
+		write_regs(state, 0x08, 2);
+		wait_for_call_done(state, 0x08);
+	}
+	if (fe->ops.i2c_gate_ctrl && !stat)
 		fe->ops.i2c_gate_ctrl(fe, 0);
-	return 0;
+	return stat;
 }
 
 static int set_lof(struct stv *state, u32 local_frequency, u32 cutoff_frequency)
@@ -518,6 +521,7 @@ static int set_params(struct dvb_frontend *fe)
 	struct stv *state = fe->tuner_priv;
 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 	u32 freq, cutoff;
+	int stat = 0;
 
 	if (p->delivery_system != SYS_DVBS && p->delivery_system != SYS_DVBS2)
 		return -EINVAL;
@@ -526,9 +530,10 @@ static int set_params(struct dvb_frontend *fe)
 	cutoff = 5000000 + muldiv32(p->symbol_rate, 135, 200);
 
 	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	set_lof(state, freq, cutoff);
-	if (fe->ops.i2c_gate_ctrl)
+		stat = fe->ops.i2c_gate_ctrl(fe, 1);
+	if (!stat)
+		set_lof(state, freq, cutoff);
+	if (fe->ops.i2c_gate_ctrl && !stat)
 		fe->ops.i2c_gate_ctrl(fe, 0);
 	return 0;
 }
@@ -575,14 +580,17 @@ static int get_rf_strength(struct dvb_frontend *fe, u16 *st)
 	if ((state->reg[0x03] & 0x60) == 0) {
 		/* RF Mode, Read AGC ADC */
 		u8 reg = 0;
+		int stat = 0;
 
 		if (fe->ops.i2c_gate_ctrl)
-			fe->ops.i2c_gate_ctrl(fe, 1);
-		write_reg(state, 0x02, state->reg[0x02] | 0x20);
-		read_reg(state, 2, &reg);
-		if (reg & 0x20)
+			stat = fe->ops.i2c_gate_ctrl(fe, 1);
+		if (!stat) {
+			write_reg(state, 0x02, state->reg[0x02] | 0x20);
 			read_reg(state, 2, &reg);
-		if (fe->ops.i2c_gate_ctrl)
+			if (reg & 0x20)
+				read_reg(state, 2, &reg);
+		}
+		if (fe->ops.i2c_gate_ctrl && !stat)
 			fe->ops.i2c_gate_ctrl(fe, 0);
 
 		if ((state->reg[0x02] & 0x80) == 0)
@@ -652,7 +660,8 @@ struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe,
 				    struct i2c_adapter *i2c, u8 adr)
 {
 	struct stv *state;
-	int stat;
+	int stat = -ENODEV;
+	int gatestat = 0;
 
 	state = kzalloc(sizeof(*state), GFP_KERNEL);
 	if (!state)
@@ -663,9 +672,10 @@ struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe,
 	init_state(state);
 
 	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	stat = attach_init(state);
-	if (fe->ops.i2c_gate_ctrl)
+		gatestat = fe->ops.i2c_gate_ctrl(fe, 1);
+	if (!gatestat)
+		stat = attach_init(state);
+	if (fe->ops.i2c_gate_ctrl && !gatestat)
 		fe->ops.i2c_gate_ctrl(fe, 0);
 	if (stat < 0) {
 		kfree(state);
diff --git a/drivers/media/dvb-frontends/tc90522.c b/drivers/media/dvb-frontends/tc90522.c
index 4687e15..5572b39 100644
--- a/drivers/media/dvb-frontends/tc90522.c
+++ b/drivers/media/dvb-frontends/tc90522.c
@@ -30,7 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/math64.h>
 #include <linux/dvb/frontend.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
 #include "tc90522.h"
 
 #define TC90522_I2C_THRU_REG 0xfe
diff --git a/drivers/media/dvb-frontends/tc90522.h b/drivers/media/dvb-frontends/tc90522.h
index b1cbddf..10e585f 100644
--- a/drivers/media/dvb-frontends/tc90522.h
+++ b/drivers/media/dvb-frontends/tc90522.h
@@ -25,7 +25,7 @@
 #define TC90522_H
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /* I2C device types */
 #define TC90522_I2C_DEV_SAT "tc90522sat"
diff --git a/drivers/media/dvb-frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c
index 32ba840..4f588eb 100644
--- a/drivers/media/dvb-frontends/tda10021.c
+++ b/drivers/media/dvb-frontends/tda10021.c
@@ -29,7 +29,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda1002x.h"
 
 
diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c
index 8028007..6c84916 100644
--- a/drivers/media/dvb-frontends/tda10023.c
+++ b/drivers/media/dvb-frontends/tda10023.c
@@ -35,7 +35,7 @@
 
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda1002x.h"
 
 #define REG0_INIT_VAL 0x23
@@ -211,7 +211,7 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
 
 		BDRX=1<<(24+NDEC);
 		BDRX*=sr;
-		do_div(BDRX, state->sysclk); 	/* BDRX/=SYSCLK; */
+		do_div(BDRX, state->sysclk);	/* BDRX/=SYSCLK; */
 
 		BDR=(s32)BDRX;
 	}
diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c
index 143b39b..de82a25 100644
--- a/drivers/media/dvb-frontends/tda10048.c
+++ b/drivers/media/dvb-frontends/tda10048.c
@@ -27,8 +27,8 @@
 #include <linux/delay.h>
 #include <linux/math64.h>
 #include <asm/div64.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
 #include "tda10048.h"
 
 #define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw"
diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c
index e674508..58e3bef 100644
--- a/drivers/media/dvb-frontends/tda1004x.c
+++ b/drivers/media/dvb-frontends/tda1004x.c
@@ -36,7 +36,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda1004x.h"
 
 static int debug;
diff --git a/drivers/media/dvb-frontends/tda10071_priv.h b/drivers/media/dvb-frontends/tda10071_priv.h
index b9c3601..67c46e8 100644
--- a/drivers/media/dvb-frontends/tda10071_priv.h
+++ b/drivers/media/dvb-frontends/tda10071_priv.h
@@ -21,7 +21,7 @@
 #ifndef TDA10071_PRIV
 #define TDA10071_PRIV
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda10071.h"
 #include <linux/firmware.h>
 #include <linux/regmap.h>
diff --git a/drivers/media/dvb-frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c
index b6d16c0..1a95c52 100644
--- a/drivers/media/dvb-frontends/tda10086.c
+++ b/drivers/media/dvb-frontends/tda10086.c
@@ -27,7 +27,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda10086.h"
 
 #define SACLK 96000000
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c
index 2d2778be..2e1d36a 100644
--- a/drivers/media/dvb-frontends/tda18271c2dd.c
+++ b/drivers/media/dvb-frontends/tda18271c2dd.c
@@ -27,7 +27,7 @@
 #include <linux/i2c.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda18271c2dd.h"
 
 /* Max transfer size done by I2C transfer functions */
@@ -674,7 +674,6 @@ static int PowerScan(struct tda_state *state,
 			Count = 200000;
 			wait = true;
 		}
-		status = status;
 		if (status < 0)
 			break;
 		if (CID_Gain >= CID_Target) {
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.h b/drivers/media/dvb-frontends/tda18271c2dd.h
index 289653d..afeb953 100644
--- a/drivers/media/dvb-frontends/tda18271c2dd.h
+++ b/drivers/media/dvb-frontends/tda18271c2dd.h
@@ -9,8 +9,8 @@ struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
 static inline struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
 					 struct i2c_adapter *i2c, u8 adr)
 {
-        printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-        return NULL;
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
 }
 #endif
 
diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c
index a63dec4..3ef7140 100644
--- a/drivers/media/dvb-frontends/tda665x.c
+++ b/drivers/media/dvb-frontends/tda665x.c
@@ -22,7 +22,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda665x.h"
 
 struct tda665x_state {
diff --git a/drivers/media/dvb-frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c
index aa3200d..29b4f64 100644
--- a/drivers/media/dvb-frontends/tda8083.c
+++ b/drivers/media/dvb-frontends/tda8083.c
@@ -30,7 +30,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda8083.h"
 
 
diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c
index 4eb294f..f72a54e 100644
--- a/drivers/media/dvb-frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -23,7 +23,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda8261.h"
 
 struct tda8261_state {
diff --git a/drivers/media/dvb-frontends/tda826x.h b/drivers/media/dvb-frontends/tda826x.h
index 6a7bed1..0ef35ff 100644
--- a/drivers/media/dvb-frontends/tda826x.h
+++ b/drivers/media/dvb-frontends/tda826x.h
@@ -24,7 +24,7 @@
 #define __DVB_TDA826X_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /**
  * Attach a tda826x tuner to the supplied frontend structure.
diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c
index 931e5c9..c55882a 100644
--- a/drivers/media/dvb-frontends/ts2020.c
+++ b/drivers/media/dvb-frontends/ts2020.c
@@ -19,7 +19,7 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "ts2020.h"
 #include <linux/regmap.h>
 #include <linux/math64.h>
@@ -368,7 +368,7 @@ static int ts2020_read_tuner_gain(struct dvb_frontend *fe, unsigned v_agc,
 		gain2 = clamp_t(long, gain2, 0, 13);
 		v_agc = clamp_t(long, v_agc, 400, 1100);
 
-		*_gain = -(gain1 * 2330 +
+		*_gain = -((__s64)gain1 * 2330 +
 			   gain2 * 3500 +
 			   v_agc * 24 / 10 * 10 +
 			   10000);
@@ -386,7 +386,7 @@ static int ts2020_read_tuner_gain(struct dvb_frontend *fe, unsigned v_agc,
 		gain3 = clamp_t(long, gain3, 0, 6);
 		v_agc = clamp_t(long, v_agc, 600, 1600);
 
-		*_gain = -(gain1 * 2650 +
+		*_gain = -((__s64)gain1 * 2650 +
 			   gain2 * 3380 +
 			   gain3 * 2850 +
 			   v_agc * 176 / 100 * 10 -
diff --git a/drivers/media/dvb-frontends/tua6100.h b/drivers/media/dvb-frontends/tua6100.h
index 6c098a8..a342bd9 100644
--- a/drivers/media/dvb-frontends/tua6100.h
+++ b/drivers/media/dvb-frontends/tua6100.h
@@ -28,7 +28,7 @@
 #define __DVB_TUA6100_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #if IS_REACHABLE(CONFIG_DVB_TUA6100)
 extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c);
diff --git a/drivers/media/dvb-frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c
index 1783637..1d89792 100644
--- a/drivers/media/dvb-frontends/ves1820.c
+++ b/drivers/media/dvb-frontends/ves1820.c
@@ -27,7 +27,7 @@
 #include <linux/slab.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "ves1820.h"
 
 
diff --git a/drivers/media/dvb-frontends/ves1x93.c b/drivers/media/dvb-frontends/ves1x93.c
index d0ee52f..0c7b328 100644
--- a/drivers/media/dvb-frontends/ves1x93.c
+++ b/drivers/media/dvb-frontends/ves1x93.c
@@ -30,7 +30,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "ves1x93.h"
 
 
diff --git a/drivers/media/dvb-frontends/zd1301_demod.h b/drivers/media/dvb-frontends/zd1301_demod.h
index 6cd8f6f..63c13fa4 100644
--- a/drivers/media/dvb-frontends/zd1301_demod.h
+++ b/drivers/media/dvb-frontends/zd1301_demod.h
@@ -19,7 +19,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /**
  * struct zd1301_demod_platform_data - Platform data for the zd1301_demod driver
diff --git a/drivers/media/dvb-frontends/zl10036.h b/drivers/media/dvb-frontends/zl10036.h
index ec90ca9..a1129ab 100644
--- a/drivers/media/dvb-frontends/zl10036.h
+++ b/drivers/media/dvb-frontends/zl10036.h
@@ -18,7 +18,7 @@
 #define DVB_ZL10036_H
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct zl10036_config {
 	u8 tuner_address;
diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c
index 623355f..6293bd9 100644
--- a/drivers/media/dvb-frontends/zl10039.c
+++ b/drivers/media/dvb-frontends/zl10039.c
@@ -21,7 +21,7 @@
 #include <linux/slab.h>
 #include <linux/dvb/frontend.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "zl10039.h"
 
 static int debug;
@@ -134,7 +134,9 @@ static inline int zl10039_writereg(struct zl10039_state *state,
 				const enum zl10039_reg_addr reg,
 				const u8 val)
 {
-	return zl10039_write(state, reg, &val, 1);
+	const u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+	return zl10039_write(state, reg, &tmp, 1);
 }
 
 static int zl10039_init(struct dvb_frontend *fe)
diff --git a/drivers/media/dvb-frontends/zl10353.c b/drivers/media/dvb-frontends/zl10353.c
index 1c689f7..c9901f4 100644
--- a/drivers/media/dvb-frontends/zl10353.c
+++ b/drivers/media/dvb-frontends/zl10353.c
@@ -23,7 +23,7 @@
 #include <linux/slab.h>
 #include <asm/div64.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "zl10353_priv.h"
 #include "zl10353.h"
 
diff --git a/drivers/media/firewire/Makefile b/drivers/media/firewire/Makefile
index 2394813..f96049f 100644
--- a/drivers/media/firewire/Makefile
+++ b/drivers/media/firewire/Makefile
@@ -2,5 +2,3 @@
 
 firedtv-y += firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o firedtv-fw.o
 firedtv-$(CONFIG_DVB_FIREDTV_INPUT)    += firedtv-rc.o
-
-ccflags-y += -Idrivers/media/dvb-core
diff --git a/drivers/media/firewire/firedtv-avc.c b/drivers/media/firewire/firedtv-avc.c
index 5bde6c2..1c933b2 100644
--- a/drivers/media/firewire/firedtv-avc.c
+++ b/drivers/media/firewire/firedtv-avc.c
@@ -24,7 +24,7 @@
 #include <linux/wait.h>
 #include <linux/workqueue.h>
 
-#include <dvb_frontend.h>
+#include <media/dvb_frontend.h>
 
 #include "firedtv.h"
 
@@ -47,7 +47,7 @@
 #define AVC_OPCODE_DSIT			0xc8
 #define AVC_OPCODE_DSD			0xcb
 
-#define DESCRIPTOR_TUNER_STATUS 	0x80
+#define DESCRIPTOR_TUNER_STATUS		0x80
 #define DESCRIPTOR_SUBUNIT_IDENTIFIER	0x00
 
 #define SFE_VENDOR_DE_COMPANYID_0	0x00 /* OUI of Digital Everywhere */
@@ -688,7 +688,7 @@ int avc_tuner_get_ts(struct firedtv *fdtv)
 	c->operand[2] = 0xff;	/* status */
 	c->operand[3] = 0x20;	/* system id = DVB */
 	c->operand[4] = 0x00;	/* antenna number */
-	c->operand[5] = 0x0; 	/* system_specific_search_flags */
+	c->operand[5] = 0x0;	/* system_specific_search_flags */
 	c->operand[6] = sl;	/* system_specific_multiplex selection_length */
 	/*
 	 * operand[7]: valid_flags[0]
diff --git a/drivers/media/firewire/firedtv-ci.c b/drivers/media/firewire/firedtv-ci.c
index fb8a1d2..b4ddfff 100644
--- a/drivers/media/firewire/firedtv-ci.c
+++ b/drivers/media/firewire/firedtv-ci.c
@@ -15,7 +15,7 @@
 #include <linux/fs.h>
 #include <linux/module.h>
 
-#include <dvbdev.h>
+#include <media/dvbdev.h>
 
 #include "firedtv.h"
 
diff --git a/drivers/media/firewire/firedtv-dvb.c b/drivers/media/firewire/firedtv-dvb.c
index f710e17..2f7ac79 100644
--- a/drivers/media/firewire/firedtv-dvb.c
+++ b/drivers/media/firewire/firedtv-dvb.c
@@ -18,10 +18,10 @@
 #include <linux/mutex.h>
 #include <linux/types.h>
 
-#include <dmxdev.h>
-#include <dvb_demux.h>
-#include <dvbdev.h>
-#include <dvb_frontend.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvbdev.h>
+#include <media/dvb_frontend.h>
 
 #include "firedtv.h"
 
diff --git a/drivers/media/firewire/firedtv-fe.c b/drivers/media/firewire/firedtv-fe.c
index 17acda6..a2ef4ed 100644
--- a/drivers/media/firewire/firedtv-fe.c
+++ b/drivers/media/firewire/firedtv-fe.c
@@ -16,7 +16,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 
-#include <dvb_frontend.h>
+#include <media/dvb_frontend.h>
 
 #include "firedtv.h"
 
@@ -165,7 +165,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
 	ops->read_snr			= fdtv_read_snr;
 	ops->read_ucblocks		= fdtv_read_uncorrected_blocks;
 
-	ops->diseqc_send_master_cmd 	= fdtv_diseqc_send_master_cmd;
+	ops->diseqc_send_master_cmd	= fdtv_diseqc_send_master_cmd;
 	ops->diseqc_send_burst		= fdtv_diseqc_send_burst;
 	ops->set_tone			= fdtv_set_tone;
 	ops->set_voltage		= fdtv_set_voltage;
@@ -220,7 +220,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
 		fi->symbol_rate_min	= 870000;
 		fi->symbol_rate_max	= 6900000;
 
-		fi->caps 		= FE_CAN_INVERSION_AUTO |
+		fi->caps		= FE_CAN_INVERSION_AUTO |
 					  FE_CAN_QAM_16		|
 					  FE_CAN_QAM_32		|
 					  FE_CAN_QAM_64		|
@@ -236,7 +236,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
 		fi->frequency_max	= 861000000;
 		fi->frequency_stepsize	= 62500;
 
-		fi->caps 		= FE_CAN_INVERSION_AUTO		|
+		fi->caps		= FE_CAN_INVERSION_AUTO		|
 					  FE_CAN_FEC_2_3		|
 					  FE_CAN_TRANSMISSION_MODE_AUTO |
 					  FE_CAN_GUARD_INTERVAL_AUTO	|
diff --git a/drivers/media/firewire/firedtv-fw.c b/drivers/media/firewire/firedtv-fw.c
index 247f0e7..92f4112 100644
--- a/drivers/media/firewire/firedtv-fw.c
+++ b/drivers/media/firewire/firedtv-fw.c
@@ -21,7 +21,7 @@
 
 #include <asm/page.h>
 
-#include <dvb_demux.h>
+#include <media/dvb_demux.h>
 
 #include "firedtv.h"
 
diff --git a/drivers/media/firewire/firedtv.h b/drivers/media/firewire/firedtv.h
index 345d1eda..876cdec 100644
--- a/drivers/media/firewire/firedtv.h
+++ b/drivers/media/firewire/firedtv.h
@@ -24,12 +24,12 @@
 #include <linux/wait.h>
 #include <linux/workqueue.h>
 
-#include <demux.h>
-#include <dmxdev.h>
-#include <dvb_demux.h>
-#include <dvb_frontend.h>
-#include <dvb_net.h>
-#include <dvbdev.h>
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
 
 struct firedtv_tuner_status {
 	unsigned active_system:8;
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index cb5d7ff..9f18cd2 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -665,6 +665,14 @@
 	  OV7670 VGA camera.  It currently only works with the M88ALP01
 	  controller.
 
+config VIDEO_OV7740
+	tristate "OmniVision OV7740 sensor support"
+	depends on I2C && VIDEO_V4L2
+	depends on MEDIA_CAMERA_SUPPORT
+	---help---
+	  This is a Video4Linux2 sensor-level driver for the OmniVision
+	  OV7740 VGA camera sensor.
+
 config VIDEO_OV9650
 	tristate "OmniVision OV9650/OV9652 sensor support"
 	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
@@ -777,12 +785,12 @@
 	  camera sensor.
 
 config VIDEO_S5K4ECGX
-        tristate "Samsung S5K4ECGX sensor support"
-        depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	tristate "Samsung S5K4ECGX sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
 	select CRC32
-        ---help---
-          This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
-          camera sensor with an embedded SoC image signal processor.
+	---help---
+	  This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
+	  camera sensor with an embedded SoC image signal processor.
 
 config VIDEO_S5K5BAF
 	tristate "Samsung S5K5BAF sensor support"
@@ -813,14 +821,6 @@
 	  This is a driver for the ADP1653 flash controller. It is used for
 	  example in Nokia N900.
 
-config VIDEO_AS3645A
-	tristate "AS3645A flash driver support"
-	depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
-	depends on MEDIA_CAMERA_SUPPORT
-	---help---
-	  This is a driver for the AS3645A and LM3555 flash controllers. It has
-	  build in control for flash, torch and indicator LEDs.
-
 config VIDEO_LM3560
 	tristate "LM3560 dual flash driver support"
 	depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 548a9ef..c0f94cd 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -68,6 +68,7 @@
 obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
 obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
 obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
+obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
 obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
 obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
 obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
@@ -84,7 +85,6 @@
 obj-$(CONFIG_VIDEO_S5K5BAF)	+= s5k5baf.o
 obj-$(CONFIG_VIDEO_S5C73M3)	+= s5c73m3/
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
-obj-$(CONFIG_VIDEO_AS3645A)	+= as3645a.o
 obj-$(CONFIG_VIDEO_LM3560)	+= lm3560.o
 obj-$(CONFIG_VIDEO_LM3646)	+= lm3646.o
 obj-$(CONFIG_VIDEO_SMIAPP_PLL)	+= smiapp-pll.o
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 6fb818a..25d24a3 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1366,11 +1366,9 @@ static int adv7180_probe(struct i2c_client *client,
 err_free_ctrl:
 	adv7180_exit_controls(state);
 err_unregister_vpp_client:
-	if (state->chip_info->flags & ADV7180_FLAG_I2P)
-		i2c_unregister_device(state->vpp_client);
+	i2c_unregister_device(state->vpp_client);
 err_unregister_csi_client:
-	if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
-		i2c_unregister_device(state->csi_client);
+	i2c_unregister_device(state->csi_client);
 	mutex_destroy(&state->mutex);
 	return ret;
 }
@@ -1388,10 +1386,8 @@ static int adv7180_remove(struct i2c_client *client)
 	media_entity_cleanup(&sd->entity);
 	adv7180_exit_controls(state);
 
-	if (state->chip_info->flags & ADV7180_FLAG_I2P)
-		i2c_unregister_device(state->vpp_client);
-	if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
-		i2c_unregister_device(state->csi_client);
+	i2c_unregister_device(state->vpp_client);
+	i2c_unregister_device(state->csi_client);
 
 	adv7180_set_power_pin(state, false);
 
diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index 11f9029..4a441ee 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -100,7 +100,7 @@ static const u8 adv7343_init_reg_val[] = {
 };
 
 /*
- * 			    2^32
+ *			    2^32
  * FSC(reg) =  FSC (HZ) * --------
  *			  27000000
  */
diff --git a/drivers/media/i2c/adv7393.c b/drivers/media/i2c/adv7393.c
index f19ad4e..b6234c8 100644
--- a/drivers/media/i2c/adv7393.c
+++ b/drivers/media/i2c/adv7393.c
@@ -103,7 +103,7 @@ static const u8 adv7393_init_reg_val[] = {
 };
 
 /*
- * 			    2^32
+ *			    2^32
  * FSC(reg) =  FSC (HZ) * --------
  *			  27000000
  */
diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c b/drivers/media/i2c/adv748x/adv748x-afe.c
index 4aa8e45b..5188178 100644
--- a/drivers/media/i2c/adv748x/adv748x-afe.c
+++ b/drivers/media/i2c/adv748x/adv748x-afe.c
@@ -267,6 +267,7 @@ static int adv748x_afe_g_input_status(struct v4l2_subdev *sd, u32 *status)
 	ret = adv748x_afe_status(afe, status, NULL);
 
 	mutex_unlock(&state->mutex);
+
 	return ret;
 }
 
diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c
index 5ee14f2..fd92c9e 100644
--- a/drivers/media/i2c/adv748x/adv748x-core.c
+++ b/drivers/media/i2c/adv748x/adv748x-core.c
@@ -225,10 +225,8 @@ static void adv748x_unregister_clients(struct adv748x_state *state)
 {
 	unsigned int i;
 
-	for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i) {
-		if (state->i2c_clients[i])
-			i2c_unregister_device(state->i2c_clients[i]);
-	}
+	for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i)
+		i2c_unregister_device(state->i2c_clients[i]);
 }
 
 static int adv748x_initialise_clients(struct adv748x_state *state)
@@ -646,14 +644,12 @@ static int adv748x_parse_dt(struct adv748x_state *state)
 
 	for_each_endpoint_of_node(state->dev->of_node, ep_np) {
 		of_graph_parse_endpoint(ep_np, &ep);
-		adv_info(state, "Endpoint %s on port %d",
-				of_node_full_name(ep.local_node),
-				ep.port);
+		adv_info(state, "Endpoint %pOF on port %d", ep.local_node,
+			 ep.port);
 
 		if (ep.port >= ADV748X_PORT_MAX) {
-			adv_err(state, "Invalid endpoint %s on port %d",
-				of_node_full_name(ep.local_node),
-				ep.port);
+			adv_err(state, "Invalid endpoint %pOF on port %d",
+				ep.local_node, ep.port);
 
 			continue;
 		}
diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c
index 979825d..820b44e 100644
--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
@@ -223,13 +223,12 @@ static const struct v4l2_subdev_ops adv748x_csi2_ops = {
 
 int adv748x_csi2_set_pixelrate(struct v4l2_subdev *sd, s64 rate)
 {
-	struct v4l2_ctrl *ctrl;
+	struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
 
-	ctrl = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_PIXEL_RATE);
-	if (!ctrl)
+	if (!tx->pixel_rate)
 		return -EINVAL;
 
-	return v4l2_ctrl_s_ctrl_int64(ctrl, rate);
+	return v4l2_ctrl_s_ctrl_int64(tx->pixel_rate, rate);
 }
 
 static int adv748x_csi2_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -251,8 +250,10 @@ static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx)
 
 	v4l2_ctrl_handler_init(&tx->ctrl_hdl, 1);
 
-	v4l2_ctrl_new_std(&tx->ctrl_hdl, &adv748x_csi2_ctrl_ops,
-			  V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
+	tx->pixel_rate = v4l2_ctrl_new_std(&tx->ctrl_hdl,
+					   &adv748x_csi2_ctrl_ops,
+					   V4L2_CID_PIXEL_RATE, 1, INT_MAX,
+					   1, 1);
 
 	tx->sd.ctrl_handler = &tx->ctrl_hdl;
 	if (tx->ctrl_hdl.error) {
diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h
index cc4151b..6789e2f 100644
--- a/drivers/media/i2c/adv748x/adv748x.h
+++ b/drivers/media/i2c/adv748x/adv748x.h
@@ -97,6 +97,7 @@ struct adv748x_csi2 {
 
 	struct media_pad pads[ADV748X_CSI2_NR_PADS];
 	struct v4l2_ctrl_handler ctrl_hdl;
+	struct v4l2_ctrl *pixel_rate;
 	struct v4l2_subdev sd;
 };
 
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index c786cd1..1544920 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -1982,6 +1982,7 @@ static void adv76xx_cec_tx_raw_status(struct v4l2_subdev *sd, u8 tx_raw_status)
 			 __func__);
 		cec_transmit_done(state->cec_adap, CEC_TX_STATUS_ARB_LOST,
 				  1, 0, 0, 0);
+		return;
 	}
 	if (tx_raw_status & 0x04) {
 		u8 status;
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c
deleted file mode 100644
index af5db71..0000000
--- a/drivers/media/i2c/as3645a.c
+++ /dev/null
@@ -1,880 +0,0 @@
-/*
- * drivers/media/i2c/as3645a.c - AS3645A and LM3555 flash controllers driver
- *
- * Copyright (C) 2008-2011 Nokia Corporation
- * Copyright (c) 2011, Intel Corporation.
- *
- * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.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.
- *
- * TODO:
- * - Check hardware FSTROBE control when sensor driver add support for this
- *
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include <media/i2c/as3645a.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-
-#define AS_TIMER_MS_TO_CODE(t)			(((t) - 100) / 50)
-#define AS_TIMER_CODE_TO_MS(c)			(50 * (c) + 100)
-
-/* Register definitions */
-
-/* Read-only Design info register: Reset state: xxxx 0001 */
-#define AS_DESIGN_INFO_REG			0x00
-#define AS_DESIGN_INFO_FACTORY(x)		(((x) >> 4))
-#define AS_DESIGN_INFO_MODEL(x)			((x) & 0x0f)
-
-/* Read-only Version control register: Reset state: 0000 0000
- * for first engineering samples
- */
-#define AS_VERSION_CONTROL_REG			0x01
-#define AS_VERSION_CONTROL_RFU(x)		(((x) >> 4))
-#define AS_VERSION_CONTROL_VERSION(x)		((x) & 0x0f)
-
-/* Read / Write	(Indicator and timer register): Reset state: 0000 1111 */
-#define AS_INDICATOR_AND_TIMER_REG		0x02
-#define AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT	0
-#define AS_INDICATOR_AND_TIMER_VREF_SHIFT	4
-#define AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT	6
-
-/* Read / Write	(Current set register): Reset state: 0110 1001 */
-#define AS_CURRENT_SET_REG			0x03
-#define AS_CURRENT_ASSIST_LIGHT_SHIFT		0
-#define AS_CURRENT_LED_DET_ON			(1 << 3)
-#define AS_CURRENT_FLASH_CURRENT_SHIFT		4
-
-/* Read / Write	(Control register): Reset state: 1011 0100 */
-#define AS_CONTROL_REG				0x04
-#define AS_CONTROL_MODE_SETTING_SHIFT		0
-#define AS_CONTROL_STROBE_ON			(1 << 2)
-#define AS_CONTROL_OUT_ON			(1 << 3)
-#define AS_CONTROL_EXT_TORCH_ON			(1 << 4)
-#define AS_CONTROL_STROBE_TYPE_EDGE		(0 << 5)
-#define AS_CONTROL_STROBE_TYPE_LEVEL		(1 << 5)
-#define AS_CONTROL_COIL_PEAK_SHIFT		6
-
-/* Read only (D3 is read / write) (Fault and info): Reset state: 0000 x000 */
-#define AS_FAULT_INFO_REG			0x05
-#define AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT	(1 << 1)
-#define AS_FAULT_INFO_INDICATOR_LED		(1 << 2)
-#define AS_FAULT_INFO_LED_AMOUNT		(1 << 3)
-#define AS_FAULT_INFO_TIMEOUT			(1 << 4)
-#define AS_FAULT_INFO_OVER_TEMPERATURE		(1 << 5)
-#define AS_FAULT_INFO_SHORT_CIRCUIT		(1 << 6)
-#define AS_FAULT_INFO_OVER_VOLTAGE		(1 << 7)
-
-/* Boost register */
-#define AS_BOOST_REG				0x0d
-#define AS_BOOST_CURRENT_DISABLE		(0 << 0)
-#define AS_BOOST_CURRENT_ENABLE			(1 << 0)
-
-/* Password register is used to unlock boost register writing */
-#define AS_PASSWORD_REG				0x0f
-#define AS_PASSWORD_UNLOCK_VALUE		0x55
-
-enum as_mode {
-	AS_MODE_EXT_TORCH = 0 << AS_CONTROL_MODE_SETTING_SHIFT,
-	AS_MODE_INDICATOR = 1 << AS_CONTROL_MODE_SETTING_SHIFT,
-	AS_MODE_ASSIST = 2 << AS_CONTROL_MODE_SETTING_SHIFT,
-	AS_MODE_FLASH = 3 << AS_CONTROL_MODE_SETTING_SHIFT,
-};
-
-/*
- * struct as3645a
- *
- * @subdev:		V4L2 subdev
- * @pdata:		Flash platform data
- * @power_lock:		Protects power_count
- * @power_count:	Power reference count
- * @led_mode:		V4L2 flash LED mode
- * @timeout:		Flash timeout in microseconds
- * @flash_current:	Flash current (0=200mA ... 15=500mA). Maximum
- *			values are 400mA for two LEDs and 500mA for one LED.
- * @assist_current:	Torch/Assist light current (0=20mA, 1=40mA ... 7=160mA)
- * @indicator_current:	Indicator LED current (0=0mA, 1=2.5mA ... 4=10mA)
- * @strobe_source:	Flash strobe source (software or external)
- */
-struct as3645a {
-	struct v4l2_subdev subdev;
-	const struct as3645a_platform_data *pdata;
-
-	struct mutex power_lock;
-	int power_count;
-
-	/* Controls */
-	struct v4l2_ctrl_handler ctrls;
-
-	enum v4l2_flash_led_mode led_mode;
-	unsigned int timeout;
-	u8 flash_current;
-	u8 assist_current;
-	u8 indicator_current;
-	enum v4l2_flash_strobe_source strobe_source;
-};
-
-#define to_as3645a(sd) container_of(sd, struct as3645a, subdev)
-
-/* Return negative errno else zero on success */
-static int as3645a_write(struct as3645a *flash, u8 addr, u8 val)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
-	int rval;
-
-	rval = i2c_smbus_write_byte_data(client, addr, val);
-
-	dev_dbg(&client->dev, "Write Addr:%02X Val:%02X %s\n", addr, val,
-		rval < 0 ? "fail" : "ok");
-
-	return rval;
-}
-
-/* Return negative errno else a data byte received from the device. */
-static int as3645a_read(struct as3645a *flash, u8 addr)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
-	int rval;
-
-	rval = i2c_smbus_read_byte_data(client, addr);
-
-	dev_dbg(&client->dev, "Read Addr:%02X Val:%02X %s\n", addr, rval,
-		rval < 0 ? "fail" : "ok");
-
-	return rval;
-}
-
-/* -----------------------------------------------------------------------------
- * Hardware configuration and trigger
- */
-
-/*
- * as3645a_set_config - Set flash configuration registers
- * @flash: The flash
- *
- * Configure the hardware with flash, assist and indicator currents, as well as
- * flash timeout.
- *
- * Return 0 on success, or a negative error code if an I2C communication error
- * occurred.
- */
-static int as3645a_set_config(struct as3645a *flash)
-{
-	int ret;
-	u8 val;
-
-	val = (flash->flash_current << AS_CURRENT_FLASH_CURRENT_SHIFT)
-	    | (flash->assist_current << AS_CURRENT_ASSIST_LIGHT_SHIFT)
-	    | AS_CURRENT_LED_DET_ON;
-
-	ret = as3645a_write(flash, AS_CURRENT_SET_REG, val);
-	if (ret < 0)
-		return ret;
-
-	val = AS_TIMER_MS_TO_CODE(flash->timeout / 1000)
-		    << AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT;
-
-	val |= (flash->pdata->vref << AS_INDICATOR_AND_TIMER_VREF_SHIFT)
-	    |  ((flash->indicator_current ? flash->indicator_current - 1 : 0)
-		 << AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT);
-
-	return as3645a_write(flash, AS_INDICATOR_AND_TIMER_REG, val);
-}
-
-/*
- * as3645a_set_control - Set flash control register
- * @flash: The flash
- * @mode: Desired output mode
- * @on: Desired output state
- *
- * Configure the hardware with output mode and state.
- *
- * Return 0 on success, or a negative error code if an I2C communication error
- * occurred.
- */
-static int
-as3645a_set_control(struct as3645a *flash, enum as_mode mode, bool on)
-{
-	u8 reg;
-
-	/* Configure output parameters and operation mode. */
-	reg = (flash->pdata->peak << AS_CONTROL_COIL_PEAK_SHIFT)
-	    | (on ? AS_CONTROL_OUT_ON : 0)
-	    | mode;
-
-	if (flash->led_mode == V4L2_FLASH_LED_MODE_FLASH &&
-	    flash->strobe_source == V4L2_FLASH_STROBE_SOURCE_EXTERNAL) {
-		reg |= AS_CONTROL_STROBE_TYPE_LEVEL
-		    |  AS_CONTROL_STROBE_ON;
-	}
-
-	return as3645a_write(flash, AS_CONTROL_REG, reg);
-}
-
-/*
- * as3645a_set_output - Configure output and operation mode
- * @flash: Flash controller
- * @strobe: Strobe the flash (only valid in flash mode)
- *
- * Turn the LEDs output on/off and set the operation mode based on the current
- * parameters.
- *
- * The AS3645A can't control the indicator LED independently of the flash/torch
- * LED. If the flash controller is in V4L2_FLASH_LED_MODE_NONE mode, set the
- * chip to indicator mode. Otherwise set it to assist light (torch) or flash
- * mode.
- *
- * In indicator and assist modes, turn the output on/off based on the indicator
- * and torch currents. In software strobe flash mode, turn the output on/off
- * based on the strobe parameter.
- */
-static int as3645a_set_output(struct as3645a *flash, bool strobe)
-{
-	enum as_mode mode;
-	bool on;
-
-	switch (flash->led_mode) {
-	case V4L2_FLASH_LED_MODE_NONE:
-		on = flash->indicator_current != 0;
-		mode = AS_MODE_INDICATOR;
-		break;
-	case V4L2_FLASH_LED_MODE_TORCH:
-		on = true;
-		mode = AS_MODE_ASSIST;
-		break;
-	case V4L2_FLASH_LED_MODE_FLASH:
-		on = strobe;
-		mode = AS_MODE_FLASH;
-		break;
-	default:
-		BUG();
-	}
-
-	/* Configure output parameters and operation mode. */
-	return as3645a_set_control(flash, mode, on);
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 controls
- */
-
-static int as3645a_is_active(struct as3645a *flash)
-{
-	int ret;
-
-	ret = as3645a_read(flash, AS_CONTROL_REG);
-	return ret < 0 ? ret : !!(ret & AS_CONTROL_OUT_ON);
-}
-
-static int as3645a_read_fault(struct as3645a *flash)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
-	int rval;
-
-	/* NOTE: reading register clear fault status */
-	rval = as3645a_read(flash, AS_FAULT_INFO_REG);
-	if (rval < 0)
-		return rval;
-
-	if (rval & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT)
-		dev_dbg(&client->dev, "Inductor Peak limit fault\n");
-
-	if (rval & AS_FAULT_INFO_INDICATOR_LED)
-		dev_dbg(&client->dev,
-			"Indicator LED fault: Short circuit or open loop\n");
-
-	dev_dbg(&client->dev, "%u connected LEDs\n",
-		rval & AS_FAULT_INFO_LED_AMOUNT ? 2 : 1);
-
-	if (rval & AS_FAULT_INFO_TIMEOUT)
-		dev_dbg(&client->dev, "Timeout fault\n");
-
-	if (rval & AS_FAULT_INFO_OVER_TEMPERATURE)
-		dev_dbg(&client->dev, "Over temperature fault\n");
-
-	if (rval & AS_FAULT_INFO_SHORT_CIRCUIT)
-		dev_dbg(&client->dev, "Short circuit fault\n");
-
-	if (rval & AS_FAULT_INFO_OVER_VOLTAGE)
-		dev_dbg(&client->dev,
-			"Over voltage fault: Indicates missing capacitor or open connection\n");
-
-	return rval;
-}
-
-static int as3645a_get_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct as3645a *flash =
-		container_of(ctrl->handler, struct as3645a, ctrls);
-	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
-	int value;
-
-	switch (ctrl->id) {
-	case V4L2_CID_FLASH_FAULT:
-		value = as3645a_read_fault(flash);
-		if (value < 0)
-			return value;
-
-		ctrl->cur.val = 0;
-		if (value & AS_FAULT_INFO_SHORT_CIRCUIT)
-			ctrl->cur.val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
-		if (value & AS_FAULT_INFO_OVER_TEMPERATURE)
-			ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
-		if (value & AS_FAULT_INFO_TIMEOUT)
-			ctrl->cur.val |= V4L2_FLASH_FAULT_TIMEOUT;
-		if (value & AS_FAULT_INFO_OVER_VOLTAGE)
-			ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
-		if (value & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT)
-			ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_CURRENT;
-		if (value & AS_FAULT_INFO_INDICATOR_LED)
-			ctrl->cur.val |= V4L2_FLASH_FAULT_INDICATOR;
-		break;
-
-	case V4L2_CID_FLASH_STROBE_STATUS:
-		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) {
-			ctrl->cur.val = 0;
-			break;
-		}
-
-		value = as3645a_is_active(flash);
-		if (value < 0)
-			return value;
-
-		ctrl->cur.val = value;
-		break;
-	}
-
-	dev_dbg(&client->dev, "G_CTRL %08x:%d\n", ctrl->id, ctrl->cur.val);
-
-	return 0;
-}
-
-static int as3645a_set_ctrl(struct v4l2_ctrl *ctrl)
-{
-	struct as3645a *flash =
-		container_of(ctrl->handler, struct as3645a, ctrls);
-	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
-	int ret;
-
-	dev_dbg(&client->dev, "S_CTRL %08x:%d\n", ctrl->id, ctrl->val);
-
-	/* If a control that doesn't apply to the current mode is modified,
-	 * we store the value and return immediately. The setting will be
-	 * applied when the LED mode is changed. Otherwise we apply the setting
-	 * immediately.
-	 */
-
-	switch (ctrl->id) {
-	case V4L2_CID_FLASH_LED_MODE:
-		if (flash->indicator_current)
-			return -EBUSY;
-
-		ret = as3645a_set_config(flash);
-		if (ret < 0)
-			return ret;
-
-		flash->led_mode = ctrl->val;
-		return as3645a_set_output(flash, false);
-
-	case V4L2_CID_FLASH_STROBE_SOURCE:
-		flash->strobe_source = ctrl->val;
-
-		/* Applies to flash mode only. */
-		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
-			break;
-
-		return as3645a_set_output(flash, false);
-
-	case V4L2_CID_FLASH_STROBE:
-		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
-			return -EBUSY;
-
-		return as3645a_set_output(flash, true);
-
-	case V4L2_CID_FLASH_STROBE_STOP:
-		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
-			return -EBUSY;
-
-		return as3645a_set_output(flash, false);
-
-	case V4L2_CID_FLASH_TIMEOUT:
-		flash->timeout = ctrl->val;
-
-		/* Applies to flash mode only. */
-		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
-			break;
-
-		return as3645a_set_config(flash);
-
-	case V4L2_CID_FLASH_INTENSITY:
-		flash->flash_current = (ctrl->val - AS3645A_FLASH_INTENSITY_MIN)
-				     / AS3645A_FLASH_INTENSITY_STEP;
-
-		/* Applies to flash mode only. */
-		if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
-			break;
-
-		return as3645a_set_config(flash);
-
-	case V4L2_CID_FLASH_TORCH_INTENSITY:
-		flash->assist_current =
-			(ctrl->val - AS3645A_TORCH_INTENSITY_MIN)
-			/ AS3645A_TORCH_INTENSITY_STEP;
-
-		/* Applies to torch mode only. */
-		if (flash->led_mode != V4L2_FLASH_LED_MODE_TORCH)
-			break;
-
-		return as3645a_set_config(flash);
-
-	case V4L2_CID_FLASH_INDICATOR_INTENSITY:
-		if (flash->led_mode != V4L2_FLASH_LED_MODE_NONE)
-			return -EBUSY;
-
-		flash->indicator_current =
-			(ctrl->val - AS3645A_INDICATOR_INTENSITY_MIN)
-			/ AS3645A_INDICATOR_INTENSITY_STEP;
-
-		ret = as3645a_set_config(flash);
-		if (ret < 0)
-			return ret;
-
-		if ((ctrl->val == 0) == (ctrl->cur.val == 0))
-			break;
-
-		return as3645a_set_output(flash, false);
-	}
-
-	return 0;
-}
-
-static const struct v4l2_ctrl_ops as3645a_ctrl_ops = {
-	.g_volatile_ctrl = as3645a_get_ctrl,
-	.s_ctrl = as3645a_set_ctrl,
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev core operations
- */
-
-/* Put device into know state. */
-static int as3645a_setup(struct as3645a *flash)
-{
-	struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
-	int ret;
-
-	/* clear errors */
-	ret = as3645a_read(flash, AS_FAULT_INFO_REG);
-	if (ret < 0)
-		return ret;
-
-	dev_dbg(&client->dev, "Fault info: %02x\n", ret);
-
-	ret = as3645a_set_config(flash);
-	if (ret < 0)
-		return ret;
-
-	ret = as3645a_set_output(flash, false);
-	if (ret < 0)
-		return ret;
-
-	/* read status */
-	ret = as3645a_read_fault(flash);
-	if (ret < 0)
-		return ret;
-
-	dev_dbg(&client->dev, "AS_INDICATOR_AND_TIMER_REG: %02x\n",
-		as3645a_read(flash, AS_INDICATOR_AND_TIMER_REG));
-	dev_dbg(&client->dev, "AS_CURRENT_SET_REG: %02x\n",
-		as3645a_read(flash, AS_CURRENT_SET_REG));
-	dev_dbg(&client->dev, "AS_CONTROL_REG: %02x\n",
-		as3645a_read(flash, AS_CONTROL_REG));
-
-	return ret & ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0;
-}
-
-static int __as3645a_set_power(struct as3645a *flash, int on)
-{
-	int ret;
-
-	if (!on)
-		as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
-
-	if (flash->pdata->set_power) {
-		ret = flash->pdata->set_power(&flash->subdev, on);
-		if (ret < 0)
-			return ret;
-	}
-
-	if (!on)
-		return 0;
-
-	ret = as3645a_setup(flash);
-	if (ret < 0) {
-		if (flash->pdata->set_power)
-			flash->pdata->set_power(&flash->subdev, 0);
-	}
-
-	return ret;
-}
-
-static int as3645a_set_power(struct v4l2_subdev *sd, int on)
-{
-	struct as3645a *flash = to_as3645a(sd);
-	int ret = 0;
-
-	mutex_lock(&flash->power_lock);
-
-	if (flash->power_count == !on) {
-		ret = __as3645a_set_power(flash, !!on);
-		if (ret < 0)
-			goto done;
-	}
-
-	flash->power_count += on ? 1 : -1;
-	WARN_ON(flash->power_count < 0);
-
-done:
-	mutex_unlock(&flash->power_lock);
-	return ret;
-}
-
-static int as3645a_registered(struct v4l2_subdev *sd)
-{
-	struct as3645a *flash = to_as3645a(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-	int rval, man, model, rfu, version;
-	const char *vendor;
-
-	/* Power up the flash driver and read manufacturer ID, model ID, RFU
-	 * and version.
-	 */
-	rval = as3645a_set_power(&flash->subdev, 1);
-	if (rval < 0)
-		return rval;
-
-	rval = as3645a_read(flash, AS_DESIGN_INFO_REG);
-	if (rval < 0)
-		goto power_off;
-
-	man = AS_DESIGN_INFO_FACTORY(rval);
-	model = AS_DESIGN_INFO_MODEL(rval);
-
-	rval = as3645a_read(flash, AS_VERSION_CONTROL_REG);
-	if (rval < 0)
-		goto power_off;
-
-	rfu = AS_VERSION_CONTROL_RFU(rval);
-	version = AS_VERSION_CONTROL_VERSION(rval);
-
-	/* Verify the chip model and version. */
-	if (model != 0x01 || rfu != 0x00) {
-		dev_err(&client->dev,
-			"AS3645A not detected (model %d rfu %d)\n", model, rfu);
-		rval = -ENODEV;
-		goto power_off;
-	}
-
-	switch (man) {
-	case 1:
-		vendor = "AMS, Austria Micro Systems";
-		break;
-	case 2:
-		vendor = "ADI, Analog Devices Inc.";
-		break;
-	case 3:
-		vendor = "NSC, National Semiconductor";
-		break;
-	case 4:
-		vendor = "NXP";
-		break;
-	case 5:
-		vendor = "TI, Texas Instrument";
-		break;
-	default:
-		vendor = "Unknown";
-	}
-
-	dev_info(&client->dev, "Chip vendor: %s (%d) Version: %d\n", vendor,
-		 man, version);
-
-	rval = as3645a_write(flash, AS_PASSWORD_REG, AS_PASSWORD_UNLOCK_VALUE);
-	if (rval < 0)
-		goto power_off;
-
-	rval = as3645a_write(flash, AS_BOOST_REG, AS_BOOST_CURRENT_DISABLE);
-	if (rval < 0)
-		goto power_off;
-
-	/* Setup default values. This makes sure that the chip is in a known
-	 * state, in case the power rail can't be controlled.
-	 */
-	rval = as3645a_setup(flash);
-
-power_off:
-	as3645a_set_power(&flash->subdev, 0);
-
-	return rval;
-}
-
-static int as3645a_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-	return as3645a_set_power(sd, 1);
-}
-
-static int as3645a_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-	return as3645a_set_power(sd, 0);
-}
-
-static const struct v4l2_subdev_core_ops as3645a_core_ops = {
-	.s_power		= as3645a_set_power,
-};
-
-static const struct v4l2_subdev_ops as3645a_ops = {
-	.core = &as3645a_core_ops,
-};
-
-static const struct v4l2_subdev_internal_ops as3645a_internal_ops = {
-	.registered = as3645a_registered,
-	.open = as3645a_open,
-	.close = as3645a_close,
-};
-
-/* -----------------------------------------------------------------------------
- *  I2C driver
- */
-#ifdef CONFIG_PM
-
-static int as3645a_suspend(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
-	struct as3645a *flash = to_as3645a(subdev);
-	int rval;
-
-	if (flash->power_count == 0)
-		return 0;
-
-	rval = __as3645a_set_power(flash, 0);
-
-	dev_dbg(&client->dev, "Suspend %s\n", rval < 0 ? "failed" : "ok");
-
-	return rval;
-}
-
-static int as3645a_resume(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
-	struct as3645a *flash = to_as3645a(subdev);
-	int rval;
-
-	if (flash->power_count == 0)
-		return 0;
-
-	rval = __as3645a_set_power(flash, 1);
-
-	dev_dbg(&client->dev, "Resume %s\n", rval < 0 ? "fail" : "ok");
-
-	return rval;
-}
-
-#else
-
-#define as3645a_suspend	NULL
-#define as3645a_resume	NULL
-
-#endif /* CONFIG_PM */
-
-/*
- * as3645a_init_controls - Create controls
- * @flash: The flash
- *
- * The number of LEDs reported in platform data is used to compute default
- * limits. Parameters passed through platform data can override those limits.
- */
-static int as3645a_init_controls(struct as3645a *flash)
-{
-	const struct as3645a_platform_data *pdata = flash->pdata;
-	struct v4l2_ctrl *ctrl;
-	int maximum;
-
-	v4l2_ctrl_handler_init(&flash->ctrls, 10);
-
-	/* V4L2_CID_FLASH_LED_MODE */
-	v4l2_ctrl_new_std_menu(&flash->ctrls, &as3645a_ctrl_ops,
-			       V4L2_CID_FLASH_LED_MODE, 2, ~7,
-			       V4L2_FLASH_LED_MODE_NONE);
-
-	/* V4L2_CID_FLASH_STROBE_SOURCE */
-	v4l2_ctrl_new_std_menu(&flash->ctrls, &as3645a_ctrl_ops,
-			       V4L2_CID_FLASH_STROBE_SOURCE,
-			       pdata->ext_strobe ? 1 : 0,
-			       pdata->ext_strobe ? ~3 : ~1,
-			       V4L2_FLASH_STROBE_SOURCE_SOFTWARE);
-
-	flash->strobe_source = V4L2_FLASH_STROBE_SOURCE_SOFTWARE;
-
-	/* V4L2_CID_FLASH_STROBE */
-	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
-			  V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
-
-	/* V4L2_CID_FLASH_STROBE_STOP */
-	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
-			  V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
-
-	/* V4L2_CID_FLASH_STROBE_STATUS */
-	ctrl = v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
-				 V4L2_CID_FLASH_STROBE_STATUS, 0, 1, 1, 1);
-	if (ctrl != NULL)
-		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
-	/* V4L2_CID_FLASH_TIMEOUT */
-	maximum = pdata->timeout_max;
-
-	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
-			  V4L2_CID_FLASH_TIMEOUT, AS3645A_FLASH_TIMEOUT_MIN,
-			  maximum, AS3645A_FLASH_TIMEOUT_STEP, maximum);
-
-	flash->timeout = maximum;
-
-	/* V4L2_CID_FLASH_INTENSITY */
-	maximum = pdata->flash_max_current;
-
-	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
-			  V4L2_CID_FLASH_INTENSITY, AS3645A_FLASH_INTENSITY_MIN,
-			  maximum, AS3645A_FLASH_INTENSITY_STEP, maximum);
-
-	flash->flash_current = (maximum - AS3645A_FLASH_INTENSITY_MIN)
-			     / AS3645A_FLASH_INTENSITY_STEP;
-
-	/* V4L2_CID_FLASH_TORCH_INTENSITY */
-	maximum = pdata->torch_max_current;
-
-	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
-			  V4L2_CID_FLASH_TORCH_INTENSITY,
-			  AS3645A_TORCH_INTENSITY_MIN, maximum,
-			  AS3645A_TORCH_INTENSITY_STEP,
-			  AS3645A_TORCH_INTENSITY_MIN);
-
-	flash->assist_current = 0;
-
-	/* V4L2_CID_FLASH_INDICATOR_INTENSITY */
-	v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
-			  V4L2_CID_FLASH_INDICATOR_INTENSITY,
-			  AS3645A_INDICATOR_INTENSITY_MIN,
-			  AS3645A_INDICATOR_INTENSITY_MAX,
-			  AS3645A_INDICATOR_INTENSITY_STEP,
-			  AS3645A_INDICATOR_INTENSITY_MIN);
-
-	flash->indicator_current = 0;
-
-	/* V4L2_CID_FLASH_FAULT */
-	ctrl = v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
-				 V4L2_CID_FLASH_FAULT, 0,
-				 V4L2_FLASH_FAULT_OVER_VOLTAGE |
-				 V4L2_FLASH_FAULT_TIMEOUT |
-				 V4L2_FLASH_FAULT_OVER_TEMPERATURE |
-				 V4L2_FLASH_FAULT_SHORT_CIRCUIT, 0, 0);
-	if (ctrl != NULL)
-		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
-	flash->subdev.ctrl_handler = &flash->ctrls;
-
-	return flash->ctrls.error;
-}
-
-static int as3645a_probe(struct i2c_client *client,
-			 const struct i2c_device_id *devid)
-{
-	struct as3645a *flash;
-	int ret;
-
-	if (client->dev.platform_data == NULL)
-		return -ENODEV;
-
-	flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
-	if (flash == NULL)
-		return -ENOMEM;
-
-	flash->pdata = client->dev.platform_data;
-
-	v4l2_i2c_subdev_init(&flash->subdev, client, &as3645a_ops);
-	flash->subdev.internal_ops = &as3645a_internal_ops;
-	flash->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
-	ret = as3645a_init_controls(flash);
-	if (ret < 0)
-		goto done;
-
-	ret = media_entity_pads_init(&flash->subdev.entity, 0, NULL);
-	if (ret < 0)
-		goto done;
-
-	flash->subdev.entity.function = MEDIA_ENT_F_FLASH;
-
-	mutex_init(&flash->power_lock);
-
-	flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
-
-done:
-	if (ret < 0)
-		v4l2_ctrl_handler_free(&flash->ctrls);
-
-	return ret;
-}
-
-static int as3645a_remove(struct i2c_client *client)
-{
-	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
-	struct as3645a *flash = to_as3645a(subdev);
-
-	v4l2_device_unregister_subdev(subdev);
-	v4l2_ctrl_handler_free(&flash->ctrls);
-	media_entity_cleanup(&flash->subdev.entity);
-	mutex_destroy(&flash->power_lock);
-
-	return 0;
-}
-
-static const struct i2c_device_id as3645a_id_table[] = {
-	{ AS3645A_NAME, 0 },
-	{ },
-};
-MODULE_DEVICE_TABLE(i2c, as3645a_id_table);
-
-static const struct dev_pm_ops as3645a_pm_ops = {
-	.suspend = as3645a_suspend,
-	.resume = as3645a_resume,
-};
-
-static struct i2c_driver as3645a_i2c_driver = {
-	.driver	= {
-		.name = AS3645A_NAME,
-		.pm   = &as3645a_pm_ops,
-	},
-	.probe	= as3645a_probe,
-	.remove	= as3645a_remove,
-	.id_table = as3645a_id_table,
-};
-
-module_i2c_driver(as3645a_i2c_driver);
-
-MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
-MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/cx25840/Makefile b/drivers/media/i2c/cx25840/Makefile
index 898eb13..ac54581 100644
--- a/drivers/media/i2c/cx25840/Makefile
+++ b/drivers/media/i2c/cx25840/Makefile
@@ -2,5 +2,3 @@
 		   cx25840-vbi.o cx25840-ir.o
 
 obj-$(CONFIG_VIDEO_CX25840) += cx25840.o
-
-ccflags-y += -Idrivers/media/i2c
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index f38bf81..98be63a 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -201,14 +201,14 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
 			} else {
 				/* IRQ_N */
 				if (p[i].flags &
-					(V4L2_SUBDEV_IO_PIN_DISABLE |
-					 V4L2_SUBDEV_IO_PIN_INPUT)) {
+					(BIT(V4L2_SUBDEV_IO_PIN_DISABLE) |
+					 BIT(V4L2_SUBDEV_IO_PIN_INPUT))) {
 					pin_ctrl &= ~(0x1 << 25);
 				} else {
 					pin_ctrl |= (0x1 << 25);
 				}
 				if (p[i].flags &
-					V4L2_SUBDEV_IO_PIN_ACTIVE_LOW) {
+					BIT(V4L2_SUBDEV_IO_PIN_ACTIVE_LOW)) {
 					pin_ctrl &= ~(0x1 << 24);
 				} else {
 					pin_ctrl |= (0x1 << 24);
@@ -224,7 +224,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
 			} else {
 				/* GPIO19 */
 				gpio_oe &= ~(0x1 << 0);
-				if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
+				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {
 					gpio_data &= ~(0x1 << 0);
 					gpio_data |= ((p[i].value & 0x1) << 0);
 				}
@@ -236,7 +236,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
 			if (p[i].function != CX23885_PAD_GPIO20) {
 				/* IR_TX */
 				gpio_oe |= (0x1 << 1);
-				if (p[i].flags & V4L2_SUBDEV_IO_PIN_DISABLE)
+				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_DISABLE))
 					pin_ctrl &= ~(0x1 << 10);
 				else
 					pin_ctrl |= (0x1 << 10);
@@ -245,7 +245,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
 			} else {
 				/* GPIO20 */
 				gpio_oe &= ~(0x1 << 1);
-				if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
+				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {
 					gpio_data &= ~(0x1 << 1);
 					gpio_data |= ((p[i].value & 0x1) << 1);
 				}
@@ -263,7 +263,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
 			} else {
 				/* GPIO21 */
 				gpio_oe &= ~(0x1 << 2);
-				if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
+				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {
 					gpio_data &= ~(0x1 << 2);
 					gpio_data |= ((p[i].value & 0x1) << 2);
 				}
@@ -281,7 +281,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
 			} else {
 				/* GPIO22 */
 				gpio_oe &= ~(0x1 << 3);
-				if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
+				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {
 					gpio_data &= ~(0x1 << 3);
 					gpio_data |= ((p[i].value & 0x1) << 3);
 				}
@@ -299,7 +299,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
 			} else {
 				/* GPIO23 */
 				gpio_oe &= ~(0x1 << 4);
-				if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
+				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {
 					gpio_data &= ~(0x1 << 4);
 					gpio_data |= ((p[i].value & 0x1) << 4);
 				}
@@ -1263,7 +1263,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
 static int set_v4lstd(struct i2c_client *client)
 {
 	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
-	u8 fmt = 0; 	/* zero is autodetect */
+	u8 fmt = 0;	/* zero is autodetect */
 	u8 pal_m = 0;
 
 	/* First tests should be against specific std */
@@ -1395,8 +1395,9 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd,
 	 * height. Without that margin the cx23885 fails in this
 	 * check.
 	 */
-	if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
-			(Vlines * 8 < Vsrc) || (Vsrc + 1 < Vlines)) {
+	if ((fmt->width == 0) || (Vlines == 0) ||
+	    (fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
+	    (Vlines * 8 < Vsrc) || (Vsrc + 1 < Vlines)) {
 		v4l_err(client, "%dx%d is not a valid size!\n",
 				fmt->width, fmt->height);
 		return -ERANGE;
@@ -1759,9 +1760,9 @@ static int cx25840_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
 
 		/* 1001 */ V4L2_STD_UNKNOWN,
 		/* 1010 */ V4L2_STD_UNKNOWN,
-		/* 1001 */ V4L2_STD_UNKNOWN,
-		/* 1010 */ V4L2_STD_UNKNOWN,
 		/* 1011 */ V4L2_STD_UNKNOWN,
+		/* 1100 */ V4L2_STD_SECAM,
+		/* 1101 */ V4L2_STD_UNKNOWN,
 		/* 1110 */ V4L2_STD_UNKNOWN,
 		/* 1111 */ V4L2_STD_UNKNOWN
 	};
@@ -2064,10 +2065,10 @@ static void cx23885_dif_setup(struct i2c_client *client, u32 ifHz)
 
 	/* Assuming TV */
 	/* Calculate the PLL frequency word based on the adjusted ifHz */
-        pll_freq = div_u64((u64)ifHz * 268435456, 50000000);
-        pll_freq_word = (u32)pll_freq;
+	pll_freq = div_u64((u64)ifHz * 268435456, 50000000);
+	pll_freq_word = (u32)pll_freq;
 
-        cx25840_write4(client, DIF_PLL_FREQ_WORD,  pll_freq_word);
+	cx25840_write4(client, DIF_PLL_FREQ_WORD,  pll_freq_word);
 
 	/* Round down to the nearest 100KHz */
 	ifHz = (ifHz / 100000) * 100000;
diff --git a/drivers/media/i2c/cx25840/cx25840-core.h b/drivers/media/i2c/cx25840/cx25840-core.h
index 55432ed..fb13a62 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.h
+++ b/drivers/media/i2c/cx25840/cx25840-core.h
@@ -118,7 +118,7 @@ static inline bool is_cx23888(struct cx25840_state *state)
 }
 
 /* ----------------------------------------------------------------------- */
-/* cx25850-core.c 							   */
+/* cx25850-core.c							   */
 int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
 int cx25840_write4(struct i2c_client *client, u16 addr, u32 value);
 u8 cx25840_read(struct i2c_client *client, u16 addr);
diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c
index 9b65c7d..ad7f66c 100644
--- a/drivers/media/i2c/cx25840/cx25840-ir.c
+++ b/drivers/media/i2c/cx25840/cx25840-ir.c
@@ -28,7 +28,7 @@ static unsigned int ir_debug;
 module_param(ir_debug, int, 0644);
 MODULE_PARM_DESC(ir_debug, "enable integrated IR debug messages");
 
-#define CX25840_IR_REG_BASE 	0x200
+#define CX25840_IR_REG_BASE	0x200
 
 #define CX25840_IR_CNTRL_REG	0x200
 #define CNTRL_WIN_3_3	0x00000000
@@ -131,7 +131,7 @@ static inline struct cx25840_ir_state *to_ir_state(struct v4l2_subdev *sd)
  * Rx and Tx Clock Divider register computations
  *
  * Note the largest clock divider value of 0xffff corresponds to:
- * 	(0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
+ *	(0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
  * which fits in 21 bits, so we'll use unsigned int for time arguments.
  */
 static inline u16 count_to_clock_divider(unsigned int d)
@@ -187,7 +187,7 @@ static inline unsigned int clock_divider_to_freq(unsigned int divider,
  * Low Pass Filter register calculations
  *
  * Note the largest count value of 0xffff corresponds to:
- * 	0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
+ *	0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
  * which fits in 21 bits, so we'll use unsigned int for time arguments.
  */
 static inline u16 count_to_lpf_count(unsigned int d)
diff --git a/drivers/media/i2c/dw9714.c b/drivers/media/i2c/dw9714.c
index ed01e8b..8dbbf0f 100644
--- a/drivers/media/i2c/dw9714.c
+++ b/drivers/media/i2c/dw9714.c
@@ -42,7 +42,6 @@
 
 /* dw9714 device structure */
 struct dw9714_device {
-	struct i2c_client *client;
 	struct v4l2_ctrl_handler ctrls_vcm;
 	struct v4l2_subdev sd;
 	u16 current_val;
@@ -61,7 +60,7 @@ static inline struct dw9714_device *sd_to_dw9714_vcm(struct v4l2_subdev *subdev)
 static int dw9714_i2c_write(struct i2c_client *client, u16 data)
 {
 	int ret;
-	u16 val = cpu_to_be16(data);
+	__be16 val = cpu_to_be16(data);
 
 	ret = i2c_master_send(client, (const char *)&val, sizeof(val));
 	if (ret != sizeof(val)) {
@@ -73,7 +72,7 @@ static int dw9714_i2c_write(struct i2c_client *client, u16 data)
 
 static int dw9714_t_focus_vcm(struct dw9714_device *dw9714_dev, u16 val)
 {
-	struct i2c_client *client = dw9714_dev->client;
+	struct i2c_client *client = v4l2_get_subdevdata(&dw9714_dev->sd);
 
 	dw9714_dev->current_val = val;
 
@@ -96,13 +95,11 @@ static const struct v4l2_ctrl_ops dw9714_vcm_ctrl_ops = {
 
 static int dw9714_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 {
-	struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
-	struct device *dev = &dw9714_dev->client->dev;
 	int rval;
 
-	rval = pm_runtime_get_sync(dev);
+	rval = pm_runtime_get_sync(sd->dev);
 	if (rval < 0) {
-		pm_runtime_put_noidle(dev);
+		pm_runtime_put_noidle(sd->dev);
 		return rval;
 	}
 
@@ -111,10 +108,7 @@ static int dw9714_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 
 static int dw9714_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 {
-	struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
-	struct device *dev = &dw9714_dev->client->dev;
-
-	pm_runtime_put(dev);
+	pm_runtime_put(sd->dev);
 
 	return 0;
 }
@@ -137,7 +131,6 @@ static int dw9714_init_controls(struct dw9714_device *dev_vcm)
 {
 	struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm;
 	const struct v4l2_ctrl_ops *ops = &dw9714_vcm_ctrl_ops;
-	struct i2c_client *client = dev_vcm->client;
 
 	v4l2_ctrl_handler_init(hdl, 1);
 
@@ -145,7 +138,7 @@ static int dw9714_init_controls(struct dw9714_device *dev_vcm)
 			  0, DW9714_MAX_FOCUS_POS, DW9714_FOCUS_STEPS, 0);
 
 	if (hdl->error)
-		dev_err(&client->dev, "%s fail error: 0x%x\n",
+		dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n",
 			__func__, hdl->error);
 	dev_vcm->sd.ctrl_handler = hdl;
 	return hdl->error;
@@ -161,8 +154,6 @@ static int dw9714_probe(struct i2c_client *client)
 	if (dw9714_dev == NULL)
 		return -ENOMEM;
 
-	dw9714_dev->client = client;
-
 	v4l2_i2c_subdev_init(&dw9714_dev->sd, client, &dw9714_ops);
 	dw9714_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	dw9714_dev->sd.internal_ops = &dw9714_int_ops;
@@ -183,6 +174,7 @@ static int dw9714_probe(struct i2c_client *client)
 
 	pm_runtime_set_active(&client->dev);
 	pm_runtime_enable(&client->dev);
+	pm_runtime_idle(&client->dev);
 
 	return 0;
 
diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c
index 2f71af2..664e8ac 100644
--- a/drivers/media/i2c/imx274.c
+++ b/drivers/media/i2c/imx274.c
@@ -634,7 +634,7 @@ static int imx274_regmap_util_write_table_8(struct regmap *regmap,
 					    const struct reg_8 table[],
 					    u16 wait_ms_addr, u16 end_addr)
 {
-	int err;
+	int err = 0;
 	const struct reg_8 *next;
 	u8 val;
 
@@ -655,6 +655,8 @@ static int imx274_regmap_util_write_table_8(struct regmap *regmap,
 				err = regmap_bulk_write(regmap, range_start,
 							&range_vals[0],
 							range_count);
+			else
+				err = 0;
 
 			if (err)
 				return err;
diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
index 8b5f7d0..193020d 100644
--- a/drivers/media/i2c/ir-kbd-i2c.c
+++ b/drivers/media/i2c/ir-kbd-i2c.c
@@ -18,6 +18,20 @@
  *      Brian Rogers <brian_rogers@comcast.net>
  * modified for AVerMedia Cardbus by
  *      Oldrich Jedlicka <oldium.pro@seznam.cz>
+ * Zilog Transmitter portions/ideas were derived from GPLv2+ sources:
+ *  - drivers/char/pctv_zilogir.[ch] from Hauppauge Broadway product
+ *	Copyright 2011 Hauppauge Computer works
+ *  - drivers/staging/media/lirc/lirc_zilog.c
+ *	Copyright (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ *	Michal Kochanowicz <mkochano@pld.org.pl>
+ *	Christoph Bartelmus <lirc@bartelmus.de>
+ *	Ulrich Mueller <ulrich.mueller42@web.de>
+ *	Stefan Jahn <stefan@lkcc.org>
+ *	Jerome Brock <jbrock@users.sourceforge.net>
+ *	Thomas Reitmayr (treitmayr@yahoo.com)
+ *	Mark Weaver <mark@npsl.co.uk>
+ *	Jarod Wilson <jarod@redhat.com>
+ *	Copyright (C) 2011 Andy Walls <awalls@md.metrocast.net>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -46,18 +60,11 @@
 #include <media/rc-core.h>
 #include <media/i2c/ir-kbd-i2c.h>
 
-/* ----------------------------------------------------------------------- */
-/* insmod parameters                                                       */
+#define FLAG_TX		1
+#define FLAG_HDPVR	2
 
-static int debug;
-module_param(debug, int, 0644);    /* debug level (0,1,2) */
-
-
-#define MODULE_NAME "ir-kbd-i2c"
-#define dprintk(level, fmt, arg...)	if (debug >= level) \
-	printk(KERN_DEBUG MODULE_NAME ": " fmt , ## arg)
-
-/* ----------------------------------------------------------------------- */
+static bool enable_hdpvr;
+module_param(enable_hdpvr, bool, 0644);
 
 static int get_key_haup_common(struct IR_i2c *ir, enum rc_proto *protocol,
 			       u32 *scancode, u8 *ptoggle, int size)
@@ -96,7 +103,8 @@ static int get_key_haup_common(struct IR_i2c *ir, enum rc_proto *protocol,
 		if (!range)
 			code += 64;
 
-		dprintk(1, "ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
+		dev_dbg(&ir->rc->dev,
+			"ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
 			start, range, toggle, dev, code);
 
 		*protocol = RC_PROTO_RC5;
@@ -113,13 +121,15 @@ static int get_key_haup_common(struct IR_i2c *ir, enum rc_proto *protocol,
 			*ptoggle = (dev & 0x80) != 0;
 			*protocol = RC_PROTO_RC6_MCE;
 			dev &= 0x7f;
-			dprintk(1, "ir hauppauge (rc6-mce): t%d vendor=%d dev=%d code=%d\n",
-						*ptoggle, vendor, dev, code);
+			dev_dbg(&ir->rc->dev,
+				"ir hauppauge (rc6-mce): t%d vendor=%d dev=%d code=%d\n",
+				*ptoggle, vendor, dev, code);
 		} else {
 			*ptoggle = 0;
 			*protocol = RC_PROTO_RC6_6A_32;
-			dprintk(1, "ir hauppauge (rc6-6a-32): vendor=%d dev=%d code=%d\n",
-							vendor, dev, code);
+			dev_dbg(&ir->rc->dev,
+				"ir hauppauge (rc6-6a-32): vendor=%d dev=%d code=%d\n",
+				vendor, dev, code);
 		}
 
 		*scancode = RC_SCANCODE_RC6_6A(vendor, dev, code);
@@ -162,7 +172,7 @@ static int get_key_pixelview(struct IR_i2c *ir, enum rc_proto *protocol,
 
 	/* poll IR chip */
 	if (1 != i2c_master_recv(ir->c, &b, 1)) {
-		dprintk(1,"read error\n");
+		dev_dbg(&ir->rc->dev, "read error\n");
 		return -EIO;
 	}
 
@@ -179,13 +189,12 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_proto *protocol,
 
 	/* poll IR chip */
 	if (4 != i2c_master_recv(ir->c, buf, 4)) {
-		dprintk(1,"read error\n");
+		dev_dbg(&ir->rc->dev, "read error\n");
 		return -EIO;
 	}
 
-	if(buf[0] !=0 || buf[1] !=0 || buf[2] !=0 || buf[3] != 0)
-		dprintk(2, "%s: 0x%2x 0x%2x 0x%2x 0x%2x\n", __func__,
-			buf[0], buf[1], buf[2], buf[3]);
+	if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0 || buf[3] != 0)
+		dev_dbg(&ir->rc->dev, "%s: %*ph\n", __func__, 4, buf);
 
 	/* no key pressed or signal from other ir remote */
 	if(buf[0] != 0x1 ||  buf[1] != 0xfe)
@@ -204,7 +213,7 @@ static int get_key_knc1(struct IR_i2c *ir, enum rc_proto *protocol,
 
 	/* poll IR chip */
 	if (1 != i2c_master_recv(ir->c, &b, 1)) {
-		dprintk(1,"read error\n");
+		dev_dbg(&ir->rc->dev, "read error\n");
 		return -EIO;
 	}
 
@@ -212,7 +221,7 @@ static int get_key_knc1(struct IR_i2c *ir, enum rc_proto *protocol,
 	   down, while 0xff indicates that no button is hold
 	   down. 0xfe sequences are sometimes interrupted by 0xFF */
 
-	dprintk(2,"key %02x\n", b);
+	dev_dbg(&ir->rc->dev, "key %02x\n", b);
 
 	if (b == 0xff)
 		return 0;
@@ -237,7 +246,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_proto *protocol,
 				  .buf = &key, .len = 1} };
 	subaddr = 0x0d;
 	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
-		dprintk(1, "read error\n");
+		dev_dbg(&ir->rc->dev, "read error\n");
 		return -EIO;
 	}
 
@@ -247,18 +256,17 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_proto *protocol,
 	subaddr = 0x0b;
 	msg[1].buf = &keygroup;
 	if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
-		dprintk(1, "read error\n");
+		dev_dbg(&ir->rc->dev, "read error\n");
 		return -EIO;
 	}
 
 	if (keygroup == 0xff)
 		return 0;
 
-	dprintk(1, "read key 0x%02x/0x%02x\n", key, keygroup);
+	dev_dbg(&ir->rc->dev, "read key 0x%02x/0x%02x\n", key, keygroup);
 	if (keygroup < 2 || keygroup > 4) {
-		/* Only a warning */
-		dprintk(1, "warning: invalid key group 0x%02x for key 0x%02x\n",
-								keygroup, key);
+		dev_warn(&ir->rc->dev, "warning: invalid key group 0x%02x for key 0x%02x\n",
+			 keygroup, key);
 	}
 	key |= (keygroup & 1) << 6;
 
@@ -279,15 +287,15 @@ static int ir_key_poll(struct IR_i2c *ir)
 	u8 toggle;
 	int rc;
 
-	dprintk(3, "%s\n", __func__);
+	dev_dbg(&ir->rc->dev, "%s\n", __func__);
 	rc = ir->get_key(ir, &protocol, &scancode, &toggle);
 	if (rc < 0) {
-		dprintk(2,"error\n");
+		dev_warn(&ir->rc->dev, "error %d\n", rc);
 		return rc;
 	}
 
 	if (rc) {
-		dprintk(1, "%s: proto = 0x%04x, scancode = 0x%08x\n",
+		dev_dbg(&ir->rc->dev, "%s: proto = 0x%04x, scancode = 0x%08x\n",
 			__func__, protocol, scancode);
 		rc_keydown(ir->rc, protocol, scancode, toggle);
 	}
@@ -299,17 +307,416 @@ static void ir_work(struct work_struct *work)
 	int rc;
 	struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work);
 
-	rc = ir_key_poll(ir);
-	if (rc == -ENODEV) {
-		rc_unregister_device(ir->rc);
-		ir->rc = NULL;
-		return;
+	/*
+	 * If the transmit code is holding the lock, skip polling for
+	 * IR, we'll get it to it next time round
+	 */
+	if (mutex_trylock(&ir->lock)) {
+		rc = ir_key_poll(ir);
+		mutex_unlock(&ir->lock);
+		if (rc == -ENODEV) {
+			rc_unregister_device(ir->rc);
+			ir->rc = NULL;
+			return;
+		}
 	}
 
 	schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling_interval));
 }
 
-/* ----------------------------------------------------------------------- */
+static int ir_open(struct rc_dev *dev)
+{
+	struct IR_i2c *ir = dev->priv;
+
+	schedule_delayed_work(&ir->work, 0);
+
+	return 0;
+}
+
+static void ir_close(struct rc_dev *dev)
+{
+	struct IR_i2c *ir = dev->priv;
+
+	cancel_delayed_work_sync(&ir->work);
+}
+
+/* Zilog Transmit Interface */
+#define XTAL_FREQ		18432000
+
+#define ZILOG_SEND		0x80
+#define ZILOG_UIR_END		0x40
+#define ZILOG_INIT_END		0x20
+#define ZILOG_LIR_END		0x10
+
+#define ZILOG_STATUS_OK		0x80
+#define ZILOG_STATUS_TX		0x40
+#define ZILOG_STATUS_SET	0x20
+
+/*
+ * As you can see here, very few different lengths of pulse and space
+ * can be encoded. This means that the hardware does not work well with
+ * recorded IR. It's best to work with generated IR, like from ir-ctl or
+ * the in-kernel encoders.
+ */
+struct code_block {
+	u8	length;
+	u16	pulse[7];	/* not aligned */
+	u8	carrier_pulse;
+	u8	carrier_space;
+	u16	space[8];	/* not aligned */
+	u8	codes[61];
+	u8	csum[2];
+} __packed;
+
+static int send_data_block(struct IR_i2c *ir, int cmd,
+			   struct code_block *code_block)
+{
+	int i, j, ret;
+	u8 buf[5], *p;
+
+	p = &code_block->length;
+	for (i = 0; p < code_block->csum; i++)
+		code_block->csum[i & 1] ^= *p++;
+
+	p = &code_block->length;
+
+	for (i = 0; i < sizeof(*code_block);) {
+		int tosend = sizeof(*code_block) - i;
+
+		if (tosend > 4)
+			tosend = 4;
+		buf[0] = i + 1;
+		for (j = 0; j < tosend; ++j)
+			buf[1 + j] = p[i + j];
+		dev_dbg(&ir->rc->dev, "%*ph", tosend + 1, buf);
+		ret = i2c_master_send(ir->tx_c, buf, tosend + 1);
+		if (ret != tosend + 1) {
+			dev_dbg(&ir->rc->dev,
+				"i2c_master_send failed with %d\n", ret);
+			return ret < 0 ? ret : -EIO;
+		}
+		i += tosend;
+	}
+
+	buf[0] = 0;
+	buf[1] = cmd;
+	ret = i2c_master_send(ir->tx_c, buf, 2);
+	if (ret != 2) {
+		dev_err(&ir->rc->dev, "i2c_master_send failed with %d\n", ret);
+		return ret < 0 ? ret : -EIO;
+	}
+
+	usleep_range(2000, 5000);
+
+	ret = i2c_master_send(ir->tx_c, buf, 1);
+	if (ret != 1) {
+		dev_err(&ir->rc->dev, "i2c_master_send failed with %d\n", ret);
+		return ret < 0 ? ret : -EIO;
+	}
+
+	return 0;
+}
+
+static int zilog_init(struct IR_i2c *ir)
+{
+	struct code_block code_block = { .length = sizeof(code_block) };
+	u8 buf[4];
+	int ret;
+
+	put_unaligned_be16(0x1000, &code_block.pulse[3]);
+
+	ret = send_data_block(ir, ZILOG_INIT_END, &code_block);
+	if (ret)
+		return ret;
+
+	ret = i2c_master_recv(ir->tx_c, buf, 4);
+	if (ret != 4) {
+		dev_err(&ir->c->dev, "failed to retrieve firmware version: %d\n",
+			ret);
+		return ret < 0 ? ret : -EIO;
+	}
+
+	dev_info(&ir->c->dev, "Zilog/Hauppauge IR blaster firmware version %d.%d.%d\n",
+		 buf[1], buf[2], buf[3]);
+
+	return 0;
+}
+
+/*
+ * If the last slot for pulse is the same as the current slot for pulse,
+ * then use slot no 7.
+ */
+static void copy_codes(u8 *dst, u8 *src, unsigned int count)
+{
+	u8 c, last = 0xff;
+
+	while (count--) {
+		c = *src++;
+		if ((c & 0xf0) == last) {
+			*dst++ = 0x70 | (c & 0xf);
+		} else {
+			*dst++ = c;
+			last = c & 0xf0;
+		}
+	}
+}
+
+/*
+ * When looking for repeats, we don't care about the trailing space. This
+ * is set to the shortest possible anyway.
+ */
+static int cmp_no_trail(u8 *a, u8 *b, unsigned int count)
+{
+	while (--count) {
+		if (*a++ != *b++)
+			return 1;
+	}
+
+	return (*a & 0xf0) - (*b & 0xf0);
+}
+
+static int find_slot(u16 *array, unsigned int size, u16 val)
+{
+	int i;
+
+	for (i = 0; i < size; i++) {
+		if (get_unaligned_be16(&array[i]) == val) {
+			return i;
+		} else if (!array[i]) {
+			put_unaligned_be16(val, &array[i]);
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+static int zilog_ir_format(struct rc_dev *rcdev, unsigned int *txbuf,
+			   unsigned int count, struct code_block *code_block)
+{
+	struct IR_i2c *ir = rcdev->priv;
+	int rep, i, l, p = 0, s, c = 0;
+	bool repeating;
+	u8 codes[174];
+
+	code_block->carrier_pulse = DIV_ROUND_CLOSEST(
+			ir->duty_cycle * XTAL_FREQ / 1000, ir->carrier);
+	code_block->carrier_space = DIV_ROUND_CLOSEST(
+			(100 - ir->duty_cycle) * XTAL_FREQ / 1000, ir->carrier);
+
+	for (i = 0; i < count; i++) {
+		if (c >= ARRAY_SIZE(codes) - 1) {
+			dev_warn(&rcdev->dev, "IR too long, cannot transmit\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * Lengths more than 142220us cannot be encoded; also
+		 * this checks for multiply overflow
+		 */
+		if (txbuf[i] > 142220)
+			return -EINVAL;
+
+		l = DIV_ROUND_CLOSEST((XTAL_FREQ / 1000) * txbuf[i], 40000);
+
+		if (i & 1) {
+			s = find_slot(code_block->space,
+				      ARRAY_SIZE(code_block->space), l);
+			if (s == -1) {
+				dev_warn(&rcdev->dev, "Too many different lengths spaces, cannot transmit");
+				return -EINVAL;
+			}
+
+			/* We have a pulse and space */
+			codes[c++] = (p << 4) | s;
+		} else {
+			p = find_slot(code_block->pulse,
+				      ARRAY_SIZE(code_block->pulse), l);
+			if (p == -1) {
+				dev_warn(&rcdev->dev, "Too many different lengths pulses, cannot transmit");
+				return -EINVAL;
+			}
+		}
+	}
+
+	/* We have to encode the trailing pulse. Find the shortest space */
+	s = 0;
+	for (i = 1; i < ARRAY_SIZE(code_block->space); i++) {
+		u16 d = get_unaligned_be16(&code_block->space[i]);
+
+		if (get_unaligned_be16(&code_block->space[s]) > d)
+			s = i;
+	}
+
+	codes[c++] = (p << 4) | s;
+
+	dev_dbg(&rcdev->dev, "generated %d codes\n", c);
+
+	/*
+	 * Are the last N codes (so pulse + space) repeating 3 times?
+	 * if so we can shorten the codes list and use code 0xc0 to repeat
+	 * them.
+	 */
+	repeating = false;
+
+	for (rep = c / 3; rep >= 1; rep--) {
+		if (!memcmp(&codes[c - rep * 3], &codes[c - rep * 2], rep) &&
+		    !cmp_no_trail(&codes[c - rep], &codes[c - rep * 2], rep)) {
+			repeating = true;
+			break;
+		}
+	}
+
+	if (repeating) {
+		/* first copy any leading non-repeating */
+		int leading = c - rep * 3;
+
+		if (leading + rep >= ARRAY_SIZE(code_block->codes) - 3) {
+			dev_warn(&rcdev->dev, "IR too long, cannot transmit\n");
+			return -EINVAL;
+		}
+
+		dev_dbg(&rcdev->dev, "found trailing %d repeat\n", rep);
+		copy_codes(code_block->codes, codes, leading);
+		code_block->codes[leading] = 0x82;
+		copy_codes(code_block->codes + leading + 1, codes + leading,
+			   rep);
+		c = leading + 1 + rep;
+		code_block->codes[c++] = 0xc0;
+	} else {
+		if (c >= ARRAY_SIZE(code_block->codes) - 3) {
+			dev_warn(&rcdev->dev, "IR too long, cannot transmit\n");
+			return -EINVAL;
+		}
+
+		dev_dbg(&rcdev->dev, "found no trailing repeat\n");
+		code_block->codes[0] = 0x82;
+		copy_codes(code_block->codes + 1, codes, c);
+		c++;
+		code_block->codes[c++] = 0xc4;
+	}
+
+	while (c < ARRAY_SIZE(code_block->codes))
+		code_block->codes[c++] = 0x83;
+
+	return 0;
+}
+
+static int zilog_tx(struct rc_dev *rcdev, unsigned int *txbuf,
+		    unsigned int count)
+{
+	struct IR_i2c *ir = rcdev->priv;
+	struct code_block code_block = { .length = sizeof(code_block) };
+	u8 buf[2];
+	int ret, i;
+
+	ret = zilog_ir_format(rcdev, txbuf, count, &code_block);
+	if (ret)
+		return ret;
+
+	ret = mutex_lock_interruptible(&ir->lock);
+	if (ret)
+		return ret;
+
+	ret = send_data_block(ir, ZILOG_UIR_END, &code_block);
+	if (ret)
+		goto out_unlock;
+
+	ret = i2c_master_recv(ir->tx_c, buf, 1);
+	if (ret != 1) {
+		dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret);
+		goto out_unlock;
+	}
+
+	dev_dbg(&ir->rc->dev, "code set status: %02x\n", buf[0]);
+
+	if (buf[0] != (ZILOG_STATUS_OK | ZILOG_STATUS_SET)) {
+		dev_err(&ir->rc->dev, "unexpected IR TX response %02x\n",
+			buf[0]);
+		ret = -EIO;
+		goto out_unlock;
+	}
+
+	buf[0] = 0x00;
+	buf[1] = ZILOG_SEND;
+
+	ret = i2c_master_send(ir->tx_c, buf, 2);
+	if (ret != 2) {
+		dev_err(&ir->rc->dev, "i2c_master_send failed with %d\n", ret);
+		if (ret >= 0)
+			ret = -EIO;
+		goto out_unlock;
+	}
+
+	dev_dbg(&ir->rc->dev, "send command sent\n");
+
+	/*
+	 * This bit NAKs until the device is ready, so we retry it
+	 * sleeping a bit each time.  This seems to be what the windows
+	 * driver does, approximately.
+	 * Try for up to 1s.
+	 */
+	for (i = 0; i < 20; ++i) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(msecs_to_jiffies(50));
+		ret = i2c_master_send(ir->tx_c, buf, 1);
+		if (ret == 1)
+			break;
+		dev_dbg(&ir->rc->dev,
+			"NAK expected: i2c_master_send failed with %d (try %d)\n",
+			ret, i + 1);
+	}
+
+	if (ret != 1) {
+		dev_err(&ir->rc->dev,
+			"IR TX chip never got ready: last i2c_master_send failed with %d\n",
+			ret);
+		if (ret >= 0)
+			ret = -EIO;
+		goto out_unlock;
+	}
+
+	i = i2c_master_recv(ir->tx_c, buf, 1);
+	if (i != 1) {
+		dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret);
+		ret = -EIO;
+		goto out_unlock;
+	} else if (buf[0] != ZILOG_STATUS_OK) {
+		dev_err(&ir->rc->dev, "unexpected IR TX response #2: %02x\n",
+			buf[0]);
+		ret = -EIO;
+		goto out_unlock;
+	}
+	dev_dbg(&ir->rc->dev, "transmit complete\n");
+
+	/* Oh good, it worked */
+	ret = count;
+out_unlock:
+	mutex_unlock(&ir->lock);
+
+	return ret;
+}
+
+static int zilog_tx_carrier(struct rc_dev *dev, u32 carrier)
+{
+	struct IR_i2c *ir = dev->priv;
+
+	if (carrier > 500000 || carrier < 20000)
+		return -EINVAL;
+
+	ir->carrier = carrier;
+
+	return 0;
+}
+
+static int zilog_tx_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
+{
+	struct IR_i2c *ir = dev->priv;
+
+	ir->duty_cycle = duty_cycle;
+
+	return 0;
+}
 
 static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
@@ -322,6 +729,11 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	unsigned short addr = client->addr;
 	int err;
 
+	if ((id->driver_data & FLAG_HDPVR) && !enable_hdpvr) {
+		dev_err(&client->dev, "IR for HDPVR is known to cause problems during recording, use enable_hdpvr modparam to enable\n");
+		return -ENODEV;
+	}
+
 	ir = devm_kzalloc(&client->dev, sizeof(*ir), GFP_KERNEL);
 	if (!ir)
 		return -ENOMEM;
@@ -433,18 +845,15 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 	/* Make sure we are all setup before going on */
 	if (!name || !ir->get_key || !rc_proto || !ir_codes) {
-		dprintk(1, ": Unsupported device at address 0x%02x\n",
-			addr);
+		dev_warn(&client->dev, "Unsupported device at address 0x%02x\n",
+			 addr);
 		err = -ENODEV;
 		goto err_out_free;
 	}
 
-	/* Sets name */
-	snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
 	ir->ir_codes = ir_codes;
 
-	snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
-		 dev_name(&adap->dev),
+	snprintf(ir->phys, sizeof(ir->phys), "%s/%s", dev_name(&adap->dev),
 		 dev_name(&client->dev));
 
 	/*
@@ -453,7 +862,11 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	 */
 	rc->input_id.bustype = BUS_I2C;
 	rc->input_phys       = ir->phys;
-	rc->device_name	     = ir->name;
+	rc->device_name	     = name;
+	rc->dev.parent       = &client->dev;
+	rc->priv             = ir;
+	rc->open             = ir_open;
+	rc->close            = ir_close;
 
 	/*
 	 * Initialize the other fields of rc_dev
@@ -461,22 +874,35 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	rc->map_name       = ir->ir_codes;
 	rc->allowed_protocols = rc_proto;
 	if (!rc->driver_name)
-		rc->driver_name = MODULE_NAME;
+		rc->driver_name = KBUILD_MODNAME;
+
+	mutex_init(&ir->lock);
+
+	INIT_DELAYED_WORK(&ir->work, ir_work);
+
+	if (id->driver_data & FLAG_TX) {
+		ir->tx_c = i2c_new_dummy(client->adapter, 0x70);
+		if (!ir->tx_c) {
+			dev_err(&client->dev, "failed to setup tx i2c address");
+		} else if (!zilog_init(ir)) {
+			ir->carrier = 38000;
+			ir->duty_cycle = 40;
+			rc->tx_ir = zilog_tx;
+			rc->s_tx_carrier = zilog_tx_carrier;
+			rc->s_tx_duty_cycle = zilog_tx_duty_cycle;
+		}
+	}
 
 	err = rc_register_device(rc);
 	if (err)
 		goto err_out_free;
 
-	printk(MODULE_NAME ": %s detected at %s [%s]\n",
-	       ir->name, ir->phys, adap->name);
-
-	/* start polling via eventd */
-	INIT_DELAYED_WORK(&ir->work, ir_work);
-	schedule_delayed_work(&ir->work, 0);
-
 	return 0;
 
  err_out_free:
+	if (ir->tx_c)
+		i2c_unregister_device(ir->tx_c);
+
 	/* Only frees rc if it were allocated internally */
 	rc_free_device(rc);
 	return err;
@@ -489,6 +915,9 @@ static int ir_remove(struct i2c_client *client)
 	/* kill outstanding polls */
 	cancel_delayed_work_sync(&ir->work);
 
+	if (ir->tx_c)
+		i2c_unregister_device(ir->tx_c);
+
 	/* unregister device */
 	rc_unregister_device(ir->rc);
 
@@ -500,10 +929,11 @@ static const struct i2c_device_id ir_kbd_id[] = {
 	/* Generic entry for any IR receiver */
 	{ "ir_video", 0 },
 	/* IR device specific entries should be added here */
-	{ "ir_rx_z8f0811_haup", 0 },
-	{ "ir_rx_z8f0811_hdpvr", 0 },
+	{ "ir_z8f0811_haup", FLAG_TX },
+	{ "ir_z8f0811_hdpvr", FLAG_TX | FLAG_HDPVR },
 	{ }
 };
+MODULE_DEVICE_TABLE(i2c, ir_kbd_id);
 
 static struct i2c_driver ir_kbd_driver = {
 	.driver = {
diff --git a/drivers/media/i2c/ks0127.c b/drivers/media/i2c/ks0127.c
index ab536c4..5905ed6 100644
--- a/drivers/media/i2c/ks0127.c
+++ b/drivers/media/i2c/ks0127.c
@@ -195,7 +195,7 @@ struct adjust {
 struct ks0127 {
 	struct v4l2_subdev sd;
 	v4l2_std_id	norm;
-	u8 		regs[256];
+	u8		regs[256];
 };
 
 static inline struct ks0127 *to_ks0127(struct v4l2_subdev *sd)
diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
index b1665d9..efda1aa 100644
--- a/drivers/media/i2c/mt9m111.c
+++ b/drivers/media/i2c/mt9m111.c
@@ -92,6 +92,7 @@
  */
 #define MT9M111_OPER_MODE_CTRL		0x106
 #define MT9M111_OUTPUT_FORMAT_CTRL	0x108
+#define MT9M111_TPG_CTRL		0x148
 #define MT9M111_REDUCER_XZOOM_B		0x1a0
 #define MT9M111_REDUCER_XSIZE_B		0x1a1
 #define MT9M111_REDUCER_YZOOM_B		0x1a3
@@ -124,6 +125,7 @@
 #define MT9M111_OUTFMT_AVG_CHROMA	(1 << 2)
 #define MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN	(1 << 1)
 #define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B	(1 << 0)
+#define MT9M111_TPG_SEL_MASK		GENMASK(2, 0)
 
 /*
  * Camera control register addresses (0x200..0x2ff not implemented)
@@ -215,6 +217,9 @@ struct mt9m111 {
 	int power_count;
 	const struct mt9m111_datafmt *fmt;
 	int lastpage;	/* PageMap cache value */
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_pad pad;
+#endif
 };
 
 /* Find a data format by a pixel code */
@@ -703,6 +708,25 @@ static int mt9m111_set_autowhitebalance(struct mt9m111 *mt9m111, int on)
 	return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
 }
 
+static const char * const mt9m111_test_pattern_menu[] = {
+	"Disabled",
+	"Vertical monochrome gradient",
+	"Flat color type 1",
+	"Flat color type 2",
+	"Flat color type 3",
+	"Flat color type 4",
+	"Flat color type 5",
+	"Color bar",
+};
+
+static int mt9m111_set_test_pattern(struct mt9m111 *mt9m111, int val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
+
+	return mt9m111_reg_mask(client, MT9M111_TPG_CTRL, val,
+				MT9M111_TPG_SEL_MASK);
+}
+
 static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct mt9m111 *mt9m111 = container_of(ctrl->handler,
@@ -721,6 +745,8 @@ static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl)
 		return mt9m111_set_autoexposure(mt9m111, ctrl->val);
 	case V4L2_CID_AUTO_WHITE_BALANCE:
 		return mt9m111_set_autowhitebalance(mt9m111, ctrl->val);
+	case V4L2_CID_TEST_PATTERN:
+		return mt9m111_set_test_pattern(mt9m111, ctrl->val);
 	}
 
 	return -EINVAL;
@@ -951,6 +977,8 @@ static int mt9m111_probe(struct i2c_client *client,
 	mt9m111->ctx = &context_b;
 
 	v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
+	mt9m111->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
 	v4l2_ctrl_handler_init(&mt9m111->hdl, 5);
 	v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
 			V4L2_CID_VFLIP, 0, 1, 1, 0);
@@ -963,12 +991,24 @@ static int mt9m111_probe(struct i2c_client *client,
 	v4l2_ctrl_new_std_menu(&mt9m111->hdl,
 			&mt9m111_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
 			V4L2_EXPOSURE_AUTO);
+	v4l2_ctrl_new_std_menu_items(&mt9m111->hdl,
+			&mt9m111_ctrl_ops, V4L2_CID_TEST_PATTERN,
+			ARRAY_SIZE(mt9m111_test_pattern_menu) - 1, 0, 0,
+			mt9m111_test_pattern_menu);
 	mt9m111->subdev.ctrl_handler = &mt9m111->hdl;
 	if (mt9m111->hdl.error) {
 		ret = mt9m111->hdl.error;
 		goto out_clkput;
 	}
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+	mt9m111->pad.flags = MEDIA_PAD_FL_SOURCE;
+	mt9m111->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&mt9m111->subdev.entity, 1, &mt9m111->pad);
+	if (ret < 0)
+		goto out_hdlfree;
+#endif
+
 	/* Second stage probe - when a capture adapter is there */
 	mt9m111->rect.left	= MT9M111_MIN_DARK_COLS;
 	mt9m111->rect.top	= MT9M111_MIN_DARK_ROWS;
@@ -980,16 +1020,20 @@ static int mt9m111_probe(struct i2c_client *client,
 
 	ret = mt9m111_video_probe(client);
 	if (ret < 0)
-		goto out_hdlfree;
+		goto out_entityclean;
 
 	mt9m111->subdev.dev = &client->dev;
 	ret = v4l2_async_register_subdev(&mt9m111->subdev);
 	if (ret < 0)
-		goto out_hdlfree;
+		goto out_entityclean;
 
 	return 0;
 
+out_entityclean:
+#ifdef CONFIG_MEDIA_CONTROLLER
+	media_entity_cleanup(&mt9m111->subdev.entity);
 out_hdlfree:
+#endif
 	v4l2_ctrl_handler_free(&mt9m111->hdl);
 out_clkput:
 	v4l2_clk_put(mt9m111->clk);
@@ -1002,6 +1046,7 @@ static int mt9m111_remove(struct i2c_client *client)
 	struct mt9m111 *mt9m111 = to_mt9m111(client);
 
 	v4l2_async_unregister_subdev(&mt9m111->subdev);
+	media_entity_cleanup(&mt9m111->subdev.entity);
 	v4l2_clk_put(mt9m111->clk);
 	v4l2_ctrl_handler_free(&mt9m111->hdl);
 
diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
index 9ed1b26..5e29064 100644
--- a/drivers/media/i2c/mt9v011.c
+++ b/drivers/media/i2c/mt9v011.c
@@ -1,9 +1,8 @@
-/*
- * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor
- *
- * Copyright (c) 2009 Mauro Carvalho Chehab
- * This code is placed under the terms of the GNU General Public License v2
- */
+// SPDX-License-Identifier: GPL-2.0
+//
+// mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor
+//
+// Copyright (c) 2009 Mauro Carvalho Chehab <mchehab@kernel.org>
 
 #include <linux/i2c.h>
 #include <linux/slab.h>
@@ -17,7 +16,7 @@
 
 MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
 MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 
 static int debug;
 module_param(debug, int, 0);
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 8a43064..4de63b2 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -294,14 +294,22 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
 	/* Reset the chip and stop data read out */
 	ret = regmap_write(map, MT9V032_RESET, 1);
 	if (ret < 0)
-		return ret;
+		goto err;
 
 	ret = regmap_write(map, MT9V032_RESET, 0);
 	if (ret < 0)
-		return ret;
+		goto err;
 
-	return regmap_write(map, MT9V032_CHIP_CONTROL,
-			    MT9V032_CHIP_CONTROL_MASTER_MODE);
+	ret = regmap_write(map, MT9V032_CHIP_CONTROL,
+			   MT9V032_CHIP_CONTROL_MASTER_MODE);
+	if (ret < 0)
+		goto err;
+
+	return 0;
+
+err:
+	clk_disable_unprepare(mt9v032->clk);
+	return ret;
 }
 
 static void mt9v032_power_off(struct mt9v032 *mt9v032)
@@ -876,6 +884,9 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
 
 	/* Read and check the sensor version */
 	ret = regmap_read(mt9v032->regmap, MT9V032_CHIP_VERSION, &version);
+
+	mt9v032_power_off(mt9v032);
+
 	if (ret < 0) {
 		dev_err(&client->dev, "Failed reading chip version\n");
 		return ret;
@@ -894,8 +905,6 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
 		return -ENODEV;
 	}
 
-	mt9v032_power_off(mt9v032);
-
 	dev_info(&client->dev, "%s detected at address 0x%02x\n",
 		 mt9v032->version->name, client->addr);
 
diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c
index 5188683..4c3b927 100644
--- a/drivers/media/i2c/ov2640.c
+++ b/drivers/media/i2c/ov2640.c
@@ -1147,9 +1147,7 @@ static int ov2640_probe(struct i2c_client *client,
 	return 0;
 
 err_videoprobe:
-#if defined(CONFIG_MEDIA_CONTROLLER)
 	media_entity_cleanup(&priv->subdev.entity);
-#endif
 err_hdl:
 	v4l2_ctrl_handler_free(&priv->hdl);
 err_clk:
@@ -1163,9 +1161,7 @@ static int ov2640_remove(struct i2c_client *client)
 
 	v4l2_async_unregister_subdev(&priv->subdev);
 	v4l2_ctrl_handler_free(&priv->hdl);
-#if defined(CONFIG_MEDIA_CONTROLLER)
 	media_entity_cleanup(&priv->subdev.entity);
-#endif
 	v4l2_device_unregister_subdev(&priv->subdev);
 	clk_disable_unprepare(priv->clk);
 	return 0;
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 122dd6c..4715edc 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1474,9 +1474,7 @@ static int ov2659_probe(struct i2c_client *client,
 
 error:
 	v4l2_ctrl_handler_free(&ov2659->ctrls);
-#if defined(CONFIG_MEDIA_CONTROLLER)
 	media_entity_cleanup(&sd->entity);
-#endif
 	mutex_destroy(&ov2659->lock);
 	return ret;
 }
@@ -1488,9 +1486,7 @@ static int ov2659_remove(struct i2c_client *client)
 
 	v4l2_ctrl_handler_free(&ov2659->ctrls);
 	v4l2_async_unregister_subdev(sd);
-#if defined(CONFIG_MEDIA_CONTROLLER)
 	media_entity_cleanup(&sd->entity);
-#endif
 	mutex_destroy(&ov2659->lock);
 
 	return 0;
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index c89ed66..e2dd352 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -34,13 +34,19 @@
 
 #define OV5640_DEFAULT_SLAVE_ID 0x3c
 
+#define OV5640_REG_SYS_CTRL0		0x3008
 #define OV5640_REG_CHIP_ID		0x300a
+#define OV5640_REG_IO_MIPI_CTRL00	0x300e
+#define OV5640_REG_PAD_OUTPUT_ENABLE01	0x3017
+#define OV5640_REG_PAD_OUTPUT_ENABLE02	0x3018
 #define OV5640_REG_PAD_OUTPUT00		0x3019
+#define OV5640_REG_SYSTEM_CONTROL1	0x302e
 #define OV5640_REG_SC_PLL_CTRL0		0x3034
 #define OV5640_REG_SC_PLL_CTRL1		0x3035
 #define OV5640_REG_SC_PLL_CTRL2		0x3036
 #define OV5640_REG_SC_PLL_CTRL3		0x3037
 #define OV5640_REG_SLAVE_ID		0x3100
+#define OV5640_REG_SCCB_SYS_CTRL1	0x3103
 #define OV5640_REG_SYS_ROOT_DIVIDER	0x3108
 #define OV5640_REG_AWB_R_GAIN		0x3400
 #define OV5640_REG_AWB_G_GAIN		0x3402
@@ -70,8 +76,11 @@
 #define OV5640_REG_HZ5060_CTRL01	0x3c01
 #define OV5640_REG_SIGMADELTA_CTRL0C	0x3c0c
 #define OV5640_REG_FRAME_CTRL01		0x4202
+#define OV5640_REG_FORMAT_CONTROL00	0x4300
+#define OV5640_REG_POLARITY_CTRL00	0x4740
 #define OV5640_REG_MIPI_CTRL00		0x4800
 #define OV5640_REG_DEBUG_MODE		0x4814
+#define OV5640_REG_ISP_FORMAT_MUX_CTRL	0x501f
 #define OV5640_REG_PRE_ISP_TEST_SET1	0x503d
 #define OV5640_REG_SDE_CTRL0		0x5580
 #define OV5640_REG_SDE_CTRL1		0x5581
@@ -99,6 +108,18 @@ enum ov5640_frame_rate {
 	OV5640_NUM_FRAMERATES,
 };
 
+struct ov5640_pixfmt {
+	u32 code;
+	u32 colorspace;
+};
+
+static const struct ov5640_pixfmt ov5640_formats[] = {
+	{ MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, },
+	{ MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, },
+	{ MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, },
+	{ MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, },
+};
+
 /*
  * FIXME: remove this when a subdev API becomes available
  * to set the MIPI CSI-2 virtual channel.
@@ -982,7 +1003,111 @@ static int ov5640_get_gain(struct ov5640_dev *sensor)
 	return gain & 0x3ff;
 }
 
-static int ov5640_set_stream(struct ov5640_dev *sensor, bool on)
+static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on)
+{
+	int ret;
+	unsigned int flags = sensor->ep.bus.parallel.flags;
+	u8 pclk_pol = 0;
+	u8 hsync_pol = 0;
+	u8 vsync_pol = 0;
+
+	/*
+	 * Note about parallel port configuration.
+	 *
+	 * When configured in parallel mode, the OV5640 will
+	 * output 10 bits data on DVP data lines [9:0].
+	 * If only 8 bits data are wanted, the 8 bits data lines
+	 * of the camera interface must be physically connected
+	 * on the DVP data lines [9:2].
+	 *
+	 * Control lines polarity can be configured through
+	 * devicetree endpoint control lines properties.
+	 * If no endpoint control lines properties are set,
+	 * polarity will be as below:
+	 * - VSYNC:	active high
+	 * - HREF:	active low
+	 * - PCLK:	active low
+	 */
+
+	if (on) {
+		/*
+		 * reset MIPI PCLK/SERCLK divider
+		 *
+		 * SC PLL CONTRL1 0
+		 * - [3..0]:	MIPI PCLK/SERCLK divider
+		 */
+		ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL1, 0x0f, 0);
+		if (ret)
+			return ret;
+
+		/*
+		 * configure parallel port control lines polarity
+		 *
+		 * POLARITY CTRL0
+		 * - [5]:	PCLK polarity (0: active low, 1: active high)
+		 * - [1]:	HREF polarity (0: active low, 1: active high)
+		 * - [0]:	VSYNC polarity (mismatch here between
+		 *		datasheet and hardware, 0 is active high
+		 *		and 1 is active low...)
+		 */
+		if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+			pclk_pol = 1;
+		if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+			hsync_pol = 1;
+		if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+			vsync_pol = 1;
+
+		ret = ov5640_write_reg(sensor,
+				       OV5640_REG_POLARITY_CTRL00,
+				       (pclk_pol << 5) |
+				       (hsync_pol << 1) |
+				       vsync_pol);
+
+		if (ret)
+			return ret;
+	}
+
+	/*
+	 * powerdown MIPI TX/RX PHY & disable MIPI
+	 *
+	 * MIPI CONTROL 00
+	 * 4:	 PWDN PHY TX
+	 * 3:	 PWDN PHY RX
+	 * 2:	 MIPI enable
+	 */
+	ret = ov5640_write_reg(sensor,
+			       OV5640_REG_IO_MIPI_CTRL00, on ? 0x18 : 0);
+	if (ret)
+		return ret;
+
+	/*
+	 * enable VSYNC/HREF/PCLK DVP control lines
+	 * & D[9:6] DVP data lines
+	 *
+	 * PAD OUTPUT ENABLE 01
+	 * - 6:		VSYNC output enable
+	 * - 5:		HREF output enable
+	 * - 4:		PCLK output enable
+	 * - [3:0]:	D[9:6] output enable
+	 */
+	ret = ov5640_write_reg(sensor,
+			       OV5640_REG_PAD_OUTPUT_ENABLE01,
+			       on ? 0x7f : 0);
+	if (ret)
+		return ret;
+
+	/*
+	 * enable D[5:0] DVP data lines
+	 *
+	 * PAD OUTPUT ENABLE 02
+	 * - [7:2]:	D[5:0] output enable
+	 */
+	return ov5640_write_reg(sensor,
+				OV5640_REG_PAD_OUTPUT_ENABLE02,
+				on ? 0xfc : 0);
+}
+
+static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
 {
 	int ret;
 
@@ -1524,7 +1649,7 @@ static int ov5640_restore_mode(struct ov5640_dev *sensor)
 
 static void ov5640_power(struct ov5640_dev *sensor, bool enable)
 {
-	gpiod_set_value(sensor->pwdn_gpio, enable ? 0 : 1);
+	gpiod_set_value_cansleep(sensor->pwdn_gpio, enable ? 0 : 1);
 }
 
 static void ov5640_reset(struct ov5640_dev *sensor)
@@ -1532,7 +1657,7 @@ static void ov5640_reset(struct ov5640_dev *sensor)
 	if (!sensor->reset_gpio)
 		return;
 
-	gpiod_set_value(sensor->reset_gpio, 0);
+	gpiod_set_value_cansleep(sensor->reset_gpio, 0);
 
 	/* camera power cycle */
 	ov5640_power(sensor, false);
@@ -1540,56 +1665,89 @@ static void ov5640_reset(struct ov5640_dev *sensor)
 	ov5640_power(sensor, true);
 	usleep_range(5000, 10000);
 
-	gpiod_set_value(sensor->reset_gpio, 1);
+	gpiod_set_value_cansleep(sensor->reset_gpio, 1);
 	usleep_range(1000, 2000);
 
-	gpiod_set_value(sensor->reset_gpio, 0);
+	gpiod_set_value_cansleep(sensor->reset_gpio, 0);
 	usleep_range(5000, 10000);
 }
 
+static int ov5640_set_power_on(struct ov5640_dev *sensor)
+{
+	struct i2c_client *client = sensor->i2c_client;
+	int ret;
+
+	ret = clk_prepare_enable(sensor->xclk);
+	if (ret) {
+		dev_err(&client->dev, "%s: failed to enable clock\n",
+			__func__);
+		return ret;
+	}
+
+	ret = regulator_bulk_enable(OV5640_NUM_SUPPLIES,
+				    sensor->supplies);
+	if (ret) {
+		dev_err(&client->dev, "%s: failed to enable regulators\n",
+			__func__);
+		goto xclk_off;
+	}
+
+	ov5640_reset(sensor);
+	ov5640_power(sensor, true);
+
+	ret = ov5640_init_slave_id(sensor);
+	if (ret)
+		goto power_off;
+
+	return 0;
+
+power_off:
+	ov5640_power(sensor, false);
+	regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
+xclk_off:
+	clk_disable_unprepare(sensor->xclk);
+	return ret;
+}
+
+static void ov5640_set_power_off(struct ov5640_dev *sensor)
+{
+	ov5640_power(sensor, false);
+	regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
+	clk_disable_unprepare(sensor->xclk);
+}
+
 static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
 {
 	int ret = 0;
 
 	if (on) {
-		clk_prepare_enable(sensor->xclk);
-
-		ret = regulator_bulk_enable(OV5640_NUM_SUPPLIES,
-					    sensor->supplies);
+		ret = ov5640_set_power_on(sensor);
 		if (ret)
-			goto xclk_off;
-
-		ov5640_reset(sensor);
-		ov5640_power(sensor, true);
-
-		ret = ov5640_init_slave_id(sensor);
-		if (ret)
-			goto power_off;
+			return ret;
 
 		ret = ov5640_restore_mode(sensor);
 		if (ret)
 			goto power_off;
 
-		/*
-		 * start streaming briefly followed by stream off in
-		 * order to coax the clock lane into LP-11 state.
-		 */
-		ret = ov5640_set_stream(sensor, true);
-		if (ret)
-			goto power_off;
-		usleep_range(1000, 2000);
-		ret = ov5640_set_stream(sensor, false);
-		if (ret)
-			goto power_off;
+		if (sensor->ep.bus_type == V4L2_MBUS_CSI2) {
+			/*
+			 * start streaming briefly followed by stream off in
+			 * order to coax the clock lane into LP-11 state.
+			 */
+			ret = ov5640_set_stream_mipi(sensor, true);
+			if (ret)
+				goto power_off;
+			usleep_range(1000, 2000);
+			ret = ov5640_set_stream_mipi(sensor, false);
+			if (ret)
+				goto power_off;
+		}
 
 		return 0;
 	}
 
 power_off:
-	ov5640_power(sensor, false);
-	regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
-xclk_off:
-	clk_disable_unprepare(sensor->xclk);
+	ov5640_set_power_off(sensor);
 	return ret;
 }
 
@@ -1693,17 +1851,23 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd,
 {
 	struct ov5640_dev *sensor = to_ov5640_dev(sd);
 	const struct ov5640_mode_info *mode;
+	int i;
 
 	mode = ov5640_find_mode(sensor, fr, fmt->width, fmt->height, true);
 	if (!mode)
 		return -EINVAL;
-
 	fmt->width = mode->width;
 	fmt->height = mode->height;
-	fmt->code = sensor->fmt.code;
 
 	if (new_mode)
 		*new_mode = mode;
+
+	for (i = 0; i < ARRAY_SIZE(ov5640_formats); i++)
+		if (ov5640_formats[i].code == fmt->code)
+			break;
+	if (i >= ARRAY_SIZE(ov5640_formats))
+		fmt->code = ov5640_formats[0].code;
+
 	return 0;
 }
 
@@ -1746,6 +1910,45 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
 	return ret;
 }
 
+static int ov5640_set_framefmt(struct ov5640_dev *sensor,
+			       struct v4l2_mbus_framefmt *format)
+{
+	int ret = 0;
+	bool is_rgb = false;
+	u8 val;
+
+	switch (format->code) {
+	case MEDIA_BUS_FMT_UYVY8_2X8:
+		/* YUV422, UYVY */
+		val = 0x3f;
+		break;
+	case MEDIA_BUS_FMT_YUYV8_2X8:
+		/* YUV422, YUYV */
+		val = 0x30;
+		break;
+	case MEDIA_BUS_FMT_RGB565_2X8_LE:
+		/* RGB565 {g[2:0],b[4:0]},{r[4:0],g[5:3]} */
+		val = 0x6F;
+		is_rgb = true;
+		break;
+	case MEDIA_BUS_FMT_RGB565_2X8_BE:
+		/* RGB565 {r[4:0],g[5:3]},{g[2:0],b[4:0]} */
+		val = 0x61;
+		is_rgb = true;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* FORMAT CONTROL00: YUV and RGB formatting */
+	ret = ov5640_write_reg(sensor, OV5640_REG_FORMAT_CONTROL00, val);
+	if (ret)
+		return ret;
+
+	/* FORMAT MUX CONTROL: ISP YUV or RGB */
+	return ov5640_write_reg(sensor, OV5640_REG_ISP_FORMAT_MUX_CTRL,
+				is_rgb ? 0x01 : 0x00);
+}
 
 /*
  * Sensor Controls.
@@ -1854,6 +2057,7 @@ static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor, int exp)
 		if (ret < 0)
 			return ret;
 		max_exp += ret;
+		ret = 0;
 
 		if (ctrls->exposure->val < max_exp)
 			ret = ov5640_set_exposure(sensor, ctrls->exposure->val);
@@ -2131,15 +2335,12 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
 				  struct v4l2_subdev_pad_config *cfg,
 				  struct v4l2_subdev_mbus_code_enum *code)
 {
-	struct ov5640_dev *sensor = to_ov5640_dev(sd);
-
 	if (code->pad != 0)
 		return -EINVAL;
-	if (code->index != 0)
+	if (code->index >= ARRAY_SIZE(ov5640_formats))
 		return -EINVAL;
 
-	code->code = sensor->fmt.code;
-
+	code->code = ov5640_formats[code->index].code;
 	return 0;
 }
 
@@ -2155,9 +2356,17 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
 			ret = ov5640_set_mode(sensor, sensor->current_mode);
 			if (ret)
 				goto out;
+
+			ret = ov5640_set_framefmt(sensor, &sensor->fmt);
+			if (ret)
+				goto out;
 		}
 
-		ret = ov5640_set_stream(sensor, enable);
+		if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
+			ret = ov5640_set_stream_mipi(sensor, enable);
+		else
+			ret = ov5640_set_stream_dvp(sensor, enable);
+
 		if (!ret)
 			sensor->streaming = enable;
 	}
@@ -2202,6 +2411,34 @@ static int ov5640_get_regulators(struct ov5640_dev *sensor)
 				       sensor->supplies);
 }
 
+static int ov5640_check_chip_id(struct ov5640_dev *sensor)
+{
+	struct i2c_client *client = sensor->i2c_client;
+	int ret = 0;
+	u16 chip_id;
+
+	ret = ov5640_set_power_on(sensor);
+	if (ret)
+		return ret;
+
+	ret = ov5640_read_reg16(sensor, OV5640_REG_CHIP_ID, &chip_id);
+	if (ret) {
+		dev_err(&client->dev, "%s: failed to read chip identifier\n",
+			__func__);
+		goto power_off;
+	}
+
+	if (chip_id != 0x5640) {
+		dev_err(&client->dev, "%s: wrong chip identifier, expected 0x5640, got 0x%x\n",
+			__func__, chip_id);
+		ret = -ENXIO;
+	}
+
+power_off:
+	ov5640_set_power_off(sensor);
+	return ret;
+}
+
 static int ov5640_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -2242,11 +2479,6 @@ static int ov5640_probe(struct i2c_client *client,
 		return ret;
 	}
 
-	if (sensor->ep.bus_type != V4L2_MBUS_CSI2) {
-		dev_err(dev, "invalid bus type, must be MIPI CSI2\n");
-		return -EINVAL;
-	}
-
 	/* get system clock (xclk) */
 	sensor->xclk = devm_clk_get(dev, "xclk");
 	if (IS_ERR(sensor->xclk)) {
@@ -2284,6 +2516,10 @@ static int ov5640_probe(struct i2c_client *client,
 
 	mutex_init(&sensor->lock);
 
+	ret = ov5640_check_chip_id(sensor);
+	if (ret)
+		goto entity_cleanup;
+
 	ret = ov5640_init_controls(sensor);
 	if (ret)
 		goto entity_cleanup;
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index 950a0ac..28571de 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -163,6 +163,11 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
 #define   DBLV_X6	  0x10	  /* clock x6 */
 #define   DBLV_X8	  0x11	  /* clock x8 */
 
+#define REG_SCALING_XSC	0x70	/* Test pattern and horizontal scale factor */
+#define   TEST_PATTTERN_0 0x80
+#define REG_SCALING_YSC	0x71	/* Test pattern and vertical scale factor */
+#define   TEST_PATTTERN_1 0x80
+
 #define REG_REG76	0x76	/* OV's name */
 #define   R76_BLKPCOR	  0x80	  /* Black pixel correction enable */
 #define   R76_WHTPCOR	  0x40	  /* White pixel correction enable */
@@ -292,7 +297,8 @@ static struct regval_list ov7670_default_regs[] = {
 
 	{ REG_COM3, 0 },	{ REG_COM14, 0 },
 	/* Mystery scaling numbers */
-	{ 0x70, 0x3a },		{ 0x71, 0x35 },
+	{ REG_SCALING_XSC, 0x3a },
+	{ REG_SCALING_YSC, 0x35 },
 	{ 0x72, 0x11 },		{ 0x73, 0xf0 },
 	{ 0xa2, 0x02 },		{ REG_COM10, 0x0 },
 
@@ -406,12 +412,12 @@ static struct regval_list ov7670_fmt_yuv422[] = {
 	{ REG_COM1, 0 },	/* CCIR601 */
 	{ REG_COM15, COM15_R00FF },
 	{ REG_COM9, 0x48 }, /* 32x gain ceiling; 0x8 is reserved bit */
-	{ 0x4f, 0x80 }, 	/* "matrix coefficient 1" */
-	{ 0x50, 0x80 }, 	/* "matrix coefficient 2" */
+	{ 0x4f, 0x80 },		/* "matrix coefficient 1" */
+	{ 0x50, 0x80 },		/* "matrix coefficient 2" */
 	{ 0x51, 0    },		/* vb */
-	{ 0x52, 0x22 }, 	/* "matrix coefficient 4" */
-	{ 0x53, 0x5e }, 	/* "matrix coefficient 5" */
-	{ 0x54, 0x80 }, 	/* "matrix coefficient 6" */
+	{ 0x52, 0x22 },		/* "matrix coefficient 4" */
+	{ 0x53, 0x5e },		/* "matrix coefficient 5" */
+	{ 0x54, 0x80 },		/* "matrix coefficient 6" */
 	{ REG_COM13, COM13_GAMMA|COM13_UVSAT },
 	{ 0xff, 0xff },
 };
@@ -421,13 +427,13 @@ static struct regval_list ov7670_fmt_rgb565[] = {
 	{ REG_RGB444, 0 },	/* No RGB444 please */
 	{ REG_COM1, 0x0 },	/* CCIR601 */
 	{ REG_COM15, COM15_RGB565 },
-	{ REG_COM9, 0x38 }, 	/* 16x gain ceiling; 0x8 is reserved bit */
-	{ 0x4f, 0xb3 }, 	/* "matrix coefficient 1" */
-	{ 0x50, 0xb3 }, 	/* "matrix coefficient 2" */
+	{ REG_COM9, 0x38 },	/* 16x gain ceiling; 0x8 is reserved bit */
+	{ 0x4f, 0xb3 },		/* "matrix coefficient 1" */
+	{ 0x50, 0xb3 },		/* "matrix coefficient 2" */
 	{ 0x51, 0    },		/* vb */
-	{ 0x52, 0x3d }, 	/* "matrix coefficient 4" */
-	{ 0x53, 0xa7 }, 	/* "matrix coefficient 5" */
-	{ 0x54, 0xe4 }, 	/* "matrix coefficient 6" */
+	{ 0x52, 0x3d },		/* "matrix coefficient 4" */
+	{ 0x53, 0xa7 },		/* "matrix coefficient 5" */
+	{ 0x54, 0xe4 },		/* "matrix coefficient 6" */
 	{ REG_COM13, COM13_GAMMA|COM13_UVSAT },
 	{ 0xff, 0xff },
 };
@@ -437,13 +443,13 @@ static struct regval_list ov7670_fmt_rgb444[] = {
 	{ REG_RGB444, R444_ENABLE },	/* Enable xxxxrrrr ggggbbbb */
 	{ REG_COM1, 0x0 },	/* CCIR601 */
 	{ REG_COM15, COM15_R01FE|COM15_RGB565 }, /* Data range needed? */
-	{ REG_COM9, 0x38 }, 	/* 16x gain ceiling; 0x8 is reserved bit */
-	{ 0x4f, 0xb3 }, 	/* "matrix coefficient 1" */
-	{ 0x50, 0xb3 }, 	/* "matrix coefficient 2" */
+	{ REG_COM9, 0x38 },	/* 16x gain ceiling; 0x8 is reserved bit */
+	{ 0x4f, 0xb3 },		/* "matrix coefficient 1" */
+	{ 0x50, 0xb3 },		/* "matrix coefficient 2" */
 	{ 0x51, 0    },		/* vb */
-	{ 0x52, 0x3d }, 	/* "matrix coefficient 4" */
-	{ 0x53, 0xa7 }, 	/* "matrix coefficient 5" */
-	{ 0x54, 0xe4 }, 	/* "matrix coefficient 6" */
+	{ 0x52, 0x3d },		/* "matrix coefficient 4" */
+	{ 0x53, 0xa7 },		/* "matrix coefficient 5" */
+	{ 0x54, 0xe4 },		/* "matrix coefficient 6" */
 	{ REG_COM13, COM13_GAMMA|COM13_UVSAT|0x2 },  /* Magic rsvd bit */
 	{ 0xff, 0xff },
 };
@@ -568,6 +574,19 @@ static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
 		return ov7670_write_i2c(sd, reg, value);
 }
 
+static int ov7670_update_bits(struct v4l2_subdev *sd, unsigned char reg,
+		unsigned char mask, unsigned char value)
+{
+	unsigned char orig;
+	int ret;
+
+	ret = ov7670_read(sd, reg, &orig);
+	if (ret)
+		return ret;
+
+	return ov7670_write(sd, reg, (orig & ~mask) | (value & mask));
+}
+
 /*
  * Write a list of register settings; ff/ff stops the process.
  */
@@ -648,7 +667,7 @@ static struct ov7670_format_struct {
 	{
 		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
 		.colorspace	= V4L2_COLORSPACE_SRGB,
-		.regs 		= ov7670_fmt_yuv422,
+		.regs		= ov7670_fmt_yuv422,
 		.cmatrix	= { 128, -128, 0, -34, -94, 128 },
 	},
 	{
@@ -666,7 +685,7 @@ static struct ov7670_format_struct {
 	{
 		.mbus_code	= MEDIA_BUS_FMT_SBGGR8_1X8,
 		.colorspace	= V4L2_COLORSPACE_SRGB,
-		.regs 		= ov7670_fmt_raw,
+		.regs		= ov7670_fmt_raw,
 		.cmatrix	= { 0, 0, 0, 0, 0, 0 },
 	},
 };
@@ -1470,6 +1489,25 @@ static int ov7670_s_autoexp(struct v4l2_subdev *sd,
 	return ret;
 }
 
+static const char * const ov7670_test_pattern_menu[] = {
+	"No test output",
+	"Shifting \"1\"",
+	"8-bar color bar",
+	"Fade to gray color bar",
+};
+
+static int ov7670_s_test_pattern(struct v4l2_subdev *sd, int value)
+{
+	int ret;
+
+	ret = ov7670_update_bits(sd, REG_SCALING_XSC, TEST_PATTTERN_0,
+				value & BIT(0) ? TEST_PATTTERN_0 : 0);
+	if (ret)
+		return ret;
+
+	return ov7670_update_bits(sd, REG_SCALING_YSC, TEST_PATTTERN_1,
+				value & BIT(1) ? TEST_PATTTERN_1 : 0);
+}
 
 static int ov7670_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
 {
@@ -1516,6 +1554,8 @@ static int ov7670_s_ctrl(struct v4l2_ctrl *ctrl)
 			return ov7670_s_exp(sd, info->exposure->val);
 		}
 		return ov7670_s_autoexp(sd, ctrl->val);
+	case V4L2_CID_TEST_PATTERN:
+		return ov7670_s_test_pattern(sd, ctrl->val);
 	}
 	return -EINVAL;
 }
@@ -1770,6 +1810,10 @@ static int ov7670_probe(struct i2c_client *client,
 	info->auto_exposure = v4l2_ctrl_new_std_menu(&info->hdl, &ov7670_ctrl_ops,
 			V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0,
 			V4L2_EXPOSURE_AUTO);
+	v4l2_ctrl_new_std_menu_items(&info->hdl, &ov7670_ctrl_ops,
+			V4L2_CID_TEST_PATTERN,
+			ARRAY_SIZE(ov7670_test_pattern_menu) - 1, 0, 0,
+			ov7670_test_pattern_menu);
 	sd->ctrl_handler = &info->hdl;
 	if (info->hdl.error) {
 		ret = info->hdl.error;
@@ -1802,9 +1846,7 @@ static int ov7670_probe(struct i2c_client *client,
 	return 0;
 
 entity_cleanup:
-#if defined(CONFIG_MEDIA_CONTROLLER)
 	media_entity_cleanup(&info->sd.entity);
-#endif
 hdl_free:
 	v4l2_ctrl_handler_free(&info->hdl);
 power_off:
@@ -1820,12 +1862,10 @@ static int ov7670_remove(struct i2c_client *client)
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct ov7670_info *info = to_state(sd);
 
-	v4l2_device_unregister_subdev(sd);
+	v4l2_async_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&info->hdl);
 	clk_disable_unprepare(info->clk);
-#if defined(CONFIG_MEDIA_CONTROLLER)
 	media_entity_cleanup(&info->sd.entity);
-#endif
 	ov7670_s_power(sd, 0);
 	return 0;
 }
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
new file mode 100644
index 0000000..fc9dbbc
--- /dev/null
+++ b/drivers/media/i2c/ov7740.c
@@ -0,0 +1,1214 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Microchip Corporation.
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-image-sizes.h>
+#include <media/v4l2-subdev.h>
+
+#define REG_OUTSIZE_LSB 0x34
+
+/* OV7740 register tables */
+#define REG_GAIN	0x00	/* Gain lower 8 bits (rest in vref) */
+#define REG_BGAIN	0x01	/* blue gain */
+#define REG_RGAIN	0x02	/* red gain */
+#define REG_GGAIN	0x03	/* green gain */
+#define REG_REG04	0x04	/* analog setting, dont change*/
+#define REG_BAVG	0x05	/* b channel average */
+#define REG_GAVG	0x06	/* g channel average */
+#define REG_RAVG	0x07	/* r channel average */
+
+#define REG_REG0C	0x0C	/* filp enable */
+#define REG0C_IMG_FLIP		0x80
+#define REG0C_IMG_MIRROR	0x40
+
+#define REG_REG0E	0x0E	/* blc line */
+#define REG_HAEC	0x0F	/* auto exposure cntrl */
+#define REG_AEC		0x10	/* auto exposure cntrl */
+
+#define REG_CLK		0x11	/* Clock control */
+#define REG_REG55	0x55	/* Clock PLL DIV/PreDiv */
+
+#define REG_REG12	0x12
+
+#define REG_REG13	0x13	/* auto/manual AGC, AEC, Write Balance*/
+#define REG13_AEC_EN	0x01
+#define REG13_AGC_EN	0x04
+
+#define REG_REG14	0x14
+#define REG_CTRL15	0x15
+#define REG15_GAIN_MSB	0x03
+
+#define REG_REG16	0x16
+
+#define REG_MIDH	0x1C	/* manufacture id byte */
+#define REG_MIDL	0x1D	/* manufacture id byre */
+#define REG_PIDH	0x0A	/* Product ID MSB */
+#define REG_PIDL	0x0B	/* Product ID LSB */
+
+#define REG_84		0x84	/* lots of stuff */
+#define REG_REG38	0x38	/* sub-addr */
+
+#define REG_AHSTART	0x17	/* Horiz start high bits */
+#define REG_AHSIZE	0x18
+#define REG_AVSTART	0x19	/* Vert start high bits */
+#define REG_AVSIZE	0x1A
+#define REG_PSHFT	0x1b	/* Pixel delay after HREF */
+
+#define REG_HOUTSIZE	0x31
+#define REG_VOUTSIZE	0x32
+#define REG_HVSIZEOFF	0x33
+#define REG_REG34	0x34	/* DSP output size H/V LSB*/
+
+#define REG_ISP_CTRL00	0x80
+#define ISPCTRL00_AWB_EN	0x10
+#define ISPCTRL00_AWB_GAIN_EN	0x04
+
+#define	REG_YGAIN	0xE2	/* ygain for contrast control */
+
+#define	REG_YBRIGHT	  0xE3
+#define	REG_SGNSET	  0xE4
+#define	SGNSET_YBRIGHT_MASK	  0x08
+
+#define REG_USAT	0xDD
+#define REG_VSAT	0xDE
+
+
+struct ov7740 {
+	struct v4l2_subdev subdev;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	struct media_pad pad;
+#endif
+	struct v4l2_mbus_framefmt format;
+	const struct ov7740_pixfmt *fmt;  /* Current format */
+	const struct ov7740_framesize *frmsize;
+	struct regmap *regmap;
+	struct clk *xvclk;
+	struct v4l2_ctrl_handler ctrl_handler;
+	struct {
+		/* gain cluster */
+		struct v4l2_ctrl *auto_gain;
+		struct v4l2_ctrl *gain;
+	};
+	struct {
+		struct v4l2_ctrl *auto_wb;
+		struct v4l2_ctrl *blue_balance;
+		struct v4l2_ctrl *red_balance;
+	};
+	struct {
+		struct v4l2_ctrl *hflip;
+		struct v4l2_ctrl *vflip;
+	};
+	struct {
+		/* exposure cluster */
+		struct v4l2_ctrl *auto_exposure;
+		struct v4l2_ctrl *exposure;
+	};
+	struct {
+		/* saturation/hue cluster */
+		struct v4l2_ctrl *saturation;
+		struct v4l2_ctrl *hue;
+	};
+	struct v4l2_ctrl *brightness;
+	struct v4l2_ctrl *contrast;
+
+	struct mutex mutex;	/* To serialize asynchronus callbacks */
+	bool streaming;		/* Streaming on/off */
+
+	struct gpio_desc *resetb_gpio;
+	struct gpio_desc *pwdn_gpio;
+};
+
+struct ov7740_pixfmt {
+	u32 mbus_code;
+	enum v4l2_colorspace colorspace;
+	const struct reg_sequence *regs;
+	u32 reg_num;
+};
+
+struct ov7740_framesize {
+	u16 width;
+	u16 height;
+	const struct reg_sequence *regs;
+	u32 reg_num;
+};
+
+static const struct reg_sequence ov7740_vga[] = {
+	{0x55, 0x40},
+	{0x11, 0x02},
+
+	{0xd5, 0x10},
+	{0x0c, 0x12},
+	{0x0d, 0x34},
+	{0x17, 0x25},
+	{0x18, 0xa0},
+	{0x19, 0x03},
+	{0x1a, 0xf0},
+	{0x1b, 0x89},
+	{0x22, 0x03},
+	{0x29, 0x18},
+	{0x2b, 0xf8},
+	{0x2c, 0x01},
+	{REG_HOUTSIZE, 0xa0},
+	{REG_VOUTSIZE, 0xf0},
+	{0x33, 0xc4},
+	{REG_OUTSIZE_LSB, 0x0},
+	{0x35, 0x05},
+	{0x04, 0x60},
+	{0x27, 0x80},
+	{0x3d, 0x0f},
+	{0x3e, 0x80},
+	{0x3f, 0x40},
+	{0x40, 0x7f},
+	{0x41, 0x6a},
+	{0x42, 0x29},
+	{0x44, 0x22},
+	{0x45, 0x41},
+	{0x47, 0x02},
+	{0x49, 0x64},
+	{0x4a, 0xa1},
+	{0x4b, 0x40},
+	{0x4c, 0x1a},
+	{0x4d, 0x50},
+	{0x4e, 0x13},
+	{0x64, 0x00},
+	{0x67, 0x88},
+	{0x68, 0x1a},
+
+	{0x14, 0x28},
+	{0x24, 0x3c},
+	{0x25, 0x30},
+	{0x26, 0x72},
+	{0x50, 0x97},
+	{0x51, 0x1f},
+	{0x52, 0x00},
+	{0x53, 0x00},
+	{0x20, 0x00},
+	{0x21, 0xcf},
+	{0x50, 0x4b},
+	{0x38, 0x14},
+	{0xe9, 0x00},
+	{0x56, 0x55},
+	{0x57, 0xff},
+	{0x58, 0xff},
+	{0x59, 0xff},
+	{0x5f, 0x04},
+	{0xec, 0x00},
+	{0x13, 0xff},
+
+	{0x81, 0x3f},
+	{0x82, 0x32},
+	{0x38, 0x11},
+	{0x84, 0x70},
+	{0x85, 0x00},
+	{0x86, 0x03},
+	{0x87, 0x01},
+	{0x88, 0x05},
+	{0x89, 0x30},
+	{0x8d, 0x30},
+	{0x8f, 0x85},
+	{0x93, 0x30},
+	{0x95, 0x85},
+	{0x99, 0x30},
+	{0x9b, 0x85},
+
+	{0x9c, 0x08},
+	{0x9d, 0x12},
+	{0x9e, 0x23},
+	{0x9f, 0x45},
+	{0xa0, 0x55},
+	{0xa1, 0x64},
+	{0xa2, 0x72},
+	{0xa3, 0x7f},
+	{0xa4, 0x8b},
+	{0xa5, 0x95},
+	{0xa6, 0xa7},
+	{0xa7, 0xb5},
+	{0xa8, 0xcb},
+	{0xa9, 0xdd},
+	{0xaa, 0xec},
+	{0xab, 0x1a},
+
+	{0xce, 0x78},
+	{0xcf, 0x6e},
+	{0xd0, 0x0a},
+	{0xd1, 0x0c},
+	{0xd2, 0x84},
+	{0xd3, 0x90},
+	{0xd4, 0x1e},
+
+	{0x5a, 0x24},
+	{0x5b, 0x1f},
+	{0x5c, 0x88},
+	{0x5d, 0x60},
+
+	{0xac, 0x6e},
+	{0xbe, 0xff},
+	{0xbf, 0x00},
+
+	{0x0f, 0x1d},
+	{0x0f, 0x1f},
+};
+
+static const struct ov7740_framesize ov7740_framesizes[] = {
+	{
+		.width		= VGA_WIDTH,
+		.height		= VGA_HEIGHT,
+		.regs		= ov7740_vga,
+		.reg_num	= ARRAY_SIZE(ov7740_vga),
+	},
+};
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov7740_get_register(struct v4l2_subdev *sd,
+			       struct v4l2_dbg_register *reg)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	struct regmap *regmap = ov7740->regmap;
+	unsigned int val = 0;
+	int ret;
+
+	ret = regmap_read(regmap, reg->reg & 0xff, &val);
+	reg->val = val;
+	reg->size = 1;
+
+	return 0;
+}
+
+static int ov7740_set_register(struct v4l2_subdev *sd,
+			       const struct v4l2_dbg_register *reg)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	struct regmap *regmap = ov7740->regmap;
+
+	regmap_write(regmap, reg->reg & 0xff, reg->val & 0xff);
+
+	return 0;
+}
+#endif
+
+static int ov7740_set_power(struct ov7740 *ov7740, int on)
+{
+	int ret;
+
+	if (on) {
+		ret = clk_prepare_enable(ov7740->xvclk);
+		if (ret)
+			return ret;
+
+		if (ov7740->pwdn_gpio)
+			gpiod_direction_output(ov7740->pwdn_gpio, 0);
+
+		if (ov7740->resetb_gpio) {
+			gpiod_set_value(ov7740->resetb_gpio, 1);
+			usleep_range(500, 1000);
+			gpiod_set_value(ov7740->resetb_gpio, 0);
+			usleep_range(3000, 5000);
+		}
+	} else {
+		clk_disable_unprepare(ov7740->xvclk);
+
+		if (ov7740->pwdn_gpio)
+			gpiod_direction_output(ov7740->pwdn_gpio, 0);
+	}
+
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops ov7740_subdev_core_ops = {
+	.log_status = v4l2_ctrl_subdev_log_status,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register = ov7740_get_register,
+	.s_register = ov7740_set_register,
+#endif
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static int ov7740_set_white_balance(struct ov7740 *ov7740, int awb)
+{
+	struct regmap *regmap = ov7740->regmap;
+	unsigned int value;
+	int ret;
+
+	ret = regmap_read(regmap, REG_ISP_CTRL00, &value);
+	if (!ret) {
+		if (awb)
+			value |= (ISPCTRL00_AWB_EN | ISPCTRL00_AWB_GAIN_EN);
+		else
+			value &= ~(ISPCTRL00_AWB_EN | ISPCTRL00_AWB_GAIN_EN);
+		ret = regmap_write(regmap, REG_ISP_CTRL00, value);
+		if (ret)
+			return ret;
+	}
+
+	if (!awb) {
+		ret = regmap_write(regmap, REG_BGAIN,
+				   ov7740->blue_balance->val);
+		if (ret)
+			return ret;
+
+		ret = regmap_write(regmap, REG_RGAIN, ov7740->red_balance->val);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int ov7740_set_saturation(struct regmap *regmap, int value)
+{
+	int ret;
+
+	ret = regmap_write(regmap, REG_USAT, (unsigned char)value);
+	if (ret)
+		return ret;
+
+	return regmap_write(regmap, REG_VSAT, (unsigned char)value);
+}
+
+static int ov7740_set_gain(struct regmap *regmap, int value)
+{
+	int ret;
+
+	ret = regmap_write(regmap, REG_GAIN, value & 0xff);
+	if (ret)
+		return ret;
+
+	ret = regmap_update_bits(regmap, REG_CTRL15,
+				 REG15_GAIN_MSB, (value >> 8) & 0x3);
+	if (!ret)
+		ret = regmap_update_bits(regmap, REG_REG13, REG13_AGC_EN, 0);
+
+	return ret;
+}
+
+static int ov7740_set_autogain(struct regmap *regmap, int value)
+{
+	unsigned int reg;
+	int ret;
+
+	ret = regmap_read(regmap, REG_REG13, &reg);
+	if (ret)
+		return ret;
+	if (value)
+		reg |= REG13_AGC_EN;
+	else
+		reg &= ~REG13_AGC_EN;
+	return regmap_write(regmap, REG_REG13, reg);
+}
+
+static int ov7740_set_brightness(struct regmap *regmap, int value)
+{
+	/* Turn off AEC/AGC */
+	regmap_update_bits(regmap, REG_REG13, REG13_AEC_EN, 0);
+	regmap_update_bits(regmap, REG_REG13, REG13_AGC_EN, 0);
+
+	if (value >= 0) {
+		regmap_write(regmap, REG_YBRIGHT, (unsigned char)value);
+		regmap_update_bits(regmap, REG_SGNSET, SGNSET_YBRIGHT_MASK, 0);
+	} else{
+		regmap_write(regmap, REG_YBRIGHT, (unsigned char)(-value));
+		regmap_update_bits(regmap, REG_SGNSET, SGNSET_YBRIGHT_MASK, 1);
+	}
+
+	return 0;
+}
+
+static int ov7740_set_contrast(struct regmap *regmap, int value)
+{
+	return regmap_write(regmap, REG_YGAIN, (unsigned char)value);
+}
+
+static int ov7740_get_gain(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl)
+{
+	struct regmap *regmap = ov7740->regmap;
+	unsigned int value0, value1;
+	int ret;
+
+	if (!ctrl->val)
+		return 0;
+
+	ret = regmap_read(regmap, REG_GAIN, &value0);
+	if (ret)
+		return ret;
+	ret = regmap_read(regmap, REG_CTRL15, &value1);
+	if (ret)
+		return ret;
+
+	ov7740->gain->val = (value1 << 8) | (value0 & 0xff);
+
+	return 0;
+}
+
+static int ov7740_set_exp(struct regmap *regmap, int value)
+{
+	int ret;
+
+	/* Turn off AEC/AGC */
+	ret = regmap_update_bits(regmap, REG_REG13,
+				 REG13_AEC_EN | REG13_AGC_EN, 0);
+	if (ret)
+		return ret;
+
+	ret = regmap_write(regmap, REG_AEC, (unsigned char)value);
+	if (ret)
+		return ret;
+
+	return regmap_write(regmap, REG_HAEC, (unsigned char)(value >> 8));
+}
+
+static int ov7740_set_autoexp(struct regmap *regmap,
+			      enum v4l2_exposure_auto_type value)
+{
+	unsigned int reg;
+	int ret;
+
+	ret = regmap_read(regmap, REG_REG13, &reg);
+	if (!ret) {
+		if (value == V4L2_EXPOSURE_AUTO)
+			reg |= (REG13_AEC_EN | REG13_AGC_EN);
+		else
+			reg &= ~(REG13_AEC_EN | REG13_AGC_EN);
+		ret = regmap_write(regmap, REG_REG13, reg);
+	}
+
+	return ret;
+}
+
+
+static int ov7740_get_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ov7740 *ov7740 = container_of(ctrl->handler,
+					     struct ov7740, ctrl_handler);
+	int ret;
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUTOGAIN:
+		ret = ov7740_get_gain(ov7740, ctrl);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ov7740 *ov7740 = container_of(ctrl->handler,
+					     struct ov7740, ctrl_handler);
+	struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
+	struct regmap *regmap = ov7740->regmap;
+	int ret;
+	u8 val = 0;
+
+	if (pm_runtime_get_if_in_use(&client->dev) <= 0)
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUTO_WHITE_BALANCE:
+		ret = ov7740_set_white_balance(ov7740, ctrl->val);
+		break;
+	case V4L2_CID_SATURATION:
+		ret = ov7740_set_saturation(regmap, ctrl->val);
+		break;
+	case V4L2_CID_BRIGHTNESS:
+		ret = ov7740_set_brightness(regmap, ctrl->val);
+		break;
+	case V4L2_CID_CONTRAST:
+		ret = ov7740_set_contrast(regmap, ctrl->val);
+		break;
+	case V4L2_CID_VFLIP:
+		ret = regmap_update_bits(regmap, REG_REG0C,
+					 REG0C_IMG_FLIP, val);
+		break;
+	case V4L2_CID_HFLIP:
+		val = ctrl->val ? REG0C_IMG_MIRROR : 0x00;
+		ret = regmap_update_bits(regmap, REG_REG0C,
+					 REG0C_IMG_MIRROR, val);
+		break;
+	case V4L2_CID_AUTOGAIN:
+		if (!ctrl->val)
+			return ov7740_set_gain(regmap, ov7740->gain->val);
+
+		ret = ov7740_set_autogain(regmap, ctrl->val);
+		break;
+
+	case V4L2_CID_EXPOSURE_AUTO:
+		if (ctrl->val == V4L2_EXPOSURE_MANUAL)
+			return ov7740_set_exp(regmap, ov7740->exposure->val);
+
+		ret = ov7740_set_autoexp(regmap, ctrl->val);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	pm_runtime_put(&client->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops ov7740_ctrl_ops = {
+	.g_volatile_ctrl = ov7740_get_volatile_ctrl,
+	.s_ctrl = ov7740_set_ctrl,
+};
+
+static int ov7740_start_streaming(struct ov7740 *ov7740)
+{
+	int ret;
+
+	if (ov7740->fmt) {
+		ret = regmap_multi_reg_write(ov7740->regmap,
+					     ov7740->fmt->regs,
+					     ov7740->fmt->reg_num);
+		if (ret)
+			return ret;
+	}
+
+	if (ov7740->frmsize) {
+		ret = regmap_multi_reg_write(ov7740->regmap,
+					     ov7740->frmsize->regs,
+					     ov7740->frmsize->reg_num);
+		if (ret)
+			return ret;
+	}
+
+	return __v4l2_ctrl_handler_setup(ov7740->subdev.ctrl_handler);
+}
+
+static int ov7740_set_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	int ret = 0;
+
+	mutex_lock(&ov7740->mutex);
+	if (ov7740->streaming == enable) {
+		mutex_unlock(&ov7740->mutex);
+		return 0;
+	}
+
+	if (enable) {
+		ret = pm_runtime_get_sync(&client->dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(&client->dev);
+			goto err_unlock;
+		}
+
+		ret = ov7740_start_streaming(ov7740);
+		if (ret)
+			goto err_rpm_put;
+	} else {
+		pm_runtime_put(&client->dev);
+	}
+
+	ov7740->streaming = enable;
+
+	mutex_unlock(&ov7740->mutex);
+	return ret;
+
+err_rpm_put:
+	pm_runtime_put(&client->dev);
+err_unlock:
+	mutex_unlock(&ov7740->mutex);
+	return ret;
+}
+
+static int ov7740_get_parm(struct v4l2_subdev *sd,
+			   struct v4l2_streamparm *parms)
+{
+	struct v4l2_captureparm *cp = &parms->parm.capture;
+	struct v4l2_fract *tpf = &cp->timeperframe;
+
+	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	memset(cp, 0, sizeof(struct v4l2_captureparm));
+	cp->capability = V4L2_CAP_TIMEPERFRAME;
+
+	tpf->numerator = 1;
+	tpf->denominator = 60;
+
+	return 0;
+}
+
+static int ov7740_set_parm(struct v4l2_subdev *sd,
+			   struct v4l2_streamparm *parms)
+{
+	struct v4l2_captureparm *cp = &parms->parm.capture;
+	struct v4l2_fract *tpf = &cp->timeperframe;
+
+	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (cp->extendedmode != 0)
+		return -EINVAL;
+
+	cp->capability = V4L2_CAP_TIMEPERFRAME;
+
+	tpf->numerator = 1;
+	tpf->denominator = 60;
+
+	return 0;
+}
+
+static struct v4l2_subdev_video_ops ov7740_subdev_video_ops = {
+	.s_stream = ov7740_set_stream,
+	.s_parm = ov7740_set_parm,
+	.g_parm = ov7740_get_parm,
+};
+
+static const struct reg_sequence ov7740_format_yuyv[] = {
+	{0x12, 0x00},
+	{0x36, 0x3f},
+	{0x80, 0x7f},
+	{0x83, 0x01},
+};
+
+static const struct reg_sequence ov7740_format_bggr8[] = {
+	{0x36, 0x2f},
+	{0x80, 0x01},
+	{0x83, 0x04},
+};
+
+static const struct ov7740_pixfmt ov7740_formats[] = {
+	{
+		.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.regs = ov7740_format_yuyv,
+		.reg_num = ARRAY_SIZE(ov7740_format_yuyv),
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.regs = ov7740_format_bggr8,
+		.reg_num = ARRAY_SIZE(ov7740_format_bggr8),
+	}
+};
+#define N_OV7740_FMTS ARRAY_SIZE(ov7740_formats)
+
+static int ov7740_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_pad_config *cfg,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->pad || code->index >= N_OV7740_FMTS)
+		return -EINVAL;
+
+	code->code = ov7740_formats[code->index].mbus_code;
+
+	return 0;
+}
+
+static int ov7740_enum_frame_interval(struct v4l2_subdev *sd,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->pad)
+		return -EINVAL;
+
+	if (fie->index >= 1)
+		return -EINVAL;
+
+	if ((fie->width != VGA_WIDTH) || (fie->height != VGA_HEIGHT))
+		return -EINVAL;
+
+	fie->interval.numerator = 1;
+	fie->interval.denominator = 60;
+
+	return 0;
+}
+
+static int ov7740_enum_frame_size(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_pad_config *cfg,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->pad)
+		return -EINVAL;
+
+	if (fse->index > 0)
+		return -EINVAL;
+
+	fse->min_width = fse->max_width = VGA_WIDTH;
+	fse->min_height = fse->max_height = VGA_HEIGHT;
+
+	return 0;
+}
+
+static int ov7740_try_fmt_internal(struct v4l2_subdev *sd,
+				   struct v4l2_mbus_framefmt *fmt,
+				   const struct ov7740_pixfmt **ret_fmt,
+				   const struct ov7740_framesize **ret_frmsize)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	const struct ov7740_framesize *fsize = &ov7740_framesizes[0];
+	int index, i;
+
+	for (index = 0; index < N_OV7740_FMTS; index++) {
+		if (ov7740_formats[index].mbus_code == fmt->code)
+			break;
+	}
+	if (index >= N_OV7740_FMTS) {
+		/* default to first format */
+		index = 0;
+		fmt->code = ov7740_formats[0].mbus_code;
+	}
+	if (ret_fmt != NULL)
+		*ret_fmt = ov7740_formats + index;
+
+	for (i = 0; i < ARRAY_SIZE(ov7740_framesizes); i++) {
+		if ((fsize->width >= fmt->width) &&
+		    (fsize->height >= fmt->height)) {
+			fmt->width = fsize->width;
+			fmt->height = fsize->height;
+			break;
+		}
+
+		fsize++;
+	}
+
+	if (ret_frmsize != NULL)
+		*ret_frmsize = fsize;
+
+	fmt->field = V4L2_FIELD_NONE;
+	fmt->colorspace = ov7740_formats[index].colorspace;
+
+	ov7740->format = *fmt;
+
+	return 0;
+}
+
+static int ov7740_set_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_format *format)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	const struct ov7740_pixfmt *ovfmt;
+	const struct ov7740_framesize *fsize;
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	struct v4l2_mbus_framefmt *mbus_fmt;
+#endif
+	int ret;
+
+	mutex_lock(&ov7740->mutex);
+	if (format->pad) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+		ret = ov7740_try_fmt_internal(sd, &format->format, NULL, NULL);
+		if (ret)
+			goto error;
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
+		*mbus_fmt = format->format;
+
+		mutex_unlock(&ov7740->mutex);
+		return 0;
+#else
+		ret = -ENOTTY;
+		goto error;
+#endif
+	}
+
+	ret = ov7740_try_fmt_internal(sd, &format->format, &ovfmt, &fsize);
+	if (ret)
+		goto error;
+
+	ov7740->fmt = ovfmt;
+	ov7740->frmsize = fsize;
+
+	mutex_unlock(&ov7740->mutex);
+	return 0;
+
+error:
+	mutex_unlock(&ov7740->mutex);
+	return ret;
+}
+
+static int ov7740_get_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_pad_config *cfg,
+			  struct v4l2_subdev_format *format)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	struct v4l2_mbus_framefmt *mbus_fmt;
+#endif
+	int ret = 0;
+
+	mutex_lock(&ov7740->mutex);
+	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+		mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
+		format->format = *mbus_fmt;
+		ret = 0;
+#else
+		ret = -ENOTTY;
+#endif
+	} else {
+		format->format = ov7740->format;
+	}
+	mutex_unlock(&ov7740->mutex);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_pad_ops ov7740_subdev_pad_ops = {
+	.enum_frame_interval = ov7740_enum_frame_interval,
+	.enum_frame_size = ov7740_enum_frame_size,
+	.enum_mbus_code = ov7740_enum_mbus_code,
+	.get_fmt = ov7740_get_fmt,
+	.set_fmt = ov7740_set_fmt,
+};
+
+static const struct v4l2_subdev_ops ov7740_subdev_ops = {
+	.core	= &ov7740_subdev_core_ops,
+	.video	= &ov7740_subdev_video_ops,
+	.pad	= &ov7740_subdev_pad_ops,
+};
+
+static void ov7740_get_default_format(struct v4l2_subdev *sd,
+				      struct v4l2_mbus_framefmt *format)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+	format->width = ov7740->frmsize->width;
+	format->height = ov7740->frmsize->height;
+	format->colorspace = ov7740->fmt->colorspace;
+	format->code = ov7740->fmt->mbus_code;
+	format->field = V4L2_FIELD_NONE;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int ov7740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+	struct v4l2_mbus_framefmt *format =
+				v4l2_subdev_get_try_format(sd, fh->pad, 0);
+
+	mutex_lock(&ov7740->mutex);
+	ov7740_get_default_format(sd, format);
+	mutex_unlock(&ov7740->mutex);
+
+	return 0;
+}
+
+static const struct v4l2_subdev_internal_ops ov7740_subdev_internal_ops = {
+	.open = ov7740_open,
+};
+#endif
+
+static int ov7740_probe_dt(struct i2c_client *client,
+			   struct ov7740 *ov7740)
+{
+	ov7740->resetb_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+			GPIOD_OUT_HIGH);
+	if (IS_ERR(ov7740->resetb_gpio)) {
+		dev_info(&client->dev, "can't get %s GPIO\n", "reset");
+		return PTR_ERR(ov7740->resetb_gpio);
+	}
+
+	ov7740->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
+			GPIOD_OUT_LOW);
+	if (IS_ERR(ov7740->pwdn_gpio)) {
+		dev_info(&client->dev, "can't get %s GPIO\n", "powerdown");
+		return PTR_ERR(ov7740->pwdn_gpio);
+	}
+
+	return 0;
+}
+
+static int ov7740_detect(struct ov7740 *ov7740)
+{
+	struct regmap *regmap = ov7740->regmap;
+	unsigned int midh, midl, pidh, pidl;
+	int ret;
+
+	ret = regmap_read(regmap, REG_MIDH, &midh);
+	if (ret)
+		return ret;
+	if (midh != 0x7f)
+		return -ENODEV;
+
+	ret = regmap_read(regmap, REG_MIDL, &midl);
+	if (ret)
+		return ret;
+	if (midl != 0xa2)
+		return -ENODEV;
+
+	ret = regmap_read(regmap, REG_PIDH, &pidh);
+	if (ret)
+		return ret;
+	if (pidh != 0x77)
+		return -ENODEV;
+
+	ret = regmap_read(regmap, REG_PIDL, &pidl);
+	if (ret)
+		return ret;
+	if ((pidl != 0x40) && (pidl != 0x41) && (pidl != 0x42))
+		return -ENODEV;
+
+	return 0;
+}
+
+static int ov7740_init_controls(struct ov7740 *ov7740)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
+	struct v4l2_ctrl_handler *ctrl_hdlr = &ov7740->ctrl_handler;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 2);
+	if (ret < 0)
+		return ret;
+
+	ctrl_hdlr->lock = &ov7740->mutex;
+	ov7740->auto_wb = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					  V4L2_CID_AUTO_WHITE_BALANCE,
+					  0, 1, 1, 1);
+	ov7740->blue_balance = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					       V4L2_CID_BLUE_BALANCE,
+					       0, 0xff, 1, 0x80);
+	ov7740->red_balance = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					      V4L2_CID_RED_BALANCE,
+					      0, 0xff, 1, 0x80);
+
+	ov7740->brightness = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					     V4L2_CID_BRIGHTNESS,
+					     -255, 255, 1, 0);
+	ov7740->contrast = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					   V4L2_CID_CONTRAST,
+					   0, 127, 1, 0x20);
+	ov7740->saturation = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+			  V4L2_CID_SATURATION, 0, 256, 1, 0x80);
+	ov7740->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					V4L2_CID_HFLIP, 0, 1, 1, 0);
+	ov7740->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					V4L2_CID_VFLIP, 0, 1, 1, 0);
+	ov7740->gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+				       V4L2_CID_GAIN, 0, 1023, 1, 500);
+	ov7740->auto_gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					    V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
+	ov7740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+					   V4L2_CID_EXPOSURE, 0, 65535, 1, 500);
+	ov7740->auto_exposure = v4l2_ctrl_new_std_menu(ctrl_hdlr,
+					&ov7740_ctrl_ops,
+					V4L2_CID_EXPOSURE_AUTO,
+					V4L2_EXPOSURE_MANUAL, 0,
+					V4L2_EXPOSURE_AUTO);
+
+	ov7740->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	ov7740->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	v4l2_ctrl_auto_cluster(3, &ov7740->auto_wb, 0, false);
+	v4l2_ctrl_auto_cluster(2, &ov7740->auto_gain, 0, true);
+	v4l2_ctrl_auto_cluster(2, &ov7740->auto_exposure,
+			       V4L2_EXPOSURE_MANUAL, false);
+	v4l2_ctrl_cluster(2, &ov7740->hflip);
+
+	ret = v4l2_ctrl_handler_setup(ctrl_hdlr);
+	if (ret) {
+		dev_err(&client->dev, "%s control init failed (%d)\n",
+			__func__, ret);
+		goto error;
+	}
+
+	ov7740->subdev.ctrl_handler = ctrl_hdlr;
+	return 0;
+
+error:
+	v4l2_ctrl_handler_free(ctrl_hdlr);
+	mutex_destroy(&ov7740->mutex);
+	return ret;
+}
+
+static void ov7740_free_controls(struct ov7740 *ov7740)
+{
+	v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
+	mutex_destroy(&ov7740->mutex);
+}
+
+#define OV7740_MAX_REGISTER     0xff
+static const struct regmap_config ov7740_regmap_config = {
+	.reg_bits	= 8,
+	.val_bits	= 8,
+	.max_register	= OV7740_MAX_REGISTER,
+};
+
+static int ov7740_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct ov7740 *ov7740;
+	struct v4l2_subdev *sd;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev,
+			"OV7740: I2C-Adapter doesn't support SMBUS\n");
+		return -EIO;
+	}
+
+	ov7740 = devm_kzalloc(&client->dev, sizeof(*ov7740), GFP_KERNEL);
+	if (!ov7740)
+		return -ENOMEM;
+
+	ov7740->xvclk = devm_clk_get(&client->dev, "xvclk");
+	if (IS_ERR(ov7740->xvclk)) {
+		ret = PTR_ERR(ov7740->xvclk);
+		dev_err(&client->dev,
+			"OV7740: fail to get xvclk: %d\n", ret);
+		return ret;
+	}
+
+	ret = ov7740_probe_dt(client, ov7740);
+	if (ret)
+		return ret;
+
+	ov7740->regmap = devm_regmap_init_i2c(client, &ov7740_regmap_config);
+	if (IS_ERR(ov7740->regmap)) {
+		ret = PTR_ERR(ov7740->regmap);
+		dev_err(&client->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
+
+	sd = &ov7740->subdev;
+	client->flags |= I2C_CLIENT_SCCB;
+	v4l2_i2c_subdev_init(sd, client, &ov7740_subdev_ops);
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+	sd->internal_ops = &ov7740_subdev_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+#endif
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	ov7740->pad.flags = MEDIA_PAD_FL_SOURCE;
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &ov7740->pad);
+	if (ret)
+		return ret;
+#endif
+
+	ret = ov7740_set_power(ov7740, 1);
+	if (ret)
+		return ret;
+
+	ret = ov7740_detect(ov7740);
+	if (ret)
+		goto error_detect;
+
+	mutex_init(&ov7740->mutex);
+
+	ret = ov7740_init_controls(ov7740);
+	if (ret)
+		goto error_init_controls;
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	ov7740->fmt = &ov7740_formats[0];
+	ov7740->frmsize = &ov7740_framesizes[0];
+
+	ov7740_get_default_format(sd, &ov7740->format);
+
+	ret = v4l2_async_register_subdev(sd);
+	if (ret)
+		goto error_async_register;
+
+	pm_runtime_set_active(&client->dev);
+	pm_runtime_enable(&client->dev);
+	pm_runtime_idle(&client->dev);
+
+	return 0;
+
+error_async_register:
+	v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
+error_init_controls:
+	ov7740_free_controls(ov7740);
+error_detect:
+	ov7740_set_power(ov7740, 0);
+	media_entity_cleanup(&ov7740->subdev.entity);
+
+	return ret;
+}
+
+static int ov7740_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+	mutex_destroy(&ov7740->mutex);
+	v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
+	media_entity_cleanup(&ov7740->subdev.entity);
+	v4l2_async_unregister_subdev(sd);
+	ov7740_free_controls(ov7740);
+
+	pm_runtime_get_sync(&client->dev);
+	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_put_noidle(&client->dev);
+
+	ov7740_set_power(ov7740, 0);
+	return 0;
+}
+
+static int __maybe_unused ov7740_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+	ov7740_set_power(ov7740, 0);
+
+	return 0;
+}
+
+static int __maybe_unused ov7740_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+	return ov7740_set_power(ov7740, 1);
+}
+
+static const struct i2c_device_id ov7740_id[] = {
+	{ "ov7740", 0 },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, ov7740_id);
+
+static const struct dev_pm_ops ov7740_pm_ops = {
+	SET_RUNTIME_PM_OPS(ov7740_runtime_suspend, ov7740_runtime_resume, NULL)
+};
+
+static const struct of_device_id ov7740_of_match[] = {
+	{.compatible = "ovti,ov7740", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ov7740_of_match);
+
+static struct i2c_driver ov7740_i2c_driver = {
+	.driver = {
+		.name = "ov7740",
+		.pm = &ov7740_pm_ops,
+		.of_match_table = of_match_ptr(ov7740_of_match),
+	},
+	.probe    = ov7740_probe,
+	.remove   = ov7740_remove,
+	.id_table = ov7740_id,
+};
+module_i2c_driver(ov7740_i2c_driver);
+
+MODULE_DESCRIPTION("The V4L2 driver for Omnivision 7740 sensor");
+MODULE_AUTHOR("Songjun Wu <songjun.wu@atmel.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 69433e1..e519f27 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -886,10 +886,12 @@ static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl)
 		if (ctrl->val == V4L2_EXPOSURE_MANUAL)
 			return 0;
 		ret = ov965x_read(client, REG_COM1, &reg0);
-		if (!ret)
-			ret = ov965x_read(client, REG_AECH, &reg1);
-		if (!ret)
-			ret = ov965x_read(client, REG_AECHM, &reg2);
+		if (ret < 0)
+			return ret;
+		ret = ov965x_read(client, REG_AECH, &reg1);
+		if (ret < 0)
+			return ret;
+		ret = ov965x_read(client, REG_AECHM, &reg2);
 		if (ret < 0)
 			return ret;
 		exposure = ((reg2 & 0x3f) << 10) | (reg1 << 2) |
diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c
index 7202d3a..170cc65 100644
--- a/drivers/media/i2c/saa6752hs.c
+++ b/drivers/media/i2c/saa6752hs.c
@@ -72,8 +72,8 @@ struct saa6752hs_mpeg_params {
 	/* video */
 	enum v4l2_mpeg_video_aspect	vi_aspect;
 	enum v4l2_mpeg_video_bitrate_mode vi_bitrate_mode;
-	__u32 				vi_bitrate;
-	__u32 				vi_bitrate_peak;
+	__u32				vi_bitrate;
+	__u32				vi_bitrate_peak;
 };
 
 static const struct v4l2_format v4l2_format_table[] =
@@ -98,8 +98,8 @@ struct saa6752hs_state {
 		struct v4l2_ctrl *video_bitrate;
 		struct v4l2_ctrl *video_bitrate_peak;
 	};
-	u32 			      revision;
-	int 			      has_ac3;
+	u32			      revision;
+	int			      has_ac3;
 	struct saa6752hs_mpeg_params  params;
 	enum saa6752hs_videoformat    video_format;
 	v4l2_std_id                   standard;
diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
index d863b04..e216cd7 100644
--- a/drivers/media/i2c/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -1,37 +1,27 @@
-/* saa711x - Philips SAA711x video decoder driver
- * This driver can work with saa7111, saa7111a, saa7113, saa7114,
- *			     saa7115 and saa7118.
- *
- * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
- * the saa7111 driver by Dave Perks.
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr <scherr@net4you.net>
- *
- * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
- * by Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
- * (2/17/2003)
- *
- * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
- *
- * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- *	SAA7111, SAA7113 and SAA7118 support
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// saa711x - Philips SAA711x video decoder driver
+// This driver can work with saa7111, saa7111a, saa7113, saa7114,
+//			     saa7115 and saa7118.
+//
+// Based on saa7114 driver by Maxim Yevtyushkin, which is based on
+// the saa7111 driver by Dave Perks.
+//
+// Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+// Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
+//
+// Slight changes for video timing and attachment output by
+// Wolfgang Scherr <scherr@net4you.net>
+//
+// Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
+// by Ronald Bultje <rbultje@ronald.bitfreak.net>
+//
+// Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
+// (2/17/2003)
+//
+// VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
+//
+// Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
+//	SAA7111, SAA7113 and SAA7118 support
 
 #include "saa711x_regs.h"
 
@@ -758,7 +748,7 @@ static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
 	u32 acni;
 	u32 hz;
 	u64 f;
-	u8 acc = 0; 	/* reg 0x3a, audio clock control */
+	u8 acc = 0;	/* reg 0x3a, audio clock control */
 
 	/* Checks for chips that don't have audio clock (saa7111, saa7113) */
 	if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
diff --git a/drivers/media/i2c/saa711x_regs.h b/drivers/media/i2c/saa711x_regs.h
index 730ca90..a50d480 100644
--- a/drivers/media/i2c/saa711x_regs.h
+++ b/drivers/media/i2c/saa711x_regs.h
@@ -1,16 +1,8 @@
-/* saa711x - Philips SAA711x video decoder register specifications
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ * saa711x - Philips SAA711x video decoder register specifications
  *
  * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #define R_00_CHIP_VERSION                             0x00
diff --git a/drivers/media/i2c/saa7127.c b/drivers/media/i2c/saa7127.c
index 01784d4..e58a150 100644
--- a/drivers/media/i2c/saa7127.c
+++ b/drivers/media/i2c/saa7127.c
@@ -132,109 +132,109 @@ struct i2c_reg_value {
 };
 
 static const struct i2c_reg_value saa7129_init_config_extra[] = {
-	{ SAA7127_REG_OUTPUT_PORT_CONTROL, 		0x38 },
-	{ SAA7127_REG_VTRIG, 				0xfa },
+	{ SAA7127_REG_OUTPUT_PORT_CONTROL,		0x38 },
+	{ SAA7127_REG_VTRIG,				0xfa },
 	{ 0, 0 }
 };
 
 static const struct i2c_reg_value saa7127_init_config_common[] = {
-	{ SAA7127_REG_WIDESCREEN_CONFIG, 		0x0d },
-	{ SAA7127_REG_WIDESCREEN_ENABLE, 		0x00 },
-	{ SAA7127_REG_COPYGEN_0, 			0x77 },
-	{ SAA7127_REG_COPYGEN_1, 			0x41 },
-	{ SAA7127_REG_COPYGEN_2, 			0x00 },	/* Macrovision enable/disable */
-	{ SAA7127_REG_OUTPUT_PORT_CONTROL, 		0xbf },
-	{ SAA7127_REG_GAIN_LUMINANCE_RGB, 		0x00 },
-	{ SAA7127_REG_GAIN_COLORDIFF_RGB, 		0x00 },
-	{ SAA7127_REG_INPUT_PORT_CONTROL_1, 		0x80 },	/* for color bars */
-	{ SAA7127_REG_LINE_21_ODD_0, 			0x77 },
-	{ SAA7127_REG_LINE_21_ODD_1, 			0x41 },
-	{ SAA7127_REG_LINE_21_EVEN_0, 			0x88 },
-	{ SAA7127_REG_LINE_21_EVEN_1, 			0x41 },
-	{ SAA7127_REG_RCV_PORT_CONTROL, 		0x12 },
-	{ SAA7127_REG_VTRIG, 				0xf9 },
-	{ SAA7127_REG_HTRIG_HI, 			0x00 },
-	{ SAA7127_REG_RCV2_OUTPUT_START, 		0x41 },
-	{ SAA7127_REG_RCV2_OUTPUT_END, 			0xc3 },
-	{ SAA7127_REG_RCV2_OUTPUT_MSBS, 		0x00 },
-	{ SAA7127_REG_TTX_REQUEST_H_START, 		0x3e },
-	{ SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH, 	0xb8 },
-	{ SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT,  	0x03 },
-	{ SAA7127_REG_TTX_ODD_REQ_VERT_START, 		0x15 },
-	{ SAA7127_REG_TTX_ODD_REQ_VERT_END, 		0x16 },
-	{ SAA7127_REG_TTX_EVEN_REQ_VERT_START, 		0x15 },
-	{ SAA7127_REG_TTX_EVEN_REQ_VERT_END, 		0x16 },
-	{ SAA7127_REG_FIRST_ACTIVE, 			0x1a },
-	{ SAA7127_REG_LAST_ACTIVE, 			0x01 },
-	{ SAA7127_REG_MSB_VERTICAL, 			0xc0 },
-	{ SAA7127_REG_DISABLE_TTX_LINE_LO_0, 		0x00 },
-	{ SAA7127_REG_DISABLE_TTX_LINE_LO_1, 		0x00 },
+	{ SAA7127_REG_WIDESCREEN_CONFIG,		0x0d },
+	{ SAA7127_REG_WIDESCREEN_ENABLE,		0x00 },
+	{ SAA7127_REG_COPYGEN_0,			0x77 },
+	{ SAA7127_REG_COPYGEN_1,			0x41 },
+	{ SAA7127_REG_COPYGEN_2,			0x00 },	/* Macrovision enable/disable */
+	{ SAA7127_REG_OUTPUT_PORT_CONTROL,		0xbf },
+	{ SAA7127_REG_GAIN_LUMINANCE_RGB,		0x00 },
+	{ SAA7127_REG_GAIN_COLORDIFF_RGB,		0x00 },
+	{ SAA7127_REG_INPUT_PORT_CONTROL_1,		0x80 },	/* for color bars */
+	{ SAA7127_REG_LINE_21_ODD_0,			0x77 },
+	{ SAA7127_REG_LINE_21_ODD_1,			0x41 },
+	{ SAA7127_REG_LINE_21_EVEN_0,			0x88 },
+	{ SAA7127_REG_LINE_21_EVEN_1,			0x41 },
+	{ SAA7127_REG_RCV_PORT_CONTROL,			0x12 },
+	{ SAA7127_REG_VTRIG,				0xf9 },
+	{ SAA7127_REG_HTRIG_HI,				0x00 },
+	{ SAA7127_REG_RCV2_OUTPUT_START,		0x41 },
+	{ SAA7127_REG_RCV2_OUTPUT_END,			0xc3 },
+	{ SAA7127_REG_RCV2_OUTPUT_MSBS,			0x00 },
+	{ SAA7127_REG_TTX_REQUEST_H_START,		0x3e },
+	{ SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH,	0xb8 },
+	{ SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT,	0x03 },
+	{ SAA7127_REG_TTX_ODD_REQ_VERT_START,		0x15 },
+	{ SAA7127_REG_TTX_ODD_REQ_VERT_END,		0x16 },
+	{ SAA7127_REG_TTX_EVEN_REQ_VERT_START,		0x15 },
+	{ SAA7127_REG_TTX_EVEN_REQ_VERT_END,		0x16 },
+	{ SAA7127_REG_FIRST_ACTIVE,			0x1a },
+	{ SAA7127_REG_LAST_ACTIVE,			0x01 },
+	{ SAA7127_REG_MSB_VERTICAL,			0xc0 },
+	{ SAA7127_REG_DISABLE_TTX_LINE_LO_0,		0x00 },
+	{ SAA7127_REG_DISABLE_TTX_LINE_LO_1,		0x00 },
 	{ 0, 0 }
 };
 
 #define SAA7127_60HZ_DAC_CONTROL 0x15
 static const struct i2c_reg_value saa7127_init_config_60hz[] = {
-	{ SAA7127_REG_BURST_START, 			0x19 },
+	{ SAA7127_REG_BURST_START,			0x19 },
 	/* BURST_END is also used as a chip ID in saa7127_probe */
-	{ SAA7127_REG_BURST_END, 			0x1d },
-	{ SAA7127_REG_CHROMA_PHASE, 			0xa3 },
-	{ SAA7127_REG_GAINU, 				0x98 },
-	{ SAA7127_REG_GAINV, 				0xd3 },
-	{ SAA7127_REG_BLACK_LEVEL, 			0x39 },
-	{ SAA7127_REG_BLANKING_LEVEL, 			0x2e },
-	{ SAA7127_REG_VBI_BLANKING, 			0x2e },
-	{ SAA7127_REG_DAC_CONTROL, 			0x15 },
-	{ SAA7127_REG_BURST_AMP, 			0x4d },
-	{ SAA7127_REG_SUBC3, 				0x1f },
-	{ SAA7127_REG_SUBC2, 				0x7c },
-	{ SAA7127_REG_SUBC1, 				0xf0 },
-	{ SAA7127_REG_SUBC0, 				0x21 },
-	{ SAA7127_REG_MULTI, 				0x90 },
-	{ SAA7127_REG_CLOSED_CAPTION, 			0x11 },
+	{ SAA7127_REG_BURST_END,			0x1d },
+	{ SAA7127_REG_CHROMA_PHASE,			0xa3 },
+	{ SAA7127_REG_GAINU,				0x98 },
+	{ SAA7127_REG_GAINV,				0xd3 },
+	{ SAA7127_REG_BLACK_LEVEL,			0x39 },
+	{ SAA7127_REG_BLANKING_LEVEL,			0x2e },
+	{ SAA7127_REG_VBI_BLANKING,			0x2e },
+	{ SAA7127_REG_DAC_CONTROL,			0x15 },
+	{ SAA7127_REG_BURST_AMP,			0x4d },
+	{ SAA7127_REG_SUBC3,				0x1f },
+	{ SAA7127_REG_SUBC2,				0x7c },
+	{ SAA7127_REG_SUBC1,				0xf0 },
+	{ SAA7127_REG_SUBC0,				0x21 },
+	{ SAA7127_REG_MULTI,				0x90 },
+	{ SAA7127_REG_CLOSED_CAPTION,			0x11 },
 	{ 0, 0 }
 };
 
 #define SAA7127_50HZ_PAL_DAC_CONTROL 0x02
 static struct i2c_reg_value saa7127_init_config_50hz_pal[] = {
-	{ SAA7127_REG_BURST_START, 			0x21 },
+	{ SAA7127_REG_BURST_START,			0x21 },
 	/* BURST_END is also used as a chip ID in saa7127_probe */
-	{ SAA7127_REG_BURST_END, 			0x1d },
-	{ SAA7127_REG_CHROMA_PHASE, 			0x3f },
-	{ SAA7127_REG_GAINU, 				0x7d },
-	{ SAA7127_REG_GAINV, 				0xaf },
-	{ SAA7127_REG_BLACK_LEVEL, 			0x33 },
-	{ SAA7127_REG_BLANKING_LEVEL, 			0x35 },
-	{ SAA7127_REG_VBI_BLANKING, 			0x35 },
-	{ SAA7127_REG_DAC_CONTROL, 			0x02 },
-	{ SAA7127_REG_BURST_AMP, 			0x2f },
-	{ SAA7127_REG_SUBC3, 				0xcb },
-	{ SAA7127_REG_SUBC2, 				0x8a },
-	{ SAA7127_REG_SUBC1, 				0x09 },
-	{ SAA7127_REG_SUBC0, 				0x2a },
-	{ SAA7127_REG_MULTI, 				0xa0 },
-	{ SAA7127_REG_CLOSED_CAPTION, 			0x00 },
+	{ SAA7127_REG_BURST_END,			0x1d },
+	{ SAA7127_REG_CHROMA_PHASE,			0x3f },
+	{ SAA7127_REG_GAINU,				0x7d },
+	{ SAA7127_REG_GAINV,				0xaf },
+	{ SAA7127_REG_BLACK_LEVEL,			0x33 },
+	{ SAA7127_REG_BLANKING_LEVEL,			0x35 },
+	{ SAA7127_REG_VBI_BLANKING,			0x35 },
+	{ SAA7127_REG_DAC_CONTROL,			0x02 },
+	{ SAA7127_REG_BURST_AMP,			0x2f },
+	{ SAA7127_REG_SUBC3,				0xcb },
+	{ SAA7127_REG_SUBC2,				0x8a },
+	{ SAA7127_REG_SUBC1,				0x09 },
+	{ SAA7127_REG_SUBC0,				0x2a },
+	{ SAA7127_REG_MULTI,				0xa0 },
+	{ SAA7127_REG_CLOSED_CAPTION,			0x00 },
 	{ 0, 0 }
 };
 
 #define SAA7127_50HZ_SECAM_DAC_CONTROL 0x08
 static struct i2c_reg_value saa7127_init_config_50hz_secam[] = {
-	{ SAA7127_REG_BURST_START, 			0x21 },
+	{ SAA7127_REG_BURST_START,			0x21 },
 	/* BURST_END is also used as a chip ID in saa7127_probe */
-	{ SAA7127_REG_BURST_END, 			0x1d },
-	{ SAA7127_REG_CHROMA_PHASE, 			0x3f },
-	{ SAA7127_REG_GAINU, 				0x6a },
-	{ SAA7127_REG_GAINV, 				0x81 },
-	{ SAA7127_REG_BLACK_LEVEL, 			0x33 },
-	{ SAA7127_REG_BLANKING_LEVEL, 			0x35 },
-	{ SAA7127_REG_VBI_BLANKING, 			0x35 },
-	{ SAA7127_REG_DAC_CONTROL, 			0x08 },
-	{ SAA7127_REG_BURST_AMP, 			0x2f },
-	{ SAA7127_REG_SUBC3, 				0xb2 },
-	{ SAA7127_REG_SUBC2, 				0x3b },
-	{ SAA7127_REG_SUBC1, 				0xa3 },
-	{ SAA7127_REG_SUBC0, 				0x28 },
-	{ SAA7127_REG_MULTI, 				0x90 },
-	{ SAA7127_REG_CLOSED_CAPTION, 			0x00 },
+	{ SAA7127_REG_BURST_END,			0x1d },
+	{ SAA7127_REG_CHROMA_PHASE,			0x3f },
+	{ SAA7127_REG_GAINU,				0x6a },
+	{ SAA7127_REG_GAINV,				0x81 },
+	{ SAA7127_REG_BLACK_LEVEL,			0x33 },
+	{ SAA7127_REG_BLANKING_LEVEL,			0x35 },
+	{ SAA7127_REG_VBI_BLANKING,			0x35 },
+	{ SAA7127_REG_DAC_CONTROL,			0x08 },
+	{ SAA7127_REG_BURST_AMP,			0x2f },
+	{ SAA7127_REG_SUBC3,				0xb2 },
+	{ SAA7127_REG_SUBC2,				0x3b },
+	{ SAA7127_REG_SUBC1,				0xa3 },
+	{ SAA7127_REG_SUBC0,				0x28 },
+	{ SAA7127_REG_MULTI,				0x90 },
+	{ SAA7127_REG_CLOSED_CAPTION,			0x00 },
 	{ 0, 0 }
 };
 
diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c
index 102467e..668c39c 100644
--- a/drivers/media/i2c/saa717x.c
+++ b/drivers/media/i2c/saa717x.c
@@ -82,13 +82,13 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
 /* ----------------------------------------------------------------------- */
 
 /* for audio mode */
-#define TUNER_AUDIO_MONO   	0  /* LL */
-#define TUNER_AUDIO_STEREO 	1  /* LR */
-#define TUNER_AUDIO_LANG1  	2  /* LL */
-#define TUNER_AUDIO_LANG2  	3  /* RR */
+#define TUNER_AUDIO_MONO	0  /* LL */
+#define TUNER_AUDIO_STEREO	1  /* LR */
+#define TUNER_AUDIO_LANG1	2  /* LL */
+#define TUNER_AUDIO_LANG2	3  /* RR */
 
-#define SAA717X_NTSC_WIDTH   	(704)
-#define SAA717X_NTSC_HEIGHT  	(480)
+#define SAA717X_NTSC_WIDTH	(704)
+#define SAA717X_NTSC_HEIGHT	(480)
 
 /* ----------------------------------------------------------------------- */
 
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index e6b717b..3b7ace3 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -1791,7 +1791,7 @@ static int smiapp_set_format_source(struct v4l2_subdev *subdev,
 	if (csi_format->compressed == old_csi_format->compressed)
 		return 0;
 
-	valid_link_freqs = 
+	valid_link_freqs =
 		&sensor->valid_link_freqs[sensor->csi_format->compressed
 					  - sensor->compressed_min_bpp];
 
diff --git a/drivers/media/i2c/tda7432.c b/drivers/media/i2c/tda7432.c
index d87168a..1c5c61d 100644
--- a/drivers/media/i2c/tda7432.c
+++ b/drivers/media/i2c/tda7432.c
@@ -36,7 +36,6 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-ctrls.h>
-#include <media/i2c-addr.h>
 
 #ifndef VIDEO_AUDIO_BALANCE
 # define VIDEO_AUDIO_BALANCE 32
diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c
index 71a3135..8206bf7 100644
--- a/drivers/media/i2c/ths7303.c
+++ b/drivers/media/i2c/ths7303.c
@@ -319,7 +319,7 @@ static const struct v4l2_subdev_core_ops ths7303_core_ops = {
 
 static const struct v4l2_subdev_ops ths7303_ops = {
 	.core	= &ths7303_core_ops,
-	.video 	= &ths7303_video_ops,
+	.video	= &ths7303_video_ops,
 };
 
 static int ths7303_probe(struct i2c_client *client,
diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c
index 16a1e08..772164b 100644
--- a/drivers/media/i2c/tvaudio.c
+++ b/drivers/media/i2c/tvaudio.c
@@ -40,8 +40,6 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ctrls.h>
 
-#include <media/i2c-addr.h>
-
 /* ---------------------------------------------------------------------- */
 /* insmod args                                                            */
 
@@ -136,7 +134,7 @@ struct CHIPSTATE {
 	/* thread */
 	struct task_struct   *thread;
 	struct timer_list    wt;
-	int 		     audmode;
+	int		     audmode;
 };
 
 static inline struct CHIPSTATE *to_state(struct v4l2_subdev *sd)
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index d575b3e..8b0aa92 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -1131,9 +1131,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 done:
 	if (ret < 0) {
 		v4l2_ctrl_handler_free(&decoder->hdl);
-#if defined(CONFIG_MEDIA_CONTROLLER)
 		media_entity_cleanup(&decoder->sd.entity);
-#endif
 	}
 	return ret;
 }
@@ -1151,9 +1149,7 @@ static int tvp514x_remove(struct i2c_client *client)
 	struct tvp514x_decoder *decoder = to_decoder(sd);
 
 	v4l2_async_unregister_subdev(&decoder->sd);
-#if defined(CONFIG_MEDIA_CONTROLLER)
 	media_entity_cleanup(&decoder->sd.entity);
-#endif
 	v4l2_ctrl_handler_free(&decoder->hdl);
 	return 0;
 }
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 7b79a74..3c18519 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -1,9 +1,8 @@
-/*
- * tvp5150 - Texas Instruments TVP5150A/AM1 and TVP5151 video decoder driver
- *
- * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
- */
+// SPDX-License-Identifier: GPL-2.0
+//
+// tvp5150 - Texas Instruments TVP5150A/AM1 and TVP5151 video decoder driver
+//
+// Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@infradead.org>
 
 #include <dt-bindings/media/tvp5150.h>
 #include <linux/i2c.h>
@@ -30,7 +29,7 @@
 
 MODULE_DESCRIPTION("Texas Instruments TVP5150A/TVP5150AM1/TVP5151 video decoder driver");
 MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 
 
 static int debug;
diff --git a/drivers/media/i2c/tvp5150_reg.h b/drivers/media/i2c/tvp5150_reg.h
index 30a48c2..c43b7b8 100644
--- a/drivers/media/i2c/tvp5150_reg.h
+++ b/drivers/media/i2c/tvp5150_reg.h
@@ -1,8 +1,9 @@
 /*
+ * SPDX-License-Identifier: GPL-2.0
+ *
  * tvp5150 - Texas Instruments TVP5150A/AM1 video decoder registers
  *
- * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
+ * Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@infradead.org>
  */
 
 #define TVP5150_VD_IN_SRC_SEL_1      0x00 /* Video input source selection #1 */
@@ -66,10 +67,10 @@
 
 #define VIDEO_STD_NTSC_MJ_BIT_AS                 0x01
 #define VIDEO_STD_PAL_BDGHIN_BIT_AS              0x03
-#define VIDEO_STD_PAL_M_BIT_AS		         0x05
+#define VIDEO_STD_PAL_M_BIT_AS			 0x05
 #define VIDEO_STD_PAL_COMBINATION_N_BIT_AS	 0x07
 #define VIDEO_STD_NTSC_4_43_BIT_AS		 0x09
-#define VIDEO_STD_SECAM_BIT_AS		         0x0b
+#define VIDEO_STD_SECAM_BIT_AS			 0x0b
 
 /* Reserved 29h-2bh */
 
diff --git a/drivers/media/i2c/tvp7002_reg.h b/drivers/media/i2c/tvp7002_reg.h
index 9336735..3c8c8b0 100644
--- a/drivers/media/i2c/tvp7002_reg.h
+++ b/drivers/media/i2c/tvp7002_reg.h
@@ -109,15 +109,15 @@
 #define TVP7002_L_FRAME_STAT_LSBS	0x37
 #define TVP7002_L_FRAME_STAT_MSBS	0x38
 #define TVP7002_CLK_L_STAT_LSBS		0x39
-#define TVP7002_CLK_L_STAT_MSBS      	0x3a
+#define TVP7002_CLK_L_STAT_MSBS		0x3a
 #define TVP7002_HSYNC_W			0x3b
 #define TVP7002_VSYNC_W                 0x3c
-#define TVP7002_L_LENGTH_TOL 		0x3d
+#define TVP7002_L_LENGTH_TOL		0x3d
 /* Reserved 0x3e */
 #define TVP7002_VIDEO_BWTH_CTL		0x3f
 #define TVP7002_AVID_START_PIXEL_LSBS	0x40
 #define TVP7002_AVID_START_PIXEL_MSBS   0x41
-#define TVP7002_AVID_STOP_PIXEL_LSBS  	0x42
+#define TVP7002_AVID_STOP_PIXEL_LSBS	0x42
 #define TVP7002_AVID_STOP_PIXEL_MSBS    0x43
 #define TVP7002_VBLK_F_0_START_L_OFF	0x44
 #define TVP7002_VBLK_F_1_START_L_OFF    0x45
diff --git a/drivers/media/i2c/vpx3220.c b/drivers/media/i2c/vpx3220.c
index 67de79b..c3549fa 100644
--- a/drivers/media/i2c/vpx3220.c
+++ b/drivers/media/i2c/vpx3220.c
@@ -201,7 +201,7 @@ static const unsigned short init_pal[] = {
 				 * skipped by the VFE) */
 	0x8b, 16,		/* Horizontal begin */
 	0x8c, 768,		/* Horizontal length */
-	0x8d, 784, 		/* Number of pixels
+	0x8d, 784,		/* Number of pixels
 				 * Must be >= Horizontal begin + Horizontal length */
 	0x8f, 0xc00,		/* Disable window 2 */
 	0xf0, 0x77,		/* 13.5 MHz transport, Forced
diff --git a/drivers/media/mmc/siano/Makefile b/drivers/media/mmc/siano/Makefile
index 0e01f97..5fc3456 100644
--- a/drivers/media/mmc/siano/Makefile
+++ b/drivers/media/mmc/siano/Makefile
@@ -1,6 +1,4 @@
 obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
 
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/common/siano
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
 
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index da28e68..5932e22 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -54,5 +54,7 @@
 source "drivers/media/pci/netup_unidvb/Kconfig"
 endif
 
+source "drivers/media/pci/intel/ipu3/Kconfig"
+
 endif #MEDIA_PCI_SUPPORT
 endif #PCI
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index 1ab759e..1c5ab07 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -14,7 +14,8 @@
 		ddbridge/	\
 		saa7146/	\
 		smipcie/	\
-		netup_unidvb/
+		netup_unidvb/	\
+		intel/
 
 obj-$(CONFIG_VIDEO_IVTV) += ivtv/
 obj-$(CONFIG_VIDEO_ZORAN) += zoran/
diff --git a/drivers/media/pci/b2c2/Makefile b/drivers/media/pci/b2c2/Makefile
index 35d6835..b43b916 100644
--- a/drivers/media/pci/b2c2/Makefile
+++ b/drivers/media/pci/b2c2/Makefile
@@ -6,5 +6,4 @@
 b2c2-flexcop-pci-objs += flexcop-pci.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
 
-ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/common/b2c2/
diff --git a/drivers/media/pci/bt8xx/Makefile b/drivers/media/pci/bt8xx/Makefile
index 009f1dc..7f1c3be 100644
--- a/drivers/media/pci/bt8xx/Makefile
+++ b/drivers/media/pci/bt8xx/Makefile
@@ -6,8 +6,6 @@
 obj-$(CONFIG_VIDEO_BT848) += bttv.o
 obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o
 
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
-ccflags-y += -Idrivers/media/i2c
 ccflags-y += -Idrivers/media/common
 ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c
index a5f5213..f5f87e0 100644
--- a/drivers/media/pci/bt8xx/bt878.c
+++ b/drivers/media/pci/bt8xx/bt878.c
@@ -40,8 +40,8 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
 #include "bt878.h"
 #include "dst_priv.h"
 
@@ -422,8 +422,7 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
 	       bt878_num);
 	if (bt878_num >= BT878_MAX) {
 		printk(KERN_ERR "bt878: Too many devices inserted\n");
-		result = -ENOMEM;
-		goto fail0;
+		return -ENOMEM;
 	}
 	if (pci_enable_device(dev))
 		return -EIO;
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c
index 5cc42b4..1902732 100644
--- a/drivers/media/pci/bt8xx/bttv-cards.c
+++ b/drivers/media/pci/bt8xx/bttv-cards.c
@@ -141,6 +141,13 @@ MODULE_PARM_DESC(audiodev, "specify audio device:\n"
 MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition.");
 MODULE_PARM_DESC(no_overlay, "allow override overlay default (0 disables, 1 enables) [some VIA/SIS chipsets are known to have problem with overlay]");
 
+
+/* I2C addresses list */
+#define I2C_ADDR_TDA7432	0x8a
+#define I2C_ADDR_MSP3400	0x80
+#define I2C_ADDR_MSP3400_ALT	0x88
+
+
 /* ----------------------------------------------------------------------- */
 /* list of card IDs for bt878+ cards                                       */
 
@@ -366,8 +373,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 15,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 2, 0, 0, 0 },
-		.gpiomute 	= 10,
+		.gpiomux	= { 2, 0, 0, 0 },
+		.gpiomute	= 10,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -378,8 +385,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 7,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 1, 2, 3 },
-		.gpiomute 	= 4,
+		.gpiomux	= { 0, 1, 2, 3 },
+		.gpiomute	= 4,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -390,8 +397,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 7,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 4, 0, 2, 3 },
-		.gpiomute 	= 1,
+		.gpiomux	= { 4, 0, 2, 3 },
+		.gpiomute	= 1,
 		.no_msp34xx	= 1,
 		.tuner_type     = TUNER_PHILIPS_NTSC,
 		.tuner_addr	= ADDR_UNSET,
@@ -407,7 +414,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0 },
+		.gpiomux	= { 0 },
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -418,8 +425,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 3,
 		.muxsel		= MUXSEL(2, 3, 1, 0),
-		.gpiomux 	= { 0, 1, 0, 1 },
-		.gpiomute 	= 3,
+		.gpiomux	= { 0, 1, 0, 1 },
+		.gpiomute	= 3,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -430,7 +437,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 3,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomask	= 0x0f,
-		.gpiomux 	= { 0x0c, 0x04, 0x08, 0x04 },
+		.gpiomux	= { 0x0c, 0x04, 0x08, 0x04 },
 		/*                0x04 for some cards ?? */
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -444,7 +451,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 3,
 		.gpiomask	= 0,
 		.muxsel		= MUXSEL(2, 3, 1, 0, 0),
-		.gpiomux 	= { 0 },
+		.gpiomux	= { 0 },
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -457,8 +464,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0xc00,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 0xc00, 0x800, 0x400 },
-		.gpiomute 	= 0xc00,
+		.gpiomux	= { 0, 0xc00, 0x800, 0x400 },
+		.gpiomute	= 0xc00,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -470,7 +477,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 3,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 1, 1, 2, 3 },
+		.gpiomux	= { 1, 1, 2, 3 },
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -482,8 +489,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x0f, /* old: 7 */
 		.muxsel		= MUXSEL(2, 0, 1, 1),
-		.gpiomux 	= { 0, 1, 2, 3 },
-		.gpiomute 	= 4,
+		.gpiomux	= { 0, 1, 2, 3 },
+		.gpiomute	= 4,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -495,8 +502,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x3014f,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0x20001,0x10001, 0, 0 },
-		.gpiomute 	= 10,
+		.gpiomux	= { 0x20001,0x10001, 0, 0 },
+		.gpiomute	= 10,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -509,7 +516,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 15,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 13, 14, 11, 7 },
+		.gpiomux	= { 13, 14, 11, 7 },
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -520,7 +527,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 15,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 13, 14, 11, 7 },
+		.gpiomux	= { 13, 14, 11, 7 },
 		.msp34xx_alt    = 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
@@ -535,8 +542,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 7,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */
-		.gpiomute 	= 4,
+		.gpiomux	= { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */
+		.gpiomute	= 4,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -548,8 +555,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 15,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 0, 1, 0 },
-		.gpiomute 	= 10,
+		.gpiomux	= { 0, 0, 1, 0 },
+		.gpiomute	= 10,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -564,7 +571,7 @@ struct tvcard bttv_tvcards[] = {
 		.muxsel		= MUXSEL(2, 3, 1, 1),
 		/* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
 		.gpiomux        = { 0x001e00, 0, 0x018000, 0x014000 },
-		.gpiomute 	= 0x002000,
+		.gpiomute	= 0x002000,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr     = ADDR_UNSET,
@@ -576,8 +583,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x8300f8,
 		.muxsel		= MUXSEL(2, 3, 1, 1, 0),
-		.gpiomux 	= { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 },
-		.gpiomute 	= 0xcfa007,
+		.gpiomux	= { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 },
+		.gpiomute	= 0xcfa007,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.volume_gpio	= winview_volume,
@@ -590,7 +597,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 1, 0, 0, 0 },
+		.gpiomux	= { 1, 0, 0, 0 },
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -601,7 +608,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= NO_SVHS,
 		.gpiomask	= 0x8dff00,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0 },
+		.gpiomux	= { 0 },
 		.no_msp34xx	= 1,
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
@@ -624,8 +631,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x1800,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 0x800, 0x1000, 0x1000 },
-		.gpiomute 	= 0x1800,
+		.gpiomux	= { 0, 0x800, 0x1000, 0x1000 },
+		.gpiomute	= 0x1800,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL_I,
 		.tuner_addr	= ADDR_UNSET,
@@ -637,8 +644,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0xc00,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 1, 0x800, 0x400 },
-		.gpiomute 	= 0xc00,
+		.gpiomux	= { 0, 1, 0x800, 0x400 },
+		.gpiomute	= 0xc00,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -652,7 +659,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask	= 7,
 		.muxsel		= MUXSEL(2, 3, 0), /* input 2 is digital */
 		/* .digital_mode= DIGITAL_MODE_CAMERA, */
-		.gpiomux 	= { 0, 0, 0, 0 },
+		.gpiomux	= { 0, 0, 0, 0 },
 		.no_msp34xx	= 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_ALPS_TSBB5_PAL_I,
@@ -667,8 +674,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0xe00,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= {0x400, 0x400, 0x400, 0x400 },
-		.gpiomute 	= 0xc00,
+		.gpiomux	= {0x400, 0x400, 0x400, 0x400 },
+		.gpiomute	= 0xc00,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -683,7 +690,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x1f0fff,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0x20000, 0x30000, 0x10000, 0 },
-		.gpiomute 	= 0x40000,
+		.gpiomute	= 0x40000,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
 		.audio_mode_gpio= terratv_audio,
@@ -695,8 +702,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 3,
 		.gpiomask	= 7,
 		.muxsel		= MUXSEL(2, 0, 1, 1),
-		.gpiomux 	= { 0, 1, 2, 3 },
-		.gpiomute 	= 4,
+		.gpiomux	= { 0, 1, 2, 3 },
+		.gpiomute	= 4,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -707,8 +714,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x1800,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 0x800, 0x1000, 0x1000 },
-		.gpiomute 	= 0x1800,
+		.gpiomux	= { 0, 0x800, 0x1000, 0x1000 },
+		.gpiomute	= 0x1800,
 		.pll            = PLL_28,
 		.tuner_type	= TUNER_PHILIPS_SECAM,
 		.tuner_addr	= ADDR_UNSET,
@@ -722,8 +729,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x1f0fff,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0x20000, 0x30000, 0x10000, 0x00000 },
-		.gpiomute 	= 0x40000,
+		.gpiomux	= { 0x20000, 0x30000, 0x10000, 0x00000 },
+		.gpiomute	= 0x40000,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
 		.audio_mode_gpio= terratv_audio,
@@ -767,7 +774,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 1, /* was: 4 */
 		.gpiomask	= 0,
 		.muxsel		= MUXSEL(2, 3, 1, 0, 0),
-		.gpiomux 	= { 0 },
+		.gpiomux	= { 0 },
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 		.muxsel_hook    = PXC200_muxsel,
@@ -780,8 +787,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x1800,  /* 0x8dfe00 */
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 0x0800, 0x1000, 0x1000 },
-		.gpiomute 	= 0x1800,
+		.gpiomux	= { 0, 0x0800, 0x1000, 0x1000 },
+		.gpiomute	= 0x1800,
 		.pll            = PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -793,7 +800,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 3,
 		.gpiomask	= 1,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 1, 0, 0, 0 },
+		.gpiomux	= { 1, 0, 0, 0 },
 		.pll            = PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -807,7 +814,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0 },
+		.gpiomux	= { 0 },
 		.tuner_type	= TUNER_ABSENT,
 		.tuner_addr	= ADDR_UNSET,
 	},
@@ -818,8 +825,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0xffff00,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0x500, 0, 0x300, 0x900 },
-		.gpiomute 	= 0x900,
+		.gpiomux	= { 0x500, 0, 0x300, 0x900 },
+		.gpiomute	= 0x900,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -833,8 +840,8 @@ struct tvcard bttv_tvcards[] = {
 		.muxsel		= MUXSEL(2, 3, 1, 1, 0),
 		/* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
 		.gpiomask	= 0xb33000,
-		.gpiomux 	= { 0x122000,0x1000,0x0000,0x620000 },
-		.gpiomute 	= 0x800000,
+		.gpiomux	= { 0x122000,0x1000,0x0000,0x620000 },
+		.gpiomute	= 0x800000,
 		/* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
 			gpio23 -- hef4052:nEnable (0x800000)
 			gpio12 -- hef4052:A1
@@ -860,8 +867,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x1800,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 0x800, 0x1000, 0x1000 },
-		.gpiomute 	= 0x1800,
+		.gpiomux	= { 0, 0x800, 0x1000, 0x1000 },
+		.gpiomute	= 0x1800,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -875,8 +882,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x1800,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 0x800, 0x1000, 0x1000 },
-		.gpiomute 	= 0x1800,
+		.gpiomux	= { 0, 0x800, 0x1000, 0x1000 },
+		.gpiomute	= 0x1800,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -889,8 +896,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0xff,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0x21, 0x20, 0x24, 0x2c },
-		.gpiomute 	= 0x29,
+		.gpiomux	= { 0x21, 0x20, 0x24, 0x2c },
+		.gpiomute	= 0x29,
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
@@ -903,8 +910,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x551e00,
 		.muxsel		= MUXSEL(2, 3, 1, 0),
-		.gpiomux 	= { 0x551400, 0x551200, 0, 0 },
-		.gpiomute 	= 0x551c00,
+		.gpiomux	= { 0x551400, 0x551200, 0, 0 },
+		.gpiomute	= 0x551c00,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL_I,
 		.tuner_addr	= ADDR_UNSET,
@@ -917,8 +924,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x03000F,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 2, 0xd0001, 0, 0 },
-		.gpiomute 	= 1,
+		.gpiomux	= { 2, 0xd0001, 0, 0 },
+		.gpiomute	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -932,8 +939,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 7,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 4, 0, 2, 3 },
-		.gpiomute 	= 1,
+		.gpiomux	= { 4, 0, 2, 3 },
+		.gpiomute	= 1,
 		.no_msp34xx	= 1,
 		.tuner_type     = TUNER_PHILIPS_NTSC,
 		.tuner_addr	= ADDR_UNSET,
@@ -947,7 +954,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 15,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 13, 4, 11, 7 },
+		.gpiomux	= { 13, 4, 11, 7 },
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -961,7 +968,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 0, 0, 0},
+		.gpiomux	= { 0, 0, 0, 0},
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL_I,
@@ -974,8 +981,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0xe00b,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 },
-		.gpiomute 	= 0xff3ffc,
+		.gpiomux	= { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 },
+		.gpiomute	= 0xff3ffc,
 		.no_msp34xx	= 1,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -989,8 +996,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= NO_SVHS,
 		.gpiomask	= 3,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 1, 1, 0, 2 },
-		.gpiomute 	= 3,
+		.gpiomux	= { 1, 1, 0, 2 },
+		.gpiomute	= 3,
 		.no_msp34xx	= 1,
 		.pll		= PLL_NONE,
 		.tuner_type	= UNSET,
@@ -1003,7 +1010,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 3,
 		.gpiomask	= 0,
 		.muxsel		= MUXSEL(2, 3, 1, 0, 0),
-		.gpiomux 	= { 0 },
+		.gpiomux	= { 0 },
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_ABSENT,
@@ -1016,8 +1023,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0xbcf03f,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0xbc803f, 0xbc903f, 0xbcb03f, 0 },
-		.gpiomute 	= 0xbcb03f,
+		.gpiomux	= { 0xbc803f, 0xbc903f, 0xbcb03f, 0 },
+		.gpiomute	= 0xbcb03f,
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TEMIC_4039FR5_NTSC,
@@ -1030,8 +1037,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x70000,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0x20000, 0x30000, 0x10000, 0 },
-		.gpiomute 	= 0x40000,
+		.gpiomux	= { 0x20000, 0x30000, 0x10000, 0 },
+		.gpiomute	= 0x40000,
 		.no_msp34xx	= 1,
 		.pll		= PLL_35,
 		.tuner_type	= TUNER_PHILIPS_PAL_I,
@@ -1047,8 +1054,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 15,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= {2,0,0,0 },
-		.gpiomute 	= 1,
+		.gpiomux	= {2,0,0,0 },
+		.gpiomute	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
@@ -1060,7 +1067,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x010f00,
 		.muxsel		= MUXSEL(2, 3, 0, 0),
-		.gpiomux 	= {0x10000, 0, 0x10000, 0 },
+		.gpiomux	= {0x10000, 0, 0x10000, 0 },
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_ALPS_TSHC6_NTSC,
@@ -1076,8 +1083,8 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask	= 0xAA0000,
 		.muxsel		= MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
 		/* .digital_mode= DIGITAL_MODE_CAMERA, */
-		.gpiomux 	= { 0x20000, 0, 0x80000, 0x80000 },
-		.gpiomute 	= 0xa8000,
+		.gpiomux	= { 0x20000, 0, 0x80000, 0x80000 },
+		.gpiomute	= 0xa8000,
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL_I,
@@ -1101,7 +1108,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 7,
 		.muxsel         = MUXSEL(2, 0, 1, 1),
 		.gpiomux        = { 0, 1, 2, 3 },
-		.gpiomute 	= 4,
+		.gpiomute	= 4,
 		.pll            = PLL_28,
 		.tuner_type     = UNSET /* TUNER_ALPS_TMDH2_NTSC */,
 		.tuner_addr	= ADDR_UNSET,
@@ -1116,8 +1123,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs           = 3,
 		.gpiomask       = 0x03000F,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 1, 0xd0001, 0, 0 },
-		.gpiomute 	= 10,
+		.gpiomux	= { 1, 0xd0001, 0, 0 },
+		.gpiomute	= 10,
 				/* sound path (5 sources):
 				MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
 					0= ext. Audio IN
@@ -1140,8 +1147,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x1c,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0, 0, 0x10, 8 },
-		.gpiomute 	= 4,
+		.gpiomux	= { 0, 0, 0x10, 8 },
+		.gpiomute	= 4,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -1159,8 +1166,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x18e0,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0x0000,0x0800,0x1000,0x1000 },
-		.gpiomute 	= 0x18e0,
+		.gpiomux	= { 0x0000,0x0800,0x1000,0x1000 },
+		.gpiomute	= 0x18e0,
 			/* For cards with tda9820/tda9821:
 				0x0000: Tuner normal stereo
 				0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
@@ -1179,7 +1186,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0xF,
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = { 2, 0, 0, 0 },
-		.gpiomute 	= 10,
+		.gpiomute	= 10,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -1195,7 +1202,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x1800,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 0x800, 0x1000, 0x1000 },
-		.gpiomute 	= 0x1800,
+		.gpiomute	= 0x1800,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -1225,7 +1232,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0xe00,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0x400, 0x400, 0x400, 0x400 },
-		.gpiomute 	= 0x800,
+		.gpiomute	= 0x800,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_TEMIC_4036FY5_NTSC,
 		.tuner_addr	= ADDR_UNSET,
@@ -1239,7 +1246,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x03000F,
 		.muxsel		= MUXSEL(2, 3, 1, 0),
 		.gpiomux        = { 2, 0, 0, 0 },
-		.gpiomute 	= 1,
+		.gpiomute	= 1,
 		.pll            = PLL_28,
 		.tuner_type	= TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -1256,7 +1263,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 11,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 2, 0, 0, 1 },
-		.gpiomute 	= 8,
+		.gpiomute	= 8,
 		.pll            = PLL_35,
 		.tuner_type     = TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -1286,7 +1293,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0xFF,
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = { 1, 0, 4, 4 },
-		.gpiomute 	= 9,
+		.gpiomute	= 9,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -1299,8 +1306,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0xf03f,
 		.muxsel		= MUXSEL(2, 3, 1, 0),
-		.gpiomux 	= { 0xbffe, 0, 0xbfff, 0 },
-		.gpiomute 	= 0xbffe,
+		.gpiomux	= { 0xbffe, 0, 0xbfff, 0 },
+		.gpiomute	= 0xbffe,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TEMIC_4006FN5_MULTI_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -1315,7 +1322,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= NO_SVHS,
 		.gpiomask	= 1,
 		.muxsel		= MUXSEL(2, 3, 0, 1),
-		.gpiomux 	= { 0, 0, 1, 0 },
+		.gpiomux	= { 0, 0, 1, 0 },
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_TEMIC_4006FN5_MULTI_PAL,
@@ -1332,8 +1339,8 @@ struct tvcard bttv_tvcards[] = {
 				/* Radio changed from 1e80 to 0x800 to make
 				FlyVideo2000S in .hu happy (gm)*/
 				/* -dk-???: set mute=0x1800 for tda9874h daughterboard */
-		.gpiomux 	= { 0x0000,0x0800,0x1000,0x1000 },
-		.gpiomute 	= 0x1800,
+		.gpiomux	= { 0x0000,0x0800,0x1000,0x1000 },
+		.gpiomute	= 0x1800,
 		.audio_mode_gpio= fv2000s_audio,
 		.no_msp34xx	= 1,
 		.pll            = PLL_28,
@@ -1347,8 +1354,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0xffff00,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0x500, 0x500, 0x300, 0x900 },
-		.gpiomute 	= 0x900,
+		.gpiomux	= { 0x500, 0x500, 0x300, 0x900 },
+		.gpiomute	= 0x900,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -1382,7 +1389,7 @@ struct tvcard bttv_tvcards[] = {
 		/* 0x100000: 1=MSP enabled (0=disable again)
 		* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
 		.gpiomux        = {0x947fff, 0x987fff,0x947fff,0x947fff },
-		.gpiomute 	= 0x947fff,
+		.gpiomute	= 0x947fff,
 		/* tvtuner, radio,   external,internal, mute,  stereo
 		* tuner, Composit, SVid, Composit-on-Svid-adapter */
 		.muxsel         = MUXSEL(2, 3, 0, 1),
@@ -1402,7 +1409,7 @@ struct tvcard bttv_tvcards[] = {
 		/* 0x100000: 1=MSP enabled (0=disable again)
 		* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
 		.gpiomux        = {0x947fff, 0x987fff,0x947fff,0x947fff },
-		.gpiomute 	= 0x947fff,
+		.gpiomute	= 0x947fff,
 		/* tvtuner, radio,   external,internal, mute,  stereo
 		* tuner, Composit, SVid, Composit-on-Svid-adapter */
 		.muxsel         = MUXSEL(2, 3, 0, 1),
@@ -1431,7 +1438,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 15,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */
-		.gpiomute 	= 13,
+		.gpiomute	= 13,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_LG_PAL_I_FM,
 		.tuner_addr	= ADDR_UNSET,
@@ -1466,8 +1473,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x3f,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 0x01, 0x00, 0x03, 0x03 },
-		.gpiomute 	= 0x09,
+		.gpiomux	= { 0x01, 0x00, 0x03, 0x03 },
+		.gpiomute	= 0x09,
 		.no_msp34xx	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_PAL,
@@ -1518,7 +1525,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x1C800F,  /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
 		.muxsel         = MUXSEL(2, 1, 1),
 		.gpiomux        = { 0, 1, 2, 2 },
-		.gpiomute 	= 4,
+		.gpiomute	= 4,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
 		.pll		= PLL_28,
@@ -1535,7 +1542,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x140007,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 3 },
-		.gpiomute 	= 4,
+		.gpiomute	= 4,
 		.tuner_type     = TUNER_PHILIPS_NTSC,
 		.tuner_addr	= ADDR_UNSET,
 		.audio_mode_gpio= windvr_audio,
@@ -1568,7 +1575,7 @@ struct tvcard bttv_tvcards[] = {
 						* gpiomux =1: lower volume, 2+3: mute
 						* btwincap uses 0x80000/0x80003
 						*/
-		.gpiomute 	= 4,
+		.gpiomute	= 4,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
@@ -1619,7 +1626,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x0f0f80,
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = {0x030000, 0x010000, 0, 0 },
-		.gpiomute 	= 0x020000,
+		.gpiomute	= 0x020000,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_NTSC_M,
@@ -1822,7 +1829,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 7,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 3},
-		.gpiomute 	= 4,
+		.gpiomute	= 4,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
 		.pll            = PLL_28,
@@ -1865,7 +1872,7 @@ struct tvcard bttv_tvcards[] = {
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		/*                  Tuner, Radio, external, internal, off,  on */
 		.gpiomux        = { 0x08,  0x0f,  0x0a,     0x08 },
-		.gpiomute 	= 0x0f,
+		.gpiomute	= 0x0f,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_NTSC,
@@ -2132,7 +2139,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x008007,
 		.muxsel         = MUXSEL(2, 3, 0, 0),
 		.gpiomux        = { 0, 0, 0, 0 },
-		.gpiomute 	= 0x000003,
+		.gpiomute	= 0x000003,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -2175,7 +2182,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x008007,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 2 },
-		.gpiomute 	= 3,
+		.gpiomute	= 3,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -2290,7 +2297,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0xFF,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 2, 0, 0, 0 },
-		.gpiomute 	= 10,
+		.gpiomute	= 10,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_PAL,
 		.tuner_addr	= ADDR_UNSET,
@@ -2319,7 +2326,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x3f,
 		.muxsel         = MUXSEL(2, 3, 1, 0),
 		.gpiomux        = {0x31, 0x31, 0x31, 0x31 },
-		.gpiomute 	= 0x31,
+		.gpiomute	= 0x31,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_PHILIPS_NTSC_M,
@@ -2433,7 +2440,7 @@ struct tvcard bttv_tvcards[] = {
 		.muxsel		= MUXSEL(2, 3, 1),
 		.gpiomask       = 0x00e00007,
 		.gpiomux        = { 0x00400005, 0, 0x00000001, 0 },
-		.gpiomute 	= 0x00c00007,
+		.gpiomute	= 0x00c00007,
 		.no_msp34xx     = 1,
 		.no_tda7432     = 1,
 		.has_dvb        = 1,
@@ -2448,7 +2455,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask	= 0x01fe00,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0x001e00, 0, 0x018000, 0x014000 },
-		.gpiomute 	= 0x002000,
+		.gpiomute	= 0x002000,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_YMEC_TVF66T5_B_DFF,
 		.tuner_addr	= 0xc1 >>1,
@@ -2463,7 +2470,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x001c0007,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 2 },
-		.gpiomute 	= 3,
+		.gpiomute	= 3,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_TENA_9533_DI,
 		.tuner_addr	= ADDR_UNSET,
@@ -2498,7 +2505,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x3f,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0x21, 0x20, 0x24, 0x2c },
-		.gpiomute 	= 0x29,
+		.gpiomute	= 0x29,
 		.no_msp34xx     = 1,
 		.pll            = PLL_28,
 		.tuner_type     = TUNER_YMEC_TVF_5533MF,
@@ -2542,8 +2549,8 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 15,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 2, 0, 0, 0 },
-		.gpiomute 	= 1,
+		.gpiomux	= { 2, 0, 0, 0 },
+		.gpiomute	= 1,
 		.pll		= PLL_28,
 		.tuner_type	= TUNER_PHILIPS_NTSC,
 		.tuner_addr	= ADDR_UNSET,
@@ -2556,7 +2563,7 @@ struct tvcard bttv_tvcards[] = {
 		.svhs		= 2,
 		.gpiomask	= 0x108007,
 		.muxsel		= MUXSEL(2, 3, 1, 1),
-		.gpiomux 	= { 100000, 100002, 100002, 100000 },
+		.gpiomux	= { 100000, 100002, 100002, 100000 },
 		.no_msp34xx	= 1,
 		.no_tda7432     = 1,
 		.pll		= PLL_28,
@@ -2592,7 +2599,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 7,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 3 },
-		.gpiomute 	= 4,
+		.gpiomute	= 4,
 		.tuner_type     = TUNER_TEMIC_4009FR5_PAL,
 		.tuner_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
@@ -2628,7 +2635,7 @@ struct tvcard bttv_tvcards[] = {
 		.muxsel		= MUXSEL(2, 3, 1),
 		.gpiomask       = 0x00e00007,
 		.gpiomux        = { 0x00400005, 0, 0x00000001, 0 },
-		.gpiomute 	= 0x00c00007,
+		.gpiomute	= 0x00c00007,
 		.no_msp34xx     = 1,
 		.no_tda7432     = 1,
 	},
@@ -2672,7 +2679,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x008007,
 		.muxsel         = MUXSEL(2, 3, 1, 1),
 		.gpiomux        = { 0, 1, 2, 2 }, /* CONTVFMi */
-		.gpiomute 	= 3, /* CONTVFMi */
+		.gpiomute	= 3, /* CONTVFMi */
 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */
 		.tuner_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
@@ -2695,7 +2702,7 @@ struct tvcard bttv_tvcards[] = {
 		.gpiomask       = 0x060040,
 		.muxsel         = MUXSEL(2, 3, 3),
 		.gpiomux        = { 0x60000, 0x60000, 0x20000, 0x20000 },
-		.gpiomute 	= 0,
+		.gpiomute	= 0,
 		.tuner_type	= TUNER_TCL_MF02GIP_5N,
 		.tuner_addr     = ADDR_UNSET,
 		.pll            = PLL_28,
@@ -2745,8 +2752,8 @@ struct tvcard bttv_tvcards[] = {
 		/* Bruno Christo <bchristo@inf.ufsm.br>
 		 *
 		 * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
-		 * 	1 audio input  per BT878A = 4 audio inputs
-		 * 	4 video inputs per BT878A = 16 video inputs
+		 *	1 audio input  per BT878A = 4 audio inputs
+		 *	4 video inputs per BT878A = 16 video inputs
 		 * This is the first BT878A chip of the GV-800(S). It's the
 		 * "master" chip and it controls the video inputs through an
 		 * analog multiplexer (a CD22M3494) via some GPIO pins. The
@@ -2772,8 +2779,8 @@ struct tvcard bttv_tvcards[] = {
 		/* Bruno Christo <bchristo@inf.ufsm.br>
 		 *
 		 * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
-		 * 	1 audio input  per BT878A = 4 audio inputs
-		 * 	4 video inputs per BT878A = 16 video inputs
+		 *	1 audio input  per BT878A = 4 audio inputs
+		 *	4 video inputs per BT878A = 16 video inputs
 		 * The 3 other BT878A chips are "slave" chips of the GV-800(S)
 		 * and should use this card type.
 		 * The audio input is not working yet.
@@ -4777,9 +4784,9 @@ static void gv800s_write(struct bttv *btv,
 	* GPIO bits 0-9 are used for the analog switch:
 	*   00 - 03:	camera selector
 	*   04 - 06:	878A (controller) selector
-	*   16: 	cselect
+	*   16:		cselect
 	*   17:		strobe
-	*   18: 	data (1->on, 0->off)
+	*   18:		data (1->on, 0->off)
 	*   19:		reset
 	*/
 	const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4);
@@ -4875,7 +4882,7 @@ void __init bttv_check_chipset(void)
 	int pcipci_fail = 0;
 	struct pci_dev *dev = NULL;
 
-	if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) 	/* should check if target is AGP */
+	if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL))	/* should check if target is AGP */
 		pcipci_fail = 1;
 	if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF))
 		triton1 = 1;
diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c
index ac76747..da49c55 100644
--- a/drivers/media/pci/bt8xx/bttv-input.c
+++ b/drivers/media/pci/bt8xx/bttv-input.c
@@ -349,12 +349,12 @@ static int get_key_pv951(struct IR_i2c *ir, enum rc_proto *protocol,
 	 * NOTE:
 	 * lirc_i2c maps the pv951 code as:
 	 *	addr = 0x61D6
-	 * 	cmd = bit_reverse (b)
+	 *	cmd = bit_reverse (b)
 	 * So, it seems that this device uses NEC extended
 	 * I decided to not fix the table, due to two reasons:
-	 * 	1) Without the actual device, this is only a guess;
-	 * 	2) As the addr is not reported via I2C, nor can be changed,
-	 * 	   the device is bound to the vendor-provided RC.
+	 *	1) Without the actual device, this is only a guess;
+	 *	2) As the addr is not reported via I2C, nor can be changed,
+	 *	   the device is bound to the vendor-provided RC.
 	 */
 
 	*protocol = RC_PROTO_UNKNOWN;
diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h
index eb67e36..a27384a 100644
--- a/drivers/media/pci/bt8xx/bttv.h
+++ b/drivers/media/pci/bt8xx/bttv.h
@@ -18,7 +18,6 @@
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
 #include <media/v4l2-device.h>
-#include <media/i2c-addr.h>
 #include <media/tuner.h>
 
 /* ---------------------------------------------------------- */
@@ -166,7 +165,7 @@
 #define BTTV_BOARD_PV_M4900                0x8b
 #define BTTV_BOARD_OSPREY440               0x8c
 #define BTTV_BOARD_ASOUND_SKYEYE	   0x8d
-#define BTTV_BOARD_SABRENT_TVFM   	   0x8e
+#define BTTV_BOARD_SABRENT_TVFM		   0x8e
 #define BTTV_BOARD_HAUPPAUGE_IMPACTVCB     0x8f
 #define BTTV_BOARD_MACHTV_MAGICTV          0x90
 #define BTTV_BOARD_SSAI_SECURITY	   0x91
@@ -266,7 +265,7 @@ extern struct tvcard bttv_tvcards[];
  * that they are changed to octal.  One should not use hex number, macros, or
  * anything else with this macro.  Just use plain integers from 0 to 3.
  */
-#define _MUXSELf(a)      	0##a << 30
+#define _MUXSELf(a)		0##a << 30
 #define _MUXSELe(a, b...)	0##a << 28 | _MUXSELf(b)
 #define _MUXSELd(a, b...)	0##a << 26 | _MUXSELe(b)
 #define _MUXSELc(a, b...)	0##a << 24 | _MUXSELd(b)
diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h
index cb1b5e6..7a86e72 100644
--- a/drivers/media/pci/bt8xx/bttvp.h
+++ b/drivers/media/pci/bt8xx/bttvp.h
@@ -141,7 +141,7 @@ struct bttv_ir {
 	bool			rc5_gpio;   /* Is RC5 legacy GPIO enabled? */
 	u32                     last_bit;   /* last raw bit seen */
 	u32                     code;       /* raw code under construction */
-	ktime_t          				base_time;  /* time of last seen code */
+	ktime_t						base_time;  /* time of last seen code */
 	bool                    active;     /* building raw code */
 };
 
@@ -400,8 +400,8 @@ struct bttv {
 	int                        i2c_state, i2c_rc;
 	int                        i2c_done;
 	wait_queue_head_t          i2c_queue;
-	struct v4l2_subdev 	  *sd_msp34xx;
-	struct v4l2_subdev 	  *sd_tvaudio;
+	struct v4l2_subdev	  *sd_msp34xx;
+	struct v4l2_subdev	  *sd_tvaudio;
 	struct v4l2_subdev	  *sd_tda7432;
 
 	/* video4linux (1) */
diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c
index 7166d22..4f0bba9 100644
--- a/drivers/media/pci/bt8xx/dst.c
+++ b/drivers/media/pci/bt8xx/dst.c
@@ -28,7 +28,7 @@
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "dst_priv.h"
 #include "dst_common.h"
 
diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c
index 530b3e9..0a7623c 100644
--- a/drivers/media/pci/bt8xx/dst_ca.c
+++ b/drivers/media/pci/bt8xx/dst_ca.c
@@ -25,8 +25,8 @@
 #include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/dvb/ca.h>
-#include "dvbdev.h"
-#include "dvb_frontend.h"
+#include <media/dvbdev.h>
+#include <media/dvb_frontend.h>
 #include "dst_ca.h"
 #include "dst_common.h"
 
diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c
index ad61787..f60d69a 100644
--- a/drivers/media/pci/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c
@@ -26,10 +26,10 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
 #include "dvb-bt8xx.h"
 #include "bt878.h"
 
diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.h b/drivers/media/pci/bt8xx/dvb-bt8xx.h
index 0ec538e..3184b3f 100644
--- a/drivers/media/pci/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/pci/bt8xx/dvb-bt8xx.h
@@ -23,8 +23,8 @@
 
 #include <linux/i2c.h>
 #include <linux/mutex.h>
-#include "dvbdev.h"
-#include "dvb_net.h"
+#include <media/dvbdev.h>
+#include <media/dvb_net.h>
 #include "bttv.h"
 #include "mt352.h"
 #include "sp887x.h"
diff --git a/drivers/media/pci/cobalt/Kconfig b/drivers/media/pci/cobalt/Kconfig
index 7034382..aa35cbc 100644
--- a/drivers/media/pci/cobalt/Kconfig
+++ b/drivers/media/pci/cobalt/Kconfig
@@ -6,6 +6,7 @@
 	depends on SND
 	depends on MTD
 	select I2C_ALGOBIT
+	select SND_PCM
 	select VIDEO_ADV7604
 	select VIDEO_ADV7511
 	select VIDEO_ADV7842
diff --git a/drivers/media/pci/cx18/Makefile b/drivers/media/pci/cx18/Makefile
index 98914a4..9c82c2d 100644
--- a/drivers/media/pci/cx18/Makefile
+++ b/drivers/media/pci/cx18/Makefile
@@ -9,6 +9,5 @@
 obj-$(CONFIG_VIDEO_CX18) += cx18.o
 obj-$(CONFIG_VIDEO_CX18_ALSA) += cx18-alsa.o
 
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/cx18/cx18-alsa-pcm.c b/drivers/media/pci/cx18/cx18-alsa-pcm.c
index aadd764..4f31042 100644
--- a/drivers/media/pci/cx18/cx18-alsa-pcm.c
+++ b/drivers/media/pci/cx18/cx18-alsa-pcm.c
@@ -41,7 +41,7 @@ MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
 #define dprintk(fmt, arg...) do {					\
 	    if (pcm_debug)						\
 		printk(KERN_INFO "cx18-alsa-pcm %s: " fmt,		\
-				  __func__, ##arg); 			\
+				  __func__, ##arg);			\
 	} while (0)
 
 static const struct snd_pcm_hardware snd_cx18_hw_capture = {
diff --git a/drivers/media/pci/cx18/cx18-av-audio.c b/drivers/media/pci/cx18/cx18-av-audio.c
index 8b95e9a..3abc54c 100644
--- a/drivers/media/pci/cx18/cx18-av-audio.c
+++ b/drivers/media/pci/cx18/cx18-av-audio.c
@@ -31,7 +31,7 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
 	 * would ideally be:
 	 *
 	 * NTSC Color subcarrier freq * 8 =
-	 * 	4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
+	 *	4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
 	 *
 	 * The accidents of history and rationale that explain from where this
 	 * combination of magic numbers originate can be found in:
diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c
index cf8817e..eda3433 100644
--- a/drivers/media/pci/cx18/cx18-av-core.c
+++ b/drivers/media/pci/cx18/cx18-av-core.c
@@ -236,10 +236,10 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
 	 */
 	cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00);
 
-/* 	if(dwEnable && dw3DCombAvailable) { */
-/*      	CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
+/*	if(dwEnable && dw3DCombAvailable) { */
+/*		CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
 /*    } else { */
-/*      	CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
+/*		CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
 /*    } */
 	cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
 	default_volume = cx18_av_read(cx, 0x8d4);
@@ -319,13 +319,13 @@ void cx18_av_std_setup(struct cx18 *cx)
 		 * vblank656: half lines after line 625/mid-313 of blanked video
 		 * vblank:    half lines, after line 5/317, of blanked video
 		 * vactive:   half lines of active video +
-		 * 		5 half lines after the end of active video
+		 *		5 half lines after the end of active video
 		 *
 		 * As far as I can tell:
 		 * vblank656 starts counting from the falling edge of the first
-		 * 	vsync pulse (start of line 1 or mid-313)
+		 *	vsync pulse (start of line 1 or mid-313)
 		 * vblank starts counting from the after the 5 vsync pulses and
-		 * 	5 or 4 equalization pulses (start of line 6 or 318)
+		 *	5 or 4 equalization pulses (start of line 6 or 318)
 		 *
 		 * For 625 line systems the driver will extract VBI information
 		 * from lines 6-23 and lines 318-335 (but the slicer can only
@@ -395,9 +395,9 @@ void cx18_av_std_setup(struct cx18 *cx)
 		 *
 		 * As far as I can tell:
 		 * vblank656 starts counting from the falling edge of the first
-		 * 	vsync pulse (start of line 4 or mid-266)
+		 *	vsync pulse (start of line 4 or mid-266)
 		 * vblank starts counting from the after the 6 vsync pulses and
-		 * 	6 or 5 equalization pulses (start of line 10 or 272)
+		 *	6 or 5 equalization pulses (start of line 10 or 272)
 		 *
 		 * For 525 line systems the driver will extract VBI information
 		 * from lines 10-21 and lines 273-284.
@@ -851,7 +851,7 @@ static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
 	struct cx18_av_state *state = to_cx18_av_state(sd);
 	struct cx18 *cx = v4l2_get_subdevdata(sd);
 
-	u8 fmt = 0; 	/* zero is autodetect */
+	u8 fmt = 0;	/* zero is autodetect */
 	u8 pal_m = 0;
 
 	if (state->radio == 0 && state->std == norm)
diff --git a/drivers/media/pci/cx18/cx18-av-core.h b/drivers/media/pci/cx18/cx18-av-core.h
index c976ce6..1a37f26 100644
--- a/drivers/media/pci/cx18/cx18-av-core.h
+++ b/drivers/media/pci/cx18/cx18-av-core.h
@@ -349,7 +349,7 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
 }
 
 /* ----------------------------------------------------------------------- */
-/* cx18_av-core.c 							   */
+/* cx18_av-core.c							   */
 int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
 int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
 int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value);
diff --git a/drivers/media/pci/cx18/cx18-cards.c b/drivers/media/pci/cx18/cx18-cards.c
index 11e898e..c2cf965 100644
--- a/drivers/media/pci/cx18/cx18-cards.c
+++ b/drivers/media/pci/cx18/cx18-cards.c
@@ -388,7 +388,7 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = {
 		{ CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
 	},
 	.audio_inputs = {
-		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 	    0 },
+		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5,	    0 },
 		{ CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL1, 1 },
 		{ CX18_CARD_INPUT_LINE_IN2,  CX18_AV_AUDIO_SERIAL2, 1 },
 	},
@@ -439,7 +439,7 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
 		{ CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
 	},
 	.audio_inputs = {
-		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 	    0 },
+		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5,	    0 },
 		{ CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL1, 1 },
 	},
 	.tuners = {
@@ -485,7 +485,7 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
 		{ CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
 	},
 	.audio_inputs = {
-		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 	    0 },
+		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5,	    0 },
 		{ CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL1, 1 },
 	},
 	.tuners = {
@@ -538,7 +538,7 @@ static const struct cx18_card cx18_card_leadtek_dvr3100h = {
 		{ CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
 	},
 	.audio_inputs = {
-		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 	    0 },
+		{ CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5,	    0 },
 		{ CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL1, 1 },
 	},
 	.tuners = {
diff --git a/drivers/media/pci/cx18/cx18-cards.h b/drivers/media/pci/cx18/cx18-cards.h
index 667e2d7..02d0fb7 100644
--- a/drivers/media/pci/cx18/cx18-cards.h
+++ b/drivers/media/pci/cx18/cx18-cards.h
@@ -25,30 +25,24 @@
 #define CX18_HW_418_AV			(1 << 4)
 #define CX18_HW_GPIO_MUX		(1 << 5)
 #define CX18_HW_GPIO_RESET_CTRL		(1 << 6)
-#define CX18_HW_Z8F0811_IR_TX_HAUP	(1 << 7)
-#define CX18_HW_Z8F0811_IR_RX_HAUP	(1 << 8)
-#define CX18_HW_Z8F0811_IR_HAUP	(CX18_HW_Z8F0811_IR_RX_HAUP | \
-				 CX18_HW_Z8F0811_IR_TX_HAUP)
-
-#define CX18_HW_IR_ANY (CX18_HW_Z8F0811_IR_RX_HAUP | \
-			CX18_HW_Z8F0811_IR_TX_HAUP)
+#define CX18_HW_Z8F0811_IR_HAUP		(1 << 7)
 
 /* video inputs */
 #define	CX18_CARD_INPUT_VID_TUNER	1
-#define	CX18_CARD_INPUT_SVIDEO1 	2
-#define	CX18_CARD_INPUT_SVIDEO2 	3
-#define	CX18_CARD_INPUT_COMPOSITE1 	4
-#define	CX18_CARD_INPUT_COMPOSITE2 	5
-#define	CX18_CARD_INPUT_COMPONENT1 	6
+#define	CX18_CARD_INPUT_SVIDEO1		2
+#define	CX18_CARD_INPUT_SVIDEO2		3
+#define	CX18_CARD_INPUT_COMPOSITE1	4
+#define	CX18_CARD_INPUT_COMPOSITE2	5
+#define	CX18_CARD_INPUT_COMPONENT1	6
 
 /* audio inputs */
 #define	CX18_CARD_INPUT_AUD_TUNER	1
-#define	CX18_CARD_INPUT_LINE_IN1 	2
-#define	CX18_CARD_INPUT_LINE_IN2 	3
+#define	CX18_CARD_INPUT_LINE_IN1	2
+#define	CX18_CARD_INPUT_LINE_IN2	3
 
 #define CX18_CARD_MAX_VIDEO_INPUTS 6
 #define CX18_CARD_MAX_AUDIO_INPUTS 3
-#define CX18_CARD_MAX_TUNERS  	   2
+#define CX18_CARD_MAX_TUNERS	   2
 
 /* V4L2 capability aliases */
 #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
@@ -57,7 +51,7 @@
 			  V4L2_CAP_SLICED_VBI_CAPTURE)
 
 struct cx18_card_video_input {
-	u8  video_type; 	/* video input type */
+	u8  video_type;		/* video input type */
 	u8  audio_index;	/* index in cx18_card_audio_input array */
 	u32 video_input;	/* hardware video input */
 };
@@ -80,7 +74,7 @@ struct cx18_card_pci_info {
 /* The mask is the set of bits used by the operation */
 
 struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
-	u32 direction; 	/* DIR setting. Leave to 0 if no init is needed */
+	u32 direction;	/* DIR setting. Leave to 0 if no init is needed */
 	u32 initial_value;
 };
 
@@ -92,16 +86,16 @@ struct cx18_gpio_i2c_slave_reset {
 	u32 ir_reset_mask;  /* GPIO to reset the Zilog Z8F0811 IR contoller */
 };
 
-struct cx18_gpio_audio_input { 	/* select tuner/line in input */
-	u32 mask; 		/* leave to 0 if not supported */
+struct cx18_gpio_audio_input {	/* select tuner/line in input */
+	u32 mask;		/* leave to 0 if not supported */
 	u32 tuner;
 	u32 linein;
 	u32 radio;
 };
 
 struct cx18_card_tuner {
-	v4l2_std_id std; 	/* standard for which the tuner is suitable */
-	int 	    tuner; 	/* tuner ID (from tuner.h) */
+	v4l2_std_id std;	/* standard for which the tuner is suitable */
+	int	    tuner;	/* tuner ID (from tuner.h) */
 };
 
 struct cx18_card_tuner_i2c {
@@ -134,8 +128,8 @@ struct cx18_card {
 	struct cx18_card_audio_input radio_input;
 
 	/* GPIO card-specific settings */
-	u8 xceive_pin; 		/* XCeive tuner GPIO reset pin */
-	struct cx18_gpio_init 		 gpio_init;
+	u8 xceive_pin;		/* XCeive tuner GPIO reset pin */
+	struct cx18_gpio_init		 gpio_init;
 	struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
 	struct cx18_gpio_audio_input    gpio_audio_input;
 
diff --git a/drivers/media/pci/cx18/cx18-driver.h b/drivers/media/pci/cx18/cx18-driver.h
index 7be2088..0b707fa 100644
--- a/drivers/media/pci/cx18/cx18-driver.h
+++ b/drivers/media/pci/cx18/cx18-driver.h
@@ -50,12 +50,12 @@
 #include "cx23418.h"
 
 /* DVB */
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
 
 /* Videobuf / YUV support */
 #include <media/videobuf-core.h>
@@ -75,8 +75,8 @@
 /* Supported cards */
 #define CX18_CARD_HVR_1600_ESMT	      0	/* Hauppauge HVR 1600 (ESMT memory) */
 #define CX18_CARD_HVR_1600_SAMSUNG    1	/* Hauppauge HVR 1600 (Samsung memory) */
-#define CX18_CARD_COMPRO_H900 	      2	/* Compro VideoMate H900 */
-#define CX18_CARD_YUAN_MPC718 	      3	/* Yuan MPC718 */
+#define CX18_CARD_COMPRO_H900	      2	/* Compro VideoMate H900 */
+#define CX18_CARD_YUAN_MPC718	      3	/* Yuan MPC718 */
 #define CX18_CARD_CNXT_RAPTOR_PAL     4	/* Conexant Raptor PAL */
 #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
 #define CX18_CARD_LEADTEK_PVR2100     6 /* Leadtek WinFast PVR2100 */
@@ -99,9 +99,9 @@
 #define PCI_DEVICE_ID_CX23418 0x5b7a
 
 /* subsystem vendor ID */
-#define CX18_PCI_ID_HAUPPAUGE 		0x0070
-#define CX18_PCI_ID_COMPRO 		0x185b
-#define CX18_PCI_ID_YUAN 		0x12ab
+#define CX18_PCI_ID_HAUPPAUGE		0x0070
+#define CX18_PCI_ID_COMPRO		0x185b
+#define CX18_PCI_ID_YUAN		0x12ab
 #define CX18_PCI_ID_CONEXANT		0x14f1
 #define CX18_PCI_ID_TOSHIBA		0x1179
 #define CX18_PCI_ID_LEADTEK		0x107D
@@ -260,7 +260,7 @@ struct cx18_options {
 #define CX18_F_M_NEED_SWAP  0	/* mdl buffer data must be endianness swapped */
 
 /* per-stream, s_flags */
-#define CX18_F_S_CLAIMED 	3	/* this stream is claimed */
+#define CX18_F_S_CLAIMED	3	/* this stream is claimed */
 #define CX18_F_S_STREAMING      4	/* the fw is decoding/encoding this stream */
 #define CX18_F_S_INTERNAL_USE	5	/* this stream is used internally (sliced VBI processing) */
 #define CX18_F_S_STREAMOFF	7	/* signal end of stream EOS */
@@ -268,12 +268,12 @@ struct cx18_options {
 #define CX18_F_S_STOPPING	9	/* telling the fw to stop capturing */
 
 /* per-cx18, i_flags */
-#define CX18_F_I_LOADED_FW		0 	/* Loaded firmware 1st time */
-#define CX18_F_I_EOS			4 	/* End of encoder stream */
-#define CX18_F_I_RADIO_USER		5 	/* radio tuner is selected */
-#define CX18_F_I_ENC_PAUSED		13 	/* the encoder is paused */
-#define CX18_F_I_INITED			21 	/* set after first open */
-#define CX18_F_I_FAILED			22 	/* set if first open failed */
+#define CX18_F_I_LOADED_FW		0	/* Loaded firmware 1st time */
+#define CX18_F_I_EOS			4	/* End of encoder stream */
+#define CX18_F_I_RADIO_USER		5	/* radio tuner is selected */
+#define CX18_F_I_ENC_PAUSED		13	/* the encoder is paused */
+#define CX18_F_I_INITED			21	/* set after first open */
+#define CX18_F_I_FAILED			22	/* set if first open failed */
 
 /* These are the VBI types as they appear in the embedded VBI private packets. */
 #define CX18_SLICED_TYPE_TELETEXT_B     (1)
@@ -370,7 +370,7 @@ struct cx18_stream {
 	   is not actually created. */
 	struct video_device video_dev;	/* v4l2_dev is NULL when stream not created */
 	struct cx18_dvb *dvb;		/* DVB / Digital Transport */
-	struct cx18 *cx; 		/* for ease of use */
+	struct cx18 *cx;		/* for ease of use */
 	const char *name;		/* name of the stream */
 	int type;			/* stream type */
 	u32 handle;			/* task handle */
@@ -525,14 +525,14 @@ struct vbi_info {
 	 * into the MPEG PS stream.
 	 *
 	 * In each sliced_mpeg_data[] buffer is:
-	 * 	16 byte MPEG-2 PS Program Pack Header
-	 * 	16 byte MPEG-2 Private Stream 1 PES Header
-	 * 	 4 byte magic number: "itv0" or "ITV0"
-	 * 	 4 byte first  field line mask, if "itv0"
-	 * 	 4 byte second field line mask, if "itv0"
-	 * 	36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
+	 *	16 byte MPEG-2 PS Program Pack Header
+	 *	16 byte MPEG-2 Private Stream 1 PES Header
+	 *	 4 byte magic number: "itv0" or "ITV0"
+	 *	 4 byte first  field line mask, if "itv0"
+	 *	 4 byte second field line mask, if "itv0"
+	 *	36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
 	 *
-	 * 	Each line in the payload is
+	 *	Each line in the payload is
 	 *	 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
 	 *	42 bytes of line data
 	 *
@@ -583,7 +583,7 @@ struct cx18 {
 	u8 nof_inputs;		/* number of video inputs */
 	u8 nof_audio_inputs;	/* number of audio inputs */
 	u32 v4l2_cap;		/* V4L2 capabilities of card */
-	u32 hw_flags; 		/* Hardware description of the board */
+	u32 hw_flags;		/* Hardware description of the board */
 	unsigned int free_mdl_idx;
 	struct cx18_scb __iomem *scb; /* pointer to SCB */
 	struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
@@ -602,10 +602,10 @@ struct cx18 {
 	u32 dualwatch_stereo_mode;
 
 	struct mutex serialize_lock;    /* mutex used to serialize open/close/start/stop/ioctl operations */
-	struct cx18_options options; 	/* User options */
+	struct cx18_options options;	/* User options */
 	int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
 	int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
-	struct cx18_stream streams[CX18_MAX_STREAMS]; 	/* Stream data */
+	struct cx18_stream streams[CX18_MAX_STREAMS];	/* Stream data */
 	struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */
 	void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data,
 				      size_t num_bytes);
diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c
index 2b0abd5..a8dbb92 100644
--- a/drivers/media/pci/cx18/cx18-fileops.c
+++ b/drivers/media/pci/cx18/cx18-fileops.c
@@ -633,7 +633,7 @@ __poll_t cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
 
 		if (v4l2_event_pending(&id->fh))
 			res |= POLLPRI;
-                if (eof && videobuf_poll == POLLERR)
+		if (eof && videobuf_poll == POLLERR)
 			return res | POLLHUP;
 		return res | videobuf_poll;
 	}
diff --git a/drivers/media/pci/cx18/cx18-firmware.c b/drivers/media/pci/cx18/cx18-firmware.c
index 1b34ea1..498a185 100644
--- a/drivers/media/pci/cx18/cx18-firmware.c
+++ b/drivers/media/pci/cx18/cx18-firmware.c
@@ -23,65 +23,65 @@
 #include "cx18-cards.h"
 #include <linux/firmware.h>
 
-#define CX18_PROC_SOFT_RESET 		0xc70010
-#define CX18_DDR_SOFT_RESET          	0xc70014
-#define CX18_CLOCK_SELECT1           	0xc71000
-#define CX18_CLOCK_SELECT2           	0xc71004
-#define CX18_HALF_CLOCK_SELECT1      	0xc71008
-#define CX18_HALF_CLOCK_SELECT2      	0xc7100C
-#define CX18_CLOCK_POLARITY1         	0xc71010
-#define CX18_CLOCK_POLARITY2         	0xc71014
-#define CX18_ADD_DELAY_ENABLE1       	0xc71018
-#define CX18_ADD_DELAY_ENABLE2       	0xc7101C
-#define CX18_CLOCK_ENABLE1           	0xc71020
-#define CX18_CLOCK_ENABLE2           	0xc71024
+#define CX18_PROC_SOFT_RESET		0xc70010
+#define CX18_DDR_SOFT_RESET		0xc70014
+#define CX18_CLOCK_SELECT1		0xc71000
+#define CX18_CLOCK_SELECT2		0xc71004
+#define CX18_HALF_CLOCK_SELECT1		0xc71008
+#define CX18_HALF_CLOCK_SELECT2		0xc7100C
+#define CX18_CLOCK_POLARITY1		0xc71010
+#define CX18_CLOCK_POLARITY2		0xc71014
+#define CX18_ADD_DELAY_ENABLE1		0xc71018
+#define CX18_ADD_DELAY_ENABLE2		0xc7101C
+#define CX18_CLOCK_ENABLE1		0xc71020
+#define CX18_CLOCK_ENABLE2		0xc71024
 
-#define CX18_REG_BUS_TIMEOUT_EN      	0xc72024
+#define CX18_REG_BUS_TIMEOUT_EN		0xc72024
 
-#define CX18_FAST_CLOCK_PLL_INT      	0xc78000
-#define CX18_FAST_CLOCK_PLL_FRAC     	0xc78004
-#define CX18_FAST_CLOCK_PLL_POST     	0xc78008
-#define CX18_FAST_CLOCK_PLL_PRESCALE 	0xc7800C
+#define CX18_FAST_CLOCK_PLL_INT		0xc78000
+#define CX18_FAST_CLOCK_PLL_FRAC	0xc78004
+#define CX18_FAST_CLOCK_PLL_POST	0xc78008
+#define CX18_FAST_CLOCK_PLL_PRESCALE	0xc7800C
 #define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010
 
-#define CX18_SLOW_CLOCK_PLL_INT      	0xc78014
-#define CX18_SLOW_CLOCK_PLL_FRAC     	0xc78018
-#define CX18_SLOW_CLOCK_PLL_POST     	0xc7801C
+#define CX18_SLOW_CLOCK_PLL_INT		0xc78014
+#define CX18_SLOW_CLOCK_PLL_FRAC	0xc78018
+#define CX18_SLOW_CLOCK_PLL_POST	0xc7801C
 #define CX18_MPEG_CLOCK_PLL_INT		0xc78040
 #define CX18_MPEG_CLOCK_PLL_FRAC	0xc78044
 #define CX18_MPEG_CLOCK_PLL_POST	0xc78048
-#define CX18_PLL_POWER_DOWN          	0xc78088
+#define CX18_PLL_POWER_DOWN		0xc78088
 #define CX18_SW1_INT_STATUS             0xc73104
 #define CX18_SW1_INT_ENABLE_PCI         0xc7311C
 #define CX18_SW2_INT_SET                0xc73140
 #define CX18_SW2_INT_STATUS             0xc73144
-#define CX18_ADEC_CONTROL            	0xc78120
+#define CX18_ADEC_CONTROL		0xc78120
 
-#define CX18_DDR_REQUEST_ENABLE      	0xc80000
-#define CX18_DDR_CHIP_CONFIG         	0xc80004
-#define CX18_DDR_REFRESH            	0xc80008
-#define CX18_DDR_TIMING1             	0xc8000C
-#define CX18_DDR_TIMING2             	0xc80010
+#define CX18_DDR_REQUEST_ENABLE		0xc80000
+#define CX18_DDR_CHIP_CONFIG		0xc80004
+#define CX18_DDR_REFRESH		0xc80008
+#define CX18_DDR_TIMING1		0xc8000C
+#define CX18_DDR_TIMING2		0xc80010
 #define CX18_DDR_POWER_REG		0xc8001C
 
-#define CX18_DDR_TUNE_LANE           	0xc80048
-#define CX18_DDR_INITIAL_EMRS        	0xc80054
-#define CX18_DDR_MB_PER_ROW_7        	0xc8009C
-#define CX18_DDR_BASE_63_ADDR        	0xc804FC
+#define CX18_DDR_TUNE_LANE		0xc80048
+#define CX18_DDR_INITIAL_EMRS		0xc80054
+#define CX18_DDR_MB_PER_ROW_7		0xc8009C
+#define CX18_DDR_BASE_63_ADDR		0xc804FC
 
-#define CX18_WMB_CLIENT02            	0xc90108
-#define CX18_WMB_CLIENT05            	0xc90114
-#define CX18_WMB_CLIENT06            	0xc90118
-#define CX18_WMB_CLIENT07            	0xc9011C
-#define CX18_WMB_CLIENT08            	0xc90120
-#define CX18_WMB_CLIENT09            	0xc90124
-#define CX18_WMB_CLIENT10            	0xc90128
-#define CX18_WMB_CLIENT11            	0xc9012C
-#define CX18_WMB_CLIENT12            	0xc90130
-#define CX18_WMB_CLIENT13            	0xc90134
-#define CX18_WMB_CLIENT14            	0xc90138
+#define CX18_WMB_CLIENT02		0xc90108
+#define CX18_WMB_CLIENT05		0xc90114
+#define CX18_WMB_CLIENT06		0xc90118
+#define CX18_WMB_CLIENT07		0xc9011C
+#define CX18_WMB_CLIENT08		0xc90120
+#define CX18_WMB_CLIENT09		0xc90124
+#define CX18_WMB_CLIENT10		0xc90128
+#define CX18_WMB_CLIENT11		0xc9012C
+#define CX18_WMB_CLIENT12		0xc90130
+#define CX18_WMB_CLIENT13		0xc90134
+#define CX18_WMB_CLIENT14		0xc90138
 
-#define CX18_DSP0_INTERRUPT_MASK     	0xd0004C
+#define CX18_DSP0_INTERRUPT_MASK	0xd0004C
 
 #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
 #define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
@@ -229,7 +229,7 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
 	 * would ideally be:
 	 *
 	 * NTSC Color subcarrier freq * 8 =
-	 * 	4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
+	 *	4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
 	 *
 	 * The accidents of history and rationale that explain from where this
 	 * combination of magic numbers originate can be found in:
diff --git a/drivers/media/pci/cx18/cx18-i2c.c b/drivers/media/pci/cx18/cx18-i2c.c
index 7f588ee..f0eb181 100644
--- a/drivers/media/pci/cx18/cx18-i2c.c
+++ b/drivers/media/pci/cx18/cx18-i2c.c
@@ -47,8 +47,7 @@ static const u8 hw_addrs[] = {
 	0,				/* CX18_HW_418_AV */
 	0,				/* CX18_HW_GPIO_MUX */
 	0,				/* CX18_HW_GPIO_RESET_CTRL */
-	CX18_Z8F0811_IR_TX_I2C_ADDR,	/* CX18_HW_Z8F0811_IR_TX_HAUP */
-	CX18_Z8F0811_IR_RX_I2C_ADDR,	/* CX18_HW_Z8F0811_IR_RX_HAUP */
+	CX18_Z8F0811_IR_RX_I2C_ADDR,	/* CX18_HW_Z8F0811_IR_HAUP */
 };
 
 /* This array should match the CX18_HW_ defines */
@@ -61,8 +60,7 @@ static const u8 hw_bus[] = {
 	0,	/* CX18_HW_418_AV */
 	0,	/* CX18_HW_GPIO_MUX */
 	0,	/* CX18_HW_GPIO_RESET_CTRL */
-	0,	/* CX18_HW_Z8F0811_IR_TX_HAUP */
-	0,	/* CX18_HW_Z8F0811_IR_RX_HAUP */
+	0,	/* CX18_HW_Z8F0811_IR_HAUP */
 };
 
 /* This array should match the CX18_HW_ defines */
@@ -74,8 +72,7 @@ static const char * const hw_devicenames[] = {
 	"cx23418_AV",
 	"gpio_mux",
 	"gpio_reset_ctrl",
-	"ir_tx_z8f0811_haup",
-	"ir_rx_z8f0811_haup",
+	"ir_z8f0811_haup",
 };
 
 static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
@@ -90,7 +87,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
 
 	/* Our default information for ir-kbd-i2c.c to use */
 	switch (hw) {
-	case CX18_HW_Z8F0811_IR_RX_HAUP:
+	case CX18_HW_Z8F0811_IR_HAUP:
 		init_data->ir_codes = RC_MAP_HAUPPAUGE;
 		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
 		init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE |
@@ -129,7 +126,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
 		return sd != NULL ? 0 : -1;
 	}
 
-	if (hw & CX18_HW_IR_ANY)
+	if (hw == CX18_HW_Z8F0811_IR_HAUP)
 		return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]);
 
 	/* Is it not an I2C device or one we do not wish to register? */
diff --git a/drivers/media/pci/cx18/cx18-mailbox.c b/drivers/media/pci/cx18/cx18-mailbox.c
index 763f960..f66dd63 100644
--- a/drivers/media/pci/cx18/cx18-mailbox.c
+++ b/drivers/media/pci/cx18/cx18-mailbox.c
@@ -35,7 +35,7 @@ struct cx18_api_info {
 	u32 cmd;
 	u8 flags;		/* Flags, see above */
 	u8 rpu;			/* Processing unit */
-	const char *name; 	/* The name of the command */
+	const char *name;	/* The name of the command */
 };
 
 #define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x }
@@ -43,9 +43,9 @@ struct cx18_api_info {
 static const struct cx18_api_info api_info[] = {
 	/* MPEG encoder API */
 	API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE,		0),
-	API_ENTRY(CPU, CX18_EPU_DEBUG, 				0),
-	API_ENTRY(CPU, CX18_CREATE_TASK, 			0),
-	API_ENTRY(CPU, CX18_DESTROY_TASK, 			0),
+	API_ENTRY(CPU, CX18_EPU_DEBUG,				0),
+	API_ENTRY(CPU, CX18_CREATE_TASK,			0),
+	API_ENTRY(CPU, CX18_DESTROY_TASK,			0),
 	API_ENTRY(CPU, CX18_CPU_CAPTURE_START,                  API_SLOW),
 	API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP,                   API_SLOW),
 	API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE,                  0),
diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c
index f35f78d..a594cfd 100644
--- a/drivers/media/pci/cx18/cx18-streams.c
+++ b/drivers/media/pci/cx18/cx18-streams.c
@@ -29,7 +29,7 @@
 #include "cx18-scb.h"
 #include "cx18-dvb.h"
 
-#define CX18_DSP0_INTERRUPT_MASK     	0xd0004C
+#define CX18_DSP0_INTERRUPT_MASK	0xd0004C
 
 static const struct v4l2_file_operations cx18_v4l2_enc_fops = {
 	.owner = THIS_MODULE,
@@ -116,7 +116,7 @@ static int cx18_prepare_buffer(struct videobuf_queue *q,
 	unsigned int width, unsigned int height,
 	enum v4l2_field field)
 {
-        struct cx18 *cx = s->cx;
+	struct cx18 *cx = s->cx;
 	int rc = 0;
 
 	/* check settings */
diff --git a/drivers/media/pci/cx18/cx18-vbi.c b/drivers/media/pci/cx18/cx18-vbi.c
index 72c74d60..81f1e27 100644
--- a/drivers/media/pci/cx18/cx18-vbi.c
+++ b/drivers/media/pci/cx18/cx18-vbi.c
@@ -47,7 +47,7 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
 		0x00, 0x00, 0x01, 0xbd,		    /* Priv Stream 1 start */
 		0x00, 0x1a,			    /* length */
 		0x84, 0x80, 0x07,		    /* flags, hdr data len */
-		0x21, 0x00, 0x5d, 0x63, 0xa7, 	    /* PTS, markers */
+		0x21, 0x00, 0x5d, 0x63, 0xa7,	    /* PTS, markers */
 		0xff, 0xff			    /* stuffing */
 	};
 	const int sd = sizeof(mpeg_hdr_data);	/* start of vbi data */
diff --git a/drivers/media/pci/cx18/cx23418.h b/drivers/media/pci/cx18/cx23418.h
index 901ed7f..15205b6 100644
--- a/drivers/media/pci/cx18/cx23418.h
+++ b/drivers/media/pci/cx18/cx23418.h
@@ -19,10 +19,10 @@
 
 #include <media/drv-intf/cx2341x.h>
 
-#define MGR_CMD_MASK            		0x40000000
+#define MGR_CMD_MASK				0x40000000
 /* The MSB of the command code indicates that this is the completion of a
    command */
-#define MGR_CMD_MASK_ACK        		(MGR_CMD_MASK | 0x80000000)
+#define MGR_CMD_MASK_ACK			(MGR_CMD_MASK | 0x80000000)
 
 /* Description: This command creates a new instance of a certain task
    IN[0]  - Task ID. This is one of the XPU_CMD_MASK_YYY where XPU is
@@ -30,26 +30,26 @@
    OUT[0] - Task handle. This handle is passed along with commands to
 	    dispatch to the right instance of the task
    ReturnCode - One of the ERR_SYS_... */
-#define CX18_CREATE_TASK      			(MGR_CMD_MASK | 0x0001)
+#define CX18_CREATE_TASK			(MGR_CMD_MASK | 0x0001)
 
 /* Description: This command destroys an instance of a task
    IN[0] - Task handle. Hanlde of the task to destroy
    ReturnCode - One of the ERR_SYS_... */
-#define CX18_DESTROY_TASK     			(MGR_CMD_MASK | 0x0002)
+#define CX18_DESTROY_TASK			(MGR_CMD_MASK | 0x0002)
 
 /* All commands for CPU have the following mask set */
-#define CPU_CMD_MASK                        	0x20000000
-#define CPU_CMD_MASK_DEBUG       		(CPU_CMD_MASK | 0x00000000)
-#define CPU_CMD_MASK_ACK                    	(CPU_CMD_MASK | 0x80000000)
-#define CPU_CMD_MASK_CAPTURE                	(CPU_CMD_MASK | 0x00020000)
-#define CPU_CMD_MASK_TS                     	(CPU_CMD_MASK | 0x00040000)
+#define CPU_CMD_MASK				0x20000000
+#define CPU_CMD_MASK_DEBUG			(CPU_CMD_MASK | 0x00000000)
+#define CPU_CMD_MASK_ACK			(CPU_CMD_MASK | 0x80000000)
+#define CPU_CMD_MASK_CAPTURE			(CPU_CMD_MASK | 0x00020000)
+#define CPU_CMD_MASK_TS				(CPU_CMD_MASK | 0x00040000)
 
-#define EPU_CMD_MASK                        	0x02000000
-#define EPU_CMD_MASK_DEBUG       		(EPU_CMD_MASK | 0x000000)
-#define EPU_CMD_MASK_DE                     	(EPU_CMD_MASK | 0x040000)
+#define EPU_CMD_MASK				0x02000000
+#define EPU_CMD_MASK_DEBUG			(EPU_CMD_MASK | 0x000000)
+#define EPU_CMD_MASK_DE				(EPU_CMD_MASK | 0x040000)
 
-#define APU_CMD_MASK 				0x10000000
-#define APU_CMD_MASK_ACK 			(APU_CMD_MASK | 0x80000000)
+#define APU_CMD_MASK				0x10000000
+#define APU_CMD_MASK_ACK			(APU_CMD_MASK | 0x80000000)
 
 #define CX18_APU_ENCODING_METHOD_MPEG		(0 << 28)
 #define CX18_APU_ENCODING_METHOD_AC3		(1 << 28)
@@ -67,7 +67,7 @@
 
 /* Description: Command APU to reset the AI
    ReturnCode - ??? */
-#define CX18_APU_RESETAI 			(APU_CMD_MASK | 0x05)
+#define CX18_APU_RESETAI			(APU_CMD_MASK | 0x05)
 
 /* Description: This command indicates that a Memory Descriptor List has been
    filled with the requested channel type
@@ -75,13 +75,13 @@
    IN[1] - Offset of the MDL_ACK from the beginning of the local DDR.
    IN[2] - Number of CNXT_MDL_ACK structures in the array pointed to by IN[1]
    ReturnCode - One of the ERR_DE_... */
-#define CX18_EPU_DMA_DONE              		(EPU_CMD_MASK_DE | 0x0001)
+#define CX18_EPU_DMA_DONE			(EPU_CMD_MASK_DE | 0x0001)
 
 /* Something interesting happened
    IN[0] - A value to log
    IN[1] - An offset of a string in the MiniMe memory;
 	   0/zero/NULL means "I have nothing to say" */
-#define CX18_EPU_DEBUG 				(EPU_CMD_MASK_DEBUG | 0x0003)
+#define CX18_EPU_DEBUG				(EPU_CMD_MASK_DEBUG | 0x0003)
 
 /* Reads memory/registers (32-bit)
    IN[0] - Address
@@ -91,40 +91,40 @@
 /* Description: This command starts streaming with the set channel type
    IN[0] - Task handle. Handle of the task to start
    ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_START               	(CPU_CMD_MASK_CAPTURE | 0x0002)
+#define CX18_CPU_CAPTURE_START			(CPU_CMD_MASK_CAPTURE | 0x0002)
 
 /* Description: This command stops streaming with the set channel type
    IN[0] - Task handle. Handle of the task to stop
    IN[1] - 0 = stop at end of GOP, 1 = stop at end of frame (MPEG only)
    ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_STOP                	(CPU_CMD_MASK_CAPTURE | 0x0003)
+#define CX18_CPU_CAPTURE_STOP			(CPU_CMD_MASK_CAPTURE | 0x0003)
 
 /* Description: This command pauses streaming with the set channel type
    IN[0] - Task handle. Handle of the task to pause
    ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_PAUSE               	(CPU_CMD_MASK_CAPTURE | 0x0007)
+#define CX18_CPU_CAPTURE_PAUSE			(CPU_CMD_MASK_CAPTURE | 0x0007)
 
 /* Description: This command resumes streaming with the set channel type
    IN[0] - Task handle. Handle of the task to resume
    ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_RESUME              	(CPU_CMD_MASK_CAPTURE | 0x0008)
+#define CX18_CPU_CAPTURE_RESUME			(CPU_CMD_MASK_CAPTURE | 0x0008)
 
-#define CAPTURE_CHANNEL_TYPE_NONE  		0
-#define CAPTURE_CHANNEL_TYPE_MPEG  		1
-#define CAPTURE_CHANNEL_TYPE_INDEX 		2
-#define CAPTURE_CHANNEL_TYPE_YUV   		3
-#define CAPTURE_CHANNEL_TYPE_PCM   		4
-#define CAPTURE_CHANNEL_TYPE_VBI   		5
+#define CAPTURE_CHANNEL_TYPE_NONE		0
+#define CAPTURE_CHANNEL_TYPE_MPEG		1
+#define CAPTURE_CHANNEL_TYPE_INDEX		2
+#define CAPTURE_CHANNEL_TYPE_YUV		3
+#define CAPTURE_CHANNEL_TYPE_PCM		4
+#define CAPTURE_CHANNEL_TYPE_VBI		5
 #define CAPTURE_CHANNEL_TYPE_SLICED_VBI		6
 #define CAPTURE_CHANNEL_TYPE_TS			7
-#define CAPTURE_CHANNEL_TYPE_MAX   		15
+#define CAPTURE_CHANNEL_TYPE_MAX		15
 
 /* Description: This command sets the channel type. This can only be done
    when stopped.
    IN[0] - Task handle. Handle of the task to start
    IN[1] - Channel Type. See Below.
    ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_CHANNEL_TYPE      		(CPU_CMD_MASK_CAPTURE + 1)
+#define CX18_CPU_SET_CHANNEL_TYPE		(CPU_CMD_MASK_CAPTURE + 1)
 
 /* Description: Set stream output type
    IN[0] - task handle. Handle of the task to start
@@ -140,7 +140,7 @@
    IN[4] - reserved
    IN[5] - frame rate, 0 - 29.97f/s, 1 - 25f/s
    ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_IN                	(CPU_CMD_MASK_CAPTURE | 0x0004)
+#define CX18_CPU_SET_VIDEO_IN			(CPU_CMD_MASK_CAPTURE | 0x0004)
 
 /* Description: Set video frame rate
    IN[0] - task handle. Handle of the task to start
@@ -149,7 +149,7 @@
    IN[3] - video peak rate
    IN[4] - system mux rate
    ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_RATE              	(CPU_CMD_MASK_CAPTURE | 0x0005)
+#define CX18_CPU_SET_VIDEO_RATE			(CPU_CMD_MASK_CAPTURE | 0x0005)
 
 /* Description: Set video output resolution
    IN[0] - task handle
@@ -166,7 +166,7 @@
 				3 = horizontal/vertical, 4 = diagonal
    IN[3] - strength, temporal 0 - 31, spatial 0 - 15
    ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_FILTER_PARAM            	(CPU_CMD_MASK_CAPTURE | 0x0009)
+#define CX18_CPU_SET_FILTER_PARAM		(CPU_CMD_MASK_CAPTURE | 0x0009)
 
 /* Description: This command set spatial filter type
    IN[0] - Task handle.
@@ -174,7 +174,7 @@
 		      3 = 2D H/V separable, 4 = 2D symmetric non-separable
    IN[2] - chroma type: 0 - disable, 1 = 1D horizontal
    ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_SPATIAL_FILTER_TYPE     	(CPU_CMD_MASK_CAPTURE | 0x000C)
+#define CX18_CPU_SET_SPATIAL_FILTER_TYPE	(CPU_CMD_MASK_CAPTURE | 0x000C)
 
 /* Description: This command set coring levels for median filter
    IN[0] - Task handle.
@@ -183,16 +183,16 @@
    IN[3] - chroma_high
    IN[4] - chroma_low
    ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_MEDIAN_CORING           	(CPU_CMD_MASK_CAPTURE | 0x000E)
+#define CX18_CPU_SET_MEDIAN_CORING		(CPU_CMD_MASK_CAPTURE | 0x000E)
 
 /* Description: This command set the picture type mask for index file
    IN[0] - Task handle (ignored by firmware)
-   IN[1] - 	0 = disable index file output
+   IN[1] -	0 = disable index file output
 			1 = output I picture
 			2 = P picture
 			4 = B picture
 			other = illegal */
-#define CX18_CPU_SET_INDEXTABLE         	(CPU_CMD_MASK_CAPTURE | 0x0010)
+#define CX18_CPU_SET_INDEXTABLE			(CPU_CMD_MASK_CAPTURE | 0x0010)
 
 /* Description: Set audio parameters
    IN[0] - task handle. Handle of the task to start
@@ -218,7 +218,7 @@
 /* Description: Set stream output type
    IN[0] - task handle. Handle of the task to start
    IN[1] - subType
-	    SET_INITIAL_SCR      		1
+	    SET_INITIAL_SCR			1
 	    SET_QUALITY_MODE            2
 	    SET_VIM_PROTECT_MODE        3
 	    SET_PTS_CORRECTION          4
@@ -311,7 +311,7 @@
 			bit 0:	output user data, 1 - enable
 			bit 1:	output private stream, 1 - enable
 			bit 2:	mux option, 0 - in GOP, 1 - in picture
-			bit[7:0] 	private stream ID
+			bit[7:0]	private stream ID
    IN[5] - insertion period while mux option is in picture
    ReturnCode - VBI data offset */
 #define CX18_CPU_SET_SLICED_VBI_PARAM		(CPU_CMD_MASK_CAPTURE | 0x0020)
@@ -344,13 +344,13 @@
 #define CX18_CPU_SET_VFC_PARAM                  (CPU_CMD_MASK_CAPTURE | 0x0023)
 
 /* Below is the list of commands related to the data exchange */
-#define CPU_CMD_MASK_DE 			(CPU_CMD_MASK | 0x040000)
+#define CPU_CMD_MASK_DE				(CPU_CMD_MASK | 0x040000)
 
 /* Description: This command provides the physical base address of the local
    DDR as viewed by EPU
    IN[0] - Physical offset where EPU has the local DDR mapped
    ReturnCode - One of the ERR_DE_... */
-#define CPU_CMD_DE_SetBase 			(CPU_CMD_MASK_DE | 0x0001)
+#define CPU_CMD_DE_SetBase			(CPU_CMD_MASK_DE | 0x0001)
 
 /* Description: This command provides the offsets in the device memory where
    the 2 cx18_mdl_ack blocks reside
@@ -360,7 +360,7 @@
    IN[2] - Offset of the second cx18_mdl_ack from the beginning of the
 	   local DDR.
    ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_SET_MDL_ACK                	(CPU_CMD_MASK_DE | 0x0002)
+#define CX18_CPU_DE_SET_MDL_ACK			(CPU_CMD_MASK_DE | 0x0002)
 
 /* Description: This command provides the offset to a Memory Descriptor List
    IN[0] - Task handle. Handle of the task to start
@@ -369,13 +369,13 @@
    IN[3] - Buffer ID
    IN[4] - Total buffer length
    ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_SET_MDL                   	(CPU_CMD_MASK_DE | 0x0005)
+#define CX18_CPU_DE_SET_MDL			(CPU_CMD_MASK_DE | 0x0005)
 
 /* Description: This command requests return of all current Memory
    Descriptor Lists to the driver
    IN[0] - Task handle. Handle of the task to start
    ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_RELEASE_MDL               	(CPU_CMD_MASK_DE | 0x0006)
+#define CX18_CPU_DE_RELEASE_MDL			(CPU_CMD_MASK_DE | 0x0006)
 
 /* Description: This command signals the cpu that the dat buffer has been
    consumed and ready for re-use.
diff --git a/drivers/media/pci/cx23885/Makefile b/drivers/media/pci/cx23885/Makefile
index b8bf780..130f0aa 100644
--- a/drivers/media/pci/cx23885/Makefile
+++ b/drivers/media/pci/cx23885/Makefile
@@ -8,9 +8,7 @@
 obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
 obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
 
-ccflags-y += -Idrivers/media/i2c
 ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 
 ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c
index 5c94e31..70aec9b 100644
--- a/drivers/media/pci/cx23885/altera-ci.c
+++ b/drivers/media/pci/cx23885/altera-ci.c
@@ -51,10 +51,10 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <dvb_demux.h>
-#include <dvb_frontend.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
 #include "altera-ci.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 
 /* FPGA regs */
 #define NETUP_CI_INT_CTRL	0x00
diff --git a/drivers/media/pci/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c
index 5e8e134..19c005f 100644
--- a/drivers/media/pci/cx23885/cimax2.c
+++ b/drivers/media/pci/cx23885/cimax2.c
@@ -21,7 +21,7 @@
 
 #include "cx23885.h"
 #include "cimax2.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 
 /* Max transfer size done by I2C transfer functions */
 #define MAX_XFER_SIZE  64
@@ -54,7 +54,7 @@
 #define NETUP_CI_CTL		0x04
 #define NETUP_CI_RD		1
 
-#define NETUP_IRQ_DETAM 	0x1
+#define NETUP_IRQ_DETAM		0x1
 #define NETUP_IRQ_IRQAM		0x4
 
 static unsigned int ci_dbg;
diff --git a/drivers/media/pci/cx23885/cimax2.h b/drivers/media/pci/cx23885/cimax2.h
index 565e958..167ffe2 100644
--- a/drivers/media/pci/cx23885/cimax2.h
+++ b/drivers/media/pci/cx23885/cimax2.h
@@ -21,7 +21,7 @@
 
 #ifndef CIMAX2_H
 #define CIMAX2_H
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 
 extern int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
 						int slot, int addr);
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index 28eab9c..3622521 100644
--- a/drivers/media/pci/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -1816,13 +1816,13 @@ int cx23885_ir_init(struct cx23885_dev *dev)
 {
 	static struct v4l2_subdev_io_pin_config ir_rxtx_pin_cfg[] = {
 		{
-			.flags	  = V4L2_SUBDEV_IO_PIN_INPUT,
+			.flags	  = BIT(V4L2_SUBDEV_IO_PIN_INPUT),
 			.pin	  = CX23885_PIN_IR_RX_GPIO19,
 			.function = CX23885_PAD_IR_RX,
 			.value	  = 0,
 			.strength = CX25840_PIN_DRIVE_MEDIUM,
 		}, {
-			.flags	  = V4L2_SUBDEV_IO_PIN_OUTPUT,
+			.flags	  = BIT(V4L2_SUBDEV_IO_PIN_OUTPUT),
 			.pin	  = CX23885_PIN_IR_TX_GPIO20,
 			.function = CX23885_PAD_IR_TX,
 			.value	  = 0,
@@ -1833,7 +1833,7 @@ int cx23885_ir_init(struct cx23885_dev *dev)
 
 	static struct v4l2_subdev_io_pin_config ir_rx_pin_cfg[] = {
 		{
-			.flags	  = V4L2_SUBDEV_IO_PIN_INPUT,
+			.flags	  = BIT(V4L2_SUBDEV_IO_PIN_INPUT),
 			.pin	  = CX23885_PIN_IR_RX_GPIO19,
 			.function = CX23885_PAD_IR_RX,
 			.value	  = 0,
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index e795dde..700422b 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -27,7 +27,7 @@
 
 #include <media/v4l2-common.h>
 
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 #include "s5h1409.h"
 #include "s5h1411.h"
 #include "mt2131.h"
@@ -1852,8 +1852,8 @@ static int dvb_register(struct cx23885_tsport *port)
 			/* attach frontend */
 			memset(&si2165_pdata, 0, sizeof(si2165_pdata));
 			si2165_pdata.fe = &fe0->dvb.frontend;
-			si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL,
-			si2165_pdata.ref_freq_Hz = 16000000,
+			si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL;
+			si2165_pdata.ref_freq_hz = 16000000;
 			memset(&info, 0, sizeof(struct i2c_board_info));
 			strlcpy(info.type, "si2165", I2C_NAME_SIZE);
 			info.addr = 0x64;
diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c
index 944b7083..0f4e542 100644
--- a/drivers/media/pci/cx23885/cx23885-input.c
+++ b/drivers/media/pci/cx23885/cx23885-input.c
@@ -340,14 +340,23 @@ int cx23885_input_init(struct cx23885_dev *dev)
 	kernel_ir->cx = dev;
 	kernel_ir->name = kasprintf(GFP_KERNEL, "cx23885 IR (%s)",
 				    cx23885_boards[dev->board].name);
+	if (!kernel_ir->name) {
+		ret = -ENOMEM;
+		goto err_out_free;
+	}
+
 	kernel_ir->phys = kasprintf(GFP_KERNEL, "pci-%s/ir0",
 				    pci_name(dev->pci));
+	if (!kernel_ir->phys) {
+		ret = -ENOMEM;
+		goto err_out_free_name;
+	}
 
 	/* input device */
 	rc = rc_allocate_device(RC_DRIVER_IR_RAW);
 	if (!rc) {
 		ret = -ENOMEM;
-		goto err_out_free;
+		goto err_out_free_phys;
 	}
 
 	kernel_ir->rc = rc;
@@ -382,9 +391,11 @@ int cx23885_input_init(struct cx23885_dev *dev)
 	cx23885_input_ir_stop(dev);
 	dev->kernel_ir = NULL;
 	rc_free_device(rc);
-err_out_free:
+err_out_free_phys:
 	kfree(kernel_ir->phys);
+err_out_free_name:
 	kfree(kernel_ir->name);
+err_out_free:
 	kfree(kernel_ir);
 	return ret;
 }
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index ecc580a..a03dcb6 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -1146,7 +1146,7 @@ static struct video_device cx23885_vbi_template;
 static struct video_device cx23885_video_template = {
 	.name                 = "cx23885-video",
 	.fops                 = &video_fops,
-	.ioctl_ops 	      = &video_ioctl_ops,
+	.ioctl_ops	      = &video_ioctl_ops,
 	.tvnorms              = CX23885_NORMS,
 };
 
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 6aab713..2a17209 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -357,7 +357,7 @@ struct cx23885_audio_dev {
 
 struct cx23885_dev {
 	atomic_t                   refcount;
-	struct v4l2_device 	   v4l2_dev;
+	struct v4l2_device	   v4l2_dev;
 	struct v4l2_ctrl_handler   ctrl_handler;
 
 	/* pci stuff */
@@ -407,7 +407,7 @@ struct cx23885_dev {
 	unsigned int               tuner_bus;
 	unsigned int               radio_type;
 	unsigned char              radio_addr;
-	struct v4l2_subdev 	   *sd_cx25840;
+	struct v4l2_subdev	   *sd_cx25840;
 	struct work_struct	   cx25840_work;
 
 	/* Infrared */
diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c
index 040323b..00329f6 100644
--- a/drivers/media/pci/cx23885/cx23888-ir.c
+++ b/drivers/media/pci/cx23885/cx23888-ir.c
@@ -29,7 +29,7 @@ static unsigned int ir_888_debug;
 module_param(ir_888_debug, int, 0644);
 MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]");
 
-#define CX23888_IR_REG_BASE 	0x170000
+#define CX23888_IR_REG_BASE	0x170000
 /*
  * These CX23888 register offsets have a straightforward one to one mapping
  * to the CX23885 register offsets of 0x200 through 0x218
@@ -170,7 +170,7 @@ static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr,
  * Rx and Tx Clock Divider register computations
  *
  * Note the largest clock divider value of 0xffff corresponds to:
- * 	(0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
+ *	(0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
  * which fits in 21 bits, so we'll use unsigned int for time arguments.
  */
 static inline u16 count_to_clock_divider(unsigned int d)
@@ -226,7 +226,7 @@ static inline unsigned int clock_divider_to_freq(unsigned int divider,
  * Low Pass Filter register calculations
  *
  * Note the largest count value of 0xffff corresponds to:
- * 	0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
+ *	0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
  * which fits in 21 bits, so we'll use unsigned int for time arguments.
  */
 static inline u16 count_to_lpf_count(unsigned int d)
diff --git a/drivers/media/pci/cx25821/Makefile b/drivers/media/pci/cx25821/Makefile
index d14d65b..94633d0 100644
--- a/drivers/media/pci/cx25821/Makefile
+++ b/drivers/media/pci/cx25821/Makefile
@@ -5,5 +5,3 @@
 
 obj-$(CONFIG_VIDEO_CX25821) += cx25821.o
 obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o
-
-ccflags-y += -Idrivers/media/i2c
diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c
index 2b34990..a45bf03 100644
--- a/drivers/media/pci/cx25821/cx25821-alsa.c
+++ b/drivers/media/pci/cx25821/cx25821-alsa.c
@@ -152,8 +152,8 @@ static int cx25821_alsa_dma_init(struct cx25821_audio_dev *chip, int nr_pages)
 		return -ENOMEM;
 	}
 
-	dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
-				(unsigned long)buf->vaddr,
+	dprintk(1, "vmalloc is at addr 0x%p, size=%d\n",
+				buf->vaddr,
 				nr_pages << PAGE_SHIFT);
 
 	memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT);
diff --git a/drivers/media/pci/cx88/Makefile b/drivers/media/pci/cx88/Makefile
index 86646ee..d0f45d6 100644
--- a/drivers/media/pci/cx88/Makefile
+++ b/drivers/media/pci/cx88/Makefile
@@ -10,8 +10,5 @@
 obj-$(CONFIG_VIDEO_CX88_BLACKBIRD) += cx88-blackbird.o
 obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
 obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
-
-ccflags-y += -Idrivers/media/i2c
 ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c
index e3101f0..0e0952e 100644
--- a/drivers/media/pci/cx88/cx88-blackbird.c
+++ b/drivers/media/pci/cx88/cx88-blackbird.c
@@ -805,8 +805,7 @@ static int vidioc_querycap(struct file *file, void  *priv,
 
 	strcpy(cap->driver, "cx88_blackbird");
 	sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
-	cx88_querycap(file, core, cap);
-	return 0;
+	return cx88_querycap(file, core, cap);
 }
 
 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index 7d25ecd..9be682c 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -806,8 +806,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	return 0;
 }
 
-void cx88_querycap(struct file *file, struct cx88_core *core,
-		   struct v4l2_capability *cap)
+int cx88_querycap(struct file *file, struct cx88_core *core,
+		  struct v4l2_capability *cap)
 {
 	struct video_device *vdev = video_devdata(file);
 
@@ -825,11 +825,14 @@ void cx88_querycap(struct file *file, struct cx88_core *core,
 	case VFL_TYPE_VBI:
 		cap->device_caps |= V4L2_CAP_VBI_CAPTURE;
 		break;
+	default:
+		return -EINVAL;
 	}
 	cap->capabilities = cap->device_caps | V4L2_CAP_VIDEO_CAPTURE |
 		V4L2_CAP_VBI_CAPTURE | V4L2_CAP_DEVICE_CAPS;
 	if (core->board.radio.type == CX88_RADIO)
 		cap->capabilities |= V4L2_CAP_RADIO;
+	return 0;
 }
 EXPORT_SYMBOL(cx88_querycap);
 
@@ -841,8 +844,7 @@ static int vidioc_querycap(struct file *file, void  *priv,
 
 	strcpy(cap->driver, "cx8800");
 	sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
-	cx88_querycap(file, core, cap);
-	return 0;
+	return cx88_querycap(file, core, cap);
 }
 
 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
index 6777926..07a33f0 100644
--- a/drivers/media/pci/cx88/cx88.h
+++ b/drivers/media/pci/cx88/cx88.h
@@ -734,7 +734,7 @@ int cx8802_start_dma(struct cx8802_dev    *dev,
 int cx88_enum_input(struct cx88_core *core, struct v4l2_input *i);
 int cx88_set_freq(struct cx88_core  *core, const struct v4l2_frequency *f);
 int cx88_video_mux(struct cx88_core *core, unsigned int input);
-void cx88_querycap(struct file *file, struct cx88_core *core,
-		   struct v4l2_capability *cap);
+int cx88_querycap(struct file *file, struct cx88_core *core,
+		  struct v4l2_capability *cap);
 
 #endif
diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile
index 7453b65..f58fdec 100644
--- a/drivers/media/pci/ddbridge/Makefile
+++ b/drivers/media/pci/ddbridge/Makefile
@@ -3,12 +3,11 @@
 # Makefile for the ddbridge device driver
 #
 
-ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-hw.o \
-		ddbridge-i2c.o ddbridge-maxs8.o
+ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-ci.o \
+		ddbridge-hw.o ddbridge-i2c.o ddbridge-max.o
 
 obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
 
-ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/dvb-frontends/
 ccflags-y += -Idrivers/media/tuners/
 
diff --git a/drivers/media/pci/ddbridge/ddbridge-ci.c b/drivers/media/pci/ddbridge/ddbridge-ci.c
new file mode 100644
index 0000000..5828111
--- /dev/null
+++ b/drivers/media/pci/ddbridge/ddbridge-ci.c
@@ -0,0 +1,359 @@
+/*
+ * ddbridge-ci.c: Digital Devices bridge CI (DuoFlex, CI Bridge) support
+ *
+ * Copyright (C) 2010-2017 Digital Devices GmbH
+ *                         Marcus Metzler <mocm@metzlerbros.de>
+ *                         Ralph Metzler <rjkm@metzlerbros.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 only, 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.
+ *
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "ddbridge.h"
+#include "ddbridge-regs.h"
+#include "ddbridge-ci.h"
+#include "ddbridge-io.h"
+#include "ddbridge-i2c.h"
+
+#include "cxd2099.h"
+
+/* Octopus CI internal CI interface */
+
+static int wait_ci_ready(struct ddb_ci *ci)
+{
+	u32 count = 10;
+
+	ndelay(500);
+	do {
+		if (ddbreadl(ci->port->dev,
+			     CI_CONTROL(ci->nr)) & CI_READY)
+			break;
+		usleep_range(1, 2);
+		if ((--count) == 0)
+			return -1;
+	} while (1);
+	return 0;
+}
+
+static int read_attribute_mem(struct dvb_ca_en50221 *ca,
+			      int slot, int address)
+{
+	struct ddb_ci *ci = ca->data;
+	u32 val, off = (address >> 1) & (CI_BUFFER_SIZE - 1);
+
+	if (address > CI_BUFFER_SIZE)
+		return -1;
+	ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address,
+		  CI_DO_READ_ATTRIBUTES(ci->nr));
+	wait_ci_ready(ci);
+	val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off);
+	return val;
+}
+
+static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
+			       int address, u8 value)
+{
+	struct ddb_ci *ci = ca->data;
+
+	ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
+		  CI_DO_ATTRIBUTE_RW(ci->nr));
+	wait_ci_ready(ci);
+	return 0;
+}
+
+static int read_cam_control(struct dvb_ca_en50221 *ca,
+			    int slot, u8 address)
+{
+	u32 count = 100;
+	struct ddb_ci *ci = ca->data;
+	u32 res;
+
+	ddbwritel(ci->port->dev, CI_READ_CMD | address,
+		  CI_DO_IO_RW(ci->nr));
+	ndelay(500);
+	do {
+		res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr));
+		if (res & CI_READY)
+			break;
+		usleep_range(1, 2);
+		if ((--count) == 0)
+			return -1;
+	} while (1);
+	return 0xff & res;
+}
+
+static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
+			     u8 address, u8 value)
+{
+	struct ddb_ci *ci = ca->data;
+
+	ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
+		  CI_DO_IO_RW(ci->nr));
+	wait_ci_ready(ci);
+	return 0;
+}
+
+static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
+{
+	struct ddb_ci *ci = ca->data;
+
+	ddbwritel(ci->port->dev, CI_POWER_ON,
+		  CI_CONTROL(ci->nr));
+	msleep(100);
+	ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM,
+		  CI_CONTROL(ci->nr));
+	ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM,
+		  CI_CONTROL(ci->nr));
+	usleep_range(20, 25);
+	ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON,
+		  CI_CONTROL(ci->nr));
+	return 0;
+}
+
+static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
+{
+	struct ddb_ci *ci = ca->data;
+
+	ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr));
+	msleep(300);
+	return 0;
+}
+
+static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
+{
+	struct ddb_ci *ci = ca->data;
+	u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
+
+	ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE,
+		  CI_CONTROL(ci->nr));
+	return 0;
+}
+
+static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+	struct ddb_ci *ci = ca->data;
+	u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
+	int stat = 0;
+
+	if (val & CI_CAM_DETECT)
+		stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
+	if (val & CI_CAM_READY)
+		stat |= DVB_CA_EN50221_POLL_CAM_READY;
+	return stat;
+}
+
+static struct dvb_ca_en50221 en_templ = {
+	.read_attribute_mem  = read_attribute_mem,
+	.write_attribute_mem = write_attribute_mem,
+	.read_cam_control    = read_cam_control,
+	.write_cam_control   = write_cam_control,
+	.slot_reset          = slot_reset,
+	.slot_shutdown       = slot_shutdown,
+	.slot_ts_enable      = slot_ts_enable,
+	.poll_slot_status    = poll_slot_status,
+};
+
+static void ci_attach(struct ddb_port *port)
+{
+	struct ddb_ci *ci = NULL;
+
+	ci = kzalloc(sizeof(*ci), GFP_KERNEL);
+	if (!ci)
+		return;
+	memcpy(&ci->en, &en_templ, sizeof(en_templ));
+	ci->en.data = ci;
+	port->en = &ci->en;
+	ci->port = port;
+	ci->nr = port->nr - 2;
+}
+
+/* DuoFlex Dual CI support */
+
+static int write_creg(struct ddb_ci *ci, u8 data, u8 mask)
+{
+	struct i2c_adapter *i2c = &ci->port->i2c->adap;
+	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+
+	ci->port->creg = (ci->port->creg & ~mask) | data;
+	return i2c_write_reg(i2c, adr, 0x02, ci->port->creg);
+}
+
+static int read_attribute_mem_xo2(struct dvb_ca_en50221 *ca,
+				  int slot, int address)
+{
+	struct ddb_ci *ci = ca->data;
+	struct i2c_adapter *i2c = &ci->port->i2c->adap;
+	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+	int res;
+	u8 val;
+
+	res = i2c_read_reg16(i2c, adr, 0x8000 | address, &val);
+	return res ? res : val;
+}
+
+static int write_attribute_mem_xo2(struct dvb_ca_en50221 *ca, int slot,
+				   int address, u8 value)
+{
+	struct ddb_ci *ci = ca->data;
+	struct i2c_adapter *i2c = &ci->port->i2c->adap;
+	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+
+	return i2c_write_reg16(i2c, adr, 0x8000 | address, value);
+}
+
+static int read_cam_control_xo2(struct dvb_ca_en50221 *ca,
+				int slot, u8 address)
+{
+	struct ddb_ci *ci = ca->data;
+	struct i2c_adapter *i2c = &ci->port->i2c->adap;
+	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+	u8 val;
+	int res;
+
+	res = i2c_read_reg(i2c, adr, 0x20 | (address & 3), &val);
+	return res ? res : val;
+}
+
+static int write_cam_control_xo2(struct dvb_ca_en50221 *ca, int slot,
+				 u8 address, u8 value)
+{
+	struct ddb_ci *ci = ca->data;
+	struct i2c_adapter *i2c = &ci->port->i2c->adap;
+	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+
+	return i2c_write_reg(i2c, adr, 0x20 | (address & 3), value);
+}
+
+static int slot_reset_xo2(struct dvb_ca_en50221 *ca, int slot)
+{
+	struct ddb_ci *ci = ca->data;
+
+	dev_dbg(ci->port->dev->dev, "%s\n", __func__);
+	write_creg(ci, 0x01, 0x01);
+	write_creg(ci, 0x04, 0x04);
+	msleep(20);
+	write_creg(ci, 0x02, 0x02);
+	write_creg(ci, 0x00, 0x04);
+	write_creg(ci, 0x18, 0x18);
+	return 0;
+}
+
+static int slot_shutdown_xo2(struct dvb_ca_en50221 *ca, int slot)
+{
+	struct ddb_ci *ci = ca->data;
+
+	dev_dbg(ci->port->dev->dev, "%s\n", __func__);
+	write_creg(ci, 0x10, 0xff);
+	write_creg(ci, 0x08, 0x08);
+	return 0;
+}
+
+static int slot_ts_enable_xo2(struct dvb_ca_en50221 *ca, int slot)
+{
+	struct ddb_ci *ci = ca->data;
+
+	dev_dbg(ci->port->dev->dev, "%s\n", __func__);
+	write_creg(ci, 0x00, 0x10);
+	return 0;
+}
+
+static int poll_slot_status_xo2(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+	struct ddb_ci *ci = ca->data;
+	struct i2c_adapter *i2c = &ci->port->i2c->adap;
+	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+	u8 val = 0;
+	int stat = 0;
+
+	i2c_read_reg(i2c, adr, 0x01, &val);
+
+	if (val & 2)
+		stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
+	if (val & 1)
+		stat |= DVB_CA_EN50221_POLL_CAM_READY;
+	return stat;
+}
+
+static struct dvb_ca_en50221 en_xo2_templ = {
+	.read_attribute_mem  = read_attribute_mem_xo2,
+	.write_attribute_mem = write_attribute_mem_xo2,
+	.read_cam_control    = read_cam_control_xo2,
+	.write_cam_control   = write_cam_control_xo2,
+	.slot_reset          = slot_reset_xo2,
+	.slot_shutdown       = slot_shutdown_xo2,
+	.slot_ts_enable      = slot_ts_enable_xo2,
+	.poll_slot_status    = poll_slot_status_xo2,
+};
+
+static void ci_xo2_attach(struct ddb_port *port)
+{
+	struct ddb_ci *ci;
+
+	ci = kzalloc(sizeof(*ci), GFP_KERNEL);
+	if (!ci)
+		return;
+	memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ));
+	ci->en.data = ci;
+	port->en = &ci->en;
+	ci->port = port;
+	ci->nr = port->nr - 2;
+	ci->port->creg = 0;
+	write_creg(ci, 0x10, 0xff);
+	write_creg(ci, 0x08, 0x08);
+}
+
+static struct cxd2099_cfg cxd_cfg = {
+	.bitrate =  72000,
+	.adr     =  0x40,
+	.polarity = 1,
+	.clock_mode = 1,
+	.max_i2c = 512,
+};
+
+int ddb_ci_attach(struct ddb_port *port, u32 bitrate)
+{
+	switch (port->type) {
+	case DDB_CI_EXTERNAL_SONY:
+		cxd_cfg.bitrate = bitrate;
+		port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap);
+		if (!port->en)
+			return -ENODEV;
+		break;
+
+	case DDB_CI_EXTERNAL_XO2:
+	case DDB_CI_EXTERNAL_XO2_B:
+		ci_xo2_attach(port);
+		if (!port->en)
+			return -ENODEV;
+		break;
+
+	case DDB_CI_INTERNAL:
+		ci_attach(port);
+		if (!port->en)
+			return -ENODEV;
+		break;
+	}
+
+	dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1);
+	return 0;
+}
+
+void ddb_ci_detach(struct ddb_port *port)
+{
+	if (port->dvb[0].dev)
+		dvb_unregister_device(port->dvb[0].dev);
+	if (port->en) {
+		dvb_ca_en50221_release(port->en);
+		kfree(port->en->data);
+		port->en = NULL;
+	}
+}
diff --git a/drivers/media/pci/ddbridge/ddbridge-maxs8.h b/drivers/media/pci/ddbridge/ddbridge-ci.h
similarity index 68%
copy from drivers/media/pci/ddbridge/ddbridge-maxs8.h
copy to drivers/media/pci/ddbridge/ddbridge-ci.h
index bb88848..35a3918 100644
--- a/drivers/media/pci/ddbridge/ddbridge-maxs8.h
+++ b/drivers/media/pci/ddbridge/ddbridge-ci.h
@@ -1,9 +1,9 @@
 /*
- * ddbridge-maxs8.h: Digital Devices bridge MaxS4/8 support
+ * ddbridge-ci.h: Digital Devices bridge CI (DuoFlex, CI Bridge) support
  *
  * Copyright (C) 2010-2017 Digital Devices GmbH
- *                         Ralph Metzler <rjkm@metzlerbros.de>
  *                         Marcus Metzler <mocm@metzlerbros.de>
+ *                         Ralph Metzler <rjkm@metzlerbros.de>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -14,16 +14,18 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
  */
 
-#ifndef _DDBRIDGE_MAXS8_H_
-#define _DDBRIDGE_MAXS8_H_
+#ifndef __DDBRIDGE_CI_H__
+#define __DDBRIDGE_CI_H__
 
 #include "ddbridge.h"
 
 /******************************************************************************/
 
-int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm);
-int fe_attach_mxl5xx(struct ddb_input *input);
+int ddb_ci_attach(struct ddb_port *port, u32 bitrate);
+void ddb_ci_detach(struct ddb_port *port);
 
-#endif /* _DDBRIDGE_MAXS8_H */
+#endif /* __DDBRIDGE_CI_H__ */
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c
index 09a25d6..42b4282 100644
--- a/drivers/media/pci/ddbridge/ddbridge-core.c
+++ b/drivers/media/pci/ddbridge/ddbridge-core.c
@@ -37,7 +37,8 @@
 #include "ddbridge.h"
 #include "ddbridge-i2c.h"
 #include "ddbridge-regs.h"
-#include "ddbridge-maxs8.h"
+#include "ddbridge-max.h"
+#include "ddbridge-ci.h"
 #include "ddbridge-io.h"
 
 #include "tda18271c2dd.h"
@@ -112,7 +113,6 @@ static void ddb_set_dma_tables(struct ddb *dev)
 	}
 }
 
-
 /****************************************************************************/
 /****************************************************************************/
 /****************************************************************************/
@@ -210,8 +210,9 @@ static int ddb_redirect(u32 i, u32 p)
 		if (input->redi) {
 			input2->redi = input->redi;
 			input->redi = NULL;
-		} else
+		} else {
 			input2->redi = input;
+		}
 	}
 	input->redo = port->output;
 	port->output->redi = input;
@@ -357,9 +358,9 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
 				max_bitrate = 0;
 				gap = 0;
 				if (bitrate != 72000) {
-					if (bitrate >= 96000)
+					if (bitrate >= 96000) {
 						*con |= 0x800;
-					else {
+					} else {
 						*con |= 0x1000;
 						nco = (bitrate * 8192 + 71999)
 							/ 72000;
@@ -506,7 +507,6 @@ static void ddb_input_start(struct ddb_input *input)
 	}
 }
 
-
 static void ddb_input_start_all(struct ddb_input *input)
 {
 	struct ddb_input *i = input;
@@ -572,7 +572,7 @@ static ssize_t ddb_output_write(struct ddb_output *output,
 	while (left) {
 		len = output->dma->size - output->dma->coff;
 		if ((((output->dma->cbuf + 1) % output->dma->num) == idx) &&
-		    (off == 0)) {
+		    off == 0) {
 			if (len <= 188)
 				break;
 			len -= 188;
@@ -593,7 +593,8 @@ static ssize_t ddb_output_write(struct ddb_output *output,
 				   buf, len))
 			return -EIO;
 		if (alt_dma)
-			dma_sync_single_for_device(dev->dev,
+			dma_sync_single_for_device(
+				dev->dev,
 				output->dma->pbuf[output->dma->cbuf],
 				output->dma->size, DMA_TO_DEVICE);
 		left -= len;
@@ -632,7 +633,7 @@ static u32 ddb_input_avail(struct ddb_input *input)
 }
 
 static ssize_t ddb_input_read(struct ddb_input *input,
-		__user u8 *buf, size_t count)
+			      __user u8 *buf, size_t count)
 {
 	struct ddb *dev = input->port->dev;
 	u32 left = count;
@@ -648,7 +649,8 @@ static ssize_t ddb_input_read(struct ddb_input *input,
 		if (free > left)
 			free = left;
 		if (alt_dma)
-			dma_sync_single_for_cpu(dev->dev,
+			dma_sync_single_for_cpu(
+				dev->dev,
 				input->dma->pbuf[input->dma->cbuf],
 				input->dma->size, DMA_FROM_DEVICE);
 		ret = copy_to_user(buf, input->dma->vbuf[input->dma->cbuf] +
@@ -792,8 +794,10 @@ static int ts_open(struct inode *inode, struct file *file)
 	} else if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
 		if (!output)
 			return -EINVAL;
-	} else
+	} else {
 		return -EINVAL;
+	}
+
 	err = dvb_generic_open(inode, file);
 	if (err < 0)
 		return err;
@@ -822,7 +826,6 @@ static struct dvb_device dvbdev_ci = {
 	.fops    = &ci_fops,
 };
 
-
 /****************************************************************************/
 /****************************************************************************/
 
@@ -848,21 +851,20 @@ static int demod_attach_drxk(struct ddb_input *input)
 	struct i2c_adapter *i2c = &input->port->i2c->adap;
 	struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
 	struct device *dev = input->port->dev->dev;
-	struct dvb_frontend *fe;
 	struct drxk_config config;
 
 	memset(&config, 0, sizeof(config));
 	config.adr = 0x29 + (input->nr & 1);
 	config.microcode_name = "drxk_a3.mc";
 
-	fe = dvb->fe = dvb_attach(drxk_attach, &config, i2c);
-	if (!fe) {
+	dvb->fe = dvb_attach(drxk_attach, &config, i2c);
+	if (!dvb->fe) {
 		dev_err(dev, "No DRXK found!\n");
 		return -ENODEV;
 	}
-	fe->sec_priv = input;
-	dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl;
-	fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
+	dvb->fe->sec_priv = input;
+	dvb->i2c_gate_ctrl = dvb->fe->ops.i2c_gate_ctrl;
+	dvb->fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
 	return 0;
 }
 
@@ -912,19 +914,18 @@ static int demod_attach_stv0367(struct ddb_input *input)
 	struct i2c_adapter *i2c = &input->port->i2c->adap;
 	struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
 	struct device *dev = input->port->dev->dev;
-	struct dvb_frontend *fe;
 
 	/* attach frontend */
-	fe = dvb->fe = dvb_attach(stv0367ddb_attach,
-		&ddb_stv0367_config[(input->nr & 1)], i2c);
+	dvb->fe = dvb_attach(stv0367ddb_attach,
+			     &ddb_stv0367_config[(input->nr & 1)], i2c);
 
 	if (!dvb->fe) {
 		dev_err(dev, "No stv0367 found!\n");
 		return -ENODEV;
 	}
-	fe->sec_priv = input;
-	dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl;
-	fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
+	dvb->fe->sec_priv = input;
+	dvb->i2c_gate_ctrl = dvb->fe->ops.i2c_gate_ctrl;
+	dvb->fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
 	return 0;
 }
 
@@ -956,7 +957,6 @@ static int demod_attach_cxd28xx(struct ddb_input *input, int par, int osc24)
 	struct i2c_adapter *i2c = &input->port->i2c->adap;
 	struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
 	struct device *dev = input->port->dev->dev;
-	struct dvb_frontend *fe;
 	struct cxd2841er_config cfg;
 
 	/* the cxd2841er driver expects 8bit/shifted I2C addresses */
@@ -971,15 +971,15 @@ static int demod_attach_cxd28xx(struct ddb_input *input, int par, int osc24)
 		cfg.flags |= CXD2841ER_TS_SERIAL;
 
 	/* attach frontend */
-	fe = dvb->fe = dvb_attach(cxd2841er_attach_t_c, &cfg, i2c);
+	dvb->fe = dvb_attach(cxd2841er_attach_t_c, &cfg, i2c);
 
 	if (!dvb->fe) {
 		dev_err(dev, "No cxd2837/38/43/54 found!\n");
 		return -ENODEV;
 	}
-	fe->sec_priv = input;
-	dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl;
-	fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
+	dvb->fe->sec_priv = input;
+	dvb->i2c_gate_ctrl = dvb->fe->ops.i2c_gate_ctrl;
+	dvb->fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
 	return 0;
 }
 
@@ -1020,7 +1020,7 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype)
 
 	/* perform tuner init/attach */
 	client = i2c_new_device(adapter, &board_info);
-	if (client == NULL || client->dev.driver == NULL)
+	if (!client || !client->dev.driver)
 		goto err;
 
 	if (!try_module_get(client->dev.driver->owner)) {
@@ -1032,7 +1032,7 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype)
 
 	return 0;
 err:
-	dev_notice(dev, "TDA18212 tuner not found. Device is not fully operational.\n");
+	dev_err(dev, "TDA18212 tuner not found. Device is not fully operational.\n");
 	return -ENODEV;
 }
 
@@ -1114,6 +1114,7 @@ static int demod_attach_stv0900(struct ddb_input *input, int type)
 			0, (input->nr & 1) ?
 			(0x09 - type) : (0x0b - type))) {
 		dev_err(dev, "No LNBH24 found!\n");
+		dvb_frontend_detach(dvb->fe);
 		return -ENODEV;
 	}
 	return 0;
@@ -1135,7 +1136,7 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type)
 		return -ENODEV;
 	}
 	dev_info(dev, "attach tuner input %d adr %02x\n",
-		input->nr, tunerconf->addr);
+		 input->nr, tunerconf->addr);
 
 	feconf->tuner_init          = ctl->tuner_init;
 	feconf->tuner_sleep         = ctl->tuner_sleep;
@@ -1196,6 +1197,7 @@ static int demod_attach_stv0910(struct ddb_input *input, int type)
 		lnbcfg.i2c_address = (((input->nr & 1) ? 0x09 : 0x08) << 1);
 		if (!dvb_attach(lnbh25_attach, dvb->fe, &lnbcfg, i2c)) {
 			dev_err(dev, "No LNBH25 found!\n");
+			dvb_frontend_detach(dvb->fe);
 			return -ENODEV;
 		}
 	}
@@ -1261,19 +1263,22 @@ static void dvb_input_detach(struct ddb_input *input)
 			dvb_unregister_frontend(dvb->fe);
 		/* fallthrough */
 	case 0x30:
-		if (dvb->fe2)
-			dvb_frontend_detach(dvb->fe2);
-		if (dvb->fe)
-			dvb_frontend_detach(dvb->fe);
-		dvb->fe = dvb->fe2 = NULL;
-		/* fallthrough */
-	case 0x20:
 		client = dvb->i2c_client[0];
 		if (client) {
 			module_put(client->dev.driver->owner);
 			i2c_unregister_device(client);
+			dvb->i2c_client[0] = NULL;
+			client = NULL;
 		}
 
+		if (dvb->fe2)
+			dvb_frontend_detach(dvb->fe2);
+		if (dvb->fe)
+			dvb_frontend_detach(dvb->fe);
+		dvb->fe = NULL;
+		dvb->fe2 = NULL;
+		/* fallthrough */
+	case 0x20:
 		dvb_net_release(&dvb->dvbnet);
 		/* fallthrough */
 	case 0x12:
@@ -1409,7 +1414,8 @@ static int dvb_input_attach(struct ddb_input *input)
 		DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
 	dvbdemux->start_feed = start_feed;
 	dvbdemux->stop_feed = stop_feed;
-	dvbdemux->filternum = dvbdemux->feednum = 256;
+	dvbdemux->filternum = 256;
+	dvbdemux->feednum = 256;
 	ret = dvb_dmx_init(dvbdemux);
 	if (ret < 0)
 		return ret;
@@ -1419,7 +1425,7 @@ static int dvb_input_attach(struct ddb_input *input)
 	dvb->dmxdev.demux = &dvbdemux->dmx;
 	ret = dvb_dmxdev_init(&dvb->dmxdev, adap);
 	if (ret < 0)
-		return ret;
+		goto err_detach;
 	dvb->attached = 0x11;
 
 	dvb->mem_frontend.source = DMX_MEMORY_FE;
@@ -1428,66 +1434,62 @@ static int dvb_input_attach(struct ddb_input *input)
 	dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->hw_frontend);
 	ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &dvb->hw_frontend);
 	if (ret < 0)
-		return ret;
+		goto err_detach;
 	dvb->attached = 0x12;
 
 	ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux);
 	if (ret < 0)
-		return ret;
+		goto err_detach;
 	dvb->attached = 0x20;
 
-	dvb->fe = dvb->fe2 = NULL;
+	dvb->fe = NULL;
+	dvb->fe2 = NULL;
 	switch (port->type) {
 	case DDB_TUNER_MXL5XX:
-		if (fe_attach_mxl5xx(input) < 0)
-			return -ENODEV;
+		if (ddb_fe_attach_mxl5xx(input) < 0)
+			goto err_detach;
 		break;
 	case DDB_TUNER_DVBS_ST:
 		if (demod_attach_stv0900(input, 0) < 0)
-			return -ENODEV;
+			goto err_detach;
 		if (tuner_attach_stv6110(input, 0) < 0)
-			return -ENODEV;
+			goto err_tuner;
 		break;
 	case DDB_TUNER_DVBS_ST_AA:
 		if (demod_attach_stv0900(input, 1) < 0)
-			return -ENODEV;
+			goto err_detach;
 		if (tuner_attach_stv6110(input, 1) < 0)
-			return -ENODEV;
+			goto err_tuner;
 		break;
 	case DDB_TUNER_DVBS_STV0910:
 		if (demod_attach_stv0910(input, 0) < 0)
-			return -ENODEV;
+			goto err_detach;
 		if (tuner_attach_stv6111(input, 0) < 0)
-			return -ENODEV;
+			goto err_tuner;
 		break;
 	case DDB_TUNER_DVBS_STV0910_PR:
 		if (demod_attach_stv0910(input, 1) < 0)
-			return -ENODEV;
+			goto err_detach;
 		if (tuner_attach_stv6111(input, 1) < 0)
-			return -ENODEV;
+			goto err_tuner;
 		break;
 	case DDB_TUNER_DVBS_STV0910_P:
 		if (demod_attach_stv0910(input, 0) < 0)
-			return -ENODEV;
+			goto err_detach;
 		if (tuner_attach_stv6111(input, 1) < 0)
-			return -ENODEV;
+			goto err_tuner;
 		break;
 	case DDB_TUNER_DVBCT_TR:
 		if (demod_attach_drxk(input) < 0)
-			return -ENODEV;
+			goto err_detach;
 		if (tuner_attach_tda18271(input) < 0)
-			return -ENODEV;
+			goto err_tuner;
 		break;
 	case DDB_TUNER_DVBCT_ST:
 		if (demod_attach_stv0367(input) < 0)
-			return -ENODEV;
-		if (tuner_attach_tda18212(input, port->type) < 0) {
-			if (dvb->fe2)
-				dvb_frontend_detach(dvb->fe2);
-			if (dvb->fe)
-				dvb_frontend_detach(dvb->fe);
-			return -ENODEV;
-		}
+			goto err_detach;
+		if (tuner_attach_tda18212(input, port->type) < 0)
+			goto err_tuner;
 		break;
 	case DDB_TUNER_DVBC2T2I_SONY_P:
 		if (input->port->dev->link[input->port->lnr].info->ts_quirks &
@@ -1505,14 +1507,9 @@ static int dvb_input_attach(struct ddb_input *input)
 		else
 			par = 1;
 		if (demod_attach_cxd28xx(input, par, osc24) < 0)
-			return -ENODEV;
-		if (tuner_attach_tda18212(input, port->type) < 0) {
-			if (dvb->fe2)
-				dvb_frontend_detach(dvb->fe2);
-			if (dvb->fe)
-				dvb_frontend_detach(dvb->fe);
-			return -ENODEV;
-		}
+			goto err_detach;
+		if (tuner_attach_tda18212(input, port->type) < 0)
+			goto err_tuner;
 		break;
 	case DDB_TUNER_DVBC2T2I_SONY:
 		osc24 = 1;
@@ -1521,14 +1518,9 @@ static int dvb_input_attach(struct ddb_input *input)
 	case DDB_TUNER_DVBC2T2_SONY:
 	case DDB_TUNER_ISDBT_SONY:
 		if (demod_attach_cxd28xx(input, 0, osc24) < 0)
-			return -ENODEV;
-		if (tuner_attach_tda18212(input, port->type) < 0) {
-			if (dvb->fe2)
-				dvb_frontend_detach(dvb->fe2);
-			if (dvb->fe)
-				dvb_frontend_detach(dvb->fe);
-			return -ENODEV;
-		}
+			goto err_detach;
+		if (tuner_attach_tda18212(input, port->type) < 0)
+			goto err_tuner;
 		break;
 	default:
 		return 0;
@@ -1537,11 +1529,13 @@ static int dvb_input_attach(struct ddb_input *input)
 
 	if (dvb->fe) {
 		if (dvb_register_frontend(adap, dvb->fe) < 0)
-			return -ENODEV;
+			goto err_detach;
 
 		if (dvb->fe2) {
-			if (dvb_register_frontend(adap, dvb->fe2) < 0)
-				return -ENODEV;
+			if (dvb_register_frontend(adap, dvb->fe2) < 0) {
+				dvb_unregister_frontend(dvb->fe);
+				goto err_detach;
+			}
 			dvb->fe2->tuner_priv = dvb->fe->tuner_priv;
 			memcpy(&dvb->fe2->ops.tuner_ops,
 			       &dvb->fe->ops.tuner_ops,
@@ -1551,6 +1545,22 @@ static int dvb_input_attach(struct ddb_input *input)
 
 	dvb->attached = 0x31;
 	return 0;
+
+err_tuner:
+	dev_err(port->dev->dev, "tuner attach failed!\n");
+
+	if (dvb->fe2)
+		dvb_frontend_detach(dvb->fe2);
+	if (dvb->fe)
+		dvb_frontend_detach(dvb->fe);
+err_detach:
+	dvb_input_detach(input);
+
+	/* return error from ret if set */
+	if (ret < 0)
+		return ret;
+
+	return -ENODEV;
 }
 
 static int port_has_encti(struct ddb_port *port)
@@ -1703,11 +1713,11 @@ static int init_xo2_ci(struct ddb_port *port)
 
 	if (data[0] > 1)  {
 		dev_info(dev->dev, "Port %d: invalid XO2 CI %02x\n",
-			port->nr, data[0]);
+			 port->nr, data[0]);
 		return -1;
 	}
 	dev_info(dev->dev, "Port %d: DuoFlex CI %u.%u\n",
-		port->nr, data[0], data[1]);
+		 port->nr, data[0], data[1]);
 
 	i2c_read_reg(i2c, 0x10, 0x08, &val);
 	if (val != 0) {
@@ -1718,7 +1728,6 @@ static int init_xo2_ci(struct ddb_port *port)
 	i2c_write_reg(i2c, 0x10, 0x08, 3);
 	usleep_range(2000, 3000);
 
-
 	/* speed: 0=55,1=75,2=90,3=104 MBit/s */
 	i2c_write_reg(i2c, 0x10, 0x09, 1);
 
@@ -1821,7 +1830,7 @@ static void ddb_port_probe(struct ddb_port *port)
 				  port->i2c->regs + I2C_TIMING);
 		} else {
 			dev_info(dev->dev, "Port %d: Uninitialized DuoFlex\n",
-			       port->nr);
+				 port->nr);
 			return;
 		}
 	} else if (port_has_xo2(port, &type, &id)) {
@@ -1912,338 +1921,10 @@ static void ddb_port_probe(struct ddb_port *port)
 	}
 }
 
-
 /****************************************************************************/
 /****************************************************************************/
 /****************************************************************************/
 
-static int wait_ci_ready(struct ddb_ci *ci)
-{
-	u32 count = 10;
-
-	ndelay(500);
-	do {
-		if (ddbreadl(ci->port->dev,
-			     CI_CONTROL(ci->nr)) & CI_READY)
-			break;
-		usleep_range(1, 2);
-		if ((--count) == 0)
-			return -1;
-	} while (1);
-	return 0;
-}
-
-static int read_attribute_mem(struct dvb_ca_en50221 *ca,
-			      int slot, int address)
-{
-	struct ddb_ci *ci = ca->data;
-	u32 val, off = (address >> 1) & (CI_BUFFER_SIZE - 1);
-
-	if (address > CI_BUFFER_SIZE)
-		return -1;
-	ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address,
-		  CI_DO_READ_ATTRIBUTES(ci->nr));
-	wait_ci_ready(ci);
-	val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off);
-	return val;
-}
-
-static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
-			       int address, u8 value)
-{
-	struct ddb_ci *ci = ca->data;
-
-	ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
-		  CI_DO_ATTRIBUTE_RW(ci->nr));
-	wait_ci_ready(ci);
-	return 0;
-}
-
-static int read_cam_control(struct dvb_ca_en50221 *ca,
-			    int slot, u8 address)
-{
-	u32 count = 100;
-	struct ddb_ci *ci = ca->data;
-	u32 res;
-
-	ddbwritel(ci->port->dev, CI_READ_CMD | address,
-		  CI_DO_IO_RW(ci->nr));
-	ndelay(500);
-	do {
-		res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr));
-		if (res & CI_READY)
-			break;
-		usleep_range(1, 2);
-		if ((--count) == 0)
-			return -1;
-	} while (1);
-	return 0xff & res;
-}
-
-static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
-			     u8 address, u8 value)
-{
-	struct ddb_ci *ci = ca->data;
-
-	ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
-		  CI_DO_IO_RW(ci->nr));
-	wait_ci_ready(ci);
-	return 0;
-}
-
-static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
-{
-	struct ddb_ci *ci = ca->data;
-
-	ddbwritel(ci->port->dev, CI_POWER_ON,
-		  CI_CONTROL(ci->nr));
-	msleep(100);
-	ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM,
-		  CI_CONTROL(ci->nr));
-	ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM,
-		  CI_CONTROL(ci->nr));
-	udelay(20);
-	ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON,
-		  CI_CONTROL(ci->nr));
-	return 0;
-}
-
-static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
-{
-	struct ddb_ci *ci = ca->data;
-
-	ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr));
-	msleep(300);
-	return 0;
-}
-
-static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
-{
-	struct ddb_ci *ci = ca->data;
-	u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
-
-	ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE,
-		  CI_CONTROL(ci->nr));
-	return 0;
-}
-
-static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
-{
-	struct ddb_ci *ci = ca->data;
-	u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
-	int stat = 0;
-
-	if (val & CI_CAM_DETECT)
-		stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
-	if (val & CI_CAM_READY)
-		stat |= DVB_CA_EN50221_POLL_CAM_READY;
-	return stat;
-}
-
-static struct dvb_ca_en50221 en_templ = {
-	.read_attribute_mem  = read_attribute_mem,
-	.write_attribute_mem = write_attribute_mem,
-	.read_cam_control    = read_cam_control,
-	.write_cam_control   = write_cam_control,
-	.slot_reset          = slot_reset,
-	.slot_shutdown       = slot_shutdown,
-	.slot_ts_enable      = slot_ts_enable,
-	.poll_slot_status    = poll_slot_status,
-};
-
-static void ci_attach(struct ddb_port *port)
-{
-	struct ddb_ci *ci = NULL;
-
-	ci = kzalloc(sizeof(*ci), GFP_KERNEL);
-	if (!ci)
-		return;
-	memcpy(&ci->en, &en_templ, sizeof(en_templ));
-	ci->en.data = ci;
-	port->en = &ci->en;
-	ci->port = port;
-	ci->nr = port->nr - 2;
-}
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-static int write_creg(struct ddb_ci *ci, u8 data, u8 mask)
-{
-	struct i2c_adapter *i2c = &ci->port->i2c->adap;
-	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
-
-	ci->port->creg = (ci->port->creg & ~mask) | data;
-	return i2c_write_reg(i2c, adr, 0x02, ci->port->creg);
-}
-
-static int read_attribute_mem_xo2(struct dvb_ca_en50221 *ca,
-				  int slot, int address)
-{
-	struct ddb_ci *ci = ca->data;
-	struct i2c_adapter *i2c = &ci->port->i2c->adap;
-	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
-	int res;
-	u8 val;
-
-	res = i2c_read_reg16(i2c, adr, 0x8000 | address, &val);
-	return res ? res : val;
-}
-
-static int write_attribute_mem_xo2(struct dvb_ca_en50221 *ca, int slot,
-				   int address, u8 value)
-{
-	struct ddb_ci *ci = ca->data;
-	struct i2c_adapter *i2c = &ci->port->i2c->adap;
-	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
-
-	return i2c_write_reg16(i2c, adr, 0x8000 | address, value);
-}
-
-static int read_cam_control_xo2(struct dvb_ca_en50221 *ca,
-				int slot, u8 address)
-{
-	struct ddb_ci *ci = ca->data;
-	struct i2c_adapter *i2c = &ci->port->i2c->adap;
-	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
-	u8 val;
-	int res;
-
-	res = i2c_read_reg(i2c, adr, 0x20 | (address & 3), &val);
-	return res ? res : val;
-}
-
-static int write_cam_control_xo2(struct dvb_ca_en50221 *ca, int slot,
-				 u8 address, u8 value)
-{
-	struct ddb_ci *ci = ca->data;
-	struct i2c_adapter *i2c = &ci->port->i2c->adap;
-	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
-
-	return i2c_write_reg(i2c, adr, 0x20 | (address & 3), value);
-}
-
-static int slot_reset_xo2(struct dvb_ca_en50221 *ca, int slot)
-{
-	struct ddb_ci *ci = ca->data;
-
-	dev_dbg(ci->port->dev->dev, "%s\n", __func__);
-	write_creg(ci, 0x01, 0x01);
-	write_creg(ci, 0x04, 0x04);
-	msleep(20);
-	write_creg(ci, 0x02, 0x02);
-	write_creg(ci, 0x00, 0x04);
-	write_creg(ci, 0x18, 0x18);
-	return 0;
-}
-
-static int slot_shutdown_xo2(struct dvb_ca_en50221 *ca, int slot)
-{
-	struct ddb_ci *ci = ca->data;
-
-	dev_dbg(ci->port->dev->dev, "%s\n", __func__);
-	write_creg(ci, 0x10, 0xff);
-	write_creg(ci, 0x08, 0x08);
-	return 0;
-}
-
-static int slot_ts_enable_xo2(struct dvb_ca_en50221 *ca, int slot)
-{
-	struct ddb_ci *ci = ca->data;
-
-	dev_info(ci->port->dev->dev, "%s\n", __func__);
-	write_creg(ci, 0x00, 0x10);
-	return 0;
-}
-
-static int poll_slot_status_xo2(struct dvb_ca_en50221 *ca, int slot, int open)
-{
-	struct ddb_ci *ci = ca->data;
-	struct i2c_adapter *i2c = &ci->port->i2c->adap;
-	u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
-	u8 val = 0;
-	int stat = 0;
-
-	i2c_read_reg(i2c, adr, 0x01, &val);
-
-	if (val & 2)
-		stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
-	if (val & 1)
-		stat |= DVB_CA_EN50221_POLL_CAM_READY;
-	return stat;
-}
-
-static struct dvb_ca_en50221 en_xo2_templ = {
-	.read_attribute_mem  = read_attribute_mem_xo2,
-	.write_attribute_mem = write_attribute_mem_xo2,
-	.read_cam_control    = read_cam_control_xo2,
-	.write_cam_control   = write_cam_control_xo2,
-	.slot_reset          = slot_reset_xo2,
-	.slot_shutdown       = slot_shutdown_xo2,
-	.slot_ts_enable      = slot_ts_enable_xo2,
-	.poll_slot_status    = poll_slot_status_xo2,
-};
-
-static void ci_xo2_attach(struct ddb_port *port)
-{
-	struct ddb_ci *ci;
-
-	ci = kzalloc(sizeof(*ci), GFP_KERNEL);
-	if (!ci)
-		return;
-	memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ));
-	ci->en.data = ci;
-	port->en = &ci->en;
-	ci->port = port;
-	ci->nr = port->nr - 2;
-	ci->port->creg = 0;
-	write_creg(ci, 0x10, 0xff);
-	write_creg(ci, 0x08, 0x08);
-}
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-static struct cxd2099_cfg cxd_cfg = {
-	.bitrate =  72000,
-	.adr     =  0x40,
-	.polarity = 1,
-	.clock_mode = 1,
-	.max_i2c = 512,
-};
-
-static int ddb_ci_attach(struct ddb_port *port)
-{
-	switch (port->type) {
-	case DDB_CI_EXTERNAL_SONY:
-		cxd_cfg.bitrate = ci_bitrate;
-		port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap);
-		if (!port->en)
-			return -ENODEV;
-		dvb_ca_en50221_init(port->dvb[0].adap,
-				    port->en, 0, 1);
-		break;
-
-	case DDB_CI_EXTERNAL_XO2:
-	case DDB_CI_EXTERNAL_XO2_B:
-		ci_xo2_attach(port);
-		if (!port->en)
-			return -ENODEV;
-		dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1);
-		break;
-
-	case DDB_CI_INTERNAL:
-		ci_attach(port);
-		if (!port->en)
-			return -ENODEV;
-		dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1);
-		break;
-	}
-	return 0;
-}
-
 static int ddb_port_attach(struct ddb_port *port)
 {
 	int ret = 0;
@@ -2254,20 +1935,22 @@ static int ddb_port_attach(struct ddb_port *port)
 		if (ret < 0)
 			break;
 		ret = dvb_input_attach(port->input[1]);
-		if (ret < 0)
+		if (ret < 0) {
+			dvb_input_detach(port->input[0]);
 			break;
+		}
 		port->input[0]->redi = port->input[0];
 		port->input[1]->redi = port->input[1];
 		break;
 	case DDB_PORT_CI:
-		ret = ddb_ci_attach(port);
+		ret = ddb_ci_attach(port, ci_bitrate);
 		if (ret < 0)
 			break;
 		/* fall-through */
 	case DDB_PORT_LOOP:
 		ret = dvb_register_device(port->dvb[0].adap,
 					  &port->dvb[0].dev,
-					  &dvbdev_ci, (void *) port->output,
+					  &dvbdev_ci, (void *)port->output,
 					  DVB_DEVICE_SEC, 0);
 		break;
 	default:
@@ -2281,7 +1964,7 @@ static int ddb_port_attach(struct ddb_port *port)
 
 int ddb_ports_attach(struct ddb *dev)
 {
-	int i, ret = 0;
+	int i, numports, err_ports = 0, ret = 0;
 	struct ddb_port *port;
 
 	if (dev->port_num) {
@@ -2291,11 +1974,31 @@ int ddb_ports_attach(struct ddb *dev)
 			return ret;
 		}
 	}
+
+	numports = dev->port_num;
+
 	for (i = 0; i < dev->port_num; i++) {
 		port = &dev->port[i];
-		ret = ddb_port_attach(port);
+		if (port->class != DDB_PORT_NONE) {
+			ret = ddb_port_attach(port);
+			if (ret)
+				err_ports++;
+		} else {
+			numports--;
+		}
 	}
-	return ret;
+
+	if (err_ports) {
+		if (err_ports == numports) {
+			dev_err(dev->dev, "All connected ports failed to initialise!\n");
+			return -ENODEV;
+		}
+
+		dev_warn(dev->dev, "%d of %d connected ports failed to initialise!\n",
+			 err_ports, numports);
+	}
+
+	return 0;
 }
 
 void ddb_ports_detach(struct ddb *dev)
@@ -2308,25 +2011,18 @@ void ddb_ports_detach(struct ddb *dev)
 
 		switch (port->class) {
 		case DDB_PORT_TUNER:
-			dvb_input_detach(port->input[0]);
 			dvb_input_detach(port->input[1]);
+			dvb_input_detach(port->input[0]);
 			break;
 		case DDB_PORT_CI:
 		case DDB_PORT_LOOP:
-			if (port->dvb[0].dev)
-				dvb_unregister_device(port->dvb[0].dev);
-			if (port->en) {
-				dvb_ca_en50221_release(port->en);
-				kfree(port->en);
-				port->en = NULL;
-			}
+			ddb_ci_detach(port);
 			break;
 		}
 	}
 	dvb_unregister_adapters(dev);
 }
 
-
 /* Copy input DMA pointers to output DMA and ACK. */
 
 static void input_write_output(struct ddb_input *input,
@@ -2353,16 +2049,18 @@ static void input_write_dvb(struct ddb_input *input,
 	struct ddb *dev = input->port->dev;
 	int ack = 1;
 
-	dma = dma2 = input->dma;
-	/* if there also is an output connected, do not ACK.
+	dma = input->dma;
+	dma2 = input->dma;
+	/*
+	 * if there also is an output connected, do not ACK.
 	 * input_write_output will ACK.
 	 */
 	if (input->redo) {
 		dma2 = input->redo->dma;
 		ack = 0;
 	}
-	while (dma->cbuf != ((dma->stat >> 11) & 0x1f)
-	       || (4 & dma->ctrl)) {
+	while (dma->cbuf != ((dma->stat >> 11) & 0x1f) ||
+	       (4 & dma->ctrl)) {
 		if (4 & dma->ctrl) {
 			/* dev_err(dev->dev, "Overflow dma %d\n", dma->nr); */
 			ack = 1;
@@ -2385,7 +2083,7 @@ static void input_write_dvb(struct ddb_input *input,
 static void input_work(struct work_struct *work)
 {
 	struct ddb_dma *dma = container_of(work, struct ddb_dma, work);
-	struct ddb_input *input = (struct ddb_input *) dma->io;
+	struct ddb_input *input = (struct ddb_input *)dma->io;
 	struct ddb *dev = input->port->dev;
 	unsigned long flags;
 
@@ -2407,11 +2105,11 @@ static void input_work(struct work_struct *work)
 
 static void input_handler(unsigned long data)
 {
-	struct ddb_input *input = (struct ddb_input *) data;
+	struct ddb_input *input = (struct ddb_input *)data;
 	struct ddb_dma *dma = input->dma;
 
-
-	/* If there is no input connected, input_tasklet() will
+	/*
+	 * If there is no input connected, input_tasklet() will
 	 * just copy pointers and ACK. So, there is no need to go
 	 * through the tasklet scheduler.
 	 */
@@ -2423,7 +2121,7 @@ static void input_handler(unsigned long data)
 
 static void output_handler(unsigned long data)
 {
-	struct ddb_output *output = (struct ddb_output *) data;
+	struct ddb_output *output = (struct ddb_output *)data;
 	struct ddb_dma *dma = output->dma;
 	struct ddb *dev = output->port->dev;
 
@@ -2512,10 +2210,10 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr)
 			dma_nr += 32 + (port->lnr - 1) * 8;
 
 		dev_dbg(dev->dev, "init link %u, input %u, handler %u\n",
-			 port->lnr, nr, dma_nr + base);
+			port->lnr, nr, dma_nr + base);
 
 		dev->handler[0][dma_nr + base] = input_handler;
-		dev->handler_data[0][dma_nr + base] = (unsigned long) input;
+		dev->handler_data[0][dma_nr + base] = (unsigned long)input;
 		ddb_dma_init(input, dma_nr, 0);
 	}
 }
@@ -2534,14 +2232,14 @@ static void ddb_output_init(struct ddb_port *port, int nr)
 		(rm->output->base + rm->output->size * nr);
 
 	dev_dbg(dev->dev, "init link %u, output %u, regs %08x\n",
-		 port->lnr, nr, output->regs);
+		port->lnr, nr, output->regs);
 
 	if (dev->has_dma) {
 		const struct ddb_regmap *rm0 = io_regmap(output, 0);
 		u32 base = rm0->irq_base_odma;
 
 		dev->handler[0][nr + base] = output_handler;
-		dev->handler_data[0][nr + base] = (unsigned long) output;
+		dev->handler_data[0][nr + base] = (unsigned long)output;
 		ddb_dma_init(output, nr, 1);
 	}
 }
@@ -2609,7 +2307,7 @@ void ddb_ports_init(struct ddb *dev)
 			port->dvb[0].adap = &dev->adap[2 * p];
 			port->dvb[1].adap = &dev->adap[2 * p + 1];
 
-			if ((port->class == DDB_PORT_NONE) && i && p &&
+			if (port->class == DDB_PORT_NONE && i && p &&
 			    dev->port[p - 1].type == DDB_CI_EXTERNAL_XO2) {
 				port->class = DDB_PORT_CI;
 				port->type = DDB_CI_EXTERNAL_XO2_B;
@@ -2618,8 +2316,8 @@ void ddb_ports_init(struct ddb *dev)
 			}
 
 			dev_info(dev->dev, "Port %u: Link %u, Link Port %u (TAB %u): %s\n",
-				port->pnr, port->lnr, port->nr, port->nr + 1,
-				port->name);
+				 port->pnr, port->lnr, port->nr, port->nr + 1,
+				 port->name);
 
 			if (port->class == DDB_PORT_CI &&
 			    port->type == DDB_CI_EXTERNAL_XO2) {
@@ -2741,7 +2439,7 @@ static void irq_handle_io(struct ddb *dev, u32 s)
 
 irqreturn_t ddb_irq_handler0(int irq, void *dev_id)
 {
-	struct ddb *dev = (struct ddb *) dev_id;
+	struct ddb *dev = (struct ddb *)dev_id;
 	u32 s = ddbreadl(dev, INTERRUPT_STATUS);
 
 	do {
@@ -2758,7 +2456,7 @@ irqreturn_t ddb_irq_handler0(int irq, void *dev_id)
 
 irqreturn_t ddb_irq_handler1(int irq, void *dev_id)
 {
-	struct ddb *dev = (struct ddb *) dev_id;
+	struct ddb *dev = (struct ddb *)dev_id;
 	u32 s = ddbreadl(dev, INTERRUPT_STATUS);
 
 	do {
@@ -2775,7 +2473,7 @@ irqreturn_t ddb_irq_handler1(int irq, void *dev_id)
 
 irqreturn_t ddb_irq_handler(int irq, void *dev_id)
 {
-	struct ddb *dev = (struct ddb *) dev_id;
+	struct ddb *dev = (struct ddb *)dev_id;
 	u32 s = ddbreadl(dev, INTERRUPT_STATUS);
 	int ret = IRQ_HANDLED;
 
@@ -2812,7 +2510,7 @@ static int reg_wait(struct ddb *dev, u32 reg, u32 bit)
 }
 
 static int flashio(struct ddb *dev, u32 lnr, u8 *wbuf, u32 wlen, u8 *rbuf,
-	u32 rlen)
+		   u32 rlen)
 {
 	u32 data, shift;
 	u32 tag = DDB_LINK_TAG(lnr);
@@ -2823,7 +2521,7 @@ static int flashio(struct ddb *dev, u32 lnr, u8 *wbuf, u32 wlen, u8 *rbuf,
 		ddbwritel(dev, 1, tag | SPI_CONTROL);
 	while (wlen > 4) {
 		/* FIXME: check for big-endian */
-		data = swab32(*(u32 *) wbuf);
+		data = swab32(*(u32 *)wbuf);
 		wbuf += 4;
 		wlen -= 4;
 		ddbwritel(dev, data, tag | SPI_DATA);
@@ -2863,12 +2561,12 @@ static int flashio(struct ddb *dev, u32 lnr, u8 *wbuf, u32 wlen, u8 *rbuf,
 		if (reg_wait(dev, tag | SPI_CONTROL, 4))
 			goto fail;
 		data = ddbreadl(dev, tag | SPI_DATA);
-		*(u32 *) rbuf = swab32(data);
+		*(u32 *)rbuf = swab32(data);
 		rbuf += 4;
 		rlen -= 4;
 	}
 	ddbwritel(dev, 0x0003 | ((rlen << (8 + 3)) & 0x1F00),
-		tag | SPI_CONTROL);
+		  tag | SPI_CONTROL);
 	ddbwritel(dev, 0xffffffff, tag | SPI_DATA);
 	if (reg_wait(dev, tag | SPI_CONTROL, 4))
 		goto fail;
@@ -3011,7 +2709,7 @@ static ssize_t fan_store(struct device *device, struct device_attribute *d,
 }
 
 static ssize_t fanspeed_show(struct device *device,
-			struct device_attribute *attr, char *buf)
+			     struct device_attribute *attr, char *buf)
 {
 	struct ddb *dev = dev_get_drvdata(device);
 	int num = attr->attr.name[8] - 0x30;
@@ -3049,7 +2747,7 @@ static ssize_t temp_show(struct device *device,
 }
 
 static ssize_t ctemp_show(struct device *device,
-		struct device_attribute *attr, char *buf)
+			  struct device_attribute *attr, char *buf)
 {
 	struct ddb *dev = dev_get_drvdata(device);
 	struct i2c_adapter *adap;
@@ -3076,7 +2774,6 @@ static ssize_t led_show(struct device *device,
 	return sprintf(buf, "%d\n", dev->leds & (1 << num) ? 1 : 0);
 }
 
-
 static void ddb_set_led(struct ddb *dev, int num, int val)
 {
 	if (!dev->link[0].info->led_num)
@@ -3163,7 +2860,7 @@ static ssize_t bsnr_show(struct device *device,
 }
 
 static ssize_t bpsnr_show(struct device *device,
-			 struct device_attribute *attr, char *buf)
+			  struct device_attribute *attr, char *buf)
 {
 	struct ddb *dev = dev_get_drvdata(device);
 	unsigned char snr[32];
@@ -3208,7 +2905,6 @@ static ssize_t gap_show(struct device *device,
 	int num = attr->attr.name[3] - 0x30;
 
 	return sprintf(buf, "%d\n", dev->port[num].gap);
-
 }
 
 static ssize_t gap_store(struct device *device, struct device_attribute *attr,
@@ -3254,7 +2950,7 @@ static ssize_t regmap_show(struct device *device,
 }
 
 static ssize_t fmode_show(struct device *device,
-			 struct device_attribute *attr, char *buf)
+			  struct device_attribute *attr, char *buf)
 {
 	int num = attr->attr.name[5] - 0x30;
 	struct ddb *dev = dev_get_drvdata(device);
@@ -3272,7 +2968,7 @@ static ssize_t devid_show(struct device *device,
 }
 
 static ssize_t fmode_store(struct device *device, struct device_attribute *attr,
-			  const char *buf, size_t count)
+			   const char *buf, size_t count)
 {
 	struct ddb *dev = dev_get_drvdata(device);
 	int num = attr->attr.name[5] - 0x30;
@@ -3282,7 +2978,7 @@ static ssize_t fmode_store(struct device *device, struct device_attribute *attr,
 		return -EINVAL;
 	if (val > 3)
 		return -EINVAL;
-	lnb_init_fmode(dev, &dev->link[num], val);
+	ddb_lnb_init_fmode(dev, &dev->link[num], val);
 	return count;
 }
 
@@ -3387,7 +3083,7 @@ static void ddb_device_attrs_del(struct ddb *dev)
 		device_remove_file(dev->ddb_dev, &ddb_attrs_snr[i]);
 		device_remove_file(dev->ddb_dev, &ddb_attrs_ctemp[i]);
 	}
-	for (i = 0; ddb_attrs[i].attr.name != NULL; i++)
+	for (i = 0; ddb_attrs[i].attr.name; i++)
 		device_remove_file(dev->ddb_dev, &ddb_attrs[i]);
 }
 
@@ -3395,7 +3091,7 @@ static int ddb_device_attrs_add(struct ddb *dev)
 {
 	int i;
 
-	for (i = 0; ddb_attrs[i].attr.name != NULL; i++)
+	for (i = 0; ddb_attrs[i].attr.name; i++)
 		if (device_create_file(dev->ddb_dev, &ddb_attrs[i]))
 			goto fail;
 	for (i = 0; i < dev->link[0].info->temp_num; i++)
@@ -3447,8 +3143,9 @@ int ddb_device_create(struct ddb *dev)
 		device_destroy(&ddb_class, MKDEV(ddb_major, dev->nr));
 		ddbs[dev->nr] = NULL;
 		dev->ddb_dev = ERR_PTR(-ENODEV);
-	} else
+	} else {
 		ddb_num++;
+	}
 fail:
 	mutex_unlock(&ddb_mutex);
 	return res;
@@ -3500,7 +3197,7 @@ static void tempmon_setfan(struct ddb_link *link)
 
 static void temp_handler(unsigned long data)
 {
-	struct ddb_link *link = (struct ddb_link *) data;
+	struct ddb_link *link = (struct ddb_link *)data;
 
 	spin_lock(&link->temp_lock);
 	tempmon_setfan(link);
@@ -3519,10 +3216,10 @@ static int tempmon_init(struct ddb_link *link, int first_time)
 			30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80 };
 
 		memcpy(link->temp_tab, temperature_table,
-			sizeof(temperature_table));
+		       sizeof(temperature_table));
 	}
 	dev->handler[l][link->info->tempmon_irq] = temp_handler;
-	dev->handler_data[l][link->info->tempmon_irq] = (unsigned long) link;
+	dev->handler_data[l][link->info->tempmon_irq] = (unsigned long)link;
 	ddblwritel(link, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN |
 			  TEMPMON_CONTROL_INTENABLE),
 		   TEMPMON_CONTROL);
@@ -3574,11 +3271,11 @@ static int ddb_init_boards(struct ddb *dev)
 			ddbwritel(dev, 0, DDB_LINK_TAG(l) | BOARD_CONTROL);
 			msleep(100);
 			ddbwritel(dev, info->board_control_2,
-				DDB_LINK_TAG(l) | BOARD_CONTROL);
+				  DDB_LINK_TAG(l) | BOARD_CONTROL);
 			usleep_range(2000, 3000);
 			ddbwritel(dev,
-				info->board_control_2 | info->board_control,
-				DDB_LINK_TAG(l) | BOARD_CONTROL);
+				  info->board_control_2 | info->board_control,
+				  DDB_LINK_TAG(l) | BOARD_CONTROL);
 			usleep_range(2000, 3000);
 		}
 		ddb_init_tempmon(link);
@@ -3598,7 +3295,7 @@ int ddb_init(struct ddb *dev)
 	ddb_init_boards(dev);
 
 	if (ddb_i2c_init(dev) < 0)
-		goto fail;
+		goto fail1;
 	ddb_ports_init(dev);
 	if (ddb_buffers_alloc(dev) < 0) {
 		dev_info(dev->dev, "Could not allocate buffer memory\n");
@@ -3616,14 +3313,14 @@ int ddb_init(struct ddb *dev)
 	return 0;
 
 fail3:
-	ddb_ports_detach(dev);
 	dev_err(dev->dev, "fail3\n");
-	ddb_ports_release(dev);
+	ddb_ports_detach(dev);
+	ddb_buffers_free(dev);
 fail2:
 	dev_err(dev->dev, "fail2\n");
-	ddb_buffers_free(dev);
+	ddb_ports_release(dev);
 	ddb_i2c_release(dev);
-fail:
+fail1:
 	dev_err(dev->dev, "fail1\n");
 	return -1;
 }
diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.c b/drivers/media/pci/ddbridge/ddbridge-hw.c
index 48248bc..c6d1492 100644
--- a/drivers/media/pci/ddbridge/ddbridge-hw.c
+++ b/drivers/media/pci/ddbridge/ddbridge-hw.c
@@ -185,7 +185,7 @@ static const struct ddb_info ddb_ctv7 = {
 	.board_control_2 = 4,
 };
 
-static const struct ddb_info ddb_satixS2v3 = {
+static const struct ddb_info ddb_satixs2v3 = {
 	.type     = DDB_OCTOPUS,
 	.name     = "Mystique SaTiX-S2 V3 DVB adapter",
 	.regmap   = &octopus_map,
@@ -336,7 +336,7 @@ static const struct ddb_device_id ddb_device_ids[] = {
 	DDB_DEVID(0x0006, 0x0022, ddb_v7),
 	DDB_DEVID(0x0006, 0x0024, ddb_v7a),
 	DDB_DEVID(0x0003, 0x0030, ddb_dvbct),
-	DDB_DEVID(0x0003, 0xdb03, ddb_satixS2v3),
+	DDB_DEVID(0x0003, 0xdb03, ddb_satixs2v3),
 	DDB_DEVID(0x0006, 0x0031, ddb_ctv7),
 	DDB_DEVID(0x0006, 0x0032, ddb_ctv7),
 	DDB_DEVID(0x0006, 0x0033, ddb_ctv7),
@@ -367,8 +367,8 @@ const struct ddb_info *get_ddb_info(u16 vendor, u16 device,
 		if (vendor == id->vendor &&
 		    device == id->device &&
 		    subvendor == id->subvendor &&
-		    ((subdevice == id->subdevice) ||
-		     (id->subdevice == 0xffff)))
+		    (subdevice == id->subdevice ||
+		     id->subdevice == 0xffff))
 			return id->info;
 	}
 
diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.c b/drivers/media/pci/ddbridge/ddbridge-i2c.c
index e4d39c3..82a9a0e 100644
--- a/drivers/media/pci/ddbridge/ddbridge-i2c.c
+++ b/drivers/media/pci/ddbridge/ddbridge-i2c.c
@@ -81,7 +81,7 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
 static int ddb_i2c_master_xfer(struct i2c_adapter *adapter,
 			       struct i2c_msg msg[], int num)
 {
-	struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter);
+	struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter);
 	struct ddb *dev = i2c->dev;
 	u8 addr = 0;
 
@@ -149,7 +149,7 @@ void ddb_i2c_release(struct ddb *dev)
 
 static void i2c_handler(unsigned long priv)
 {
-	struct ddb_i2c *i2c = (struct ddb_i2c *) priv;
+	struct ddb_i2c *i2c = (struct ddb_i2c *)priv;
 
 	complete(&i2c->completion);
 }
@@ -171,20 +171,20 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
 		(regmap->i2c->base + regmap->i2c->size * i);
 	ddbwritel(dev, I2C_SPEED_100, i2c->regs + I2C_TIMING);
 	ddbwritel(dev, ((i2c->rbuf & 0xffff) << 16) | (i2c->wbuf & 0xffff),
-		i2c->regs + I2C_TASKADDRESS);
+		  i2c->regs + I2C_TASKADDRESS);
 	init_completion(&i2c->completion);
 
 	adap = &i2c->adap;
 	i2c_set_adapdata(adap, i2c);
 #ifdef I2C_ADAP_CLASS_TV_DIGITAL
-	adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG;
+	adap->class = I2C_ADAP_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG;
 #else
 #ifdef I2C_CLASS_TV_ANALOG
 	adap->class = I2C_CLASS_TV_ANALOG;
 #endif
 #endif
 	snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x",
-		dev->nr, i2c->link, i);
+		 dev->nr, i2c->link, i);
 	adap->algo = &ddb_i2c_algo;
 	adap->algo_data = (void *)i2c;
 	adap->dev.parent = dev->dev;
@@ -210,7 +210,7 @@ int ddb_i2c_init(struct ddb *dev)
 			if (!(dev->link[l].info->i2c_mask & (1 << i)))
 				continue;
 			i2c = &dev->i2c[num];
-			dev->handler_data[l][i + base] = (unsigned long) i2c;
+			dev->handler_data[l][i + base] = (unsigned long)i2c;
 			dev->handler[l][i + base] = i2c_handler;
 			stat = ddb_i2c_add(dev, i2c, regmap, l, i, num);
 			if (stat)
@@ -224,7 +224,9 @@ int ddb_i2c_init(struct ddb *dev)
 			adap = &i2c->adap;
 			i2c_del_adapter(adap);
 		}
-	} else
+	} else {
 		dev->i2c_num = num;
+	}
+
 	return stat;
 }
diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c
index ccac7fe..26497d6 100644
--- a/drivers/media/pci/ddbridge/ddbridge-main.c
+++ b/drivers/media/pci/ddbridge/ddbridge-main.c
@@ -107,7 +107,7 @@ static void ddb_irq_exit(struct ddb *dev)
 
 static void ddb_remove(struct pci_dev *pdev)
 {
-	struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev);
+	struct ddb *dev = (struct ddb *)pci_get_drvdata(pdev);
 
 	ddb_device_destroy(dev);
 	ddb_ports_detach(dev);
@@ -132,9 +132,10 @@ static void ddb_irq_msi(struct ddb *dev, int nr)
 		if (stat >= 1) {
 			dev->msi = stat;
 			dev_info(dev->dev, "using %d MSI interrupt(s)\n",
-				dev->msi);
-		} else
+				 dev->msi);
+		} else {
 			dev_info(dev->dev, "MSI not available.\n");
+		}
 	}
 }
 #endif
@@ -160,11 +161,11 @@ static int ddb_irq_init(struct ddb *dev)
 		irq_flag = 0;
 	if (dev->msi == 2) {
 		stat = request_irq(dev->pdev->irq, ddb_irq_handler0,
-				   irq_flag, "ddbridge", (void *) dev);
+				   irq_flag, "ddbridge", (void *)dev);
 		if (stat < 0)
 			return stat;
 		stat = request_irq(dev->pdev->irq + 1, ddb_irq_handler1,
-				   irq_flag, "ddbridge", (void *) dev);
+				   irq_flag, "ddbridge", (void *)dev);
 		if (stat < 0) {
 			free_irq(dev->pdev->irq, dev);
 			return stat;
@@ -173,7 +174,7 @@ static int ddb_irq_init(struct ddb *dev)
 #endif
 	{
 		stat = request_irq(dev->pdev->irq, ddb_irq_handler,
-				   irq_flag, "ddbridge", (void *) dev);
+				   irq_flag, "ddbridge", (void *)dev);
 		if (stat < 0)
 			return stat;
 	}
@@ -188,7 +189,7 @@ static int ddb_irq_init(struct ddb *dev)
 }
 
 static int ddb_probe(struct pci_dev *pdev,
-			       const struct pci_device_id *id)
+		     const struct pci_device_id *id)
 {
 	struct ddb *dev;
 	int stat = 0;
@@ -202,8 +203,8 @@ static int ddb_probe(struct pci_dev *pdev,
 		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
 			return -ENODEV;
 
-	dev = vzalloc(sizeof(struct ddb));
-	if (dev == NULL)
+	dev = vzalloc(sizeof(*dev));
+	if (!dev)
 		return -ENOMEM;
 
 	mutex_init(&dev->mutex);
@@ -242,7 +243,7 @@ static int ddb_probe(struct pci_dev *pdev,
 	dev->link[0].ids.regmapid = ddbreadl(dev, 4);
 
 	dev_info(&pdev->dev, "HW %08x REGMAP %08x\n",
-		dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
+		 dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
 
 	ddbwritel(dev, 0, DMA_BASE_READ);
 	ddbwritel(dev, 0, DMA_BASE_WRITE);
@@ -317,7 +318,7 @@ static __init int module_init_ddbridge(void)
 	if (ddb_class_create() < 0)
 		return -1;
 	ddb_wq = create_workqueue("ddbridge");
-	if (ddb_wq == NULL)
+	if (!ddb_wq)
 		goto exit1;
 	stat = pci_register_driver(&ddb_pci_driver);
 	if (stat < 0)
diff --git a/drivers/media/pci/ddbridge/ddbridge-maxs8.c b/drivers/media/pci/ddbridge/ddbridge-max.c
similarity index 91%
rename from drivers/media/pci/ddbridge/ddbridge-maxs8.c
rename to drivers/media/pci/ddbridge/ddbridge-max.c
index f8a53bc..dc6b814 100644
--- a/drivers/media/pci/ddbridge/ddbridge-maxs8.c
+++ b/drivers/media/pci/ddbridge/ddbridge-max.c
@@ -1,5 +1,5 @@
 /*
- * ddbridge-maxs8.c: Digital Devices bridge MaxS4/8 support
+ * ddbridge-max.c: Digital Devices bridge MAX card support
  *
  * Copyright (C) 2010-2017 Digital Devices GmbH
  *                         Ralph Metzler <rjkm@metzlerbros.de>
@@ -34,7 +34,7 @@
 #include "ddbridge-regs.h"
 #include "ddbridge-io.h"
 
-#include "ddbridge-maxs8.h"
+#include "ddbridge-max.h"
 #include "mxl5xx.h"
 
 /******************************************************************************/
@@ -68,7 +68,7 @@ static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
 	}
 	if (c == 10)
 		dev_info(dev->dev, "%s lnb = %08x  cmd = %08x\n",
-			__func__, lnb, cmd);
+			 __func__, lnb, cmd);
 	return 0;
 }
 
@@ -123,7 +123,7 @@ static int lnb_set_sat(struct ddb *dev, u32 link, u32 input, u32 sat, u32 band,
 }
 
 static int lnb_set_tone(struct ddb *dev, u32 link, u32 input,
-	enum fe_sec_tone_mode tone)
+			enum fe_sec_tone_mode tone)
 {
 	int s = 0;
 	u32 mask = (1ULL << input);
@@ -149,7 +149,7 @@ static int lnb_set_tone(struct ddb *dev, u32 link, u32 input,
 }
 
 static int lnb_set_voltage(struct ddb *dev, u32 link, u32 input,
-	enum fe_sec_voltage voltage)
+			   enum fe_sec_voltage voltage)
 {
 	int s = 0;
 
@@ -291,34 +291,45 @@ static int max_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
 
 		if (nv != ov) {
 			if (nv) {
-				lnb_set_voltage(dev,
-					port->lnr, 0, SEC_VOLTAGE_13);
+				lnb_set_voltage(
+					dev, port->lnr,
+					0, SEC_VOLTAGE_13);
 				if (fmode == 1) {
-					lnb_set_voltage(dev, port->lnr,
+					lnb_set_voltage(
+						dev, port->lnr,
 						0, SEC_VOLTAGE_13);
 					if (old_quattro) {
-						lnb_set_voltage(dev, port->lnr,
+						lnb_set_voltage(
+							dev, port->lnr,
 							1, SEC_VOLTAGE_18);
-						lnb_set_voltage(dev, port->lnr,
+						lnb_set_voltage(
+							dev, port->lnr,
 							2, SEC_VOLTAGE_13);
 					} else {
-						lnb_set_voltage(dev, port->lnr,
+						lnb_set_voltage(
+							dev, port->lnr,
 							1, SEC_VOLTAGE_13);
-						lnb_set_voltage(dev, port->lnr,
+						lnb_set_voltage(
+							dev, port->lnr,
 							2, SEC_VOLTAGE_18);
 					}
-					lnb_set_voltage(dev, port->lnr,
+					lnb_set_voltage(
+						dev, port->lnr,
 						3, SEC_VOLTAGE_18);
 				}
 			} else {
-				lnb_set_voltage(dev, port->lnr,
+				lnb_set_voltage(
+					dev, port->lnr,
 					0, SEC_VOLTAGE_OFF);
 				if (fmode == 1) {
-					lnb_set_voltage(dev, port->lnr,
+					lnb_set_voltage(
+						dev, port->lnr,
 						1, SEC_VOLTAGE_OFF);
-					lnb_set_voltage(dev, port->lnr,
+					lnb_set_voltage(
+						dev, port->lnr,
 						2, SEC_VOLTAGE_OFF);
-					lnb_set_voltage(dev, port->lnr,
+					lnb_set_voltage(
+						dev, port->lnr,
 						3, SEC_VOLTAGE_OFF);
 				}
 			}
@@ -331,7 +342,6 @@ static int max_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
 
 static int max_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
 {
-
 	return 0;
 }
 
@@ -350,7 +360,7 @@ static int mxl_fw_read(void *priv, u8 *buf, u32 len)
 	return ddbridge_flashread(dev, link->nr, buf, 0xc0000, len);
 }
 
-int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm)
+int ddb_lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm)
 {
 	u32 l = link->nr;
 
@@ -394,7 +404,7 @@ static struct mxl5xx_cfg mxl5xx = {
 	.fw_read  = mxl_fw_read,
 };
 
-int fe_attach_mxl5xx(struct ddb_input *input)
+int ddb_fe_attach_mxl5xx(struct ddb_input *input)
 {
 	struct ddb *dev = input->port->dev;
 	struct i2c_adapter *i2c = &input->port->i2c->adap;
@@ -414,7 +424,7 @@ int fe_attach_mxl5xx(struct ddb_input *input)
 		tuner = 0;
 
 	dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg,
-		demod, tuner, &dvb->set_input);
+			     demod, tuner, &dvb->set_input);
 
 	if (!dvb->fe) {
 		dev_err(dev->dev, "No MXL5XX found!\n");
@@ -430,7 +440,7 @@ int fe_attach_mxl5xx(struct ddb_input *input)
 		lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT);
 		lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF);
 	}
-	lnb_init_fmode(dev, link, fmode);
+	ddb_lnb_init_fmode(dev, link, fmode);
 
 	dvb->fe->ops.set_voltage = max_set_voltage;
 	dvb->fe->ops.enable_high_lnb_voltage = max_enable_high_lnb_voltage;
diff --git a/drivers/media/pci/ddbridge/ddbridge-maxs8.h b/drivers/media/pci/ddbridge/ddbridge-max.h
similarity index 73%
rename from drivers/media/pci/ddbridge/ddbridge-maxs8.h
rename to drivers/media/pci/ddbridge/ddbridge-max.h
index bb88848..bf8bf38 100644
--- a/drivers/media/pci/ddbridge/ddbridge-maxs8.h
+++ b/drivers/media/pci/ddbridge/ddbridge-max.h
@@ -1,5 +1,5 @@
 /*
- * ddbridge-maxs8.h: Digital Devices bridge MaxS4/8 support
+ * ddbridge-max.h: Digital Devices bridge MAX card support
  *
  * Copyright (C) 2010-2017 Digital Devices GmbH
  *                         Ralph Metzler <rjkm@metzlerbros.de>
@@ -16,14 +16,14 @@
  *
  */
 
-#ifndef _DDBRIDGE_MAXS8_H_
-#define _DDBRIDGE_MAXS8_H_
+#ifndef _DDBRIDGE_MAX_H_
+#define _DDBRIDGE_MAX_H_
 
 #include "ddbridge.h"
 
 /******************************************************************************/
 
-int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm);
-int fe_attach_mxl5xx(struct ddb_input *input);
+int ddb_lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm);
+int ddb_fe_attach_mxl5xx(struct ddb_input *input);
 
-#endif /* _DDBRIDGE_MAXS8_H */
+#endif /* _DDBRIDGE_MAX_H */
diff --git a/drivers/media/pci/ddbridge/ddbridge-regs.h b/drivers/media/pci/ddbridge/ddbridge-regs.h
index 9d44f8d..23d74ff 100644
--- a/drivers/media/pci/ddbridge/ddbridge-regs.h
+++ b/drivers/media/pci/ddbridge/ddbridge-regs.h
@@ -95,27 +95,27 @@
 #define DMA_BASE_WRITE        (0x100)
 #define DMA_BASE_READ         (0x140)
 
-#define TS_CONTROL(_io)         (_io->regs + 0x00)
-#define TS_CONTROL2(_io)        (_io->regs + 0x04)
+#define TS_CONTROL(_io)         ((_io)->regs + 0x00)
+#define TS_CONTROL2(_io)        ((_io)->regs + 0x04)
 
 /* ------------------------------------------------------------------------- */
 /* DMA  Buffer */
 
-#define DMA_BUFFER_CONTROL(_dma)       (_dma->regs + 0x00)
-#define DMA_BUFFER_ACK(_dma)           (_dma->regs + 0x04)
-#define DMA_BUFFER_CURRENT(_dma)       (_dma->regs + 0x08)
-#define DMA_BUFFER_SIZE(_dma)          (_dma->regs + 0x0c)
+#define DMA_BUFFER_CONTROL(_dma)       ((_dma)->regs + 0x00)
+#define DMA_BUFFER_ACK(_dma)           ((_dma)->regs + 0x04)
+#define DMA_BUFFER_CURRENT(_dma)       ((_dma)->regs + 0x08)
+#define DMA_BUFFER_SIZE(_dma)          ((_dma)->regs + 0x0c)
 
 /* ------------------------------------------------------------------------- */
 /* CI Interface (only CI-Bridge) */
 
-#define CI_BASE                     (0x400)
-#define CI_CONTROL(i)               (CI_BASE + (i) * 32 + 0x00)
+#define CI_BASE                         (0x400)
+#define CI_CONTROL(i)                   (CI_BASE + (i) * 32 + 0x00)
 
-#define CI_DO_ATTRIBUTE_RW(i)       (CI_BASE + (i) * 32 + 0x04)
-#define CI_DO_IO_RW(i)              (CI_BASE + (i) * 32 + 0x08)
-#define CI_READDATA(i)              (CI_BASE + (i) * 32 + 0x0c)
-#define CI_DO_READ_ATTRIBUTES(i)    (CI_BASE + (i) * 32 + 0x10)
+#define CI_DO_ATTRIBUTE_RW(i)           (CI_BASE + (i) * 32 + 0x04)
+#define CI_DO_IO_RW(i)                  (CI_BASE + (i) * 32 + 0x08)
+#define CI_READDATA(i)                  (CI_BASE + (i) * 32 + 0x0c)
+#define CI_DO_READ_ATTRIBUTES(i)        (CI_BASE + (i) * 32 + 0x10)
 
 #define CI_RESET_CAM                    (0x00000001)
 #define CI_POWER_ON                     (0x00000002)
@@ -132,7 +132,7 @@
 #define CI_BUFFER_BASE                  (0x3000)
 #define CI_BUFFER_SIZE                  (0x0800)
 
-#define CI_BUFFER(i)                  (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE)
+#define CI_BUFFER(i)                    (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE)
 
 /* ------------------------------------------------------------------------- */
 /* LNB commands (mxl5xx / Max S8) */
@@ -140,7 +140,7 @@
 #define LNB_BASE			(0x400)
 #define LNB_CONTROL(i)			(LNB_BASE + (i) * 0x20 + 0x00)
 
-#define LNB_CMD				(7ULL <<  0)
+#define LNB_CMD				(7ULL << 0)
 #define LNB_CMD_NOP			0
 #define LNB_CMD_INIT			1
 #define LNB_CMD_LOW			3
@@ -148,8 +148,8 @@
 #define LNB_CMD_OFF			5
 #define LNB_CMD_DISEQC			6
 
-#define LNB_BUSY			(1ULL <<  4)
-#define LNB_TONE			(1ULL << 15)
+#define LNB_BUSY			BIT_ULL(4)
+#define LNB_TONE			BIT_ULL(15)
 
 #define LNB_BUF_LEVEL(i)		(LNB_BASE + (i) * 0x20 + 0x10)
 #define LNB_BUF_WRITE(i)		(LNB_BASE + (i) * 0x20 + 0x14)
diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h
index e9afa96..0954577 100644
--- a/drivers/media/pci/ddbridge/ddbridge.h
+++ b/drivers/media/pci/ddbridge/ddbridge.h
@@ -55,15 +55,15 @@
 #include <linux/device.h>
 #include <linux/io.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_ringbuffer.h"
-#include "dvb_ca_en50221.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_ringbuffer.h>
+#include <media/dvb_ca_en50221.h>
+#include <media/dvb_net.h>
 
-#define DDBRIDGE_VERSION "0.9.31intermediate-integrated"
+#define DDBRIDGE_VERSION "0.9.32-integrated"
 
 #define DDB_MAX_I2C    32
 #define DDB_MAX_PORT   32
@@ -143,11 +143,11 @@ struct ddb_info {
 #define DMA_MAX_BUFS 32      /* hardware table limit */
 
 #define INPUT_DMA_BUFS 8
-#define INPUT_DMA_SIZE (128*47*21)
+#define INPUT_DMA_SIZE (128 * 47 * 21)
 #define INPUT_DMA_IRQ_DIV 1
 
 #define OUTPUT_DMA_BUFS 8
-#define OUTPUT_DMA_SIZE (128*47*21)
+#define OUTPUT_DMA_SIZE (128 * 47 * 21)
 #define OUTPUT_DMA_IRQ_DIV 1
 
 struct ddb;
@@ -166,7 +166,7 @@ struct ddb_dma {
 	u32                    bufval;
 
 	struct work_struct     work;
-	spinlock_t             lock;
+	spinlock_t             lock; /* DMA lock */
 	wait_queue_head_t      wq;
 	int                    running;
 	u32                    stat;
@@ -196,17 +196,16 @@ struct ddb_dvb {
 
 	int (*i2c_gate_ctrl)(struct dvb_frontend *, int);
 	int (*set_voltage)(struct dvb_frontend *fe,
-		enum fe_sec_voltage voltage);
+			   enum fe_sec_voltage voltage);
 	int (*set_input)(struct dvb_frontend *fe, int input);
 	int (*diseqc_send_master_cmd)(struct dvb_frontend *fe,
-		struct dvb_diseqc_master_cmd *cmd);
+				      struct dvb_diseqc_master_cmd *cmd);
 };
 
 struct ddb_ci {
 	struct dvb_ca_en50221  en;
 	struct ddb_port       *port;
 	u32                    nr;
-	struct mutex           lock;
 };
 
 struct ddb_io {
@@ -240,7 +239,7 @@ struct ddb_port {
 	u32                    regs;
 	u32                    lnr;
 	struct ddb_i2c        *i2c;
-	struct mutex           i2c_gate_lock;
+	struct mutex           i2c_gate_lock; /* I2C access lock */
 	u32                    class;
 #define DDB_PORT_NONE           0
 #define DDB_PORT_CI             1
@@ -297,7 +296,7 @@ struct ddb_port {
 #define TS_CAPTURE_LEN  (4096)
 
 struct ddb_lnb {
-	struct mutex           lock;
+	struct mutex           lock; /* lock lnb access */
 	u32                    tone;
 	enum fe_sec_voltage    oldvoltage[4];
 	u32                    voltage[4];
@@ -310,54 +309,54 @@ struct ddb_link {
 	const struct ddb_info *info;
 	u32                    nr;
 	u32                    regs;
-	spinlock_t             lock;
-	struct mutex           flash_mutex;
+	spinlock_t             lock; /* lock link access */
+	struct mutex           flash_mutex; /* lock flash access */
 	struct ddb_lnb         lnb;
 	struct tasklet_struct  tasklet;
 	struct ddb_ids         ids;
 
-	spinlock_t             temp_lock;
+	spinlock_t             temp_lock; /* lock temp chip access */
 	int                    overtemperature_error;
 	u8                     temp_tab[11];
 };
 
 struct ddb {
-	struct pci_dev        *pdev;
-	struct platform_device *pfdev;
-	struct device         *dev;
+	struct pci_dev          *pdev;
+	struct platform_device  *pfdev;
+	struct device           *dev;
 
-	int                    msi;
+	int                      msi;
 	struct workqueue_struct *wq;
-	u32                    has_dma;
+	u32                      has_dma;
 
-	struct ddb_link        link[DDB_MAX_LINK];
-	unsigned char __iomem *regs;
-	u32                    regs_len;
-	u32                    port_num;
-	struct ddb_port        port[DDB_MAX_PORT];
-	u32                    i2c_num;
-	struct ddb_i2c         i2c[DDB_MAX_I2C];
-	struct ddb_input       input[DDB_MAX_INPUT];
-	struct ddb_output      output[DDB_MAX_OUTPUT];
-	struct dvb_adapter     adap[DDB_MAX_INPUT];
-	struct ddb_dma         idma[DDB_MAX_INPUT];
-	struct ddb_dma         odma[DDB_MAX_OUTPUT];
+	struct ddb_link          link[DDB_MAX_LINK];
+	unsigned char __iomem   *regs;
+	u32                      regs_len;
+	u32                      port_num;
+	struct ddb_port          port[DDB_MAX_PORT];
+	u32                      i2c_num;
+	struct ddb_i2c           i2c[DDB_MAX_I2C];
+	struct ddb_input         input[DDB_MAX_INPUT];
+	struct ddb_output        output[DDB_MAX_OUTPUT];
+	struct dvb_adapter       adap[DDB_MAX_INPUT];
+	struct ddb_dma           idma[DDB_MAX_INPUT];
+	struct ddb_dma           odma[DDB_MAX_OUTPUT];
 
-	void                   (*handler[4][256])(unsigned long);
-	unsigned long          handler_data[4][256];
+	void                     (*handler[4][256])(unsigned long);
+	unsigned long            handler_data[4][256];
 
-	struct device         *ddb_dev;
-	u32                    ddb_dev_users;
-	u32                    nr;
-	u8                     iobuf[1028];
+	struct device           *ddb_dev;
+	u32                      ddb_dev_users;
+	u32                      nr;
+	u8                       iobuf[1028];
 
-	u8                     leds;
-	u32                    ts_irq;
-	u32                    i2c_irq;
+	u8                       leds;
+	u32                      ts_irq;
+	u32                      i2c_irq;
 
-	struct mutex           mutex;
+	struct mutex             mutex; /* lock access to global ddb array */
 
-	u8                     tsbuf[TS_CAPTURE_LEN];
+	u8                       tsbuf[TS_CAPTURE_LEN];
 };
 
 /****************************************************************************/
diff --git a/drivers/media/pci/dm1105/Makefile b/drivers/media/pci/dm1105/Makefile
index 3275851..d22c254 100644
--- a/drivers/media/pci/dm1105/Makefile
+++ b/drivers/media/pci/dm1105/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_DVB_DM1105) += dm1105.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index 7c3900d..c9db108 100644
--- a/drivers/media/pci/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
@@ -27,12 +27,12 @@
 #include <linux/slab.h>
 #include <media/rc-core.h>
 
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
 #include "dvb-pll.h"
 
 #include "stv0299.h"
diff --git a/drivers/media/pci/intel/Makefile b/drivers/media/pci/intel/Makefile
new file mode 100644
index 0000000..745c8b2
--- /dev/null
+++ b/drivers/media/pci/intel/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the IPU3 cio2 and ImGU drivers
+#
+
+obj-y	+= ipu3/
diff --git a/drivers/media/pci/intel/ipu3/Kconfig b/drivers/media/pci/intel/ipu3/Kconfig
new file mode 100644
index 0000000..a82d3fe
--- /dev/null
+++ b/drivers/media/pci/intel/ipu3/Kconfig
@@ -0,0 +1,19 @@
+config VIDEO_IPU3_CIO2
+	tristate "Intel ipu3-cio2 driver"
+	depends on VIDEO_V4L2 && PCI
+	depends on VIDEO_V4L2_SUBDEV_API
+	depends on X86 || COMPILE_TEST
+	depends on MEDIA_CONTROLLER
+	depends on HAS_DMA
+	depends on ACPI
+	select V4L2_FWNODE
+	select VIDEOBUF2_DMA_SG
+
+	---help---
+	This is the Intel IPU3 CIO2 CSI-2 receiver unit, found in Intel
+	Skylake and Kaby Lake SoCs and used for capturing images and
+	video from a camera sensor.
+
+	Say Y or M here if you have a Skylake/Kaby Lake SoC with MIPI CSI-2
+	connected camera.
+	The module will be called ipu3-cio2.
diff --git a/drivers/media/pci/intel/ipu3/Makefile b/drivers/media/pci/intel/ipu3/Makefile
new file mode 100644
index 0000000..20186e3
--- /dev/null
+++ b/drivers/media/pci/intel/ipu3/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_IPU3_CIO2) += ipu3-cio2.o
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
new file mode 100644
index 0000000..6c4444b
--- /dev/null
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
@@ -0,0 +1,2048 @@
+/*
+ * Copyright (c) 2017 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * Based partially on Intel IPU4 driver written by
+ *  Sakari Ailus <sakari.ailus@linux.intel.com>
+ *  Samu Onkalo <samu.onkalo@intel.com>
+ *  Jouni Högander <jouni.hogander@intel.com>
+ *  Jouni Ukkonen <jouni.ukkonen@intel.com>
+ *  Antti Laakso <antti.laakso@intel.com>
+ * et al.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-dma-sg.h>
+
+#include "ipu3-cio2.h"
+
+struct ipu3_cio2_fmt {
+	u32 mbus_code;
+	u32 fourcc;
+	u8 mipicode;
+};
+
+/*
+ * These are raw formats used in Intel's third generation of
+ * Image Processing Unit known as IPU3.
+ * 10bit raw bayer packed, 32 bytes for every 25 pixels,
+ * last LSB 6 bits unused.
+ */
+static const struct ipu3_cio2_fmt formats[] = {
+	{	/* put default entry at beginning */
+		.mbus_code	= MEDIA_BUS_FMT_SGRBG10_1X10,
+		.fourcc		= V4L2_PIX_FMT_IPU3_SGRBG10,
+		.mipicode	= 0x2b,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SGBRG10_1X10,
+		.fourcc		= V4L2_PIX_FMT_IPU3_SGBRG10,
+		.mipicode	= 0x2b,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SBGGR10_1X10,
+		.fourcc		= V4L2_PIX_FMT_IPU3_SBGGR10,
+		.mipicode	= 0x2b,
+	}, {
+		.mbus_code	= MEDIA_BUS_FMT_SRGGB10_1X10,
+		.fourcc		= V4L2_PIX_FMT_IPU3_SRGGB10,
+		.mipicode	= 0x2b,
+	},
+};
+
+/*
+ * cio2_find_format - lookup color format by fourcc or/and media bus code
+ * @pixelformat: fourcc to match, ignored if null
+ * @mbus_code: media bus code to match, ignored if null
+ */
+static const struct ipu3_cio2_fmt *cio2_find_format(const u32 *pixelformat,
+						    const u32 *mbus_code)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		if (pixelformat && *pixelformat != formats[i].fourcc)
+			continue;
+		if (mbus_code && *mbus_code != formats[i].mbus_code)
+			continue;
+
+		return &formats[i];
+	}
+
+	return NULL;
+}
+
+static inline u32 cio2_bytesperline(const unsigned int width)
+{
+	/*
+	 * 64 bytes for every 50 pixels, the line length
+	 * in bytes is multiple of 64 (line end alignment).
+	 */
+	return DIV_ROUND_UP(width, 50) * 64;
+}
+
+/**************** FBPT operations ****************/
+
+static void cio2_fbpt_exit_dummy(struct cio2_device *cio2)
+{
+	if (cio2->dummy_lop) {
+		dma_free_coherent(&cio2->pci_dev->dev, CIO2_PAGE_SIZE,
+				  cio2->dummy_lop, cio2->dummy_lop_bus_addr);
+		cio2->dummy_lop = NULL;
+	}
+	if (cio2->dummy_page) {
+		dma_free_coherent(&cio2->pci_dev->dev, CIO2_PAGE_SIZE,
+				  cio2->dummy_page, cio2->dummy_page_bus_addr);
+		cio2->dummy_page = NULL;
+	}
+}
+
+static int cio2_fbpt_init_dummy(struct cio2_device *cio2)
+{
+	unsigned int i;
+
+	cio2->dummy_page = dma_alloc_coherent(&cio2->pci_dev->dev,
+					      CIO2_PAGE_SIZE,
+					      &cio2->dummy_page_bus_addr,
+					      GFP_KERNEL);
+	cio2->dummy_lop = dma_alloc_coherent(&cio2->pci_dev->dev,
+					     CIO2_PAGE_SIZE,
+					     &cio2->dummy_lop_bus_addr,
+					     GFP_KERNEL);
+	if (!cio2->dummy_page || !cio2->dummy_lop) {
+		cio2_fbpt_exit_dummy(cio2);
+		return -ENOMEM;
+	}
+	/*
+	 * List of Pointers(LOP) contains 1024x32b pointers to 4KB page each
+	 * Initialize each entry to dummy_page bus base address.
+	 */
+	for (i = 0; i < CIO2_PAGE_SIZE / sizeof(*cio2->dummy_lop); i++)
+		cio2->dummy_lop[i] = cio2->dummy_page_bus_addr >> PAGE_SHIFT;
+
+	return 0;
+}
+
+static void cio2_fbpt_entry_enable(struct cio2_device *cio2,
+				   struct cio2_fbpt_entry entry[CIO2_MAX_LOPS])
+{
+	/*
+	 * The CPU first initializes some fields in fbpt, then sets
+	 * the VALID bit, this barrier is to ensure that the DMA(device)
+	 * does not see the VALID bit enabled before other fields are
+	 * initialized; otherwise it could lead to havoc.
+	 */
+	dma_wmb();
+
+	/*
+	 * Request interrupts for start and completion
+	 * Valid bit is applicable only to 1st entry
+	 */
+	entry[0].first_entry.ctrl = CIO2_FBPT_CTRL_VALID |
+		CIO2_FBPT_CTRL_IOC | CIO2_FBPT_CTRL_IOS;
+}
+
+/* Initialize fpbt entries to point to dummy frame */
+static void cio2_fbpt_entry_init_dummy(struct cio2_device *cio2,
+				       struct cio2_fbpt_entry
+				       entry[CIO2_MAX_LOPS])
+{
+	unsigned int i;
+
+	entry[0].first_entry.first_page_offset = 0;
+	entry[1].second_entry.num_of_pages =
+		CIO2_PAGE_SIZE / sizeof(u32) * CIO2_MAX_LOPS;
+	entry[1].second_entry.last_page_available_bytes = CIO2_PAGE_SIZE - 1;
+
+	for (i = 0; i < CIO2_MAX_LOPS; i++)
+		entry[i].lop_page_addr = cio2->dummy_lop_bus_addr >> PAGE_SHIFT;
+
+	cio2_fbpt_entry_enable(cio2, entry);
+}
+
+/* Initialize fpbt entries to point to a given buffer */
+static void cio2_fbpt_entry_init_buf(struct cio2_device *cio2,
+				     struct cio2_buffer *b,
+				     struct cio2_fbpt_entry
+				     entry[CIO2_MAX_LOPS])
+{
+	struct vb2_buffer *vb = &b->vbb.vb2_buf;
+	unsigned int length = vb->planes[0].length;
+	int remaining, i;
+
+	entry[0].first_entry.first_page_offset = b->offset;
+	remaining = length + entry[0].first_entry.first_page_offset;
+	entry[1].second_entry.num_of_pages =
+		DIV_ROUND_UP(remaining, CIO2_PAGE_SIZE);
+	/*
+	 * last_page_available_bytes has the offset of the last byte in the
+	 * last page which is still accessible by DMA. DMA cannot access
+	 * beyond this point. Valid range for this is from 0 to 4095.
+	 * 0 indicates 1st byte in the page is DMA accessible.
+	 * 4095 (CIO2_PAGE_SIZE - 1) means every single byte in the last page
+	 * is available for DMA transfer.
+	 */
+	entry[1].second_entry.last_page_available_bytes =
+			(remaining & ~PAGE_MASK) ?
+				(remaining & ~PAGE_MASK) - 1 :
+				CIO2_PAGE_SIZE - 1;
+	/* Fill FBPT */
+	remaining = length;
+	i = 0;
+	while (remaining > 0) {
+		entry->lop_page_addr = b->lop_bus_addr[i] >> PAGE_SHIFT;
+		remaining -= CIO2_PAGE_SIZE / sizeof(u32) * CIO2_PAGE_SIZE;
+		entry++;
+		i++;
+	}
+
+	/*
+	 * The first not meaningful FBPT entry should point to a valid LOP
+	 */
+	entry->lop_page_addr = cio2->dummy_lop_bus_addr >> PAGE_SHIFT;
+
+	cio2_fbpt_entry_enable(cio2, entry);
+}
+
+static int cio2_fbpt_init(struct cio2_device *cio2, struct cio2_queue *q)
+{
+	struct device *dev = &cio2->pci_dev->dev;
+
+	q->fbpt = dma_alloc_coherent(dev, CIO2_FBPT_SIZE, &q->fbpt_bus_addr,
+				     GFP_KERNEL);
+	if (!q->fbpt)
+		return -ENOMEM;
+
+	memset(q->fbpt, 0, CIO2_FBPT_SIZE);
+
+	return 0;
+}
+
+static void cio2_fbpt_exit(struct cio2_queue *q, struct device *dev)
+{
+	dma_free_coherent(dev, CIO2_FBPT_SIZE, q->fbpt, q->fbpt_bus_addr);
+}
+
+/**************** CSI2 hardware setup ****************/
+
+/*
+ * The CSI2 receiver has several parameters affecting
+ * the receiver timings. These depend on the MIPI bus frequency
+ * F in Hz (sensor transmitter rate) as follows:
+ *     register value = (A/1e9 + B * UI) / COUNT_ACC
+ * where
+ *      UI = 1 / (2 * F) in seconds
+ *      COUNT_ACC = counter accuracy in seconds
+ *      For IPU3 COUNT_ACC = 0.0625
+ *
+ * A and B are coefficients from the table below,
+ * depending whether the register minimum or maximum value is
+ * calculated.
+ *                                     Minimum     Maximum
+ * Clock lane                          A     B     A     B
+ * reg_rx_csi_dly_cnt_termen_clane     0     0    38     0
+ * reg_rx_csi_dly_cnt_settle_clane    95    -8   300   -16
+ * Data lanes
+ * reg_rx_csi_dly_cnt_termen_dlane0    0     0    35     4
+ * reg_rx_csi_dly_cnt_settle_dlane0   85    -2   145    -6
+ * reg_rx_csi_dly_cnt_termen_dlane1    0     0    35     4
+ * reg_rx_csi_dly_cnt_settle_dlane1   85    -2   145    -6
+ * reg_rx_csi_dly_cnt_termen_dlane2    0     0    35     4
+ * reg_rx_csi_dly_cnt_settle_dlane2   85    -2   145    -6
+ * reg_rx_csi_dly_cnt_termen_dlane3    0     0    35     4
+ * reg_rx_csi_dly_cnt_settle_dlane3   85    -2   145    -6
+ *
+ * We use the minimum values of both A and B.
+ */
+
+/*
+ * shift for keeping value range suitable for 32-bit integer arithmetics
+ */
+#define LIMIT_SHIFT	8
+
+static s32 cio2_rx_timing(s32 a, s32 b, s64 freq, int def)
+{
+	const u32 accinv = 16; /* invert of counter resolution */
+	const u32 uiinv = 500000000; /* 1e9 / 2 */
+	s32 r;
+
+	freq >>= LIMIT_SHIFT;
+
+	if (WARN_ON(freq <= 0 || freq > S32_MAX))
+		return def;
+	/*
+	 * b could be 0, -2 or -8, so |accinv * b| is always
+	 * less than (1 << ds) and thus |r| < 500000000.
+	 */
+	r = accinv * b * (uiinv >> LIMIT_SHIFT);
+	r = r / (s32)freq;
+	/* max value of a is 95 */
+	r += accinv * a;
+
+	return r;
+};
+
+/* Calculate the the delay value for termination enable of clock lane HS Rx */
+static int cio2_csi2_calc_timing(struct cio2_device *cio2, struct cio2_queue *q,
+				 struct cio2_csi2_timing *timing)
+{
+	struct device *dev = &cio2->pci_dev->dev;
+	struct v4l2_querymenu qm = {.id = V4L2_CID_LINK_FREQ, };
+	struct v4l2_ctrl *link_freq;
+	s64 freq;
+	int r;
+
+	if (!q->sensor)
+		return -ENODEV;
+
+	link_freq = v4l2_ctrl_find(q->sensor->ctrl_handler, V4L2_CID_LINK_FREQ);
+	if (!link_freq) {
+		dev_err(dev, "failed to find LINK_FREQ\n");
+		return -EPIPE;
+	}
+
+	qm.index = v4l2_ctrl_g_ctrl(link_freq);
+	r = v4l2_querymenu(q->sensor->ctrl_handler, &qm);
+	if (r) {
+		dev_err(dev, "failed to get menu item\n");
+		return r;
+	}
+
+	if (!qm.value) {
+		dev_err(dev, "error invalid link_freq\n");
+		return -EINVAL;
+	}
+	freq = qm.value;
+
+	timing->clk_termen = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_A,
+					    CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_B,
+					    freq,
+					    CIO2_CSIRX_DLY_CNT_TERMEN_DEFAULT);
+	timing->clk_settle = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_SETTLE_CLANE_A,
+					    CIO2_CSIRX_DLY_CNT_SETTLE_CLANE_B,
+					    freq,
+					    CIO2_CSIRX_DLY_CNT_SETTLE_DEFAULT);
+	timing->dat_termen = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_TERMEN_DLANE_A,
+					    CIO2_CSIRX_DLY_CNT_TERMEN_DLANE_B,
+					    freq,
+					    CIO2_CSIRX_DLY_CNT_TERMEN_DEFAULT);
+	timing->dat_settle = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_SETTLE_DLANE_A,
+					    CIO2_CSIRX_DLY_CNT_SETTLE_DLANE_B,
+					    freq,
+					    CIO2_CSIRX_DLY_CNT_SETTLE_DEFAULT);
+
+	dev_dbg(dev, "freq ct value is %d\n", timing->clk_termen);
+	dev_dbg(dev, "freq cs value is %d\n", timing->clk_settle);
+	dev_dbg(dev, "freq dt value is %d\n", timing->dat_termen);
+	dev_dbg(dev, "freq ds value is %d\n", timing->dat_settle);
+
+	return 0;
+};
+
+static int cio2_hw_init(struct cio2_device *cio2, struct cio2_queue *q)
+{
+	static const int NUM_VCS = 4;
+	static const int SID;	/* Stream id */
+	static const int ENTRY;
+	static const int FBPT_WIDTH = DIV_ROUND_UP(CIO2_MAX_LOPS,
+					CIO2_FBPT_SUBENTRY_UNIT);
+	const u32 num_buffers1 = CIO2_MAX_BUFFERS - 1;
+	const struct ipu3_cio2_fmt *fmt;
+	void __iomem *const base = cio2->base;
+	u8 lanes, csi2bus = q->csi2.port;
+	u8 sensor_vc = SENSOR_VIR_CH_DFLT;
+	struct cio2_csi2_timing timing;
+	int i, r;
+
+	fmt = cio2_find_format(NULL, &q->subdev_fmt.code);
+	if (!fmt)
+		return -EINVAL;
+
+	lanes = q->csi2.lanes;
+
+	r = cio2_csi2_calc_timing(cio2, q, &timing);
+	if (r)
+		return r;
+
+	writel(timing.clk_termen, q->csi_rx_base +
+		CIO2_REG_CSIRX_DLY_CNT_TERMEN(CIO2_CSIRX_DLY_CNT_CLANE_IDX));
+	writel(timing.clk_settle, q->csi_rx_base +
+		CIO2_REG_CSIRX_DLY_CNT_SETTLE(CIO2_CSIRX_DLY_CNT_CLANE_IDX));
+
+	for (i = 0; i < lanes; i++) {
+		writel(timing.dat_termen, q->csi_rx_base +
+			CIO2_REG_CSIRX_DLY_CNT_TERMEN(i));
+		writel(timing.dat_settle, q->csi_rx_base +
+			CIO2_REG_CSIRX_DLY_CNT_SETTLE(i));
+	}
+
+	writel(CIO2_PBM_WMCTRL1_MIN_2CK |
+	       CIO2_PBM_WMCTRL1_MID1_2CK |
+	       CIO2_PBM_WMCTRL1_MID2_2CK, base + CIO2_REG_PBM_WMCTRL1);
+	writel(CIO2_PBM_WMCTRL2_HWM_2CK << CIO2_PBM_WMCTRL2_HWM_2CK_SHIFT |
+	       CIO2_PBM_WMCTRL2_LWM_2CK << CIO2_PBM_WMCTRL2_LWM_2CK_SHIFT |
+	       CIO2_PBM_WMCTRL2_OBFFWM_2CK <<
+	       CIO2_PBM_WMCTRL2_OBFFWM_2CK_SHIFT |
+	       CIO2_PBM_WMCTRL2_TRANSDYN << CIO2_PBM_WMCTRL2_TRANSDYN_SHIFT |
+	       CIO2_PBM_WMCTRL2_OBFF_MEM_EN, base + CIO2_REG_PBM_WMCTRL2);
+	writel(CIO2_PBM_ARB_CTRL_LANES_DIV <<
+	       CIO2_PBM_ARB_CTRL_LANES_DIV_SHIFT |
+	       CIO2_PBM_ARB_CTRL_LE_EN |
+	       CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN <<
+	       CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN_SHIFT |
+	       CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP <<
+	       CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP_SHIFT,
+	       base + CIO2_REG_PBM_ARB_CTRL);
+	writel(CIO2_CSIRX_STATUS_DLANE_HS_MASK,
+	       q->csi_rx_base + CIO2_REG_CSIRX_STATUS_DLANE_HS);
+	writel(CIO2_CSIRX_STATUS_DLANE_LP_MASK,
+	       q->csi_rx_base + CIO2_REG_CSIRX_STATUS_DLANE_LP);
+
+	writel(CIO2_FB_HPLL_FREQ, base + CIO2_REG_FB_HPLL_FREQ);
+	writel(CIO2_ISCLK_RATIO, base + CIO2_REG_ISCLK_RATIO);
+
+	/* Configure MIPI backend */
+	for (i = 0; i < NUM_VCS; i++)
+		writel(1, q->csi_rx_base + CIO2_REG_MIPIBE_SP_LUT_ENTRY(i));
+
+	/* There are 16 short packet LUT entry */
+	for (i = 0; i < 16; i++)
+		writel(CIO2_MIPIBE_LP_LUT_ENTRY_DISREGARD,
+		       q->csi_rx_base + CIO2_REG_MIPIBE_LP_LUT_ENTRY(i));
+	writel(CIO2_MIPIBE_GLOBAL_LUT_DISREGARD,
+	       q->csi_rx_base + CIO2_REG_MIPIBE_GLOBAL_LUT_DISREGARD);
+
+	writel(CIO2_INT_EN_EXT_IE_MASK, base + CIO2_REG_INT_EN_EXT_IE);
+	writel(CIO2_IRQCTRL_MASK, q->csi_rx_base + CIO2_REG_IRQCTRL_MASK);
+	writel(CIO2_IRQCTRL_MASK, q->csi_rx_base + CIO2_REG_IRQCTRL_ENABLE);
+	writel(0, q->csi_rx_base + CIO2_REG_IRQCTRL_EDGE);
+	writel(0, q->csi_rx_base + CIO2_REG_IRQCTRL_LEVEL_NOT_PULSE);
+	writel(CIO2_INT_EN_EXT_OE_MASK, base + CIO2_REG_INT_EN_EXT_OE);
+
+	writel(CIO2_REG_INT_EN_IRQ | CIO2_INT_IOC(CIO2_DMA_CHAN) |
+	       CIO2_REG_INT_EN_IOS(CIO2_DMA_CHAN),
+	       base + CIO2_REG_INT_EN);
+
+	writel((CIO2_PXM_PXF_FMT_CFG_BPP_10 | CIO2_PXM_PXF_FMT_CFG_PCK_64B)
+	       << CIO2_PXM_PXF_FMT_CFG_SID0_SHIFT,
+	       base + CIO2_REG_PXM_PXF_FMT_CFG0(csi2bus));
+	writel(SID << CIO2_MIPIBE_LP_LUT_ENTRY_SID_SHIFT |
+	       sensor_vc << CIO2_MIPIBE_LP_LUT_ENTRY_VC_SHIFT |
+	       fmt->mipicode << CIO2_MIPIBE_LP_LUT_ENTRY_FORMAT_TYPE_SHIFT,
+	       q->csi_rx_base + CIO2_REG_MIPIBE_LP_LUT_ENTRY(ENTRY));
+	writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_COMP_FORMAT(sensor_vc));
+	writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_FORCE_RAW8);
+	writel(0, base + CIO2_REG_PXM_SID2BID0(csi2bus));
+
+	writel(lanes, q->csi_rx_base + CIO2_REG_CSIRX_NOF_ENABLED_LANES);
+	writel(CIO2_CGC_PRIM_TGE |
+	       CIO2_CGC_SIDE_TGE |
+	       CIO2_CGC_XOSC_TGE |
+	       CIO2_CGC_D3I3_TGE |
+	       CIO2_CGC_CSI2_INTERFRAME_TGE |
+	       CIO2_CGC_CSI2_PORT_DCGE |
+	       CIO2_CGC_SIDE_DCGE |
+	       CIO2_CGC_PRIM_DCGE |
+	       CIO2_CGC_ROSC_DCGE |
+	       CIO2_CGC_XOSC_DCGE |
+	       CIO2_CGC_CLKGATE_HOLDOFF << CIO2_CGC_CLKGATE_HOLDOFF_SHIFT |
+	       CIO2_CGC_CSI_CLKGATE_HOLDOFF
+	       << CIO2_CGC_CSI_CLKGATE_HOLDOFF_SHIFT, base + CIO2_REG_CGC);
+	writel(CIO2_LTRCTRL_LTRDYNEN, base + CIO2_REG_LTRCTRL);
+	writel(CIO2_LTRVAL0_VAL << CIO2_LTRVAL02_VAL_SHIFT |
+	       CIO2_LTRVAL0_SCALE << CIO2_LTRVAL02_SCALE_SHIFT |
+	       CIO2_LTRVAL1_VAL << CIO2_LTRVAL13_VAL_SHIFT |
+	       CIO2_LTRVAL1_SCALE << CIO2_LTRVAL13_SCALE_SHIFT,
+	       base + CIO2_REG_LTRVAL01);
+	writel(CIO2_LTRVAL2_VAL << CIO2_LTRVAL02_VAL_SHIFT |
+	       CIO2_LTRVAL2_SCALE << CIO2_LTRVAL02_SCALE_SHIFT |
+	       CIO2_LTRVAL3_VAL << CIO2_LTRVAL13_VAL_SHIFT |
+	       CIO2_LTRVAL3_SCALE << CIO2_LTRVAL13_SCALE_SHIFT,
+	       base + CIO2_REG_LTRVAL23);
+
+	for (i = 0; i < CIO2_NUM_DMA_CHAN; i++) {
+		writel(0, base + CIO2_REG_CDMABA(i));
+		writel(0, base + CIO2_REG_CDMAC0(i));
+		writel(0, base + CIO2_REG_CDMAC1(i));
+	}
+
+	/* Enable DMA */
+	writel(q->fbpt_bus_addr >> PAGE_SHIFT,
+	       base + CIO2_REG_CDMABA(CIO2_DMA_CHAN));
+
+	writel(num_buffers1 << CIO2_CDMAC0_FBPT_LEN_SHIFT |
+	       FBPT_WIDTH << CIO2_CDMAC0_FBPT_WIDTH_SHIFT |
+	       CIO2_CDMAC0_DMA_INTR_ON_FE |
+	       CIO2_CDMAC0_FBPT_UPDATE_FIFO_FULL |
+	       CIO2_CDMAC0_DMA_EN |
+	       CIO2_CDMAC0_DMA_INTR_ON_FS |
+	       CIO2_CDMAC0_DMA_HALTED, base + CIO2_REG_CDMAC0(CIO2_DMA_CHAN));
+
+	writel(1 << CIO2_CDMAC1_LINENUMUPDATE_SHIFT,
+	       base + CIO2_REG_CDMAC1(CIO2_DMA_CHAN));
+
+	writel(0, base + CIO2_REG_PBM_FOPN_ABORT);
+
+	writel(CIO2_PXM_FRF_CFG_CRC_TH << CIO2_PXM_FRF_CFG_CRC_TH_SHIFT |
+	       CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NR |
+	       CIO2_PXM_FRF_CFG_MSK_ECC_RE |
+	       CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NE,
+	       base + CIO2_REG_PXM_FRF_CFG(q->csi2.port));
+
+	/* Clear interrupts */
+	writel(CIO2_IRQCTRL_MASK, q->csi_rx_base + CIO2_REG_IRQCTRL_CLEAR);
+	writel(~0, base + CIO2_REG_INT_STS_EXT_OE);
+	writel(~0, base + CIO2_REG_INT_STS_EXT_IE);
+	writel(~0, base + CIO2_REG_INT_STS);
+
+	/* Enable devices, starting from the last device in the pipe */
+	writel(1, q->csi_rx_base + CIO2_REG_MIPIBE_ENABLE);
+	writel(1, q->csi_rx_base + CIO2_REG_CSIRX_ENABLE);
+
+	return 0;
+}
+
+static void cio2_hw_exit(struct cio2_device *cio2, struct cio2_queue *q)
+{
+	void __iomem *base = cio2->base;
+	unsigned int i, maxloops = 1000;
+
+	/* Disable CSI receiver and MIPI backend devices */
+	writel(0, q->csi_rx_base + CIO2_REG_CSIRX_ENABLE);
+	writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_ENABLE);
+
+	/* Halt DMA */
+	writel(0, base + CIO2_REG_CDMAC0(CIO2_DMA_CHAN));
+	do {
+		if (readl(base + CIO2_REG_CDMAC0(CIO2_DMA_CHAN)) &
+		    CIO2_CDMAC0_DMA_HALTED)
+			break;
+		usleep_range(1000, 2000);
+	} while (--maxloops);
+	if (!maxloops)
+		dev_err(&cio2->pci_dev->dev,
+			"DMA %i can not be halted\n", CIO2_DMA_CHAN);
+
+	for (i = 0; i < CIO2_NUM_PORTS; i++) {
+		writel(readl(base + CIO2_REG_PXM_FRF_CFG(i)) |
+		       CIO2_PXM_FRF_CFG_ABORT, base + CIO2_REG_PXM_FRF_CFG(i));
+		writel(readl(base + CIO2_REG_PBM_FOPN_ABORT) |
+		       CIO2_PBM_FOPN_ABORT(i), base + CIO2_REG_PBM_FOPN_ABORT);
+	}
+}
+
+static void cio2_buffer_done(struct cio2_device *cio2, unsigned int dma_chan)
+{
+	struct device *dev = &cio2->pci_dev->dev;
+	struct cio2_queue *q = cio2->cur_queue;
+	int buffers_found = 0;
+	u64 ns = ktime_get_ns();
+
+	if (dma_chan >= CIO2_QUEUES) {
+		dev_err(dev, "bad DMA channel %i\n", dma_chan);
+		return;
+	}
+
+	/* Find out which buffer(s) are ready */
+	do {
+		struct cio2_fbpt_entry *const entry =
+			&q->fbpt[q->bufs_first * CIO2_MAX_LOPS];
+		struct cio2_buffer *b;
+
+		if (entry->first_entry.ctrl & CIO2_FBPT_CTRL_VALID)
+			break;
+
+		b = q->bufs[q->bufs_first];
+		if (b) {
+			unsigned int bytes = entry[1].second_entry.num_of_bytes;
+
+			q->bufs[q->bufs_first] = NULL;
+			atomic_dec(&q->bufs_queued);
+			dev_dbg(&cio2->pci_dev->dev,
+				"buffer %i done\n", b->vbb.vb2_buf.index);
+
+			b->vbb.vb2_buf.timestamp = ns;
+			b->vbb.field = V4L2_FIELD_NONE;
+			b->vbb.sequence = atomic_read(&q->frame_sequence);
+			if (b->vbb.vb2_buf.planes[0].length != bytes)
+				dev_warn(dev, "buffer length is %d received %d\n",
+					 b->vbb.vb2_buf.planes[0].length,
+					 bytes);
+			vb2_buffer_done(&b->vbb.vb2_buf, VB2_BUF_STATE_DONE);
+		}
+		atomic_inc(&q->frame_sequence);
+		cio2_fbpt_entry_init_dummy(cio2, entry);
+		q->bufs_first = (q->bufs_first + 1) % CIO2_MAX_BUFFERS;
+		buffers_found++;
+	} while (1);
+
+	if (buffers_found == 0)
+		dev_warn(&cio2->pci_dev->dev,
+			 "no ready buffers found on DMA channel %u\n",
+			 dma_chan);
+}
+
+static void cio2_queue_event_sof(struct cio2_device *cio2, struct cio2_queue *q)
+{
+	/*
+	 * For the user space camera control algorithms it is essential
+	 * to know when the reception of a frame has begun. That's often
+	 * the best timing information to get from the hardware.
+	 */
+	struct v4l2_event event = {
+		.type = V4L2_EVENT_FRAME_SYNC,
+		.u.frame_sync.frame_sequence = atomic_read(&q->frame_sequence),
+	};
+
+	v4l2_event_queue(q->subdev.devnode, &event);
+}
+
+static const char *const cio2_irq_errs[] = {
+	"single packet header error corrected",
+	"multiple packet header errors detected",
+	"payload checksum (CRC) error",
+	"fifo overflow",
+	"reserved short packet data type detected",
+	"reserved long packet data type detected",
+	"incomplete long packet detected",
+	"frame sync error",
+	"line sync error",
+	"DPHY start of transmission error",
+	"DPHY synchronization error",
+	"escape mode error",
+	"escape mode trigger event",
+	"escape mode ultra-low power state for data lane(s)",
+	"escape mode ultra-low power state exit for clock lane",
+	"inter-frame short packet discarded",
+	"inter-frame long packet discarded",
+	"non-matching Long Packet stalled",
+};
+
+static const char *const cio2_port_errs[] = {
+	"ECC recoverable",
+	"DPHY not recoverable",
+	"ECC not recoverable",
+	"CRC error",
+	"INTERFRAMEDATA",
+	"PKT2SHORT",
+	"PKT2LONG",
+};
+
+static irqreturn_t cio2_irq(int irq, void *cio2_ptr)
+{
+	struct cio2_device *cio2 = cio2_ptr;
+	void __iomem *const base = cio2->base;
+	struct device *dev = &cio2->pci_dev->dev;
+	u32 int_status, int_clear;
+
+	int_status = readl(base + CIO2_REG_INT_STS);
+	int_clear = int_status;
+
+	if (!int_status)
+		return IRQ_NONE;
+
+	if (int_status & CIO2_INT_IOOE) {
+		/*
+		 * Interrupt on Output Error:
+		 * 1) SRAM is full and FS received, or
+		 * 2) An invalid bit detected by DMA.
+		 */
+		u32 oe_status, oe_clear;
+
+		oe_clear = readl(base + CIO2_REG_INT_STS_EXT_OE);
+		oe_status = oe_clear;
+
+		if (oe_status & CIO2_INT_EXT_OE_DMAOE_MASK) {
+			dev_err(dev, "DMA output error: 0x%x\n",
+				(oe_status & CIO2_INT_EXT_OE_DMAOE_MASK)
+				>> CIO2_INT_EXT_OE_DMAOE_SHIFT);
+			oe_status &= ~CIO2_INT_EXT_OE_DMAOE_MASK;
+		}
+		if (oe_status & CIO2_INT_EXT_OE_OES_MASK) {
+			dev_err(dev, "DMA output error on CSI2 buses: 0x%x\n",
+				(oe_status & CIO2_INT_EXT_OE_OES_MASK)
+				>> CIO2_INT_EXT_OE_OES_SHIFT);
+			oe_status &= ~CIO2_INT_EXT_OE_OES_MASK;
+		}
+		writel(oe_clear, base + CIO2_REG_INT_STS_EXT_OE);
+		if (oe_status)
+			dev_warn(dev, "unknown interrupt 0x%x on OE\n",
+				 oe_status);
+		int_status &= ~CIO2_INT_IOOE;
+	}
+
+	if (int_status & CIO2_INT_IOC_MASK) {
+		/* DMA IO done -- frame ready */
+		u32 clr = 0;
+		unsigned int d;
+
+		for (d = 0; d < CIO2_NUM_DMA_CHAN; d++)
+			if (int_status & CIO2_INT_IOC(d)) {
+				clr |= CIO2_INT_IOC(d);
+				cio2_buffer_done(cio2, d);
+			}
+		int_status &= ~clr;
+	}
+
+	if (int_status & CIO2_INT_IOS_IOLN_MASK) {
+		/* DMA IO starts or reached specified line */
+		u32 clr = 0;
+		unsigned int d;
+
+		for (d = 0; d < CIO2_NUM_DMA_CHAN; d++)
+			if (int_status & CIO2_INT_IOS_IOLN(d)) {
+				clr |= CIO2_INT_IOS_IOLN(d);
+				if (d == CIO2_DMA_CHAN)
+					cio2_queue_event_sof(cio2,
+							     cio2->cur_queue);
+			}
+		int_status &= ~clr;
+	}
+
+	if (int_status & (CIO2_INT_IOIE | CIO2_INT_IOIRQ)) {
+		/* CSI2 receiver (error) interrupt */
+		u32 ie_status, ie_clear;
+		unsigned int port;
+
+		ie_clear = readl(base + CIO2_REG_INT_STS_EXT_IE);
+		ie_status = ie_clear;
+
+		for (port = 0; port < CIO2_NUM_PORTS; port++) {
+			u32 port_status = (ie_status >> (port * 8)) & 0xff;
+			u32 err_mask = BIT_MASK(ARRAY_SIZE(cio2_port_errs)) - 1;
+			void __iomem *const csi_rx_base =
+						base + CIO2_REG_PIPE_BASE(port);
+			unsigned int i;
+
+			while (port_status & err_mask) {
+				i = ffs(port_status) - 1;
+				dev_err(dev, "port %i error %s\n",
+					port, cio2_port_errs[i]);
+				ie_status &= ~BIT(port * 8 + i);
+				port_status &= ~BIT(i);
+			}
+
+			if (ie_status & CIO2_INT_EXT_IE_IRQ(port)) {
+				u32 csi2_status, csi2_clear;
+
+				csi2_status = readl(csi_rx_base +
+						CIO2_REG_IRQCTRL_STATUS);
+				csi2_clear = csi2_status;
+				err_mask =
+					BIT_MASK(ARRAY_SIZE(cio2_irq_errs)) - 1;
+
+				while (csi2_status & err_mask) {
+					i = ffs(csi2_status) - 1;
+					dev_err(dev,
+						"CSI-2 receiver port %i: %s\n",
+							port, cio2_irq_errs[i]);
+					csi2_status &= ~BIT(i);
+				}
+
+				writel(csi2_clear,
+				       csi_rx_base + CIO2_REG_IRQCTRL_CLEAR);
+				if (csi2_status)
+					dev_warn(dev,
+						 "unknown CSI2 error 0x%x on port %i\n",
+						 csi2_status, port);
+
+				ie_status &= ~CIO2_INT_EXT_IE_IRQ(port);
+			}
+		}
+
+		writel(ie_clear, base + CIO2_REG_INT_STS_EXT_IE);
+		if (ie_status)
+			dev_warn(dev, "unknown interrupt 0x%x on IE\n",
+				 ie_status);
+
+		int_status &= ~(CIO2_INT_IOIE | CIO2_INT_IOIRQ);
+	}
+
+	writel(int_clear, base + CIO2_REG_INT_STS);
+	if (int_status)
+		dev_warn(dev, "unknown interrupt 0x%x on INT\n", int_status);
+
+	return IRQ_HANDLED;
+}
+
+/**************** Videobuf2 interface ****************/
+
+static void cio2_vb2_return_all_buffers(struct cio2_queue *q,
+					enum vb2_buffer_state state)
+{
+	unsigned int i;
+
+	for (i = 0; i < CIO2_MAX_BUFFERS; i++) {
+		if (q->bufs[i]) {
+			atomic_dec(&q->bufs_queued);
+			vb2_buffer_done(&q->bufs[i]->vbb.vb2_buf,
+					state);
+		}
+	}
+}
+
+static int cio2_vb2_queue_setup(struct vb2_queue *vq,
+				unsigned int *num_buffers,
+				unsigned int *num_planes,
+				unsigned int sizes[],
+				struct device *alloc_devs[])
+{
+	struct cio2_device *cio2 = vb2_get_drv_priv(vq);
+	struct cio2_queue *q = vb2q_to_cio2_queue(vq);
+	unsigned int i;
+
+	*num_planes = q->format.num_planes;
+
+	for (i = 0; i < *num_planes; ++i) {
+		sizes[i] = q->format.plane_fmt[i].sizeimage;
+		alloc_devs[i] = &cio2->pci_dev->dev;
+	}
+
+	*num_buffers = clamp_val(*num_buffers, 1, CIO2_MAX_BUFFERS);
+
+	/* Initialize buffer queue */
+	for (i = 0; i < CIO2_MAX_BUFFERS; i++) {
+		q->bufs[i] = NULL;
+		cio2_fbpt_entry_init_dummy(cio2, &q->fbpt[i * CIO2_MAX_LOPS]);
+	}
+	atomic_set(&q->bufs_queued, 0);
+	q->bufs_first = 0;
+	q->bufs_next = 0;
+
+	return 0;
+}
+
+/* Called after each buffer is allocated */
+static int cio2_vb2_buf_init(struct vb2_buffer *vb)
+{
+	struct cio2_device *cio2 = vb2_get_drv_priv(vb->vb2_queue);
+	struct device *dev = &cio2->pci_dev->dev;
+	struct cio2_buffer *b =
+		container_of(vb, struct cio2_buffer, vbb.vb2_buf);
+	static const unsigned int entries_per_page =
+		CIO2_PAGE_SIZE / sizeof(u32);
+	unsigned int pages = DIV_ROUND_UP(vb->planes[0].length, CIO2_PAGE_SIZE);
+	unsigned int lops = DIV_ROUND_UP(pages + 1, entries_per_page);
+	struct sg_table *sg;
+	struct sg_page_iter sg_iter;
+	int i, j;
+
+	if (lops <= 0 || lops > CIO2_MAX_LOPS) {
+		dev_err(dev, "%s: bad buffer size (%i)\n", __func__,
+			vb->planes[0].length);
+		return -ENOSPC;		/* Should never happen */
+	}
+
+	memset(b->lop, 0, sizeof(b->lop));
+	/* Allocate LOP table */
+	for (i = 0; i < lops; i++) {
+		b->lop[i] = dma_alloc_coherent(dev, CIO2_PAGE_SIZE,
+					       &b->lop_bus_addr[i], GFP_KERNEL);
+		if (!b->lop[i])
+			goto fail;
+	}
+
+	/* Fill LOP */
+	sg = vb2_dma_sg_plane_desc(vb, 0);
+	if (!sg)
+		return -ENOMEM;
+
+	if (sg->nents && sg->sgl)
+		b->offset = sg->sgl->offset;
+
+	i = j = 0;
+	for_each_sg_page(sg->sgl, &sg_iter, sg->nents, 0) {
+		if (!pages--)
+			break;
+		b->lop[i][j] = sg_page_iter_dma_address(&sg_iter) >> PAGE_SHIFT;
+		j++;
+		if (j == entries_per_page) {
+			i++;
+			j = 0;
+		}
+	}
+
+	b->lop[i][j] = cio2->dummy_page_bus_addr >> PAGE_SHIFT;
+	return 0;
+fail:
+	for (i--; i >= 0; i--)
+		dma_free_coherent(dev, CIO2_PAGE_SIZE,
+				  b->lop[i], b->lop_bus_addr[i]);
+	return -ENOMEM;
+}
+
+/* Transfer buffer ownership to cio2 */
+static void cio2_vb2_buf_queue(struct vb2_buffer *vb)
+{
+	struct cio2_device *cio2 = vb2_get_drv_priv(vb->vb2_queue);
+	struct cio2_queue *q =
+		container_of(vb->vb2_queue, struct cio2_queue, vbq);
+	struct cio2_buffer *b =
+		container_of(vb, struct cio2_buffer, vbb.vb2_buf);
+	struct cio2_fbpt_entry *entry;
+	unsigned long flags;
+	unsigned int i, j, next = q->bufs_next;
+	int bufs_queued = atomic_inc_return(&q->bufs_queued);
+	u32 fbpt_rp;
+
+	dev_dbg(&cio2->pci_dev->dev, "queue buffer %d\n", vb->index);
+
+	/*
+	 * This code queues the buffer to the CIO2 DMA engine, which starts
+	 * running once streaming has started. It is possible that this code
+	 * gets pre-empted due to increased CPU load. Upon this, the driver
+	 * does not get an opportunity to queue new buffers to the CIO2 DMA
+	 * engine. When the DMA engine encounters an FBPT entry without the
+	 * VALID bit set, the DMA engine halts, which requires a restart of
+	 * the DMA engine and sensor, to continue streaming.
+	 * This is not desired and is highly unlikely given that there are
+	 * 32 FBPT entries that the DMA engine needs to process, to run into
+	 * an FBPT entry, without the VALID bit set. We try to mitigate this
+	 * by disabling interrupts for the duration of this queueing.
+	 */
+	local_irq_save(flags);
+
+	fbpt_rp = (readl(cio2->base + CIO2_REG_CDMARI(CIO2_DMA_CHAN))
+		   >> CIO2_CDMARI_FBPT_RP_SHIFT)
+		   & CIO2_CDMARI_FBPT_RP_MASK;
+
+	/*
+	 * fbpt_rp is the fbpt entry that the dma is currently working
+	 * on, but since it could jump to next entry at any time,
+	 * assume that we might already be there.
+	 */
+	fbpt_rp = (fbpt_rp + 1) % CIO2_MAX_BUFFERS;
+
+	if (bufs_queued <= 1 || fbpt_rp == next)
+		/* Buffers were drained */
+		next = (fbpt_rp + 1) % CIO2_MAX_BUFFERS;
+
+	for (i = 0; i < CIO2_MAX_BUFFERS; i++) {
+		/*
+		 * We have allocated CIO2_MAX_BUFFERS circularly for the
+		 * hw, the user has requested N buffer queue. The driver
+		 * ensures N <= CIO2_MAX_BUFFERS and guarantees that whenever
+		 * user queues a buffer, there necessarily is a free buffer.
+		 */
+		if (!q->bufs[next]) {
+			q->bufs[next] = b;
+			entry = &q->fbpt[next * CIO2_MAX_LOPS];
+			cio2_fbpt_entry_init_buf(cio2, b, entry);
+			local_irq_restore(flags);
+			q->bufs_next = (next + 1) % CIO2_MAX_BUFFERS;
+			for (j = 0; j < vb->num_planes; j++)
+				vb2_set_plane_payload(vb, j,
+					q->format.plane_fmt[j].sizeimage);
+			return;
+		}
+
+		dev_dbg(&cio2->pci_dev->dev, "entry %i was full!\n", next);
+		next = (next + 1) % CIO2_MAX_BUFFERS;
+	}
+
+	local_irq_restore(flags);
+	dev_err(&cio2->pci_dev->dev, "error: all cio2 entries were full!\n");
+	atomic_dec(&q->bufs_queued);
+	vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+}
+
+/* Called when each buffer is freed */
+static void cio2_vb2_buf_cleanup(struct vb2_buffer *vb)
+{
+	struct cio2_device *cio2 = vb2_get_drv_priv(vb->vb2_queue);
+	struct cio2_buffer *b =
+		container_of(vb, struct cio2_buffer, vbb.vb2_buf);
+	unsigned int i;
+
+	/* Free LOP table */
+	for (i = 0; i < CIO2_MAX_LOPS; i++) {
+		if (b->lop[i])
+			dma_free_coherent(&cio2->pci_dev->dev, CIO2_PAGE_SIZE,
+					  b->lop[i], b->lop_bus_addr[i]);
+	}
+}
+
+static int cio2_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct cio2_queue *q = vb2q_to_cio2_queue(vq);
+	struct cio2_device *cio2 = vb2_get_drv_priv(vq);
+	int r;
+
+	cio2->cur_queue = q;
+	atomic_set(&q->frame_sequence, 0);
+
+	r = pm_runtime_get_sync(&cio2->pci_dev->dev);
+	if (r < 0) {
+		dev_info(&cio2->pci_dev->dev, "failed to set power %d\n", r);
+		pm_runtime_put_noidle(&cio2->pci_dev->dev);
+		return r;
+	}
+
+	r = media_pipeline_start(&q->vdev.entity, &q->pipe);
+	if (r)
+		goto fail_pipeline;
+
+	r = cio2_hw_init(cio2, q);
+	if (r)
+		goto fail_hw;
+
+	/* Start streaming on sensor */
+	r = v4l2_subdev_call(q->sensor, video, s_stream, 1);
+	if (r)
+		goto fail_csi2_subdev;
+
+	cio2->streaming = true;
+
+	return 0;
+
+fail_csi2_subdev:
+	cio2_hw_exit(cio2, q);
+fail_hw:
+	media_pipeline_stop(&q->vdev.entity);
+fail_pipeline:
+	dev_dbg(&cio2->pci_dev->dev, "failed to start streaming (%d)\n", r);
+	cio2_vb2_return_all_buffers(q, VB2_BUF_STATE_QUEUED);
+	pm_runtime_put(&cio2->pci_dev->dev);
+
+	return r;
+}
+
+static void cio2_vb2_stop_streaming(struct vb2_queue *vq)
+{
+	struct cio2_queue *q = vb2q_to_cio2_queue(vq);
+	struct cio2_device *cio2 = vb2_get_drv_priv(vq);
+
+	if (v4l2_subdev_call(q->sensor, video, s_stream, 0))
+		dev_err(&cio2->pci_dev->dev,
+			"failed to stop sensor streaming\n");
+
+	cio2_hw_exit(cio2, q);
+	cio2_vb2_return_all_buffers(q, VB2_BUF_STATE_ERROR);
+	media_pipeline_stop(&q->vdev.entity);
+	pm_runtime_put(&cio2->pci_dev->dev);
+	cio2->streaming = false;
+}
+
+static const struct vb2_ops cio2_vb2_ops = {
+	.buf_init = cio2_vb2_buf_init,
+	.buf_queue = cio2_vb2_buf_queue,
+	.buf_cleanup = cio2_vb2_buf_cleanup,
+	.queue_setup = cio2_vb2_queue_setup,
+	.start_streaming = cio2_vb2_start_streaming,
+	.stop_streaming = cio2_vb2_stop_streaming,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+};
+
+/**************** V4L2 interface ****************/
+
+static int cio2_v4l2_querycap(struct file *file, void *fh,
+			      struct v4l2_capability *cap)
+{
+	struct cio2_device *cio2 = video_drvdata(file);
+
+	strlcpy(cap->driver, CIO2_NAME, sizeof(cap->driver));
+	strlcpy(cap->card, CIO2_DEVICE_NAME, sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+		 "PCI:%s", pci_name(cio2->pci_dev));
+
+	return 0;
+}
+
+static int cio2_v4l2_enum_fmt(struct file *file, void *fh,
+			      struct v4l2_fmtdesc *f)
+{
+	if (f->index >= ARRAY_SIZE(formats))
+		return -EINVAL;
+
+	f->pixelformat = formats[f->index].fourcc;
+
+	return 0;
+}
+
+/* The format is validated in cio2_video_link_validate() */
+static int cio2_v4l2_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct cio2_queue *q = file_to_cio2_queue(file);
+
+	f->fmt.pix_mp = q->format;
+
+	return 0;
+}
+
+static int cio2_v4l2_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	const struct ipu3_cio2_fmt *fmt;
+	struct v4l2_pix_format_mplane *mpix = &f->fmt.pix_mp;
+
+	fmt = cio2_find_format(&mpix->pixelformat, NULL);
+	if (!fmt)
+		fmt = &formats[0];
+
+	/* Only supports up to 4224x3136 */
+	if (mpix->width > CIO2_IMAGE_MAX_WIDTH)
+		mpix->width = CIO2_IMAGE_MAX_WIDTH;
+	if (mpix->height > CIO2_IMAGE_MAX_LENGTH)
+		mpix->height = CIO2_IMAGE_MAX_LENGTH;
+
+	mpix->num_planes = 1;
+	mpix->pixelformat = fmt->fourcc;
+	mpix->colorspace = V4L2_COLORSPACE_RAW;
+	mpix->field = V4L2_FIELD_NONE;
+	memset(mpix->reserved, 0, sizeof(mpix->reserved));
+	mpix->plane_fmt[0].bytesperline = cio2_bytesperline(mpix->width);
+	mpix->plane_fmt[0].sizeimage = mpix->plane_fmt[0].bytesperline *
+							mpix->height;
+	memset(mpix->plane_fmt[0].reserved, 0,
+	       sizeof(mpix->plane_fmt[0].reserved));
+
+	/* use default */
+	mpix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+	mpix->quantization = V4L2_QUANTIZATION_DEFAULT;
+	mpix->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+
+	return 0;
+}
+
+static int cio2_v4l2_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct cio2_queue *q = file_to_cio2_queue(file);
+
+	cio2_v4l2_try_fmt(file, fh, f);
+	q->format = f->fmt.pix_mp;
+
+	return 0;
+}
+
+static int
+cio2_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
+{
+	if (input->index > 0)
+		return -EINVAL;
+
+	strlcpy(input->name, "camera", sizeof(input->name));
+	input->type = V4L2_INPUT_TYPE_CAMERA;
+
+	return 0;
+}
+
+static int
+cio2_video_g_input(struct file *file, void *fh, unsigned int *input)
+{
+	*input = 0;
+
+	return 0;
+}
+
+static int
+cio2_video_s_input(struct file *file, void *fh, unsigned int input)
+{
+	return input == 0 ? 0 : -EINVAL;
+}
+
+static const struct v4l2_file_operations cio2_v4l2_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = video_ioctl2,
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
+	.poll = vb2_fop_poll,
+	.mmap = vb2_fop_mmap,
+};
+
+static const struct v4l2_ioctl_ops cio2_v4l2_ioctl_ops = {
+	.vidioc_querycap = cio2_v4l2_querycap,
+	.vidioc_enum_fmt_vid_cap_mplane = cio2_v4l2_enum_fmt,
+	.vidioc_g_fmt_vid_cap_mplane = cio2_v4l2_g_fmt,
+	.vidioc_s_fmt_vid_cap_mplane = cio2_v4l2_s_fmt,
+	.vidioc_try_fmt_vid_cap_mplane = cio2_v4l2_try_fmt,
+	.vidioc_reqbufs = vb2_ioctl_reqbufs,
+	.vidioc_create_bufs = vb2_ioctl_create_bufs,
+	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf = vb2_ioctl_querybuf,
+	.vidioc_qbuf = vb2_ioctl_qbuf,
+	.vidioc_dqbuf = vb2_ioctl_dqbuf,
+	.vidioc_streamon = vb2_ioctl_streamon,
+	.vidioc_streamoff = vb2_ioctl_streamoff,
+	.vidioc_expbuf = vb2_ioctl_expbuf,
+	.vidioc_enum_input = cio2_video_enum_input,
+	.vidioc_g_input	= cio2_video_g_input,
+	.vidioc_s_input	= cio2_video_s_input,
+};
+
+static int cio2_subdev_subscribe_event(struct v4l2_subdev *sd,
+				       struct v4l2_fh *fh,
+				       struct v4l2_event_subscription *sub)
+{
+	if (sub->type != V4L2_EVENT_FRAME_SYNC)
+		return -EINVAL;
+
+	/* Line number. For now only zero accepted. */
+	if (sub->id != 0)
+		return -EINVAL;
+
+	return v4l2_event_subscribe(fh, sub, 0, NULL);
+}
+
+static int cio2_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct v4l2_mbus_framefmt *format;
+	const struct v4l2_mbus_framefmt fmt_default = {
+		.width = 1936,
+		.height = 1096,
+		.code = formats[0].mbus_code,
+		.field = V4L2_FIELD_NONE,
+		.colorspace = V4L2_COLORSPACE_RAW,
+		.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
+		.quantization = V4L2_QUANTIZATION_DEFAULT,
+		.xfer_func = V4L2_XFER_FUNC_DEFAULT,
+	};
+
+	/* Initialize try_fmt */
+	format = v4l2_subdev_get_try_format(sd, fh->pad, CIO2_PAD_SINK);
+	*format = fmt_default;
+
+	/* same as sink */
+	format = v4l2_subdev_get_try_format(sd, fh->pad, CIO2_PAD_SOURCE);
+	*format = fmt_default;
+
+	return 0;
+}
+
+/*
+ * cio2_subdev_get_fmt - 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
+ * return -EINVAL or zero on success
+ */
+static int cio2_subdev_get_fmt(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_pad_config *cfg,
+			       struct v4l2_subdev_format *fmt)
+{
+	struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev);
+	struct v4l2_subdev_format format;
+	int ret;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+		return 0;
+	}
+
+	if (fmt->pad == CIO2_PAD_SINK) {
+		format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
+				       &format);
+
+		if (ret)
+			return ret;
+		/* update colorspace etc */
+		q->subdev_fmt.colorspace = format.format.colorspace;
+		q->subdev_fmt.ycbcr_enc = format.format.ycbcr_enc;
+		q->subdev_fmt.quantization = format.format.quantization;
+		q->subdev_fmt.xfer_func = format.format.xfer_func;
+	}
+
+	fmt->format = q->subdev_fmt;
+
+	return 0;
+}
+
+/*
+ * cio2_subdev_set_fmt - 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 cio2_subdev_set_fmt(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_pad_config *cfg,
+			       struct v4l2_subdev_format *fmt)
+{
+	struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev);
+
+	/*
+	 * Only allow setting sink pad format;
+	 * source always propagates from sink
+	 */
+	if (fmt->pad == CIO2_PAD_SOURCE)
+		return cio2_subdev_get_fmt(sd, cfg, fmt);
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		*v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+	} else {
+		/* It's the sink, allow changing frame size */
+		q->subdev_fmt.width = fmt->format.width;
+		q->subdev_fmt.height = fmt->format.height;
+		q->subdev_fmt.code = fmt->format.code;
+		fmt->format = q->subdev_fmt;
+	}
+
+	return 0;
+}
+
+static int cio2_subdev_enum_mbus_code(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_pad_config *cfg,
+				      struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= ARRAY_SIZE(formats))
+		return -EINVAL;
+
+	code->code = formats[code->index].mbus_code;
+	return 0;
+}
+
+static int cio2_subdev_link_validate_get_format(struct media_pad *pad,
+						struct v4l2_subdev_format *fmt)
+{
+	if (is_media_entity_v4l2_subdev(pad->entity)) {
+		struct v4l2_subdev *sd =
+			media_entity_to_v4l2_subdev(pad->entity);
+
+		fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		fmt->pad = pad->index;
+		return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
+	}
+
+	return -EINVAL;
+}
+
+static int cio2_video_link_validate(struct media_link *link)
+{
+	struct video_device *vd = container_of(link->sink->entity,
+						struct video_device, entity);
+	struct cio2_queue *q = container_of(vd, struct cio2_queue, vdev);
+	struct cio2_device *cio2 = video_get_drvdata(vd);
+	struct v4l2_subdev_format source_fmt;
+	int ret;
+
+	if (!media_entity_remote_pad(link->sink->entity->pads)) {
+		dev_info(&cio2->pci_dev->dev,
+			 "video node %s pad not connected\n", vd->name);
+		return -ENOTCONN;
+	}
+
+	ret = cio2_subdev_link_validate_get_format(link->source, &source_fmt);
+	if (ret < 0)
+		return 0;
+
+	if (source_fmt.format.width != q->format.width ||
+	    source_fmt.format.height != q->format.height) {
+		dev_err(&cio2->pci_dev->dev,
+			"Wrong width or height %ux%u (%ux%u expected)\n",
+			q->format.width, q->format.height,
+			source_fmt.format.width, source_fmt.format.height);
+		return -EINVAL;
+	}
+
+	if (!cio2_find_format(&q->format.pixelformat, &source_fmt.format.code))
+		return -EINVAL;
+
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops cio2_subdev_core_ops = {
+	.subscribe_event = cio2_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_internal_ops cio2_subdev_internal_ops = {
+	.open = cio2_subdev_open,
+};
+
+static const struct v4l2_subdev_pad_ops cio2_subdev_pad_ops = {
+	.link_validate = v4l2_subdev_link_validate_default,
+	.get_fmt = cio2_subdev_get_fmt,
+	.set_fmt = cio2_subdev_set_fmt,
+	.enum_mbus_code = cio2_subdev_enum_mbus_code,
+};
+
+static const struct v4l2_subdev_ops cio2_subdev_ops = {
+	.core = &cio2_subdev_core_ops,
+	.pad = &cio2_subdev_pad_ops,
+};
+
+/******* V4L2 sub-device asynchronous registration callbacks***********/
+
+struct sensor_async_subdev {
+	struct v4l2_async_subdev asd;
+	struct csi2_bus_info csi2;
+};
+
+/* The .bound() notifier callback when a match is found */
+static int cio2_notifier_bound(struct v4l2_async_notifier *notifier,
+			       struct v4l2_subdev *sd,
+			       struct v4l2_async_subdev *asd)
+{
+	struct cio2_device *cio2 = container_of(notifier,
+					struct cio2_device, notifier);
+	struct sensor_async_subdev *s_asd = container_of(asd,
+					struct sensor_async_subdev, asd);
+	struct cio2_queue *q;
+
+	if (cio2->queue[s_asd->csi2.port].sensor)
+		return -EBUSY;
+
+	q = &cio2->queue[s_asd->csi2.port];
+
+	q->csi2 = s_asd->csi2;
+	q->sensor = sd;
+	q->csi_rx_base = cio2->base + CIO2_REG_PIPE_BASE(q->csi2.port);
+
+	return 0;
+}
+
+/* The .unbind callback */
+static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier,
+				 struct v4l2_subdev *sd,
+				 struct v4l2_async_subdev *asd)
+{
+	struct cio2_device *cio2 = container_of(notifier,
+						struct cio2_device, notifier);
+	struct sensor_async_subdev *s_asd = container_of(asd,
+					struct sensor_async_subdev, asd);
+
+	cio2->queue[s_asd->csi2.port].sensor = NULL;
+}
+
+/* .complete() is called after all subdevices have been located */
+static int cio2_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+	struct cio2_device *cio2 = container_of(notifier, struct cio2_device,
+						notifier);
+	struct sensor_async_subdev *s_asd;
+	struct cio2_queue *q;
+	unsigned int i, pad;
+	int ret;
+
+	for (i = 0; i < notifier->num_subdevs; i++) {
+		s_asd = container_of(cio2->notifier.subdevs[i],
+				     struct sensor_async_subdev, asd);
+		q = &cio2->queue[s_asd->csi2.port];
+
+		for (pad = 0; pad < q->sensor->entity.num_pads; pad++)
+			if (q->sensor->entity.pads[pad].flags &
+						MEDIA_PAD_FL_SOURCE)
+				break;
+
+		if (pad == q->sensor->entity.num_pads) {
+			dev_err(&cio2->pci_dev->dev,
+				"failed to find src pad for %s\n",
+				q->sensor->name);
+			return -ENXIO;
+		}
+
+		ret = media_create_pad_link(
+				&q->sensor->entity, pad,
+				&q->subdev.entity, CIO2_PAD_SINK,
+				0);
+		if (ret) {
+			dev_err(&cio2->pci_dev->dev,
+				"failed to create link for %s\n",
+				cio2->queue[i].sensor->name);
+			return ret;
+		}
+	}
+
+	return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev);
+}
+
+static const struct v4l2_async_notifier_operations cio2_async_ops = {
+	.bound = cio2_notifier_bound,
+	.unbind = cio2_notifier_unbind,
+	.complete = cio2_notifier_complete,
+};
+
+static int cio2_fwnode_parse(struct device *dev,
+			     struct v4l2_fwnode_endpoint *vep,
+			     struct v4l2_async_subdev *asd)
+{
+	struct sensor_async_subdev *s_asd =
+			container_of(asd, struct sensor_async_subdev, asd);
+
+	if (vep->bus_type != V4L2_MBUS_CSI2) {
+		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)
+{
+	int ret;
+
+	ret = v4l2_async_notifier_parse_fwnode_endpoints(
+		&cio2->pci_dev->dev, &cio2->notifier,
+		sizeof(struct sensor_async_subdev),
+		cio2_fwnode_parse);
+	if (ret < 0)
+		return ret;
+
+	if (!cio2->notifier.num_subdevs)
+		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;
+}
+
+static void cio2_notifier_exit(struct cio2_device *cio2)
+{
+	v4l2_async_notifier_unregister(&cio2->notifier);
+	v4l2_async_notifier_cleanup(&cio2->notifier);
+}
+
+/**************** Queue initialization ****************/
+static const struct media_entity_operations cio2_media_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+static const struct media_entity_operations cio2_video_entity_ops = {
+	.link_validate = cio2_video_link_validate,
+};
+
+static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q)
+{
+	static const u32 default_width = 1936;
+	static const u32 default_height = 1096;
+	const struct ipu3_cio2_fmt dflt_fmt = formats[0];
+
+	struct video_device *vdev = &q->vdev;
+	struct vb2_queue *vbq = &q->vbq;
+	struct v4l2_subdev *subdev = &q->subdev;
+	struct v4l2_mbus_framefmt *fmt;
+	int r;
+
+	/* Initialize miscellaneous variables */
+	mutex_init(&q->lock);
+
+	/* Initialize formats to default values */
+	fmt = &q->subdev_fmt;
+	fmt->width = default_width;
+	fmt->height = default_height;
+	fmt->code = dflt_fmt.mbus_code;
+	fmt->field = V4L2_FIELD_NONE;
+
+	q->format.width = default_width;
+	q->format.height = default_height;
+	q->format.pixelformat = dflt_fmt.fourcc;
+	q->format.colorspace = V4L2_COLORSPACE_RAW;
+	q->format.field = V4L2_FIELD_NONE;
+	q->format.num_planes = 1;
+	q->format.plane_fmt[0].bytesperline =
+				cio2_bytesperline(q->format.width);
+	q->format.plane_fmt[0].sizeimage = q->format.plane_fmt[0].bytesperline *
+						q->format.height;
+
+	/* Initialize fbpt */
+	r = cio2_fbpt_init(cio2, q);
+	if (r)
+		goto fail_fbpt;
+
+	/* Initialize media entities */
+	q->subdev_pads[CIO2_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
+		MEDIA_PAD_FL_MUST_CONNECT;
+	q->subdev_pads[CIO2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+	subdev->entity.ops = &cio2_media_ops;
+	subdev->internal_ops = &cio2_subdev_internal_ops;
+	r = media_entity_pads_init(&subdev->entity, CIO2_PADS, q->subdev_pads);
+	if (r) {
+		dev_err(&cio2->pci_dev->dev,
+			"failed initialize subdev media entity (%d)\n", r);
+		goto fail_subdev_media_entity;
+	}
+
+	q->vdev_pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
+	vdev->entity.ops = &cio2_video_entity_ops;
+	r = media_entity_pads_init(&vdev->entity, 1, &q->vdev_pad);
+	if (r) {
+		dev_err(&cio2->pci_dev->dev,
+			"failed initialize videodev media entity (%d)\n", r);
+		goto fail_vdev_media_entity;
+	}
+
+	/* Initialize subdev */
+	v4l2_subdev_init(subdev, &cio2_subdev_ops);
+	subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+	subdev->owner = THIS_MODULE;
+	snprintf(subdev->name, sizeof(subdev->name),
+		 CIO2_ENTITY_NAME " %td", q - cio2->queue);
+	v4l2_set_subdevdata(subdev, cio2);
+	r = v4l2_device_register_subdev(&cio2->v4l2_dev, subdev);
+	if (r) {
+		dev_err(&cio2->pci_dev->dev,
+			"failed initialize subdev (%d)\n", r);
+		goto fail_subdev;
+	}
+
+	/* Initialize vbq */
+	vbq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	vbq->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF;
+	vbq->ops = &cio2_vb2_ops;
+	vbq->mem_ops = &vb2_dma_sg_memops;
+	vbq->buf_struct_size = sizeof(struct cio2_buffer);
+	vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	vbq->min_buffers_needed = 1;
+	vbq->drv_priv = cio2;
+	vbq->lock = &q->lock;
+	r = vb2_queue_init(vbq);
+	if (r) {
+		dev_err(&cio2->pci_dev->dev,
+			"failed to initialize videobuf2 queue (%d)\n", r);
+		goto fail_vbq;
+	}
+
+	/* Initialize vdev */
+	snprintf(vdev->name, sizeof(vdev->name),
+		 "%s %td", CIO2_NAME, q - cio2->queue);
+	vdev->release = video_device_release_empty;
+	vdev->fops = &cio2_v4l2_fops;
+	vdev->ioctl_ops = &cio2_v4l2_ioctl_ops;
+	vdev->lock = &cio2->lock;
+	vdev->v4l2_dev = &cio2->v4l2_dev;
+	vdev->queue = &q->vbq;
+	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING;
+	video_set_drvdata(vdev, cio2);
+	r = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+	if (r) {
+		dev_err(&cio2->pci_dev->dev,
+			"failed to register video device (%d)\n", r);
+		goto fail_vdev;
+	}
+
+	/* Create link from CIO2 subdev to output node */
+	r = media_create_pad_link(
+		&subdev->entity, CIO2_PAD_SOURCE, &vdev->entity, 0,
+		MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
+	if (r)
+		goto fail_link;
+
+	return 0;
+
+fail_link:
+	video_unregister_device(&q->vdev);
+fail_vdev:
+	vb2_queue_release(vbq);
+fail_vbq:
+	v4l2_device_unregister_subdev(subdev);
+fail_subdev:
+	media_entity_cleanup(&vdev->entity);
+fail_vdev_media_entity:
+	media_entity_cleanup(&subdev->entity);
+fail_subdev_media_entity:
+	cio2_fbpt_exit(q, &cio2->pci_dev->dev);
+fail_fbpt:
+	mutex_destroy(&q->lock);
+
+	return r;
+}
+
+static void cio2_queue_exit(struct cio2_device *cio2, struct cio2_queue *q)
+{
+	video_unregister_device(&q->vdev);
+	media_entity_cleanup(&q->vdev.entity);
+	vb2_queue_release(&q->vbq);
+	v4l2_device_unregister_subdev(&q->subdev);
+	media_entity_cleanup(&q->subdev.entity);
+	cio2_fbpt_exit(q, &cio2->pci_dev->dev);
+	mutex_destroy(&q->lock);
+}
+
+static int cio2_queues_init(struct cio2_device *cio2)
+{
+	int i, r;
+
+	for (i = 0; i < CIO2_QUEUES; i++) {
+		r = cio2_queue_init(cio2, &cio2->queue[i]);
+		if (r)
+			break;
+	}
+
+	if (i == CIO2_QUEUES)
+		return 0;
+
+	for (i--; i >= 0; i--)
+		cio2_queue_exit(cio2, &cio2->queue[i]);
+
+	return r;
+}
+
+static void cio2_queues_exit(struct cio2_device *cio2)
+{
+	unsigned int i;
+
+	for (i = 0; i < CIO2_QUEUES; i++)
+		cio2_queue_exit(cio2, &cio2->queue[i]);
+}
+
+/**************** PCI interface ****************/
+
+static int cio2_pci_config_setup(struct pci_dev *dev)
+{
+	u16 pci_command;
+	int r = pci_enable_msi(dev);
+
+	if (r) {
+		dev_err(&dev->dev, "failed to enable MSI (%d)\n", r);
+		return r;
+	}
+
+	pci_read_config_word(dev, PCI_COMMAND, &pci_command);
+	pci_command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+		PCI_COMMAND_INTX_DISABLE;
+	pci_write_config_word(dev, PCI_COMMAND, pci_command);
+
+	return 0;
+}
+
+static int cio2_pci_probe(struct pci_dev *pci_dev,
+			  const struct pci_device_id *id)
+{
+	struct cio2_device *cio2;
+	void __iomem *const *iomap;
+	int r;
+
+	cio2 = devm_kzalloc(&pci_dev->dev, sizeof(*cio2), GFP_KERNEL);
+	if (!cio2)
+		return -ENOMEM;
+	cio2->pci_dev = pci_dev;
+
+	r = pcim_enable_device(pci_dev);
+	if (r) {
+		dev_err(&pci_dev->dev, "failed to enable device (%d)\n", r);
+		return r;
+	}
+
+	dev_info(&pci_dev->dev, "device 0x%x (rev: 0x%x)\n",
+		 pci_dev->device, pci_dev->revision);
+
+	r = pcim_iomap_regions(pci_dev, 1 << CIO2_PCI_BAR, pci_name(pci_dev));
+	if (r) {
+		dev_err(&pci_dev->dev, "failed to remap I/O memory (%d)\n", r);
+		return -ENODEV;
+	}
+
+	iomap = pcim_iomap_table(pci_dev);
+	if (!iomap) {
+		dev_err(&pci_dev->dev, "failed to iomap table\n");
+		return -ENODEV;
+	}
+
+	cio2->base = iomap[CIO2_PCI_BAR];
+
+	pci_set_drvdata(pci_dev, cio2);
+
+	pci_set_master(pci_dev);
+
+	r = pci_set_dma_mask(pci_dev, CIO2_DMA_MASK);
+	if (r) {
+		dev_err(&pci_dev->dev, "failed to set DMA mask (%d)\n", r);
+		return -ENODEV;
+	}
+
+	r = cio2_pci_config_setup(pci_dev);
+	if (r)
+		return -ENODEV;
+
+	r = cio2_fbpt_init_dummy(cio2);
+	if (r)
+		return r;
+
+	mutex_init(&cio2->lock);
+
+	cio2->media_dev.dev = &cio2->pci_dev->dev;
+	strlcpy(cio2->media_dev.model, CIO2_DEVICE_NAME,
+		sizeof(cio2->media_dev.model));
+	snprintf(cio2->media_dev.bus_info, sizeof(cio2->media_dev.bus_info),
+		 "PCI:%s", pci_name(cio2->pci_dev));
+	cio2->media_dev.hw_revision = 0;
+
+	media_device_init(&cio2->media_dev);
+	r = media_device_register(&cio2->media_dev);
+	if (r < 0)
+		goto fail_mutex_destroy;
+
+	cio2->v4l2_dev.mdev = &cio2->media_dev;
+	r = v4l2_device_register(&pci_dev->dev, &cio2->v4l2_dev);
+	if (r) {
+		dev_err(&pci_dev->dev,
+			"failed to register V4L2 device (%d)\n", r);
+		goto fail_media_device_unregister;
+	}
+
+	r = cio2_queues_init(cio2);
+	if (r)
+		goto fail_v4l2_device_unregister;
+
+	/* Register notifier for subdevices we care */
+	r = cio2_notifier_init(cio2);
+	if (r)
+		goto fail_cio2_queue_exit;
+
+	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;
+	}
+
+	pm_runtime_put_noidle(&pci_dev->dev);
+	pm_runtime_allow(&pci_dev->dev);
+
+	return 0;
+
+fail:
+	cio2_notifier_exit(cio2);
+fail_cio2_queue_exit:
+	cio2_queues_exit(cio2);
+fail_v4l2_device_unregister:
+	v4l2_device_unregister(&cio2->v4l2_dev);
+fail_media_device_unregister:
+	media_device_unregister(&cio2->media_dev);
+	media_device_cleanup(&cio2->media_dev);
+fail_mutex_destroy:
+	mutex_destroy(&cio2->lock);
+	cio2_fbpt_exit_dummy(cio2);
+
+	return r;
+}
+
+static void cio2_pci_remove(struct pci_dev *pci_dev)
+{
+	struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+	unsigned int i;
+
+	cio2_notifier_exit(cio2);
+	cio2_fbpt_exit_dummy(cio2);
+	for (i = 0; i < CIO2_QUEUES; i++)
+		cio2_queue_exit(cio2, &cio2->queue[i]);
+	v4l2_device_unregister(&cio2->v4l2_dev);
+	media_device_unregister(&cio2->media_dev);
+	media_device_cleanup(&cio2->media_dev);
+	mutex_destroy(&cio2->lock);
+}
+
+static int __maybe_unused cio2_runtime_suspend(struct device *dev)
+{
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+	void __iomem *const base = cio2->base;
+	u16 pm;
+
+	writel(CIO2_D0I3C_I3, base + CIO2_REG_D0I3C);
+	dev_dbg(dev, "cio2 runtime suspend.\n");
+
+	pci_read_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, &pm);
+	pm = (pm >> CIO2_PMCSR_D0D3_SHIFT) << CIO2_PMCSR_D0D3_SHIFT;
+	pm |= CIO2_PMCSR_D3;
+	pci_write_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, pm);
+
+	return 0;
+}
+
+static int __maybe_unused cio2_runtime_resume(struct device *dev)
+{
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+	void __iomem *const base = cio2->base;
+	u16 pm;
+
+	writel(CIO2_D0I3C_RR, base + CIO2_REG_D0I3C);
+	dev_dbg(dev, "cio2 runtime resume.\n");
+
+	pci_read_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, &pm);
+	pm = (pm >> CIO2_PMCSR_D0D3_SHIFT) << CIO2_PMCSR_D0D3_SHIFT;
+	pci_write_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, pm);
+
+	return 0;
+}
+
+/*
+ * Helper function to advance all the elements of a circular buffer by "start"
+ * positions
+ */
+static void arrange(void *ptr, size_t elem_size, size_t elems, size_t start)
+{
+	struct {
+		size_t begin, end;
+	} arr[2] = {
+		{ 0, start - 1 },
+		{ start, elems - 1 },
+	};
+
+#define CHUNK_SIZE(a) ((a)->end - (a)->begin + 1)
+
+	/* Loop as long as we have out-of-place entries */
+	while (CHUNK_SIZE(&arr[0]) && CHUNK_SIZE(&arr[1])) {
+		size_t size0, i;
+
+		/*
+		 * Find the number of entries that can be arranged on this
+		 * iteration.
+		 */
+		size0 = min(CHUNK_SIZE(&arr[0]), CHUNK_SIZE(&arr[1]));
+
+		/* Swap the entries in two parts of the array. */
+		for (i = 0; i < size0; i++) {
+			u8 *d = ptr + elem_size * (arr[1].begin + i);
+			u8 *s = ptr + elem_size * (arr[0].begin + i);
+			size_t j;
+
+			for (j = 0; j < elem_size; j++)
+				swap(d[j], s[j]);
+		}
+
+		if (CHUNK_SIZE(&arr[0]) > CHUNK_SIZE(&arr[1])) {
+			/* The end of the first array remains unarranged. */
+			arr[0].begin += size0;
+		} else {
+			/*
+			 * The first array is fully arranged so we proceed
+			 * handling the next one.
+			 */
+			arr[0].begin = arr[1].begin;
+			arr[0].end = arr[1].begin + size0 - 1;
+			arr[1].begin += size0;
+		}
+	}
+}
+
+static void cio2_fbpt_rearrange(struct cio2_device *cio2, struct cio2_queue *q)
+{
+	unsigned int i, j;
+
+	for (i = 0, j = q->bufs_first; i < CIO2_MAX_BUFFERS;
+		i++, j = (j + 1) % CIO2_MAX_BUFFERS)
+		if (q->bufs[j])
+			break;
+
+	if (i == CIO2_MAX_BUFFERS)
+		return;
+
+	if (j) {
+		arrange(q->fbpt, sizeof(struct cio2_fbpt_entry) * CIO2_MAX_LOPS,
+			CIO2_MAX_BUFFERS, j);
+		arrange(q->bufs, sizeof(struct cio2_buffer *),
+			CIO2_MAX_BUFFERS, j);
+	}
+
+	/*
+	 * DMA clears the valid bit when accessing the buffer.
+	 * When stopping stream in suspend callback, some of the buffers
+	 * may be in invalid state. After resume, when DMA meets the invalid
+	 * buffer, it will halt and stop receiving new data.
+	 * To avoid DMA halting, set the valid bit for all buffers in FBPT.
+	 */
+	for (i = 0; i < CIO2_MAX_BUFFERS; i++)
+		cio2_fbpt_entry_enable(cio2, q->fbpt + i * CIO2_MAX_LOPS);
+}
+
+static int __maybe_unused cio2_suspend(struct device *dev)
+{
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+	struct cio2_queue *q = cio2->cur_queue;
+
+	dev_dbg(dev, "cio2 suspend\n");
+	if (!cio2->streaming)
+		return 0;
+
+	/* Stop stream */
+	cio2_hw_exit(cio2, q);
+
+	pm_runtime_force_suspend(dev);
+
+	/*
+	 * Upon resume, hw starts to process the fbpt entries from beginning,
+	 * so relocate the queued buffs to the fbpt head before suspend.
+	 */
+	cio2_fbpt_rearrange(cio2, q);
+	q->bufs_first = 0;
+	q->bufs_next = 0;
+
+	return 0;
+}
+
+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);
+	int r = 0;
+	struct cio2_queue *q = cio2->cur_queue;
+
+	dev_dbg(dev, "cio2 resume\n");
+	if (!cio2->streaming)
+		return 0;
+	/* Start stream */
+	r = pm_runtime_force_resume(&cio2->pci_dev->dev);
+	if (r < 0) {
+		dev_err(&cio2->pci_dev->dev,
+			"failed to set power %d\n", r);
+		return r;
+	}
+
+	r = cio2_hw_init(cio2, q);
+	if (r)
+		dev_err(dev, "fail to init cio2 hw\n");
+
+	return r;
+}
+
+static const struct dev_pm_ops cio2_pm_ops = {
+	SET_RUNTIME_PM_OPS(&cio2_runtime_suspend, &cio2_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(&cio2_suspend, &cio2_resume)
+};
+
+static const struct pci_device_id cio2_pci_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, CIO2_PCI_ID) },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, cio2_pci_id_table);
+
+static struct pci_driver cio2_pci_driver = {
+	.name = CIO2_NAME,
+	.id_table = cio2_pci_id_table,
+	.probe = cio2_pci_probe,
+	.remove = cio2_pci_remove,
+	.driver = {
+		.pm = &cio2_pm_ops,
+	},
+};
+
+module_pci_driver(cio2_pci_driver);
+
+MODULE_AUTHOR("Tuukka Toivonen <tuukka.toivonen@intel.com>");
+MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>");
+MODULE_AUTHOR("Jian Xu Zheng <jian.xu.zheng@intel.com>");
+MODULE_AUTHOR("Yuning Pu <yuning.pu@intel.com>");
+MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("IPU3 CIO2 driver");
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.h b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
new file mode 100644
index 0000000..78a5799
--- /dev/null
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2017 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * 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 __IPU3_CIO2_H
+#define __IPU3_CIO2_H
+
+#define CIO2_NAME					"ipu3-cio2"
+#define CIO2_DEVICE_NAME				"Intel IPU3 CIO2"
+#define CIO2_ENTITY_NAME				"ipu3-csi2"
+#define CIO2_PCI_ID					0x9d32
+#define CIO2_PCI_BAR					0
+#define CIO2_DMA_MASK					DMA_BIT_MASK(39)
+#define CIO2_IMAGE_MAX_WIDTH				4224
+#define CIO2_IMAGE_MAX_LENGTH				3136
+
+#define CIO2_IMAGE_MAX_WIDTH				4224
+#define CIO2_IMAGE_MAX_LENGTH				3136
+
+/* 32MB = 8xFBPT_entry */
+#define CIO2_MAX_LOPS					8
+#define CIO2_MAX_BUFFERS			(PAGE_SIZE / 16 / CIO2_MAX_LOPS)
+
+#define CIO2_PAD_SINK					0
+#define CIO2_PAD_SOURCE					1
+#define CIO2_PADS					2
+
+#define CIO2_NUM_DMA_CHAN				20
+#define CIO2_NUM_PORTS					4 /* DPHYs */
+
+/* 1 for each sensor */
+#define CIO2_QUEUES					CIO2_NUM_PORTS
+
+/* Register and bit field definitions */
+#define CIO2_REG_PIPE_BASE(n)			((n) * 0x0400)	/* n = 0..3 */
+#define CIO2_REG_CSIRX_BASE				0x000
+#define CIO2_REG_MIPIBE_BASE				0x100
+#define CIO2_REG_PIXELGEN_BAS				0x200
+#define CIO2_REG_IRQCTRL_BASE				0x300
+#define CIO2_REG_GPREG_BASE				0x1000
+
+/* base register: CIO2_REG_PIPE_BASE(pipe) * CIO2_REG_CSIRX_BASE */
+#define CIO2_REG_CSIRX_ENABLE			(CIO2_REG_CSIRX_BASE + 0x0)
+#define CIO2_REG_CSIRX_NOF_ENABLED_LANES	(CIO2_REG_CSIRX_BASE + 0x4)
+#define CIO2_REG_CSIRX_SP_IF_CONFIG		(CIO2_REG_CSIRX_BASE + 0x10)
+#define CIO2_REG_CSIRX_LP_IF_CONFIG		(CIO2_REG_CSIRX_BASE + 0x14)
+#define CIO2_CSIRX_IF_CONFIG_FILTEROUT			0x00
+#define CIO2_CSIRX_IF_CONFIG_FILTEROUT_VC_INACTIVE	0x01
+#define CIO2_CSIRX_IF_CONFIG_PASS			0x02
+#define CIO2_CSIRX_IF_CONFIG_FLAG_ERROR			BIT(2)
+#define CIO2_REG_CSIRX_STATUS			(CIO2_REG_CSIRX_BASE + 0x18)
+#define CIO2_REG_CSIRX_STATUS_DLANE_HS		(CIO2_REG_CSIRX_BASE + 0x1c)
+#define CIO2_CSIRX_STATUS_DLANE_HS_MASK			0xff
+#define CIO2_REG_CSIRX_STATUS_DLANE_LP		(CIO2_REG_CSIRX_BASE + 0x20)
+#define CIO2_CSIRX_STATUS_DLANE_LP_MASK			0xffffff
+/* Termination enable and settle in 0.0625ns units, lane=0..3 or -1 for clock */
+#define CIO2_REG_CSIRX_DLY_CNT_TERMEN(lane) \
+				(CIO2_REG_CSIRX_BASE + 0x2c + 8 * (lane))
+#define CIO2_REG_CSIRX_DLY_CNT_SETTLE(lane) \
+				(CIO2_REG_CSIRX_BASE + 0x30 + 8 * (lane))
+/* base register: CIO2_REG_PIPE_BASE(pipe) * CIO2_REG_MIPIBE_BASE */
+#define CIO2_REG_MIPIBE_ENABLE		(CIO2_REG_MIPIBE_BASE + 0x0)
+#define CIO2_REG_MIPIBE_STATUS		(CIO2_REG_MIPIBE_BASE + 0x4)
+#define CIO2_REG_MIPIBE_COMP_FORMAT(vc) \
+				(CIO2_REG_MIPIBE_BASE + 0x8 + 0x4 * (vc))
+#define CIO2_REG_MIPIBE_FORCE_RAW8	(CIO2_REG_MIPIBE_BASE + 0x20)
+#define CIO2_REG_MIPIBE_FORCE_RAW8_ENABLE		BIT(0)
+#define CIO2_REG_MIPIBE_FORCE_RAW8_USE_TYPEID		BIT(1)
+#define CIO2_REG_MIPIBE_FORCE_RAW8_TYPEID_SHIFT		2
+
+#define CIO2_REG_MIPIBE_IRQ_STATUS	(CIO2_REG_MIPIBE_BASE + 0x24)
+#define CIO2_REG_MIPIBE_IRQ_CLEAR	(CIO2_REG_MIPIBE_BASE + 0x28)
+#define CIO2_REG_MIPIBE_GLOBAL_LUT_DISREGARD (CIO2_REG_MIPIBE_BASE + 0x68)
+#define CIO2_MIPIBE_GLOBAL_LUT_DISREGARD		1
+#define CIO2_REG_MIPIBE_PKT_STALL_STATUS (CIO2_REG_MIPIBE_BASE + 0x6c)
+#define CIO2_REG_MIPIBE_PARSE_GSP_THROUGH_LP_LUT_REG_IDX \
+					(CIO2_REG_MIPIBE_BASE + 0x70)
+#define CIO2_REG_MIPIBE_SP_LUT_ENTRY(vc) \
+				       (CIO2_REG_MIPIBE_BASE + 0x74 + 4 * (vc))
+#define CIO2_REG_MIPIBE_LP_LUT_ENTRY(m)	/* m = 0..15 */ \
+					(CIO2_REG_MIPIBE_BASE + 0x84 + 4 * (m))
+#define CIO2_MIPIBE_LP_LUT_ENTRY_DISREGARD		1
+#define CIO2_MIPIBE_LP_LUT_ENTRY_SID_SHIFT		1
+#define CIO2_MIPIBE_LP_LUT_ENTRY_VC_SHIFT		5
+#define CIO2_MIPIBE_LP_LUT_ENTRY_FORMAT_TYPE_SHIFT	7
+
+/* base register: CIO2_REG_PIPE_BASE(pipe) * CIO2_REG_IRQCTRL_BASE */
+/* IRQ registers are 18-bit wide, see cio2_irq_error for bit definitions */
+#define CIO2_REG_IRQCTRL_EDGE		(CIO2_REG_IRQCTRL_BASE + 0x00)
+#define CIO2_REG_IRQCTRL_MASK		(CIO2_REG_IRQCTRL_BASE + 0x04)
+#define CIO2_REG_IRQCTRL_STATUS		(CIO2_REG_IRQCTRL_BASE + 0x08)
+#define CIO2_REG_IRQCTRL_CLEAR		(CIO2_REG_IRQCTRL_BASE + 0x0c)
+#define CIO2_REG_IRQCTRL_ENABLE		(CIO2_REG_IRQCTRL_BASE + 0x10)
+#define CIO2_REG_IRQCTRL_LEVEL_NOT_PULSE	(CIO2_REG_IRQCTRL_BASE + 0x14)
+
+#define CIO2_REG_GPREG_SRST		(CIO2_REG_GPREG_BASE + 0x0)
+#define CIO2_GPREG_SRST_ALL				0xffff	/* Reset all */
+#define CIO2_REG_FB_HPLL_FREQ		(CIO2_REG_GPREG_BASE + 0x08)
+#define CIO2_REG_ISCLK_RATIO		(CIO2_REG_GPREG_BASE + 0xc)
+
+#define CIO2_REG_CGC					0x1400
+#define CIO2_CGC_CSI2_TGE				BIT(0)
+#define CIO2_CGC_PRIM_TGE				BIT(1)
+#define CIO2_CGC_SIDE_TGE				BIT(2)
+#define CIO2_CGC_XOSC_TGE				BIT(3)
+#define CIO2_CGC_MPLL_SHUTDOWN_EN			BIT(4)
+#define CIO2_CGC_D3I3_TGE				BIT(5)
+#define CIO2_CGC_CSI2_INTERFRAME_TGE			BIT(6)
+#define CIO2_CGC_CSI2_PORT_DCGE				BIT(8)
+#define CIO2_CGC_CSI2_DCGE				BIT(9)
+#define CIO2_CGC_SIDE_DCGE				BIT(10)
+#define CIO2_CGC_PRIM_DCGE				BIT(11)
+#define CIO2_CGC_ROSC_DCGE				BIT(12)
+#define CIO2_CGC_XOSC_DCGE				BIT(13)
+#define CIO2_CGC_FLIS_DCGE				BIT(14)
+#define CIO2_CGC_CLKGATE_HOLDOFF_SHIFT			20
+#define CIO2_CGC_CSI_CLKGATE_HOLDOFF_SHIFT		24
+#define CIO2_REG_D0I3C					0x1408
+#define CIO2_D0I3C_I3					BIT(2)	/* Set D0I3 */
+#define CIO2_D0I3C_RR					BIT(3)	/* Restore? */
+#define CIO2_REG_SWRESET				0x140c
+#define CIO2_SWRESET_SWRESET				1
+#define CIO2_REG_SENSOR_ACTIVE				0x1410
+#define CIO2_REG_INT_STS				0x1414
+#define CIO2_REG_INT_STS_EXT_OE				0x1418
+#define CIO2_INT_EXT_OE_DMAOE_SHIFT			0
+#define CIO2_INT_EXT_OE_DMAOE_MASK			0x7ffff
+#define CIO2_INT_EXT_OE_OES_SHIFT			24
+#define CIO2_INT_EXT_OE_OES_MASK	(0xf << CIO2_INT_EXT_OE_OES_SHIFT)
+#define CIO2_REG_INT_EN					0x1420
+#define CIO2_REG_INT_EN_IRQ				(1 << 24)
+#define CIO2_REG_INT_EN_IOS(dma)	(1 << (((dma) >> 1) + 12))
+/*
+ * Interrupt on completion bit, Eg. DMA 0-3 maps to bit 0-3,
+ * DMA4 & DMA5 map to bit 4 ... DMA18 & DMA19 map to bit 11 Et cetera
+ */
+#define CIO2_INT_IOC(dma)	(1 << ((dma) < 4 ? (dma) : ((dma) >> 1) + 2))
+#define CIO2_INT_IOC_SHIFT				0
+#define CIO2_INT_IOC_MASK		(0x7ff << CIO2_INT_IOC_SHIFT)
+#define CIO2_INT_IOS_IOLN(dma)		(1 << (((dma) >> 1) + 12))
+#define CIO2_INT_IOS_IOLN_SHIFT				12
+#define CIO2_INT_IOS_IOLN_MASK		(0x3ff << CIO2_INT_IOS_IOLN_SHIFT)
+#define CIO2_INT_IOIE					BIT(22)
+#define CIO2_INT_IOOE					BIT(23)
+#define CIO2_INT_IOIRQ					BIT(24)
+#define CIO2_REG_INT_EN_EXT_OE				0x1424
+#define CIO2_REG_DMA_DBG				0x1448
+#define CIO2_REG_DMA_DBG_DMA_INDEX_SHIFT		0
+#define CIO2_REG_PBM_ARB_CTRL				0x1460
+#define CIO2_PBM_ARB_CTRL_LANES_DIV			0 /* 4-4-2-2 lanes */
+#define CIO2_PBM_ARB_CTRL_LANES_DIV_SHIFT		0
+#define CIO2_PBM_ARB_CTRL_LE_EN				BIT(7)
+#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN		2
+#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN_SHIFT		8
+#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP			480
+#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP_SHIFT		16
+#define CIO2_REG_PBM_WMCTRL1				0x1464
+#define CIO2_PBM_WMCTRL1_MIN_2CK_SHIFT			0
+#define CIO2_PBM_WMCTRL1_MID1_2CK_SHIFT			8
+#define CIO2_PBM_WMCTRL1_MID2_2CK_SHIFT			16
+#define CIO2_PBM_WMCTRL1_TS_COUNT_DISABLE		BIT(31)
+#define CIO2_PBM_WMCTRL1_MIN_2CK	(4 << CIO2_PBM_WMCTRL1_MIN_2CK_SHIFT)
+#define CIO2_PBM_WMCTRL1_MID1_2CK	(16 << CIO2_PBM_WMCTRL1_MID1_2CK_SHIFT)
+#define CIO2_PBM_WMCTRL1_MID2_2CK	(21 << CIO2_PBM_WMCTRL1_MID2_2CK_SHIFT)
+#define CIO2_REG_PBM_WMCTRL2				0x1468
+#define CIO2_PBM_WMCTRL2_HWM_2CK			40
+#define CIO2_PBM_WMCTRL2_HWM_2CK_SHIFT			0
+#define CIO2_PBM_WMCTRL2_LWM_2CK			22
+#define CIO2_PBM_WMCTRL2_LWM_2CK_SHIFT			8
+#define CIO2_PBM_WMCTRL2_OBFFWM_2CK			2
+#define CIO2_PBM_WMCTRL2_OBFFWM_2CK_SHIFT		16
+#define CIO2_PBM_WMCTRL2_TRANSDYN			1
+#define CIO2_PBM_WMCTRL2_TRANSDYN_SHIFT			24
+#define CIO2_PBM_WMCTRL2_DYNWMEN			BIT(28)
+#define CIO2_PBM_WMCTRL2_OBFF_MEM_EN			BIT(29)
+#define CIO2_PBM_WMCTRL2_OBFF_CPU_EN			BIT(30)
+#define CIO2_PBM_WMCTRL2_DRAINNOW			BIT(31)
+#define CIO2_REG_PBM_TS_COUNT				0x146c
+#define CIO2_REG_PBM_FOPN_ABORT				0x1474
+/* below n = 0..3 */
+#define CIO2_PBM_FOPN_ABORT(n)				(0x1 << 8 * (n))
+#define CIO2_PBM_FOPN_FORCE_ABORT(n)			(0x2 << 8 * (n))
+#define CIO2_PBM_FOPN_FRAMEOPEN(n)			(0x8 << 8 * (n))
+#define CIO2_REG_LTRCTRL				0x1480
+#define CIO2_LTRCTRL_LTRDYNEN				BIT(16)
+#define CIO2_LTRCTRL_LTRSTABLETIME_SHIFT		8
+#define CIO2_LTRCTRL_LTRSTABLETIME_MASK			0xff
+#define CIO2_LTRCTRL_LTRSEL1S3				BIT(7)
+#define CIO2_LTRCTRL_LTRSEL1S2				BIT(6)
+#define CIO2_LTRCTRL_LTRSEL1S1				BIT(5)
+#define CIO2_LTRCTRL_LTRSEL1S0				BIT(4)
+#define CIO2_LTRCTRL_LTRSEL2S3				BIT(3)
+#define CIO2_LTRCTRL_LTRSEL2S2				BIT(2)
+#define CIO2_LTRCTRL_LTRSEL2S1				BIT(1)
+#define CIO2_LTRCTRL_LTRSEL2S0				BIT(0)
+#define CIO2_REG_LTRVAL23				0x1484
+#define CIO2_REG_LTRVAL01				0x1488
+#define CIO2_LTRVAL02_VAL_SHIFT				0
+#define CIO2_LTRVAL02_SCALE_SHIFT			10
+#define CIO2_LTRVAL13_VAL_SHIFT				16
+#define CIO2_LTRVAL13_SCALE_SHIFT			26
+
+#define CIO2_LTRVAL0_VAL				175
+/* Value times 1024 ns */
+#define CIO2_LTRVAL0_SCALE				2
+#define CIO2_LTRVAL1_VAL				90
+#define CIO2_LTRVAL1_SCALE				2
+#define CIO2_LTRVAL2_VAL				90
+#define CIO2_LTRVAL2_SCALE				2
+#define CIO2_LTRVAL3_VAL				90
+#define CIO2_LTRVAL3_SCALE				2
+
+#define CIO2_REG_CDMABA(n)		(0x1500 + 0x10 * (n))	/* n = 0..19 */
+#define CIO2_REG_CDMARI(n)		(0x1504 + 0x10 * (n))
+#define CIO2_CDMARI_FBPT_RP_SHIFT			0
+#define CIO2_CDMARI_FBPT_RP_MASK			0xff
+#define CIO2_REG_CDMAC0(n)		(0x1508 + 0x10 * (n))
+#define CIO2_CDMAC0_FBPT_LEN_SHIFT			0
+#define CIO2_CDMAC0_FBPT_WIDTH_SHIFT			8
+#define CIO2_CDMAC0_FBPT_NS				BIT(25)
+#define CIO2_CDMAC0_DMA_INTR_ON_FS			BIT(26)
+#define CIO2_CDMAC0_DMA_INTR_ON_FE			BIT(27)
+#define CIO2_CDMAC0_FBPT_UPDATE_FIFO_FULL		BIT(28)
+#define CIO2_CDMAC0_FBPT_FIFO_FULL_FIX_DIS		BIT(29)
+#define CIO2_CDMAC0_DMA_EN				BIT(30)
+#define CIO2_CDMAC0_DMA_HALTED				BIT(31)
+#define CIO2_REG_CDMAC1(n)		(0x150c + 0x10 * (n))
+#define CIO2_CDMAC1_LINENUMINT_SHIFT			0
+#define CIO2_CDMAC1_LINENUMUPDATE_SHIFT			16
+/* n = 0..3 */
+#define CIO2_REG_PXM_PXF_FMT_CFG0(n)	(0x1700 + 0x30 * (n))
+#define CIO2_PXM_PXF_FMT_CFG_SID0_SHIFT			0
+#define CIO2_PXM_PXF_FMT_CFG_SID1_SHIFT			16
+#define CIO2_PXM_PXF_FMT_CFG_PCK_64B			(0 << 0)
+#define CIO2_PXM_PXF_FMT_CFG_PCK_32B			(1 << 0)
+#define CIO2_PXM_PXF_FMT_CFG_BPP_08			(0 << 2)
+#define CIO2_PXM_PXF_FMT_CFG_BPP_10			(1 << 2)
+#define CIO2_PXM_PXF_FMT_CFG_BPP_12			(2 << 2)
+#define CIO2_PXM_PXF_FMT_CFG_BPP_14			(3 << 2)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_4PPC			(0 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_3PPC_RGBA		(1 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_3PPC_ARGB		(2 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_PLANAR2		(3 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_PLANAR3		(4 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_NV16			(5 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_PSWAP4_1ST_AB		(1 << 7)
+#define CIO2_PXM_PXF_FMT_CFG_PSWAP4_1ST_CD		(1 << 8)
+#define CIO2_PXM_PXF_FMT_CFG_PSWAP4_2ND_AC		(1 << 9)
+#define CIO2_PXM_PXF_FMT_CFG_PSWAP4_2ND_BD		(1 << 10)
+#define CIO2_REG_INT_STS_EXT_IE				0x17e4
+#define CIO2_REG_INT_EN_EXT_IE				0x17e8
+#define CIO2_INT_EXT_IE_ECC_RE(n)			(0x01 << (8 * (n)))
+#define CIO2_INT_EXT_IE_DPHY_NR(n)			(0x02 << (8 * (n)))
+#define CIO2_INT_EXT_IE_ECC_NR(n)			(0x04 << (8 * (n)))
+#define CIO2_INT_EXT_IE_CRCERR(n)			(0x08 << (8 * (n)))
+#define CIO2_INT_EXT_IE_INTERFRAMEDATA(n)		(0x10 << (8 * (n)))
+#define CIO2_INT_EXT_IE_PKT2SHORT(n)			(0x20 << (8 * (n)))
+#define CIO2_INT_EXT_IE_PKT2LONG(n)			(0x40 << (8 * (n)))
+#define CIO2_INT_EXT_IE_IRQ(n)				(0x80 << (8 * (n)))
+#define CIO2_REG_PXM_FRF_CFG(n)				(0x1720 + 0x30 * (n))
+#define CIO2_PXM_FRF_CFG_FNSEL				BIT(0)
+#define CIO2_PXM_FRF_CFG_FN_RST				BIT(1)
+#define CIO2_PXM_FRF_CFG_ABORT				BIT(2)
+#define CIO2_PXM_FRF_CFG_CRC_TH_SHIFT			3
+#define CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NR		BIT(8)
+#define CIO2_PXM_FRF_CFG_MSK_ECC_RE			BIT(9)
+#define CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NE		BIT(10)
+#define CIO2_PXM_FRF_CFG_EVEN_ODD_MODE_SHIFT		11
+#define CIO2_PXM_FRF_CFG_MASK_CRC_THRES			BIT(13)
+#define CIO2_PXM_FRF_CFG_MASK_CSI_ACCEPT		BIT(14)
+#define CIO2_PXM_FRF_CFG_CIOHC_FS_MODE			BIT(15)
+#define CIO2_PXM_FRF_CFG_CIOHC_FRST_FRM_SHIFT		16
+#define CIO2_REG_PXM_SID2BID0(n)			(0x1724 + 0x30 * (n))
+#define CIO2_FB_HPLL_FREQ				0x2
+#define CIO2_ISCLK_RATIO				0xc
+
+#define CIO2_IRQCTRL_MASK				0x3ffff
+
+#define CIO2_INT_EN_EXT_OE_MASK				0x8f0fffff
+
+#define CIO2_CGC_CLKGATE_HOLDOFF			3
+#define CIO2_CGC_CSI_CLKGATE_HOLDOFF			5
+
+#define CIO2_PXM_FRF_CFG_CRC_TH				16
+
+#define CIO2_INT_EN_EXT_IE_MASK				0xffffffff
+
+#define CIO2_DMA_CHAN					0
+
+#define CIO2_CSIRX_DLY_CNT_CLANE_IDX			-1
+
+#define CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_A		0
+#define CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_B		0
+#define CIO2_CSIRX_DLY_CNT_SETTLE_CLANE_A		95
+#define CIO2_CSIRX_DLY_CNT_SETTLE_CLANE_B		-8
+
+#define CIO2_CSIRX_DLY_CNT_TERMEN_DLANE_A		0
+#define CIO2_CSIRX_DLY_CNT_TERMEN_DLANE_B		0
+#define CIO2_CSIRX_DLY_CNT_SETTLE_DLANE_A		85
+#define CIO2_CSIRX_DLY_CNT_SETTLE_DLANE_B		-2
+
+#define CIO2_CSIRX_DLY_CNT_TERMEN_DEFAULT		0x4
+#define CIO2_CSIRX_DLY_CNT_SETTLE_DEFAULT		0x570
+
+#define CIO2_PMCSR_OFFSET				4
+#define CIO2_PMCSR_D0D3_SHIFT				2
+#define CIO2_PMCSR_D3					0x3
+
+struct cio2_csi2_timing {
+	s32 clk_termen;
+	s32 clk_settle;
+	s32 dat_termen;
+	s32 dat_settle;
+};
+
+struct cio2_buffer {
+	struct vb2_v4l2_buffer vbb;
+	u32 *lop[CIO2_MAX_LOPS];
+	dma_addr_t lop_bus_addr[CIO2_MAX_LOPS];
+	unsigned int offset;
+};
+
+struct csi2_bus_info {
+	u32 port;
+	u32 lanes;
+};
+
+struct cio2_queue {
+	/* mutex to be used by vb2_queue */
+	struct mutex lock;
+	struct media_pipeline pipe;
+	struct csi2_bus_info csi2;
+	struct v4l2_subdev *sensor;
+	void __iomem *csi_rx_base;
+
+	/* Subdev, /dev/v4l-subdevX */
+	struct v4l2_subdev subdev;
+	struct media_pad subdev_pads[CIO2_PADS];
+	struct v4l2_mbus_framefmt subdev_fmt;
+	atomic_t frame_sequence;
+
+	/* Video device, /dev/videoX */
+	struct video_device vdev;
+	struct media_pad vdev_pad;
+	struct v4l2_pix_format_mplane format;
+	struct vb2_queue vbq;
+
+	/* Buffer queue handling */
+	struct cio2_fbpt_entry *fbpt;	/* Frame buffer pointer table */
+	dma_addr_t fbpt_bus_addr;
+	struct cio2_buffer *bufs[CIO2_MAX_BUFFERS];
+	unsigned int bufs_first;	/* Index of the first used entry */
+	unsigned int bufs_next;	/* Index of the first unused entry */
+	atomic_t bufs_queued;
+};
+
+struct cio2_device {
+	struct pci_dev *pci_dev;
+	void __iomem *base;
+	struct v4l2_device v4l2_dev;
+	struct cio2_queue queue[CIO2_QUEUES];
+	struct cio2_queue *cur_queue;
+	/* mutex to be used by video_device */
+	struct mutex lock;
+
+	bool streaming;
+	struct v4l2_async_notifier notifier;
+	struct media_device media_dev;
+
+	/*
+	 * Safety net to catch DMA fetch ahead
+	 * when reaching the end of LOP
+	 */
+	void *dummy_page;
+	/* DMA handle of dummy_page */
+	dma_addr_t dummy_page_bus_addr;
+	/* single List of Pointers (LOP) page */
+	u32 *dummy_lop;
+	/* DMA handle of dummy_lop */
+	dma_addr_t dummy_lop_bus_addr;
+};
+
+/**************** Virtual channel ****************/
+/*
+ * This should come from sensor driver. No
+ * driver interface nor requirement yet.
+ */
+#define SENSOR_VIR_CH_DFLT		0
+
+/**************** FBPT operations ****************/
+#define CIO2_FBPT_SIZE			(CIO2_MAX_BUFFERS * CIO2_MAX_LOPS * \
+					 sizeof(struct cio2_fbpt_entry))
+
+#define CIO2_FBPT_SUBENTRY_UNIT		4
+#define CIO2_PAGE_SIZE			4096
+
+/* cio2 fbpt first_entry ctrl status */
+#define CIO2_FBPT_CTRL_VALID		BIT(0)
+#define CIO2_FBPT_CTRL_IOC		BIT(1)
+#define CIO2_FBPT_CTRL_IOS		BIT(2)
+#define CIO2_FBPT_CTRL_SUCCXFAIL	BIT(3)
+#define CIO2_FBPT_CTRL_CMPLCODE_SHIFT	4
+
+/*
+ * Frame Buffer Pointer Table(FBPT) entry
+ * each entry describe an output buffer and consists of
+ * several sub-entries
+ */
+struct __packed cio2_fbpt_entry {
+	union {
+		struct __packed {
+			u32 ctrl; /* status ctrl */
+			u16 cur_line_num; /* current line # written to DDR */
+			u16 frame_num; /* updated by DMA upon FE */
+			u32 first_page_offset; /* offset for 1st page in LOP */
+		} first_entry;
+		/* Second entry per buffer */
+		struct __packed {
+			u32 timestamp;
+			u32 num_of_bytes;
+			/* the number of bytes for write on last page */
+			u16 last_page_available_bytes;
+			/* the number of pages allocated for this buf */
+			u16 num_of_pages;
+		} second_entry;
+	};
+	u32 lop_page_addr;	/* Points to list of pointers (LOP) table */
+};
+
+static inline struct cio2_queue *file_to_cio2_queue(struct file *file)
+{
+	return container_of(video_devdata(file), struct cio2_queue, vdev);
+}
+
+static inline struct cio2_queue *vb2q_to_cio2_queue(struct vb2_queue *vq)
+{
+	return container_of(vq, struct cio2_queue, vbq);
+}
+
+#endif
diff --git a/drivers/media/pci/ivtv/Makefile b/drivers/media/pci/ivtv/Makefile
index 48f8a23..5de95db 100644
--- a/drivers/media/pci/ivtv/Makefile
+++ b/drivers/media/pci/ivtv/Makefile
@@ -10,8 +10,6 @@
 obj-$(CONFIG_VIDEO_IVTV_ALSA) += ivtv-alsa.o
 obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o
 
-ccflags-y += -I$(srctree)/drivers/media/i2c
 ccflags-y += -I$(srctree)/drivers/media/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 
diff --git a/drivers/media/pci/ivtv/ivtv-cards.c b/drivers/media/pci/ivtv/ivtv-cards.c
index 410d97b..c637929 100644
--- a/drivers/media/pci/ivtv/ivtv-cards.c
+++ b/drivers/media/pci/ivtv/ivtv-cards.c
@@ -65,7 +65,7 @@ static struct ivtv_card_tuner_i2c ivtv_i2c_tda8290 = {
 
 /********************** card configuration *******************************/
 
-/* Please add new PCI IDs to: http://pci-ids.ucw.cz/ 
+/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
    This keeps the PCI ID database up to date. Note that the entries
    must be added under vendor 0x4444 (Conexant) as subsystem IDs.
    New vendor IDs should still be added to the vendor ID list. */
diff --git a/drivers/media/pci/ivtv/ivtv-cards.h b/drivers/media/pci/ivtv/ivtv-cards.h
index e6f5c02..1557a6e 100644
--- a/drivers/media/pci/ivtv/ivtv-cards.h
+++ b/drivers/media/pci/ivtv/ivtv-cards.h
@@ -22,26 +22,26 @@
 #define IVTV_CARDS_H
 
 /* Supported cards */
-#define IVTV_CARD_PVR_250 	      0	/* WinTV PVR 250 */
-#define IVTV_CARD_PVR_350 	      1	/* encoder, decoder, tv-out */
-#define IVTV_CARD_PVR_150 	      2	/* WinTV PVR 150 and PVR 500 (really just two
+#define IVTV_CARD_PVR_250	      0	/* WinTV PVR 250 */
+#define IVTV_CARD_PVR_350	      1	/* encoder, decoder, tv-out */
+#define IVTV_CARD_PVR_150	      2	/* WinTV PVR 150 and PVR 500 (really just two
 					   PVR150s on one PCI board) */
-#define IVTV_CARD_M179    	      3	/* AVerMedia M179 (encoder only) */
-#define IVTV_CARD_MPG600  	      4	/* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */
-#define IVTV_CARD_MPG160  	      5	/* Kuroutoshikou ITVC15-STVLP/YUAN MPG160
+#define IVTV_CARD_M179		      3	/* AVerMedia M179 (encoder only) */
+#define IVTV_CARD_MPG600	      4	/* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */
+#define IVTV_CARD_MPG160	      5	/* Kuroutoshikou ITVC15-STVLP/YUAN MPG160
 					   cx23415 based, but does not have tv-out */
-#define IVTV_CARD_PG600 	      6	/* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */
-#define IVTV_CARD_AVC2410 	      7	/* Adaptec AVC-2410 */
-#define IVTV_CARD_AVC2010 	      8	/* Adaptec AVD-2010 (No Tuner) */
-#define IVTV_CARD_TG5000TV   	      9 /* NAGASE TRANSGEAR 5000TV, encoder only */
+#define IVTV_CARD_PG600		      6	/* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */
+#define IVTV_CARD_AVC2410	      7	/* Adaptec AVC-2410 */
+#define IVTV_CARD_AVC2010	      8	/* Adaptec AVD-2010 (No Tuner) */
+#define IVTV_CARD_TG5000TV	      9 /* NAGASE TRANSGEAR 5000TV, encoder only */
 #define IVTV_CARD_VA2000MAX_SNT6     10 /* VA2000MAX-STN6 */
-#define IVTV_CARD_CX23416GYC 	     11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
-#define IVTV_CARD_GV_MVPRX   	     12 /* I/O Data GV-MVP/RX, RX2, RX2W */
-#define IVTV_CARD_GV_MVPRX2E 	     13 /* I/O Data GV-MVP/RX2E */
+#define IVTV_CARD_CX23416GYC	     11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
+#define IVTV_CARD_GV_MVPRX	     12 /* I/O Data GV-MVP/RX, RX2, RX2W */
+#define IVTV_CARD_GV_MVPRX2E	     13 /* I/O Data GV-MVP/RX2E */
 #define IVTV_CARD_GOTVIEW_PCI_DVD    14	/* GotView PCI DVD */
 #define IVTV_CARD_GOTVIEW_PCI_DVD2   15	/* GotView PCI DVD2 */
 #define IVTV_CARD_YUAN_MPC622        16	/* Yuan MPC622 miniPCI */
-#define IVTV_CARD_DCTMTVP1 	     17 /* DIGITAL COWBOY DCT-MTVP1 */
+#define IVTV_CARD_DCTMTVP1	     17 /* DIGITAL COWBOY DCT-MTVP1 */
 #define IVTV_CARD_PG600V2	     18 /* Yuan PG600V2/GotView PCI DVD Lite */
 #define IVTV_CARD_CLUB3D	     19 /* Club3D ZAP-TV1x01 */
 #define IVTV_CARD_AVERTV_MCE116	     20 /* AVerTV MCE 116 Plus */
@@ -52,7 +52,7 @@
 #define IVTV_CARD_BUFFALO_MV5L       25 /* Buffalo PC-MV5L/PCI card */
 #define IVTV_CARD_AVER_ULTRA1500MCE  26 /* AVerMedia UltraTV 1500 MCE */
 #define IVTV_CARD_KIKYOU             27 /* Sony VAIO Giga Pocket (ENX Kikyou) */
-#define IVTV_CARD_LAST 		     27
+#define IVTV_CARD_LAST		     27
 
 /* Variants of existing cards but with the same PCI IDs. The driver
    detects these based on other device information.
@@ -61,7 +61,7 @@
    must be adjusted accordingly. */
 
 /* PVR-350 V1 (uses saa7114) */
-#define IVTV_CARD_PVR_350_V1 	     (IVTV_CARD_LAST+1)
+#define IVTV_CARD_PVR_350_V1	     (IVTV_CARD_LAST+1)
 /* 2 variants of Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
 #define IVTV_CARD_CX23416GYC_NOGR    (IVTV_CARD_LAST+2)
 #define IVTV_CARD_CX23416GYC_NOGRYCS (IVTV_CARD_LAST+3)
@@ -72,22 +72,22 @@
 #define PCI_DEVICE_ID_IVTV16 0x0016
 
 /* subsystem vendor ID */
-#define IVTV_PCI_ID_HAUPPAUGE 		0x0070
-#define IVTV_PCI_ID_HAUPPAUGE_ALT1 	0x0270
-#define IVTV_PCI_ID_HAUPPAUGE_ALT2 	0x4070
-#define IVTV_PCI_ID_ADAPTEC 		0x9005
-#define IVTV_PCI_ID_ASUSTEK 		0x1043
-#define IVTV_PCI_ID_AVERMEDIA 		0x1461
+#define IVTV_PCI_ID_HAUPPAUGE		0x0070
+#define IVTV_PCI_ID_HAUPPAUGE_ALT1	0x0270
+#define IVTV_PCI_ID_HAUPPAUGE_ALT2	0x4070
+#define IVTV_PCI_ID_ADAPTEC		0x9005
+#define IVTV_PCI_ID_ASUSTEK		0x1043
+#define IVTV_PCI_ID_AVERMEDIA		0x1461
 #define IVTV_PCI_ID_YUAN1		0x12ab
-#define IVTV_PCI_ID_YUAN2 		0xff01
-#define IVTV_PCI_ID_YUAN3 		0xffab
-#define IVTV_PCI_ID_YUAN4 		0xfbab
-#define IVTV_PCI_ID_DIAMONDMM 		0xff92
-#define IVTV_PCI_ID_IODATA 		0x10fc
-#define IVTV_PCI_ID_MELCO 		0x1154
+#define IVTV_PCI_ID_YUAN2		0xff01
+#define IVTV_PCI_ID_YUAN3		0xffab
+#define IVTV_PCI_ID_YUAN4		0xfbab
+#define IVTV_PCI_ID_DIAMONDMM		0xff92
+#define IVTV_PCI_ID_IODATA		0x10fc
+#define IVTV_PCI_ID_MELCO		0x1154
 #define IVTV_PCI_ID_GOTVIEW1		0xffac
-#define IVTV_PCI_ID_GOTVIEW2 		0xffad
-#define IVTV_PCI_ID_SONY 		0x104d
+#define IVTV_PCI_ID_GOTVIEW2		0xffad
+#define IVTV_PCI_ID_SONY		0x104d
 
 /* hardware flags, no gaps allowed */
 #define IVTV_HW_CX25840			(1 << 0)
@@ -109,41 +109,33 @@
 #define IVTV_HW_I2C_IR_RX_AVER		(1 << 16)
 #define IVTV_HW_I2C_IR_RX_HAUP_EXT	(1 << 17) /* External before internal */
 #define IVTV_HW_I2C_IR_RX_HAUP_INT	(1 << 18)
-#define IVTV_HW_Z8F0811_IR_TX_HAUP	(1 << 19)
-#define IVTV_HW_Z8F0811_IR_RX_HAUP	(1 << 20)
-#define IVTV_HW_I2C_IR_RX_ADAPTEC	(1 << 21)
-
-#define IVTV_HW_Z8F0811_IR_HAUP	(IVTV_HW_Z8F0811_IR_RX_HAUP | \
-				 IVTV_HW_Z8F0811_IR_TX_HAUP)
+#define IVTV_HW_Z8F0811_IR_HAUP		(1 << 19)
+#define IVTV_HW_I2C_IR_RX_ADAPTEC	(1 << 20)
 
 #define IVTV_HW_SAA711X   (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
 
-#define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \
-			   IVTV_HW_I2C_IR_RX_HAUP_EXT | \
-			   IVTV_HW_I2C_IR_RX_HAUP_INT | \
-			   IVTV_HW_Z8F0811_IR_RX_HAUP | \
-			   IVTV_HW_I2C_IR_RX_ADAPTEC)
-
-#define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP)
-
-#define IVTV_HW_IR_ANY	  (IVTV_HW_IR_RX_ANY | IVTV_HW_IR_TX_ANY)
+#define IVTV_HW_IR_ANY (IVTV_HW_I2C_IR_RX_AVER | \
+			IVTV_HW_I2C_IR_RX_HAUP_EXT | \
+			IVTV_HW_I2C_IR_RX_HAUP_INT | \
+			IVTV_HW_Z8F0811_IR_HAUP | \
+			IVTV_HW_I2C_IR_RX_ADAPTEC)
 
 /* video inputs */
 #define	IVTV_CARD_INPUT_VID_TUNER	1
-#define	IVTV_CARD_INPUT_SVIDEO1 	2
-#define	IVTV_CARD_INPUT_SVIDEO2 	3
-#define	IVTV_CARD_INPUT_COMPOSITE1 	4
-#define	IVTV_CARD_INPUT_COMPOSITE2 	5
-#define	IVTV_CARD_INPUT_COMPOSITE3 	6
+#define	IVTV_CARD_INPUT_SVIDEO1		2
+#define	IVTV_CARD_INPUT_SVIDEO2		3
+#define	IVTV_CARD_INPUT_COMPOSITE1	4
+#define	IVTV_CARD_INPUT_COMPOSITE2	5
+#define	IVTV_CARD_INPUT_COMPOSITE3	6
 
 /* audio inputs */
 #define	IVTV_CARD_INPUT_AUD_TUNER	1
-#define	IVTV_CARD_INPUT_LINE_IN1 	2
-#define	IVTV_CARD_INPUT_LINE_IN2 	3
+#define	IVTV_CARD_INPUT_LINE_IN1	2
+#define	IVTV_CARD_INPUT_LINE_IN2	3
 
 #define IVTV_CARD_MAX_VIDEO_INPUTS 6
 #define IVTV_CARD_MAX_AUDIO_INPUTS 3
-#define IVTV_CARD_MAX_TUNERS  	   3
+#define IVTV_CARD_MAX_TUNERS	   3
 
 /* SAA71XX HW inputs */
 #define IVTV_SAA71XX_COMPOSITE0 0
@@ -180,7 +172,7 @@
 			  V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
 
 struct ivtv_card_video_input {
-	u8  video_type; 	/* video input type */
+	u8  video_type;		/* video input type */
 	u8  audio_index;	/* index in ivtv_card_audio_input array */
 	u16 video_input;	/* hardware video input */
 };
@@ -207,55 +199,55 @@ struct ivtv_card_pci_info {
 
 /* The mask is the set of bits used by the operation */
 
-struct ivtv_gpio_init { 	/* set initial GPIO DIR and OUT values */
-	u16 direction; 		/* DIR setting. Leave to 0 if no init is needed */
+struct ivtv_gpio_init {		/* set initial GPIO DIR and OUT values */
+	u16 direction;		/* DIR setting. Leave to 0 if no init is needed */
 	u16 initial_value;
 };
 
-struct ivtv_gpio_video_input { 	/* select tuner/line in input */
-	u16 mask; 		/* leave to 0 if not supported */
+struct ivtv_gpio_video_input {	/* select tuner/line in input */
+	u16 mask;		/* leave to 0 if not supported */
 	u16 tuner;
 	u16 composite;
 	u16 svideo;
 };
 
-struct ivtv_gpio_audio_input { 	/* select tuner/line in input */
-	u16 mask; 		/* leave to 0 if not supported */
+struct ivtv_gpio_audio_input {	/* select tuner/line in input */
+	u16 mask;		/* leave to 0 if not supported */
 	u16 tuner;
 	u16 linein;
 	u16 radio;
 };
 
 struct ivtv_gpio_audio_mute {
-	u16 mask; 		/* leave to 0 if not supported */
+	u16 mask;		/* leave to 0 if not supported */
 	u16 mute;		/* set this value to mute, 0 to unmute */
 };
 
 struct ivtv_gpio_audio_mode {
-	u16 mask; 		/* leave to 0 if not supported */
-	u16 mono; 		/* set audio to mono */
-	u16 stereo; 		/* set audio to stereo */
+	u16 mask;		/* leave to 0 if not supported */
+	u16 mono;		/* set audio to mono */
+	u16 stereo;		/* set audio to stereo */
 	u16 lang1;		/* set audio to the first language */
 	u16 lang2;		/* set audio to the second language */
-	u16 both; 		/* both languages are output */
+	u16 both;		/* both languages are output */
 };
 
 struct ivtv_gpio_audio_freq {
-	u16 mask; 		/* leave to 0 if not supported */
+	u16 mask;		/* leave to 0 if not supported */
 	u16 f32000;
 	u16 f44100;
 	u16 f48000;
 };
 
 struct ivtv_gpio_audio_detect {
-	u16 mask; 		/* leave to 0 if not supported */
-	u16 stereo; 		/* if the input matches this value then
+	u16 mask;		/* leave to 0 if not supported */
+	u16 stereo;		/* if the input matches this value then
 				   stereo is detected */
 };
 
 struct ivtv_card_tuner {
-	v4l2_std_id std; 	/* standard for which the tuner is suitable */
-	int 	    tuner; 	/* tuner ID (from tuner.h) */
+	v4l2_std_id std;	/* standard for which the tuner is suitable */
+	int	    tuner;	/* tuner ID (from tuner.h) */
 };
 
 struct ivtv_card_tuner_i2c {
@@ -280,17 +272,17 @@ struct ivtv_card {
 	struct ivtv_card_audio_input radio_input;
 	int nof_outputs;
 	const struct ivtv_card_output *video_outputs;
-	u8 gr_config; 		/* config byte for the ghost reduction device */
-	u8 xceive_pin; 		/* XCeive tuner GPIO reset pin */
+	u8 gr_config;		/* config byte for the ghost reduction device */
+	u8 xceive_pin;		/* XCeive tuner GPIO reset pin */
 
 	/* GPIO card-specific settings */
-	struct ivtv_gpio_init 		gpio_init;
+	struct ivtv_gpio_init		gpio_init;
 	struct ivtv_gpio_video_input	gpio_video_input;
-	struct ivtv_gpio_audio_input 	gpio_audio_input;
-	struct ivtv_gpio_audio_mute 	gpio_audio_mute;
-	struct ivtv_gpio_audio_mode 	gpio_audio_mode;
-	struct ivtv_gpio_audio_freq 	gpio_audio_freq;
-	struct ivtv_gpio_audio_detect 	gpio_audio_detect;
+	struct ivtv_gpio_audio_input	gpio_audio_input;
+	struct ivtv_gpio_audio_mute	gpio_audio_mute;
+	struct ivtv_gpio_audio_mode	gpio_audio_mode;
+	struct ivtv_gpio_audio_freq	gpio_audio_freq;
+	struct ivtv_gpio_audio_detect	gpio_audio_detect;
 
 	struct ivtv_card_tuner tuners[IVTV_CARD_MAX_TUNERS];
 	struct ivtv_card_tuner_i2c *i2c;
diff --git a/drivers/media/pci/ivtv/ivtv-driver.h b/drivers/media/pci/ivtv/ivtv-driver.h
index d27c5c2..cafba6b 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.h
+++ b/drivers/media/pci/ivtv/ivtv-driver.h
@@ -76,7 +76,7 @@
 #define IVTV_ENCODER_SIZE	0x00800000	/* Total size is 0x01000000, but only first half is used */
 #define IVTV_DECODER_OFFSET	0x01000000
 #define IVTV_DECODER_SIZE	0x00800000	/* Total size is 0x01000000, but only first half is used */
-#define IVTV_REG_OFFSET 	0x02000000
+#define IVTV_REG_OFFSET		0x02000000
 #define IVTV_REG_SIZE		0x00010000
 
 /* Maximum ivtv driver instances. Some people have a huge number of
@@ -97,26 +97,26 @@
 #define IVTV_DMA_SG_OSD_ENT	(2883584/PAGE_SIZE)	/* sg entities */
 
 /* DMA Registers */
-#define IVTV_REG_DMAXFER 	(0x0000)
-#define IVTV_REG_DMASTATUS 	(0x0004)
-#define IVTV_REG_DECDMAADDR 	(0x0008)
-#define IVTV_REG_ENCDMAADDR 	(0x000c)
-#define IVTV_REG_DMACONTROL 	(0x0010)
-#define IVTV_REG_IRQSTATUS 	(0x0040)
-#define IVTV_REG_IRQMASK 	(0x0048)
+#define IVTV_REG_DMAXFER	(0x0000)
+#define IVTV_REG_DMASTATUS	(0x0004)
+#define IVTV_REG_DECDMAADDR	(0x0008)
+#define IVTV_REG_ENCDMAADDR	(0x000c)
+#define IVTV_REG_DMACONTROL	(0x0010)
+#define IVTV_REG_IRQSTATUS	(0x0040)
+#define IVTV_REG_IRQMASK	(0x0048)
 
 /* Setup Registers */
-#define IVTV_REG_ENC_SDRAM_REFRESH 	(0x07F8)
-#define IVTV_REG_ENC_SDRAM_PRECHARGE 	(0x07FC)
-#define IVTV_REG_DEC_SDRAM_REFRESH 	(0x08F8)
-#define IVTV_REG_DEC_SDRAM_PRECHARGE 	(0x08FC)
-#define IVTV_REG_VDM 			(0x2800)
-#define IVTV_REG_AO 			(0x2D00)
-#define IVTV_REG_BYTEFLUSH 		(0x2D24)
-#define IVTV_REG_SPU 			(0x9050)
-#define IVTV_REG_HW_BLOCKS 		(0x9054)
-#define IVTV_REG_VPU 			(0x9058)
-#define IVTV_REG_APU 			(0xA064)
+#define IVTV_REG_ENC_SDRAM_REFRESH	(0x07F8)
+#define IVTV_REG_ENC_SDRAM_PRECHARGE	(0x07FC)
+#define IVTV_REG_DEC_SDRAM_REFRESH	(0x08F8)
+#define IVTV_REG_DEC_SDRAM_PRECHARGE	(0x08FC)
+#define IVTV_REG_VDM			(0x2800)
+#define IVTV_REG_AO			(0x2D00)
+#define IVTV_REG_BYTEFLUSH		(0x2D24)
+#define IVTV_REG_SPU			(0x9050)
+#define IVTV_REG_HW_BLOCKS		(0x9054)
+#define IVTV_REG_VPU			(0x9058)
+#define IVTV_REG_APU			(0xA064)
 
 /* Other registers */
 #define IVTV_REG_DEC_LINE_FIELD		(0x28C0)
@@ -158,7 +158,7 @@ extern int ivtv_fw_debug;
 
 #define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
 	do { \
-		if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) 	\
+		if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL))	\
 			v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args);	\
 	} while (0)
 #define IVTV_DEBUG_HI_WARN(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN,  "warn",  fmt , ## args)
@@ -226,9 +226,9 @@ struct ivtv_mailbox_data {
 /* per-stream, s_flags */
 #define IVTV_F_S_DMA_PENDING	0	/* this stream has pending DMA */
 #define IVTV_F_S_DMA_HAS_VBI	1       /* the current DMA request also requests VBI data */
-#define IVTV_F_S_NEEDS_DATA	2 	/* this decoding stream needs more data */
+#define IVTV_F_S_NEEDS_DATA	2	/* this decoding stream needs more data */
 
-#define IVTV_F_S_CLAIMED 	3	/* this stream is claimed */
+#define IVTV_F_S_CLAIMED	3	/* this stream is claimed */
 #define IVTV_F_S_STREAMING      4	/* the fw is decoding/encoding this stream */
 #define IVTV_F_S_INTERNAL_USE	5	/* this stream is used internally (sliced VBI processing) */
 #define IVTV_F_S_PASSTHROUGH	6	/* this stream is in passthrough mode */
@@ -239,35 +239,35 @@ struct ivtv_mailbox_data {
 #define IVTV_F_S_PIO_HAS_VBI	1       /* the current PIO request also requests VBI data */
 
 /* per-ivtv, i_flags */
-#define IVTV_F_I_DMA		   0 	/* DMA in progress */
-#define IVTV_F_I_UDMA		   1 	/* UDMA in progress */
-#define IVTV_F_I_UDMA_PENDING	   2 	/* UDMA pending */
-#define IVTV_F_I_SPEED_CHANGE	   3 	/* a speed change is in progress */
-#define IVTV_F_I_EOS		   4 	/* end of encoder stream reached */
-#define IVTV_F_I_RADIO_USER	   5 	/* the radio tuner is selected */
-#define IVTV_F_I_DIG_RST	   6 	/* reset digitizer */
-#define IVTV_F_I_DEC_YUV	   7 	/* YUV instead of MPG is being decoded */
-#define IVTV_F_I_UPDATE_CC	   9  	/* CC should be updated */
-#define IVTV_F_I_UPDATE_WSS	   10 	/* WSS should be updated */
-#define IVTV_F_I_UPDATE_VPS	   11 	/* VPS should be updated */
-#define IVTV_F_I_DECODING_YUV	   12 	/* this stream is YUV frame decoding */
-#define IVTV_F_I_ENC_PAUSED	   13 	/* the encoder is paused */
-#define IVTV_F_I_VALID_DEC_TIMINGS 14 	/* last_dec_timing is valid */
-#define IVTV_F_I_HAVE_WORK  	   15	/* used in the interrupt handler: there is work to be done */
+#define IVTV_F_I_DMA		   0	/* DMA in progress */
+#define IVTV_F_I_UDMA		   1	/* UDMA in progress */
+#define IVTV_F_I_UDMA_PENDING	   2	/* UDMA pending */
+#define IVTV_F_I_SPEED_CHANGE	   3	/* a speed change is in progress */
+#define IVTV_F_I_EOS		   4	/* end of encoder stream reached */
+#define IVTV_F_I_RADIO_USER	   5	/* the radio tuner is selected */
+#define IVTV_F_I_DIG_RST	   6	/* reset digitizer */
+#define IVTV_F_I_DEC_YUV	   7	/* YUV instead of MPG is being decoded */
+#define IVTV_F_I_UPDATE_CC	   9	/* CC should be updated */
+#define IVTV_F_I_UPDATE_WSS	   10	/* WSS should be updated */
+#define IVTV_F_I_UPDATE_VPS	   11	/* VPS should be updated */
+#define IVTV_F_I_DECODING_YUV	   12	/* this stream is YUV frame decoding */
+#define IVTV_F_I_ENC_PAUSED	   13	/* the encoder is paused */
+#define IVTV_F_I_VALID_DEC_TIMINGS 14	/* last_dec_timing is valid */
+#define IVTV_F_I_HAVE_WORK	   15	/* used in the interrupt handler: there is work to be done */
 #define IVTV_F_I_WORK_HANDLER_VBI  16	/* there is work to be done for VBI */
 #define IVTV_F_I_WORK_HANDLER_YUV  17	/* there is work to be done for YUV */
 #define IVTV_F_I_WORK_HANDLER_PIO  18	/* there is work to be done for PIO */
 #define IVTV_F_I_PIO		   19	/* PIO in progress */
-#define IVTV_F_I_DEC_PAUSED	   20 	/* the decoder is paused */
-#define IVTV_F_I_INITED		   21 	/* set after first open */
-#define IVTV_F_I_FAILED		   22 	/* set if first open failed */
+#define IVTV_F_I_DEC_PAUSED	   20	/* the decoder is paused */
+#define IVTV_F_I_INITED		   21	/* set after first open */
+#define IVTV_F_I_FAILED		   22	/* set if first open failed */
 #define IVTV_F_I_WORK_HANDLER_PCM  23	/* there is work to be done for PCM */
 
 /* Event notifications */
 #define IVTV_F_I_EV_DEC_STOPPED	   28	/* decoder stopped event */
-#define IVTV_F_I_EV_VSYNC	   29 	/* VSYNC event */
-#define IVTV_F_I_EV_VSYNC_FIELD    30 	/* VSYNC event field (0 = first, 1 = second field) */
-#define IVTV_F_I_EV_VSYNC_ENABLED  31 	/* VSYNC event enabled */
+#define IVTV_F_I_EV_VSYNC	   29	/* VSYNC event */
+#define IVTV_F_I_EV_VSYNC_FIELD    30	/* VSYNC event field (0 = first, 1 = second field) */
+#define IVTV_F_I_EV_VSYNC_ENABLED  31	/* VSYNC event enabled */
 
 /* Scatter-Gather array element, used in DMA transfers */
 struct ivtv_sg_element {
@@ -330,13 +330,13 @@ struct ivtv_stream {
 	/* These first four fields are always set, even if the stream
 	   is not actually created. */
 	struct video_device vdev;	/* vdev.v4l2_dev is NULL if there is no device */
-	struct ivtv *itv; 		/* for ease of use */
+	struct ivtv *itv;		/* for ease of use */
 	const char *name;		/* name of the stream */
 	int type;			/* stream type */
 	u32 caps;			/* V4L2 capabilities */
 
 	struct v4l2_fh *fh;		/* pointer to the streaming filehandle */
-	spinlock_t qlock; 		/* locks access to the queues */
+	spinlock_t qlock;		/* locks access to the queues */
 	unsigned long s_flags;		/* status flags, see above */
 	int dma;			/* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */
 	u32 pending_offset;
@@ -564,7 +564,7 @@ struct vbi_info {
 
 	/* Raw VBI compatibility hack */
 
-	u32 frame; 				/* frame counter hack needed for backwards compatibility
+	u32 frame;				/* frame counter hack needed for backwards compatibility
 						   of old VBI software */
 
 	/* Sliced VBI output data */
@@ -620,7 +620,7 @@ struct ivtv {
 	u8 nof_inputs;			/* number of video inputs */
 	u8 nof_audio_inputs;		/* number of audio inputs */
 	u32 v4l2_cap;			/* V4L2 capabilities of card */
-	u32 hw_flags; 			/* hardware description of the board */
+	u32 hw_flags;			/* hardware description of the board */
 	v4l2_std_id tuner_std;		/* the norm of the card's tuner (fixed) */
 	struct v4l2_subdev *sd_video;	/* controlling video decoder subdev */
 	struct v4l2_subdev *sd_audio;	/* controlling audio subdev */
@@ -629,7 +629,7 @@ struct ivtv {
 	volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */
 	volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */
 	volatile void __iomem *reg_mem; /* pointer to mapped registers */
-	struct ivtv_options options; 	/* user options */
+	struct ivtv_options options;	/* user options */
 
 	struct v4l2_device v4l2_dev;
 	struct cx2341x_handler cxhdl;
@@ -668,7 +668,7 @@ struct ivtv {
 
 	/* Streams */
 	int stream_buf_size[IVTV_MAX_STREAMS];          /* stream buffer size */
-	struct ivtv_stream streams[IVTV_MAX_STREAMS]; 	/* stream data */
+	struct ivtv_stream streams[IVTV_MAX_STREAMS];	/* stream data */
 	atomic_t capturing;		/* count number of active capture streams */
 	atomic_t decoding;		/* count number of active decoding streams */
 
@@ -704,7 +704,7 @@ struct ivtv {
 	/* Mailbox */
 	struct ivtv_mailbox_data enc_mbox;              /* encoder mailboxes */
 	struct ivtv_mailbox_data dec_mbox;              /* decoder mailboxes */
-	struct ivtv_api_cache api_cache[256]; 		/* cached API commands */
+	struct ivtv_api_cache api_cache[256];		/* cached API commands */
 
 
 	/* I2C */
@@ -828,7 +828,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv)
 
 /* Call the specified callback for all subdevs matching hw (if 0, then
    match them all). Ignore any errors. */
-#define ivtv_call_hw(itv, hw, o, f, args...) 				\
+#define ivtv_call_hw(itv, hw, o, f, args...)				\
 	v4l2_device_mask_call_all(&(itv)->v4l2_dev, hw, o, f, ##args)
 
 #define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args)
diff --git a/drivers/media/pci/ivtv/ivtv-firmware.c b/drivers/media/pci/ivtv/ivtv-firmware.c
index ba279fd..9f05472f 100644
--- a/drivers/media/pci/ivtv/ivtv-firmware.c
+++ b/drivers/media/pci/ivtv/ivtv-firmware.c
@@ -28,26 +28,26 @@
 #include <linux/firmware.h>
 #include <media/i2c/saa7127.h>
 
-#define IVTV_MASK_SPU_ENABLE 		0xFFFFFFFE
-#define IVTV_MASK_VPU_ENABLE15 		0xFFFFFFF6
-#define IVTV_MASK_VPU_ENABLE16 		0xFFFFFFFB
-#define IVTV_CMD_VDM_STOP 		0x00000000
-#define IVTV_CMD_AO_STOP 		0x00000005
-#define IVTV_CMD_APU_PING 		0x00000000
-#define IVTV_CMD_VPU_STOP15 		0xFFFFFFFE
-#define IVTV_CMD_VPU_STOP16 		0xFFFFFFEE
-#define IVTV_CMD_HW_BLOCKS_RST 		0xFFFFFFFF
-#define IVTV_CMD_SPU_STOP 		0x00000001
-#define IVTV_CMD_SDRAM_PRECHARGE_INIT 	0x0000001A
-#define IVTV_CMD_SDRAM_REFRESH_INIT 	0x80000640
-#define IVTV_SDRAM_SLEEPTIME 		600
+#define IVTV_MASK_SPU_ENABLE		0xFFFFFFFE
+#define IVTV_MASK_VPU_ENABLE15		0xFFFFFFF6
+#define IVTV_MASK_VPU_ENABLE16		0xFFFFFFFB
+#define IVTV_CMD_VDM_STOP		0x00000000
+#define IVTV_CMD_AO_STOP		0x00000005
+#define IVTV_CMD_APU_PING		0x00000000
+#define IVTV_CMD_VPU_STOP15		0xFFFFFFFE
+#define IVTV_CMD_VPU_STOP16		0xFFFFFFEE
+#define IVTV_CMD_HW_BLOCKS_RST		0xFFFFFFFF
+#define IVTV_CMD_SPU_STOP		0x00000001
+#define IVTV_CMD_SDRAM_PRECHARGE_INIT	0x0000001A
+#define IVTV_CMD_SDRAM_REFRESH_INIT	0x80000640
+#define IVTV_SDRAM_SLEEPTIME		600
 
-#define IVTV_DECODE_INIT_MPEG_FILENAME 	"v4l-cx2341x-init.mpg"
-#define IVTV_DECODE_INIT_MPEG_SIZE 	(152*1024)
+#define IVTV_DECODE_INIT_MPEG_FILENAME	"v4l-cx2341x-init.mpg"
+#define IVTV_DECODE_INIT_MPEG_SIZE	(152*1024)
 
 /* Encoder/decoder firmware sizes */
-#define IVTV_FW_ENC_SIZE 		(376836)
-#define IVTV_FW_DEC_SIZE 		(256*1024)
+#define IVTV_FW_ENC_SIZE		(376836)
+#define IVTV_FW_DEC_SIZE		(256*1024)
 
 static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv *itv, long size)
 {
diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c
index 893962a..522cd11 100644
--- a/drivers/media/pci/ivtv/ivtv-i2c.c
+++ b/drivers/media/pci/ivtv/ivtv-i2c.c
@@ -76,22 +76,22 @@
 
 #define IVTV_CS53L32A_I2C_ADDR		0x11
 #define IVTV_M52790_I2C_ADDR		0x48
-#define IVTV_CX25840_I2C_ADDR 		0x44
-#define IVTV_SAA7115_I2C_ADDR 		0x21
-#define IVTV_SAA7127_I2C_ADDR 		0x44
-#define IVTV_SAA717x_I2C_ADDR 		0x21
-#define IVTV_MSP3400_I2C_ADDR 		0x40
-#define IVTV_HAUPPAUGE_I2C_ADDR 	0x50
-#define IVTV_WM8739_I2C_ADDR 		0x1a
+#define IVTV_CX25840_I2C_ADDR		0x44
+#define IVTV_SAA7115_I2C_ADDR		0x21
+#define IVTV_SAA7127_I2C_ADDR		0x44
+#define IVTV_SAA717x_I2C_ADDR		0x21
+#define IVTV_MSP3400_I2C_ADDR		0x40
+#define IVTV_HAUPPAUGE_I2C_ADDR		0x50
+#define IVTV_WM8739_I2C_ADDR		0x1a
 #define IVTV_WM8775_I2C_ADDR		0x1b
 #define IVTV_TEA5767_I2C_ADDR		0x60
-#define IVTV_UPD64031A_I2C_ADDR 	0x12
-#define IVTV_UPD64083_I2C_ADDR 		0x5c
-#define IVTV_VP27SMPX_I2C_ADDR      	0x5b
-#define IVTV_M52790_I2C_ADDR      	0x48
+#define IVTV_UPD64031A_I2C_ADDR		0x12
+#define IVTV_UPD64083_I2C_ADDR		0x5c
+#define IVTV_VP27SMPX_I2C_ADDR		0x5b
+#define IVTV_M52790_I2C_ADDR		0x48
 #define IVTV_AVERMEDIA_IR_RX_I2C_ADDR	0x40
-#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 	0x1a
-#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 	0x18
+#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR	0x1a
+#define IVTV_HAUP_INT_IR_RX_I2C_ADDR	0x18
 #define IVTV_Z8F0811_IR_TX_I2C_ADDR	0x70
 #define IVTV_Z8F0811_IR_RX_I2C_ADDR	0x71
 #define IVTV_ADAPTEC_IR_ADDR		0x6b
@@ -117,8 +117,7 @@ static const u8 hw_addrs[] = {
 	IVTV_AVERMEDIA_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_AVER */
 	IVTV_HAUP_EXT_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_HAUP_EXT */
 	IVTV_HAUP_INT_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_HAUP_INT */
-	IVTV_Z8F0811_IR_TX_I2C_ADDR,	/* IVTV_HW_Z8F0811_IR_TX_HAUP */
-	IVTV_Z8F0811_IR_RX_I2C_ADDR,	/* IVTV_HW_Z8F0811_IR_RX_HAUP */
+	IVTV_Z8F0811_IR_RX_I2C_ADDR,	/* IVTV_HW_Z8F0811_IR_HAUP */
 	IVTV_ADAPTEC_IR_ADDR,		/* IVTV_HW_I2C_IR_RX_ADAPTEC */
 };
 
@@ -143,8 +142,7 @@ static const char * const hw_devicenames[] = {
 	"ir_video",		/* IVTV_HW_I2C_IR_RX_AVER */
 	"ir_video",		/* IVTV_HW_I2C_IR_RX_HAUP_EXT */
 	"ir_video",		/* IVTV_HW_I2C_IR_RX_HAUP_INT */
-	"ir_tx_z8f0811_haup",	/* IVTV_HW_Z8F0811_IR_TX_HAUP */
-	"ir_rx_z8f0811_haup",	/* IVTV_HW_Z8F0811_IR_RX_HAUP */
+	"ir_z8f0811_haup",	/* IVTV_HW_Z8F0811_IR_HAUP */
 	"ir_video",		/* IVTV_HW_I2C_IR_RX_ADAPTEC */
 };
 
@@ -181,18 +179,8 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
 	struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data;
 	unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
 
-	/* Only allow one IR transmitter to be registered per board */
-	if (hw & IVTV_HW_IR_TX_ANY) {
-		if (itv->hw_flags & IVTV_HW_IR_TX_ANY)
-			return -1;
-		memset(&info, 0, sizeof(struct i2c_board_info));
-		strlcpy(info.type, type, I2C_NAME_SIZE);
-		return i2c_new_probed_device(adap, &info, addr_list, NULL)
-							   == NULL ? -1 : 0;
-	}
-
 	/* Only allow one IR receiver to be registered per board */
-	if (itv->hw_flags & IVTV_HW_IR_RX_ANY)
+	if (itv->hw_flags & IVTV_HW_IR_ANY)
 		return -1;
 
 	/* Our default information for ir-kbd-i2c.c to use */
@@ -211,7 +199,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
 		init_data->type = RC_PROTO_BIT_RC5;
 		init_data->name = itv->card_name;
 		break;
-	case IVTV_HW_Z8F0811_IR_RX_HAUP:
+	case IVTV_HW_Z8F0811_IR_HAUP:
 		/* Default to grey remote */
 		init_data->ir_codes = RC_MAP_HAUPPAUGE;
 		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index 670462d..4cdc6d2 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -1884,65 +1884,65 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
 }
 
 static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
-	.vidioc_querycap    		    = ivtv_querycap,
-	.vidioc_s_audio     		    = ivtv_s_audio,
-	.vidioc_g_audio     		    = ivtv_g_audio,
-	.vidioc_enumaudio   		    = ivtv_enumaudio,
-	.vidioc_s_audout     		    = ivtv_s_audout,
-	.vidioc_g_audout     		    = ivtv_g_audout,
-	.vidioc_enum_input   		    = ivtv_enum_input,
-	.vidioc_enum_output   		    = ivtv_enum_output,
-	.vidioc_enumaudout   		    = ivtv_enumaudout,
-	.vidioc_cropcap       		    = ivtv_cropcap,
+	.vidioc_querycap		    = ivtv_querycap,
+	.vidioc_s_audio			    = ivtv_s_audio,
+	.vidioc_g_audio			    = ivtv_g_audio,
+	.vidioc_enumaudio		    = ivtv_enumaudio,
+	.vidioc_s_audout		    = ivtv_s_audout,
+	.vidioc_g_audout		    = ivtv_g_audout,
+	.vidioc_enum_input		    = ivtv_enum_input,
+	.vidioc_enum_output		    = ivtv_enum_output,
+	.vidioc_enumaudout		    = ivtv_enumaudout,
+	.vidioc_cropcap			    = ivtv_cropcap,
 	.vidioc_s_selection		    = ivtv_s_selection,
 	.vidioc_g_selection		    = ivtv_g_selection,
-	.vidioc_g_input      		    = ivtv_g_input,
-	.vidioc_s_input      		    = ivtv_s_input,
-	.vidioc_g_output     		    = ivtv_g_output,
-	.vidioc_s_output     		    = ivtv_s_output,
-	.vidioc_g_frequency 		    = ivtv_g_frequency,
-	.vidioc_s_frequency  		    = ivtv_s_frequency,
-	.vidioc_s_tuner      		    = ivtv_s_tuner,
-	.vidioc_g_tuner      		    = ivtv_g_tuner,
-	.vidioc_g_enc_index 		    = ivtv_g_enc_index,
+	.vidioc_g_input			    = ivtv_g_input,
+	.vidioc_s_input			    = ivtv_s_input,
+	.vidioc_g_output		    = ivtv_g_output,
+	.vidioc_s_output		    = ivtv_s_output,
+	.vidioc_g_frequency		    = ivtv_g_frequency,
+	.vidioc_s_frequency		    = ivtv_s_frequency,
+	.vidioc_s_tuner			    = ivtv_s_tuner,
+	.vidioc_g_tuner			    = ivtv_g_tuner,
+	.vidioc_g_enc_index		    = ivtv_g_enc_index,
 	.vidioc_g_fbuf			    = ivtv_g_fbuf,
 	.vidioc_s_fbuf			    = ivtv_s_fbuf,
-	.vidioc_g_std 			    = ivtv_g_std,
-	.vidioc_s_std 			    = ivtv_s_std,
+	.vidioc_g_std			    = ivtv_g_std,
+	.vidioc_s_std			    = ivtv_s_std,
 	.vidioc_overlay			    = ivtv_overlay,
 	.vidioc_log_status		    = ivtv_log_status,
-	.vidioc_enum_fmt_vid_cap 	    = ivtv_enum_fmt_vid_cap,
-	.vidioc_encoder_cmd  		    = ivtv_encoder_cmd,
-	.vidioc_try_encoder_cmd 	    = ivtv_try_encoder_cmd,
+	.vidioc_enum_fmt_vid_cap	    = ivtv_enum_fmt_vid_cap,
+	.vidioc_encoder_cmd		    = ivtv_encoder_cmd,
+	.vidioc_try_encoder_cmd		    = ivtv_try_encoder_cmd,
 	.vidioc_decoder_cmd		    = ivtv_decoder_cmd,
 	.vidioc_try_decoder_cmd		    = ivtv_try_decoder_cmd,
-	.vidioc_enum_fmt_vid_out 	    = ivtv_enum_fmt_vid_out,
-	.vidioc_g_fmt_vid_cap 		    = ivtv_g_fmt_vid_cap,
+	.vidioc_enum_fmt_vid_out	    = ivtv_enum_fmt_vid_out,
+	.vidioc_g_fmt_vid_cap		    = ivtv_g_fmt_vid_cap,
 	.vidioc_g_fmt_vbi_cap		    = ivtv_g_fmt_vbi_cap,
 	.vidioc_g_fmt_sliced_vbi_cap        = ivtv_g_fmt_sliced_vbi_cap,
 	.vidioc_g_fmt_vid_out               = ivtv_g_fmt_vid_out,
 	.vidioc_g_fmt_vid_out_overlay       = ivtv_g_fmt_vid_out_overlay,
 	.vidioc_g_fmt_sliced_vbi_out        = ivtv_g_fmt_sliced_vbi_out,
-	.vidioc_s_fmt_vid_cap  		    = ivtv_s_fmt_vid_cap,
-	.vidioc_s_fmt_vbi_cap 		    = ivtv_s_fmt_vbi_cap,
+	.vidioc_s_fmt_vid_cap		    = ivtv_s_fmt_vid_cap,
+	.vidioc_s_fmt_vbi_cap		    = ivtv_s_fmt_vbi_cap,
 	.vidioc_s_fmt_sliced_vbi_cap        = ivtv_s_fmt_sliced_vbi_cap,
 	.vidioc_s_fmt_vid_out               = ivtv_s_fmt_vid_out,
 	.vidioc_s_fmt_vid_out_overlay       = ivtv_s_fmt_vid_out_overlay,
 	.vidioc_s_fmt_sliced_vbi_out        = ivtv_s_fmt_sliced_vbi_out,
-	.vidioc_try_fmt_vid_cap  	    = ivtv_try_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap		    = ivtv_try_fmt_vid_cap,
 	.vidioc_try_fmt_vbi_cap		    = ivtv_try_fmt_vbi_cap,
 	.vidioc_try_fmt_sliced_vbi_cap      = ivtv_try_fmt_sliced_vbi_cap,
-	.vidioc_try_fmt_vid_out 	    = ivtv_try_fmt_vid_out,
+	.vidioc_try_fmt_vid_out		    = ivtv_try_fmt_vid_out,
 	.vidioc_try_fmt_vid_out_overlay     = ivtv_try_fmt_vid_out_overlay,
-	.vidioc_try_fmt_sliced_vbi_out 	    = ivtv_try_fmt_sliced_vbi_out,
-	.vidioc_g_sliced_vbi_cap 	    = ivtv_g_sliced_vbi_cap,
+	.vidioc_try_fmt_sliced_vbi_out	    = ivtv_try_fmt_sliced_vbi_out,
+	.vidioc_g_sliced_vbi_cap	    = ivtv_g_sliced_vbi_cap,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	.vidioc_g_register 		    = ivtv_g_register,
-	.vidioc_s_register 		    = ivtv_s_register,
+	.vidioc_g_register		    = ivtv_g_register,
+	.vidioc_s_register		    = ivtv_s_register,
 #endif
-	.vidioc_default 		    = ivtv_default,
-	.vidioc_subscribe_event 	    = ivtv_subscribe_event,
-	.vidioc_unsubscribe_event 	    = v4l2_event_unsubscribe,
+	.vidioc_default			    = ivtv_default,
+	.vidioc_subscribe_event		    = ivtv_subscribe_event,
+	.vidioc_unsubscribe_event	    = v4l2_event_unsubscribe,
 };
 
 void ivtv_set_funcs(struct video_device *vdev)
diff --git a/drivers/media/pci/ivtv/ivtv-mailbox.c b/drivers/media/pci/ivtv/ivtv-mailbox.c
index 9a2506a..f317c8f 100644
--- a/drivers/media/pci/ivtv/ivtv-mailbox.c
+++ b/drivers/media/pci/ivtv/ivtv-mailbox.c
@@ -28,118 +28,118 @@
 #define IVTV_MBOX_FIRMWARE_DONE 0x00000004
 #define IVTV_MBOX_DRIVER_DONE   0x00000002
 #define IVTV_MBOX_DRIVER_BUSY   0x00000001
-#define IVTV_MBOX_FREE 		0x00000000
+#define IVTV_MBOX_FREE		0x00000000
 
 /* Firmware mailbox standard timeout */
-#define IVTV_API_STD_TIMEOUT 	0x02000000
+#define IVTV_API_STD_TIMEOUT	0x02000000
 
-#define API_CACHE 	 (1 << 0) 	/* Allow the command to be stored in the cache */
-#define API_RESULT	 (1 << 1) 	/* Allow 1 second for this cmd to end */
+#define API_CACHE	 (1 << 0)	/* Allow the command to be stored in the cache */
+#define API_RESULT	 (1 << 1)	/* Allow 1 second for this cmd to end */
 #define API_FAST_RESULT	 (3 << 1)	/* Allow 0.1 second for this cmd to end */
-#define API_DMA 	 (1 << 3)	/* DMA mailbox, has special handling */
-#define API_HIGH_VOL 	 (1 << 5)	/* High volume command (i.e. called during encoding or decoding) */
-#define API_NO_WAIT_MB 	 (1 << 4)	/* Command may not wait for a free mailbox */
+#define API_DMA		 (1 << 3)	/* DMA mailbox, has special handling */
+#define API_HIGH_VOL	 (1 << 5)	/* High volume command (i.e. called during encoding or decoding) */
+#define API_NO_WAIT_MB	 (1 << 4)	/* Command may not wait for a free mailbox */
 #define API_NO_WAIT_RES	 (1 << 5)	/* Command may not wait for the result */
 #define API_NO_POLL	 (1 << 6)	/* Avoid pointless polling */
 
 struct ivtv_api_info {
 	int flags;		/* Flags, see above */
-	const char *name; 	/* The name of the command */
+	const char *name;	/* The name of the command */
 };
 
 #define API_ENTRY(x, f) [x] = { (f), #x }
 
 static const struct ivtv_api_info api_info[256] = {
 	/* MPEG encoder API */
-	API_ENTRY(CX2341X_ENC_PING_FW, 			API_FAST_RESULT),
-	API_ENTRY(CX2341X_ENC_START_CAPTURE, 		API_RESULT | API_NO_POLL),
-	API_ENTRY(CX2341X_ENC_STOP_CAPTURE, 		API_RESULT),
-	API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_PCR_ID, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_FRAME_RATE, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_BIT_RATE, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES, 	API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO, 	API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE, 	API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS, 	API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS, 	API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 	API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_VBI_LINE, 		API_RESULT),
-	API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES, 	API_CACHE),
-	API_ENTRY(CX2341X_ENC_HALT_FW, 			API_FAST_RESULT),
-	API_ENTRY(CX2341X_ENC_GET_VERSION, 		API_FAST_RESULT),
-	API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_GET_SEQ_END, 		API_RESULT),
-	API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO, 	API_FAST_RESULT),
-	API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG, 		API_RESULT),
-	API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, 	API_CACHE),
-	API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, 	API_FAST_RESULT),
-	API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, 	API_FAST_RESULT),
-	API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, 	API_DMA | API_HIGH_VOL),
-	API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, 	API_RESULT),
-	API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, 	API_CACHE),
-	API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, 		API_RESULT),
-	API_ENTRY(CX2341X_ENC_REFRESH_INPUT, 		API_NO_WAIT_MB | API_HIGH_VOL),
-	API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, 	API_RESULT),
-	API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, 	API_CACHE),
-	API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER, 		API_CACHE),
-	API_ENTRY(CX2341X_ENC_MUTE_VIDEO, 		API_RESULT),
-	API_ENTRY(CX2341X_ENC_MUTE_AUDIO, 		API_RESULT),
+	API_ENTRY(CX2341X_ENC_PING_FW,			API_FAST_RESULT),
+	API_ENTRY(CX2341X_ENC_START_CAPTURE,		API_RESULT | API_NO_POLL),
+	API_ENTRY(CX2341X_ENC_STOP_CAPTURE,		API_RESULT),
+	API_ENTRY(CX2341X_ENC_SET_AUDIO_ID,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_VIDEO_ID,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_PCR_ID,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_FRAME_RATE,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_BIT_RATE,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES,	API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE,	API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS,	API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS,	API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE,	API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_VBI_LINE,		API_RESULT),
+	API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES,	API_CACHE),
+	API_ENTRY(CX2341X_ENC_HALT_FW,			API_FAST_RESULT),
+	API_ENTRY(CX2341X_ENC_GET_VERSION,		API_FAST_RESULT),
+	API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_GET_SEQ_END,		API_RESULT),
+	API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO,	API_FAST_RESULT),
+	API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG,		API_RESULT),
+	API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE,	API_CACHE),
+	API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10,	API_FAST_RESULT),
+	API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9,	API_FAST_RESULT),
+	API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST,	API_DMA | API_HIGH_VOL),
+	API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT,		API_RESULT),
+	API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE,	API_CACHE),
+	API_ENTRY(CX2341X_ENC_PAUSE_ENCODER,		API_RESULT),
+	API_ENTRY(CX2341X_ENC_REFRESH_INPUT,		API_NO_WAIT_MB | API_HIGH_VOL),
+	API_ENTRY(CX2341X_ENC_SET_COPYRIGHT,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION,	API_RESULT),
+	API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES,	API_CACHE),
+	API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER,		API_CACHE),
+	API_ENTRY(CX2341X_ENC_MUTE_VIDEO,		API_RESULT),
+	API_ENTRY(CX2341X_ENC_MUTE_AUDIO,		API_RESULT),
 	API_ENTRY(CX2341X_ENC_SET_VERT_CROP_LINE,	API_FAST_RESULT),
-	API_ENTRY(CX2341X_ENC_MISC, 			API_FAST_RESULT),
+	API_ENTRY(CX2341X_ENC_MISC,			API_FAST_RESULT),
 	/* Obsolete PULLDOWN API command */
-	API_ENTRY(0xb1, 				API_CACHE),
+	API_ENTRY(0xb1,					API_CACHE),
 
 	/* MPEG decoder API */
-	API_ENTRY(CX2341X_DEC_PING_FW, 			API_FAST_RESULT),
-	API_ENTRY(CX2341X_DEC_START_PLAYBACK, 		API_RESULT | API_NO_POLL),
-	API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, 		API_RESULT),
-	API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, 	API_RESULT),
-	API_ENTRY(CX2341X_DEC_STEP_VIDEO, 		API_RESULT),
-	API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, 	API_CACHE),
-	API_ENTRY(CX2341X_DEC_GET_XFER_INFO, 		API_FAST_RESULT),
-	API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, 		API_FAST_RESULT),
-	API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, 	API_DMA | API_HIGH_VOL),
-	API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, 		API_RESULT),
-	API_ENTRY(CX2341X_DEC_HALT_FW, 			API_FAST_RESULT),
-	API_ENTRY(CX2341X_DEC_SET_STANDARD, 		API_CACHE),
-	API_ENTRY(CX2341X_DEC_GET_VERSION, 		API_FAST_RESULT),
-	API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT, 	API_CACHE),
-	API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, 		API_RESULT /*| API_NO_WAIT_RES*/),
-	API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE, 		API_CACHE),
-	API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION, 	API_RESULT),
-	API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS, 	API_CACHE),
-	API_ENTRY(CX2341X_DEC_EXTRACT_VBI, 		API_RESULT),
-	API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE, 	API_FAST_RESULT),
-	API_ENTRY(CX2341X_DEC_SET_PREBUFFERING, 	API_CACHE),
+	API_ENTRY(CX2341X_DEC_PING_FW,			API_FAST_RESULT),
+	API_ENTRY(CX2341X_DEC_START_PLAYBACK,		API_RESULT | API_NO_POLL),
+	API_ENTRY(CX2341X_DEC_STOP_PLAYBACK,		API_RESULT),
+	API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED,	API_RESULT),
+	API_ENTRY(CX2341X_DEC_STEP_VIDEO,		API_RESULT),
+	API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE,	API_CACHE),
+	API_ENTRY(CX2341X_DEC_GET_XFER_INFO,		API_FAST_RESULT),
+	API_ENTRY(CX2341X_DEC_GET_DMA_STATUS,		API_FAST_RESULT),
+	API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST,	API_DMA | API_HIGH_VOL),
+	API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK,		API_RESULT),
+	API_ENTRY(CX2341X_DEC_HALT_FW,			API_FAST_RESULT),
+	API_ENTRY(CX2341X_DEC_SET_STANDARD,		API_CACHE),
+	API_ENTRY(CX2341X_DEC_GET_VERSION,		API_FAST_RESULT),
+	API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT,		API_CACHE),
+	API_ENTRY(CX2341X_DEC_GET_TIMING_INFO,		API_RESULT /*| API_NO_WAIT_RES*/),
+	API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE,		API_CACHE),
+	API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION,	API_RESULT),
+	API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS,	API_CACHE),
+	API_ENTRY(CX2341X_DEC_EXTRACT_VBI,		API_RESULT),
+	API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE,	API_FAST_RESULT),
+	API_ENTRY(CX2341X_DEC_SET_PREBUFFERING,		API_CACHE),
 
 	/* OSD API */
-	API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER, 		API_FAST_RESULT),
-	API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT, 	API_FAST_RESULT),
-	API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT, 	API_CACHE),
-	API_ENTRY(CX2341X_OSD_GET_STATE, 		API_FAST_RESULT),
-	API_ENTRY(CX2341X_OSD_SET_STATE, 		API_CACHE),
-	API_ENTRY(CX2341X_OSD_GET_OSD_COORDS, 		API_FAST_RESULT),
-	API_ENTRY(CX2341X_OSD_SET_OSD_COORDS, 		API_CACHE),
-	API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS, 	API_FAST_RESULT),
-	API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS, 	API_CACHE),
-	API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA, 	API_FAST_RESULT),
-	API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA, 	API_CACHE),
-	API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS, 	API_CACHE),
-	API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE, 	API_FAST_RESULT),
-	API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE, 	API_CACHE),
-	API_ENTRY(CX2341X_OSD_BLT_COPY, 		API_RESULT),
-	API_ENTRY(CX2341X_OSD_BLT_FILL, 		API_RESULT),
-	API_ENTRY(CX2341X_OSD_BLT_TEXT, 		API_RESULT),
-	API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 	API_CACHE),
-	API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY, 		API_CACHE),
-	API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX, 	API_FAST_RESULT),
-	API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX, 	API_CACHE)
+	API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER,		API_FAST_RESULT),
+	API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT,		API_FAST_RESULT),
+	API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT,		API_CACHE),
+	API_ENTRY(CX2341X_OSD_GET_STATE,		API_FAST_RESULT),
+	API_ENTRY(CX2341X_OSD_SET_STATE,		API_CACHE),
+	API_ENTRY(CX2341X_OSD_GET_OSD_COORDS,		API_FAST_RESULT),
+	API_ENTRY(CX2341X_OSD_SET_OSD_COORDS,		API_CACHE),
+	API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS,	API_FAST_RESULT),
+	API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS,	API_CACHE),
+	API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA,		API_FAST_RESULT),
+	API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA,		API_CACHE),
+	API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS,		API_CACHE),
+	API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE,	API_FAST_RESULT),
+	API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE,	API_CACHE),
+	API_ENTRY(CX2341X_OSD_BLT_COPY,			API_RESULT),
+	API_ENTRY(CX2341X_OSD_BLT_FILL,			API_RESULT),
+	API_ENTRY(CX2341X_OSD_BLT_TEXT,			API_RESULT),
+	API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW,	API_CACHE),
+	API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY,		API_CACHE),
+	API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX,	API_FAST_RESULT),
+	API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX,	API_CACHE)
 };
 
 static int try_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int mb)
diff --git a/drivers/media/pci/mantis/Makefile b/drivers/media/pci/mantis/Makefile
index a684dc2..b5ef396 100644
--- a/drivers/media/pci/mantis/Makefile
+++ b/drivers/media/pci/mantis/Makefile
@@ -26,4 +26,4 @@
 obj-$(CONFIG_DVB_MANTIS)	+= mantis.o
 obj-$(CONFIG_DVB_HOPPER)	+= hopper.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/dvb-frontends/
diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c
index ed855e3..89759cb 100644
--- a/drivers/media/pci/mantis/hopper_cards.c
+++ b/drivers/media/pci/mantis/hopper_cards.c
@@ -26,11 +26,11 @@
 #include <asm/irq.h>
 #include <linux/interrupt.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "hopper_vp3028.h"
diff --git a/drivers/media/pci/mantis/hopper_vp3028.c b/drivers/media/pci/mantis/hopper_vp3028.c
index 1032db6..d58ae00 100644
--- a/drivers/media/pci/mantis/hopper_vp3028.c
+++ b/drivers/media/pci/mantis/hopper_vp3028.c
@@ -22,11 +22,11 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "zl10353.h"
 #include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_ca.c b/drivers/media/pci/mantis/mantis_ca.c
index 60c6c2f..4f0ba45 100644
--- a/drivers/media/pci/mantis/mantis_ca.c
+++ b/drivers/media/pci/mantis/mantis_ca.c
@@ -24,11 +24,11 @@
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_link.h"
diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c
index 4ce8a90..7eb75cb 100644
--- a/drivers/media/pci/mantis/mantis_cards.c
+++ b/drivers/media/pci/mantis/mantis_cards.c
@@ -27,11 +27,11 @@
 #include <linux/interrupt.h>
 #include <media/rc-map.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 
diff --git a/drivers/media/pci/mantis/mantis_dma.c b/drivers/media/pci/mantis/mantis_dma.c
index 2ce310b..84406a4 100644
--- a/drivers/media/pci/mantis/mantis_dma.c
+++ b/drivers/media/pci/mantis/mantis_dma.c
@@ -28,11 +28,11 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_reg.h"
diff --git a/drivers/media/pci/mantis/mantis_dvb.c b/drivers/media/pci/mantis/mantis_dvb.c
index 0db4de3a..54dbaa7 100644
--- a/drivers/media/pci/mantis/mantis_dvb.c
+++ b/drivers/media/pci/mantis/mantis_dvb.c
@@ -26,11 +26,11 @@
 #include <linux/pci.h>
 #include <linux/i2c.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_dma.h"
diff --git a/drivers/media/pci/mantis/mantis_evm.c b/drivers/media/pci/mantis/mantis_evm.c
index 909ff54..443ac5a 100644
--- a/drivers/media/pci/mantis/mantis_evm.c
+++ b/drivers/media/pci/mantis/mantis_evm.c
@@ -25,11 +25,11 @@
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_link.h"
diff --git a/drivers/media/pci/mantis/mantis_hif.c b/drivers/media/pci/mantis/mantis_hif.c
index 10c68df..bf61f8c 100644
--- a/drivers/media/pci/mantis/mantis_hif.c
+++ b/drivers/media/pci/mantis/mantis_hif.c
@@ -25,11 +25,11 @@
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 
diff --git a/drivers/media/pci/mantis/mantis_i2c.c b/drivers/media/pci/mantis/mantis_i2c.c
index 496c10d..6528a21 100644
--- a/drivers/media/pci/mantis/mantis_i2c.c
+++ b/drivers/media/pci/mantis/mantis_i2c.c
@@ -23,11 +23,11 @@
 #include <linux/pci.h>
 #include <linux/i2c.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_reg.h"
diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c
index 7519dcc..5b472e9 100644
--- a/drivers/media/pci/mantis/mantis_input.c
+++ b/drivers/media/pci/mantis/mantis_input.c
@@ -17,11 +17,11 @@
 #include <media/rc-core.h>
 #include <linux/pci.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_input.h"
diff --git a/drivers/media/pci/mantis/mantis_ioc.c b/drivers/media/pci/mantis/mantis_ioc.c
index 24fcdc6..f45c234 100644
--- a/drivers/media/pci/mantis/mantis_ioc.c
+++ b/drivers/media/pci/mantis/mantis_ioc.c
@@ -26,11 +26,11 @@
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_reg.h"
diff --git a/drivers/media/pci/mantis/mantis_link.h b/drivers/media/pci/mantis/mantis_link.h
index 2a81477..c669897 100644
--- a/drivers/media/pci/mantis/mantis_link.h
+++ b/drivers/media/pci/mantis/mantis_link.h
@@ -23,7 +23,7 @@
 
 #include <linux/mutex.h>
 #include <linux/workqueue.h>
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 
 enum mantis_sbuf_status {
 	MANTIS_SBUF_DATA_AVAIL		= 1,
diff --git a/drivers/media/pci/mantis/mantis_pci.c b/drivers/media/pci/mantis/mantis_pci.c
index 9e89e04..d590524 100644
--- a/drivers/media/pci/mantis/mantis_pci.c
+++ b/drivers/media/pci/mantis/mantis_pci.c
@@ -34,11 +34,11 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_reg.h"
diff --git a/drivers/media/pci/mantis/mantis_pcmcia.c b/drivers/media/pci/mantis/mantis_pcmcia.c
index b2dbc7b..2a316b9 100644
--- a/drivers/media/pci/mantis/mantis_pcmcia.c
+++ b/drivers/media/pci/mantis/mantis_pcmcia.c
@@ -25,11 +25,11 @@
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_link.h" /* temporary due to physical layer stuff */
diff --git a/drivers/media/pci/mantis/mantis_reg.h b/drivers/media/pci/mantis/mantis_reg.h
index 7761f9d..762ed9f 100644
--- a/drivers/media/pci/mantis/mantis_reg.h
+++ b/drivers/media/pci/mantis/mantis_reg.h
@@ -166,12 +166,12 @@
 #define MANTIS_CARD_PLUGOUT		(0x01 <<  0)
 
 #define MANTIS_GPIF_BRADDR		0xa0
-#define MANTIS_GPIF_PCMCIAREG		(0x01 		<< 27)
-#define MANTIS_GPIF_PCMCIAIOM		(0x01 		<< 26)
+#define MANTIS_GPIF_PCMCIAREG		(0x01		<< 27)
+#define MANTIS_GPIF_PCMCIAIOM		(0x01		<< 26)
 #define MANTIS_GPIF_BR_ADDR		(0xfffffff	<<  0)
 
 #define MANTIS_GPIF_BRBYTES		0xa4
-#define MANTIS_GPIF_BRCNT		(0xfff 		<<  0)
+#define MANTIS_GPIF_BRCNT		(0xfff		<<  0)
 
 #define MANTIS_PCMCIA_RESET		0xa8
 #define MANTIS_PCMCIA_RSTVAL		(0xff << 0)
diff --git a/drivers/media/pci/mantis/mantis_uart.c b/drivers/media/pci/mantis/mantis_uart.c
index f1c96ae..18f81c1 100644
--- a/drivers/media/pci/mantis/mantis_uart.c
+++ b/drivers/media/pci/mantis/mantis_uart.c
@@ -27,11 +27,11 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_reg.h"
diff --git a/drivers/media/pci/mantis/mantis_vp1033.c b/drivers/media/pci/mantis/mantis_vp1033.c
index 12a6adb..54d2ab4 100644
--- a/drivers/media/pci/mantis/mantis_vp1033.c
+++ b/drivers/media/pci/mantis/mantis_vp1033.c
@@ -22,11 +22,11 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "stv0299.h"
 #include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_vp1034.c b/drivers/media/pci/mantis/mantis_vp1034.c
index e4972ff..26672a4 100644
--- a/drivers/media/pci/mantis/mantis_vp1034.c
+++ b/drivers/media/pci/mantis/mantis_vp1034.c
@@ -23,11 +23,11 @@
 #include <linux/interrupt.h>
 #include <asm/io.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mb86a16.h"
 #include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_vp1034.h b/drivers/media/pci/mantis/mantis_vp1034.h
index 764b1c6..35af4e5 100644
--- a/drivers/media/pci/mantis/mantis_vp1034.h
+++ b/drivers/media/pci/mantis/mantis_vp1034.h
@@ -21,7 +21,7 @@
 #ifndef __MANTIS_VP1034_H
 #define __MANTIS_VP1034_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mantis_common.h"
 
 
diff --git a/drivers/media/pci/mantis/mantis_vp1041.c b/drivers/media/pci/mantis/mantis_vp1041.c
index 7082fcb..0eeccc2 100644
--- a/drivers/media/pci/mantis/mantis_vp1041.c
+++ b/drivers/media/pci/mantis/mantis_vp1041.c
@@ -22,11 +22,11 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "mantis_common.h"
 #include "mantis_ioc.h"
@@ -47,70 +47,70 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = {
 	/* 0x0000000b, *//* SYSREG */
 	{ STB0899_DEV_ID		, 0x30 },
 	{ STB0899_DISCNTRL1		, 0x32 },
-	{ STB0899_DISCNTRL2     	, 0x80 },
-	{ STB0899_DISRX_ST0     	, 0x04 },
-	{ STB0899_DISRX_ST1     	, 0x00 },
-	{ STB0899_DISPARITY     	, 0x00 },
+	{ STB0899_DISCNTRL2		, 0x80 },
+	{ STB0899_DISRX_ST0		, 0x04 },
+	{ STB0899_DISRX_ST1		, 0x00 },
+	{ STB0899_DISPARITY		, 0x00 },
 	{ STB0899_DISSTATUS		, 0x20 },
-	{ STB0899_DISF22        	, 0x99 },
-	{ STB0899_DISF22RX      	, 0xa8 },
+	{ STB0899_DISF22		, 0x99 },
+	{ STB0899_DISF22RX		, 0xa8 },
 	/* SYSREG ? */
-	{ STB0899_ACRPRESC      	, 0x11 },
-	{ STB0899_ACRDIV1       	, 0x0a },
-	{ STB0899_ACRDIV2       	, 0x05 },
-	{ STB0899_DACR1         	, 0x00 },
-	{ STB0899_DACR2         	, 0x00 },
-	{ STB0899_OUTCFG        	, 0x00 },
-	{ STB0899_MODECFG       	, 0x00 },
+	{ STB0899_ACRPRESC		, 0x11 },
+	{ STB0899_ACRDIV1		, 0x0a },
+	{ STB0899_ACRDIV2		, 0x05 },
+	{ STB0899_DACR1			, 0x00 },
+	{ STB0899_DACR2			, 0x00 },
+	{ STB0899_OUTCFG		, 0x00 },
+	{ STB0899_MODECFG		, 0x00 },
 	{ STB0899_IRQSTATUS_3		, 0xfe },
 	{ STB0899_IRQSTATUS_2		, 0x03 },
 	{ STB0899_IRQSTATUS_1		, 0x7c },
 	{ STB0899_IRQSTATUS_0		, 0xf4 },
-	{ STB0899_IRQMSK_3      	, 0xf3 },
-	{ STB0899_IRQMSK_2      	, 0xfc },
-	{ STB0899_IRQMSK_1      	, 0xff },
+	{ STB0899_IRQMSK_3		, 0xf3 },
+	{ STB0899_IRQMSK_2		, 0xfc },
+	{ STB0899_IRQMSK_1		, 0xff },
 	{ STB0899_IRQMSK_0		, 0xff },
 	{ STB0899_IRQCFG		, 0x00 },
-	{ STB0899_I2CCFG        	, 0x88 },
-	{ STB0899_I2CRPT        	, 0x58 },
+	{ STB0899_I2CCFG		, 0x88 },
+	{ STB0899_I2CRPT		, 0x58 },
 	{ STB0899_IOPVALUE5		, 0x00 },
 	{ STB0899_IOPVALUE4		, 0x33 },
 	{ STB0899_IOPVALUE3		, 0x6d },
 	{ STB0899_IOPVALUE2		, 0x90 },
 	{ STB0899_IOPVALUE1		, 0x60 },
 	{ STB0899_IOPVALUE0		, 0x00 },
-	{ STB0899_GPIO00CFG     	, 0x82 },
-	{ STB0899_GPIO01CFG     	, 0x82 },
-	{ STB0899_GPIO02CFG     	, 0x82 },
-	{ STB0899_GPIO03CFG     	, 0x82 },
-	{ STB0899_GPIO04CFG     	, 0x82 },
-	{ STB0899_GPIO05CFG     	, 0x82 },
-	{ STB0899_GPIO06CFG     	, 0x82 },
-	{ STB0899_GPIO07CFG     	, 0x82 },
-	{ STB0899_GPIO08CFG     	, 0x82 },
-	{ STB0899_GPIO09CFG     	, 0x82 },
-	{ STB0899_GPIO10CFG     	, 0x82 },
-	{ STB0899_GPIO11CFG     	, 0x82 },
-	{ STB0899_GPIO12CFG     	, 0x82 },
-	{ STB0899_GPIO13CFG     	, 0x82 },
-	{ STB0899_GPIO14CFG     	, 0x82 },
-	{ STB0899_GPIO15CFG     	, 0x82 },
-	{ STB0899_GPIO16CFG     	, 0x82 },
-	{ STB0899_GPIO17CFG     	, 0x82 },
-	{ STB0899_GPIO18CFG     	, 0x82 },
-	{ STB0899_GPIO19CFG     	, 0x82 },
-	{ STB0899_GPIO20CFG     	, 0x82 },
-	{ STB0899_SDATCFG       	, 0xb8 },
-	{ STB0899_SCLTCFG       	, 0xba },
-	{ STB0899_AGCRFCFG      	, 0x1c }, /* 0x11 */
-	{ STB0899_GPIO22        	, 0x82 }, /* AGCBB2CFG */
-	{ STB0899_GPIO21        	, 0x91 }, /* AGCBB1CFG */
-	{ STB0899_DIRCLKCFG     	, 0x82 },
-	{ STB0899_CLKOUT27CFG   	, 0x7e },
-	{ STB0899_STDBYCFG      	, 0x82 },
-	{ STB0899_CS0CFG        	, 0x82 },
-	{ STB0899_CS1CFG        	, 0x82 },
-	{ STB0899_DISEQCOCFG    	, 0x20 },
+	{ STB0899_GPIO00CFG		, 0x82 },
+	{ STB0899_GPIO01CFG		, 0x82 },
+	{ STB0899_GPIO02CFG		, 0x82 },
+	{ STB0899_GPIO03CFG		, 0x82 },
+	{ STB0899_GPIO04CFG		, 0x82 },
+	{ STB0899_GPIO05CFG		, 0x82 },
+	{ STB0899_GPIO06CFG		, 0x82 },
+	{ STB0899_GPIO07CFG		, 0x82 },
+	{ STB0899_GPIO08CFG		, 0x82 },
+	{ STB0899_GPIO09CFG		, 0x82 },
+	{ STB0899_GPIO10CFG		, 0x82 },
+	{ STB0899_GPIO11CFG		, 0x82 },
+	{ STB0899_GPIO12CFG		, 0x82 },
+	{ STB0899_GPIO13CFG		, 0x82 },
+	{ STB0899_GPIO14CFG		, 0x82 },
+	{ STB0899_GPIO15CFG		, 0x82 },
+	{ STB0899_GPIO16CFG		, 0x82 },
+	{ STB0899_GPIO17CFG		, 0x82 },
+	{ STB0899_GPIO18CFG		, 0x82 },
+	{ STB0899_GPIO19CFG		, 0x82 },
+	{ STB0899_GPIO20CFG		, 0x82 },
+	{ STB0899_SDATCFG		, 0xb8 },
+	{ STB0899_SCLTCFG		, 0xba },
+	{ STB0899_AGCRFCFG		, 0x1c }, /* 0x11 */
+	{ STB0899_GPIO22		, 0x82 }, /* AGCBB2CFG */
+	{ STB0899_GPIO21		, 0x91 }, /* AGCBB1CFG */
+	{ STB0899_DIRCLKCFG		, 0x82 },
+	{ STB0899_CLKOUT27CFG		, 0x7e },
+	{ STB0899_STDBYCFG		, 0x82 },
+	{ STB0899_CS0CFG		, 0x82 },
+	{ STB0899_CS1CFG		, 0x82 },
+	{ STB0899_DISEQCOCFG		, 0x20 },
 	{ STB0899_GPIO32CFG		, 0x82 },
 	{ STB0899_GPIO33CFG		, 0x82 },
 	{ STB0899_GPIO34CFG		, 0x82 },
@@ -119,35 +119,35 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = {
 	{ STB0899_GPIO37CFG		, 0x82 },
 	{ STB0899_GPIO38CFG		, 0x82 },
 	{ STB0899_GPIO39CFG		, 0x82 },
-	{ STB0899_NCOARSE       	, 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
-	{ STB0899_SYNTCTRL      	, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
-	{ STB0899_FILTCTRL      	, 0x00 },
-	{ STB0899_SYSCTRL       	, 0x01 },
-	{ STB0899_STOPCLK1      	, 0x20 },
-	{ STB0899_STOPCLK2      	, 0x00 },
+	{ STB0899_NCOARSE		, 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+	{ STB0899_SYNTCTRL		, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+	{ STB0899_FILTCTRL		, 0x00 },
+	{ STB0899_SYSCTRL		, 0x01 },
+	{ STB0899_STOPCLK1		, 0x20 },
+	{ STB0899_STOPCLK2		, 0x00 },
 	{ STB0899_INTBUFSTATUS		, 0x00 },
-	{ STB0899_INTBUFCTRL    	, 0x0a },
+	{ STB0899_INTBUFCTRL		, 0x0a },
 	{ 0xffff			, 0xff },
 };
 
 static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
-	{ STB0899_DEMOD         	, 0x00 },
-	{ STB0899_RCOMPC        	, 0xc9 },
-	{ STB0899_AGC1CN        	, 0x01 },
-	{ STB0899_AGC1REF       	, 0x10 },
+	{ STB0899_DEMOD			, 0x00 },
+	{ STB0899_RCOMPC		, 0xc9 },
+	{ STB0899_AGC1CN		, 0x01 },
+	{ STB0899_AGC1REF		, 0x10 },
 	{ STB0899_RTC			, 0x23 },
-	{ STB0899_TMGCFG        	, 0x4e },
-	{ STB0899_AGC2REF       	, 0x34 },
-	{ STB0899_TLSR          	, 0x84 },
-	{ STB0899_CFD           	, 0xf7 },
+	{ STB0899_TMGCFG		, 0x4e },
+	{ STB0899_AGC2REF		, 0x34 },
+	{ STB0899_TLSR			, 0x84 },
+	{ STB0899_CFD			, 0xf7 },
 	{ STB0899_ACLC			, 0x87 },
-	{ STB0899_BCLC          	, 0x94 },
-	{ STB0899_EQON          	, 0x41 },
-	{ STB0899_LDT           	, 0xf1 },
-	{ STB0899_LDT2          	, 0xe3 },
-	{ STB0899_EQUALREF      	, 0xb4 },
-	{ STB0899_TMGRAMP       	, 0x10 },
-	{ STB0899_TMGTHD        	, 0x30 },
+	{ STB0899_BCLC			, 0x94 },
+	{ STB0899_EQON			, 0x41 },
+	{ STB0899_LDT			, 0xf1 },
+	{ STB0899_LDT2			, 0xe3 },
+	{ STB0899_EQUALREF		, 0xb4 },
+	{ STB0899_TMGRAMP		, 0x10 },
+	{ STB0899_TMGTHD		, 0x30 },
 	{ STB0899_IDCCOMP		, 0xfd },
 	{ STB0899_QDCCOMP		, 0xff },
 	{ STB0899_POWERI		, 0x0c },
@@ -166,12 +166,12 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
 	{ STB0899_NIRL			, 0x80 },
 	{ STB0899_ISYMB			, 0x1d },
 	{ STB0899_QSYMB			, 0xa6 },
-	{ STB0899_SFRH          	, 0x2f },
-	{ STB0899_SFRM          	, 0x68 },
-	{ STB0899_SFRL          	, 0x40 },
-	{ STB0899_SFRUPH        	, 0x2f },
-	{ STB0899_SFRUPM        	, 0x68 },
-	{ STB0899_SFRUPL        	, 0x40 },
+	{ STB0899_SFRH			, 0x2f },
+	{ STB0899_SFRM			, 0x68 },
+	{ STB0899_SFRL			, 0x40 },
+	{ STB0899_SFRUPH		, 0x2f },
+	{ STB0899_SFRUPM		, 0x68 },
+	{ STB0899_SFRUPL		, 0x40 },
 	{ STB0899_EQUAI1		, 0x02 },
 	{ STB0899_EQUAQ1		, 0xff },
 	{ STB0899_EQUAI2		, 0x04 },
@@ -183,7 +183,7 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
 	{ STB0899_EQUAI5		, 0x08 },
 	{ STB0899_EQUAQ5		, 0xf5 },
 	{ STB0899_DSTATUS2		, 0x00 },
-	{ STB0899_VSTATUS       	, 0x00 },
+	{ STB0899_VSTATUS		, 0x00 },
 	{ STB0899_VERROR		, 0x86 },
 	{ STB0899_IQSWAP		, 0x2a },
 	{ STB0899_ECNT1M		, 0x00 },
@@ -192,26 +192,26 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
 	{ STB0899_ECNT2L		, 0x00 },
 	{ STB0899_ECNT3M		, 0x0a },
 	{ STB0899_ECNT3L		, 0xad },
-	{ STB0899_FECAUTO1      	, 0x06 },
+	{ STB0899_FECAUTO1		, 0x06 },
 	{ STB0899_FECM			, 0x01 },
-	{ STB0899_VTH12         	, 0xb0 },
-	{ STB0899_VTH23         	, 0x7a },
+	{ STB0899_VTH12			, 0xb0 },
+	{ STB0899_VTH23			, 0x7a },
 	{ STB0899_VTH34			, 0x58 },
-	{ STB0899_VTH56         	, 0x38 },
-	{ STB0899_VTH67         	, 0x34 },
-	{ STB0899_VTH78         	, 0x24 },
-	{ STB0899_PRVIT         	, 0xff },
-	{ STB0899_VITSYNC       	, 0x19 },
-	{ STB0899_RSULC         	, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
-	{ STB0899_TSULC         	, 0x42 },
-	{ STB0899_RSLLC         	, 0x41 },
+	{ STB0899_VTH56			, 0x38 },
+	{ STB0899_VTH67			, 0x34 },
+	{ STB0899_VTH78			, 0x24 },
+	{ STB0899_PRVIT			, 0xff },
+	{ STB0899_VITSYNC		, 0x19 },
+	{ STB0899_RSULC			, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+	{ STB0899_TSULC			, 0x42 },
+	{ STB0899_RSLLC			, 0x41 },
 	{ STB0899_TSLPL			, 0x12 },
-	{ STB0899_TSCFGH        	, 0x0c },
-	{ STB0899_TSCFGM        	, 0x00 },
-	{ STB0899_TSCFGL        	, 0x00 },
+	{ STB0899_TSCFGH		, 0x0c },
+	{ STB0899_TSCFGM		, 0x00 },
+	{ STB0899_TSCFGL		, 0x00 },
 	{ STB0899_TSOUT			, 0x69 }, /* 0x0d for CAM */
-	{ STB0899_RSSYNCDEL     	, 0x00 },
-	{ STB0899_TSINHDELH     	, 0x02 },
+	{ STB0899_RSSYNCDEL		, 0x00 },
+	{ STB0899_TSINHDELH		, 0x02 },
 	{ STB0899_TSINHDELM		, 0x00 },
 	{ STB0899_TSINHDELL		, 0x00 },
 	{ STB0899_TSLLSTKM		, 0x1b },
@@ -222,18 +222,18 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
 	{ STB0899_PCKLENLL		, 0xcc },
 	{ STB0899_RSPCKLEN		, 0xbd },
 	{ STB0899_TSSTATUS		, 0x90 },
-	{ STB0899_ERRCTRL1      	, 0xb6 },
-	{ STB0899_ERRCTRL2      	, 0x95 },
-	{ STB0899_ERRCTRL3      	, 0x8d },
+	{ STB0899_ERRCTRL1		, 0xb6 },
+	{ STB0899_ERRCTRL2		, 0x95 },
+	{ STB0899_ERRCTRL3		, 0x8d },
 	{ STB0899_DMONMSK1		, 0x27 },
 	{ STB0899_DMONMSK0		, 0x03 },
-	{ STB0899_DEMAPVIT      	, 0x5c },
+	{ STB0899_DEMAPVIT		, 0x5c },
 	{ STB0899_PLPARM		, 0x19 },
-	{ STB0899_PDELCTRL      	, 0x48 },
-	{ STB0899_PDELCTRL2     	, 0x00 },
-	{ STB0899_BBHCTRL1      	, 0x00 },
-	{ STB0899_BBHCTRL2      	, 0x00 },
-	{ STB0899_HYSTTHRESH    	, 0x77 },
+	{ STB0899_PDELCTRL		, 0x48 },
+	{ STB0899_PDELCTRL2		, 0x00 },
+	{ STB0899_BBHCTRL1		, 0x00 },
+	{ STB0899_BBHCTRL2		, 0x00 },
+	{ STB0899_HYSTTHRESH		, 0x77 },
 	{ STB0899_MATCSTM		, 0x00 },
 	{ STB0899_MATCSTL		, 0x00 },
 	{ STB0899_UPLCSTM		, 0x00 },
@@ -270,7 +270,7 @@ static struct stb0899_config vp1041_stb0899_config = {
 	.init_s2_fec		= stb0899_s2_init_4,
 	.init_tst		= stb0899_s1_init_5,
 
-	.demod_address 		= 0x68, /*  0xd0 >> 1 */
+	.demod_address		= 0x68, /*  0xd0 >> 1 */
 
 	.xtal_freq		= 27000000,
 	.inversion		= IQ_SWAP_ON,
diff --git a/drivers/media/pci/mantis/mantis_vp2033.c b/drivers/media/pci/mantis/mantis_vp2033.c
index 8d48b5a..d98e0a3 100644
--- a/drivers/media/pci/mantis/mantis_vp2033.c
+++ b/drivers/media/pci/mantis/mantis_vp2033.c
@@ -22,11 +22,11 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "tda1002x.h"
 #include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_vp2040.c b/drivers/media/pci/mantis/mantis_vp2040.c
index 8dd17d7..2c52f3d 100644
--- a/drivers/media/pci/mantis/mantis_vp2040.c
+++ b/drivers/media/pci/mantis/mantis_vp2040.c
@@ -22,11 +22,11 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "tda1002x.h"
 #include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_vp3028.h b/drivers/media/pci/mantis/mantis_vp3028.h
index b07be6a..34130d2 100644
--- a/drivers/media/pci/mantis/mantis_vp3028.h
+++ b/drivers/media/pci/mantis/mantis_vp3028.h
@@ -21,7 +21,7 @@
 #ifndef __MANTIS_VP3028_H
 #define __MANTIS_VP3028_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mantis_common.h"
 #include "zl10353.h"
 
diff --git a/drivers/media/pci/mantis/mantis_vp3030.c b/drivers/media/pci/mantis/mantis_vp3030.c
index 5c1dd92..14f6e15 100644
--- a/drivers/media/pci/mantis/mantis_vp3030.c
+++ b/drivers/media/pci/mantis/mantis_vp3030.c
@@ -22,11 +22,11 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "zl10353.h"
 #include "tda665x.h"
diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c
index f74b086..ae83293 100644
--- a/drivers/media/pci/meye/meye.c
+++ b/drivers/media/pci/meye/meye.c
@@ -1536,7 +1536,7 @@ static const struct v4l2_ioctl_ops meye_ioctl_ops = {
 static const struct video_device meye_template = {
 	.name		= "meye",
 	.fops		= &meye_fops,
-	.ioctl_ops 	= &meye_ioctl_ops,
+	.ioctl_ops	= &meye_ioctl_ops,
 	.release	= video_device_release_empty,
 };
 
diff --git a/drivers/media/pci/netup_unidvb/Makefile b/drivers/media/pci/netup_unidvb/Makefile
index 07d3f1e..944c3e1 100644
--- a/drivers/media/pci/netup_unidvb/Makefile
+++ b/drivers/media/pci/netup_unidvb/Makefile
@@ -6,5 +6,4 @@
 
 obj-$(CONFIG_DVB_NETUP_UNIDVB) += netup-unidvb.o
 
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb.h b/drivers/media/pci/netup_unidvb/netup_unidvb.h
index 39b08ec..3253ac3 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb.h
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb.h
@@ -24,7 +24,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/videobuf2-dvb.h>
-#include <dvb_ca_en50221.h>
+#include <media/dvb_ca_en50221.h>
 
 #define NETUP_UNIDVB_NAME	"netup_unidvb"
 #define NETUP_UNIDVB_VERSION	"0.0.1"
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index 509d69e..ead59fa 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -862,7 +862,7 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
 		PCI_EXP_DEVCTL_NOSNOOP_EN, 0);
 	/* Adjust PCIe completion timeout. */
 	pcie_capability_clear_and_set_word(pci_dev,
-		PCI_EXP_DEVCTL2, 0xf, 0x2);
+		PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_COMP_TIMEOUT, 0x2);
 
 	if (netup_unidvb_request_mmio(pci_dev)) {
 		dev_err(&pci_dev->dev,
diff --git a/drivers/media/pci/ngene/Makefile b/drivers/media/pci/ngene/Makefile
index dbdf284..e4208f5 100644
--- a/drivers/media/pci/ngene/Makefile
+++ b/drivers/media/pci/ngene/Makefile
@@ -7,7 +7,6 @@
 
 obj-$(CONFIG_DVB_NGENE) += ngene.o
 
-ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/dvb-frontends/
 ccflags-y += -Idrivers/media/tuners/
 
diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h
index 7c7cd21..02dbd18 100644
--- a/drivers/media/pci/ngene/ngene.h
+++ b/drivers/media/pci/ngene/ngene.h
@@ -29,13 +29,13 @@
 
 #include <linux/dvb/frontend.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_ca_en50221.h"
-#include "dvb_frontend.h"
-#include "dvb_ringbuffer.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_ca_en50221.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_ringbuffer.h>
+#include <media/dvb_net.h>
 #include "cxd2099.h"
 
 #define DEVICE_NAME "ngene"
diff --git a/drivers/media/pci/pluto2/Makefile b/drivers/media/pci/pluto2/Makefile
index 524bf84..3c2aea1 100644
--- a/drivers/media/pci/pluto2/Makefile
+++ b/drivers/media/pci/pluto2/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_DVB_PLUTO2) += pluto2.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/dvb-frontends/
diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c
index 39dcba2..5e6fe68 100644
--- a/drivers/media/pci/pluto2/pluto2.c
+++ b/drivers/media/pci/pluto2/pluto2.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2005 Andreas Oberritter <obi@linuxtv.org>
  *
  * based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/
- * 	by Dany Salman <salmandany@yahoo.fr>
+ *	by Dany Salman <salmandany@yahoo.fr>
  *	Copyright (c) 2004 TDF
  *
  * This program is free software; you can redistribute it and/or modify
@@ -29,12 +29,12 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
 #include "tda1004x.h"
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
diff --git a/drivers/media/pci/pt1/Makefile b/drivers/media/pci/pt1/Makefile
index 98e3912..ab873ae 100644
--- a/drivers/media/pci/pt1/Makefile
+++ b/drivers/media/pci/pt1/Makefile
@@ -2,4 +2,4 @@
 
 obj-$(CONFIG_DVB_PT1) += earth-pt1.o
 
-ccflags-y += -Idrivers/media/dvb-core -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
index b6b1a8d..4f6867a 100644
--- a/drivers/media/pci/pt1/pt1.c
+++ b/drivers/media/pci/pt1/pt1.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
  *
  * based on pt1dvr - http://pt1dvr.sourceforge.jp/
- * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,11 +27,11 @@
 #include <linux/freezer.h>
 #include <linux/ratelimit.h>
 
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dmxdev.h"
-#include "dvb_net.h"
-#include "dvb_frontend.h"
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_net.h>
+#include <media/dvb_frontend.h>
 
 #include "va1j5jf8007t.h"
 #include "va1j5jf8007s.h"
@@ -116,8 +116,8 @@ static u32 pt1_read_reg(struct pt1 *pt1, int reg)
 	return readl(pt1->regs + reg * 4);
 }
 
-static int pt1_nr_tables = 8;
-module_param_named(nr_tables, pt1_nr_tables, int, 0);
+static unsigned int pt1_nr_tables = 8;
+module_param_named(nr_tables, pt1_nr_tables, uint, 0);
 
 static void pt1_increment_table_count(struct pt1 *pt1)
 {
@@ -443,6 +443,9 @@ static int pt1_init_tables(struct pt1 *pt1)
 	int i, ret;
 	u32 first_pfn, pfn;
 
+	if (!pt1_nr_tables)
+		return 0;
+
 	tables = vmalloc(sizeof(struct pt1_table) * pt1_nr_tables);
 	if (tables == NULL)
 		return -ENOMEM;
@@ -450,12 +453,10 @@ static int pt1_init_tables(struct pt1 *pt1)
 	pt1_init_table_count(pt1);
 
 	i = 0;
-	if (pt1_nr_tables) {
-		ret = pt1_init_table(pt1, &tables[0], &first_pfn);
-		if (ret)
-			goto err;
-		i++;
-	}
+	ret = pt1_init_table(pt1, &tables[0], &first_pfn);
+	if (ret)
+		goto err;
+	i++;
 
 	while (i < pt1_nr_tables) {
 		ret = pt1_init_table(pt1, &tables[i], &pfn);
diff --git a/drivers/media/pci/pt1/va1j5jf8007s.c b/drivers/media/pci/pt1/va1j5jf8007s.c
index f75f695..f49867a 100644
--- a/drivers/media/pci/pt1/va1j5jf8007s.c
+++ b/drivers/media/pci/pt1/va1j5jf8007s.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
  *
  * based on pt1dvr - http://pt1dvr.sourceforge.jp/
- * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "va1j5jf8007s.h"
 
 enum va1j5jf8007s_tune_state {
diff --git a/drivers/media/pci/pt1/va1j5jf8007s.h b/drivers/media/pci/pt1/va1j5jf8007s.h
index efbe6cc..f8ce560 100644
--- a/drivers/media/pci/pt1/va1j5jf8007s.h
+++ b/drivers/media/pci/pt1/va1j5jf8007s.h
@@ -4,7 +4,7 @@
  * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
  *
  * based on pt1dvr - http://pt1dvr.sourceforge.jp/
- * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/pci/pt1/va1j5jf8007t.c b/drivers/media/pci/pt1/va1j5jf8007t.c
index 63fda79..a52984a 100644
--- a/drivers/media/pci/pt1/va1j5jf8007t.c
+++ b/drivers/media/pci/pt1/va1j5jf8007t.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
  *
  * based on pt1dvr - http://pt1dvr.sourceforge.jp/
- * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,8 +21,8 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
 #include "va1j5jf8007t.h"
 
 enum va1j5jf8007t_tune_state {
diff --git a/drivers/media/pci/pt1/va1j5jf8007t.h b/drivers/media/pci/pt1/va1j5jf8007t.h
index 6fb119c..95eb7d2 100644
--- a/drivers/media/pci/pt1/va1j5jf8007t.h
+++ b/drivers/media/pci/pt1/va1j5jf8007t.h
@@ -4,7 +4,7 @@
  * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
  *
  * based on pt1dvr - http://pt1dvr.sourceforge.jp/
- * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/pci/pt3/Makefile b/drivers/media/pci/pt3/Makefile
index aded875..8698d5d 100644
--- a/drivers/media/pci/pt3/Makefile
+++ b/drivers/media/pci/pt3/Makefile
@@ -4,6 +4,5 @@
 
 obj-$(CONFIG_DVB_PT3) += earth-pt3.o
 
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/pt3/pt3.c b/drivers/media/pci/pt3/pt3.c
index 34044a4..da74828 100644
--- a/drivers/media/pci/pt3/pt3.c
+++ b/drivers/media/pci/pt3/pt3.c
@@ -23,10 +23,10 @@
 #include <linux/string.h>
 #include <linux/sched/signal.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
 
 #include "pt3.h"
 
diff --git a/drivers/media/pci/pt3/pt3.h b/drivers/media/pci/pt3/pt3.h
index 1b3f2ad..fbe8d9b 100644
--- a/drivers/media/pci/pt3/pt3.h
+++ b/drivers/media/pci/pt3/pt3.h
@@ -20,9 +20,9 @@
 #include <linux/atomic.h>
 #include <linux/types.h>
 
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dmxdev.h"
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dmxdev.h>
 
 #include "tc90522.h"
 #include "mxl301rf.h"
diff --git a/drivers/media/pci/pt3/pt3_i2c.c b/drivers/media/pci/pt3/pt3_i2c.c
index ec6a8a2..b66138c 100644
--- a/drivers/media/pci/pt3/pt3_i2c.c
+++ b/drivers/media/pci/pt3/pt3_i2c.c
@@ -85,7 +85,6 @@ static void put_byte_write(struct pt3_i2cbuf *cbuf, u8 val)
 {
 	u8 mask;
 
-	mask = 0x80;
 	for (mask = 0x80; mask > 0; mask >>= 1)
 		cmdbuf_add(cbuf, (val & mask) ? I_DATA_H_NOP : I_DATA_L_NOP);
 	cmdbuf_add(cbuf, I_DATA_H_ACK0);
diff --git a/drivers/media/pci/saa7134/Makefile b/drivers/media/pci/saa7134/Makefile
index dbaaddd..82ac7f3 100644
--- a/drivers/media/pci/saa7134/Makefile
+++ b/drivers/media/pci/saa7134/Makefile
@@ -12,8 +12,6 @@
 
 obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
 
-ccflags-y += -I$(srctree)/drivers/media/i2c
 ccflags-y += -I$(srctree)/drivers/media/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 ccflags-y += -I$(srctree)/drivers/media/usb/go7007
diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c
index 9965d35..9d6688a 100644
--- a/drivers/media/pci/saa7134/saa7134-cards.c
+++ b/drivers/media/pci/saa7134/saa7134-cards.c
@@ -323,7 +323,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.empress_addr 	= 0x20,
+		.empress_addr	= 0x20,
 
 		.inputs         = {{
 			.type = SAA7134_INPUT_COMPOSITE1,
@@ -454,7 +454,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.empress_addr 	= 0x20,
+		.empress_addr	= 0x20,
 		.tda9887_conf	= TDA9887_PRESENT,
 		.gpiomask	= 0x820000,
 		.inputs		= {{
@@ -849,7 +849,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.empress_addr 	= 0x20,
+		.empress_addr	= 0x20,
 		.inputs         = {{
 			.type = SAA7134_INPUT_COMPOSITE1,
 			.vmux = 4,
@@ -1006,7 +1006,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.empress_addr 	= 0x20,
+		.empress_addr	= 0x20,
 		.inputs         = {{
 			.type = SAA7134_INPUT_COMPOSITE1,
 			.vmux = 1,
@@ -1767,7 +1767,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.rds_addr 	= 0x10,
+		.rds_addr	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.type = SAA7134_INPUT_TV,
@@ -2412,7 +2412,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.empress_addr 	= 0x21,
+		.empress_addr	= 0x21,
 		.inputs		= {{
 			.type = SAA7134_INPUT_COMPOSITE0,
 			.vmux   = 0,
@@ -3978,13 +3978,13 @@ struct saa7134_board saa7134_boards[] = {
 	[SAA7134_BOARD_BEHOLD_407] = {
 		/*       Beholder Intl. Ltd. 2008      */
 		/*Dmitry Belimov <d.belimov@gmail.com> */
-		.name 		= "Beholder BeholdTV 407",
-		.audio_clock 	= 0x00187de7,
-		.tuner_type 	= TUNER_PHILIPS_FM1216ME_MK3,
-		.radio_type 	= UNSET,
-		.tuner_addr 	= ADDR_UNSET,
-		.radio_addr 	= ADDR_UNSET,
-		.tda9887_conf 	= TDA9887_PRESENT,
+		.name		= "Beholder BeholdTV 407",
+		.audio_clock	= 0x00187de7,
+		.tuner_type	= TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type	= UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf	= TDA9887_PRESENT,
 		.gpiomask       = 0x00008000,
 		.inputs = {{
 			.type = SAA7134_INPUT_SVIDEO,
@@ -4006,13 +4006,13 @@ struct saa7134_board saa7134_boards[] = {
 	[SAA7134_BOARD_BEHOLD_407FM] = {
 		/*       Beholder Intl. Ltd. 2008      */
 		/*Dmitry Belimov <d.belimov@gmail.com> */
-		.name 		= "Beholder BeholdTV 407 FM",
-		.audio_clock 	= 0x00187de7,
-		.tuner_type 	= TUNER_PHILIPS_FM1216ME_MK3,
-		.radio_type 	= UNSET,
-		.tuner_addr 	= ADDR_UNSET,
-		.radio_addr 	= ADDR_UNSET,
-		.tda9887_conf 	= TDA9887_PRESENT,
+		.name		= "Beholder BeholdTV 407 FM",
+		.audio_clock	= 0x00187de7,
+		.tuner_type	= TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type	= UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf	= TDA9887_PRESENT,
 		.gpiomask       = 0x00008000,
 		.inputs = {{
 			.type = SAA7134_INPUT_SVIDEO,
@@ -4103,7 +4103,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.rds_addr 	= 0x10,
+		.rds_addr	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.gpiomask       = 0x00008000,
 		.inputs         = {{
@@ -4166,7 +4166,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.rds_addr 	= 0x10,
+		.rds_addr	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.gpiomask       = 0x00008000,
 		.inputs         = {{
@@ -4196,7 +4196,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.rds_addr 	= 0x10,
+		.rds_addr	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.gpiomask       = 0x00008000,
 		.inputs         = {{
@@ -4366,7 +4366,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.rds_addr 	= 0x10,
+		.rds_addr	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.type = SAA7134_INPUT_TV,
@@ -4394,7 +4394,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.rds_addr 	= 0x10,
+		.rds_addr	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.type = SAA7134_INPUT_TV,
@@ -4422,7 +4422,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.rds_addr 	= 0x10,
+		.rds_addr	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.type = SAA7134_INPUT_TV,
@@ -4450,7 +4450,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.rds_addr 	= 0x10,
+		.rds_addr	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.type = SAA7134_INPUT_TV,
@@ -4481,7 +4481,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.empress_addr 	= 0x20,
+		.empress_addr	= 0x20,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = { {
 			.type = SAA7134_INPUT_TV,
@@ -4517,7 +4517,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.empress_addr 	= 0x20,
+		.empress_addr	= 0x20,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = { {
 			.type = SAA7134_INPUT_TV,
@@ -4554,8 +4554,8 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.rds_addr 	= 0x10,
-		.empress_addr 	= 0x20,
+		.rds_addr	= 0x10,
+		.empress_addr	= 0x20,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = { {
 			.type = SAA7134_INPUT_TV,
@@ -5297,7 +5297,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
-		.rds_addr 	= 0x10,
+		.rds_addr	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.gpiomask       = 0x00008000,
 		.inputs         = {{
diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c
index 731dee0..a7a63d6 100644
--- a/drivers/media/pci/saa7134/saa7134-dvb.c
+++ b/drivers/media/pci/saa7134/saa7134-dvb.c
@@ -29,7 +29,7 @@
 
 #include <media/v4l2-common.h>
 #include "dvb-pll.h"
-#include <dvb_frontend.h>
+#include <media/dvb_frontend.h>
 
 #include "mt352.h"
 #include "mt352_priv.h" /* FIXME */
@@ -1389,7 +1389,7 @@ static int dvb_init(struct saa7134_dev *dev)
 			if (configure_tda827x_fe(dev, &lifeview_trio_config,
 						 &tda827x_cfg_0) < 0)
 				goto detach_frontend;
-		} else {  		/* satellite */
+		} else {		/* satellite */
 			fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
 			if (fe0->dvb.frontend) {
 				if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63,
@@ -1659,7 +1659,7 @@ static int dvb_init(struct saa7134_dev *dev)
 			if (configure_tda827x_fe(dev, &asus_tiger_3in1_config,
 							&tda827x_cfg_2) < 0)
 				goto detach_frontend;
-		} else {  		/* satellite */
+		} else {		/* satellite */
 			fe0->dvb.frontend = dvb_attach(tda10086_attach,
 						&flydvbs, &dev->i2c_adap);
 			if (fe0->dvb.frontend) {
diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
index 2d5abed..33ee832 100644
--- a/drivers/media/pci/saa7134/saa7134-input.c
+++ b/drivers/media/pci/saa7134/saa7134-input.c
@@ -43,7 +43,8 @@ MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=g
 	} while (0)
 #define ir_dbg(ir, fmt, arg...) do { \
 	if (ir_debug) \
-		printk(KERN_DEBUG pr_fmt("ir %s: " fmt), ir->name, ## arg); \
+		printk(KERN_DEBUG pr_fmt("ir %s: " fmt), ir->rc->device_name, \
+		       ## arg); \
 	} while (0)
 
 /* Helper function for raw decoding at GPIO16 or GPIO18 */
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 0ceaa34..1ca6a32 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -1531,6 +1531,8 @@ int saa7134_querycap(struct file *file, void *priv,
 	case VFL_TYPE_VBI:
 		cap->device_caps |= vbi_caps;
 		break;
+	default:
+		return -EINVAL;
 	}
 	cap->capabilities = radio_caps | video_caps | vbi_caps |
 		cap->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -2041,14 +2043,14 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
 struct video_device saa7134_video_template = {
 	.name				= "saa7134-video",
 	.fops				= &video_fops,
-	.ioctl_ops 			= &video_ioctl_ops,
+	.ioctl_ops			= &video_ioctl_ops,
 	.tvnorms			= SAA7134_NORMS,
 };
 
 struct video_device saa7134_radio_template = {
 	.name			= "saa7134-radio",
 	.fops			= &radio_fops,
-	.ioctl_ops 		= &radio_ioctl_ops,
+	.ioctl_ops		= &radio_ioctl_ops,
 };
 
 static const struct v4l2_ctrl_ops saa7134_ctrl_ops = {
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index 39c36e6..d99e937 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -261,8 +261,8 @@ struct saa7134_card_ir {
 #define SAA7134_BOARD_SABRENT_TV_PCB05     115
 #define SAA7134_BOARD_10MOONSTVMASTER3     116
 #define SAA7134_BOARD_AVERMEDIA_SUPER_007  117
-#define SAA7134_BOARD_BEHOLD_401  	118
-#define SAA7134_BOARD_BEHOLD_403  	119
+#define SAA7134_BOARD_BEHOLD_401	118
+#define SAA7134_BOARD_BEHOLD_403	119
 #define SAA7134_BOARD_BEHOLD_403FM	120
 #define SAA7134_BOARD_BEHOLD_405	121
 #define SAA7134_BOARD_BEHOLD_405FM	122
@@ -581,7 +581,7 @@ struct saa7134_dev {
 	/* config info */
 	unsigned int               board;
 	unsigned int               tuner_type;
-	unsigned int 		   radio_type;
+	unsigned int		   radio_type;
 	unsigned char		   tuner_addr;
 	unsigned char		   radio_addr;
 
@@ -592,7 +592,7 @@ struct saa7134_dev {
 	struct i2c_adapter         i2c_adap;
 	struct i2c_client          i2c_client;
 	unsigned char              eedata[256];
-	int 			   has_rds;
+	int			   has_rds;
 
 	/* video overlay */
 	struct v4l2_framebuffer    ovbuf;
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c
index d31a2d4..5817d9c 100644
--- a/drivers/media/pci/saa7146/hexium_gemini.c
+++ b/drivers/media/pci/saa7146/hexium_gemini.c
@@ -27,6 +27,7 @@
 
 #include <media/drv-intf/saa7146_vv.h>
 #include <linux/module.h>
+#include <linux/kernel.h>
 
 static int debug;
 module_param(debug, int, 0);
@@ -69,8 +70,8 @@ struct hexium
 	struct video_device	video_dev;
 	struct i2c_adapter	i2c_adapter;
 
-	int 		cur_input;	/* current input */
-	v4l2_std_id 	cur_std;	/* current standard */
+	int		cur_input;	/* current input */
+	v4l2_std_id	cur_std;	/* current standard */
 };
 
 /* Samsung KS0127B decoder default registers */
@@ -137,19 +138,19 @@ static struct hexium_data hexium_input_select[] = {
    are currently *not* supported*/
 static struct saa7146_standard hexium_standards[] = {
 	{
-		.name	= "PAL", 	.id	= V4L2_STD_PAL,
-		.v_offset	= 28,	.v_field 	= 288,
-		.h_offset	= 1,	.h_pixels 	= 680,
+		.name	= "PAL",	.id	= V4L2_STD_PAL,
+		.v_offset	= 28,	.v_field	= 288,
+		.h_offset	= 1,	.h_pixels	= 680,
 		.v_max_out	= 576,	.h_max_out	= 768,
 	}, {
-		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
-		.v_offset	= 28,	.v_field 	= 240,
-		.h_offset	= 1,	.h_pixels 	= 640,
+		.name	= "NTSC",	.id	= V4L2_STD_NTSC,
+		.v_offset	= 28,	.v_field	= 240,
+		.h_offset	= 1,	.h_pixels	= 640,
 		.v_max_out	= 480,	.h_max_out	= 640,
 	}, {
-		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,
-		.v_offset	= 28,	.v_field 	= 288,
-		.h_offset	= 1,	.h_pixels 	= 720,
+		.name	= "SECAM",	.id	= V4L2_STD_SECAM,
+		.v_offset	= 28,	.v_field	= 288,
+		.h_offset	= 1,	.h_pixels	= 720,
 		.v_max_out	= 576,	.h_max_out	= 768,
 	}
 };
@@ -388,7 +389,7 @@ static struct saa7146_ext_vv vv_data = {
 	.inputs = HEXIUM_INPUTS,
 	.capabilities = 0,
 	.stds = &hexium_standards[0],
-	.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
+	.num_stds = ARRAY_SIZE(hexium_standards),
 	.std_callback = &std_callback,
 };
 
diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c
index 043318a..0a05176 100644
--- a/drivers/media/pci/saa7146/hexium_orion.c
+++ b/drivers/media/pci/saa7146/hexium_orion.c
@@ -27,6 +27,7 @@
 
 #include <media/drv-intf/saa7146_vv.h>
 #include <linux/module.h>
+#include <linux/kernel.h>
 
 static int debug;
 module_param(debug, int, 0);
@@ -187,19 +188,19 @@ static struct {
 
 static struct saa7146_standard hexium_standards[] = {
 	{
-		.name	= "PAL", 	.id	= V4L2_STD_PAL,
-		.v_offset	= 16,	.v_field 	= 288,
-		.h_offset	= 1,	.h_pixels 	= 680,
+		.name	= "PAL",	.id	= V4L2_STD_PAL,
+		.v_offset	= 16,	.v_field	= 288,
+		.h_offset	= 1,	.h_pixels	= 680,
 		.v_max_out	= 576,	.h_max_out	= 768,
 	}, {
-		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
-		.v_offset	= 16,	.v_field 	= 240,
-		.h_offset	= 1,	.h_pixels 	= 640,
+		.name	= "NTSC",	.id	= V4L2_STD_NTSC,
+		.v_offset	= 16,	.v_field	= 240,
+		.h_offset	= 1,	.h_pixels	= 640,
 		.v_max_out	= 480,	.h_max_out	= 640,
 	}, {
-		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,
-		.v_offset	= 16,	.v_field 	= 288,
-		.h_offset	= 1,	.h_pixels 	= 720,
+		.name	= "SECAM",	.id	= V4L2_STD_SECAM,
+		.v_offset	= 16,	.v_field	= 288,
+		.h_offset	= 1,	.h_pixels	= 720,
 		.v_max_out	= 576,	.h_max_out	= 768,
 	}
 };
@@ -460,7 +461,7 @@ static struct saa7146_ext_vv vv_data = {
 	.inputs = HEXIUM_INPUTS,
 	.capabilities = 0,
 	.stds = &hexium_standards[0],
-	.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
+	.num_stds = ARRAY_SIZE(hexium_standards),
 	.std_callback = &std_callback,
 };
 
diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c
index 930218c..6b5582b 100644
--- a/drivers/media/pci/saa7146/mxb.c
+++ b/drivers/media/pci/saa7146/mxb.c
@@ -3,7 +3,7 @@
 
     Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
 
-    Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html 
+    Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html
     for further details about this card.
 
     This program is free software; you can redistribute it and/or modify
@@ -30,6 +30,7 @@
 #include <media/v4l2-common.h>
 #include <media/i2c/saa7115.h>
 #include <linux/module.h>
+#include <linux/kernel.h>
 
 #include "tea6415c.h"
 #include "tea6420.h"
@@ -792,24 +793,24 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
 
 static struct saa7146_standard standard[] = {
 	{
-		.name	= "PAL-BG", 	.id	= V4L2_STD_PAL_BG,
-		.v_offset	= 0x17,	.v_field 	= 288,
-		.h_offset	= 0x14,	.h_pixels 	= 680,
+		.name	= "PAL-BG",	.id	= V4L2_STD_PAL_BG,
+		.v_offset	= 0x17,	.v_field	= 288,
+		.h_offset	= 0x14,	.h_pixels	= 680,
 		.v_max_out	= 576,	.h_max_out	= 768,
 	}, {
-		.name	= "PAL-I", 	.id	= V4L2_STD_PAL_I,
-		.v_offset	= 0x17,	.v_field 	= 288,
-		.h_offset	= 0x14,	.h_pixels 	= 680,
+		.name	= "PAL-I",	.id	= V4L2_STD_PAL_I,
+		.v_offset	= 0x17,	.v_field	= 288,
+		.h_offset	= 0x14,	.h_pixels	= 680,
 		.v_max_out	= 576,	.h_max_out	= 768,
 	}, {
-		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
-		.v_offset	= 0x16,	.v_field 	= 240,
-		.h_offset	= 0x06,	.h_pixels 	= 708,
+		.name	= "NTSC",	.id	= V4L2_STD_NTSC,
+		.v_offset	= 0x16,	.v_field	= 240,
+		.h_offset	= 0x06,	.h_pixels	= 708,
 		.v_max_out	= 480,	.h_max_out	= 640,
 	}, {
-		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,
-		.v_offset	= 0x14,	.v_field 	= 288,
-		.h_offset	= 0x14,	.h_pixels 	= 720,
+		.name	= "SECAM",	.id	= V4L2_STD_SECAM,
+		.v_offset	= 0x14,	.v_field	= 288,
+		.h_offset	= 0x14,	.h_pixels	= 720,
 		.v_max_out	= 576,	.h_max_out	= 768,
 	}
 };
@@ -837,7 +838,7 @@ static struct saa7146_ext_vv vv_data = {
 	.inputs		= MXB_INPUTS,
 	.capabilities	= V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_AUDIO,
 	.stds		= &standard[0],
-	.num_stds	= sizeof(standard)/sizeof(struct saa7146_standard),
+	.num_stds	= ARRAY_SIZE(standard),
 	.std_callback	= &std_callback,
 };
 
diff --git a/drivers/media/pci/saa7164/Makefile b/drivers/media/pci/saa7164/Makefile
index 3896bcd..dea0767 100644
--- a/drivers/media/pci/saa7164/Makefile
+++ b/drivers/media/pci/saa7164/Makefile
@@ -5,9 +5,5 @@
 
 obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
 
-ccflags-y += -I$(srctree)/drivers/media/i2c
 ccflags-y += -I$(srctree)/drivers/media/tuners
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
-
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h
index 81b3f0e1..f3358f4 100644
--- a/drivers/media/pci/saa7164/saa7164.h
+++ b/drivers/media/pci/saa7164/saa7164.h
@@ -50,11 +50,11 @@
 
 #include <media/tuner.h>
 #include <media/tveeprom.h>
-#include <dvb_demux.h>
-#include <dvb_frontend.h>
-#include <dvb_net.h>
-#include <dvbdev.h>
-#include <dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
+#include <media/dmxdev.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
diff --git a/drivers/media/pci/smipcie/Makefile b/drivers/media/pci/smipcie/Makefile
index 6006aac..214ebfe 100644
--- a/drivers/media/pci/smipcie/Makefile
+++ b/drivers/media/pci/smipcie/Makefile
@@ -5,6 +5,5 @@
 obj-$(CONFIG_DVB_SMIPCIE) += smipcie.o
 
 ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 
diff --git a/drivers/media/pci/smipcie/smipcie.h b/drivers/media/pci/smipcie/smipcie.h
index c8368c7..a6c5b1b 100644
--- a/drivers/media/pci/smipcie/smipcie.h
+++ b/drivers/media/pci/smipcie/smipcie.h
@@ -29,12 +29,12 @@
 #include <linux/slab.h>
 #include <media/rc-core.h>
 
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
 
 /* -------- Register Base -------- */
 #define    MSI_CONTROL_REG_BASE                 0x0800
diff --git a/drivers/media/pci/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c
index ca0873e..19ffd2e 100644
--- a/drivers/media/pci/solo6x10/solo6x10-core.c
+++ b/drivers/media/pci/solo6x10/solo6x10-core.c
@@ -47,18 +47,19 @@ MODULE_PARM_DESC(full_eeprom, "Allow access to full 128B EEPROM (dangerous)");
 
 static void solo_set_time(struct solo_dev *solo_dev)
 {
-	struct timespec ts;
+	struct timespec64 ts;
 
-	ktime_get_ts(&ts);
+	ktime_get_ts64(&ts);
 
-	solo_reg_write(solo_dev, SOLO_TIMER_SEC, ts.tv_sec);
-	solo_reg_write(solo_dev, SOLO_TIMER_USEC, ts.tv_nsec / NSEC_PER_USEC);
+	/* no overflow because we use monotonic timestamps */
+	solo_reg_write(solo_dev, SOLO_TIMER_SEC, (u32)ts.tv_sec);
+	solo_reg_write(solo_dev, SOLO_TIMER_USEC, (u32)ts.tv_nsec / NSEC_PER_USEC);
 }
 
 static void solo_timer_sync(struct solo_dev *solo_dev)
 {
 	u32 sec, usec;
-	struct timespec ts;
+	struct timespec64 ts;
 	long diff;
 
 	if (solo_dev->type != SOLO_DEV_6110)
@@ -72,11 +73,11 @@ static void solo_timer_sync(struct solo_dev *solo_dev)
 	sec = solo_reg_read(solo_dev, SOLO_TIMER_SEC);
 	usec = solo_reg_read(solo_dev, SOLO_TIMER_USEC);
 
-	ktime_get_ts(&ts);
+	ktime_get_ts64(&ts);
 
-	diff = (long)ts.tv_sec - (long)sec;
+	diff = (s32)ts.tv_sec - (s32)sec;
 	diff = (diff * 1000000)
-		+ ((long)(ts.tv_nsec / NSEC_PER_USEC) - (long)usec);
+		+ ((s32)(ts.tv_nsec / NSEC_PER_USEC) - (s32)usec);
 
 	if (diff > 1000 || diff < -1000) {
 		solo_set_time(solo_dev);
diff --git a/drivers/media/pci/solo6x10/solo6x10-gpio.c b/drivers/media/pci/solo6x10/solo6x10-gpio.c
index 3d0d1aa..7b4641a 100644
--- a/drivers/media/pci/solo6x10/solo6x10-gpio.c
+++ b/drivers/media/pci/solo6x10/solo6x10-gpio.c
@@ -162,7 +162,9 @@ static void solo_gpiochip_set(struct gpio_chip *chip,
 
 int solo_gpio_init(struct solo_dev *solo_dev)
 {
+#ifdef CONFIG_GPIOLIB
 	int ret;
+#endif
 
 	solo_gpio_config(solo_dev);
 #ifdef CONFIG_GPIOLIB
diff --git a/drivers/media/pci/ttpci/Makefile b/drivers/media/pci/ttpci/Makefile
index 0b80533..58ca127 100644
--- a/drivers/media/pci/ttpci/Makefile
+++ b/drivers/media/pci/ttpci/Makefile
@@ -18,5 +18,5 @@
 obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
 obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/dvb-frontends/
 ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c
index 6d415bd..dc8e577 100644
--- a/drivers/media/pci/ttpci/av7110.c
+++ b/drivers/media/pci/ttpci/av7110.c
@@ -53,7 +53,7 @@
 
 #include <linux/dvb/frontend.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "ttpci-eeprom.h"
 #include "av7110.h"
diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h
index cbb150d..8606ef5 100644
--- a/drivers/media/pci/ttpci/av7110.h
+++ b/drivers/media/pci/ttpci/av7110.h
@@ -17,14 +17,14 @@
 #include <linux/dvb/net.h>
 #include <linux/mutex.h>
 
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_demux.h"
-#include "dmxdev.h"
+#include <media/dvbdev.h>
+#include <media/demux.h>
+#include <media/dvb_demux.h>
+#include <media/dmxdev.h>
 #include "dvb_filter.h"
-#include "dvb_net.h"
-#include "dvb_ringbuffer.h"
-#include "dvb_frontend.h"
+#include <media/dvb_net.h>
+#include <media/dvb_ringbuffer.h>
+#include <media/dvb_frontend.h>
 #include "ves1820.h"
 #include "ves1x93.h"
 #include "stv0299.h"
@@ -52,7 +52,7 @@ extern int av7110_debug;
 enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM};
 
 enum av7110_video_mode {
-	AV7110_VIDEO_MODE_PAL 	= 0,
+	AV7110_VIDEO_MODE_PAL	= 0,
 	AV7110_VIDEO_MODE_NTSC	= 1
 };
 
diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c
index ac83fff..abc98f1 100644
--- a/drivers/media/pci/ttpci/budget-av.c
+++ b/drivers/media/pci/ttpci/budget-av.c
@@ -51,7 +51,7 @@
 #include <linux/input.h>
 #include <linux/spinlock.h>
 
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 
 #define DEBICICAM		0x02420000
 
@@ -1181,14 +1181,14 @@ static u8 read_pwm(struct budget_av *budget_av)
 #define SUBID_DVBS_KNC1_PLUS		0x0011
 #define SUBID_DVBS_TYPHOON		0x4f56
 #define SUBID_DVBS_CINERGY1200		0x1154
-#define SUBID_DVBS_CYNERGY1200N 	0x1155
+#define SUBID_DVBS_CYNERGY1200N		0x1155
 #define SUBID_DVBS_TV_STAR		0x0014
 #define SUBID_DVBS_TV_STAR_PLUS_X4	0x0015
 #define SUBID_DVBS_TV_STAR_CI		0x0016
 #define SUBID_DVBS2_KNC1		0x0018
 #define SUBID_DVBS2_KNC1_OEM		0x0019
-#define SUBID_DVBS_EASYWATCH_1  	0x001a
-#define SUBID_DVBS_EASYWATCH_2  	0x001b
+#define SUBID_DVBS_EASYWATCH_1		0x001a
+#define SUBID_DVBS_EASYWATCH_2		0x001b
 #define SUBID_DVBS2_EASYWATCH		0x001d
 #define SUBID_DVBS_EASYWATCH		0x001e
 
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
index 57af118..ec8f925 100644
--- a/drivers/media/pci/ttpci/budget-ci.c
+++ b/drivers/media/pci/ttpci/budget-ci.c
@@ -35,7 +35,7 @@
 
 #include "budget.h"
 
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 #include "stv0299.h"
 #include "stv0297.h"
 #include "tda1004x.h"
@@ -1050,70 +1050,70 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
 
 	{ STB0899_DEV_ID		, 0x81 },
 	{ STB0899_DISCNTRL1		, 0x32 },
-	{ STB0899_DISCNTRL2     	, 0x80 },
-	{ STB0899_DISRX_ST0     	, 0x04 },
-	{ STB0899_DISRX_ST1     	, 0x00 },
-	{ STB0899_DISPARITY     	, 0x00 },
+	{ STB0899_DISCNTRL2		, 0x80 },
+	{ STB0899_DISRX_ST0		, 0x04 },
+	{ STB0899_DISRX_ST1		, 0x00 },
+	{ STB0899_DISPARITY		, 0x00 },
 	{ STB0899_DISSTATUS		, 0x20 },
-	{ STB0899_DISF22        	, 0x8c },
-	{ STB0899_DISF22RX      	, 0x9a },
+	{ STB0899_DISF22		, 0x8c },
+	{ STB0899_DISF22RX		, 0x9a },
 	{ STB0899_SYSREG		, 0x0b },
-	{ STB0899_ACRPRESC      	, 0x11 },
-	{ STB0899_ACRDIV1       	, 0x0a },
-	{ STB0899_ACRDIV2       	, 0x05 },
-	{ STB0899_DACR1         	, 0x00 },
-	{ STB0899_DACR2         	, 0x00 },
-	{ STB0899_OUTCFG        	, 0x00 },
-	{ STB0899_MODECFG       	, 0x00 },
+	{ STB0899_ACRPRESC		, 0x11 },
+	{ STB0899_ACRDIV1		, 0x0a },
+	{ STB0899_ACRDIV2		, 0x05 },
+	{ STB0899_DACR1			, 0x00 },
+	{ STB0899_DACR2			, 0x00 },
+	{ STB0899_OUTCFG		, 0x00 },
+	{ STB0899_MODECFG		, 0x00 },
 	{ STB0899_IRQSTATUS_3		, 0x30 },
 	{ STB0899_IRQSTATUS_2		, 0x00 },
 	{ STB0899_IRQSTATUS_1		, 0x00 },
 	{ STB0899_IRQSTATUS_0		, 0x00 },
-	{ STB0899_IRQMSK_3      	, 0xf3 },
-	{ STB0899_IRQMSK_2      	, 0xfc },
-	{ STB0899_IRQMSK_1      	, 0xff },
+	{ STB0899_IRQMSK_3		, 0xf3 },
+	{ STB0899_IRQMSK_2		, 0xfc },
+	{ STB0899_IRQMSK_1		, 0xff },
 	{ STB0899_IRQMSK_0		, 0xff },
 	{ STB0899_IRQCFG		, 0x00 },
-	{ STB0899_I2CCFG        	, 0x88 },
-	{ STB0899_I2CRPT        	, 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
+	{ STB0899_I2CCFG		, 0x88 },
+	{ STB0899_I2CRPT		, 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
 	{ STB0899_IOPVALUE5		, 0x00 },
 	{ STB0899_IOPVALUE4		, 0x20 },
 	{ STB0899_IOPVALUE3		, 0xc9 },
 	{ STB0899_IOPVALUE2		, 0x90 },
 	{ STB0899_IOPVALUE1		, 0x40 },
 	{ STB0899_IOPVALUE0		, 0x00 },
-	{ STB0899_GPIO00CFG     	, 0x82 },
-	{ STB0899_GPIO01CFG     	, 0x82 },
-	{ STB0899_GPIO02CFG     	, 0x82 },
-	{ STB0899_GPIO03CFG     	, 0x82 },
-	{ STB0899_GPIO04CFG     	, 0x82 },
-	{ STB0899_GPIO05CFG     	, 0x82 },
-	{ STB0899_GPIO06CFG     	, 0x82 },
-	{ STB0899_GPIO07CFG     	, 0x82 },
-	{ STB0899_GPIO08CFG     	, 0x82 },
-	{ STB0899_GPIO09CFG     	, 0x82 },
-	{ STB0899_GPIO10CFG     	, 0x82 },
-	{ STB0899_GPIO11CFG     	, 0x82 },
-	{ STB0899_GPIO12CFG     	, 0x82 },
-	{ STB0899_GPIO13CFG     	, 0x82 },
-	{ STB0899_GPIO14CFG     	, 0x82 },
-	{ STB0899_GPIO15CFG     	, 0x82 },
-	{ STB0899_GPIO16CFG     	, 0x82 },
-	{ STB0899_GPIO17CFG     	, 0x82 },
-	{ STB0899_GPIO18CFG     	, 0x82 },
-	{ STB0899_GPIO19CFG     	, 0x82 },
-	{ STB0899_GPIO20CFG     	, 0x82 },
-	{ STB0899_SDATCFG       	, 0xb8 },
-	{ STB0899_SCLTCFG       	, 0xba },
-	{ STB0899_AGCRFCFG      	, 0x1c }, /* 0x11 */
-	{ STB0899_GPIO22        	, 0x82 }, /* AGCBB2CFG */
-	{ STB0899_GPIO21        	, 0x91 }, /* AGCBB1CFG */
-	{ STB0899_DIRCLKCFG     	, 0x82 },
-	{ STB0899_CLKOUT27CFG   	, 0x7e },
-	{ STB0899_STDBYCFG      	, 0x82 },
-	{ STB0899_CS0CFG        	, 0x82 },
-	{ STB0899_CS1CFG        	, 0x82 },
-	{ STB0899_DISEQCOCFG    	, 0x20 },
+	{ STB0899_GPIO00CFG		, 0x82 },
+	{ STB0899_GPIO01CFG		, 0x82 },
+	{ STB0899_GPIO02CFG		, 0x82 },
+	{ STB0899_GPIO03CFG		, 0x82 },
+	{ STB0899_GPIO04CFG		, 0x82 },
+	{ STB0899_GPIO05CFG		, 0x82 },
+	{ STB0899_GPIO06CFG		, 0x82 },
+	{ STB0899_GPIO07CFG		, 0x82 },
+	{ STB0899_GPIO08CFG		, 0x82 },
+	{ STB0899_GPIO09CFG		, 0x82 },
+	{ STB0899_GPIO10CFG		, 0x82 },
+	{ STB0899_GPIO11CFG		, 0x82 },
+	{ STB0899_GPIO12CFG		, 0x82 },
+	{ STB0899_GPIO13CFG		, 0x82 },
+	{ STB0899_GPIO14CFG		, 0x82 },
+	{ STB0899_GPIO15CFG		, 0x82 },
+	{ STB0899_GPIO16CFG		, 0x82 },
+	{ STB0899_GPIO17CFG		, 0x82 },
+	{ STB0899_GPIO18CFG		, 0x82 },
+	{ STB0899_GPIO19CFG		, 0x82 },
+	{ STB0899_GPIO20CFG		, 0x82 },
+	{ STB0899_SDATCFG		, 0xb8 },
+	{ STB0899_SCLTCFG		, 0xba },
+	{ STB0899_AGCRFCFG		, 0x1c }, /* 0x11 */
+	{ STB0899_GPIO22		, 0x82 }, /* AGCBB2CFG */
+	{ STB0899_GPIO21		, 0x91 }, /* AGCBB1CFG */
+	{ STB0899_DIRCLKCFG		, 0x82 },
+	{ STB0899_CLKOUT27CFG		, 0x7e },
+	{ STB0899_STDBYCFG		, 0x82 },
+	{ STB0899_CS0CFG		, 0x82 },
+	{ STB0899_CS1CFG		, 0x82 },
+	{ STB0899_DISEQCOCFG		, 0x20 },
 	{ STB0899_GPIO32CFG		, 0x82 },
 	{ STB0899_GPIO33CFG		, 0x82 },
 	{ STB0899_GPIO34CFG		, 0x82 },
@@ -1122,35 +1122,35 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
 	{ STB0899_GPIO37CFG		, 0x82 },
 	{ STB0899_GPIO38CFG		, 0x82 },
 	{ STB0899_GPIO39CFG		, 0x82 },
-	{ STB0899_NCOARSE       	, 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
-	{ STB0899_SYNTCTRL      	, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
-	{ STB0899_FILTCTRL      	, 0x00 },
-	{ STB0899_SYSCTRL       	, 0x00 },
-	{ STB0899_STOPCLK1      	, 0x20 },
-	{ STB0899_STOPCLK2      	, 0x00 },
+	{ STB0899_NCOARSE		, 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+	{ STB0899_SYNTCTRL		, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+	{ STB0899_FILTCTRL		, 0x00 },
+	{ STB0899_SYSCTRL		, 0x00 },
+	{ STB0899_STOPCLK1		, 0x20 },
+	{ STB0899_STOPCLK2		, 0x00 },
 	{ STB0899_INTBUFSTATUS		, 0x00 },
-	{ STB0899_INTBUFCTRL    	, 0x0a },
+	{ STB0899_INTBUFCTRL		, 0x0a },
 	{ 0xffff			, 0xff },
 };
 
 static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
-	{ STB0899_DEMOD         	, 0x00 },
-	{ STB0899_RCOMPC        	, 0xc9 },
-	{ STB0899_AGC1CN        	, 0x41 },
-	{ STB0899_AGC1REF       	, 0x10 },
+	{ STB0899_DEMOD			, 0x00 },
+	{ STB0899_RCOMPC		, 0xc9 },
+	{ STB0899_AGC1CN		, 0x41 },
+	{ STB0899_AGC1REF		, 0x10 },
 	{ STB0899_RTC			, 0x7a },
-	{ STB0899_TMGCFG        	, 0x4e },
-	{ STB0899_AGC2REF       	, 0x34 },
-	{ STB0899_TLSR          	, 0x84 },
-	{ STB0899_CFD           	, 0xc7 },
+	{ STB0899_TMGCFG		, 0x4e },
+	{ STB0899_AGC2REF		, 0x34 },
+	{ STB0899_TLSR			, 0x84 },
+	{ STB0899_CFD			, 0xc7 },
 	{ STB0899_ACLC			, 0x87 },
-	{ STB0899_BCLC          	, 0x94 },
-	{ STB0899_EQON          	, 0x41 },
-	{ STB0899_LDT           	, 0xdd },
-	{ STB0899_LDT2          	, 0xc9 },
-	{ STB0899_EQUALREF      	, 0xb4 },
-	{ STB0899_TMGRAMP       	, 0x10 },
-	{ STB0899_TMGTHD        	, 0x30 },
+	{ STB0899_BCLC			, 0x94 },
+	{ STB0899_EQON			, 0x41 },
+	{ STB0899_LDT			, 0xdd },
+	{ STB0899_LDT2			, 0xc9 },
+	{ STB0899_EQUALREF		, 0xb4 },
+	{ STB0899_TMGRAMP		, 0x10 },
+	{ STB0899_TMGTHD		, 0x30 },
 	{ STB0899_IDCCOMP		, 0xfb },
 	{ STB0899_QDCCOMP		, 0x03 },
 	{ STB0899_POWERI		, 0x3b },
@@ -1169,12 +1169,12 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
 	{ STB0899_NIRL			, 0x05 },
 	{ STB0899_ISYMB			, 0x17 },
 	{ STB0899_QSYMB			, 0xfa },
-	{ STB0899_SFRH          	, 0x2f },
-	{ STB0899_SFRM          	, 0x68 },
-	{ STB0899_SFRL          	, 0x40 },
-	{ STB0899_SFRUPH        	, 0x2f },
-	{ STB0899_SFRUPM        	, 0x68 },
-	{ STB0899_SFRUPL        	, 0x40 },
+	{ STB0899_SFRH			, 0x2f },
+	{ STB0899_SFRM			, 0x68 },
+	{ STB0899_SFRL			, 0x40 },
+	{ STB0899_SFRUPH		, 0x2f },
+	{ STB0899_SFRUPM		, 0x68 },
+	{ STB0899_SFRUPL		, 0x40 },
 	{ STB0899_EQUAI1		, 0xfd },
 	{ STB0899_EQUAQ1		, 0x04 },
 	{ STB0899_EQUAI2		, 0x0f },
@@ -1186,7 +1186,7 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
 	{ STB0899_EQUAI5		, 0xbd },
 	{ STB0899_EQUAQ5		, 0xf7 },
 	{ STB0899_DSTATUS2		, 0x00 },
-	{ STB0899_VSTATUS       	, 0x00 },
+	{ STB0899_VSTATUS		, 0x00 },
 	{ STB0899_VERROR		, 0xff },
 	{ STB0899_IQSWAP		, 0x2a },
 	{ STB0899_ECNT1M		, 0x00 },
@@ -1195,26 +1195,26 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
 	{ STB0899_ECNT2L		, 0x00 },
 	{ STB0899_ECNT3M		, 0x00 },
 	{ STB0899_ECNT3L		, 0x00 },
-	{ STB0899_FECAUTO1      	, 0x06 },
+	{ STB0899_FECAUTO1		, 0x06 },
 	{ STB0899_FECM			, 0x01 },
-	{ STB0899_VTH12         	, 0xf0 },
-	{ STB0899_VTH23         	, 0xa0 },
+	{ STB0899_VTH12			, 0xf0 },
+	{ STB0899_VTH23			, 0xa0 },
 	{ STB0899_VTH34			, 0x78 },
-	{ STB0899_VTH56         	, 0x4e },
-	{ STB0899_VTH67         	, 0x48 },
-	{ STB0899_VTH78         	, 0x38 },
-	{ STB0899_PRVIT         	, 0xff },
-	{ STB0899_VITSYNC       	, 0x19 },
-	{ STB0899_RSULC         	, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
-	{ STB0899_TSULC         	, 0x42 },
-	{ STB0899_RSLLC         	, 0x40 },
+	{ STB0899_VTH56			, 0x4e },
+	{ STB0899_VTH67			, 0x48 },
+	{ STB0899_VTH78			, 0x38 },
+	{ STB0899_PRVIT			, 0xff },
+	{ STB0899_VITSYNC		, 0x19 },
+	{ STB0899_RSULC			, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+	{ STB0899_TSULC			, 0x42 },
+	{ STB0899_RSLLC			, 0x40 },
 	{ STB0899_TSLPL			, 0x12 },
-	{ STB0899_TSCFGH        	, 0x0c },
-	{ STB0899_TSCFGM        	, 0x00 },
-	{ STB0899_TSCFGL        	, 0x0c },
+	{ STB0899_TSCFGH		, 0x0c },
+	{ STB0899_TSCFGM		, 0x00 },
+	{ STB0899_TSCFGL		, 0x0c },
 	{ STB0899_TSOUT			, 0x4d }, /* 0x0d for CAM */
-	{ STB0899_RSSYNCDEL     	, 0x00 },
-	{ STB0899_TSINHDELH     	, 0x02 },
+	{ STB0899_RSSYNCDEL		, 0x00 },
+	{ STB0899_TSINHDELH		, 0x02 },
 	{ STB0899_TSINHDELM		, 0x00 },
 	{ STB0899_TSINHDELL		, 0x00 },
 	{ STB0899_TSLLSTKM		, 0x00 },
@@ -1225,18 +1225,18 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
 	{ STB0899_PCKLENLL		, 0xcc },
 	{ STB0899_RSPCKLEN		, 0xcc },
 	{ STB0899_TSSTATUS		, 0x80 },
-	{ STB0899_ERRCTRL1      	, 0xb6 },
-	{ STB0899_ERRCTRL2      	, 0x96 },
-	{ STB0899_ERRCTRL3      	, 0x89 },
+	{ STB0899_ERRCTRL1		, 0xb6 },
+	{ STB0899_ERRCTRL2		, 0x96 },
+	{ STB0899_ERRCTRL3		, 0x89 },
 	{ STB0899_DMONMSK1		, 0x27 },
 	{ STB0899_DMONMSK0		, 0x03 },
-	{ STB0899_DEMAPVIT      	, 0x5c },
+	{ STB0899_DEMAPVIT		, 0x5c },
 	{ STB0899_PLPARM		, 0x1f },
-	{ STB0899_PDELCTRL      	, 0x48 },
-	{ STB0899_PDELCTRL2     	, 0x00 },
-	{ STB0899_BBHCTRL1      	, 0x00 },
-	{ STB0899_BBHCTRL2      	, 0x00 },
-	{ STB0899_HYSTTHRESH    	, 0x77 },
+	{ STB0899_PDELCTRL		, 0x48 },
+	{ STB0899_PDELCTRL2		, 0x00 },
+	{ STB0899_BBHCTRL1		, 0x00 },
+	{ STB0899_BBHCTRL2		, 0x00 },
+	{ STB0899_HYSTTHRESH		, 0x77 },
 	{ STB0899_MATCSTM		, 0x00 },
 	{ STB0899_MATCSTL		, 0x00 },
 	{ STB0899_UPLCSTM		, 0x00 },
@@ -1275,7 +1275,7 @@ static struct stb0899_config tt3200_config = {
 
 	.postproc		= NULL,
 
-	.demod_address 		= 0x68,
+	.demod_address		= 0x68,
 
 	.xtal_freq		= 27000000,
 	.inversion		= IQ_SWAP_ON,
diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h
index fae8386..a7463da 100644
--- a/drivers/media/pci/ttpci/budget.h
+++ b/drivers/media/pci/ttpci/budget.h
@@ -3,13 +3,13 @@
 #ifndef __BUDGET_DVB__
 #define __BUDGET_DVB__
 
-#include "dvb_frontend.h"
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_demux.h"
-#include "dmxdev.h"
+#include <media/dvb_frontend.h>
+#include <media/dvbdev.h>
+#include <media/demux.h>
+#include <media/dvb_demux.h>
+#include <media/dmxdev.h>
 #include "dvb_filter.h"
-#include "dvb_net.h"
+#include <media/dvb_net.h>
 
 #include <linux/module.h>
 #include <linux/mutex.h>
diff --git a/drivers/media/pci/ttpci/dvb_filter.h b/drivers/media/pci/ttpci/dvb_filter.h
index 3d410d0..67a3c63 100644
--- a/drivers/media/pci/ttpci/dvb_filter.h
+++ b/drivers/media/pci/ttpci/dvb_filter.h
@@ -19,7 +19,7 @@
 
 #include <linux/slab.h>
 
-#include "demux.h"
+#include <media/demux.h>
 
 typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
 
diff --git a/drivers/media/pci/tw5864/tw5864-video.c b/drivers/media/pci/tw5864/tw5864-video.c
index e7bd2b8..ff2b7da 100644
--- a/drivers/media/pci/tw5864/tw5864-video.c
+++ b/drivers/media/pci/tw5864/tw5864-video.c
@@ -730,7 +730,7 @@ static int tw5864_frameinterval_get(struct tw5864_input *input,
 		frameinterval->denominator = 25;
 		break;
 	default:
-	        dev_warn(&dev->pci->dev, "tw5864_frameinterval_get requested for unknown std %d\n",
+		dev_warn(&dev->pci->dev, "tw5864_frameinterval_get requested for unknown std %d\n",
 			 input->std);
 		return -EINVAL;
 	}
diff --git a/drivers/media/pci/zoran/videocodec.c b/drivers/media/pci/zoran/videocodec.c
index 303289a..5ff23ef 100644
--- a/drivers/media/pci/zoran/videocodec.c
+++ b/drivers/media/pci/zoran/videocodec.c
@@ -325,7 +325,6 @@ static int proc_videocodecs_show(struct seq_file *m, void *v)
 	seq_printf(m, "<S>lave or attached <M>aster name  type flags    magic    ");
 	seq_printf(m, "(connected as)\n");
 
-	h = codeclist_top;
 	while (h) {
 		seq_printf(m, "S %32s %04x %08lx %08lx (TEMPLATE)\n",
 			      h->codec->name, h->codec->type,
diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c
index b6a6c4f..c464dae 100644
--- a/drivers/media/pci/zoran/zoran_driver.c
+++ b/drivers/media/pci/zoran/zoran_driver.c
@@ -2792,21 +2792,21 @@ zoran_mmap (struct file           *file,
 }
 
 static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
-	.vidioc_querycap    		    = zoran_querycap,
+	.vidioc_querycap		    = zoran_querycap,
 	.vidioc_s_selection		    = zoran_s_selection,
 	.vidioc_g_selection		    = zoran_g_selection,
-	.vidioc_enum_input     		    = zoran_enum_input,
-	.vidioc_g_input      		    = zoran_g_input,
-	.vidioc_s_input      		    = zoran_s_input,
-	.vidioc_enum_output    		    = zoran_enum_output,
-	.vidioc_g_output     		    = zoran_g_output,
-	.vidioc_s_output     		    = zoran_s_output,
+	.vidioc_enum_input		    = zoran_enum_input,
+	.vidioc_g_input			    = zoran_g_input,
+	.vidioc_s_input			    = zoran_s_input,
+	.vidioc_enum_output		    = zoran_enum_output,
+	.vidioc_g_output		    = zoran_g_output,
+	.vidioc_s_output		    = zoran_s_output,
 	.vidioc_g_fbuf			    = zoran_g_fbuf,
 	.vidioc_s_fbuf			    = zoran_s_fbuf,
-	.vidioc_g_std 			    = zoran_g_std,
-	.vidioc_s_std 			    = zoran_s_std,
-	.vidioc_g_jpegcomp 		    = zoran_g_jpegcomp,
-	.vidioc_s_jpegcomp 		    = zoran_s_jpegcomp,
+	.vidioc_g_std			    = zoran_g_std,
+	.vidioc_s_std			    = zoran_s_std,
+	.vidioc_g_jpegcomp		    = zoran_g_jpegcomp,
+	.vidioc_s_jpegcomp		    = zoran_s_jpegcomp,
 	.vidioc_overlay			    = zoran_overlay,
 	.vidioc_reqbufs			    = zoran_reqbufs,
 	.vidioc_querybuf		    = zoran_querybuf,
@@ -2814,18 +2814,18 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
 	.vidioc_dqbuf			    = zoran_dqbuf,
 	.vidioc_streamon		    = zoran_streamon,
 	.vidioc_streamoff		    = zoran_streamoff,
-	.vidioc_enum_fmt_vid_cap 	    = zoran_enum_fmt_vid_cap,
-	.vidioc_enum_fmt_vid_out 	    = zoran_enum_fmt_vid_out,
-	.vidioc_enum_fmt_vid_overlay 	    = zoran_enum_fmt_vid_overlay,
-	.vidioc_g_fmt_vid_cap 		    = zoran_g_fmt_vid_cap,
+	.vidioc_enum_fmt_vid_cap	    = zoran_enum_fmt_vid_cap,
+	.vidioc_enum_fmt_vid_out	    = zoran_enum_fmt_vid_out,
+	.vidioc_enum_fmt_vid_overlay	    = zoran_enum_fmt_vid_overlay,
+	.vidioc_g_fmt_vid_cap		    = zoran_g_fmt_vid_cap,
 	.vidioc_g_fmt_vid_out               = zoran_g_fmt_vid_out,
 	.vidioc_g_fmt_vid_overlay           = zoran_g_fmt_vid_overlay,
-	.vidioc_s_fmt_vid_cap  		    = zoran_s_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap		    = zoran_s_fmt_vid_cap,
 	.vidioc_s_fmt_vid_out               = zoran_s_fmt_vid_out,
 	.vidioc_s_fmt_vid_overlay           = zoran_s_fmt_vid_overlay,
-	.vidioc_try_fmt_vid_cap  	    = zoran_try_fmt_vid_cap,
-	.vidioc_try_fmt_vid_out 	    = zoran_try_fmt_vid_out,
-	.vidioc_try_fmt_vid_overlay 	    = zoran_try_fmt_vid_overlay,
+	.vidioc_try_fmt_vid_cap		    = zoran_try_fmt_vid_cap,
+	.vidioc_try_fmt_vid_out		    = zoran_try_fmt_vid_out,
+	.vidioc_try_fmt_vid_overlay	    = zoran_try_fmt_vid_overlay,
 	.vidioc_subscribe_event             = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event           = v4l2_event_unsubscribe,
 };
diff --git a/drivers/media/pci/zoran/zr36057.h b/drivers/media/pci/zoran/zr36057.h
index c9ffef1..c8acb21 100644
--- a/drivers/media/pci/zoran/zr36057.h
+++ b/drivers/media/pci/zoran/zr36057.h
@@ -103,8 +103,8 @@
 #define ZR36057_ICR_IntPinEn            (1<<24)
 
 #define ZR36057_I2CBR           0x044	/* I2C Bus Register */
-#define ZR36057_I2CBR_SDA       	(1<<1)
-#define ZR36057_I2CBR_SCL       	(1<<0)
+#define ZR36057_I2CBR_SDA		(1<<1)
+#define ZR36057_I2CBR_SCL		(1<<0)
 
 #define ZR36057_JMC             0x100	/* JPEG Mode and Control */
 #define ZR36057_JMC_JPG                 (1 << 31)
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index fd0c998..614fbef 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -353,10 +353,10 @@
 	depends on DEBUG_FS
 	help
 	  Select this to see information about the internal state and the last
-          operation of STMicroelectronics HVA multi-format video encoder in
-          debugfs.
+	  operation of STMicroelectronics HVA multi-format video encoder in
+	  debugfs.
 
-          Choose N unless you know you need this.
+	  Choose N unless you know you need this.
 
 config VIDEO_STI_DELTA
 	tristate "STMicroelectronics DELTA multi-format video decoder V4L2 driver"
@@ -586,10 +586,10 @@
        select CEC_CORE
        select CEC_NOTIFIER
        ---help---
-         This is a driver for Samsung S5P HDMI CEC interface. It uses the
-         generic CEC framework interface.
-         CEC bus is present in the HDMI connector and enables communication
-         between compatible devices.
+	 This is a driver for Samsung S5P HDMI CEC interface. It uses the
+	 generic CEC framework interface.
+	 CEC bus is present in the HDMI connector and enables communication
+	 between compatible devices.
 
 config VIDEO_STI_HDMI_CEC
        tristate "STMicroelectronics STiH4xx HDMI CEC driver"
@@ -597,10 +597,10 @@
        select CEC_CORE
        select CEC_NOTIFIER
        ---help---
-         This is a driver for STIH4xx HDMI CEC interface. It uses the
-         generic CEC framework interface.
-         CEC bus is present in the HDMI connector and enables communication
-         between compatible devices.
+	 This is a driver for STIH4xx HDMI CEC interface. It uses the
+	 generic CEC framework interface.
+	 CEC bus is present in the HDMI connector and enables communication
+	 between compatible devices.
 
 config VIDEO_STM32_HDMI_CEC
        tristate "STMicroelectronics STM32 HDMI CEC driver"
@@ -609,10 +609,10 @@
        select REGMAP_MMIO
        select CEC_CORE
        ---help---
-         This is a driver for STM32 interface. It uses the
-         generic CEC framework interface.
-         CEC bus is present in the HDMI connector and enables communication
-         between compatible devices.
+	 This is a driver for STM32 interface. It uses the
+	 generic CEC framework interface.
+	 CEC bus is present in the HDMI connector and enables communication
+	 between compatible devices.
 
 config VIDEO_TEGRA_HDMI_CEC
        tristate "Tegra HDMI CEC driver"
@@ -620,10 +620,10 @@
        select CEC_CORE
        select CEC_NOTIFIER
        ---help---
-         This is a driver for the Tegra HDMI CEC interface. It uses the
-         generic CEC framework interface.
-         The CEC bus is present in the HDMI connector and enables communication
-         between compatible devices.
+	 This is a driver for the Tegra HDMI CEC interface. It uses the
+	 generic CEC framework interface.
+	 The CEC bus is present in the HDMI connector and enables communication
+	 between compatible devices.
 
 endif #CEC_PLATFORM_DRIVERS
 
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 003b0bb..7f30804 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -23,7 +23,7 @@
 obj-$(CONFIG_VIDEO_TI_CAL)		+= ti-vpe/
 
 obj-$(CONFIG_VIDEO_MX2_EMMAPRP)		+= mx2_emmaprp.o
-obj-$(CONFIG_VIDEO_CODA) 		+= coda/
+obj-$(CONFIG_VIDEO_CODA)		+= coda/
 
 obj-$(CONFIG_VIDEO_SH_VEU)		+= sh_veu.o
 
@@ -33,8 +33,8 @@
 
 obj-$(CONFIG_VIDEO_MUX)			+= video-mux.o
 
-obj-$(CONFIG_VIDEO_S3C_CAMIF) 		+= s3c-camif/
-obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS) 	+= exynos4-is/
+obj-$(CONFIG_VIDEO_S3C_CAMIF)		+= s3c-camif/
+obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS)	+= exynos4-is/
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG)	+= s5p-jpeg/
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC)	+= s5p-mfc/
 
@@ -45,13 +45,13 @@
 obj-$(CONFIG_VIDEO_STI_BDISP)		+= sti/bdisp/
 obj-$(CONFIG_VIDEO_STI_HVA)		+= sti/hva/
 obj-$(CONFIG_DVB_C8SECTPFE)		+= sti/c8sectpfe/
-obj-$(CONFIG_VIDEO_STI_HDMI_CEC) 	+= sti/cec/
+obj-$(CONFIG_VIDEO_STI_HDMI_CEC)	+= sti/cec/
 
 obj-$(CONFIG_VIDEO_STI_DELTA)		+= sti/delta/
 
 obj-$(CONFIG_VIDEO_TEGRA_HDMI_CEC)	+= tegra-cec/
 
-obj-y 					+= stm32/
+obj-y					+= stm32/
 
 obj-y                                   += blackfin/
 
@@ -62,9 +62,9 @@
 obj-$(CONFIG_SOC_CAMERA)		+= soc_camera/
 
 obj-$(CONFIG_VIDEO_RCAR_DRIF)		+= rcar_drif.o
-obj-$(CONFIG_VIDEO_RENESAS_FCP) 	+= rcar-fcp.o
+obj-$(CONFIG_VIDEO_RENESAS_FCP)		+= rcar-fcp.o
 obj-$(CONFIG_VIDEO_RENESAS_FDP1)	+= rcar_fdp1.o
-obj-$(CONFIG_VIDEO_RENESAS_JPU) 	+= rcar_jpu.o
+obj-$(CONFIG_VIDEO_RENESAS_JPU)		+= rcar_jpu.o
 obj-$(CONFIG_VIDEO_RENESAS_VSP1)	+= vsp1/
 
 obj-$(CONFIG_VIDEO_ROCKCHIP_RGA)	+= rockchip/rga/
@@ -82,8 +82,6 @@
 
 obj-$(CONFIG_VIDEO_STM32_DCMI)		+= stm32/
 
-ccflags-y += -I$(srctree)/drivers/media/i2c
-
 obj-$(CONFIG_VIDEO_MEDIATEK_VPU)	+= mtk-vpu/
 
 obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC)	+= mtk-vcodec/
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
index 0997c64..601ae64 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -2304,8 +2304,8 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
 	vpfe_dbg(1, vpfe, "vpfe_async_bound\n");
 
 	for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) {
-		if (vpfe->cfg->asd[i]->match.fwnode.fwnode ==
-		    asd[i].match.fwnode.fwnode) {
+		if (vpfe->cfg->asd[i]->match.fwnode ==
+		    asd[i].match.fwnode) {
 			sdinfo = &vpfe->cfg->sub_devs[i];
 			vpfe->sd[i] = subdev;
 			vpfe->sd[i]->grp_id = sdinfo->grp_id;
@@ -2510,7 +2510,7 @@ vpfe_get_pdata(struct platform_device *pdev)
 		}
 
 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		pdata->asd[i]->match.fwnode.fwnode = of_fwnode_handle(rem);
+		pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);
 		of_node_put(rem);
 	}
 
diff --git a/drivers/media/platform/arv.c b/drivers/media/platform/arv.c
index 8fe59bf..1e865fe 100644
--- a/drivers/media/platform/arv.c
+++ b/drivers/media/platform/arv.c
@@ -56,7 +56,7 @@
 
 #define VERSION	"0.0.5"
 
-#define ar_inl(addr) 		inl((unsigned long)(addr))
+#define ar_inl(addr)		inl((unsigned long)(addr))
 #define ar_outl(val, addr)	outl((unsigned long)(val), (unsigned long)(addr))
 
 extern struct cpuinfo_m32r	boot_cpu_data;
@@ -66,7 +66,7 @@ extern struct cpuinfo_m32r	boot_cpu_data;
  *	Note that M32700UT does not support CIF mode, but QVGA is
  *	supported by M32700UT hardware using VGA mode of AR LSI.
  *
- * 	Supported: VGA  (Normal mode, Interlace mode)
+ *	Supported: VGA  (Normal mode, Interlace mode)
  *		   QVGA (Always Interlace mode of VGA)
  *
  */
@@ -210,8 +210,8 @@ static void init_iic(void)
 	 * ICU Setting (iic)
 	 */
 	/* I2C Setting */
-	ar_outl(0x0, PLDI2CCR);      	/* I2CCR Disable                   */
-	ar_outl(0x0300, PLDI2CMOD); 	/* I2CMOD ACK/8b-data/7b-addr/auto */
+	ar_outl(0x0, PLDI2CCR);		/* I2CCR Disable                   */
+	ar_outl(0x0300, PLDI2CMOD);	/* I2CMOD ACK/8b-data/7b-addr/auto */
 	ar_outl(0x1, PLDI2CACK);	/* I2CACK ACK                      */
 
 	/* I2C CLK */
@@ -222,7 +222,7 @@ static void init_iic(void)
 		ar_outl(244, PLDI2CFREQ);	/* BCLK = 50MHz */
 	else
 		ar_outl(244, PLDI2CFREQ);	/* default: BCLK = 50MHz */
-	ar_outl(0x1, PLDI2CCR); 	/* I2CCR Enable */
+	ar_outl(0x1, PLDI2CCR);		/* I2CCR Enable */
 }
 
 /**************************************************************************
@@ -300,9 +300,9 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 	ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
 	ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
 	ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL);	/* destination addr. */
-	ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); 	/* reload address */
-	ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); 	/* byte count (bytes) */
-	ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); 	/* reload count (bytes) */
+	ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL);	/* reload address */
+	ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL);	/* byte count (bytes) */
+	ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL);	/* reload count (bytes) */
 
 	/*
 	 * Okay, kick AR LSI to invoke an interrupt
@@ -364,7 +364,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 
 	/*
 	 * convert YUV422 to YUV422P
-	 * 	+--------------------+
+	 *	+--------------------+
 	 *	|  Y0,Y1,...	     |
 	 *	|  ..............Yn  |
 	 *	+--------------------+
@@ -533,9 +533,9 @@ static void ar_interrupt(int irq, void *dev)
 	line_count = ar_inl(ARVHCOUNT);			/* line number */
 	if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
 		/* operations for interlace mode */
-		if (line_count < (AR_HEIGHT_VGA / 2)) 	/* even line */
+		if (line_count < (AR_HEIGHT_VGA / 2))	/* even line */
 			line_number = (line_count << 1);
-		else 					/* odd line */
+		else					/* odd line */
 			line_number =
 			(((line_count - (AR_HEIGHT_VGA / 2)) << 1) + 1);
 	} else {
@@ -568,7 +568,7 @@ static void ar_interrupt(int irq, void *dev)
 		 * if captured all line of a frame, disable AR interrupt
 		 * and wake a process up.
 		 */
-		if (line_number == (ar->height - 1)) { 	/* end  of line */
+		if (line_number == (ar->height - 1)) {	/* end  of line */
 
 			ar->start_capture = 0;
 
@@ -590,7 +590,7 @@ static void ar_interrupt(int irq, void *dev)
 
 /*
  * ar_initialize()
- * 	ar_initialize() is called by video_register_device() and
+ *	ar_initialize() is called by video_register_device() and
  *	initializes AR LSI and peripherals.
  *
  *	-1 is returned in all failures.
@@ -718,14 +718,14 @@ static const struct v4l2_file_operations ar_fops = {
 };
 
 static const struct v4l2_ioctl_ops ar_ioctl_ops = {
-	.vidioc_querycap    		    = ar_querycap,
-	.vidioc_g_input      		    = ar_g_input,
-	.vidioc_s_input      		    = ar_s_input,
-	.vidioc_enum_input   		    = ar_enum_input,
-	.vidioc_enum_fmt_vid_cap 	    = ar_enum_fmt_vid_cap,
-	.vidioc_g_fmt_vid_cap 		    = ar_g_fmt_vid_cap,
-	.vidioc_s_fmt_vid_cap  		    = ar_s_fmt_vid_cap,
-	.vidioc_try_fmt_vid_cap  	    = ar_try_fmt_vid_cap,
+	.vidioc_querycap		    = ar_querycap,
+	.vidioc_g_input			    = ar_g_input,
+	.vidioc_s_input			    = ar_s_input,
+	.vidioc_enum_input		    = ar_enum_input,
+	.vidioc_enum_fmt_vid_cap	    = ar_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap		    = ar_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap		    = ar_s_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap		    = ar_try_fmt_vid_cap,
 };
 
 #define ALIGN4(x)	((((int)(x)) & 0x3) == 0)
@@ -776,9 +776,9 @@ static int __init ar_init(void)
 	video_set_drvdata(&ar->vdev, ar);
 
 	if (vga) {
-		ar->width 	= AR_WIDTH_VGA;
-		ar->height 	= AR_HEIGHT_VGA;
-		ar->size 	= AR_SIZE_VGA;
+		ar->width	= AR_WIDTH_VGA;
+		ar->height	= AR_HEIGHT_VGA;
+		ar->size	= AR_SIZE_VGA;
 		ar->frame_bytes = AR_FRAME_BYTES_VGA;
 		ar->line_bytes	= AR_LINE_BYTES_VGA;
 		if (vga_interlace)
@@ -786,9 +786,9 @@ static int __init ar_init(void)
 		else
 			ar->mode = AR_MODE_NORMAL;
 	} else {
-		ar->width 	= AR_WIDTH_QVGA;
-		ar->height 	= AR_HEIGHT_QVGA;
-		ar->size 	= AR_SIZE_QVGA;
+		ar->width	= AR_WIDTH_QVGA;
+		ar->height	= AR_HEIGHT_QVGA;
+		ar->size	= AR_SIZE_QVGA;
 		ar->frame_bytes = AR_FRAME_BYTES_QVGA;
 		ar->line_bytes	= AR_LINE_BYTES_QVGA;
 		ar->mode	= AR_MODE_INTERLACE;
diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c
index 13f1c1c..3467640 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -2039,10 +2039,10 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
 
 	INIT_LIST_HEAD(&isc->subdev_entities);
 
-	for (; ;) {
+	while (1) {
 		epn = of_graph_get_next_endpoint(np, epn);
 		if (!epn)
-			break;
+			return 0;
 
 		rem = of_graph_get_remote_port_parent(epn);
 		if (!rem) {
@@ -2088,7 +2088,7 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
 			subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW;
 
 		subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		subdev_entity->asd->match.fwnode.fwnode =
+		subdev_entity->asd->match.fwnode =
 			of_fwnode_handle(rem);
 		list_add_tail(&subdev_entity->list, &isc->subdev_entities);
 	}
diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index e900995..9958918 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -1128,7 +1128,7 @@ static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
 		/* Remote node to connect */
 		isi->entity.node = remote;
 		isi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		isi->entity.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		isi->entity.asd.match.fwnode = of_fwnode_handle(remote);
 		return 0;
 	}
 }
diff --git a/drivers/media/platform/blackfin/ppi.c b/drivers/media/platform/blackfin/ppi.c
index 478eb2f..d3dc765 100644
--- a/drivers/media/platform/blackfin/ppi.c
+++ b/drivers/media/platform/blackfin/ppi.c
@@ -52,7 +52,7 @@ static irqreturn_t ppi_irq_err(int irq, void *dev_id)
 		struct bfin_ppi_regs *reg = info->base;
 		unsigned short status;
 
-		/* register on bf561 is cleared when read 
+		/* register on bf561 is cleared when read
 		 * others are W1C
 		 */
 		status = bfin_read16(&reg->status);
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index bfc4ecf..9fe113cb 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -395,6 +395,7 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx,
 
 	if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 ||
 	    ctx->codec->dst_fourcc == V4L2_PIX_FMT_H264 ||
+	    ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4 ||
 	    ctx->codec->dst_fourcc == V4L2_PIX_FMT_MPEG4) {
 		width = round_up(q_data->width, 16);
 		height = round_up(q_data->height, 16);
@@ -413,8 +414,10 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx,
 			size = round_up(ysize, 4096) + ysize / 2;
 		else
 			size = ysize + ysize / 2;
-		if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 &&
-		    dev->devtype->product != CODA_DX6)
+		/* Add space for mvcol buffers */
+		if (dev->devtype->product != CODA_DX6 &&
+		    (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 ||
+		     (ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4 && i == 0)))
 			size += ysize / 4;
 		name = kasprintf(GFP_KERNEL, "fb%d", i);
 		if (!name) {
@@ -452,17 +455,15 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx,
 		coda_parabuf_write(ctx, i * 3 + 1, cb);
 		coda_parabuf_write(ctx, i * 3 + 2, cr);
 
-		/* mvcol buffer for h.264 */
-		if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 &&
-		    dev->devtype->product != CODA_DX6)
-			coda_parabuf_write(ctx, 96 + i, mvcol);
-	}
+		if (dev->devtype->product == CODA_DX6)
+			continue;
 
-	/* mvcol buffer for mpeg4 */
-	if ((dev->devtype->product != CODA_DX6) &&
-	    (ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4))
-		coda_parabuf_write(ctx, 97, ctx->internal_frames[0].paddr +
-					    ysize + ysize/4 + ysize/4);
+		/* mvcol buffer for h.264 and mpeg4 */
+		if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264)
+			coda_parabuf_write(ctx, 96 + i, mvcol);
+		if (ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4 && i == 0)
+			coda_parabuf_write(ctx, 97, mvcol);
+	}
 
 	return 0;
 }
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index 15eb5dc..e8a7554 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -486,8 +486,8 @@ static int coda_try_fmt_vdoa(struct coda_ctx *ctx, struct v4l2_format *f,
 		return 0;
 	}
 
-	err = vdoa_context_configure(NULL, f->fmt.pix.width, f->fmt.pix.height,
-				     f->fmt.pix.pixelformat);
+	err = vdoa_context_configure(NULL, round_up(f->fmt.pix.width, 16),
+				     f->fmt.pix.height, f->fmt.pix.pixelformat);
 	if (err) {
 		*use_vdoa = false;
 		return 0;
@@ -730,7 +730,8 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f,
 	if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP &&
 	    !coda_try_fmt_vdoa(ctx, f, &ctx->use_vdoa) &&
 	    ctx->use_vdoa)
-		vdoa_context_configure(ctx->vdoa, f->fmt.pix.width,
+		vdoa_context_configure(ctx->vdoa,
+				       round_up(f->fmt.pix.width, 16),
 				       f->fmt.pix.height,
 				       f->fmt.pix.pixelformat);
 	else
@@ -1884,6 +1885,12 @@ static int coda_queue_init(struct coda_ctx *ctx, struct vb2_queue *vq)
 	 * that videobuf2 will keep the value of bytesused intact.
 	 */
 	vq->allow_zero_bytesused = 1;
+	/*
+	 * We might be fine with no buffers on some of the queues, but that
+	 * would need to be reflected in job_ready(). Currently we expect all
+	 * queues to have at least one buffer queued.
+	 */
+	vq->min_buffers_needed = 1;
 	vq->dev = &ctx->dev->plat_dev->dev;
 
 	return vb2_queue_init(vq);
diff --git a/drivers/media/platform/coda/coda_regs.h b/drivers/media/platform/coda/coda_regs.h
index 38df5fd..3b650b8 100644
--- a/drivers/media/platform/coda/coda_regs.h
+++ b/drivers/media/platform/coda/coda_regs.h
@@ -125,7 +125,7 @@
 #define		CODA9_MODE_ENCODE_H264		8
 #define		CODA9_MODE_ENCODE_MP4		11
 #define		CODA9_MODE_ENCODE_MJPG		13
-#define 	CODA_MODE_INVALID		0xffff
+#define		CODA_MODE_INVALID		0xffff
 #define CODA_REG_BIT_INT_ENABLE		0x170
 #define		CODA_INT_INTERRUPT_ENABLE	(1 << 3)
 #define CODA_REG_BIT_INT_REASON			0x174
@@ -254,7 +254,6 @@
 #define		CODA9_STD_H264					0
 #define		CODA_STD_H263					1
 #define		CODA_STD_H264					2
-#define		CODA_STD_MJPG					3
 #define		CODA9_STD_MPEG4					3
 
 #define CODA_CMD_ENC_SEQ_SRC_SIZE				0x190
diff --git a/drivers/media/platform/coda/imx-vdoa.c b/drivers/media/platform/coda/imx-vdoa.c
index 8eb3e0c..85a66e4e 100644
--- a/drivers/media/platform/coda/imx-vdoa.c
+++ b/drivers/media/platform/coda/imx-vdoa.c
@@ -86,7 +86,6 @@ struct vdoa_data {
 	struct device		*dev;
 	struct clk		*vdoa_clk;
 	void __iomem		*regs;
-	int			irq;
 };
 
 struct vdoa_q_data {
@@ -293,6 +292,7 @@ static int vdoa_probe(struct platform_device *pdev)
 {
 	struct vdoa_data *vdoa;
 	struct resource *res;
+	int ret;
 
 	dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
 
@@ -316,12 +316,12 @@ static int vdoa_probe(struct platform_device *pdev)
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res)
 		return -EINVAL;
-	vdoa->irq = devm_request_threaded_irq(&pdev->dev, res->start, NULL,
+	ret = devm_request_threaded_irq(&pdev->dev, res->start, NULL,
 					vdoa_irq_handler, IRQF_ONESHOT,
 					"vdoa", vdoa);
-	if (vdoa->irq < 0) {
+	if (ret < 0) {
 		dev_err(vdoa->dev, "Failed to get irq\n");
-		return vdoa->irq;
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, vdoa);
diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c
index 89cb309..238d01b 100644
--- a/drivers/media/platform/davinci/dm355_ccdc.c
+++ b/drivers/media/platform/davinci/dm355_ccdc.c
@@ -20,10 +20,10 @@
  * pre-process the Bayer RGB data, before writing it to SDRAM.
  *
  * TODO: 1) Raw bayer parameter settings and bayer capture
- * 	 2) Split module parameter structure to module specific ioctl structs
+ *	 2) Split module parameter structure to module specific ioctl structs
  *	 3) add support for lense shading correction
  *	 4) investigate if enum used for user space type definition
- * 	    to be replaced by #defines or integer
+ *	    to be replaced by #defines or integer
  */
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
diff --git a/drivers/media/platform/davinci/dm355_ccdc_regs.h b/drivers/media/platform/davinci/dm355_ccdc_regs.h
index a753ce2..20ba390 100644
--- a/drivers/media/platform/davinci/dm355_ccdc_regs.h
+++ b/drivers/media/platform/davinci/dm355_ccdc_regs.h
@@ -107,7 +107,7 @@
 #define CCDC_RAW_IP_MODE			0
 #define CCDC_VDHDOUT_INPUT			0
 #define CCDC_YCINSWP_RAW			(0 << 4)
-#define CCDC_EXWEN_DISABLE 			0
+#define CCDC_EXWEN_DISABLE			0
 #define CCDC_DATAPOL_NORMAL			0
 #define CCDC_CCDCFG_FIDMD_LATCH_VSYNC		0
 #define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC	(1 << 6)
@@ -152,7 +152,7 @@
 #define CCDC_ALAW_GAMMA_WD_MASK			7
 #define CCDC_REC656IF_BT656_EN			3
 
-#define CCDC_FMTCFG_FMTMODE_MASK 		3
+#define CCDC_FMTCFG_FMTMODE_MASK		3
 #define CCDC_FMTCFG_FMTMODE_SHIFT		1
 #define CCDC_FMTCFG_LNUM_MASK			3
 #define CCDC_FMTCFG_LNUM_SHIFT			4
@@ -196,7 +196,7 @@
 #define CCDC_LATCH_ON_VSYNC_DISABLE		(1 << 15)
 #define CCDC_LATCH_ON_VSYNC_ENABLE		(0 << 15)
 #define CCDC_FPC_ENABLE				(1 << 15)
-#define CCDC_FPC_FPC_NUM_MASK 			0x7FFF
+#define CCDC_FPC_FPC_NUM_MASK			0x7FFF
 #define CCDC_DATA_PACK_ENABLE			(1 << 11)
 #define CCDC_FMT_HORZ_FMTLNH_MASK		0x1FFF
 #define CCDC_FMT_HORZ_FMTSPH_MASK		0x1FFF
diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c
index 5fa0a1f..592d3fc 100644
--- a/drivers/media/platform/davinci/dm644x_ccdc.c
+++ b/drivers/media/platform/davinci/dm644x_ccdc.c
@@ -22,9 +22,9 @@
  * may be supported using the same module.
  *
  * TODO: Test Raw bayer parameter settings and bayer capture
- * 	 Split module parameter structure to module specific ioctl structs
- * 	 investigate if enum used for user space type definition
- * 	 to be replaced by #defines or integer
+ *	 Split module parameter structure to module specific ioctl structs
+ *	 investigate if enum used for user space type definition
+ *	 to be replaced by #defines or integer
  */
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
diff --git a/drivers/media/platform/davinci/dm644x_ccdc_regs.h b/drivers/media/platform/davinci/dm644x_ccdc_regs.h
index bece0bd..ffd89c7 100644
--- a/drivers/media/platform/davinci/dm644x_ccdc_regs.h
+++ b/drivers/media/platform/davinci/dm644x_ccdc_regs.h
@@ -97,7 +97,7 @@
 #define CCDC_LATCH_ON_VSYNC_DISABLE		(1 << 15)
 #define CCDC_FPC_ENABLE				(1 << 15)
 #define CCDC_FPC_DISABLE			0
-#define CCDC_FPC_FPC_NUM_MASK 			0x7FFF
+#define CCDC_FPC_FPC_NUM_MASK			0x7FFF
 #define CCDC_DATA_PACK_ENABLE			(1 << 11)
 #define CCDC_FMTCFG_VPIN_MASK			7
 #define CCDC_FMTCFG_VPIN_SHIFT			12
@@ -143,7 +143,7 @@
 #define CCDC_REC656IF_BT656_EN			3
 #define CCDC_SYN_MODE_VD_POL_NEGATIVE		(1 << 2)
 #define CCDC_CCDCFG_Y8POS_SHIFT			11
-#define CCDC_CCDCFG_BW656_10BIT 		(1 << 5)
+#define CCDC_CCDCFG_BW656_10BIT			(1 << 5)
 #define CCDC_SDOFST_FIELD_INTERLEAVED		0x249
 #define CCDC_NO_CULLING				0xffff00ff
 #endif
diff --git a/drivers/media/platform/davinci/isif_regs.h b/drivers/media/platform/davinci/isif_regs.h
index a3564ab..97d3ba1 100644
--- a/drivers/media/platform/davinci/isif_regs.h
+++ b/drivers/media/platform/davinci/isif_regs.h
@@ -35,7 +35,7 @@
 #define LINCFG0					0x44
 #define LINCFG1					0x48
 #define CCOLP					0x4c
-#define CRGAIN 					0x50
+#define CRGAIN					0x50
 #define CGRGAIN					0x54
 #define CGBGAIN					0x58
 #define CBGAIN					0x5c
@@ -46,7 +46,7 @@
 #define VDINT0					0x70
 #define VDINT1					0x74
 #define VDINT2					0x78
-#define MISC 					0x7c
+#define MISC					0x7c
 #define CGAMMAWD				0x80
 #define REC656IF				0x84
 #define CCDCFG					0x88
@@ -191,7 +191,7 @@
 #define ISIF_VD_POL_SHIFT			2
 #define ISIF_DATAPOL_NORMAL			0
 #define ISIF_DATAPOL_SHIFT			6
-#define ISIF_EXWEN_DISABLE 			0
+#define ISIF_EXWEN_DISABLE			0
 #define ISIF_EXWEN_SHIFT			5
 #define ISIF_FRM_FMT_SHIFT			7
 #define ISIF_DATASFT_SHIFT			8
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index cf65b39..6f44abf 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -26,8 +26,8 @@
  *
  *
  *    decoder(TVP5146/		YUV/
- * 	     MT9T001)   -->  Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
- *    				data input              |      |
+ *	     MT9T001)   -->  Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
+ *				data input              |      |
  *							V      |
  *						      SDRAM    |
  *							       V
@@ -47,7 +47,7 @@
  *    block such as IPIPE (on DM355 only).
  *
  *    Features supported
- *  		- MMAP IO
+ *		- MMAP IO
  *		- Capture using TVP5146 over BT.656
  *		- support for interfacing decoders using sub device model
  *		- Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV
@@ -1794,7 +1794,7 @@ static int vpfe_probe(struct platform_device *pdev)
 	vfd->fops		= &vpfe_fops;
 	vfd->ioctl_ops		= &vpfe_ioctl_ops;
 	vfd->tvnorms		= 0;
-	vfd->v4l2_dev 		= &vpfe_dev->v4l2_dev;
+	vfd->v4l2_dev		= &vpfe_dev->v4l2_dev;
 	snprintf(vfd->name, sizeof(vfd->name),
 		 "%s_V%d.%d.%d",
 		 CAPTURE_DRV_NAME,
diff --git a/drivers/media/platform/davinci/vpif.h b/drivers/media/platform/davinci/vpif.h
index 9956e67..2466c7c 100644
--- a/drivers/media/platform/davinci/vpif.h
+++ b/drivers/media/platform/davinci/vpif.h
@@ -226,11 +226,11 @@ static inline void vpif_clr_bit(u32 reg, u32 bit)
 	(VPIF_INT_BOTH << VPIF_CH1_INT_CTRL_SHIFT)), VPIF_CH1_CTRL))
 
 /* enabled interrupt on both the fields on vpid_ch0_ctrl register */
-#define channel2_intr_assert() 	(regw((regr(VPIF_CH2_CTRL)|\
+#define channel2_intr_assert()	(regw((regr(VPIF_CH2_CTRL)|\
 	(VPIF_INT_BOTH << VPIF_CH2_INT_CTRL_SHIFT)), VPIF_CH2_CTRL))
 
 /* enabled interrupt on both the fields on vpid_ch1_ctrl register */
-#define channel3_intr_assert() 	(regw((regr(VPIF_CH3_CTRL)|\
+#define channel3_intr_assert()	(regw((regr(VPIF_CH3_CTRL)|\
 	(VPIF_INT_BOTH << VPIF_CH3_INT_CTRL_SHIFT)), VPIF_CH3_CTRL))
 
 #define VPIF_CH_FID_MASK	(0x20)
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index fca4dc8..9364cdf 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -1390,16 +1390,16 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
 
 	for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
 		struct v4l2_async_subdev *_asd = vpif_obj.config->asd[i];
-		const struct fwnode_handle *fwnode = _asd->match.fwnode.fwnode;
+		const struct fwnode_handle *fwnode = _asd->match.fwnode;
 
 		if (fwnode == subdev->fwnode) {
 			vpif_obj.sd[i] = subdev;
 			vpif_obj.config->chan_config->inputs[i].subdev_name =
 				(char *)to_of_node(subdev->fwnode)->full_name;
 			vpif_dbg(2, debug,
-				 "%s: setting input %d subdev_name = %pOF\n",
+				 "%s: setting input %d subdev_name = %s\n",
 				 __func__, i,
-				 to_of_node(subdev->fwnode));
+				vpif_obj.config->chan_config->inputs[i].subdev_name);
 			return 0;
 		}
 	}
@@ -1550,6 +1550,8 @@ vpif_capture_get_pdata(struct platform_device *pdev)
 					    sizeof(*chan->inputs) *
 					    VPIF_CAPTURE_NUM_CHANNELS,
 					    GFP_KERNEL);
+		if (!chan->inputs)
+			return NULL;
 
 		chan->input_count++;
 		chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;
@@ -1593,7 +1595,7 @@ vpif_capture_get_pdata(struct platform_device *pdev)
 		}
 
 		pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		pdata->asd[i]->match.fwnode.fwnode = of_fwnode_handle(rem);
+		pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);
 		of_node_put(rem);
 	}
 
diff --git a/drivers/media/platform/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c
index f2d27b9..b738865 100644
--- a/drivers/media/platform/davinci/vpss.c
+++ b/drivers/media/platform/davinci/vpss.c
@@ -59,9 +59,9 @@ MODULE_AUTHOR("Texas Instruments");
 #define DM365_ISP5_INTSEL1		0x10
 #define DM365_ISP5_INTSEL2		0x14
 #define DM365_ISP5_INTSEL3		0x18
-#define DM365_ISP5_CCDCMUX 		0x20
-#define DM365_ISP5_PG_FRAME_SIZE 	0x28
-#define DM365_VPBE_CLK_CTRL 		0x00
+#define DM365_ISP5_CCDCMUX		0x20
+#define DM365_ISP5_PG_FRAME_SIZE	0x28
+#define DM365_VPBE_CLK_CTRL		0x00
 
 #define VPSS_CLK_CTRL			0x01c40044
 #define VPSS_CLK_CTRL_VENCCLKEN		BIT(3)
@@ -78,8 +78,8 @@ MODULE_AUTHOR("Texas Instruments");
 #define DM365_ISP5_INTSEL3_DEFAULT	0x00000015
 
 /* masks and shifts for DM365*/
-#define DM365_CCDC_PG_VD_POL_SHIFT 	0
-#define DM365_CCDC_PG_HD_POL_SHIFT 	1
+#define DM365_CCDC_PG_VD_POL_SHIFT	0
+#define DM365_CCDC_PG_HD_POL_SHIFT	1
 
 #define CCD_SRC_SEL_MASK		(BIT_MASK(5) | BIT_MASK(4))
 #define CCD_SRC_SEL_SHIFT		4
diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c
index b2dc524..e9ff279 100644
--- a/drivers/media/platform/exynos-gsc/gsc-m2m.c
+++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c
@@ -298,9 +298,7 @@ static int gsc_m2m_querycap(struct file *file, void *fh,
 	strlcpy(cap->card, GSC_MODULE_NAME " gscaler", sizeof(cap->card));
 	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
 		 dev_name(&gsc->pdev->dev));
-	cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE |
-		V4L2_CAP_VIDEO_CAPTURE_MPLANE |	V4L2_CAP_VIDEO_OUTPUT_MPLANE;
-
+	cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
index 46a7d24..7b2c49e 100644
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ b/drivers/media/platform/exynos4-is/Kconfig
@@ -41,7 +41,7 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called s5p-csis.
 
-if SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250
+if SOC_EXYNOS4412 || SOC_EXYNOS5250
 
 config VIDEO_EXYNOS_FIMC_LITE
 	tristate "EXYNOS FIMC-LITE camera interface driver"
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index 099c735..d8d8c99 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -1211,7 +1211,7 @@ static const struct fimc_drvdata fimc_drvdata_exynos4210 = {
 	.out_buf_count	= 32,
 };
 
-/* EXYNOS4212, EXYNOS4412 */
+/* EXYNOS4412 */
 static const struct fimc_drvdata fimc_drvdata_exynos4x12 = {
 	.num_entities	= 4,
 	.lclk_frequency	= 166000000UL,
@@ -1246,7 +1246,7 @@ static struct platform_driver fimc_driver = {
 	.driver = {
 		.of_match_table = fimc_of_match,
 		.name		= FIMC_DRIVER_NAME,
-		.pm     	= &fimc_pm_ops,
+		.pm		= &fimc_pm_ops,
 	}
 };
 
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
index c0373ae..82d514d 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.h
+++ b/drivers/media/platform/exynos4-is/fimc-core.h
@@ -303,7 +303,7 @@ struct fimc_m2m_device {
  * @input: capture input type, grp_id of the attached subdev
  * @user_subdev_api: true if subdevs are not configured by the host driver
  * @inh_sensor_ctrls: a flag indicating v4l2 controls are inherited from
- * 		      an image sensor subdev
+ *		      an image sensor subdev
  */
 struct fimc_vid_cap {
 	struct fimc_ctx			*ctx;
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index fd793d3..9a48c0f 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -366,16 +366,16 @@ static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on)
 static int fimc_isp_subdev_open(struct v4l2_subdev *sd,
 				struct v4l2_subdev_fh *fh)
 {
-	struct v4l2_mbus_framefmt fmt;
 	struct v4l2_mbus_framefmt *format;
+	struct v4l2_mbus_framefmt fmt = {
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.code = fimc_isp_formats[0].mbus_code,
+		.width = DEFAULT_PREVIEW_STILL_WIDTH + FIMC_ISP_CAC_MARGIN_WIDTH,
+		.height = DEFAULT_PREVIEW_STILL_HEIGHT + FIMC_ISP_CAC_MARGIN_HEIGHT,
+		.field = V4L2_FIELD_NONE,
+	};
 
 	format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SINK);
-
-	fmt.colorspace = V4L2_COLORSPACE_SRGB;
-	fmt.code = fimc_isp_formats[0].mbus_code;
-	fmt.width = DEFAULT_PREVIEW_STILL_WIDTH + FIMC_ISP_CAC_MARGIN_WIDTH;
-	fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT + FIMC_ISP_CAC_MARGIN_HEIGHT;
-	fmt.field = V4L2_FIELD_NONE;
 	*format = fmt;
 
 	format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SRC_FIFO);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 4a3c994..70d5f55 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1462,10 +1462,7 @@ static void fimc_lite_clk_put(struct fimc_lite *fimc)
 static int fimc_lite_clk_get(struct fimc_lite *fimc)
 {
 	fimc->clock = clk_get(&fimc->pdev->dev, FLITE_CLK_NAME);
-	if (IS_ERR(fimc->clock))
-		return PTR_ERR(fimc->clock);
-
-	return 0;
+	return PTR_ERR_OR_ZERO(fimc->clock);
 }
 
 static const struct of_device_id flite_of_match[];
@@ -1646,7 +1643,7 @@ static const struct dev_pm_ops fimc_lite_pm_ops = {
 			   NULL)
 };
 
-/* EXYNOS4212, EXYNOS4412 */
+/* EXYNOS4412 */
 static struct flite_drvdata fimc_lite_drvdata_exynos4 = {
 	.max_width		= 8192,
 	.max_height		= 8192,
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
index 9ae1e96..3e238b8 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite.h
@@ -56,9 +56,9 @@ enum {
  * @max_height: maximum camera interface input height in pixels
  * @out_width_align: minimum output width alignment in pixels
  * @win_hor_offs_align: minimum camera interface crop window horizontal
- * 			offset alignment in pixels
+ *			offset alignment in pixels
  * @out_hor_offs_align: minimum output DMA compose rectangle horizontal
- * 			offset alignment in pixels
+ *			offset alignment in pixels
  * @max_dma_bufs: number of output DMA buffer start address registers
  * @num_instances: total number of FIMC-LITE IP instances available
  */
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index 9027d0b..a19f8b1 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -236,15 +236,7 @@ static int fimc_m2m_querycap(struct file *file, void *fh,
 				     struct v4l2_capability *cap)
 {
 	struct fimc_dev *fimc = video_drvdata(file);
-	unsigned int caps;
-
-	/*
-	 * 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.
-	 */
-	caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE |
-		V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
+	unsigned int caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
 
 	__fimc_vidioc_querycap(&fimc->pdev->dev, cap, caps);
 	return 0;
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 0ef583c..78b48a1 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -456,7 +456,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
 	}
 
 	fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-	fmd->sensor[index].asd.match.fwnode.fwnode = of_fwnode_handle(rem);
+	fmd->sensor[index].asd.match.fwnode = of_fwnode_handle(rem);
 	fmd->async_subdevs[index] = &fmd->sensor[index].asd;
 
 	fmd->num_sensors++;
@@ -1364,7 +1364,7 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
 
 	/* Find platform data for this sensor subdev */
 	for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
-		if (fmd->sensor[i].asd.match.fwnode.fwnode ==
+		if (fmd->sensor[i].asd.match.fwnode ==
 		    of_fwnode_handle(subdev->dev->of_node))
 			si = &fmd->sensor[i];
 
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index 945ef1e..1e41951 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -384,16 +384,16 @@ static void deinterlace_device_run(void *priv)
 	 * 4 possible field conversions are possible at the moment:
 	 *  V4L2_FIELD_SEQ_TB --> V4L2_FIELD_INTERLACED_TB:
 	 *	two separate fields in the same input buffer are interlaced
-	 * 	in the output buffer using weaving. Top field comes first.
+	 *	in the output buffer using weaving. Top field comes first.
 	 *  V4L2_FIELD_SEQ_TB --> V4L2_FIELD_NONE:
-	 * 	top field from the input buffer is copied to the output buffer
-	 * 	using line doubling. Bottom field from the input buffer is discarded.
+	 *	top field from the input buffer is copied to the output buffer
+	 *	using line doubling. Bottom field from the input buffer is discarded.
 	 * V4L2_FIELD_SEQ_BT --> V4L2_FIELD_INTERLACED_BT:
 	 *	two separate fields in the same input buffer are interlaced
-	 * 	in the output buffer using weaving. Bottom field comes first.
+	 *	in the output buffer using weaving. Bottom field comes first.
 	 * V4L2_FIELD_SEQ_BT --> V4L2_FIELD_NONE:
-	 * 	bottom field from the input buffer is copied to the output buffer
-	 * 	using line doubling. Top field from the input buffer is discarded.
+	 *	bottom field from the input buffer is copied to the output buffer
+	 *	using line doubling. Top field from the input buffer is discarded.
 	 */
 	switch (dst_q_data->fmt->fourcc) {
 	case V4L2_PIX_FMT_YUV420:
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index 46768c0..0c28d0b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -115,3 +115,6 @@ struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev)
 	return ctx;
 }
 EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Mediatek video codec driver");
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index 0dc9ed0..cd37bb2 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -26,7 +26,7 @@
  * @inst_addr	: VPU decoder instance address
  * @signaled    : 1 - Host has received ack message from VPU, 0 - not received
  * @ctx         : context for v4l2 layer integration
- * @dev	        : platform device of VPU
+ * @dev		: platform device of VPU
  * @wq          : wait queue to wait VPU message ack
  * @handler     : ipi handler for each decoder
  */
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index abb14ee..a795a9f 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -1774,8 +1774,8 @@ static int vidioc_g_fbuf(struct file *file, void *fh,
 }
 
 static const struct v4l2_ioctl_ops vout_ioctl_ops = {
-	.vidioc_querycap      			= vidioc_querycap,
-	.vidioc_enum_fmt_vid_out 		= vidioc_enum_fmt_vid_out,
+	.vidioc_querycap			= vidioc_querycap,
+	.vidioc_enum_fmt_vid_out		= vidioc_enum_fmt_vid_out,
 	.vidioc_g_fmt_vid_out			= vidioc_g_fmt_vid_out,
 	.vidioc_try_fmt_vid_out			= vidioc_try_fmt_vid_out,
 	.vidioc_s_fmt_vid_out			= vidioc_s_fmt_vid_out,
@@ -1795,12 +1795,12 @@ static const struct v4l2_ioctl_ops vout_ioctl_ops = {
 };
 
 static const struct v4l2_file_operations omap_vout_fops = {
-	.owner 		= THIS_MODULE,
+	.owner		= THIS_MODULE,
 	.poll		= omap_vout_poll,
 	.unlocked_ioctl	= video_ioctl2,
-	.mmap 		= omap_vout_mmap,
-	.open 		= omap_vout_open,
-	.release 	= omap_vout_release,
+	.mmap		= omap_vout_mmap,
+	.open		= omap_vout_open,
+	.release	= omap_vout_release,
 };
 
 /* Init functions used during driver initialization */
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index b7ff384..8eb000e 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -920,7 +920,7 @@ static void isp_pipeline_suspend(struct isp_pipeline *pipe)
 
 /*
  * isp_pipeline_is_last - Verify if entity has an enabled link to the output
- * 			  video node
+ *			  video node
  * @me: ISP module's media entity
  *
  * Returns 1 if the entity has an enabled link to the output video node or 0
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index 295f34a..c71a007 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -32,7 +32,6 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
 #include <linux/dma/pxa-dma.h>
 
 #include <media/v4l2-async.h>
@@ -647,16 +646,16 @@ static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cf
 }
 
 /**
- * struct soc_camera_format_xlate - match between host and sensor formats
+ * struct pxa_camera_format_xlate - match between host and sensor formats
  * @code: code of a sensor provided format
  * @host_fmt: host format after host translation from code
  *
  * Host and sensor translation structure. Used in table of host and sensor
- * formats matchings in soc_camera_device. A host can override the generic list
+ * formats matchings in pxa_camera_device. A host can override the generic list
  * generation by implementing get_formats(), and use it for format checks and
  * format setup.
  */
-struct soc_camera_format_xlate {
+struct pxa_camera_format_xlate {
 	u32 code;
 	const struct pxa_mbus_pixelfmt *host_fmt;
 };
@@ -693,8 +692,8 @@ struct pxa_camera_dev {
 	struct v4l2_async_notifier notifier;
 	struct vb2_queue	vb2_vq;
 	struct v4l2_subdev	*sensor;
-	struct soc_camera_format_xlate *user_formats;
-	const struct soc_camera_format_xlate *current_fmt;
+	struct pxa_camera_format_xlate *user_formats;
+	const struct pxa_camera_format_xlate *current_fmt;
 	struct v4l2_pix_format	current_pix;
 
 	struct v4l2_async_subdev asd;
@@ -743,8 +742,8 @@ static const char *pxa_cam_driver_description = "PXA_Camera";
 /*
  * Format translation functions
  */
-static const struct soc_camera_format_xlate
-*pxa_mbus_xlate_by_fourcc(struct soc_camera_format_xlate *user_formats,
+static const struct pxa_camera_format_xlate
+*pxa_mbus_xlate_by_fourcc(struct pxa_camera_format_xlate *user_formats,
 			  unsigned int fourcc)
 {
 	unsigned int i;
@@ -755,17 +754,17 @@ static const struct soc_camera_format_xlate
 	return NULL;
 }
 
-static struct soc_camera_format_xlate *pxa_mbus_build_fmts_xlate(
+static struct pxa_camera_format_xlate *pxa_mbus_build_fmts_xlate(
 	struct v4l2_device *v4l2_dev, struct v4l2_subdev *subdev,
 	int (*get_formats)(struct v4l2_device *, unsigned int,
-			   struct soc_camera_format_xlate *xlate))
+			   struct pxa_camera_format_xlate *xlate))
 {
 	unsigned int i, fmts = 0, raw_fmts = 0;
 	int ret;
 	struct v4l2_subdev_mbus_code_enum code = {
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 	};
-	struct soc_camera_format_xlate *user_formats;
+	struct pxa_camera_format_xlate *user_formats;
 
 	while (!v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
 		raw_fmts++;
@@ -1722,7 +1721,7 @@ static bool pxa_camera_packing_supported(const struct pxa_mbus_pixelfmt *fmt)
 
 static int pxa_camera_get_formats(struct v4l2_device *v4l2_dev,
 				  unsigned int idx,
-				  struct soc_camera_format_xlate *xlate)
+				  struct pxa_camera_format_xlate *xlate)
 {
 	struct pxa_camera_dev *pcdev = v4l2_dev_to_pcdev(v4l2_dev);
 	int formats = 0, ret;
@@ -1794,7 +1793,7 @@ static int pxa_camera_get_formats(struct v4l2_device *v4l2_dev,
 
 static int pxa_camera_build_formats(struct pxa_camera_dev *pcdev)
 {
-	struct soc_camera_format_xlate *xlate;
+	struct pxa_camera_format_xlate *xlate;
 
 	xlate = pxa_mbus_build_fmts_xlate(&pcdev->v4l2_dev, pcdev->sensor,
 					  pxa_camera_get_formats);
@@ -1883,7 +1882,7 @@ static int pxac_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
 				      struct v4l2_format *f)
 {
 	struct pxa_camera_dev *pcdev = video_drvdata(filp);
-	const struct soc_camera_format_xlate *xlate;
+	const struct pxa_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	struct v4l2_subdev_pad_config pad_cfg;
 	struct v4l2_subdev_format format = {
@@ -1947,7 +1946,7 @@ static int pxac_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
 				    struct v4l2_format *f)
 {
 	struct pxa_camera_dev *pcdev = video_drvdata(filp);
-	const struct soc_camera_format_xlate *xlate;
+	const struct pxa_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	struct v4l2_subdev_format format = {
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
@@ -2336,7 +2335,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
 	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
 	remote = of_graph_get_remote_port(np);
 	if (remote) {
-		asd->match.fwnode.fwnode = of_fwnode_handle(remote);
+		asd->match.fwnode = of_fwnode_handle(remote);
 		of_node_put(remote);
 	} else {
 		dev_notice(dev, "no remote for %pOF\n", np);
@@ -2492,7 +2491,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
 	dev_set_drvdata(&pdev->dev, pcdev);
 	err = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev);
 	if (err)
-		goto exit_free_dma;
+		goto exit_deactivate;
 
 	pcdev->asds[0] = &pcdev->asd;
 	pcdev->notifier.subdevs = pcdev->asds;
@@ -2528,6 +2527,8 @@ static int pxa_camera_probe(struct platform_device *pdev)
 	v4l2_clk_unregister(pcdev->mclk_clk);
 exit_free_v4l2dev:
 	v4l2_device_unregister(&pcdev->v4l2_dev);
+exit_deactivate:
+	pxa_camera_deactivate(pcdev);
 exit_free_dma:
 	dma_release_channel(pcdev->dma_chans[2]);
 exit_free_dma_u:
diff --git a/drivers/media/platform/qcom/camss-8x16/camss.c b/drivers/media/platform/qcom/camss-8x16/camss.c
index 390a42c..05f06c9 100644
--- a/drivers/media/platform/qcom/camss-8x16/camss.c
+++ b/drivers/media/platform/qcom/camss-8x16/camss.c
@@ -341,7 +341,7 @@ static int camss_of_parse_ports(struct device *dev,
 		}
 
 		csd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		csd->asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		csd->asd.match.fwnode = of_fwnode_handle(remote);
 	}
 
 	return notifier->num_subdevs;
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index a0fe80d..0360d29 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -144,8 +144,8 @@ struct venc_controls {
 	u32 h264_min_qp;
 	u32 h264_max_qp;
 	u32 h264_loop_filter_mode;
-	u32 h264_loop_filter_alpha;
-	u32 h264_loop_filter_beta;
+	s32 h264_loop_filter_alpha;
+	s32 h264_loop_filter_beta;
 
 	u32 vp8_min_qp;
 	u32 vp8_max_qp;
diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c
index b83c5b8..1cfeb77 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.c
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
@@ -421,12 +421,12 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
 	pkt->shdr.session_id = hash32_ptr(cookie);
 	pkt->num_properties = 1;
+	pkt->data[0] = ptype;
 
 	switch (ptype) {
 	case HFI_PROPERTY_CONFIG_FRAME_RATE: {
 		struct hfi_framerate *in = pdata, *frate = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_FRAME_RATE;
 		frate->buffer_type = in->buffer_type;
 		frate->framerate = in->framerate;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*frate);
@@ -436,7 +436,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_uncompressed_format_select *in = pdata;
 		struct hfi_uncompressed_format_select *hfi = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
 		hfi->buffer_type = in->buffer_type;
 		hfi->format = in->format;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hfi);
@@ -445,7 +444,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_FRAME_SIZE: {
 		struct hfi_framesize *in = pdata, *fsize = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_FRAME_SIZE;
 		fsize->buffer_type = in->buffer_type;
 		fsize->height = in->height;
 		fsize->width = in->width;
@@ -455,7 +453,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_REALTIME: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_REALTIME;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) * 2;
 		break;
@@ -463,7 +460,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: {
 		struct hfi_buffer_count_actual *in = pdata, *count = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
 		count->count_actual = in->count_actual;
 		count->type = in->type;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
@@ -472,7 +468,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL: {
 		struct hfi_buffer_size_actual *in = pdata, *sz = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
 		sz->size = in->size;
 		sz->type = in->type;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*sz);
@@ -482,8 +477,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_buffer_display_hold_count_actual *in = pdata;
 		struct hfi_buffer_display_hold_count_actual *count = prop_data;
 
-		pkt->data[0] =
-			HFI_PROPERTY_PARAM_BUFFER_DISPLAY_HOLD_COUNT_ACTUAL;
 		count->hold_count = in->hold_count;
 		count->type = in->type;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
@@ -493,7 +486,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_nal_stream_format_select *in = pdata;
 		struct hfi_nal_stream_format_select *fmt = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT;
 		fmt->format = in->format;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*fmt);
 		break;
@@ -510,7 +502,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 			break;
 		}
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER;
 		pkt->data[1] = *in;
 		pkt->shdr.hdr.size += sizeof(u32) * 2;
 		break;
@@ -518,7 +509,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE: {
 		struct hfi_enable_picture *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE;
 		en->picture_type = in->picture_type;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -526,8 +516,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] =
-			HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -536,7 +524,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_enable *in = pdata;
 		struct hfi_enable *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -544,7 +531,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM: {
 		struct hfi_multi_stream *in = pdata, *multi = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
 		multi->buffer_type = in->buffer_type;
 		multi->enable = in->enable;
 		multi->width = in->width;
@@ -556,8 +542,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_display_picture_buffer_count *in = pdata;
 		struct hfi_display_picture_buffer_count *count = prop_data;
 
-		pkt->data[0] =
-			HFI_PROPERTY_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT;
 		count->count = in->count;
 		count->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
@@ -576,7 +560,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 			break;
 		}
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_DIVX_FORMAT;
 		pkt->data[1] = *in;
 		pkt->shdr.hdr.size += sizeof(u32) * 2;
 		break;
@@ -584,7 +567,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -592,7 +574,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -600,7 +581,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -608,14 +588,11 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] =
-			HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
 	}
 	case HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME:
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME;
 		pkt->shdr.hdr.size += sizeof(u32);
 		break;
 	case HFI_PROPERTY_PARAM_VENC_MPEG4_SHORT_HEADER:
@@ -625,7 +602,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE: {
 		struct hfi_bitrate *in = pdata, *brate = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE;
 		brate->bitrate = in->bitrate;
 		brate->layer_id = in->layer_id;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*brate);
@@ -634,7 +610,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE: {
 		struct hfi_bitrate *in = pdata, *hfi = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE;
 		hfi->bitrate = in->bitrate;
 		hfi->layer_id = in->layer_id;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hfi);
@@ -643,7 +618,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: {
 		struct hfi_profile_level *in = pdata, *pl = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
 		pl->level = in->level;
 		pl->profile = in->profile;
 		if (pl->profile <= 0)
@@ -660,7 +634,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL: {
 		struct hfi_h264_entropy_control *in = pdata, *hfi = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL;
 		hfi->entropy_mode = in->entropy_mode;
 		if (hfi->entropy_mode == HFI_H264_ENTROPY_CABAC)
 			hfi->cabac_model = in->cabac_model;
@@ -682,7 +655,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 			break;
 		}
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_RATE_CONTROL;
 		pkt->data[1] = *in;
 		pkt->shdr.hdr.size += sizeof(u32) * 2;
 		break;
@@ -690,7 +662,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_MPEG4_TIME_RESOLUTION: {
 		struct hfi_mpeg4_time_resolution *in = pdata, *res = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_MPEG4_TIME_RESOLUTION;
 		res->time_increment_resolution = in->time_increment_resolution;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*res);
 		break;
@@ -698,7 +669,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_MPEG4_HEADER_EXTENSION: {
 		struct hfi_mpeg4_header_extension *in = pdata, *ext = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_MPEG4_HEADER_EXTENSION;
 		ext->header_extension = in->header_extension;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ext);
 		break;
@@ -716,7 +686,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 			break;
 		}
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL;
 		db->mode = in->mode;
 		db->slice_alpha_offset = in->slice_alpha_offset;
 		db->slice_beta_offset = in->slice_beta_offset;
@@ -726,7 +695,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_SESSION_QP: {
 		struct hfi_quantization *in = pdata, *quant = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_SESSION_QP;
 		quant->qp_i = in->qp_i;
 		quant->qp_p = in->qp_p;
 		quant->qp_b = in->qp_b;
@@ -738,7 +706,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_quantization_range *in = pdata, *range = prop_data;
 		u32 min_qp, max_qp;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE;
 		min_qp = in->min_qp;
 		max_qp = in->max_qp;
 
@@ -764,8 +731,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_VC1_PERF_CFG: {
 		struct hfi_vc1e_perf_cfg_type *in = pdata, *perf = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_VC1_PERF_CFG;
-
 		memcpy(perf->search_range_x_subsampled,
 		       in->search_range_x_subsampled,
 		       sizeof(perf->search_range_x_subsampled));
@@ -780,7 +745,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_max_num_b_frames *bframes = prop_data;
 		u32 *in = pdata;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES;
 		bframes->max_num_b_frames = *in;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*bframes);
 		break;
@@ -788,7 +752,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD: {
 		struct hfi_intra_period *in = pdata, *intra = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD;
 		intra->pframes = in->pframes;
 		intra->bframes = in->bframes;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*intra);
@@ -797,7 +760,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD: {
 		struct hfi_idr_period *in = pdata, *idr = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD;
 		idr->idr_period = in->idr_period;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*idr);
 		break;
@@ -806,7 +768,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_conceal_color *color = prop_data;
 		u32 *in = pdata;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR;
 		color->conceal_color = *in;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*color);
 		break;
@@ -835,7 +796,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 			break;
 		}
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VPE_OPERATIONS;
 		ops->rotation = in->rotation;
 		ops->flip = in->flip;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ops);
@@ -856,7 +816,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 			break;
 		}
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH;
 		intra->mode = in->mode;
 		intra->air_mbs = in->air_mbs;
 		intra->air_ref = in->air_ref;
@@ -878,7 +837,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 			break;
 		}
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_CONTROL;
 		multi->multi_slice = in->multi_slice;
 		multi->slice_size = in->slice_size;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*multi);
@@ -887,7 +845,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_SLICE_DELIVERY_MODE: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_SLICE_DELIVERY_MODE;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -895,7 +852,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO: {
 		struct hfi_h264_vui_timing_info *in = pdata, *vui = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO;
 		vui->enable = in->enable;
 		vui->fixed_framerate = in->fixed_framerate;
 		vui->time_scale = in->time_scale;
@@ -905,7 +861,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VPE_DEINTERLACE: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VPE_DEINTERLACE;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -913,7 +868,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_H264_GENERATE_AUDNAL: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_H264_GENERATE_AUDNAL;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -921,7 +875,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE: {
 		struct hfi_buffer_alloc_mode *in = pdata, *mode = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE;
 		mode->type = in->type;
 		mode->mode = in->mode;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*mode);
@@ -930,7 +883,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VDEC_FRAME_ASSEMBLY: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_FRAME_ASSEMBLY;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -938,8 +890,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_H264_VUI_BITSTREAM_RESTRC: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] =
-			HFI_PROPERTY_PARAM_VENC_H264_VUI_BITSTREAM_RESTRC;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -947,7 +897,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_PRESERVE_TEXT_QUALITY: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_PRESERVE_TEXT_QUALITY;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -956,7 +905,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_scs_threshold *thres = prop_data;
 		u32 *in = pdata;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_SCS_THRESHOLD;
 		thres->threshold_value = *in;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*thres);
 		break;
@@ -974,7 +922,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 			break;
 		}
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_MVC_BUFFER_LAYOUT;
 		mvc->layout_type = in->layout_type;
 		mvc->bright_view_first = in->bright_view_first;
 		mvc->ngap = in->ngap;
@@ -994,7 +941,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 			break;
 		}
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_LTRMODE;
 		ltr->ltr_mode = in->ltr_mode;
 		ltr->ltr_count = in->ltr_count;
 		ltr->trust_mode = in->trust_mode;
@@ -1004,7 +950,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VENC_USELTRFRAME: {
 		struct hfi_ltr_use *in = pdata, *ltr_use = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_USELTRFRAME;
 		ltr_use->frames = in->frames;
 		ltr_use->ref_ltr = in->ref_ltr;
 		ltr_use->use_constrnt = in->use_constrnt;
@@ -1014,7 +959,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME: {
 		struct hfi_ltr_mark *in = pdata, *ltr_mark = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME;
 		ltr_mark->mark_frame = in->mark_frame;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_mark);
 		break;
@@ -1022,7 +966,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER: {
 		u32 *in = pdata;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER;
 		pkt->data[1] = *in;
 		pkt->shdr.hdr.size += sizeof(u32) * 2;
 		break;
@@ -1030,7 +973,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER: {
 		u32 *in = pdata;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER;
 		pkt->data[1] = *in;
 		pkt->shdr.hdr.size += sizeof(u32) * 2;
 		break;
@@ -1038,7 +980,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -1046,7 +987,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_INITIAL_QP: {
 		struct hfi_initial_quantization *in = pdata, *quant = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_INITIAL_QP;
 		quant->init_qp_enable = in->init_qp_enable;
 		quant->qp_i = in->qp_i;
 		quant->qp_p = in->qp_p;
@@ -1058,7 +998,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_vpe_color_space_conversion *in = pdata;
 		struct hfi_vpe_color_space_conversion *csc = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VPE_COLOR_SPACE_CONVERSION;
 		memcpy(csc->csc_matrix, in->csc_matrix,
 		       sizeof(csc->csc_matrix));
 		memcpy(csc->csc_bias, in->csc_bias, sizeof(csc->csc_bias));
@@ -1069,8 +1008,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] =
-			HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -1078,7 +1015,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_H264_NAL_SVC_EXT: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_H264_NAL_SVC_EXT;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -1086,7 +1022,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_CONFIG_VENC_PERF_MODE: {
 		u32 *in = pdata;
 
-		pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_PERF_MODE;
 		pkt->data[1] = *in;
 		pkt->shdr.hdr.size += sizeof(u32) * 2;
 		break;
@@ -1094,7 +1029,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_HIER_B_MAX_NUM_ENH_LAYER: {
 		u32 *in = pdata;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_HIER_B_MAX_NUM_ENH_LAYER;
 		pkt->data[1] = *in;
 		pkt->shdr.hdr.size += sizeof(u32) * 2;
 		break;
@@ -1102,7 +1036,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VDEC_NONCP_OUTPUT2: {
 		struct hfi_enable *in = pdata, *en = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_NONCP_OUTPUT2;
 		en->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
 		break;
@@ -1110,7 +1043,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
 	case HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE: {
 		struct hfi_hybrid_hierp *in = pdata, *hierp = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE;
 		hierp->layers = in->layers;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hierp);
 		break;
@@ -1185,6 +1117,7 @@ pkt_session_set_property_3xx(struct hfi_session_set_property_pkt *pkt,
 	pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
 	pkt->shdr.session_id = hash32_ptr(cookie);
 	pkt->num_properties = 1;
+	pkt->data[0] = ptype;
 
 	/*
 	 * Any session set property which is different in 3XX packetization
@@ -1196,7 +1129,6 @@ pkt_session_set_property_3xx(struct hfi_session_set_property_pkt *pkt,
 		struct hfi_multi_stream *in = pdata;
 		struct hfi_multi_stream_3x *multi = prop_data;
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
 		multi->buffer_type = in->buffer_type;
 		multi->enable = in->enable;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*multi);
@@ -1218,7 +1150,6 @@ pkt_session_set_property_3xx(struct hfi_session_set_property_pkt *pkt,
 			break;
 		}
 
-		pkt->data[0] = HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH;
 		intra->mode = in->mode;
 		intra->mbs = in->cir_mbs;
 		pkt->shdr.hdr.size += sizeof(u32) + sizeof(*intra);
diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h b/drivers/media/platform/qcom/venus/hfi_helper.h
index 8d282db..55d8eb2 100644
--- a/drivers/media/platform/qcom/venus/hfi_helper.h
+++ b/drivers/media/platform/qcom/venus/hfi_helper.h
@@ -585,8 +585,8 @@ struct hfi_enable {
 
 struct hfi_h264_db_control {
 	u32 mode;
-	u32 slice_alpha_offset;
-	u32 slice_beta_offset;
+	s32 slice_alpha_offset;
+	s32 slice_beta_offset;
 };
 
 #define HFI_H264_ENTROPY_CAVLC			0x1
diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
index 3fcf0e9..e3a10a8 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -234,6 +234,16 @@ static int venc_v4l2_to_hfi(int id, int value)
 		case 3:
 			return HFI_VPX_PROFILE_VERSION_3;
 		}
+	case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
+		switch (value) {
+		case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED:
+		default:
+			return HFI_H264_DB_MODE_ALL_BOUNDARY;
+		case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED:
+			return HFI_H264_DB_MODE_DISABLE;
+		case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY:
+			return HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY;
+		}
 	}
 
 	return 0;
@@ -641,6 +651,8 @@ static int venc_set_properties(struct venus_inst *inst)
 
 	if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264) {
 		struct hfi_h264_vui_timing_info info;
+		struct hfi_h264_entropy_control entropy;
+		struct hfi_h264_db_control deblock;
 
 		ptype = HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO;
 		info.enable = 1;
@@ -650,10 +662,36 @@ static int venc_set_properties(struct venus_inst *inst)
 		ret = hfi_session_set_property(inst, ptype, &info);
 		if (ret)
 			return ret;
+
+		ptype = HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL;
+		entropy.entropy_mode = venc_v4l2_to_hfi(
+					  V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
+					  ctr->h264_entropy_mode);
+		entropy.cabac_model = HFI_H264_CABAC_MODEL_0;
+
+		ret = hfi_session_set_property(inst, ptype, &entropy);
+		if (ret)
+			return ret;
+
+		ptype = HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL;
+		deblock.mode = venc_v4l2_to_hfi(
+				      V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
+				      ctr->h264_loop_filter_mode);
+		deblock.slice_alpha_offset = ctr->h264_loop_filter_alpha;
+		deblock.slice_beta_offset = ctr->h264_loop_filter_beta;
+
+		ret = hfi_session_set_property(inst, ptype, &deblock);
+		if (ret)
+			return ret;
 	}
 
+	/* IDR periodicity, n:
+	 * n = 0 - only the first I-frame is IDR frame
+	 * n = 1 - all I-frames will be IDR frames
+	 * n > 1 - every n-th I-frame will be IDR frame
+	 */
 	ptype = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD;
-	idrp.idr_period = ctr->gop_size;
+	idrp.idr_period = 0;
 	ret = hfi_session_set_property(inst, ptype, &idrp);
 	if (ret)
 		return ret;
@@ -667,10 +705,6 @@ static int venc_set_properties(struct venus_inst *inst)
 			return ret;
 	}
 
-	/* intra_period = pframes + bframes + 1 */
-	if (!ctr->num_p_frames)
-		ctr->num_p_frames = 2 * 15 - 1,
-
 	ptype = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD;
 	intra_period.pframes = ctr->num_p_frames;
 	intra_period.bframes = ctr->num_b_frames;
@@ -767,6 +801,10 @@ static int venc_init_session(struct venus_inst *inst)
 	if (ret)
 		goto deinit;
 
+	ret = venc_set_properties(inst);
+	if (ret)
+		goto deinit;
+
 	return 0;
 deinit:
 	hfi_session_deinit(inst);
diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c b/drivers/media/platform/qcom/venus/venc_ctrls.c
index ab0fe51..21e938a 100644
--- a/drivers/media/platform/qcom/venus/venc_ctrls.c
+++ b/drivers/media/platform/qcom/venus/venc_ctrls.c
@@ -30,10 +30,57 @@
 #define AT_SLICE_BOUNDARY	\
 	V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
 
+static int venc_calc_bpframes(u32 gop_size, u32 conseq_b, u32 *bf, u32 *pf)
+{
+	u32 half = (gop_size - 1) >> 1;
+	u32 b, p, ratio;
+	bool found = false;
+
+	if (!gop_size)
+		return -EINVAL;
+
+	*bf = *pf = 0;
+
+	if (!conseq_b) {
+		*pf = gop_size -  1;
+		return 0;
+	}
+
+	b = p = half;
+
+	for (; b <= gop_size - 1; b++, p--) {
+		if (b % p)
+			continue;
+
+		ratio = b / p;
+
+		if (ratio == conseq_b) {
+			found = true;
+			break;
+		}
+
+		if (ratio > conseq_b)
+			break;
+	}
+
+	if (!found)
+		return -EINVAL;
+
+	if (b + p + 1 != gop_size)
+		return -EINVAL;
+
+	*bf = b;
+	*pf = p;
+
+	return 0;
+}
+
 static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct venus_inst *inst = ctrl_to_inst(ctrl);
 	struct venc_controls *ctr = &inst->controls.enc;
+	u32 bframes;
+	int ret;
 
 	switch (ctrl->id) {
 	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
@@ -102,6 +149,11 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
 	case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
 		break;
 	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		ret = venc_calc_bpframes(ctrl->val, ctr->num_b_frames, &bframes,
+					 &ctr->num_p_frames);
+		if (ret)
+			return ret;
+
 		ctr->gop_size = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
@@ -114,7 +166,12 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
 		ctr->vp8_max_qp = ctrl->val;
 		break;
 	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
-		ctr->num_b_frames = ctrl->val;
+		ret = venc_calc_bpframes(ctr->gop_size, ctrl->val, &bframes,
+					 &ctr->num_p_frames);
+		if (ret)
+			return ret;
+
+		ctr->num_b_frames = bframes;
 		break;
 	default:
 		return -EINVAL;
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 108d776..f1fc797 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -187,7 +187,7 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
 		return -ENODEV;
 
 	vin_dbg(vin, "Found digital subdevice %pOF\n",
-		to_of_node(vin->digital->asd.match.fwnode.fwnode));
+		to_of_node(vin->digital->asd.match.fwnode));
 
 	vin->notifier.ops = &rvin_digital_notify_ops;
 	ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
diff --git a/drivers/media/platform/rcar_drif.c b/drivers/media/platform/rcar_drif.c
index 63c94f4..b2e080e 100644
--- a/drivers/media/platform/rcar_drif.c
+++ b/drivers/media/platform/rcar_drif.c
@@ -1107,7 +1107,7 @@ static int rcar_drif_notify_bound(struct v4l2_async_notifier *notifier,
 	struct rcar_drif_sdr *sdr =
 		container_of(notifier, struct rcar_drif_sdr, notifier);
 
-	if (sdr->ep.asd.match.fwnode.fwnode !=
+	if (sdr->ep.asd.match.fwnode !=
 	    of_fwnode_handle(subdev->dev->of_node)) {
 		rdrif_err(sdr, "subdev %s cannot bind\n", subdev->name);
 		return -EINVAL;
@@ -1235,7 +1235,7 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr)
 		return -EINVAL;
 	}
 
-	sdr->ep.asd.match.fwnode.fwnode = fwnode;
+	sdr->ep.asd.match.fwnode = fwnode;
 	sdr->ep.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 	notifier->num_subdevs++;
 
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index faac816..79b63da 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -3086,7 +3086,7 @@ static int s5p_jpeg_runtime_resume(struct device *dev)
 	for (i = 0; i < jpeg->variant->num_clocks; i++) {
 		ret = clk_prepare_enable(jpeg->clocks[i]);
 		if (ret) {
-			while (--i > 0)
+			while (--i >= 0)
 				clk_disable_unprepare(jpeg->clocks[i]);
 			return ret;
 		}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index fe94bd6..f15cf24 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1309,6 +1309,12 @@ static int s5p_mfc_probe(struct platform_device *pdev)
 		goto err_dma;
 	}
 
+	/*
+	 * Load fails if fs isn't mounted. Try loading anyway.
+	 * _open() will load it, it it fails now. Ignore failure.
+	 */
+	s5p_mfc_load_firmware(dev);
+
 	mutex_init(&dev->mfc_mutex);
 	init_waitqueue_head(&dev->queue);
 	dev->hw_lock = 0;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index 4220914..76119a8 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -290,6 +290,8 @@ struct s5p_mfc_priv_buf {
  * @mfc_cmds:		cmd structure holding HW commands function pointers
  * @mfc_regs:		structure holding MFC registers
  * @fw_ver:		loaded firmware sub-version
+ * @fw_get_done		flag set when request_firmware() is complete and
+ *			copied into fw_buf
  * risc_on:		flag indicates RISC is on or off
  *
  */
@@ -336,6 +338,7 @@ struct s5p_mfc_dev {
 	struct s5p_mfc_hw_cmds *mfc_cmds;
 	const struct s5p_mfc_regs *mfc_regs;
 	enum s5p_mfc_fw_ver fw_ver;
+	bool fw_get_done;
 	bool risc_on; /* indicates if RISC is on or off */
 };
 
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
index 69ef9c2..f95cd76 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
@@ -55,6 +55,9 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
 	 * into kernel. */
 	mfc_debug_enter();
 
+	if (dev->fw_get_done)
+		return 0;
+
 	for (i = MFC_FW_MAX_VERSIONS - 1; i >= 0; i--) {
 		if (!dev->variant->fw_name[i])
 			continue;
@@ -75,13 +78,9 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
 		release_firmware(fw_blob);
 		return -ENOMEM;
 	}
-	if (!dev->fw_buf.virt) {
-		mfc_err("MFC firmware is not allocated\n");
-		release_firmware(fw_blob);
-		return -EINVAL;
-	}
 	memcpy(dev->fw_buf.virt, fw_blob->data, fw_blob->size);
 	wmb();
+	dev->fw_get_done = true;
 	release_firmware(fw_blob);
 	mfc_debug_leave();
 	return 0;
@@ -93,6 +92,7 @@ int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev)
 	/* Before calling this function one has to make sure
 	 * that MFC is no longer processing */
 	s5p_mfc_release_priv_buf(dev, &dev->fw_buf);
+	dev->fw_get_done = false;
 	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 2a5fd7c..0d5d465 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -2080,7 +2080,7 @@ int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx)
 
 			if (cfg.type == V4L2_CTRL_TYPE_MENU) {
 				cfg.step = 0;
-				cfg.menu_skip_mask = cfg.menu_skip_mask;
+				cfg.menu_skip_mask = controls[i].menu_skip_mask;
 				cfg.qmenu = mfc51_get_menu(cfg.id);
 			} else {
 				cfg.step = controls[i].step;
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 871da2a..4dccf29 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -1181,7 +1181,7 @@ static int sh_vou_release(struct file *file)
 
 /* sh_vou display ioctl operations */
 static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
-	.vidioc_querycap        	= sh_vou_querycap,
+	.vidioc_querycap		= sh_vou_querycap,
 	.vidioc_enum_fmt_vid_out	= sh_vou_enum_fmt_vid_out,
 	.vidioc_g_fmt_vid_out		= sh_vou_g_fmt_vid_out,
 	.vidioc_s_fmt_vid_out		= sh_vou_s_fmt_vid_out,
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index 9b06978..242342f 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -451,13 +451,18 @@ static void sh_mobile_ceu_stop_streaming(struct vb2_queue *q)
 	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
 	struct list_head *buf_head, *tmp;
+	struct vb2_v4l2_buffer *vbuf;
 
 	spin_lock_irq(&pcdev->lock);
 
 	pcdev->active = NULL;
 
-	list_for_each_safe(buf_head, tmp, &pcdev->capture)
+	list_for_each_safe(buf_head, tmp, &pcdev->capture) {
+		vbuf = &list_entry(buf_head, struct sh_mobile_ceu_buffer,
+				   queue)->vb;
+		vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
 		list_del_init(buf_head);
+	}
 
 	spin_unlock_irq(&pcdev->lock);
 
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index d964c07..70fc5f0 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -1517,7 +1517,7 @@ static int soc_of_bind(struct soc_camera_host *ici,
 	if (!info)
 		return -ENOMEM;
 
-	info->sasd.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+	info->sasd.asd.match.fwnode = of_fwnode_handle(remote);
 	info->sasd.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 	info->subdev = &info->sasd.asd;
 
diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
index 270ec61..6164102 100644
--- a/drivers/media/platform/soc_camera/soc_scale_crop.c
+++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
@@ -420,3 +420,7 @@ void soc_camera_calc_client_output(struct soc_camera_device *icd,
 	mf->height = soc_camera_shift_scale(rect->height, shift, scale_v);
 }
 EXPORT_SYMBOL(soc_camera_calc_client_output);
+
+MODULE_DESCRIPTION("soc-camera scaling-cropping functions");
+MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/sti/bdisp/bdisp-debug.c b/drivers/media/platform/sti/bdisp/bdisp-debug.c
index 2cc289e..c6a4e2d 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-debug.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-debug.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2014
  * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/debugfs.h>
diff --git a/drivers/media/platform/sti/bdisp/bdisp-filter.h b/drivers/media/platform/sti/bdisp/bdisp-filter.h
index 53e52fb..d25adb5 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-filter.h
+++ b/drivers/media/platform/sti/bdisp/bdisp-filter.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2014
  * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #define BDISP_HF_NB             64
diff --git a/drivers/media/platform/sti/bdisp/bdisp-hw.c b/drivers/media/platform/sti/bdisp/bdisp-hw.c
index b7892f3..a5eb592 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-hw.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-hw.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2014
  * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/delay.h>
@@ -1064,7 +1064,7 @@ static void bdisp_hw_save_request(struct bdisp_ctx *ctx)
 		if (!copy_node[i]) {
 			copy_node[i] = devm_kzalloc(ctx->bdisp_dev->dev,
 						    sizeof(*copy_node[i]),
-						    GFP_KERNEL);
+						    GFP_ATOMIC);
 			if (!copy_node[i])
 				return;
 		}
diff --git a/drivers/media/platform/sti/bdisp/bdisp-reg.h b/drivers/media/platform/sti/bdisp/bdisp-reg.h
index e7e1a42..b07ecc9 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-reg.h
+++ b/drivers/media/platform/sti/bdisp/bdisp-reg.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2014
  * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 struct bdisp_node {
diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
index 7e9ed9c..bf4ca16 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2014
  * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/errno.h>
diff --git a/drivers/media/platform/sti/bdisp/bdisp.h b/drivers/media/platform/sti/bdisp/bdisp.h
index b3fbf99..e309cde 100644
--- a/drivers/media/platform/sti/bdisp/bdisp.h
+++ b/drivers/media/platform/sti/bdisp/bdisp.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2014
  * Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/clk.h>
diff --git a/drivers/media/platform/sti/c8sectpfe/Kconfig b/drivers/media/platform/sti/c8sectpfe/Kconfig
index 7420a50..740190f 100644
--- a/drivers/media/platform/sti/c8sectpfe/Kconfig
+++ b/drivers/media/platform/sti/c8sectpfe/Kconfig
@@ -1,6 +1,6 @@
 config DVB_C8SECTPFE
 	tristate "STMicroelectronics C8SECTPFE DVB support"
-	depends on PINCTRL && DVB_CORE && I2C
+	depends on PINCTRL && DVB_CORE && I2C && HAS_DMA
 	depends on ARCH_STI || ARCH_MULTIPLATFORM || COMPILE_TEST
 	select FW_LOADER
 	select DEBUG_FS
diff --git a/drivers/media/platform/sti/c8sectpfe/Makefile b/drivers/media/platform/sti/c8sectpfe/Makefile
index b642b4f..34d6947 100644
--- a/drivers/media/platform/sti/c8sectpfe/Makefile
+++ b/drivers/media/platform/sti/c8sectpfe/Makefile
@@ -4,7 +4,6 @@
 
 obj-$(CONFIG_DVB_C8SECTPFE) += c8sectpfe.o
 
-ccflags-y += -Idrivers/media/i2c
 ccflags-y += -Idrivers/media/common
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ \
-		-Idrivers/media/tuners/
+ccflags-y += -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.c
index 2dfbe8a..5df67da 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * c8sectpfe-common.c - C8SECTPFE STi DVB driver
  *
@@ -5,10 +6,6 @@
  *
  *   Author: Peter Griffin <peter.griffin@linaro.org>
  *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License as
- *      published by the Free Software Foundation; either version 2 of
- *      the License, or (at your option) any later version.
  */
 #include <linux/completion.h>
 #include <linux/delay.h>
@@ -24,11 +21,11 @@
 #include <linux/time.h>
 #include <linux/wait.h>
 
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #include "c8sectpfe-common.h"
 #include "c8sectpfe-core.h"
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h
index da21c0a..5ab7ca44 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * c8sectpfe-common.h - C8SECTPFE STi DVB driver
  *
@@ -5,10 +6,6 @@
  *
  *   Author: Peter Griffin <peter.griffin@linaro.org>
  *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License as
- *      published by the Free Software Foundation; either version 2 of
- *      the License, or (at your option) any later version.
  */
 #ifndef _C8SECTPFE_COMMON_H_
 #define _C8SECTPFE_COMMON_H_
@@ -18,10 +15,10 @@
 #include <linux/gpio.h>
 #include <linux/version.h>
 
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 /* Maximum number of channels */
 #define C8SECTPFE_MAXADAPTER (4)
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index a0acee7..3c05b3d 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * c8sectpfe-core.c - C8SECTPFE STi DVB driver
  *
@@ -6,10 +7,6 @@
  *   Author:Peter Bennett <peter.bennett@st.com>
  *	    Peter Griffin <peter.griffin@linaro.org>
  *
- *	This program is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU General Public License as
- *	published by the Free Software Foundation; either version 2 of
- *	the License, or (at your option) any later version.
  */
 #include <linux/atomic.h>
 #include <linux/clk.h>
@@ -38,10 +35,10 @@
 #include "c8sectpfe-core.h"
 #include "c8sectpfe-common.h"
 #include "c8sectpfe-debugfs.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 
 #define FIRMWARE_MEMDMA "pti_memdma_h407.elf"
 MODULE_FIRMWARE(FIRMWARE_MEMDMA);
@@ -83,7 +80,7 @@ static void c8sectpfe_timer_interrupt(struct timer_list *t)
 static void channel_swdemux_tsklet(unsigned long data)
 {
 	struct channel_info *channel = (struct channel_info *)data;
-	struct c8sectpfei *fei = channel->fei;
+	struct c8sectpfei *fei;
 	unsigned long wp, rp;
 	int pos, num_packets, n, size;
 	u8 *buf;
@@ -91,6 +88,8 @@ static void channel_swdemux_tsklet(unsigned long data)
 	if (unlikely(!channel || !channel->irec))
 		return;
 
+	fei = channel->fei;
+
 	wp = readl(channel->irec + DMA_PRDS_BUSWP_TP(0));
 	rp = readl(channel->irec + DMA_PRDS_BUSRP_TP(0));
 
@@ -691,7 +690,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
 	if (IS_ERR(fei->sram))
 		return PTR_ERR(fei->sram);
 
-	fei->sram_size = res->end - res->start;
+	fei->sram_size = resource_size(res);
 
 	fei->idle_irq = platform_get_irq_byname(pdev, "c8sectpfe-idle-irq");
 	if (fei->idle_irq < 0) {
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.h b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.h
index 39e7a22..3dbb3a2 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.h
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * c8sectpfe-core.h - C8SECTPFE STi DVB driver
  *
@@ -6,10 +7,6 @@
  *   Author:Peter Bennett <peter.bennett@st.com>
  *	    Peter Griffin <peter.griffin@linaro.org>
  *
- *	This program is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU General Public License as
- *	published by the Free Software Foundation; either version 2 of
- *	the License, or (at your option) any later version.
  */
 #ifndef _C8SECTPFE_CORE_H_
 #define _C8SECTPFE_CORE_H_
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.c
index e9ba13d..8f0ddcb 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * c8sectpfe-debugfs.c - C8SECTPFE STi DVB driver
  *
@@ -5,14 +6,6 @@
  *
  * Author: Peter Griffin <peter.griffin@linaro.org>
  *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2  of
- * the License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 #include <linux/debugfs.h>
 #include <linux/device.h>
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.h b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.h
index 8af1ac1..b8c30bc 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.h
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /**
  * c8sectpfe-debugfs.h - C8SECTPFE STi DVB driver debugfs header
  *
@@ -5,14 +6,6 @@
  *
  * Authors: Peter Griffin <peter.griffin@linaro.org>
  *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2  of
- * the License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #ifndef __C8SECTPFE_DEBUG_H
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c
index 2c0015b..075d469 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *  c8sectpfe-dvb.c - C8SECTPFE STi DVB driver
  *
@@ -5,16 +6,6 @@
  *
  *  Author Peter Griffin <peter.griffin@linaro.org>
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *
- *  GNU General Public License for more details.
  */
 #include <linux/completion.h>
 #include <linux/delay.h>
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.h b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.h
index bd366db..3d87a9ae 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.h
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * c8sectpfe-common.h - C8SECTPFE STi DVB driver
  *
@@ -5,10 +6,6 @@
  *
  *   Author: Peter Griffin <peter.griffin@linaro.org>
  *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License as
- *      published by the Free Software Foundation; either version 2 of
- *      the License, or (at your option) any later version.
  */
 #ifndef _C8SECTPFE_DVB_H_
 #define _C8SECTPFE_DVB_H_
diff --git a/drivers/media/platform/sti/cec/stih-cec.c b/drivers/media/platform/sti/cec/stih-cec.c
index 70160df..d34099f 100644
--- a/drivers/media/platform/sti/cec/stih-cec.c
+++ b/drivers/media/platform/sti/cec/stih-cec.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * STIH4xx CEC driver
  * Copyright (C) STMicroelectronics SA 2016
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 #include <linux/clk.h>
 #include <linux/interrupt.h>
diff --git a/drivers/media/platform/sti/delta/delta-cfg.h b/drivers/media/platform/sti/delta/delta-cfg.h
index c6388f5..f47c6e6 100644
--- a/drivers/media/platform/sti/delta/delta-cfg.h
+++ b/drivers/media/platform/sti/delta/delta-cfg.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef DELTA_CFG_H
diff --git a/drivers/media/platform/sti/delta/delta-debug.c b/drivers/media/platform/sti/delta/delta-debug.c
index a7ebf2c..4b2eb6b 100644
--- a/drivers/media/platform/sti/delta/delta-debug.c
+++ b/drivers/media/platform/sti/delta/delta-debug.c
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Hugues Fruchet <hugues.fruchet@st.com>
  *          Fabrice Lecoultre <fabrice.lecoultre@st.com>
  *          for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include "delta.h"
diff --git a/drivers/media/platform/sti/delta/delta-debug.h b/drivers/media/platform/sti/delta/delta-debug.h
index 955c158..fa90252 100644
--- a/drivers/media/platform/sti/delta/delta-debug.h
+++ b/drivers/media/platform/sti/delta/delta-debug.h
@@ -1,9 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Hugues Fruchet <hugues.fruchet@st.com>
  *          Fabrice Lecoultre <fabrice.lecoultre@st.com>
  *          for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef DELTA_DEBUG_H
diff --git a/drivers/media/platform/sti/delta/delta-ipc.c b/drivers/media/platform/sti/delta/delta-ipc.c
index 41e4a4c..a4603d5 100644
--- a/drivers/media/platform/sti/delta/delta-ipc.c
+++ b/drivers/media/platform/sti/delta/delta-ipc.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/rpmsg.h>
diff --git a/drivers/media/platform/sti/delta/delta-ipc.h b/drivers/media/platform/sti/delta/delta-ipc.h
index cef2019..9fba6b5 100644
--- a/drivers/media/platform/sti/delta/delta-ipc.h
+++ b/drivers/media/platform/sti/delta/delta-ipc.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef DELTA_IPC_H
diff --git a/drivers/media/platform/sti/delta/delta-mem.c b/drivers/media/platform/sti/delta/delta-mem.c
index d7b53d3..aeccd50 100644
--- a/drivers/media/platform/sti/delta/delta-mem.c
+++ b/drivers/media/platform/sti/delta/delta-mem.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include "delta.h"
diff --git a/drivers/media/platform/sti/delta/delta-mem.h b/drivers/media/platform/sti/delta/delta-mem.h
index f8ca109..ff7d02f 100644
--- a/drivers/media/platform/sti/delta/delta-mem.h
+++ b/drivers/media/platform/sti/delta/delta-mem.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef DELTA_MEM_H
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg-dec.c b/drivers/media/platform/sti/delta/delta-mjpeg-dec.c
index 84ea43c..0533d4a 100644
--- a/drivers/media/platform/sti/delta/delta-mjpeg-dec.c
+++ b/drivers/media/platform/sti/delta/delta-mjpeg-dec.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2013
  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/slab.h>
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg-fw.h b/drivers/media/platform/sti/delta/delta-mjpeg-fw.h
index de803d0..5a9404f 100644
--- a/drivers/media/platform/sti/delta/delta-mjpeg-fw.h
+++ b/drivers/media/platform/sti/delta/delta-mjpeg-fw.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef DELTA_MJPEG_FW_H
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg-hdr.c b/drivers/media/platform/sti/delta/delta-mjpeg-hdr.c
index a8fd8fa..90e5b2f 100644
--- a/drivers/media/platform/sti/delta/delta-mjpeg-hdr.c
+++ b/drivers/media/platform/sti/delta/delta-mjpeg-hdr.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2013
  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include "delta.h"
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg.h b/drivers/media/platform/sti/delta/delta-mjpeg.h
index 18e6b37..43f7a88 100644
--- a/drivers/media/platform/sti/delta/delta-mjpeg.h
+++ b/drivers/media/platform/sti/delta/delta-mjpeg.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2013
  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef DELTA_MJPEG_H
diff --git a/drivers/media/platform/sti/delta/delta-v4l2.c b/drivers/media/platform/sti/delta/delta-v4l2.c
index b2dc3d2..232d508 100644
--- a/drivers/media/platform/sti/delta/delta-v4l2.c
+++ b/drivers/media/platform/sti/delta/delta-v4l2.c
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Hugues Fruchet <hugues.fruchet@st.com>
  *          Jean-Christophe Trotin <jean-christophe.trotin@st.com>
  *          for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/clk.h>
diff --git a/drivers/media/platform/sti/delta/delta.h b/drivers/media/platform/sti/delta/delta.h
index 60c07324..2ba9992 100644
--- a/drivers/media/platform/sti/delta/delta.h
+++ b/drivers/media/platform/sti/delta/delta.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef DELTA_H
diff --git a/drivers/media/platform/sti/hva/hva-debugfs.c b/drivers/media/platform/sti/hva/hva-debugfs.c
index 83a6258..9f7e8ac 100644
--- a/drivers/media/platform/sti/hva/hva-debugfs.c
+++ b/drivers/media/platform/sti/hva/hva-debugfs.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Yannick Fertre <yannick.fertre@st.com>
  *          Hugues Fruchet <hugues.fruchet@st.com>
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/debugfs.h>
diff --git a/drivers/media/platform/sti/hva/hva-h264.c b/drivers/media/platform/sti/hva/hva-h264.c
index 17f1eb0..b61a5d3 100644
--- a/drivers/media/platform/sti/hva/hva-h264.c
+++ b/drivers/media/platform/sti/hva/hva-h264.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Yannick Fertre <yannick.fertre@st.com>
  *          Hugues Fruchet <hugues.fruchet@st.com>
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include "hva.h"
diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c
index ec25bdc..7917fd2 100644
--- a/drivers/media/platform/sti/hva/hva-hw.c
+++ b/drivers/media/platform/sti/hva/hva-hw.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Yannick Fertre <yannick.fertre@st.com>
  *          Hugues Fruchet <hugues.fruchet@st.com>
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/clk.h>
diff --git a/drivers/media/platform/sti/hva/hva-hw.h b/drivers/media/platform/sti/hva/hva-hw.h
index b46017d..b298990 100644
--- a/drivers/media/platform/sti/hva/hva-hw.h
+++ b/drivers/media/platform/sti/hva/hva-hw.h
@@ -1,8 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Yannick Fertre <yannick.fertre@st.com>
  *          Hugues Fruchet <hugues.fruchet@st.com>
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef HVA_HW_H
diff --git a/drivers/media/platform/sti/hva/hva-mem.c b/drivers/media/platform/sti/hva/hva-mem.c
index 821c78e..caf50cd 100644
--- a/drivers/media/platform/sti/hva/hva-mem.c
+++ b/drivers/media/platform/sti/hva/hva-mem.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Yannick Fertre <yannick.fertre@st.com>
  *          Hugues Fruchet <hugues.fruchet@st.com>
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include "hva.h"
diff --git a/drivers/media/platform/sti/hva/hva-mem.h b/drivers/media/platform/sti/hva/hva-mem.h
index a95c728..fec549d 100644
--- a/drivers/media/platform/sti/hva/hva-mem.h
+++ b/drivers/media/platform/sti/hva/hva-mem.h
@@ -1,8 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Yannick Fertre <yannick.fertre@st.com>
  *          Hugues Fruchet <hugues.fruchet@st.com>
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef HVA_MEM_H
diff --git a/drivers/media/platform/sti/hva/hva-v4l2.c b/drivers/media/platform/sti/hva/hva-v4l2.c
index 1c4fc33..2ab0b5c 100644
--- a/drivers/media/platform/sti/hva/hva-v4l2.c
+++ b/drivers/media/platform/sti/hva/hva-v4l2.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Yannick Fertre <yannick.fertre@st.com>
  *          Hugues Fruchet <hugues.fruchet@st.com>
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/module.h>
diff --git a/drivers/media/platform/sti/hva/hva.h b/drivers/media/platform/sti/hva/hva.h
index 0d749b2..1226d60 100644
--- a/drivers/media/platform/sti/hva/hva.h
+++ b/drivers/media/platform/sti/hva/hva.h
@@ -1,8 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) STMicroelectronics SA 2015
  * Authors: Yannick Fertre <yannick.fertre@st.com>
  *          Hugues Fruchet <hugues.fruchet@st.com>
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #ifndef HVA_H
@@ -245,7 +245,7 @@ struct hva_enc;
  * @dbg:             context debug info
  */
 struct hva_ctx {
-	struct hva_dev		        *hva_dev;
+	struct hva_dev			*hva_dev;
 	struct v4l2_fh			fh;
 	struct v4l2_ctrl_handler	ctrl_handler;
 	struct hva_controls		ctrls;
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
index ac4c450..9460b30 100644
--- a/drivers/media/platform/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/stm32/stm32-dcmi.c
@@ -1520,7 +1520,7 @@ static int dcmi_graph_parse(struct stm32_dcmi *dcmi, struct device_node *node)
 		/* Remote node to connect */
 		dcmi->entity.node = remote;
 		dcmi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		dcmi->entity.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		dcmi->entity.asd.match.fwnode = of_fwnode_handle(remote);
 		return 0;
 	}
 }
diff --git a/drivers/media/platform/tegra-cec/tegra_cec.c b/drivers/media/platform/tegra-cec/tegra_cec.c
index 807c94c..92f93a8 100644
--- a/drivers/media/platform/tegra-cec/tegra_cec.c
+++ b/drivers/media/platform/tegra-cec/tegra_cec.c
@@ -493,3 +493,8 @@ static struct platform_driver tegra_cec_driver = {
 };
 
 module_platform_driver(tegra_cec_driver);
+
+MODULE_DESCRIPTION("Tegra HDMI CEC driver");
+MODULE_AUTHOR("NVIDIA CORPORATION");
+MODULE_AUTHOR("Cisco Systems, Inc. and/or its affiliates");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
index 8b586c8..d1febe5 100644
--- a/drivers/media/platform/ti-vpe/cal.c
+++ b/drivers/media/platform/ti-vpe/cal.c
@@ -28,10 +28,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
 #include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-common.h>
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-dma-contig.h>
 #include "cal_regs.h"
@@ -1705,7 +1702,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
 		goto cleanup_exit;
 	}
 	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-	asd->match.fwnode.fwnode = of_fwnode_handle(sensor_node);
+	asd->match.fwnode = of_fwnode_handle(sensor_node);
 
 	remote_ep = of_graph_get_remote_endpoint(ep_node);
 	if (!remote_ep) {
diff --git a/drivers/media/platform/via-camera.h b/drivers/media/platform/via-camera.h
index 2d67f8c..54f1631 100644
--- a/drivers/media/platform/via-camera.h
+++ b/drivers/media/platform/via-camera.h
@@ -29,7 +29,7 @@
 #define   VCR_CI_BSS	  0x00000002  /* WTF "bit stream selection" */
 #define   VCR_CI_3BUFS	  0x00000004  /* 1 = 3 buffers, 0 = 2 buffers */
 #define   VCR_CI_VIPEN	  0x00000008  /* VIP enable */
-#define   VCR_CI_CCIR601_8  0	        /* CCIR601 input stream, 8 bit */
+#define   VCR_CI_CCIR601_8  0		/* CCIR601 input stream, 8 bit */
 #define   VCR_CI_CCIR656_8  0x00000010  /* ... CCIR656, 8 bit */
 #define   VCR_CI_CCIR601_16 0x00000020  /* ... CCIR601, 16 bit */
 #define   VCR_CI_CCIR656_16 0x00000030  /* ... CCIR656, 16 bit */
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
index dca528a..2e9981b 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -22,6 +22,11 @@
 #include <media/media-device.h>
 #include <media/v4l2-device.h>
 
+/* VIMC-specific controls */
+#define VIMC_CID_VIMC_BASE		(0x00f00000 | 0xf000)
+#define VIMC_CID_VIMC_CLASS		(0x00f00000 | 1)
+#define VIMC_CID_TEST_PATTERN		(VIMC_CID_VIMC_BASE + 0)
+
 #define VIMC_FRAME_MAX_WIDTH 4096
 #define VIMC_FRAME_MAX_HEIGHT 2160
 #define VIMC_FRAME_MIN_WIDTH 16
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index 02e68c8..457e211 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -22,8 +22,9 @@
 #include <linux/platform_device.h>
 #include <linux/v4l2-mediabus.h>
 #include <linux/vmalloc.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-subdev.h>
-#include <media/v4l2-tpg.h>
+#include <media/tpg/v4l2-tpg.h>
 
 #include "vimc-common.h"
 
@@ -38,6 +39,7 @@ struct vimc_sen_device {
 	u8 *frame;
 	/* The active format */
 	struct v4l2_mbus_framefmt mbus_format;
+	struct v4l2_ctrl_handler hdl;
 };
 
 static const struct v4l2_mbus_framefmt fmt_default = {
@@ -291,6 +293,31 @@ static const struct v4l2_subdev_ops vimc_sen_ops = {
 	.video = &vimc_sen_video_ops,
 };
 
+static int vimc_sen_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vimc_sen_device *vsen =
+		container_of(ctrl->handler, struct vimc_sen_device, hdl);
+
+	switch (ctrl->id) {
+	case VIMC_CID_TEST_PATTERN:
+		tpg_s_pattern(&vsen->tpg, ctrl->val);
+		break;
+	case V4L2_CID_HFLIP:
+		tpg_s_hflip(&vsen->tpg, ctrl->val);
+		break;
+	case V4L2_CID_VFLIP:
+		tpg_s_vflip(&vsen->tpg, ctrl->val);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = {
+	.s_ctrl = vimc_sen_s_ctrl,
+};
+
 static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
 				 void *master_data)
 {
@@ -299,10 +326,28 @@ static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
 				container_of(ved, struct vimc_sen_device, ved);
 
 	vimc_ent_sd_unregister(ved, &vsen->sd);
+	v4l2_ctrl_handler_free(&vsen->hdl);
 	tpg_free(&vsen->tpg);
 	kfree(vsen);
 }
 
+/* Image Processing Controls */
+static const struct v4l2_ctrl_config vimc_sen_ctrl_class = {
+	.flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
+	.id = VIMC_CID_VIMC_CLASS,
+	.name = "VIMC Controls",
+	.type = V4L2_CTRL_TYPE_CTRL_CLASS,
+};
+
+static const struct v4l2_ctrl_config vimc_sen_ctrl_test_pattern = {
+	.ops = &vimc_sen_ctrl_ops,
+	.id = VIMC_CID_TEST_PATTERN,
+	.name = "Test Pattern",
+	.type = V4L2_CTRL_TYPE_MENU,
+	.max = TPG_PAT_NOISE,
+	.qmenu = tpg_pattern_strings,
+};
+
 static int vimc_sen_comp_bind(struct device *comp, struct device *master,
 			      void *master_data)
 {
@@ -316,6 +361,20 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
 	if (!vsen)
 		return -ENOMEM;
 
+	v4l2_ctrl_handler_init(&vsen->hdl, 4);
+
+	v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_class, NULL);
+	v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_test_pattern, NULL);
+	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+			  V4L2_CID_VFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+			  V4L2_CID_HFLIP, 0, 1, 1, 0);
+	vsen->sd.ctrl_handler = &vsen->hdl;
+	if (vsen->hdl.error) {
+		ret = vsen->hdl.error;
+		goto err_free_vsen;
+	}
+
 	/* Initialize ved and sd */
 	ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
 				   pdata->entity_name,
@@ -323,7 +382,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
 				   (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
 				   &vimc_sen_ops);
 	if (ret)
-		goto err_free_vsen;
+		goto err_free_hdl;
 
 	dev_set_drvdata(comp, &vsen->ved);
 	vsen->dev = comp;
@@ -342,6 +401,8 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
 
 err_unregister_ent_sd:
 	vimc_ent_sd_unregister(&vsen->ved,  &vsen->sd);
+err_free_hdl:
+	v4l2_ctrl_handler_free(&vsen->hdl);
 err_free_vsen:
 	kfree(vsen);
 
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index c802395..9f036c5 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -995,7 +995,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
 
 	dev->edid_max_blocks = dev->edid_blocks = 2;
 	memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid));
-	ktime_get_ts(&dev->radio_rds_init_ts);
+	dev->radio_rds_init_time = ktime_get();
 
 	/* create all controls */
 	ret = vivid_create_controls(dev, ccs_cap == -1, ccs_out == -1, no_error_inj,
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
index 5cdf95b..c90e4a0 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -27,7 +27,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-dev.h>
 #include <media/v4l2-ctrls.h>
-#include <media/v4l2-tpg.h>
+#include <media/tpg/v4l2-tpg.h>
 #include "vivid-rds-gen.h"
 #include "vivid-vbi-gen.h"
 
@@ -154,6 +154,7 @@ struct vivid_dev {
 	struct v4l2_ctrl_handler	ctrl_hdl_streaming;
 	struct v4l2_ctrl_handler	ctrl_hdl_sdtv_cap;
 	struct v4l2_ctrl_handler	ctrl_hdl_loop_cap;
+	struct v4l2_ctrl_handler	ctrl_hdl_fb;
 	struct video_device		vid_cap_dev;
 	struct v4l2_ctrl_handler	ctrl_hdl_vid_cap;
 	struct video_device		vid_out_dev;
@@ -510,7 +511,7 @@ struct vivid_dev {
 
 	/* Shared between radio receiver and transmitter */
 	bool				radio_rds_loop;
-	struct timespec			radio_rds_init_ts;
+	ktime_t				radio_rds_init_time;
 
 	/* CEC */
 	struct cec_adapter		*cec_rx_adap;
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
index 34731f7..3f9d354 100644
--- a/drivers/media/platform/vivid/vivid-ctrls.c
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
@@ -120,9 +120,6 @@ static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
 		clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
 		clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
 		break;
-	case VIVID_CID_CLEAR_FB:
-		vivid_clear_fb(dev);
-		break;
 	case VIVID_CID_BUTTON:
 		dev->button_pressed = 30;
 		break;
@@ -274,8 +271,28 @@ static const struct v4l2_ctrl_config vivid_ctrl_disconnect = {
 	.type = V4L2_CTRL_TYPE_BUTTON,
 };
 
+
+/* Framebuffer Controls */
+
+static int vivid_fb_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vivid_dev *dev = container_of(ctrl->handler,
+					     struct vivid_dev, ctrl_hdl_fb);
+
+	switch (ctrl->id) {
+	case VIVID_CID_CLEAR_FB:
+		vivid_clear_fb(dev);
+		break;
+	}
+	return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_fb_ctrl_ops = {
+	.s_ctrl = vivid_fb_s_ctrl,
+};
+
 static const struct v4l2_ctrl_config vivid_ctrl_clear_fb = {
-	.ops = &vivid_user_gen_ctrl_ops,
+	.ops = &vivid_fb_ctrl_ops,
 	.id = VIVID_CID_CLEAR_FB,
 	.name = "Clear Framebuffer",
 	.type = V4L2_CTRL_TYPE_BUTTON,
@@ -1357,6 +1374,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
 	struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming;
 	struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap;
 	struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap;
+	struct v4l2_ctrl_handler *hdl_fb = &dev->ctrl_hdl_fb;
 	struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap;
 	struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out;
 	struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap;
@@ -1384,10 +1402,12 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
 	v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL);
 	v4l2_ctrl_handler_init(hdl_loop_cap, 1);
 	v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL);
+	v4l2_ctrl_handler_init(hdl_fb, 1);
+	v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_class, NULL);
 	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)
+	if (!no_error_inj || dev->has_fb)
 		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);
@@ -1561,7 +1581,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
 		v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL);
 
 	if (dev->has_fb)
-		v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_clear_fb, NULL);
+		v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_clear_fb, NULL);
 
 	if (dev->has_radio_rx) {
 		v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_mode, NULL);
@@ -1658,6 +1678,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
 		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL);
 		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL);
 		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL);
+		v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL);
 		if (hdl_vid_cap->error)
 			return hdl_vid_cap->error;
 		dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
@@ -1666,6 +1687,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
 		v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL);
 		v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL);
 		v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL);
+		v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL);
 		if (hdl_vid_out->error)
 			return hdl_vid_out->error;
 		dev->vid_out_dev.ctrl_handler = hdl_vid_out;
@@ -1725,4 +1747,5 @@ void vivid_free_controls(struct vivid_dev *dev)
 	v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming);
 	v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap);
 	v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap);
+	v4l2_ctrl_handler_free(&dev->ctrl_hdl_fb);
 }
diff --git a/drivers/media/platform/vivid/vivid-radio-rx.c b/drivers/media/platform/vivid/vivid-radio-rx.c
index 71f3ebb..fcb7a9f 100644
--- a/drivers/media/platform/vivid/vivid-radio-rx.c
+++ b/drivers/media/platform/vivid/vivid-radio-rx.c
@@ -38,9 +38,9 @@ ssize_t vivid_radio_rx_read(struct file *file, char __user *buf,
 			 size_t size, loff_t *offset)
 {
 	struct vivid_dev *dev = video_drvdata(file);
-	struct timespec ts;
 	struct v4l2_rds_data *data = dev->rds_gen.data;
 	bool use_alternates;
+	ktime_t timestamp;
 	unsigned blk;
 	int perc;
 	int i;
@@ -64,17 +64,16 @@ ssize_t vivid_radio_rx_read(struct file *file, char __user *buf,
 	}
 
 retry:
-	ktime_get_ts(&ts);
-	use_alternates = ts.tv_sec % 10 >= 5;
+	timestamp = ktime_sub(ktime_get(), dev->radio_rds_init_time);
+	blk = ktime_divns(timestamp, VIVID_RDS_NSEC_PER_BLK);
+	use_alternates = (blk % VIVID_RDS_GEN_BLOCKS) & 1;
+
 	if (dev->radio_rx_rds_last_block == 0 ||
 	    dev->radio_rx_rds_use_alternates != use_alternates) {
 		dev->radio_rx_rds_use_alternates = use_alternates;
 		/* Re-init the RDS generator */
 		vivid_radio_rds_init(dev);
 	}
-	ts = timespec_sub(ts, dev->radio_rds_init_ts);
-	blk = ts.tv_sec * 100 + ts.tv_nsec / 10000000;
-	blk = (blk * VIVID_RDS_GEN_BLOCKS) / 500;
 	if (blk >= dev->radio_rx_rds_last_block + VIVID_RDS_GEN_BLOCKS)
 		dev->radio_rx_rds_last_block = blk - VIVID_RDS_GEN_BLOCKS + 1;
 
diff --git a/drivers/media/platform/vivid/vivid-radio-tx.c b/drivers/media/platform/vivid/vivid-radio-tx.c
index f0917f4..af4907a 100644
--- a/drivers/media/platform/vivid/vivid-radio-tx.c
+++ b/drivers/media/platform/vivid/vivid-radio-tx.c
@@ -37,7 +37,7 @@ ssize_t vivid_radio_tx_write(struct file *file, const char __user *buf,
 {
 	struct vivid_dev *dev = video_drvdata(file);
 	struct v4l2_rds_data *data = dev->rds_gen.data;
-	struct timespec ts;
+	ktime_t timestamp;
 	unsigned blk;
 	int i;
 
@@ -58,10 +58,8 @@ ssize_t vivid_radio_tx_write(struct file *file, const char __user *buf,
 	dev->radio_tx_rds_owner = file->private_data;
 
 retry:
-	ktime_get_ts(&ts);
-	ts = timespec_sub(ts, dev->radio_rds_init_ts);
-	blk = ts.tv_sec * 100 + ts.tv_nsec / 10000000;
-	blk = (blk * VIVID_RDS_GEN_BLOCKS) / 500;
+	timestamp = ktime_sub(ktime_get(), dev->radio_rds_init_time);
+	blk = ktime_divns(timestamp, VIVID_RDS_NSEC_PER_BLK);
 	if (blk - VIVID_RDS_GEN_BLOCKS >= dev->radio_tx_rds_last_block)
 		dev->radio_tx_rds_last_block = blk - VIVID_RDS_GEN_BLOCKS + 1;
 
diff --git a/drivers/media/platform/vivid/vivid-rds-gen.c b/drivers/media/platform/vivid/vivid-rds-gen.c
index 53c7777d..996e35e 100644
--- a/drivers/media/platform/vivid/vivid-rds-gen.c
+++ b/drivers/media/platform/vivid/vivid-rds-gen.c
@@ -103,7 +103,7 @@ void vivid_rds_generate(struct vivid_rds_gen *rds)
 			 * EN 50067:1998 to convert a UTC date to an RDS Modified
 			 * Julian Day.
 			 */
-			time_to_tm(get_seconds(), 0, &tm);
+			time64_to_tm(ktime_get_real_seconds(), 0, &tm);
 			l = tm.tm_mon <= 1;
 			date = 14956 + tm.tm_mday + ((tm.tm_year - l) * 1461) / 4 +
 				((tm.tm_mon + 2 + l * 12) * 306001) / 10000;
diff --git a/drivers/media/platform/vivid/vivid-rds-gen.h b/drivers/media/platform/vivid/vivid-rds-gen.h
index eff4bf5..e55e3b2 100644
--- a/drivers/media/platform/vivid/vivid-rds-gen.h
+++ b/drivers/media/platform/vivid/vivid-rds-gen.h
@@ -29,6 +29,7 @@
 #define VIVID_RDS_GEN_GROUPS 57
 #define VIVID_RDS_GEN_BLKS_PER_GRP 4
 #define VIVID_RDS_GEN_BLOCKS (VIVID_RDS_GEN_BLKS_PER_GRP * VIVID_RDS_GEN_GROUPS)
+#define VIVID_RDS_NSEC_PER_BLK (u32)(5ull * NSEC_PER_SEC / VIVID_RDS_GEN_BLOCKS)
 
 struct vivid_rds_gen {
 	struct v4l2_rds_data	data[VIVID_RDS_GEN_BLOCKS];
diff --git a/drivers/media/platform/vivid/vivid-vbi-gen.c b/drivers/media/platform/vivid/vivid-vbi-gen.c
index a2159de..02c79d7 100644
--- a/drivers/media/platform/vivid/vivid-vbi-gen.c
+++ b/drivers/media/platform/vivid/vivid-vbi-gen.c
@@ -190,7 +190,7 @@ static void vivid_vbi_gen_set_time_of_day(u8 *packet)
 	struct tm tm;
 	u8 checksum, i;
 
-	time_to_tm(get_seconds(), 0, &tm);
+	time64_to_tm(ktime_get_real_seconds(), 0, &tm);
 	packet[0] = calc_parity(0x07);
 	packet[1] = calc_parity(0x01);
 	packet[2] = calc_parity(0x40 | tm.tm_min);
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
index 0141945..0fbbcde 100644
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
@@ -93,11 +93,6 @@ static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = {
 	{  1, 60 },
 };
 
-static const struct v4l2_discrete_probe webcam_probe = {
-	webcam_sizes,
-	VIVID_WEBCAM_SIZES
-};
-
 static int vid_cap_queue_setup(struct vb2_queue *vq,
 		       unsigned *nbuffers, unsigned *nplanes,
 		       unsigned sizes[], struct device *alloc_devs[])
@@ -578,7 +573,9 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
 	mp->field = vivid_field_cap(dev, mp->field);
 	if (vivid_is_webcam(dev)) {
 		const struct v4l2_frmsize_discrete *sz =
-			v4l2_find_nearest_format(&webcam_probe, mp->width, mp->height);
+			v4l2_find_nearest_format(webcam_sizes,
+						 VIVID_WEBCAM_SIZES,
+						 mp->width, mp->height);
 
 		w = sz->width;
 		h = sz->height;
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 962e4c3..eed9516 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -571,7 +571,13 @@ static int __maybe_unused vsp1_pm_suspend(struct device *dev)
 {
 	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
 
-	vsp1_pipelines_suspend(vsp1);
+	/*
+	 * When used as part of a display pipeline, the VSP is stopped and
+	 * restarted explicitly by the DU.
+	 */
+	if (!vsp1->drm)
+		vsp1_pipelines_suspend(vsp1);
+
 	pm_runtime_force_suspend(vsp1->dev);
 
 	return 0;
@@ -582,7 +588,13 @@ static int __maybe_unused vsp1_pm_resume(struct device *dev)
 	struct vsp1_device *vsp1 = dev_get_drvdata(dev);
 
 	pm_runtime_force_resume(vsp1->dev);
-	vsp1_pipelines_resume(vsp1);
+
+	/*
+	 * When used as part of a display pipeline, the VSP is stopped and
+	 * restarted explicitly by the DU.
+	 */
+	if (!vsp1->drm)
+		vsp1_pipelines_resume(vsp1);
 
 	return 0;
 }
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index d881cf0..6bb28cd4 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -76,20 +76,16 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
 	struct xvip_graph_entity *ent;
 	struct v4l2_fwnode_link link;
 	struct device_node *ep = NULL;
-	struct device_node *next;
 	int ret = 0;
 
 	dev_dbg(xdev->dev, "creating links for entity %s\n", local->name);
 
 	while (1) {
 		/* Get the next endpoint and parse its link. */
-		next = of_graph_get_next_endpoint(entity->node, ep);
-		if (next == NULL)
+		ep = of_graph_get_next_endpoint(entity->node, ep);
+		if (ep == NULL)
 			break;
 
-		of_node_put(ep);
-		ep = next;
-
 		dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep);
 
 		ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
@@ -200,7 +196,6 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
 	struct xvip_graph_entity *ent;
 	struct v4l2_fwnode_link link;
 	struct device_node *ep = NULL;
-	struct device_node *next;
 	struct xvip_dma *dma;
 	int ret = 0;
 
@@ -208,13 +203,10 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
 
 	while (1) {
 		/* Get the next endpoint and parse its link. */
-		next = of_graph_get_next_endpoint(node, ep);
-		if (next == NULL)
+		ep = of_graph_get_next_endpoint(node, ep);
+		if (ep == NULL)
 			break;
 
-		of_node_put(ep);
-		ep = next;
-
 		dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep);
 
 		ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
@@ -395,7 +387,7 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
 
 		entity->node = remote;
 		entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
-		entity->asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+		entity->asd.match.fwnode = of_fwnode_handle(remote);
 		list_add_tail(&entity->list, &xdev->entities);
 		xdev->num_subdevs++;
 	}
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index ea930879..5ef635e 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -26,7 +26,7 @@
  * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
  */
 
-#include <linux/module.h>	/* Modules 			*/
+#include <linux/module.h>	/* Modules			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* msleep			*/
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index f445327..9e12c60 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -15,7 +15,7 @@
  * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
 */
 
-#include <linux/module.h>	/* Modules 			*/
+#include <linux/module.h>	/* Modules			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index dba6110..af7c68b 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -30,7 +30,7 @@
  *		Changed API to V4L2
  */
 
-#include <linux/module.h>	/* Modules 			*/
+#include <linux/module.h>	/* Modules			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
@@ -503,7 +503,7 @@ static __poll_t cadet_poll(struct file *file, struct poll_table_struct *wait)
 static const struct v4l2_file_operations cadet_fops = {
 	.owner		= THIS_MODULE,
 	.open		= cadet_open,
-	.release       	= cadet_release,
+	.release	= cadet_release,
 	.read		= cadet_read,
 	.unlocked_ioctl	= video_ioctl2,
 	.poll		= cadet_poll,
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index ddc12b1..3ff4c4e 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -22,7 +22,7 @@
  * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
  */
 
-#include <linux/module.h>	/* Modules 			*/
+#include <linux/module.h>	/* Modules			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
@@ -102,9 +102,9 @@ struct gemtek {
 	u32 bu2614data;
 };
 
-#define BU2614_FREQ_BITS 	16 /* D0..D15, Frequency data		*/
+#define BU2614_FREQ_BITS	16 /* D0..D15, Frequency data		*/
 #define BU2614_PORT_BITS	3 /* P0..P2, Output port control data	*/
-#define BU2614_VOID_BITS	4 /* unused 				*/
+#define BU2614_VOID_BITS	4 /* unused				*/
 #define BU2614_FMES_BITS	1 /* CT, Frequency measurement beginning data */
 #define BU2614_STDF_BITS	3 /* R0..R2, Standard frequency data	*/
 #define BU2614_SWIN_BITS	1 /* S, Switch between FMIN / AMIN	*/
@@ -113,7 +113,7 @@ struct gemtek {
 #define BU2614_FMUN_BITS	1 /* GT, Frequency measurement time & unlock */
 #define BU2614_TEST_BITS	1 /* TS, Test data is input		*/
 
-#define BU2614_FREQ_SHIFT 	0
+#define BU2614_FREQ_SHIFT	0
 #define BU2614_PORT_SHIFT	(BU2614_FREQ_BITS + BU2614_FREQ_SHIFT)
 #define BU2614_VOID_SHIFT	(BU2614_PORT_BITS + BU2614_PORT_SHIFT)
 #define BU2614_FMES_SHIFT	(BU2614_VOID_BITS + BU2614_VOID_SHIFT)
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 3aa5ad3..95f06f3 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -13,7 +13,7 @@
  * anybody does please mail me.
  *
  * For the pdf file see:
- * http://www.nxp.com/acrobat_download2/expired_datasheets/TEA5757_5759_3.pdf 
+ * http://www.nxp.com/acrobat_download2/expired_datasheets/TEA5757_5759_3.pdf
  *
  *
  * CHANGES:
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index c9f5912..dc6c4f9 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -31,22 +31,22 @@
  * http://www.spinics.net/lists/linux-usb-devel/msg10109.html
  *
  * Version 0.01:	First working version.
- * 			It's required to blacklist AverMedia USB Radio
- * 			in usbhid/hid-quirks.c
+ *			It's required to blacklist AverMedia USB Radio
+ *			in usbhid/hid-quirks.c
  * Version 0.10:	A lot of cleanups and fixes: unpluging the device,
- * 			few mutex locks were added, codinstyle issues, etc.
- * 			Added stereo support. Thanks to
- * 			Douglas Schilling Landgraf <dougsland@gmail.com> and
- * 			David Ellingsworth <david@identd.dyndns.org>
- * 			for discussion, help and support.
+ *			few mutex locks were added, codinstyle issues, etc.
+ *			Added stereo support. Thanks to
+ *			Douglas Schilling Landgraf <dougsland@gmail.com> and
+ *			David Ellingsworth <david@identd.dyndns.org>
+ *			for discussion, help and support.
  * Version 0.11:	Converted to v4l2_device.
  *
  * Many things to do:
- * 	- Correct power management of device (suspend & resume)
- * 	- Add code for scanning and smooth tuning
- * 	- Add code for sensitivity value
- * 	- Correct mistakes
- * 	- In Japan another FREQ_MIN and FREQ_MAX
+ *	- Correct power management of device (suspend & resume)
+ *	- Add code for scanning and smooth tuning
+ *	- Add code for sensitivity value
+ *	- Correct mistakes
+ *	- In Japan another FREQ_MIN and FREQ_MAX
  */
 
 /* kernel includes */
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 09cfbc3..abeaedd 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -12,7 +12,7 @@
  * Fully tested with actual hardware and the v4l2-compliance tool.
  */
 
-#include <linux/module.h>	/* Modules 			*/
+#include <linux/module.h>	/* Modules			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 28a8946..fc4e63d 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -17,7 +17,7 @@
  */
 
 #include <linux/kernel.h>	/* __setup			*/
-#include <linux/module.h>	/* Modules 			*/
+#include <linux/module.h>	/* Modules			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/delay.h>	/* udelay			*/
@@ -110,7 +110,7 @@ static inline int fmi_getsigstr(struct fmi *fmi)
 	val = fmi->mute ? 0x00 : 0x08;	/* mute/unmute */
 	outb(val, fmi->io);
 	outb(val | 0x10, fmi->io);
-	msleep(143); 		/* was schedule_timeout(HZ/7) */
+	msleep(143);		/* was schedule_timeout(HZ/7) */
 	res = (int)inb(fmi->io + 1);
 	outb(val, fmi->io);
 
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index de79d55..7b07d42 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -7,7 +7,7 @@
  */
 
 #include <linux/delay.h>
-#include <linux/module.h>	/* Modules 			*/
+#include <linux/module.h>	/* Modules			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/slab.h>
 #include <linux/ioport.h>	/* request_region		*/
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c
index 49293dd..bff9789 100644
--- a/drivers/media/radio/radio-si476x.c
+++ b/drivers/media/radio/radio-si476x.c
@@ -759,7 +759,7 @@ static int si476x_radio_s_hw_freq_seek(struct file *file, void *priv,
 {
 	int err;
 	enum si476x_func func;
-	u32 rangelow, rangehigh;
+	u32 rangelow = seek->rangelow, rangehigh = seek->rangehigh;
 	struct si476x_radio *radio = video_drvdata(file);
 
 	if (file->f_flags & O_NONBLOCK)
@@ -771,23 +771,21 @@ static int si476x_radio_s_hw_freq_seek(struct file *file, void *priv,
 
 	si476x_core_lock(radio->core);
 
-	if (!seek->rangelow) {
+	if (!rangelow) {
 		err = regmap_read(radio->core->regmap,
 				  SI476X_PROP_SEEK_BAND_BOTTOM,
 				  &rangelow);
-		if (!err)
-			rangelow = si476x_to_v4l2(radio->core, rangelow);
-		else
+		if (err)
 			goto unlock;
+		rangelow = si476x_to_v4l2(radio->core, rangelow);
 	}
-	if (!seek->rangehigh) {
+	if (!rangehigh) {
 		err = regmap_read(radio->core->regmap,
 				  SI476X_PROP_SEEK_BAND_TOP,
 				  &rangehigh);
-		if (!err)
-			rangehigh = si476x_to_v4l2(radio->core, rangehigh);
-		else
+		if (err)
 			goto unlock;
+		rangehigh = si476x_to_v4l2(radio->core, rangehigh);
 	}
 
 	if (rangelow > rangehigh) {
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index bc7e69e..afb7632 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -417,7 +417,7 @@ static const struct v4l2_ioctl_ops tea5764_ioctl_ops = {
 static const struct video_device tea5764_radio_template = {
 	.name		= "TEA5764 FM-Radio",
 	.fops           = &tea5764_fops,
-	.ioctl_ops 	= &tea5764_ioctl_ops,
+	.ioctl_ops	= &tea5764_ioctl_ops,
 	.release	= video_device_release_empty,
 };
 
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index be10a80..4f116ea 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -20,7 +20,7 @@
  * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
  */
 
-#include <linux/module.h>	/* Modules 			*/
+#include <linux/module.h>	/* Modules			*/
 #include <linux/init.h>		/* Initdata			*/
 #include <linux/ioport.h>	/* request_region		*/
 #include <linux/videodev2.h>	/* kernel radio structs		*/
@@ -45,12 +45,12 @@ static int radio_nr = -1;
 module_param(radio_nr, int, 0444);
 MODULE_PARM_DESC(radio_nr, "Radio device number");
 
-#define WRT_DIS 	0x00
+#define WRT_DIS		0x00
 #define CLK_OFF		0x00
 #define IIC_DATA	0x01
 #define IIC_CLK		0x02
 #define DATA		0x04
-#define CLK_ON 		0x08
+#define CLK_ON		0x08
 #define WRT_EN		0x10
 
 static struct radio_isa_card *terratec_alloc(void)
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 68fe9e5..5b477b7 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -33,18 +33,18 @@
  *		- switched from bit structs to bit masks
  *		- header file cleaned and integrated
  * 2008-01-14	Tobias Lorenz <tobias.lorenz@gmx.net>
- * 		Version 1.0.2
- * 		- hex values are now lower case
- * 		- commented USB ID for ADS/Tech moved on todo list
- * 		- blacklisted si470x in hid-quirks.c
- * 		- rds buffer handling functions integrated into *_work, *_read
- * 		- rds_command in si470x_poll exchanged against simple retval
- * 		- check for firmware version 15
- * 		- code order and prototypes still remain the same
- * 		- spacing and bottom of band codes remain the same
+ *		Version 1.0.2
+ *		- hex values are now lower case
+ *		- commented USB ID for ADS/Tech moved on todo list
+ *		- blacklisted si470x in hid-quirks.c
+ *		- rds buffer handling functions integrated into *_work, *_read
+ *		- rds_command in si470x_poll exchanged against simple retval
+ *		- check for firmware version 15
+ *		- code order and prototypes still remain the same
+ *		- spacing and bottom of band codes remain the same
  * 2008-01-16	Tobias Lorenz <tobias.lorenz@gmx.net>
  *		Version 1.0.3
- * 		- code reordered to avoid function prototypes
+ *		- code reordered to avoid function prototypes
  *		- switch/case defaults are now more user-friendly
  *		- unified comment style
  *		- applied all checkpatch.pl v1.12 suggestions
@@ -88,8 +88,8 @@
  *		- more safety checks, let si470x_get_freq return errno
  *		- vidioc behavior corrected according to v4l2 spec
  * 2008-10-20	Alexey Klimov <klimov.linux@gmail.com>
- * 		- add support for KWorld USB FM Radio FM700
- * 		- blacklisted KWorld radio in hid-core.c and hid-ids.h
+ *		- add support for KWorld USB FM Radio FM700
+ *		- blacklisted KWorld radio in hid-core.c and hid-ids.h
  * 2008-12-03	Mark Lord <mlord@pobox.com>
  *		- add support for DealExtreme USB Radio
  * 2009-01-31	Bob Ross <pigiron@gmx.com>
diff --git a/drivers/media/radio/tea575x.c b/drivers/media/radio/tea575x.c
index 4dc2067..7412fe1 100644
--- a/drivers/media/radio/tea575x.c
+++ b/drivers/media/radio/tea575x.c
@@ -498,7 +498,7 @@ static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
 };
 
 static const struct video_device tea575x_radio = {
-	.ioctl_ops 	= &tea575x_ioctl_ops,
+	.ioctl_ops	= &tea575x_ioctl_ops,
 	.release        = video_device_release_empty,
 };
 
diff --git a/drivers/media/radio/wl128x/fmdrv_common.h b/drivers/media/radio/wl128x/fmdrv_common.h
index 7f1514eb..552e22e 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.h
+++ b/drivers/media/radio/wl128x/fmdrv_common.h
@@ -311,11 +311,11 @@ struct fm_event_msg_hdr {
 #define FM_RDS_GROUP_TYPE_MASK_15B	    ((unsigned long)1<<31)
 
 /* RX Alternate Frequency info */
-#define FM_RDS_MIN_AF		          1
-#define FM_RDS_MAX_AF		        204
-#define FM_RDS_MAX_AF_JAPAN	        140
-#define FM_RDS_1_AF_FOLLOWS	        225
-#define FM_RDS_25_AF_FOLLOWS	        249
+#define FM_RDS_MIN_AF			  1
+#define FM_RDS_MAX_AF			204
+#define FM_RDS_MAX_AF_JAPAN		140
+#define FM_RDS_1_AF_FOLLOWS		225
+#define FM_RDS_25_AF_FOLLOWS		249
 
 /* RDS system type (RDS/RBDS) */
 #define FM_RDS_SYSTEM_RDS		0
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index afb3456..f14ead5 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -16,34 +16,21 @@
 if RC_CORE
 source "drivers/media/rc/keymaps/Kconfig"
 
+config LIRC
+	bool "LIRC user interface"
+	depends on RC_CORE
+	---help---
+	   Enable this option to enable the Linux Infrared Remote
+	   Control user interface (e.g. /dev/lirc*). This interface
+	   passes raw IR to and from userspace, which is needed for
+	   IR transmitting (aka "blasting") and for the lirc daemon.
+
 menuconfig RC_DECODERS
-        bool "Remote controller decoders"
+	bool "Remote controller decoders"
 	depends on RC_CORE
 	default y
 
 if RC_DECODERS
-config LIRC
-	tristate "LIRC interface driver"
-	depends on RC_CORE
-
-	---help---
-	   Enable this option to build the Linux Infrared Remote
-	   Control (LIRC) core device interface driver. The LIRC
-	   interface passes raw IR to and from userspace, where the
-	   LIRC daemon handles protocol decoding for IR reception and
-	   encoding for IR transmitting (aka "blasting").
-
-config IR_LIRC_CODEC
-	tristate "Enable IR to LIRC bridge"
-	depends on RC_CORE
-	depends on LIRC
-	default y
-
-	---help---
-	   Enable this option to pass raw IR to and from userspace via
-	   the LIRC interface.
-
-
 config IR_NEC_DECODER
 	tristate "Enable IR raw decoder for the NEC protocol"
 	depends on RC_CORE
@@ -465,9 +452,9 @@
 	   Serial Port Transmitter support
 
 config IR_SIR
-        tristate "Built-in SIR IrDA port"
-        depends on RC_CORE
-        ---help---
+	tristate "Built-in SIR IrDA port"
+	depends on RC_CORE
+	---help---
 	   Say Y if you want to use a IrDA SIR port Transceivers.
 
 	   To compile this driver as a module, choose M here: the module will
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 1002647..0e85781 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -1,10 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
-rc-core-objs	:= rc-main.o rc-ir-raw.o
 
 obj-y += keymaps/
 
 obj-$(CONFIG_RC_CORE) += rc-core.o
-obj-$(CONFIG_LIRC) += lirc_dev.o
+rc-core-y := rc-main.o rc-ir-raw.o
+rc-core-$(CONFIG_LIRC) += lirc_dev.o
 obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
 obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
 obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
@@ -13,7 +13,6 @@
 obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o
 obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o
 obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o
-obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
 obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o
 
 # stand-alone IR receivers/transmitters
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index 30e24da..7daac8b 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -347,26 +347,23 @@ static int iguanair_set_tx_mask(struct rc_dev *dev, uint32_t mask)
 static int iguanair_tx(struct rc_dev *dev, unsigned *txbuf, unsigned count)
 {
 	struct iguanair *ir = dev->priv;
-	uint8_t space;
-	unsigned i, size, periods, bytes;
+	unsigned int i, size, p, periods;
 	int rc;
 
 	mutex_lock(&ir->lock);
 
 	/* convert from us to carrier periods */
-	for (i = space = size = 0; i < count; i++) {
+	for (i = size = 0; i < count; i++) {
 		periods = DIV_ROUND_CLOSEST(txbuf[i] * ir->carrier, 1000000);
-		bytes = DIV_ROUND_UP(periods, 127);
-		if (size + bytes > ir->bufsize) {
-			rc = -EINVAL;
-			goto out;
-		}
 		while (periods) {
-			unsigned p = min(periods, 127u);
-			ir->packet->payload[size++] = p | space;
+			p = min(periods, 127u);
+			if (size >= ir->bufsize) {
+				rc = -EINVAL;
+				goto out;
+			}
+			ir->packet->payload[size++] = p | ((i & 1) ? 0x80 : 0);
 			periods -= p;
 		}
-		space ^= 0x80;
 	}
 
 	ir->packet->header.start = 0;
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index eb943e8..950d068 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -27,6 +27,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/ktime.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
@@ -37,7 +38,6 @@
 #include <linux/usb/input.h>
 #include <media/rc-core.h>
 
-#include <linux/time.h>
 #include <linux/timer.h>
 
 #define MOD_AUTHOR	"Jarod Wilson <jarod@wilsonet.com>"
@@ -1168,29 +1168,6 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto)
 	return retval;
 }
 
-static inline int tv2int(const struct timeval *a, const struct timeval *b)
-{
-	int usecs = 0;
-	int sec   = 0;
-
-	if (b->tv_usec > a->tv_usec) {
-		usecs = 1000000;
-		sec--;
-	}
-
-	usecs += a->tv_usec - b->tv_usec;
-
-	sec += a->tv_sec - b->tv_sec;
-	sec *= 1000;
-	usecs /= 1000;
-	sec += usecs;
-
-	if (sec < 0)
-		sec = 1000;
-
-	return sec;
-}
-
 /*
  * The directional pad behaves a bit differently, depending on whether this is
  * one of the older ffdc devices or a newer device. Newer devices appear to
@@ -1201,16 +1178,16 @@ static inline int tv2int(const struct timeval *a, const struct timeval *b)
  */
 static int stabilize(int a, int b, u16 timeout, u16 threshold)
 {
-	struct timeval ct;
-	static struct timeval prev_time = {0, 0};
-	static struct timeval hit_time  = {0, 0};
+	ktime_t ct;
+	static ktime_t prev_time;
+	static ktime_t hit_time;
 	static int x, y, prev_result, hits;
 	int result = 0;
-	int msec, msec_hit;
+	long msec, msec_hit;
 
-	do_gettimeofday(&ct);
-	msec = tv2int(&ct, &prev_time);
-	msec_hit = tv2int(&ct, &hit_time);
+	ct = ktime_get();
+	msec = ktime_ms_delta(ct, prev_time);
+	msec_hit = ktime_ms_delta(ct, hit_time);
 
 	if (msec > 100) {
 		x = 0;
@@ -1688,9 +1665,9 @@ static void imon_incoming_scancode(struct imon_context *ictx,
 	u32 kc;
 	u64 scancode;
 	int press_type = 0;
-	int msec;
-	struct timeval t;
-	static struct timeval prev_time = { 0, 0 };
+	long msec;
+	ktime_t t;
+	static ktime_t prev_time;
 	u8 ktype;
 
 	/* filter out junk data on the older 0xffdc imon devices */
@@ -1783,10 +1760,10 @@ static void imon_incoming_scancode(struct imon_context *ictx,
 	/* Only panel type events left to process now */
 	spin_lock_irqsave(&ictx->kc_lock, flags);
 
-	do_gettimeofday(&t);
+	t = ktime_get();
 	/* KEY_MUTE repeats from knob need to be suppressed */
 	if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) {
-		msec = tv2int(&t, &prev_time);
+		msec = ktime_ms_delta(t, prev_time);
 		if (msec < ictx->idev->rep[REP_DELAY]) {
 			spin_unlock_irqrestore(&ictx->kc_lock, flags);
 			return;
@@ -1956,6 +1933,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
 		break;
 	/* iMON VFD, iMON IR */
 	case 0x24:
+	case 0x30:
 	case 0x85:
 		dev_info(ictx->dev, "0xffdc iMON VFD, iMON IR");
 		detected_display_type = IMON_DISPLAY_TYPE_VFD;
@@ -1974,6 +1952,11 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
 		detected_display_type = IMON_DISPLAY_TYPE_LCD;
 		allowed_protos = RC_PROTO_BIT_RC6_MCE;
 		break;
+	/* no display, iMON IR */
+	case 0x26:
+		dev_info(ictx->dev, "0xffdc iMON Inside, iMON IR");
+		ictx->display_supported = false;
+		break;
 	default:
 		dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR");
 		detected_display_type = IMON_DISPLAY_TYPE_VFD;
diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c
index 22c8aee..c03c776 100644
--- a/drivers/media/rc/ir-jvc-decoder.c
+++ b/drivers/media/rc/ir-jvc-decoder.c
@@ -212,6 +212,7 @@ static struct ir_raw_handler jvc_handler = {
 	.protocols	= RC_PROTO_BIT_JVC,
 	.decode		= ir_jvc_decode,
 	.encode		= ir_jvc_encode,
+	.carrier	= 38000,
 };
 
 static int __init ir_jvc_decode_init(void)
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
deleted file mode 100644
index 4fd45216..0000000
--- a/drivers/media/rc/ir-lirc-codec.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/* ir-lirc-codec.c - rc-core to classic lirc interface bridge
- *
- * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- */
-
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <media/lirc.h>
-#include <media/lirc_dev.h>
-#include <media/rc-core.h>
-#include "rc-core-priv.h"
-
-#define LIRCBUF_SIZE 256
-
-/**
- * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
- *		      lircd userspace daemon for decoding.
- * @dev:	the struct rc_dev descriptor of the device
- * @ev:		the struct ir_raw_event descriptor of the pulse/space
- *
- * This function returns -EINVAL if the lirc interfaces aren't wired up.
- */
-static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
-{
-	struct lirc_codec *lirc = &dev->raw->lirc;
-	int sample;
-
-	if (!dev->raw->lirc.ldev || !dev->raw->lirc.ldev->buf)
-		return -EINVAL;
-
-	/* Packet start */
-	if (ev.reset) {
-		/* Userspace expects a long space event before the start of
-		 * the signal to use as a sync.  This may be done with repeat
-		 * packets and normal samples.  But if a reset has been sent
-		 * then we assume that a long time has passed, so we send a
-		 * space with the maximum time value. */
-		sample = LIRC_SPACE(LIRC_VALUE_MASK);
-		IR_dprintk(2, "delivering reset sync space to lirc_dev\n");
-
-	/* Carrier reports */
-	} else if (ev.carrier_report) {
-		sample = LIRC_FREQUENCY(ev.carrier);
-		IR_dprintk(2, "carrier report (freq: %d)\n", sample);
-
-	/* Packet end */
-	} else if (ev.timeout) {
-
-		if (lirc->gap)
-			return 0;
-
-		lirc->gap_start = ktime_get();
-		lirc->gap = true;
-		lirc->gap_duration = ev.duration;
-
-		if (!lirc->send_timeout_reports)
-			return 0;
-
-		sample = LIRC_TIMEOUT(ev.duration / 1000);
-		IR_dprintk(2, "timeout report (duration: %d)\n", sample);
-
-	/* Normal sample */
-	} else {
-
-		if (lirc->gap) {
-			int gap_sample;
-
-			lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
-				lirc->gap_start));
-
-			/* Convert to ms and cap by LIRC_VALUE_MASK */
-			do_div(lirc->gap_duration, 1000);
-			lirc->gap_duration = min(lirc->gap_duration,
-							(u64)LIRC_VALUE_MASK);
-
-			gap_sample = LIRC_SPACE(lirc->gap_duration);
-			lirc_buffer_write(dev->raw->lirc.ldev->buf,
-					  (unsigned char *)&gap_sample);
-			lirc->gap = false;
-		}
-
-		sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
-					LIRC_SPACE(ev.duration / 1000);
-		IR_dprintk(2, "delivering %uus %s to lirc_dev\n",
-			   TO_US(ev.duration), TO_STR(ev.pulse));
-	}
-
-	lirc_buffer_write(dev->raw->lirc.ldev->buf,
-			  (unsigned char *) &sample);
-	wake_up(&dev->raw->lirc.ldev->buf->wait_poll);
-
-	return 0;
-}
-
-static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
-				   size_t n, loff_t *ppos)
-{
-	struct lirc_codec *lirc;
-	struct rc_dev *dev;
-	unsigned int *txbuf; /* buffer with values to transmit */
-	ssize_t ret = -EINVAL;
-	size_t count;
-	ktime_t start;
-	s64 towait;
-	unsigned int duration = 0; /* signal duration in us */
-	int i;
-
-	start = ktime_get();
-
-	lirc = lirc_get_pdata(file);
-	if (!lirc)
-		return -EFAULT;
-
-	if (n < sizeof(unsigned) || n % sizeof(unsigned))
-		return -EINVAL;
-
-	count = n / sizeof(unsigned);
-	if (count > LIRCBUF_SIZE || count % 2 == 0)
-		return -EINVAL;
-
-	txbuf = memdup_user(buf, n);
-	if (IS_ERR(txbuf))
-		return PTR_ERR(txbuf);
-
-	dev = lirc->dev;
-	if (!dev) {
-		ret = -EFAULT;
-		goto out;
-	}
-
-	if (!dev->tx_ir) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	for (i = 0; i < count; i++) {
-		if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) {
-			ret = -EINVAL;
-			goto out;
-		}
-
-		duration += txbuf[i];
-	}
-
-	ret = dev->tx_ir(dev, txbuf, count);
-	if (ret < 0)
-		goto out;
-
-	for (duration = i = 0; i < ret; i++)
-		duration += txbuf[i];
-
-	ret *= sizeof(unsigned int);
-
-	/*
-	 * The lircd gap calculation expects the write function to
-	 * wait for the actual IR signal to be transmitted before
-	 * returning.
-	 */
-	towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get());
-	if (towait > 0) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(usecs_to_jiffies(towait));
-	}
-
-out:
-	kfree(txbuf);
-	return ret;
-}
-
-static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
-			unsigned long arg)
-{
-	struct lirc_codec *lirc;
-	struct rc_dev *dev;
-	u32 __user *argp = (u32 __user *)(arg);
-	int ret = 0;
-	__u32 val = 0, tmp;
-
-	lirc = lirc_get_pdata(filep);
-	if (!lirc)
-		return -EFAULT;
-
-	dev = lirc->dev;
-	if (!dev)
-		return -EFAULT;
-
-	if (_IOC_DIR(cmd) & _IOC_WRITE) {
-		ret = get_user(val, argp);
-		if (ret)
-			return ret;
-	}
-
-	switch (cmd) {
-
-	/* legacy support */
-	case LIRC_GET_SEND_MODE:
-		if (!dev->tx_ir)
-			return -ENOTTY;
-
-		val = LIRC_MODE_PULSE;
-		break;
-
-	case LIRC_SET_SEND_MODE:
-		if (!dev->tx_ir)
-			return -ENOTTY;
-
-		if (val != LIRC_MODE_PULSE)
-			return -EINVAL;
-		return 0;
-
-	/* TX settings */
-	case LIRC_SET_TRANSMITTER_MASK:
-		if (!dev->s_tx_mask)
-			return -ENOTTY;
-
-		return dev->s_tx_mask(dev, val);
-
-	case LIRC_SET_SEND_CARRIER:
-		if (!dev->s_tx_carrier)
-			return -ENOTTY;
-
-		return dev->s_tx_carrier(dev, val);
-
-	case LIRC_SET_SEND_DUTY_CYCLE:
-		if (!dev->s_tx_duty_cycle)
-			return -ENOTTY;
-
-		if (val <= 0 || val >= 100)
-			return -EINVAL;
-
-		return dev->s_tx_duty_cycle(dev, val);
-
-	/* RX settings */
-	case LIRC_SET_REC_CARRIER:
-		if (!dev->s_rx_carrier_range)
-			return -ENOTTY;
-
-		if (val <= 0)
-			return -EINVAL;
-
-		return dev->s_rx_carrier_range(dev,
-					       dev->raw->lirc.carrier_low,
-					       val);
-
-	case LIRC_SET_REC_CARRIER_RANGE:
-		if (!dev->s_rx_carrier_range)
-			return -ENOTTY;
-
-		if (val <= 0)
-			return -EINVAL;
-
-		dev->raw->lirc.carrier_low = val;
-		return 0;
-
-	case LIRC_GET_REC_RESOLUTION:
-		if (!dev->rx_resolution)
-			return -ENOTTY;
-
-		val = dev->rx_resolution / 1000;
-		break;
-
-	case LIRC_SET_WIDEBAND_RECEIVER:
-		if (!dev->s_learning_mode)
-			return -ENOTTY;
-
-		return dev->s_learning_mode(dev, !!val);
-
-	case LIRC_SET_MEASURE_CARRIER_MODE:
-		if (!dev->s_carrier_report)
-			return -ENOTTY;
-
-		return dev->s_carrier_report(dev, !!val);
-
-	/* Generic timeout support */
-	case LIRC_GET_MIN_TIMEOUT:
-		if (!dev->max_timeout)
-			return -ENOTTY;
-		val = DIV_ROUND_UP(dev->min_timeout, 1000);
-		break;
-
-	case LIRC_GET_MAX_TIMEOUT:
-		if (!dev->max_timeout)
-			return -ENOTTY;
-		val = dev->max_timeout / 1000;
-		break;
-
-	case LIRC_SET_REC_TIMEOUT:
-		if (!dev->max_timeout)
-			return -ENOTTY;
-
-		/* Check for multiply overflow */
-		if (val > U32_MAX / 1000)
-			return -EINVAL;
-
-		tmp = val * 1000;
-
-		if (tmp < dev->min_timeout || tmp > dev->max_timeout)
-			return -EINVAL;
-
-		if (dev->s_timeout)
-			ret = dev->s_timeout(dev, tmp);
-		if (!ret)
-			dev->timeout = tmp;
-		break;
-
-	case LIRC_SET_REC_TIMEOUT_REPORTS:
-		if (!dev->timeout)
-			return -ENOTTY;
-
-		lirc->send_timeout_reports = !!val;
-		break;
-
-	default:
-		return lirc_dev_fop_ioctl(filep, cmd, arg);
-	}
-
-	if (_IOC_DIR(cmd) & _IOC_READ)
-		ret = put_user(val, argp);
-
-	return ret;
-}
-
-static const struct file_operations lirc_fops = {
-	.owner		= THIS_MODULE,
-	.write		= ir_lirc_transmit_ir,
-	.unlocked_ioctl	= ir_lirc_ioctl,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl	= ir_lirc_ioctl,
-#endif
-	.read		= lirc_dev_fop_read,
-	.poll		= lirc_dev_fop_poll,
-	.open		= lirc_dev_fop_open,
-	.release	= lirc_dev_fop_close,
-	.llseek		= no_llseek,
-};
-
-static int ir_lirc_register(struct rc_dev *dev)
-{
-	struct lirc_dev *ldev;
-	int rc = -ENOMEM;
-	unsigned long features = 0;
-
-	ldev = lirc_allocate_device();
-	if (!ldev)
-		return rc;
-
-	if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
-		features |= LIRC_CAN_REC_MODE2;
-		if (dev->rx_resolution)
-			features |= LIRC_CAN_GET_REC_RESOLUTION;
-	}
-
-	if (dev->tx_ir) {
-		features |= LIRC_CAN_SEND_PULSE;
-		if (dev->s_tx_mask)
-			features |= LIRC_CAN_SET_TRANSMITTER_MASK;
-		if (dev->s_tx_carrier)
-			features |= LIRC_CAN_SET_SEND_CARRIER;
-		if (dev->s_tx_duty_cycle)
-			features |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
-	}
-
-	if (dev->s_rx_carrier_range)
-		features |= LIRC_CAN_SET_REC_CARRIER |
-			LIRC_CAN_SET_REC_CARRIER_RANGE;
-
-	if (dev->s_learning_mode)
-		features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
-
-	if (dev->s_carrier_report)
-		features |= LIRC_CAN_MEASURE_CARRIER;
-
-	if (dev->max_timeout)
-		features |= LIRC_CAN_SET_REC_TIMEOUT;
-
-	snprintf(ldev->name, sizeof(ldev->name), "ir-lirc-codec (%s)",
-		 dev->driver_name);
-	ldev->features = features;
-	ldev->data = &dev->raw->lirc;
-	ldev->buf = NULL;
-	ldev->code_length = sizeof(struct ir_raw_event) * 8;
-	ldev->chunk_size = sizeof(int);
-	ldev->buffer_size = LIRCBUF_SIZE;
-	ldev->fops = &lirc_fops;
-	ldev->dev.parent = &dev->dev;
-	ldev->rdev = dev;
-	ldev->owner = THIS_MODULE;
-
-	rc = lirc_register_device(ldev);
-	if (rc < 0)
-		goto out;
-
-	dev->raw->lirc.ldev = ldev;
-	dev->raw->lirc.dev = dev;
-	return 0;
-
-out:
-	lirc_free_device(ldev);
-	return rc;
-}
-
-static int ir_lirc_unregister(struct rc_dev *dev)
-{
-	struct lirc_codec *lirc = &dev->raw->lirc;
-
-	lirc_unregister_device(lirc->ldev);
-	lirc->ldev = NULL;
-
-	return 0;
-}
-
-static struct ir_raw_handler lirc_handler = {
-	.protocols	= 0,
-	.decode		= ir_lirc_decode,
-	.raw_register	= ir_lirc_register,
-	.raw_unregister	= ir_lirc_unregister,
-};
-
-static int __init ir_lirc_codec_init(void)
-{
-	ir_raw_handler_register(&lirc_handler);
-
-	printk(KERN_INFO "IR LIRC bridge handler initialized\n");
-	return 0;
-}
-
-static void __exit ir_lirc_codec_exit(void)
-{
-	ir_raw_handler_unregister(&lirc_handler);
-}
-
-module_init(ir_lirc_codec_init);
-module_exit(ir_lirc_codec_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
-MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
-MODULE_DESCRIPTION("LIRC IR handler bridge");
diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c
index 69d6264..2c3df02e 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -215,6 +215,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev)
 	struct mce_kbd_dec *data = &dev->raw->mce_kbd;
 	u32 scancode;
 	unsigned long delay;
+	struct lirc_scancode lsc = {};
 
 	if (!is_timing_event(ev)) {
 		if (ev.reset)
@@ -326,18 +327,22 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev)
 			mod_timer(&data->rx_timeout, jiffies + delay);
 			/* Pass data to keyboard buffer parser */
 			ir_mce_kbd_process_keyboard_data(data->idev, scancode);
+			lsc.rc_proto = RC_PROTO_MCIR2_KBD;
 			break;
 		case MCIR2_MOUSE_NBITS:
 			scancode = data->body & 0x1fffff;
 			IR_dprintk(1, "mouse data 0x%06x\n", scancode);
 			/* Pass data to mouse buffer parser */
 			ir_mce_kbd_process_mouse_data(data->idev, scancode);
+			lsc.rc_proto = RC_PROTO_MCIR2_MSE;
 			break;
 		default:
 			IR_dprintk(1, "not keyboard or mouse data\n");
 			goto out;
 		}
 
+		lsc.scancode = scancode;
+		ir_lirc_scancode_event(dev, &lsc);
 		data->state = STATE_INACTIVE;
 		input_event(data->idev, EV_MSC, MSC_SCAN, scancode);
 		input_sync(data->idev);
@@ -358,9 +363,6 @@ static int ir_mce_kbd_register(struct rc_dev *dev)
 	struct input_dev *idev;
 	int i, ret;
 
-	if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
-		return 0;
-
 	idev = input_allocate_device();
 	if (!idev)
 		return -ENOMEM;
@@ -415,9 +417,6 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev)
 	struct mce_kbd_dec *mce_kbd = &dev->raw->mce_kbd;
 	struct input_dev *idev = mce_kbd->idev;
 
-	if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
-		return 0;
-
 	del_timer_sync(&mce_kbd->rx_timeout);
 	input_unregister_device(idev);
 
@@ -425,7 +424,7 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev)
 }
 
 static const struct ir_raw_timings_manchester ir_mce_kbd_timings = {
-	.leader		= MCIR2_PREFIX_PULSE,
+	.leader_pulse	= MCIR2_PREFIX_PULSE,
 	.invert		= 1,
 	.clock		= MCIR2_UNIT,
 	.trailer_space	= MCIR2_UNIT * 10,
@@ -453,11 +452,11 @@ static int ir_mce_kbd_encode(enum rc_proto protocol, u32 scancode,
 	if (protocol == RC_PROTO_MCIR2_KBD) {
 		raw = scancode |
 		      ((u64)MCIR2_KEYBOARD_HEADER << MCIR2_KEYBOARD_NBITS);
-		len = MCIR2_KEYBOARD_NBITS + MCIR2_HEADER_NBITS + 1;
+		len = MCIR2_KEYBOARD_NBITS + MCIR2_HEADER_NBITS;
 	} else {
 		raw = scancode |
 		      ((u64)MCIR2_MOUSE_HEADER << MCIR2_MOUSE_NBITS);
-		len = MCIR2_MOUSE_NBITS + MCIR2_HEADER_NBITS + 1;
+		len = MCIR2_MOUSE_NBITS + MCIR2_HEADER_NBITS;
 	}
 
 	ret = ir_raw_gen_manchester(&e, max, &ir_mce_kbd_timings, len, raw);
@@ -473,6 +472,7 @@ static struct ir_raw_handler mce_kbd_handler = {
 	.encode		= ir_mce_kbd_encode,
 	.raw_register	= ir_mce_kbd_register,
 	.raw_unregister	= ir_mce_kbd_unregister,
+	.carrier	= 36000,
 };
 
 static int __init ir_mce_kbd_decode_init(void)
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 6880c19..31d7baf 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -1,16 +1,7 @@
-/* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
- *
- * Copyright (C) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0
+// ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
+//
+// Copyright (C) 2010 by Mauro Carvalho Chehab
 
 #include <linux/bitrev.h>
 #include <linux/module.h>
@@ -263,6 +254,7 @@ static struct ir_raw_handler nec_handler = {
 							RC_PROTO_BIT_NEC32,
 	.decode		= ir_nec_decode,
 	.encode		= ir_nec_encode,
+	.carrier	= 38000,
 };
 
 static int __init ir_nec_decode_init(void)
@@ -281,7 +273,7 @@ static void __exit ir_nec_decode_exit(void)
 module_init(ir_nec_decode_init);
 module_exit(ir_nec_decode_exit);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 MODULE_DESCRIPTION("NEC IR protocol decoder");
diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c
index 1292f53..11a28f8 100644
--- a/drivers/media/rc/ir-rc5-decoder.c
+++ b/drivers/media/rc/ir-rc5-decoder.c
@@ -1,17 +1,8 @@
-/* ir-rc5-decoder.c - decoder for RC5(x) and StreamZap protocols
- *
- * Copyright (C) 2010 by Mauro Carvalho Chehab
- * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0
+// ir-rc5-decoder.c - decoder for RC5(x) and StreamZap protocols
+//
+// Copyright (C) 2010 by Mauro Carvalho Chehab
+// Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
 
 /*
  * This decoder handles the 14 bit RC5 protocol, 15 bit "StreamZap" protocol
@@ -182,16 +173,14 @@ static int ir_rc5_decode(struct rc_dev *dev, struct ir_raw_event ev)
 }
 
 static const struct ir_raw_timings_manchester ir_rc5_timings = {
-	.leader			= RC5_UNIT,
-	.pulse_space_start	= 0,
+	.leader_pulse		= RC5_UNIT,
 	.clock			= RC5_UNIT,
 	.trailer_space		= RC5_UNIT * 10,
 };
 
 static const struct ir_raw_timings_manchester ir_rc5x_timings[2] = {
 	{
-		.leader			= RC5_UNIT,
-		.pulse_space_start	= 0,
+		.leader_pulse		= RC5_UNIT,
 		.clock			= RC5_UNIT,
 		.trailer_space		= RC5X_SPACE,
 	},
@@ -202,8 +191,7 @@ static const struct ir_raw_timings_manchester ir_rc5x_timings[2] = {
 };
 
 static const struct ir_raw_timings_manchester ir_rc5_sz_timings = {
-	.leader				= RC5_UNIT,
-	.pulse_space_start		= 0,
+	.leader_pulse			= RC5_UNIT,
 	.clock				= RC5_UNIT,
 	.trailer_space			= RC5_UNIT * 10,
 };
@@ -237,9 +225,9 @@ static int ir_rc5_encode(enum rc_proto protocol, u32 scancode,
 		/* encode data */
 		data = !commandx << 12 | system << 6 | command;
 
-		/* Modulate the data */
+		/* First bit is encoded by leader_pulse */
 		ret = ir_raw_gen_manchester(&e, max, &ir_rc5_timings,
-					    RC5_NBITS, data);
+					    RC5_NBITS - 1, data);
 		if (ret < 0)
 			return ret;
 	} else if (protocol == RC_PROTO_RC5X_20) {
@@ -252,10 +240,11 @@ static int ir_rc5_encode(enum rc_proto protocol, u32 scancode,
 		/* encode data */
 		data = commandx << 18 | system << 12 | command << 6 | xdata;
 
-		/* Modulate the data */
+		/* First bit is encoded by leader_pulse */
 		pre_space_data = data >> (RC5X_NBITS - CHECK_RC5X_NBITS);
 		ret = ir_raw_gen_manchester(&e, max, &ir_rc5x_timings[0],
-					    CHECK_RC5X_NBITS, pre_space_data);
+					    CHECK_RC5X_NBITS - 1,
+					    pre_space_data);
 		if (ret < 0)
 			return ret;
 		ret = ir_raw_gen_manchester(&e, max - (e - events),
@@ -266,8 +255,10 @@ static int ir_rc5_encode(enum rc_proto protocol, u32 scancode,
 			return ret;
 	} else if (protocol == RC_PROTO_RC5_SZ) {
 		/* RC5-SZ scancode is raw enough for Manchester as it is */
+		/* First bit is encoded by leader_pulse */
 		ret = ir_raw_gen_manchester(&e, max, &ir_rc5_sz_timings,
-					    RC5_SZ_NBITS, scancode & 0x2fff);
+					    RC5_SZ_NBITS - 1,
+					    scancode & 0x2fff);
 		if (ret < 0)
 			return ret;
 	} else {
@@ -282,6 +273,7 @@ static struct ir_raw_handler rc5_handler = {
 							RC_PROTO_BIT_RC5_SZ,
 	.decode		= ir_rc5_decode,
 	.encode		= ir_rc5_encode,
+	.carrier	= 36000,
 };
 
 static int __init ir_rc5_decode_init(void)
@@ -300,7 +292,7 @@ static void __exit ir_rc5_decode_exit(void)
 module_init(ir_rc5_decode_init);
 module_exit(ir_rc5_decode_exit);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Mauro Carvalho Chehab and Jarod Wilson");
 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 MODULE_DESCRIPTION("RC5(x/sz) IR protocol decoder");
diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c
index 5d0d2fe..55bb19b 100644
--- a/drivers/media/rc/ir-rc6-decoder.c
+++ b/drivers/media/rc/ir-rc6-decoder.c
@@ -288,13 +288,8 @@ static int ir_rc6_decode(struct rc_dev *dev, struct ir_raw_event ev)
 
 static const struct ir_raw_timings_manchester ir_rc6_timings[4] = {
 	{
-		.leader			= RC6_PREFIX_PULSE,
-		.pulse_space_start	= 0,
-		.clock			= RC6_UNIT,
-		.invert			= 1,
-		.trailer_space		= RC6_PREFIX_SPACE,
-	},
-	{
+		.leader_pulse		= RC6_PREFIX_PULSE,
+		.leader_space		= RC6_PREFIX_SPACE,
 		.clock			= RC6_UNIT,
 		.invert			= 1,
 	},
@@ -329,27 +324,22 @@ static int ir_rc6_encode(enum rc_proto protocol, u32 scancode,
 	struct ir_raw_event *e = events;
 
 	if (protocol == RC_PROTO_RC6_0) {
-		/* Modulate the preamble */
-		ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0);
-		if (ret < 0)
-			return ret;
-
 		/* Modulate the header (Start Bit & Mode-0) */
 		ret = ir_raw_gen_manchester(&e, max - (e - events),
-					    &ir_rc6_timings[1],
+					    &ir_rc6_timings[0],
 					    RC6_HEADER_NBITS, (1 << 3));
 		if (ret < 0)
 			return ret;
 
 		/* Modulate Trailer Bit */
 		ret = ir_raw_gen_manchester(&e, max - (e - events),
-					    &ir_rc6_timings[2], 1, 0);
+					    &ir_rc6_timings[1], 1, 0);
 		if (ret < 0)
 			return ret;
 
 		/* Modulate rest of the data */
 		ret = ir_raw_gen_manchester(&e, max - (e - events),
-					    &ir_rc6_timings[3], RC6_0_NBITS,
+					    &ir_rc6_timings[2], RC6_0_NBITS,
 					    scancode);
 		if (ret < 0)
 			return ret;
@@ -372,27 +362,22 @@ static int ir_rc6_encode(enum rc_proto protocol, u32 scancode,
 			return -EINVAL;
 		}
 
-		/* Modulate the preamble */
-		ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0);
-		if (ret < 0)
-			return ret;
-
 		/* Modulate the header (Start Bit & Header-version 6 */
 		ret = ir_raw_gen_manchester(&e, max - (e - events),
-					    &ir_rc6_timings[1],
+					    &ir_rc6_timings[0],
 					    RC6_HEADER_NBITS, (1 << 3 | 6));
 		if (ret < 0)
 			return ret;
 
 		/* Modulate Trailer Bit */
 		ret = ir_raw_gen_manchester(&e, max - (e - events),
-					    &ir_rc6_timings[2], 1, 0);
+					    &ir_rc6_timings[1], 1, 0);
 		if (ret < 0)
 			return ret;
 
 		/* Modulate rest of the data */
 		ret = ir_raw_gen_manchester(&e, max - (e - events),
-					    &ir_rc6_timings[3],
+					    &ir_rc6_timings[2],
 					    bits,
 					    scancode);
 		if (ret < 0)
@@ -408,6 +393,7 @@ static struct ir_raw_handler rc6_handler = {
 			  RC_PROTO_BIT_RC6_MCE,
 	.decode		= ir_rc6_decode,
 	.encode		= ir_rc6_encode,
+	.carrier	= 36000,
 };
 
 static int __init ir_rc6_decode_init(void)
diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c
index d94e07b..ded39cd 100644
--- a/drivers/media/rc/ir-sanyo-decoder.c
+++ b/drivers/media/rc/ir-sanyo-decoder.c
@@ -1,25 +1,16 @@
-/* ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol
- *
- * Copyright (C) 2011 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- * This protocol uses the NEC protocol timings. However, data is formatted as:
- *	13 bits Custom Code
- *	13 bits NOT(Custom Code)
- *	8 bits Key data
- *	8 bits NOT(Key data)
- *
- * According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
- * Information for this protocol is available at the Sanyo LC7461 datasheet.
- */
+// SPDX-License-Identifier: GPL-2.0
+// ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol
+//
+// Copyright (C) 2011 by Mauro Carvalho Chehab
+//
+// This protocol uses the NEC protocol timings. However, data is formatted as:
+//	13 bits Custom Code
+//	13 bits NOT(Custom Code)
+//	8 bits Key data
+//	8 bits NOT(Key data)
+//
+// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
+// Information for this protocol is available at the Sanyo LC7461 datasheet.
 
 #include <linux/module.h>
 #include <linux/bitrev.h>
@@ -218,6 +209,7 @@ static struct ir_raw_handler sanyo_handler = {
 	.protocols	= RC_PROTO_BIT_SANYO,
 	.decode		= ir_sanyo_decode,
 	.encode		= ir_sanyo_encode,
+	.carrier	= 38000,
 };
 
 static int __init ir_sanyo_decode_init(void)
@@ -236,7 +228,7 @@ static void __exit ir_sanyo_decode_exit(void)
 module_init(ir_sanyo_decode_init);
 module_exit(ir_sanyo_decode_exit);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Mauro Carvalho Chehab");
 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
 MODULE_DESCRIPTION("SANYO IR protocol decoder");
diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c
index 7140dd6..df29699 100644
--- a/drivers/media/rc/ir-sharp-decoder.c
+++ b/drivers/media/rc/ir-sharp-decoder.c
@@ -226,6 +226,7 @@ static struct ir_raw_handler sharp_handler = {
 	.protocols	= RC_PROTO_BIT_SHARP,
 	.decode		= ir_sharp_decode,
 	.encode		= ir_sharp_encode,
+	.carrier	= 38000,
 };
 
 static int __init ir_sharp_decode_init(void)
diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c
index a47ced7..e4bcff2 100644
--- a/drivers/media/rc/ir-sony-decoder.c
+++ b/drivers/media/rc/ir-sony-decoder.c
@@ -221,6 +221,7 @@ static struct ir_raw_handler sony_handler = {
 							RC_PROTO_BIT_SONY20,
 	.decode		= ir_sony_decode,
 	.encode		= ir_sony_encode,
+	.carrier	= 40000,
 };
 
 static int __init ir_sony_decode_init(void)
diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c
index 29ed063..a32a84a 100644
--- a/drivers/media/rc/ir-spi.c
+++ b/drivers/media/rc/ir-spi.c
@@ -1,13 +1,8 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * Author: Andi Shyti <andi.shyti@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * SPI driven IR LED device driver
- */
+// SPDX-License-Identifier: GPL-2.0
+// SPI driven IR LED device driver
+//
+// Copyright (c) 2016 Samsung Electronics Co., Ltd.
+// Copyright (c) Andi Shyti <andi.shyti@samsung.com>
 
 #include <linux/delay.h>
 #include <linux/fs.h>
diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
index 2d303c2..732687c 100644
--- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
+++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
@@ -1,14 +1,9 @@
-/* adstech-dvb-t-pci.h - Keytable for adstech_dvb_t_pci Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// adstech-dvb-t-pci.h - Keytable for adstech_dvb_t_pci Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-apac-viewcomp.c b/drivers/media/rc/keymaps/rc-apac-viewcomp.c
index 65bc895..af2e7fd 100644
--- a/drivers/media/rc/keymaps/rc-apac-viewcomp.c
+++ b/drivers/media/rc/keymaps/rc-apac-viewcomp.c
@@ -1,14 +1,9 @@
-/* apac-viewcomp.h - Keytable for apac_viewcomp Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// apac-viewcomp.h - Keytable for apac_viewcomp Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-asus-pc39.c b/drivers/media/rc/keymaps/rc-asus-pc39.c
index 530e1d1..13a935c 100644
--- a/drivers/media/rc/keymaps/rc-asus-pc39.c
+++ b/drivers/media/rc/keymaps/rc-asus-pc39.c
@@ -1,14 +1,9 @@
-/* asus-pc39.h - Keytable for asus_pc39 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// asus-pc39.h - Keytable for asus_pc39 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-asus-ps3-100.c b/drivers/media/rc/keymaps/rc-asus-ps3-100.c
index c91ba33..7f836fc 100644
--- a/drivers/media/rc/keymaps/rc-asus-ps3-100.c
+++ b/drivers/media/rc/keymaps/rc-asus-ps3-100.c
@@ -1,14 +1,9 @@
-/* asus-ps3-100.h - Keytable for asus_ps3_100 Remote Controller
- *
- * Copyright (c) 2012 by Mauro Carvalho Chehab
- *
- * Based on a previous patch from Remi Schwartz <remi.schwartz@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// asus-ps3-100.h - Keytable for asus_ps3_100 Remote Controller
+//
+// Copyright (c) 2012 by Mauro Carvalho Chehab
+//
+// Based on a previous patch from Remi Schwartz <remi.schwartz@gmail.com>
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
index 11b4bdd..b4b7932 100644
--- a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
+++ b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
@@ -1,14 +1,9 @@
-/* ati-tv-wonder-hd-600.h - Keytable for ati_tv_wonder_hd_600 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// ati-tv-wonder-hd-600.h - Keytable for ati_tv_wonder_hd_600 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avermedia-a16d.c b/drivers/media/rc/keymaps/rc-avermedia-a16d.c
index 510dc90..5549c04 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-a16d.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-a16d.c
@@ -1,14 +1,9 @@
-/* avermedia-a16d.h - Keytable for avermedia_a16d Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avermedia-a16d.h - Keytable for avermedia_a16d Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
index 4bbc1e6..74edcd8 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
@@ -1,14 +1,9 @@
-/* avermedia-cardbus.h - Keytable for avermedia_cardbus Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avermedia-cardbus.h - Keytable for avermedia_cardbus Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
index f6b8547..7961841 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
@@ -1,14 +1,9 @@
-/* avermedia-dvbt.h - Keytable for avermedia_dvbt Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avermedia-dvbt.h - Keytable for avermedia_dvbt Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
index 6d5a73b..f6977df 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
@@ -1,13 +1,8 @@
-/* avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- * Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
+// Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avermedia.c b/drivers/media/rc/keymaps/rc-avermedia.c
index 6503f11..631ff52 100644
--- a/drivers/media/rc/keymaps/rc-avermedia.c
+++ b/drivers/media/rc/keymaps/rc-avermedia.c
@@ -1,14 +1,9 @@
-/* avermedia.h - Keytable for avermedia Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avermedia.h - Keytable for avermedia Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avertv-303.c b/drivers/media/rc/keymaps/rc-avertv-303.c
index fbdd7ad..47ca8b7 100644
--- a/drivers/media/rc/keymaps/rc-avertv-303.c
+++ b/drivers/media/rc/keymaps/rc-avertv-303.c
@@ -1,14 +1,9 @@
-/* avertv-303.h - Keytable for avertv_303 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avertv-303.h - Keytable for avertv_303 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c
index d256743..e730579 100644
--- a/drivers/media/rc/keymaps/rc-behold-columbus.c
+++ b/drivers/media/rc/keymaps/rc-behold-columbus.c
@@ -1,14 +1,9 @@
-/* behold-columbus.h - Keytable for behold_columbus Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// behold-columbus.h - Keytable for behold_columbus Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
@@ -35,12 +30,12 @@ static struct rc_map_table behold_columbus[] = {
 
 	/*  0x01    0x02    0x03  0x0D    *
 	 *   1       2       3   Stereo   *
-	 *                        	  *
+	 *				  *
 	 *  0x04    0x05    0x06  0x19    *
 	 *   4       5       6   Snapshot *
-	 *                        	  *
+	 *				  *
 	 *  0x07    0x08    0x09  0x10    *
-	 *   7       8       9    Zoom 	  *
+	 *   7       8       9    Zoom	  *
 	 *                                */
 	{ 0x01, KEY_1 },
 	{ 0x02, KEY_2 },
diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c
index 93dc795..9b1b57e 100644
--- a/drivers/media/rc/keymaps/rc-behold.c
+++ b/drivers/media/rc/keymaps/rc-behold.c
@@ -1,14 +1,9 @@
-/* behold.h - Keytable for behold Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// behold.h - Keytable for behold Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c
index 81ea142..56f051a 100644
--- a/drivers/media/rc/keymaps/rc-budget-ci-old.c
+++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c
@@ -1,14 +1,9 @@
-/* budget-ci-old.h - Keytable for budget_ci_old Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// budget-ci-old.h - Keytable for budget_ci_old Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-cinergy-1400.c b/drivers/media/rc/keymaps/rc-cinergy-1400.c
index bcb96b3d..dacb13c 100644
--- a/drivers/media/rc/keymaps/rc-cinergy-1400.c
+++ b/drivers/media/rc/keymaps/rc-cinergy-1400.c
@@ -1,14 +1,9 @@
-/* cinergy-1400.h - Keytable for cinergy_1400 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// cinergy-1400.h - Keytable for cinergy_1400 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c
index fd56c40..6ab2e51b 100644
--- a/drivers/media/rc/keymaps/rc-cinergy.c
+++ b/drivers/media/rc/keymaps/rc-cinergy.c
@@ -1,14 +1,9 @@
-/* cinergy.h - Keytable for cinergy Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// cinergy.h - Keytable for cinergy Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c
index 1b4df10..4ee801a 100644
--- a/drivers/media/rc/keymaps/rc-dib0700-nec.c
+++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c
@@ -1,19 +1,14 @@
-/* rc-dvb0700-big.c - Keytable for devices in dvb0700
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * TODO: This table is a real mess, as it merges RC codes from several
- * devices into a big table. It also has both RC-5 and NEC codes inside.
- * It should be broken into small tables, and the protocols should properly
- * be identificated.
- *
- * The table were imported from dib0700_devices.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// rc-dvb0700-big.c - Keytable for devices in dvb0700
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
+//
+// TODO: This table is a real mess, as it merges RC codes from several
+// devices into a big table. It also has both RC-5 and NEC codes inside.
+// It should be broken into small tables, and the protocols should properly
+// be identificated.
+//
+// The table were imported from dib0700_devices.c.
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-dib0700-rc5.c b/drivers/media/rc/keymaps/rc-dib0700-rc5.c
index b0f8151..ef4085a 100644
--- a/drivers/media/rc/keymaps/rc-dib0700-rc5.c
+++ b/drivers/media/rc/keymaps/rc-dib0700-rc5.c
@@ -1,19 +1,14 @@
-/* rc-dvb0700-big.c - Keytable for devices in dvb0700
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * TODO: This table is a real mess, as it merges RC codes from several
- * devices into a big table. It also has both RC-5 and NEC codes inside.
- * It should be broken into small tables, and the protocols should properly
- * be identificated.
- *
- * The table were imported from dib0700_devices.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// rc-dvb0700-big.c - Keytable for devices in dvb0700
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
+//
+// TODO: This table is a real mess, as it merges RC codes from several
+// devices into a big table. It also has both RC-5 and NEC codes inside.
+// It should be broken into small tables, and the protocols should properly
+// be identificated.
+//
+// The table were imported from dib0700_devices.c.
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-dm1105-nec.c b/drivers/media/rc/keymaps/rc-dm1105-nec.c
index c353445..d853cd9 100644
--- a/drivers/media/rc/keymaps/rc-dm1105-nec.c
+++ b/drivers/media/rc/keymaps/rc-dm1105-nec.c
@@ -1,14 +1,9 @@
-/* dm1105-nec.h - Keytable for dm1105_nec Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// dm1105-nec.h - Keytable for dm1105_nec Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
index 5bafd5b..cdc1d8c 100644
--- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
@@ -1,14 +1,9 @@
-/* dntv-live-dvb-t.h - Keytable for dntv_live_dvb_t Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// dntv-live-dvb-t.h - Keytable for dntv_live_dvb_t Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
index 360167c..38e1d1b 100644
--- a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
@@ -1,14 +1,9 @@
-/* dntv-live-dvbt-pro.h - Keytable for dntv_live_dvbt_pro Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// dntv-live-dvbt-pro.h - Keytable for dntv_live_dvbt_pro Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-em-terratec.c b/drivers/media/rc/keymaps/rc-em-terratec.c
index 18e1a26..cbbba21 100644
--- a/drivers/media/rc/keymaps/rc-em-terratec.c
+++ b/drivers/media/rc/keymaps/rc-em-terratec.c
@@ -1,14 +1,9 @@
-/* em-terratec.h - Keytable for em_terratec Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// em-terratec.h - Keytable for em_terratec Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
index 72ffd5c..e4e78c1 100644
--- a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
@@ -1,14 +1,9 @@
-/* encore-enltv-fm53.h - Keytable for encore_enltv_fm53 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// encore-enltv-fm53.h - Keytable for encore_enltv_fm53 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c
index e0381e7..5b4e832 100644
--- a/drivers/media/rc/keymaps/rc-encore-enltv.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv.c
@@ -1,14 +1,9 @@
-/* encore-enltv.h - Keytable for encore_enltv Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// encore-enltv.h - Keytable for encore_enltv Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c
index e9b0bfb..c3d4437 100644
--- a/drivers/media/rc/keymaps/rc-encore-enltv2.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c
@@ -1,14 +1,9 @@
-/* encore-enltv2.h - Keytable for encore_enltv2 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// encore-enltv2.h - Keytable for encore_enltv2 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-evga-indtube.c b/drivers/media/rc/keymaps/rc-evga-indtube.c
index b77c5e9..f439844 100644
--- a/drivers/media/rc/keymaps/rc-evga-indtube.c
+++ b/drivers/media/rc/keymaps/rc-evga-indtube.c
@@ -1,14 +1,9 @@
-/* evga-indtube.h - Keytable for evga_indtube Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// evga-indtube.h - Keytable for evga_indtube Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-eztv.c b/drivers/media/rc/keymaps/rc-eztv.c
index 5013b3b..0e481d5 100644
--- a/drivers/media/rc/keymaps/rc-eztv.c
+++ b/drivers/media/rc/keymaps/rc-eztv.c
@@ -1,14 +1,9 @@
-/* eztv.h - Keytable for eztv Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// eztv.h - Keytable for eztv Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c
index 418b325..45940d7 100644
--- a/drivers/media/rc/keymaps/rc-flydvb.c
+++ b/drivers/media/rc/keymaps/rc-flydvb.c
@@ -1,14 +1,9 @@
-/* flydvb.h - Keytable for flydvb Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// flydvb.h - Keytable for flydvb Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-flyvideo.c b/drivers/media/rc/keymaps/rc-flyvideo.c
index 93fb87e..b2d4e4c 100644
--- a/drivers/media/rc/keymaps/rc-flyvideo.c
+++ b/drivers/media/rc/keymaps/rc-flyvideo.c
@@ -1,14 +1,9 @@
-/* flyvideo.h - Keytable for flyvideo Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// flyvideo.h - Keytable for flyvideo Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
index 9ed3f74..1c63fc7 100644
--- a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
+++ b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
@@ -1,14 +1,9 @@
-/* fusionhdtv-mce.h - Keytable for fusionhdtv_mce Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// fusionhdtv-mce.h - Keytable for fusionhdtv_mce Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c
index 3443b72..4a0a978 100644
--- a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c
+++ b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c
@@ -1,14 +1,9 @@
-/* gadmei-rm008z.h - Keytable for gadmei_rm008z Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// gadmei-rm008z.h - Keytable for gadmei_rm008z Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
index d140e8d..cc876a8 100644
--- a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
+++ b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
@@ -1,14 +1,9 @@
-/* genius-tvgo-a11mce.h - Keytable for genius_tvgo_a11mce Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// genius-tvgo-a11mce.h - Keytable for genius_tvgo_a11mce Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-gotview7135.c b/drivers/media/rc/keymaps/rc-gotview7135.c
index 51230fb..6b94bd3 100644
--- a/drivers/media/rc/keymaps/rc-gotview7135.c
+++ b/drivers/media/rc/keymaps/rc-gotview7135.c
@@ -1,14 +1,9 @@
-/* gotview7135.h - Keytable for gotview7135 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// gotview7135.h - Keytable for gotview7135 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c b/drivers/media/rc/keymaps/rc-hauppauge.c
index 890164b..582aa90 100644
--- a/drivers/media/rc/keymaps/rc-hauppauge.c
+++ b/drivers/media/rc/keymaps/rc-hauppauge.c
@@ -1,20 +1,15 @@
-/* rc-hauppauge.c - Keytable for Hauppauge Remote Controllers
- *
- * keymap imported from ir-keymaps.c
- *
- * This map currently contains the code for four different RCs:
- *	- New Hauppauge Gray;
- *	- Old Hauppauge Gray (with a golden screen for media keys);
- *	- Hauppauge Black;
- *	- DSR-0112 remote bundled with Haupauge MiniStick.
- *
- * Copyright (c) 2010-2011 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// rc-hauppauge.c - Keytable for Hauppauge Remote Controllers
+//
+// keymap imported from ir-keymaps.c
+//
+// This map currently contains the code for four different RCs:
+//	- New Hauppauge Gray;
+//	- Old Hauppauge Gray (with a golden screen for media keys);
+//	- Hauppauge Black;
+//	- DSR-0112 remote bundled with Haupauge MiniStick.
+//
+// Copyright (c) 2010-2011 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c
index 8cf87a1..6ced434 100644
--- a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c
+++ b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c
@@ -1,14 +1,9 @@
-/* iodata-bctv7e.h - Keytable for iodata_bctv7e Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// iodata-bctv7e.h - Keytable for iodata_bctv7e Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c
index e791f1e..f0f88df 100644
--- a/drivers/media/rc/keymaps/rc-kaiomy.c
+++ b/drivers/media/rc/keymaps/rc-kaiomy.c
@@ -1,14 +1,9 @@
-/* kaiomy.h - Keytable for kaiomy Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// kaiomy.h - Keytable for kaiomy Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c
index 71dce01..ed0e0586 100644
--- a/drivers/media/rc/keymaps/rc-kworld-315u.c
+++ b/drivers/media/rc/keymaps/rc-kworld-315u.c
@@ -1,14 +1,9 @@
-/* kworld-315u.h - Keytable for kworld_315u Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// kworld-315u.h - Keytable for kworld_315u Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
index e0322ed..453e0437 100644
--- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
@@ -1,14 +1,9 @@
-/* kworld-plus-tv-analog.h - Keytable for kworld_plus_tv_analog Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// kworld-plus-tv-analog.h - Keytable for kworld_plus_tv_analog Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-manli.c b/drivers/media/rc/keymaps/rc-manli.c
index da56690..29c9fea 100644
--- a/drivers/media/rc/keymaps/rc-manli.c
+++ b/drivers/media/rc/keymaps/rc-manli.c
@@ -1,14 +1,9 @@
-/* manli.h - Keytable for manli Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// manli.h - Keytable for manli Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
index dfa0ed1..78cf2c2 100644
--- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
@@ -1,14 +1,9 @@
-/* msi-tvanywhere-plus.h - Keytable for msi_tvanywhere_plus Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// msi-tvanywhere-plus.h - Keytable for msi_tvanywhere_plus Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c
index 2111816..359a57b 100644
--- a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c
+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c
@@ -1,14 +1,9 @@
-/* msi-tvanywhere.h - Keytable for msi_tvanywhere Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// msi-tvanywhere.h - Keytable for msi_tvanywhere Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c
index 109b6e1..17d7c1b 100644
--- a/drivers/media/rc/keymaps/rc-nebula.c
+++ b/drivers/media/rc/keymaps/rc-nebula.c
@@ -1,14 +1,9 @@
-/* nebula.h - Keytable for nebula Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// nebula.h - Keytable for nebula Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
index bb2d3a2..76beef4 100644
--- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
+++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
@@ -1,14 +1,9 @@
-/* nec-terratec-cinergy-xs.h - Keytable for nec_terratec_cinergy_xs Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// nec-terratec-cinergy-xs.h - Keytable for nec_terratec_cinergy_xs Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c
index cd25df3..3765705 100644
--- a/drivers/media/rc/keymaps/rc-norwood.c
+++ b/drivers/media/rc/keymaps/rc-norwood.c
@@ -1,14 +1,9 @@
-/* norwood.h - Keytable for norwood Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// norwood.h - Keytable for norwood Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-npgtech.c b/drivers/media/rc/keymaps/rc-npgtech.c
index 140bbc2..abaf7f6 100644
--- a/drivers/media/rc/keymaps/rc-npgtech.c
+++ b/drivers/media/rc/keymaps/rc-npgtech.c
@@ -1,14 +1,9 @@
-/* npgtech.h - Keytable for npgtech Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// npgtech.h - Keytable for npgtech Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c
index 52b4558..e3462c5 100644
--- a/drivers/media/rc/keymaps/rc-pctv-sedna.c
+++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c
@@ -1,14 +1,9 @@
-/* pctv-sedna.h - Keytable for pctv_sedna Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pctv-sedna.h - Keytable for pctv_sedna Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pinnacle-color.c b/drivers/media/rc/keymaps/rc-pinnacle-color.c
index 973c9c3..63c2851 100644
--- a/drivers/media/rc/keymaps/rc-pinnacle-color.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-color.c
@@ -1,14 +1,9 @@
-/* pinnacle-color.h - Keytable for pinnacle_color Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pinnacle-color.h - Keytable for pinnacle_color Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pinnacle-grey.c b/drivers/media/rc/keymaps/rc-pinnacle-grey.c
index 22e44b0..31794d4 100644
--- a/drivers/media/rc/keymaps/rc-pinnacle-grey.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-grey.c
@@ -1,14 +1,9 @@
-/* pinnacle-grey.h - Keytable for pinnacle_grey Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pinnacle-grey.h - Keytable for pinnacle_grey Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
index 186dcf8..876aeb6 100644
--- a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
@@ -1,14 +1,9 @@
-/* pinnacle-pctv-hd.h - Keytable for pinnacle_pctv_hd Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pinnacle-pctv-hd.h - Keytable for pinnacle_pctv_hd Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pixelview-002t.c b/drivers/media/rc/keymaps/rc-pixelview-002t.c
index b235ada..4ed85f6 100644
--- a/drivers/media/rc/keymaps/rc-pixelview-002t.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-002t.c
@@ -1,14 +1,9 @@
-/* rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
index 453d52d..6ded64b 100644
--- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
@@ -1,14 +1,9 @@
-/* rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c
index ef97095..791130f 100644
--- a/drivers/media/rc/keymaps/rc-pixelview-new.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-new.c
@@ -1,14 +1,9 @@
-/* pixelview-new.h - Keytable for pixelview_new Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pixelview-new.h - Keytable for pixelview_new Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c
index cfd8f80..9889197 100644
--- a/drivers/media/rc/keymaps/rc-pixelview.c
+++ b/drivers/media/rc/keymaps/rc-pixelview.c
@@ -1,14 +1,9 @@
-/* pixelview.h - Keytable for pixelview Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pixelview.h - Keytable for pixelview Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c
index b63f82b..4988e71 100644
--- a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c
+++ b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c
@@ -1,14 +1,9 @@
-/* powercolor-real-angel.h - Keytable for powercolor_real_angel Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// powercolor-real-angel.h - Keytable for powercolor_real_angel Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-proteus-2309.c b/drivers/media/rc/keymaps/rc-proteus-2309.c
index be34c51..d2c13d0 100644
--- a/drivers/media/rc/keymaps/rc-proteus-2309.c
+++ b/drivers/media/rc/keymaps/rc-proteus-2309.c
@@ -1,14 +1,9 @@
-/* proteus-2309.h - Keytable for proteus_2309 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// proteus-2309.h - Keytable for proteus_2309 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-purpletv.c b/drivers/media/rc/keymaps/rc-purpletv.c
index 84c40b9..c8011f4 100644
--- a/drivers/media/rc/keymaps/rc-purpletv.c
+++ b/drivers/media/rc/keymaps/rc-purpletv.c
@@ -1,14 +1,9 @@
-/* purpletv.h - Keytable for purpletv Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// purpletv.h - Keytable for purpletv Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c
index be190dd..5235ee8 100644
--- a/drivers/media/rc/keymaps/rc-pv951.c
+++ b/drivers/media/rc/keymaps/rc-pv951.c
@@ -1,14 +1,9 @@
-/* pv951.h - Keytable for pv951 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pv951.h - Keytable for pv951 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
index 957fa21..1cf7866 100644
--- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
+++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
@@ -1,14 +1,9 @@
-/* real-audio-220-32-keys.h - Keytable for real_audio_220_32_keys Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// real-audio-220-32-keys.h - Keytable for real_audio_220_32_keys Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c
index 05facc0..42766cb 100644
--- a/drivers/media/rc/keymaps/rc-tbs-nec.c
+++ b/drivers/media/rc/keymaps/rc-tbs-nec.c
@@ -1,14 +1,9 @@
-/* tbs-nec.h - Keytable for tbs_nec Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// tbs-nec.h - Keytable for tbs_nec Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
index 3d0f6f7..6cf53a56 100644
--- a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
+++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
@@ -1,14 +1,9 @@
-/* terratec-cinergy-xs.h - Keytable for terratec_cinergy_xs Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// terratec-cinergy-xs.h - Keytable for terratec_cinergy_xs Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-tevii-nec.c b/drivers/media/rc/keymaps/rc-tevii-nec.c
index 31f8a0f..58fcc72 100644
--- a/drivers/media/rc/keymaps/rc-tevii-nec.c
+++ b/drivers/media/rc/keymaps/rc-tevii-nec.c
@@ -1,14 +1,9 @@
-/* tevii-nec.h - Keytable for tevii_nec Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// tevii-nec.h - Keytable for tevii_nec Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c
index 374c230..52f239d 100644
--- a/drivers/media/rc/keymaps/rc-tt-1500.c
+++ b/drivers/media/rc/keymaps/rc-tt-1500.c
@@ -1,14 +1,9 @@
-/* tt-1500.h - Keytable for tt_1500 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// tt-1500.h - Keytable for tt_1500 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-videomate-s350.c b/drivers/media/rc/keymaps/rc-videomate-s350.c
index b4f1032..e4d4dff 100644
--- a/drivers/media/rc/keymaps/rc-videomate-s350.c
+++ b/drivers/media/rc/keymaps/rc-videomate-s350.c
@@ -1,14 +1,9 @@
-/* videomate-s350.h - Keytable for videomate_s350 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// videomate-s350.h - Keytable for videomate_s350 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
index c431fdf..7c48909 100644
--- a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
+++ b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
@@ -1,14 +1,9 @@
-/* videomate-tv-pvr.h - Keytable for videomate_tv_pvr Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// videomate-tv-pvr.h - Keytable for videomate_tv_pvr Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
index 5a437e6..e443192 100644
--- a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
+++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
@@ -1,14 +1,9 @@
-/* winfast-usbii-deluxe.h - Keytable for winfast_usbii_deluxe Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// winfast-usbii-deluxe.h - Keytable for winfast_usbii_deluxe Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
@@ -42,7 +37,7 @@ static struct rc_map_table winfast_usbii_deluxe[] = {
 	{ 0x60, KEY_CHANNELDOWN},	/* CHANNELDOWN */
 	{ 0x61, KEY_LAST},		/* LAST CHANNEL (RECALL) */
 
-	{ 0x72, KEY_VIDEO}, 		/* INPUT MODES (TV/FM) */
+	{ 0x72, KEY_VIDEO},		/* INPUT MODES (TV/FM) */
 
 	{ 0x70, KEY_POWER2},		/* TV ON/OFF */
 
diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c
index 53685d1..ee7f4c3 100644
--- a/drivers/media/rc/keymaps/rc-winfast.c
+++ b/drivers/media/rc/keymaps/rc-winfast.c
@@ -1,14 +1,9 @@
-/* winfast.h - Keytable for winfast Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// winfast.h - Keytable for winfast Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
 
 #include <media/rc-map.h>
 #include <linux/module.h>
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index aab5364..b3544988 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -18,466 +18,775 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/module.h>
-#include <linux/sched/signal.h>
-#include <linux/ioctl.h>
-#include <linux/poll.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
-#include <linux/cdev.h>
 #include <linux/idr.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
 
-#include <media/rc-core.h>
-#include <media/lirc.h>
-#include <media/lirc_dev.h>
+#include "rc-core-priv.h"
+#include <uapi/linux/lirc.h>
 
-#define LOGHEAD		"lirc_dev (%s[%d]): "
+#define LIRCBUF_SIZE	256
 
 static dev_t lirc_base_dev;
 
 /* Used to keep track of allocated lirc devices */
-#define LIRC_MAX_DEVICES 256
 static DEFINE_IDA(lirc_ida);
 
 /* Only used for sysfs but defined to void otherwise */
 static struct class *lirc_class;
 
-static void lirc_release_device(struct device *ld)
+/**
+ * ir_lirc_raw_event() - Send raw IR data to lirc to be relayed to userspace
+ *
+ * @dev:	the struct rc_dev descriptor of the device
+ * @ev:		the struct ir_raw_event descriptor of the pulse/space
+ */
+void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)
 {
-	struct lirc_dev *d = container_of(ld, struct lirc_dev, dev);
+	unsigned long flags;
+	struct lirc_fh *fh;
+	int sample;
 
-	put_device(d->dev.parent);
+	/* Packet start */
+	if (ev.reset) {
+		/*
+		 * Userspace expects a long space event before the start of
+		 * the signal to use as a sync.  This may be done with repeat
+		 * packets and normal samples.  But if a reset has been sent
+		 * then we assume that a long time has passed, so we send a
+		 * space with the maximum time value.
+		 */
+		sample = LIRC_SPACE(LIRC_VALUE_MASK);
+		IR_dprintk(2, "delivering reset sync space to lirc_dev\n");
 
-	if (d->buf_internal) {
-		lirc_buffer_free(d->buf);
-		kfree(d->buf);
-		d->buf = NULL;
+	/* Carrier reports */
+	} else if (ev.carrier_report) {
+		sample = LIRC_FREQUENCY(ev.carrier);
+		IR_dprintk(2, "carrier report (freq: %d)\n", sample);
+
+	/* Packet end */
+	} else if (ev.timeout) {
+		if (dev->gap)
+			return;
+
+		dev->gap_start = ktime_get();
+		dev->gap = true;
+		dev->gap_duration = ev.duration;
+
+		sample = LIRC_TIMEOUT(ev.duration / 1000);
+		IR_dprintk(2, "timeout report (duration: %d)\n", sample);
+
+	/* Normal sample */
+	} else {
+		if (dev->gap) {
+			dev->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
+							 dev->gap_start));
+
+			/* Convert to ms and cap by LIRC_VALUE_MASK */
+			do_div(dev->gap_duration, 1000);
+			dev->gap_duration = min_t(u64, dev->gap_duration,
+						  LIRC_VALUE_MASK);
+
+			spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+			list_for_each_entry(fh, &dev->lirc_fh, list)
+				kfifo_put(&fh->rawir,
+					  LIRC_SPACE(dev->gap_duration));
+			spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
+			dev->gap = false;
+		}
+
+		sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
+					LIRC_SPACE(ev.duration / 1000);
+		IR_dprintk(2, "delivering %uus %s to lirc_dev\n",
+			   TO_US(ev.duration), TO_STR(ev.pulse));
 	}
-	kfree(d);
-	module_put(THIS_MODULE);
+
+	spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+	list_for_each_entry(fh, &dev->lirc_fh, list) {
+		if (LIRC_IS_TIMEOUT(sample) && !fh->send_timeout_reports)
+			continue;
+		if (kfifo_put(&fh->rawir, sample))
+			wake_up_poll(&fh->wait_poll, POLLIN | POLLRDNORM);
+	}
+	spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
 }
 
-static int lirc_allocate_buffer(struct lirc_dev *d)
+/**
+ * ir_lirc_scancode_event() - Send scancode data to lirc to be relayed to
+ *		userspace. This can be called in atomic context.
+ * @dev:	the struct rc_dev descriptor of the device
+ * @lsc:	the struct lirc_scancode describing the decoded scancode
+ */
+void ir_lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc)
 {
-	int err;
+	unsigned long flags;
+	struct lirc_fh *fh;
 
-	if (d->buf) {
-		d->buf_internal = false;
-		return 0;
+	lsc->timestamp = ktime_get_ns();
+
+	spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+	list_for_each_entry(fh, &dev->lirc_fh, list) {
+		if (kfifo_put(&fh->scancodes, *lsc))
+			wake_up_poll(&fh->wait_poll, POLLIN | POLLRDNORM);
 	}
-
-	d->buf = kmalloc(sizeof(*d->buf), GFP_KERNEL);
-	if (!d->buf)
-		return -ENOMEM;
-
-	err = lirc_buffer_init(d->buf, d->chunk_size, d->buffer_size);
-	if (err) {
-		kfree(d->buf);
-		d->buf = NULL;
-		return err;
-	}
-
-	d->buf_internal = true;
-	return 0;
+	spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
 }
+EXPORT_SYMBOL_GPL(ir_lirc_scancode_event);
 
-struct lirc_dev *
-lirc_allocate_device(void)
+static int ir_lirc_open(struct inode *inode, struct file *file)
 {
-	struct lirc_dev *d;
-
-	d = kzalloc(sizeof(*d), GFP_KERNEL);
-	if (d) {
-		mutex_init(&d->mutex);
-		device_initialize(&d->dev);
-		d->dev.class = lirc_class;
-		d->dev.release = lirc_release_device;
-		__module_get(THIS_MODULE);
-	}
-
-	return d;
-}
-EXPORT_SYMBOL(lirc_allocate_device);
-
-void lirc_free_device(struct lirc_dev *d)
-{
-	if (!d)
-		return;
-
-	put_device(&d->dev);
-}
-EXPORT_SYMBOL(lirc_free_device);
-
-int lirc_register_device(struct lirc_dev *d)
-{
-	int minor;
-	int err;
-
-	if (!d) {
-		pr_err("driver pointer must be not NULL!\n");
-		return -EBADRQC;
-	}
-
-	if (!d->dev.parent) {
-		pr_err("dev parent pointer not filled in!\n");
-		return -EINVAL;
-	}
-
-	if (!d->fops) {
-		pr_err("fops pointer not filled in!\n");
-		return -EINVAL;
-	}
-
-	if (!d->buf && d->chunk_size < 1) {
-		pr_err("chunk_size must be set!\n");
-		return -EINVAL;
-	}
-
-	if (!d->buf && d->buffer_size < 1) {
-		pr_err("buffer_size must be set!\n");
-		return -EINVAL;
-	}
-
-	if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) {
-		dev_err(&d->dev, "code length must be less than %d bits\n",
-			BUFLEN * 8);
-		return -EBADRQC;
-	}
-
-	if (!d->buf && !(d->fops && d->fops->read &&
-			 d->fops->poll && d->fops->unlocked_ioctl)) {
-		dev_err(&d->dev, "undefined read, poll, ioctl\n");
-		return -EBADRQC;
-	}
-
-	/* some safety check 8-) */
-	d->name[sizeof(d->name) - 1] = '\0';
-
-	if (d->features == 0)
-		d->features = LIRC_CAN_REC_LIRCCODE;
-
-	if (LIRC_CAN_REC(d->features)) {
-		err = lirc_allocate_buffer(d);
-		if (err)
-			return err;
-	}
-
-	minor = ida_simple_get(&lirc_ida, 0, LIRC_MAX_DEVICES, GFP_KERNEL);
-	if (minor < 0)
-		return minor;
-
-	d->minor = minor;
-	d->dev.devt = MKDEV(MAJOR(lirc_base_dev), d->minor);
-	dev_set_name(&d->dev, "lirc%d", d->minor);
-
-	cdev_init(&d->cdev, d->fops);
-	d->cdev.owner = d->owner;
-	d->attached = true;
-
-	err = cdev_device_add(&d->cdev, &d->dev);
-	if (err) {
-		ida_simple_remove(&lirc_ida, minor);
-		return err;
-	}
-
-	get_device(d->dev.parent);
-
-	dev_info(&d->dev, "lirc_dev: driver %s registered at minor = %d\n",
-		 d->name, d->minor);
-
-	return 0;
-}
-EXPORT_SYMBOL(lirc_register_device);
-
-void lirc_unregister_device(struct lirc_dev *d)
-{
-	if (!d)
-		return;
-
-	dev_dbg(&d->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
-		d->name, d->minor);
-
-	mutex_lock(&d->mutex);
-
-	d->attached = false;
-	if (d->open) {
-		dev_dbg(&d->dev, LOGHEAD "releasing opened driver\n",
-			d->name, d->minor);
-		wake_up_interruptible(&d->buf->wait_poll);
-	}
-
-	mutex_unlock(&d->mutex);
-
-	cdev_device_del(&d->cdev, &d->dev);
-	ida_simple_remove(&lirc_ida, d->minor);
-	put_device(&d->dev);
-}
-EXPORT_SYMBOL(lirc_unregister_device);
-
-int lirc_dev_fop_open(struct inode *inode, struct file *file)
-{
-	struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
+	struct rc_dev *dev = container_of(inode->i_cdev, struct rc_dev,
+					  lirc_cdev);
+	struct lirc_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	unsigned long flags;
 	int retval;
 
-	dev_dbg(&d->dev, LOGHEAD "open called\n", d->name, d->minor);
+	if (!fh)
+		return -ENOMEM;
 
-	retval = mutex_lock_interruptible(&d->mutex);
-	if (retval)
-		return retval;
+	get_device(&dev->dev);
 
-	if (!d->attached) {
+	if (!dev->registered) {
 		retval = -ENODEV;
-		goto out;
+		goto out_fh;
 	}
 
-	if (d->open) {
-		retval = -EBUSY;
-		goto out;
+	if (dev->driver_type == RC_DRIVER_IR_RAW) {
+		if (kfifo_alloc(&fh->rawir, MAX_IR_EVENT_SIZE, GFP_KERNEL)) {
+			retval = -ENOMEM;
+			goto out_fh;
+		}
 	}
 
-	if (d->rdev) {
-		retval = rc_open(d->rdev);
-		if (retval)
-			goto out;
+	if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
+		if (kfifo_alloc(&fh->scancodes, 32, GFP_KERNEL)) {
+			retval = -ENOMEM;
+			goto out_rawir;
+		}
 	}
 
-	if (d->buf)
-		lirc_buffer_clear(d->buf);
+	fh->send_mode = LIRC_MODE_PULSE;
+	fh->rc = dev;
+	fh->send_timeout_reports = true;
 
-	d->open++;
+	if (dev->driver_type == RC_DRIVER_SCANCODE)
+		fh->rec_mode = LIRC_MODE_SCANCODE;
+	else
+		fh->rec_mode = LIRC_MODE_MODE2;
 
-	lirc_init_pdata(inode, file);
+	retval = rc_open(dev);
+	if (retval)
+		goto out_kfifo;
+
+	init_waitqueue_head(&fh->wait_poll);
+
+	file->private_data = fh;
+	spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+	list_add(&fh->list, &dev->lirc_fh);
+	spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
+
 	nonseekable_open(inode, file);
-	mutex_unlock(&d->mutex);
 
 	return 0;
+out_kfifo:
+	if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
+		kfifo_free(&fh->scancodes);
+out_rawir:
+	if (dev->driver_type == RC_DRIVER_IR_RAW)
+		kfifo_free(&fh->rawir);
+out_fh:
+	kfree(fh);
+	put_device(&dev->dev);
 
-out:
-	mutex_unlock(&d->mutex);
 	return retval;
 }
-EXPORT_SYMBOL(lirc_dev_fop_open);
 
-int lirc_dev_fop_close(struct inode *inode, struct file *file)
+static int ir_lirc_close(struct inode *inode, struct file *file)
 {
-	struct lirc_dev *d = file->private_data;
+	struct lirc_fh *fh = file->private_data;
+	struct rc_dev *dev = fh->rc;
+	unsigned long flags;
 
-	mutex_lock(&d->mutex);
+	spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+	list_del(&fh->list);
+	spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
 
-	rc_close(d->rdev);
-	d->open--;
+	if (dev->driver_type == RC_DRIVER_IR_RAW)
+		kfifo_free(&fh->rawir);
+	if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
+		kfifo_free(&fh->scancodes);
+	kfree(fh);
 
-	mutex_unlock(&d->mutex);
+	rc_close(dev);
+	put_device(&dev->dev);
 
 	return 0;
 }
-EXPORT_SYMBOL(lirc_dev_fop_close);
 
-__poll_t lirc_dev_fop_poll(struct file *file, poll_table *wait)
+static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
+				   size_t n, loff_t *ppos)
 {
-	struct lirc_dev *d = file->private_data;
-	__poll_t ret;
+	struct lirc_fh *fh = file->private_data;
+	struct rc_dev *dev = fh->rc;
+	unsigned int *txbuf;
+	struct ir_raw_event *raw = NULL;
+	ssize_t ret;
+	size_t count;
+	ktime_t start;
+	s64 towait;
+	unsigned int duration = 0; /* signal duration in us */
+	int i;
 
-	if (!d->attached)
-		return POLLHUP | POLLERR;
+	ret = mutex_lock_interruptible(&dev->lock);
+	if (ret)
+		return ret;
 
-	if (d->buf) {
-		poll_wait(file, &d->buf->wait_poll, wait);
-
-		if (lirc_buffer_empty(d->buf))
-			ret = 0;
-		else
-			ret = POLLIN | POLLRDNORM;
-	} else {
-		ret = POLLERR;
+	if (!dev->registered) {
+		ret = -ENODEV;
+		goto out_unlock;
 	}
 
-	dev_dbg(&d->dev, LOGHEAD "poll result = %d\n", d->name, d->minor, ret);
+	start = ktime_get();
 
+	if (!dev->tx_ir) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	if (fh->send_mode == LIRC_MODE_SCANCODE) {
+		struct lirc_scancode scan;
+
+		if (n != sizeof(scan)) {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+
+		if (copy_from_user(&scan, buf, sizeof(scan))) {
+			ret = -EFAULT;
+			goto out_unlock;
+		}
+
+		if (scan.flags || scan.keycode || scan.timestamp) {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+
+		/*
+		 * The scancode field in lirc_scancode is 64-bit simply
+		 * to future-proof it, since there are IR protocols encode
+		 * use more than 32 bits. For now only 32-bit protocols
+		 * are supported.
+		 */
+		if (scan.scancode > U32_MAX ||
+		    !rc_validate_scancode(scan.rc_proto, scan.scancode)) {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+
+		raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL);
+		if (!raw) {
+			ret = -ENOMEM;
+			goto out_unlock;
+		}
+
+		ret = ir_raw_encode_scancode(scan.rc_proto, scan.scancode,
+					     raw, LIRCBUF_SIZE);
+		if (ret < 0)
+			goto out_kfree_raw;
+
+		count = ret;
+
+		txbuf = kmalloc_array(count, sizeof(unsigned int), GFP_KERNEL);
+		if (!txbuf) {
+			ret = -ENOMEM;
+			goto out_kfree_raw;
+		}
+
+		for (i = 0; i < count; i++)
+			/* Convert from NS to US */
+			txbuf[i] = DIV_ROUND_UP(raw[i].duration, 1000);
+
+		if (dev->s_tx_carrier) {
+			int carrier = ir_raw_encode_carrier(scan.rc_proto);
+
+			if (carrier > 0)
+				dev->s_tx_carrier(dev, carrier);
+		}
+	} else {
+		if (n < sizeof(unsigned int) || n % sizeof(unsigned int)) {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+
+		count = n / sizeof(unsigned int);
+		if (count > LIRCBUF_SIZE || count % 2 == 0) {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+
+		txbuf = memdup_user(buf, n);
+		if (IS_ERR(txbuf)) {
+			ret = PTR_ERR(txbuf);
+			goto out_unlock;
+		}
+	}
+
+	for (i = 0; i < count; i++) {
+		if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) {
+			ret = -EINVAL;
+			goto out_kfree;
+		}
+
+		duration += txbuf[i];
+	}
+
+	ret = dev->tx_ir(dev, txbuf, count);
+	if (ret < 0)
+		goto out_kfree;
+
+	kfree(txbuf);
+	kfree(raw);
+	mutex_unlock(&dev->lock);
+
+	/*
+	 * The lircd gap calculation expects the write function to
+	 * wait for the actual IR signal to be transmitted before
+	 * returning.
+	 */
+	towait = ktime_us_delta(ktime_add_us(start, duration),
+				ktime_get());
+	if (towait > 0) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(usecs_to_jiffies(towait));
+	}
+
+	return n;
+out_kfree:
+	kfree(txbuf);
+out_kfree_raw:
+	kfree(raw);
+out_unlock:
+	mutex_unlock(&dev->lock);
 	return ret;
 }
-EXPORT_SYMBOL(lirc_dev_fop_poll);
 
-long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long ir_lirc_ioctl(struct file *file, unsigned int cmd,
+			  unsigned long arg)
 {
-	struct lirc_dev *d = file->private_data;
-	__u32 mode;
-	int result;
+	struct lirc_fh *fh = file->private_data;
+	struct rc_dev *dev = fh->rc;
+	u32 __user *argp = (u32 __user *)(arg);
+	u32 val = 0;
+	int ret;
 
-	dev_dbg(&d->dev, LOGHEAD "ioctl called (0x%x)\n",
-		d->name, d->minor, cmd);
+	if (_IOC_DIR(cmd) & _IOC_WRITE) {
+		ret = get_user(val, argp);
+		if (ret)
+			return ret;
+	}
 
-	result = mutex_lock_interruptible(&d->mutex);
-	if (result)
-		return result;
+	ret = mutex_lock_interruptible(&dev->lock);
+	if (ret)
+		return ret;
 
-	if (!d->attached) {
-		result = -ENODEV;
+	if (!dev->registered) {
+		ret = -ENODEV;
 		goto out;
 	}
 
 	switch (cmd) {
 	case LIRC_GET_FEATURES:
-		result = put_user(d->features, (__u32 __user *)arg);
+		if (dev->driver_type == RC_DRIVER_SCANCODE)
+			val |= LIRC_CAN_REC_SCANCODE;
+
+		if (dev->driver_type == RC_DRIVER_IR_RAW) {
+			val |= LIRC_CAN_REC_MODE2;
+			if (dev->rx_resolution)
+				val |= LIRC_CAN_GET_REC_RESOLUTION;
+		}
+
+		if (dev->tx_ir) {
+			val |= LIRC_CAN_SEND_PULSE;
+			if (dev->s_tx_mask)
+				val |= LIRC_CAN_SET_TRANSMITTER_MASK;
+			if (dev->s_tx_carrier)
+				val |= LIRC_CAN_SET_SEND_CARRIER;
+			if (dev->s_tx_duty_cycle)
+				val |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
+		}
+
+		if (dev->s_rx_carrier_range)
+			val |= LIRC_CAN_SET_REC_CARRIER |
+				LIRC_CAN_SET_REC_CARRIER_RANGE;
+
+		if (dev->s_learning_mode)
+			val |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
+
+		if (dev->s_carrier_report)
+			val |= LIRC_CAN_MEASURE_CARRIER;
+
+		if (dev->max_timeout)
+			val |= LIRC_CAN_SET_REC_TIMEOUT;
+
 		break;
+
+	/* mode support */
 	case LIRC_GET_REC_MODE:
-		if (!LIRC_CAN_REC(d->features)) {
-			result = -ENOTTY;
-			break;
-		}
-
-		result = put_user(LIRC_REC2MODE
-				  (d->features & LIRC_CAN_REC_MASK),
-				  (__u32 __user *)arg);
+		if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
+			ret = -ENOTTY;
+		else
+			val = fh->rec_mode;
 		break;
+
 	case LIRC_SET_REC_MODE:
-		if (!LIRC_CAN_REC(d->features)) {
-			result = -ENOTTY;
+		switch (dev->driver_type) {
+		case RC_DRIVER_IR_RAW_TX:
+			ret = -ENOTTY;
+			break;
+		case RC_DRIVER_SCANCODE:
+			if (val != LIRC_MODE_SCANCODE)
+				ret = -EINVAL;
+			break;
+		case RC_DRIVER_IR_RAW:
+			if (!(val == LIRC_MODE_MODE2 ||
+			      val == LIRC_MODE_SCANCODE))
+				ret = -EINVAL;
 			break;
 		}
 
-		result = get_user(mode, (__u32 __user *)arg);
-		if (!result && !(LIRC_MODE2REC(mode) & d->features))
-			result = -EINVAL;
-		/*
-		 * FIXME: We should actually set the mode somehow but
-		 * for now, lirc_serial doesn't support mode changing either
-		 */
+		if (!ret)
+			fh->rec_mode = val;
 		break;
-	case LIRC_GET_LENGTH:
-		result = put_user(d->code_length, (__u32 __user *)arg);
+
+	case LIRC_GET_SEND_MODE:
+		if (!dev->tx_ir)
+			ret = -ENOTTY;
+		else
+			val = fh->send_mode;
 		break;
+
+	case LIRC_SET_SEND_MODE:
+		if (!dev->tx_ir)
+			ret = -ENOTTY;
+		else if (!(val == LIRC_MODE_PULSE || val == LIRC_MODE_SCANCODE))
+			ret = -EINVAL;
+		else
+			fh->send_mode = val;
+		break;
+
+	/* TX settings */
+	case LIRC_SET_TRANSMITTER_MASK:
+		if (!dev->s_tx_mask)
+			ret = -ENOTTY;
+		else
+			ret = dev->s_tx_mask(dev, val);
+		break;
+
+	case LIRC_SET_SEND_CARRIER:
+		if (!dev->s_tx_carrier)
+			ret = -ENOTTY;
+		else
+			ret = dev->s_tx_carrier(dev, val);
+		break;
+
+	case LIRC_SET_SEND_DUTY_CYCLE:
+		if (!dev->s_tx_duty_cycle)
+			ret = -ENOTTY;
+		else if (val <= 0 || val >= 100)
+			ret = -EINVAL;
+		else
+			ret = dev->s_tx_duty_cycle(dev, val);
+		break;
+
+	/* RX settings */
+	case LIRC_SET_REC_CARRIER:
+		if (!dev->s_rx_carrier_range)
+			ret = -ENOTTY;
+		else if (val <= 0)
+			ret = -EINVAL;
+		else
+			ret = dev->s_rx_carrier_range(dev, fh->carrier_low,
+						      val);
+		break;
+
+	case LIRC_SET_REC_CARRIER_RANGE:
+		if (!dev->s_rx_carrier_range)
+			ret = -ENOTTY;
+		else if (val <= 0)
+			ret = -EINVAL;
+		else
+			fh->carrier_low = val;
+		break;
+
+	case LIRC_GET_REC_RESOLUTION:
+		if (!dev->rx_resolution)
+			ret = -ENOTTY;
+		else
+			val = dev->rx_resolution / 1000;
+		break;
+
+	case LIRC_SET_WIDEBAND_RECEIVER:
+		if (!dev->s_learning_mode)
+			ret = -ENOTTY;
+		else
+			ret = dev->s_learning_mode(dev, !!val);
+		break;
+
+	case LIRC_SET_MEASURE_CARRIER_MODE:
+		if (!dev->s_carrier_report)
+			ret = -ENOTTY;
+		else
+			ret = dev->s_carrier_report(dev, !!val);
+		break;
+
+	/* Generic timeout support */
+	case LIRC_GET_MIN_TIMEOUT:
+		if (!dev->max_timeout)
+			ret = -ENOTTY;
+		else
+			val = DIV_ROUND_UP(dev->min_timeout, 1000);
+		break;
+
+	case LIRC_GET_MAX_TIMEOUT:
+		if (!dev->max_timeout)
+			ret = -ENOTTY;
+		else
+			val = dev->max_timeout / 1000;
+		break;
+
+	case LIRC_SET_REC_TIMEOUT:
+		if (!dev->max_timeout) {
+			ret = -ENOTTY;
+		} else if (val > U32_MAX / 1000) {
+			/* Check for multiply overflow */
+			ret = -EINVAL;
+		} else {
+			u32 tmp = val * 1000;
+
+			if (tmp < dev->min_timeout || tmp > dev->max_timeout)
+				ret = -EINVAL;
+			else if (dev->s_timeout)
+				ret = dev->s_timeout(dev, tmp);
+			else if (!ret)
+				dev->timeout = tmp;
+		}
+		break;
+
+	case LIRC_SET_REC_TIMEOUT_REPORTS:
+		if (!dev->timeout)
+			ret = -ENOTTY;
+		else
+			fh->send_timeout_reports = !!val;
+		break;
+
 	default:
-		result = -ENOTTY;
+		ret = -ENOTTY;
 	}
 
+	if (!ret && _IOC_DIR(cmd) & _IOC_READ)
+		ret = put_user(val, argp);
+
 out:
-	mutex_unlock(&d->mutex);
-	return result;
+	mutex_unlock(&dev->lock);
+	return ret;
 }
-EXPORT_SYMBOL(lirc_dev_fop_ioctl);
 
-ssize_t lirc_dev_fop_read(struct file *file,
-			  char __user *buffer,
-			  size_t length,
-			  loff_t *ppos)
+static __poll_t ir_lirc_poll(struct file *file, struct poll_table_struct *wait)
 {
-	struct lirc_dev *d = file->private_data;
-	unsigned char *buf;
-	int ret, written = 0;
-	DECLARE_WAITQUEUE(wait, current);
+	struct lirc_fh *fh = file->private_data;
+	struct rc_dev *rcdev = fh->rc;
+	__poll_t events = 0;
 
-	buf = kzalloc(d->buf->chunk_size, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
+	poll_wait(file, &fh->wait_poll, wait);
 
-	dev_dbg(&d->dev, LOGHEAD "read called\n", d->name, d->minor);
+	if (!rcdev->registered) {
+		events = POLLHUP | POLLERR;
+	} else if (rcdev->driver_type != RC_DRIVER_IR_RAW_TX) {
+		if (fh->rec_mode == LIRC_MODE_SCANCODE &&
+		    !kfifo_is_empty(&fh->scancodes))
+			events = POLLIN | POLLRDNORM;
 
-	ret = mutex_lock_interruptible(&d->mutex);
-	if (ret) {
-		kfree(buf);
-		return ret;
+		if (fh->rec_mode == LIRC_MODE_MODE2 &&
+		    !kfifo_is_empty(&fh->rawir))
+			events = POLLIN | POLLRDNORM;
 	}
 
-	if (!d->attached) {
-		ret = -ENODEV;
-		goto out_locked;
-	}
+	return events;
+}
 
-	if (!LIRC_CAN_REC(d->features)) {
-		ret = -EINVAL;
-		goto out_locked;
-	}
+static ssize_t ir_lirc_read_mode2(struct file *file, char __user *buffer,
+				  size_t length)
+{
+	struct lirc_fh *fh = file->private_data;
+	struct rc_dev *rcdev = fh->rc;
+	unsigned int copied;
+	int ret;
 
-	if (length % d->buf->chunk_size) {
-		ret = -EINVAL;
-		goto out_locked;
-	}
+	if (length < sizeof(unsigned int) || length % sizeof(unsigned int))
+		return -EINVAL;
 
-	/*
-	 * we add ourselves to the task queue before buffer check
-	 * to avoid losing scan code (in case when queue is awaken somewhere
-	 * between while condition checking and scheduling)
-	 */
-	add_wait_queue(&d->buf->wait_poll, &wait);
+	do {
+		if (kfifo_is_empty(&fh->rawir)) {
+			if (file->f_flags & O_NONBLOCK)
+				return -EAGAIN;
 
-	/*
-	 * while we didn't provide 'length' bytes, device is opened in blocking
-	 * mode and 'copy_to_user' is happy, wait for data.
-	 */
-	while (written < length && ret == 0) {
-		if (lirc_buffer_empty(d->buf)) {
-			/* According to the read(2) man page, 'written' can be
-			 * returned as less than 'length', instead of blocking
-			 * again, returning -EWOULDBLOCK, or returning
-			 * -ERESTARTSYS
-			 */
-			if (written)
-				break;
-			if (file->f_flags & O_NONBLOCK) {
-				ret = -EWOULDBLOCK;
-				break;
-			}
-			if (signal_pending(current)) {
-				ret = -ERESTARTSYS;
-				break;
-			}
-
-			mutex_unlock(&d->mutex);
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule();
-			set_current_state(TASK_RUNNING);
-
-			ret = mutex_lock_interruptible(&d->mutex);
-			if (ret) {
-				remove_wait_queue(&d->buf->wait_poll, &wait);
-				goto out_unlocked;
-			}
-
-			if (!d->attached) {
-				ret = -ENODEV;
-				goto out_locked;
-			}
-		} else {
-			lirc_buffer_read(d->buf, buf);
-			ret = copy_to_user((void __user *)buffer+written, buf,
-					   d->buf->chunk_size);
-			if (!ret)
-				written += d->buf->chunk_size;
-			else
-				ret = -EFAULT;
+			ret = wait_event_interruptible(fh->wait_poll,
+					!kfifo_is_empty(&fh->rawir) ||
+					!rcdev->registered);
+			if (ret)
+				return ret;
 		}
-	}
 
-	remove_wait_queue(&d->buf->wait_poll, &wait);
+		if (!rcdev->registered)
+			return -ENODEV;
 
-out_locked:
-	mutex_unlock(&d->mutex);
+		ret = mutex_lock_interruptible(&rcdev->lock);
+		if (ret)
+			return ret;
+		ret = kfifo_to_user(&fh->rawir, buffer, length, &copied);
+		mutex_unlock(&rcdev->lock);
+		if (ret)
+			return ret;
+	} while (copied == 0);
 
-out_unlocked:
-	kfree(buf);
-
-	return ret ? ret : written;
+	return copied;
 }
-EXPORT_SYMBOL(lirc_dev_fop_read);
 
-void lirc_init_pdata(struct inode *inode, struct file *file)
+static ssize_t ir_lirc_read_scancode(struct file *file, char __user *buffer,
+				     size_t length)
 {
-	struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
+	struct lirc_fh *fh = file->private_data;
+	struct rc_dev *rcdev = fh->rc;
+	unsigned int copied;
+	int ret;
 
-	file->private_data = d;
+	if (length < sizeof(struct lirc_scancode) ||
+	    length % sizeof(struct lirc_scancode))
+		return -EINVAL;
+
+	do {
+		if (kfifo_is_empty(&fh->scancodes)) {
+			if (file->f_flags & O_NONBLOCK)
+				return -EAGAIN;
+
+			ret = wait_event_interruptible(fh->wait_poll,
+					!kfifo_is_empty(&fh->scancodes) ||
+					!rcdev->registered);
+			if (ret)
+				return ret;
+		}
+
+		if (!rcdev->registered)
+			return -ENODEV;
+
+		ret = mutex_lock_interruptible(&rcdev->lock);
+		if (ret)
+			return ret;
+		ret = kfifo_to_user(&fh->scancodes, buffer, length, &copied);
+		mutex_unlock(&rcdev->lock);
+		if (ret)
+			return ret;
+	} while (copied == 0);
+
+	return copied;
 }
-EXPORT_SYMBOL(lirc_init_pdata);
 
-void *lirc_get_pdata(struct file *file)
+static ssize_t ir_lirc_read(struct file *file, char __user *buffer,
+			    size_t length, loff_t *ppos)
 {
-	struct lirc_dev *d = file->private_data;
+	struct lirc_fh *fh = file->private_data;
+	struct rc_dev *rcdev = fh->rc;
 
-	return d->data;
+	if (rcdev->driver_type == RC_DRIVER_IR_RAW_TX)
+		return -EINVAL;
+
+	if (!rcdev->registered)
+		return -ENODEV;
+
+	if (fh->rec_mode == LIRC_MODE_MODE2)
+		return ir_lirc_read_mode2(file, buffer, length);
+	else /* LIRC_MODE_SCANCODE */
+		return ir_lirc_read_scancode(file, buffer, length);
 }
-EXPORT_SYMBOL(lirc_get_pdata);
 
+static const struct file_operations lirc_fops = {
+	.owner		= THIS_MODULE,
+	.write		= ir_lirc_transmit_ir,
+	.unlocked_ioctl	= ir_lirc_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= ir_lirc_ioctl,
+#endif
+	.read		= ir_lirc_read,
+	.poll		= ir_lirc_poll,
+	.open		= ir_lirc_open,
+	.release	= ir_lirc_close,
+	.llseek		= no_llseek,
+};
 
-static int __init lirc_dev_init(void)
+static void lirc_release_device(struct device *ld)
+{
+	struct rc_dev *rcdev = container_of(ld, struct rc_dev, lirc_dev);
+
+	put_device(&rcdev->dev);
+}
+
+int ir_lirc_register(struct rc_dev *dev)
+{
+	int err, minor;
+
+	minor = ida_simple_get(&lirc_ida, 0, RC_DEV_MAX, GFP_KERNEL);
+	if (minor < 0)
+		return minor;
+
+	device_initialize(&dev->lirc_dev);
+	dev->lirc_dev.class = lirc_class;
+	dev->lirc_dev.parent = &dev->dev;
+	dev->lirc_dev.release = lirc_release_device;
+	dev->lirc_dev.devt = MKDEV(MAJOR(lirc_base_dev), minor);
+	dev_set_name(&dev->lirc_dev, "lirc%d", minor);
+
+	INIT_LIST_HEAD(&dev->lirc_fh);
+	spin_lock_init(&dev->lirc_fh_lock);
+
+	cdev_init(&dev->lirc_cdev, &lirc_fops);
+
+	err = cdev_device_add(&dev->lirc_cdev, &dev->lirc_dev);
+	if (err)
+		goto out_ida;
+
+	get_device(&dev->dev);
+
+	dev_info(&dev->dev, "lirc_dev: driver %s registered at minor = %d",
+		 dev->driver_name, minor);
+
+	return 0;
+
+out_ida:
+	ida_simple_remove(&lirc_ida, minor);
+	return err;
+}
+
+void ir_lirc_unregister(struct rc_dev *dev)
+{
+	unsigned long flags;
+	struct lirc_fh *fh;
+
+	dev_dbg(&dev->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
+		dev->driver_name, MINOR(dev->lirc_dev.devt));
+
+	spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+	list_for_each_entry(fh, &dev->lirc_fh, list)
+		wake_up_poll(&fh->wait_poll, POLLHUP | POLLERR);
+	spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
+
+	cdev_device_del(&dev->lirc_cdev, &dev->lirc_dev);
+	ida_simple_remove(&lirc_ida, MINOR(dev->lirc_dev.devt));
+}
+
+int __init lirc_dev_init(void)
 {
 	int retval;
 
@@ -487,7 +796,7 @@ static int __init lirc_dev_init(void)
 		return PTR_ERR(lirc_class);
 	}
 
-	retval = alloc_chrdev_region(&lirc_base_dev, 0, LIRC_MAX_DEVICES,
+	retval = alloc_chrdev_region(&lirc_base_dev, 0, RC_DEV_MAX,
 				     "BaseRemoteCtl");
 	if (retval) {
 		class_destroy(lirc_class);
@@ -501,16 +810,10 @@ static int __init lirc_dev_init(void)
 	return 0;
 }
 
-static void __exit lirc_dev_exit(void)
+void __exit lirc_dev_exit(void)
 {
 	class_destroy(lirc_class);
-	unregister_chrdev_region(lirc_base_dev, LIRC_MAX_DEVICES);
-	pr_info("module unloaded\n");
+	unregister_chrdev_region(lirc_base_dev, RC_DEV_MAX);
 }
 
-module_init(lirc_dev_init);
-module_exit(lirc_dev_exit);
-
-MODULE_DESCRIPTION("LIRC base driver module");
-MODULE_AUTHOR("Artur Lipowski");
-MODULE_LICENSE("GPL");
+MODULE_ALIAS("lirc_dev");
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index ae4dd0c..458e9eb 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -1,27 +1,34 @@
 /*
+ * SPDX-License-Identifier: GPL-2.0
  * Remote Controller core raw events header
  *
  * Copyright (C) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
  */
 
 #ifndef _RC_CORE_PRIV
 #define _RC_CORE_PRIV
 
+#define	RC_DEV_MAX		256
 /* Define the max number of pulse/space transitions to buffer */
 #define	MAX_IR_EVENT_SIZE	512
 
 #include <linux/slab.h>
 #include <media/rc-core.h>
 
+/**
+ * rc_open - Opens a RC device
+ *
+ * @rdev: pointer to struct rc_dev.
+ */
+int rc_open(struct rc_dev *rdev);
+
+/**
+ * rc_close - Closes a RC device
+ *
+ * @rdev: pointer to struct rc_dev.
+ */
+void rc_close(struct rc_dev *rdev);
+
 struct ir_raw_handler {
 	struct list_head list;
 
@@ -29,8 +36,9 @@ struct ir_raw_handler {
 	int (*decode)(struct rc_dev *dev, struct ir_raw_event event);
 	int (*encode)(enum rc_proto protocol, u32 scancode,
 		      struct ir_raw_event *events, unsigned int max);
+	u32 carrier;
 
-	/* These two should only be used by the lirc decoder */
+	/* These two should only be used by the mce kbd decoder */
 	int (*raw_register)(struct rc_dev *dev);
 	int (*raw_unregister)(struct rc_dev *dev);
 };
@@ -104,17 +112,6 @@ struct ir_raw_event_ctrl {
 		unsigned count;
 		unsigned wanted_bits;
 	} mce_kbd;
-	struct lirc_codec {
-		struct rc_dev *dev;
-		struct lirc_dev *ldev;
-		int carrier_low;
-
-		ktime_t gap_start;
-		u64 gap_duration;
-		bool gap;
-		bool send_timeout_reports;
-
-	} lirc;
 	struct xmp_dec {
 		int state;
 		unsigned count;
@@ -156,6 +153,7 @@ static inline bool is_timing_event(struct ir_raw_event ev)
 #define TO_STR(is_pulse)		((is_pulse) ? "pulse" : "space")
 
 /* functions for IR encoders */
+bool rc_validate_scancode(enum rc_proto proto, u32 scancode);
 
 static inline void init_ir_raw_event_duration(struct ir_raw_event *ev,
 					      unsigned int pulse,
@@ -168,17 +166,17 @@ static inline void init_ir_raw_event_duration(struct ir_raw_event *ev,
 
 /**
  * struct ir_raw_timings_manchester - Manchester coding timings
- * @leader:		duration of leader pulse (if any) 0 if continuing
- *			existing signal (see @pulse_space_start)
- * @pulse_space_start:	1 for starting with pulse (0 for starting with space)
+ * @leader_pulse:	duration of leader pulse (if any) 0 if continuing
+ *			existing signal
+ * @leader_space:	duration of leader space (if any)
  * @clock:		duration of each pulse/space in ns
  * @invert:		if set clock logic is inverted
  *			(0 = space + pulse, 1 = pulse + space)
  * @trailer_space:	duration of trailer space in ns
  */
 struct ir_raw_timings_manchester {
-	unsigned int leader;
-	unsigned int pulse_space_start:1;
+	unsigned int leader_pulse;
+	unsigned int leader_space;
 	unsigned int clock;
 	unsigned int invert:1;
 	unsigned int trailer_space;
@@ -270,9 +268,31 @@ void ir_raw_event_free(struct rc_dev *dev);
 void ir_raw_event_unregister(struct rc_dev *dev);
 int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
 void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
+void ir_raw_load_modules(u64 *protocols);
 void ir_raw_init(void);
 
 /*
+ * lirc interface
+ */
+#ifdef CONFIG_LIRC
+int lirc_dev_init(void);
+void lirc_dev_exit(void);
+void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev);
+void ir_lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc);
+int ir_lirc_register(struct rc_dev *dev);
+void ir_lirc_unregister(struct rc_dev *dev);
+#else
+static inline int lirc_dev_init(void) { return 0; }
+static inline void lirc_dev_exit(void) {}
+static inline void ir_lirc_raw_event(struct rc_dev *dev,
+				     struct ir_raw_event ev) { }
+static inline void ir_lirc_scancode_event(struct rc_dev *dev,
+					  struct lirc_scancode *lsc) { }
+static inline int ir_lirc_register(struct rc_dev *dev) { return 0; }
+static inline void ir_lirc_unregister(struct rc_dev *dev) { }
+#endif
+
+/*
  * Decoder initialization code
  *
  * Those load logic are called during ir-core init, and automatically
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index d78483a..1850487 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -1,16 +1,7 @@
-/* rc-ir-raw.c - handle IR pulse/space events
- *
- * Copyright (C) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0
+// rc-ir-raw.c - handle IR pulse/space events
+//
+// Copyright (C) 2010 by Mauro Carvalho Chehab
 
 #include <linux/export.h>
 #include <linux/kthread.h>
@@ -40,6 +31,7 @@ static int ir_raw_event_thread(void *data)
 				if (raw->dev->enabled_protocols &
 				    handler->protocols || !handler->protocols)
 					handler->decode(raw->dev, ev);
+			ir_lirc_raw_event(raw->dev, ev);
 			raw->prev_ev = ev;
 		}
 		mutex_unlock(&ir_raw_handler_lock);
@@ -254,19 +246,16 @@ int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max,
 
 	i = BIT_ULL(n - 1);
 
-	if (timings->leader) {
+	if (timings->leader_pulse) {
 		if (!max--)
 			return ret;
-		if (timings->pulse_space_start) {
-			init_ir_raw_event_duration((*ev)++, 1, timings->leader);
-
+		init_ir_raw_event_duration((*ev), 1, timings->leader_pulse);
+		if (timings->leader_space) {
 			if (!max--)
 				return ret;
-			init_ir_raw_event_duration((*ev), 0, timings->leader);
-		} else {
-			init_ir_raw_event_duration((*ev), 1, timings->leader);
+			init_ir_raw_event_duration(++(*ev), 0,
+						   timings->leader_space);
 		}
-		i >>= 1;
 	} else {
 		/* continue existing signal */
 		--(*ev);
@@ -457,6 +446,8 @@ int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode,
 	int ret = -EINVAL;
 	u64 mask = 1ULL << protocol;
 
+	ir_raw_load_modules(&mask);
+
 	mutex_lock(&ir_raw_handler_lock);
 	list_for_each_entry(handler, &ir_raw_handler_list, list) {
 		if (handler->protocols & mask && handler->encode) {
@@ -493,21 +484,44 @@ static void edge_handle(struct timer_list *t)
 	ir_raw_event_handle(dev);
 }
 
+/**
+ * ir_raw_encode_carrier() - Get carrier used for protocol
+ *
+ * @protocol:		protocol
+ *
+ * Attempts to find the carrier for the specified protocol
+ *
+ * Returns:	The carrier in Hz
+ *		-EINVAL if the protocol is invalid, or if no
+ *		compatible encoder was found.
+ */
+int ir_raw_encode_carrier(enum rc_proto protocol)
+{
+	struct ir_raw_handler *handler;
+	int ret = -EINVAL;
+	u64 mask = BIT_ULL(protocol);
+
+	mutex_lock(&ir_raw_handler_lock);
+	list_for_each_entry(handler, &ir_raw_handler_list, list) {
+		if (handler->protocols & mask && handler->encode) {
+			ret = handler->carrier;
+			break;
+		}
+	}
+	mutex_unlock(&ir_raw_handler_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(ir_raw_encode_carrier);
+
 /*
  * Used to (un)register raw event clients
  */
 int ir_raw_event_prepare(struct rc_dev *dev)
 {
-	static bool raw_init; /* 'false' default value, raw decoders loaded? */
-
 	if (!dev)
 		return -EINVAL;
 
-	if (!raw_init) {
-		request_module("ir-lirc-codec");
-		raw_init = true;
-	}
-
 	dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL);
 	if (!dev->raw)
 		return -ENOMEM;
@@ -525,19 +539,11 @@ int ir_raw_event_register(struct rc_dev *dev)
 	struct ir_raw_handler *handler;
 	struct task_struct *thread;
 
-	/*
-	 * raw transmitters do not need any event registration
-	 * because the event is coming from userspace
-	 */
-	if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
-		thread = kthread_run(ir_raw_event_thread, dev->raw, "rc%u",
-				     dev->minor);
+	thread = kthread_run(ir_raw_event_thread, dev->raw, "rc%u", dev->minor);
+	if (IS_ERR(thread))
+		return PTR_ERR(thread);
 
-		if (IS_ERR(thread))
-			return PTR_ERR(thread);
-
-		dev->raw->thread = thread;
-	}
+	dev->raw->thread = thread;
 
 	mutex_lock(&ir_raw_handler_lock);
 	list_add_tail(&dev->raw->list, &ir_raw_client_list);
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index c144b77..1db8d38f 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1,16 +1,7 @@
-/* rc-main.c - Remote Controller core module
- *
- * Copyright (C) 2009-2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0
+// rc-main.c - Remote Controller core module
+//
+// Copyright (C) 2009-2010 by Mauro Carvalho Chehab
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -29,7 +20,6 @@
 /* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
 #define IR_TAB_MIN_SIZE	256
 #define IR_TAB_MAX_SIZE	8192
-#define RC_DEV_MAX	256
 
 static const struct {
 	const char *name;
@@ -607,6 +597,7 @@ static void ir_do_keyup(struct rc_dev *dev, bool sync)
 		return;
 
 	IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
+	del_timer(&dev->timer_repeat);
 	input_report_key(dev->input_dev, dev->last_keycode, 0);
 	led_trigger_event(led_feedback, LED_OFF);
 	if (sync)
@@ -661,6 +652,31 @@ static void ir_timer_keyup(struct timer_list *t)
 }
 
 /**
+ * ir_timer_repeat() - generates a repeat event after a timeout
+ *
+ * @t:		a pointer to the struct timer_list
+ *
+ * This routine will generate a soft repeat event every REP_PERIOD
+ * milliseconds.
+ */
+static void ir_timer_repeat(struct timer_list *t)
+{
+	struct rc_dev *dev = from_timer(dev, t, timer_repeat);
+	struct input_dev *input = dev->input_dev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->keylock, flags);
+	if (dev->keypressed) {
+		input_event(input, EV_KEY, dev->last_keycode, 2);
+		input_sync(input);
+		if (input->rep[REP_PERIOD])
+			mod_timer(&dev->timer_repeat, jiffies +
+				  msecs_to_jiffies(input->rep[REP_PERIOD]));
+	}
+	spin_unlock_irqrestore(&dev->keylock, flags);
+}
+
+/**
  * rc_repeat() - signals that a key is still pressed
  * @dev:	the struct rc_dev descriptor of the device
  *
@@ -672,19 +688,25 @@ void rc_repeat(struct rc_dev *dev)
 {
 	unsigned long flags;
 	unsigned int timeout = protocols[dev->last_protocol].repeat_period;
+	struct lirc_scancode sc = {
+		.scancode = dev->last_scancode, .rc_proto = dev->last_protocol,
+		.keycode = dev->keypressed ? dev->last_keycode : KEY_RESERVED,
+		.flags = LIRC_SCANCODE_FLAG_REPEAT |
+			 (dev->last_toggle ? LIRC_SCANCODE_FLAG_TOGGLE : 0)
+	};
+
+	ir_lirc_scancode_event(dev, &sc);
 
 	spin_lock_irqsave(&dev->keylock, flags);
 
-	if (!dev->keypressed)
-		goto out;
-
 	input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
 	input_sync(dev->input_dev);
 
-	dev->keyup_jiffies = jiffies + msecs_to_jiffies(timeout);
-	mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
+	if (dev->keypressed) {
+		dev->keyup_jiffies = jiffies + msecs_to_jiffies(timeout);
+		mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
+	}
 
-out:
 	spin_unlock_irqrestore(&dev->keylock, flags);
 }
 EXPORT_SYMBOL_GPL(rc_repeat);
@@ -707,19 +729,27 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
 			  dev->last_protocol != protocol ||
 			  dev->last_scancode != scancode ||
 			  dev->last_toggle   != toggle);
+	struct lirc_scancode sc = {
+		.scancode = scancode, .rc_proto = protocol,
+		.flags = toggle ? LIRC_SCANCODE_FLAG_TOGGLE : 0,
+		.keycode = keycode
+	};
+
+	ir_lirc_scancode_event(dev, &sc);
 
 	if (new_event && dev->keypressed)
 		ir_do_keyup(dev, false);
 
 	input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
 
+	dev->last_protocol = protocol;
+	dev->last_scancode = scancode;
+	dev->last_toggle = toggle;
+	dev->last_keycode = keycode;
+
 	if (new_event && keycode != KEY_RESERVED) {
 		/* Register a keypress */
 		dev->keypressed = true;
-		dev->last_protocol = protocol;
-		dev->last_scancode = scancode;
-		dev->last_toggle = toggle;
-		dev->last_keycode = keycode;
 
 		IR_dprintk(1, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n",
 			   dev->device_name, keycode, protocol, scancode);
@@ -728,6 +758,22 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
 		led_trigger_event(led_feedback, LED_FULL);
 	}
 
+	/*
+	 * For CEC, start sending repeat messages as soon as the first
+	 * repeated message is sent, as long as REP_DELAY = 0 and REP_PERIOD
+	 * is non-zero. Otherwise, the input layer will generate repeat
+	 * messages.
+	 */
+	if (!new_event && keycode != KEY_RESERVED &&
+	    dev->allowed_protocols == RC_PROTO_BIT_CEC &&
+	    !timer_pending(&dev->timer_repeat) &&
+	    dev->input_dev->rep[REP_PERIOD] &&
+	    !dev->input_dev->rep[REP_DELAY]) {
+		input_event(dev->input_dev, EV_KEY, keycode, 2);
+		mod_timer(&dev->timer_repeat, jiffies +
+			  msecs_to_jiffies(dev->input_dev->rep[REP_PERIOD]));
+	}
+
 	input_sync(dev->input_dev);
 }
 
@@ -785,6 +831,51 @@ void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
 EXPORT_SYMBOL_GPL(rc_keydown_notimeout);
 
 /**
+ * rc_validate_scancode() - checks that a scancode is valid for a protocol.
+ *	For nec, it should do the opposite of ir_nec_bytes_to_scancode()
+ * @proto:	protocol
+ * @scancode:	scancode
+ */
+bool rc_validate_scancode(enum rc_proto proto, u32 scancode)
+{
+	switch (proto) {
+	/*
+	 * NECX has a 16-bit address; if the lower 8 bits match the upper
+	 * 8 bits inverted, then the address would match regular nec.
+	 */
+	case RC_PROTO_NECX:
+		if ((((scancode >> 16) ^ ~(scancode >> 8)) & 0xff) == 0)
+			return false;
+		break;
+	/*
+	 * NEC32 has a 16 bit address and 16 bit command. If the lower 8 bits
+	 * of the command match the upper 8 bits inverted, then it would
+	 * be either NEC or NECX.
+	 */
+	case RC_PROTO_NEC32:
+		if ((((scancode >> 8) ^ ~scancode) & 0xff) == 0)
+			return false;
+		break;
+	/*
+	 * If the customer code (top 32-bit) is 0x800f, it is MCE else it
+	 * is regular mode-6a 32 bit
+	 */
+	case RC_PROTO_RC6_MCE:
+		if ((scancode & 0xffff0000) != 0x800f0000)
+			return false;
+		break;
+	case RC_PROTO_RC6_6A_32:
+		if ((scancode & 0xffff0000) == 0x800f0000)
+			return false;
+		break;
+	default:
+		break;
+	}
+
+	return true;
+}
+
+/**
  * rc_validate_filter() - checks that the scancode and mask are valid and
  *			  provides sensible defaults
  * @dev:	the struct rc_dev descriptor of the device
@@ -803,26 +894,8 @@ static int rc_validate_filter(struct rc_dev *dev,
 
 	mask = protocols[protocol].scancode_bits;
 
-	switch (protocol) {
-	case RC_PROTO_NECX:
-		if ((((s >> 16) ^ ~(s >> 8)) & 0xff) == 0)
-			return -EINVAL;
-		break;
-	case RC_PROTO_NEC32:
-		if ((((s >> 24) ^ ~(s >> 16)) & 0xff) == 0)
-			return -EINVAL;
-		break;
-	case RC_PROTO_RC6_MCE:
-		if ((s & 0xffff0000) != 0x800f0000)
-			return -EINVAL;
-		break;
-	case RC_PROTO_RC6_6A_32:
-		if ((s & 0xffff0000) == 0x800f0000)
-			return -EINVAL;
-		break;
-	default:
-		break;
-	}
+	if (!rc_validate_scancode(protocol, s))
+		return -EINVAL;
 
 	filter->data &= mask;
 	filter->mask &= mask;
@@ -845,17 +918,20 @@ int rc_open(struct rc_dev *rdev)
 
 	mutex_lock(&rdev->lock);
 
-	if (!rdev->users++ && rdev->open != NULL)
-		rval = rdev->open(rdev);
+	if (!rdev->registered) {
+		rval = -ENODEV;
+	} else {
+		if (!rdev->users++ && rdev->open)
+			rval = rdev->open(rdev);
 
-	if (rval)
-		rdev->users--;
+		if (rval)
+			rdev->users--;
+	}
 
 	mutex_unlock(&rdev->lock);
 
 	return rval;
 }
-EXPORT_SYMBOL_GPL(rc_open);
 
 static int ir_open(struct input_dev *idev)
 {
@@ -869,13 +945,12 @@ void rc_close(struct rc_dev *rdev)
 	if (rdev) {
 		mutex_lock(&rdev->lock);
 
-		if (!--rdev->users && rdev->close != NULL)
+		if (!--rdev->users && rdev->close && rdev->registered)
 			rdev->close(rdev);
 
 		mutex_unlock(&rdev->lock);
 	}
 }
-EXPORT_SYMBOL_GPL(rc_close);
 
 static void ir_close(struct input_dev *idev)
 {
@@ -950,23 +1025,6 @@ struct rc_filter_attribute {
 		.mask = (_mask),					\
 	}
 
-static bool lirc_is_present(void)
-{
-#if defined(CONFIG_LIRC_MODULE)
-	struct module *lirc;
-
-	mutex_lock(&module_mutex);
-	lirc = find_module("lirc_dev");
-	mutex_unlock(&module_mutex);
-
-	return lirc ? true : false;
-#elif defined(CONFIG_LIRC)
-	return true;
-#else
-	return false;
-#endif
-}
-
 /**
  * show_protocols() - shows the current IR protocol(s)
  * @device:	the device descriptor
@@ -1011,8 +1069,10 @@ static ssize_t show_protocols(struct device *device,
 			allowed &= ~proto_names[i].type;
 	}
 
-	if (dev->driver_type == RC_DRIVER_IR_RAW && lirc_is_present())
+#ifdef CONFIG_LIRC
+	if (dev->driver_type == RC_DRIVER_IR_RAW)
 		tmp += sprintf(tmp, "[lirc] ");
+#endif
 
 	if (tmp != buf)
 		tmp--;
@@ -1091,7 +1151,7 @@ static int parse_protocol_change(u64 *protocols, const char *buf)
 	return count;
 }
 
-static void ir_raw_load_modules(u64 *protocols)
+void ir_raw_load_modules(u64 *protocols)
 {
 	u64 available;
 	int i, ret;
@@ -1581,6 +1641,7 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type)
 		input_set_drvdata(dev->input_dev, dev);
 
 		timer_setup(&dev->timer_keyup, ir_timer_keyup, 0);
+		timer_setup(&dev->timer_repeat, ir_timer_repeat, 0);
 
 		spin_lock_init(&dev->rc_map.lock);
 		spin_lock_init(&dev->keylock);
@@ -1714,7 +1775,10 @@ static int rc_setup_rx_device(struct rc_dev *dev)
 	 * to avoid wrong repetition of the keycodes. Note that this must be
 	 * set after the call to input_register_device().
 	 */
-	dev->input_dev->rep[REP_DELAY] = 500;
+	if (dev->allowed_protocols == RC_PROTO_BIT_CEC)
+		dev->input_dev->rep[REP_DELAY] = 0;
+	else
+		dev->input_dev->rep[REP_DELAY] = 500;
 
 	/*
 	 * As a repeat event on protocols like RC-5 and NEC take as long as
@@ -1768,8 +1832,7 @@ int rc_register_device(struct rc_dev *dev)
 		dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp;
 	dev->sysfs_groups[attr++] = NULL;
 
-	if (dev->driver_type == RC_DRIVER_IR_RAW ||
-	    dev->driver_type == RC_DRIVER_IR_RAW_TX) {
+	if (dev->driver_type == RC_DRIVER_IR_RAW) {
 		rc = ir_raw_event_prepare(dev);
 		if (rc < 0)
 			goto out_minor;
@@ -1796,19 +1859,30 @@ int rc_register_device(struct rc_dev *dev)
 			goto out_dev;
 	}
 
-	if (dev->driver_type == RC_DRIVER_IR_RAW ||
-	    dev->driver_type == RC_DRIVER_IR_RAW_TX) {
-		rc = ir_raw_event_register(dev);
+	/* Ensure that the lirc kfifo is setup before we start the thread */
+	if (dev->allowed_protocols != RC_PROTO_BIT_CEC) {
+		rc = ir_lirc_register(dev);
 		if (rc < 0)
 			goto out_rx;
 	}
 
+	if (dev->driver_type == RC_DRIVER_IR_RAW) {
+		rc = ir_raw_event_register(dev);
+		if (rc < 0)
+			goto out_lirc;
+	}
+
+	dev->registered = true;
+
 	IR_dprintk(1, "Registered rc%u (driver: %s)\n",
 		   dev->minor,
 		   dev->driver_name ? dev->driver_name : "unknown");
 
 	return 0;
 
+out_lirc:
+	if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
+		ir_lirc_unregister(dev);
 out_rx:
 	rc_free_rx_device(dev);
 out_dev:
@@ -1856,12 +1930,24 @@ void rc_unregister_device(struct rc_dev *dev)
 		return;
 
 	del_timer_sync(&dev->timer_keyup);
+	del_timer_sync(&dev->timer_repeat);
 
 	if (dev->driver_type == RC_DRIVER_IR_RAW)
 		ir_raw_event_unregister(dev);
 
 	rc_free_rx_device(dev);
 
+	mutex_lock(&dev->lock);
+	dev->registered = false;
+	mutex_unlock(&dev->lock);
+
+	/*
+	 * lirc device should be freed with dev->registered = false, so
+	 * that userspace polling will get notified.
+	 */
+	if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
+		ir_lirc_unregister(dev);
+
 	device_del(&dev->dev);
 
 	ida_simple_remove(&rc_ida, dev->minor);
@@ -1884,6 +1970,13 @@ static int __init rc_core_init(void)
 		return rc;
 	}
 
+	rc = lirc_dev_init();
+	if (rc) {
+		pr_err("rc_core: unable to init lirc\n");
+		class_unregister(&rc_class);
+		return 0;
+	}
+
 	led_trigger_register_simple("rc-feedback", &led_feedback);
 	rc_map_register(&empty_map);
 
@@ -1892,6 +1985,7 @@ static int __init rc_core_init(void)
 
 static void __exit rc_core_exit(void)
 {
+	lirc_dev_exit();
 	class_unregister(&rc_class);
 	led_trigger_unregister_simple(led_feedback);
 	rc_map_unregister(&empty_map);
@@ -1905,4 +1999,4 @@ EXPORT_SYMBOL_GPL(rc_core_debug);
 module_param_named(debug, rc_core_debug, int, 0644);
 
 MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 3ca7ab4..0adf099 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -1044,7 +1044,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
 	data->irq = pnp_irq(device, 0);
 
 	if (data->wbase == 0 || data->ebase == 0 ||
-	    data->sbase == 0 || data->irq == 0) {
+	    data->sbase == 0 || data->irq == -1) {
 		err = -ENODEV;
 		dev_err(dev, "Invalid resources\n");
 		goto exit_free_data;
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
index 05998f0..6687514 100644
--- a/drivers/media/tuners/Kconfig
+++ b/drivers/media/tuners/Kconfig
@@ -26,6 +26,13 @@
 	help
 	  Say Y here to include support for various simple tuners.
 
+config MEDIA_TUNER_TDA18250
+	tristate "NXP TDA18250 silicon tuner"
+	depends on MEDIA_SUPPORT && I2C
+	default m if !MEDIA_SUBDRV_AUTOSELECT
+	help
+	  Say Y here to include support for TDA18250 tuner.
+
 config MEDIA_TUNER_TDA8290
 	tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
 	depends on MEDIA_SUPPORT && I2C
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile
index 7be9651..0ff21f1 100644
--- a/drivers/media/tuners/Makefile
+++ b/drivers/media/tuners/Makefile
@@ -42,6 +42,6 @@
 obj-$(CONFIG_MEDIA_TUNER_MXL301RF) += mxl301rf.o
 obj-$(CONFIG_MEDIA_TUNER_QM1D1C0042) += qm1d1c0042.o
 obj-$(CONFIG_MEDIA_TUNER_M88RS6000T) += m88rs6000t.o
+obj-$(CONFIG_MEDIA_TUNER_TDA18250) += tda18250.o
 
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/tuners/e4000.h b/drivers/media/tuners/e4000.h
index aa9340c..9a65208 100644
--- a/drivers/media/tuners/e4000.h
+++ b/drivers/media/tuners/e4000.h
@@ -21,7 +21,7 @@
 #ifndef E4000_H
 #define E4000_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /*
  * I2C address
diff --git a/drivers/media/tuners/fc0011.h b/drivers/media/tuners/fc0011.h
index a36871c..ebae37c 100644
--- a/drivers/media/tuners/fc0011.h
+++ b/drivers/media/tuners/fc0011.h
@@ -2,7 +2,7 @@
 #ifndef LINUX_FC0011_H_
 #define LINUX_FC0011_H_
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 
 /** struct fc0011_config - fc0011 hardware config
diff --git a/drivers/media/tuners/fc0012.h b/drivers/media/tuners/fc0012.h
index 64d07a2..29e84c4 100644
--- a/drivers/media/tuners/fc0012.h
+++ b/drivers/media/tuners/fc0012.h
@@ -17,7 +17,7 @@
 #ifndef _FC0012_H_
 #define _FC0012_H_
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "fc001x-common.h"
 
 struct fc0012_config {
diff --git a/drivers/media/tuners/fc0013.h b/drivers/media/tuners/fc0013.h
index 4431e7c..2d03925 100644
--- a/drivers/media/tuners/fc0013.h
+++ b/drivers/media/tuners/fc0013.h
@@ -18,7 +18,7 @@
 #ifndef _FC0013_H_
 #define _FC0013_H_
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "fc001x-common.h"
 
 #if IS_REACHABLE(CONFIG_MEDIA_TUNER_FC0013)
diff --git a/drivers/media/tuners/fc2580.h b/drivers/media/tuners/fc2580.h
index 862ea46..a04fba6 100644
--- a/drivers/media/tuners/fc2580.h
+++ b/drivers/media/tuners/fc2580.h
@@ -21,7 +21,7 @@
 #ifndef FC2580_H
 #define FC2580_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include <media/v4l2-subdev.h>
 #include <linux/i2c.h>
 
diff --git a/drivers/media/tuners/it913x.h b/drivers/media/tuners/it913x.h
index 226f657..3cb219a 100644
--- a/drivers/media/tuners/it913x.h
+++ b/drivers/media/tuners/it913x.h
@@ -19,7 +19,7 @@
 #ifndef IT913X_H
 #define IT913X_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /**
  * struct it913x_platform_data - Platform data for the it913x driver
diff --git a/drivers/media/tuners/m88rs6000t.h b/drivers/media/tuners/m88rs6000t.h
index 264c13e..318b48c 100644
--- a/drivers/media/tuners/m88rs6000t.h
+++ b/drivers/media/tuners/m88rs6000t.h
@@ -17,7 +17,7 @@
 #ifndef _M88RS6000T_H_
 #define _M88RS6000T_H_
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct m88rs6000t_config {
 	/*
diff --git a/drivers/media/tuners/max2165.c b/drivers/media/tuners/max2165.c
index a86c081..20ceb72 100644
--- a/drivers/media/tuners/max2165.c
+++ b/drivers/media/tuners/max2165.c
@@ -23,7 +23,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "max2165.h"
 #include "max2165_priv.h"
diff --git a/drivers/media/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c
index 12f545e..403c6b2 100644
--- a/drivers/media/tuners/mc44s803.c
+++ b/drivers/media/tuners/mc44s803.c
@@ -21,7 +21,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "mc44s803.h"
 #include "mc44s803_priv.h"
diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c
index 4983eeb..3d3c681 100644
--- a/drivers/media/tuners/mt2060.c
+++ b/drivers/media/tuners/mt2060.c
@@ -23,7 +23,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "mt2060.h"
 #include "mt2060_priv.h"
diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c
index 5c87c5c..80dc3e2 100644
--- a/drivers/media/tuners/mt2063.c
+++ b/drivers/media/tuners/mt2063.c
@@ -1168,7 +1168,7 @@ static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
 
 /*
  * MT2063_SetReceiverMode() - Set the MT2063 receiver mode, according with
- * 			      the selected enum mt2063_delivery_sys type.
+ *			      the selected enum mt2063_delivery_sys type.
  *
  *  (DNC1GC & DNC2GC are the values, which are used, when the specific
  *   DNC Output is selected, the other is always off)
@@ -1544,7 +1544,7 @@ static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
 	 * Save original LO1 and LO2 register values
 	 */
 	ofLO1 = state->AS_Data.f_LO1;
-	ofLO2 = state->AS_Data.f_LO2; 
+	ofLO2 = state->AS_Data.f_LO2;
 
 	/*
 	 * Find and set RF Band setting
diff --git a/drivers/media/tuners/mt2063.h b/drivers/media/tuners/mt2063.h
index 0e3e3b0..30d03cd 100644
--- a/drivers/media/tuners/mt2063.h
+++ b/drivers/media/tuners/mt2063.h
@@ -2,7 +2,7 @@
 #ifndef __MT2063_H__
 #define __MT2063_H__
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct mt2063_config {
 	u8 tuner_address;
diff --git a/drivers/media/tuners/mt20xx.h b/drivers/media/tuners/mt20xx.h
index 9912362b..3cc41a5 100644
--- a/drivers/media/tuners/mt20xx.h
+++ b/drivers/media/tuners/mt20xx.h
@@ -18,7 +18,7 @@
 #define __MT20XX_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #if IS_REACHABLE(CONFIG_MEDIA_TUNER_MT20XX)
 extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/tuners/mt2131.c b/drivers/media/tuners/mt2131.c
index dd85d58..659bf19 100644
--- a/drivers/media/tuners/mt2131.c
+++ b/drivers/media/tuners/mt2131.c
@@ -21,7 +21,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "mt2131.h"
 #include "mt2131_priv.h"
diff --git a/drivers/media/tuners/mt2266.c b/drivers/media/tuners/mt2266.c
index 88edcc0..f4545b7f 100644
--- a/drivers/media/tuners/mt2266.c
+++ b/drivers/media/tuners/mt2266.c
@@ -20,7 +20,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mt2266.h"
 
 #define I2C_ADDRESS 0x60
diff --git a/drivers/media/tuners/mxl301rf.h b/drivers/media/tuners/mxl301rf.h
index 19e68405..d32d4e8 100644
--- a/drivers/media/tuners/mxl301rf.h
+++ b/drivers/media/tuners/mxl301rf.h
@@ -17,7 +17,7 @@
 #ifndef MXL301RF_H
 #define MXL301RF_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct mxl301rf_config {
 	struct dvb_frontend *fe;
diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c
index dd59c2c..355ef295 100644
--- a/drivers/media/tuners/mxl5005s.c
+++ b/drivers/media/tuners/mxl5005s.c
@@ -63,7 +63,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mxl5005s.h"
 
 static int debug;
@@ -1677,10 +1677,10 @@ static u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
 	u8	AGC_Mode,	/* AGC Mode - Dual AGC: 0, Single AGC: 1 */
 	u16	TOP,		/* 0: Dual AGC; Value: take over point */
 	u16	IF_OUT_LOAD,	/* IF Out Load Resistor (200 / 300 Ohms) */
-	u8	CLOCK_OUT, 	/* 0: turn off clk out; 1: turn on clock out */
+	u8	CLOCK_OUT,	/* 0: turn off clk out; 1: turn on clock out */
 	u8	DIV_OUT,	/* 0: Div-1; 1: Div-4 */
-	u8	CAPSELECT, 	/* 0: disable On-Chip pulling cap; 1: enable */
-	u8	EN_RSSI, 	/* 0: disable RSSI; 1: enable RSSI */
+	u8	CAPSELECT,	/* 0: disable On-Chip pulling cap; 1: enable */
+	u8	EN_RSSI,	/* 0: disable RSSI; 1: enable RSSI */
 
 	/* Modulation Type; */
 	/* 0 - Default;	1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
@@ -3591,10 +3591,11 @@ static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
 	u16 status = 0;
 	int i ;
 
-	u8 RegAddr[] = {
+	static const u8 RegAddr[] = {
 		11, 12, 13, 22, 32, 43, 44, 53, 56, 59, 73,
 		76, 77, 91, 134, 135, 137, 147,
-		156, 166, 167, 168, 25 };
+		156, 166, 167, 168, 25
+	};
 
 	*count = ARRAY_SIZE(RegAddr);
 
@@ -3616,11 +3617,15 @@ static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal,
 
 /* add 77, 166, 167, 168 register for 2.6.12 */
 #ifdef _MXL_PRODUCTION
-	u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 65, 68, 69, 70, 73, 92, 93, 106,
-	   107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
+	static const u8 RegAddr[] = {
+		14, 15, 16, 17, 22, 43, 65, 68, 69, 70, 73, 92, 93, 106,
+		107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168
+	};
 #else
-	u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 68, 69, 70, 73, 92, 93, 106,
-	   107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
+	static const u8 RegAddr[] = {
+		14, 15, 16, 17, 22, 43, 68, 69, 70, 73, 92, 93, 106,
+		107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168
+	};
 	/*
 	u8 RegAddr[171];
 	for (i = 0; i <= 170; i++)
diff --git a/drivers/media/tuners/mxl5005s.h b/drivers/media/tuners/mxl5005s.h
index d842734f..9ac0811 100644
--- a/drivers/media/tuners/mxl5005s.h
+++ b/drivers/media/tuners/mxl5005s.h
@@ -24,7 +24,7 @@
 #define __MXL5005S_H
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct mxl5005s_config {
 
diff --git a/drivers/media/tuners/mxl5007t.h b/drivers/media/tuners/mxl5007t.h
index 273f61a..f7f16b8 100644
--- a/drivers/media/tuners/mxl5007t.h
+++ b/drivers/media/tuners/mxl5007t.h
@@ -17,7 +17,7 @@
 #ifndef __MXL5007T_H__
 #define __MXL5007T_H__
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /* ------------------------------------------------------------------------- */
 
diff --git a/drivers/media/tuners/qm1d1c0042.h b/drivers/media/tuners/qm1d1c0042.h
index 4f5c188..8331f8b 100644
--- a/drivers/media/tuners/qm1d1c0042.h
+++ b/drivers/media/tuners/qm1d1c0042.h
@@ -17,7 +17,7 @@
 #ifndef QM1D1C0042_H
 #define QM1D1C0042_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 
 struct qm1d1c0042_config {
diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c
index ee33b7c..b92be88 100644
--- a/drivers/media/tuners/qt1010.c
+++ b/drivers/media/tuners/qt1010.c
@@ -224,7 +224,7 @@ static int qt1010_set_params(struct dvb_frontend *fe)
 static int qt1010_init_meas1(struct qt1010_priv *priv,
 			     u8 oper, u8 reg, u8 reg_init_val, u8 *retval)
 {
-	u8 i, val1, val2;
+	u8 i, val1, uninitialized_var(val2);
 	int err;
 
 	qt1010_i2c_oper_t i2c_data[] = {
@@ -259,7 +259,7 @@ static int qt1010_init_meas1(struct qt1010_priv *priv,
 static int qt1010_init_meas2(struct qt1010_priv *priv,
 			    u8 reg_init_val, u8 *retval)
 {
-	u8 i, val;
+	u8 i, uninitialized_var(val);
 	int err;
 	qt1010_i2c_oper_t i2c_data[] = {
 		{ QT1010_WR, 0x07, reg_init_val },
diff --git a/drivers/media/tuners/qt1010.h b/drivers/media/tuners/qt1010.h
index 276e59e..24216c2 100644
--- a/drivers/media/tuners/qt1010.h
+++ b/drivers/media/tuners/qt1010.h
@@ -18,7 +18,7 @@
 #ifndef QT1010_H
 #define QT1010_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct qt1010_config {
 	u8 i2c_address;
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index ba80376..bc92990 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -1,36 +1,24 @@
-/*
- * Rafael Micro R820T driver
- *
- * Copyright (C) 2013 Mauro Carvalho Chehab
- *
- * This driver was written from scratch, based on an existing driver
- * that it is part of rtl-sdr git tree, released under GPLv2:
- *	https://groups.google.com/forum/#!topic/ultra-cheap-sdr/Y3rBEOFtHug
- *	https://github.com/n1gp/gr-baz
- *
- * From what I understood from the threads, the original driver was converted
- * to userspace from a Realtek tree. I couldn't find the original tree.
- * However, the original driver look awkward on my eyes. So, I decided to
- * write a new version from it from the scratch, while trying to reproduce
- * everything found there.
- *
- * TODO:
- *	After locking, the original driver seems to have some routines to
- *		improve reception. This was not implemented here yet.
- *
- *	RF Gain set/get is not implemented.
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- */
+// SPDX-License-Identifier: GPL-2.0
+// Rafael Micro R820T driver
+//
+// Copyright (C) 2013 Mauro Carvalho Chehab
+//
+// This driver was written from scratch, based on an existing driver
+// that it is part of rtl-sdr git tree, released under GPLv2:
+//	https://groups.google.com/forum/#!topic/ultra-cheap-sdr/Y3rBEOFtHug
+//	https://github.com/n1gp/gr-baz
+//
+// From what I understood from the threads, the original driver was converted
+// to userspace from a Realtek tree. I couldn't find the original tree.
+// However, the original driver look awkward on my eyes. So, I decided to
+// write a new version from it from the scratch, while trying to reproduce
+// everything found there.
+//
+// TODO:
+//	After locking, the original driver seems to have some routines to
+//		improve reception. This was not implemented here yet.
+//
+//	RF Gain set/get is not implemented.
 
 #include <linux/videodev2.h>
 #include <linux/mutex.h>
@@ -396,9 +384,11 @@ static int r820t_write(struct r820t_priv *priv, u8 reg, const u8 *val,
 	return 0;
 }
 
-static int r820t_write_reg(struct r820t_priv *priv, u8 reg, u8 val)
+static inline int r820t_write_reg(struct r820t_priv *priv, u8 reg, u8 val)
 {
-	return r820t_write(priv, reg, &val, 1);
+	u8 tmp = val; /* work around GCC PR81715 with asan-stack=1 */
+
+	return r820t_write(priv, reg, &tmp, 1);
 }
 
 static int r820t_read_cache_reg(struct r820t_priv *priv, int reg)
@@ -411,17 +401,18 @@ static int r820t_read_cache_reg(struct r820t_priv *priv, int reg)
 		return -EINVAL;
 }
 
-static int r820t_write_reg_mask(struct r820t_priv *priv, u8 reg, u8 val,
+static inline int r820t_write_reg_mask(struct r820t_priv *priv, u8 reg, u8 val,
 				u8 bit_mask)
 {
+	u8 tmp = val;
 	int rc = r820t_read_cache_reg(priv, reg);
 
 	if (rc < 0)
 		return rc;
 
-	val = (rc & ~bit_mask) | (val & bit_mask);
+	tmp = (rc & ~bit_mask) | (tmp & bit_mask);
 
-	return r820t_write(priv, reg, &val, 1);
+	return r820t_write(priv, reg, &tmp, 1);
 }
 
 static int r820t_read(struct r820t_priv *priv, u8 reg, u8 *val, int len)
@@ -2388,4 +2379,4 @@ EXPORT_SYMBOL_GPL(r820t_attach);
 
 MODULE_DESCRIPTION("Rafael Micro r820t silicon tuner driver");
 MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/tuners/r820t.h b/drivers/media/tuners/r820t.h
index fdcab91..4f91dbb 100644
--- a/drivers/media/tuners/r820t.h
+++ b/drivers/media/tuners/r820t.h
@@ -21,7 +21,7 @@
 #ifndef R820T_H
 #define R820T_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 enum r820t_chip {
 	CHIP_R820T,
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index e35b1fa..9e34d31 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -532,7 +532,7 @@ MODULE_DEVICE_TABLE(i2c, si2157_id_table);
 
 static struct i2c_driver si2157_driver = {
 	.driver = {
-		.name	             = "si2157",
+		.name		     = "si2157",
 		.suppress_bind_attrs = true,
 	},
 	.probe		= si2157_probe,
diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h
index 76807f5..de597fa 100644
--- a/drivers/media/tuners/si2157.h
+++ b/drivers/media/tuners/si2157.h
@@ -18,7 +18,7 @@
 #define SI2157_H
 
 #include <media/media-device.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /*
  * I2C address
diff --git a/drivers/media/tuners/tda18212.h b/drivers/media/tuners/tda18212.h
index 6391daf..9ed4367 100644
--- a/drivers/media/tuners/tda18212.h
+++ b/drivers/media/tuners/tda18212.h
@@ -21,7 +21,7 @@
 #ifndef TDA18212_H
 #define TDA18212_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct tda18212_config {
 	u16 if_dvbt_6;
diff --git a/drivers/media/tuners/tda18218.h b/drivers/media/tuners/tda18218.h
index 9c0e3fd..0427c6f 100644
--- a/drivers/media/tuners/tda18218.h
+++ b/drivers/media/tuners/tda18218.h
@@ -17,7 +17,7 @@
 #ifndef TDA18218_H
 #define TDA18218_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct tda18218_config {
 	u8 i2c_address;
diff --git a/drivers/media/tuners/tda18250.c b/drivers/media/tuners/tda18250.c
new file mode 100644
index 0000000..20d12b0
--- /dev/null
+++ b/drivers/media/tuners/tda18250.c
@@ -0,0 +1,902 @@
+/*
+ * NXP TDA18250 silicon tuner driver
+ *
+ * Copyright (C) 2017 Olli Salonen <olli.salonen@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ */
+
+#include "tda18250_priv.h"
+#include <linux/regmap.h>
+
+static const struct dvb_tuner_ops tda18250_ops;
+
+static int tda18250_power_control(struct dvb_frontend *fe,
+		unsigned int power_state)
+{
+	struct i2c_client *client = fe->tuner_priv;
+	struct tda18250_dev *dev = i2c_get_clientdata(client);
+	int ret;
+	unsigned int utmp;
+
+	dev_dbg(&client->dev, "power state: %d", power_state);
+
+	switch (power_state) {
+	case TDA18250_POWER_NORMAL:
+		ret = regmap_write_bits(dev->regmap, R06_POWER2, 0x07, 0x00);
+		if (ret)
+			goto err;
+		ret = regmap_write_bits(dev->regmap, R25_REF, 0xc0, 0xc0);
+		if (ret)
+			goto err;
+		break;
+	case TDA18250_POWER_STANDBY:
+		if (dev->loopthrough) {
+			ret = regmap_write_bits(dev->regmap,
+					R25_REF, 0xc0, 0x80);
+			if (ret)
+				goto err;
+			ret = regmap_write_bits(dev->regmap,
+					R06_POWER2, 0x07, 0x02);
+			if (ret)
+				goto err;
+			ret = regmap_write_bits(dev->regmap,
+					R10_LT1, 0x80, 0x00);
+			if (ret)
+				goto err;
+		} else {
+			ret = regmap_write_bits(dev->regmap,
+					R25_REF, 0xc0, 0x80);
+			if (ret)
+				goto err;
+			ret = regmap_write_bits(dev->regmap,
+					R06_POWER2, 0x07, 0x01);
+			if (ret)
+				goto err;
+			ret = regmap_read(dev->regmap,
+					R0D_AGC12, &utmp);
+			if (ret)
+				goto err;
+			ret = regmap_write_bits(dev->regmap,
+					R0D_AGC12, 0x03, 0x03);
+			if (ret)
+				goto err;
+			ret = regmap_write_bits(dev->regmap,
+					R10_LT1, 0x80, 0x80);
+			if (ret)
+				goto err;
+			ret = regmap_write_bits(dev->regmap,
+					R0D_AGC12, 0x03, utmp & 0x03);
+			if (ret)
+				goto err;
+		}
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+
+	return 0;
+err:
+	return ret;
+}
+
+static int tda18250_wait_for_irq(struct dvb_frontend *fe,
+		int maxwait, int step, u8 irq)
+{
+	struct i2c_client *client = fe->tuner_priv;
+	struct tda18250_dev *dev = i2c_get_clientdata(client);
+	int ret;
+	unsigned long timeout;
+	bool triggered;
+	unsigned int utmp;
+
+	triggered = false;
+	timeout = jiffies + msecs_to_jiffies(maxwait);
+	while (!time_after(jiffies, timeout)) {
+		// check for the IRQ
+		ret = regmap_read(dev->regmap, R08_IRQ1, &utmp);
+		if (ret)
+			goto err;
+		if ((utmp & irq) == irq) {
+			triggered = true;
+			break;
+		}
+		msleep(step);
+	}
+
+	dev_dbg(&client->dev, "waited IRQ (0x%02x) %d ms, triggered: %s", irq,
+			jiffies_to_msecs(jiffies) -
+			(jiffies_to_msecs(timeout) - maxwait),
+			triggered ? "true" : "false");
+
+	if (!triggered)
+		return -ETIMEDOUT;
+
+	return 0;
+err:
+	return ret;
+}
+
+static int tda18250_init(struct dvb_frontend *fe)
+{
+	struct i2c_client *client = fe->tuner_priv;
+	struct tda18250_dev *dev = i2c_get_clientdata(client);
+	int ret, i;
+
+	/* default values for various regs */
+	static const u8 init_regs[][2] = {
+		{ R0C_AGC11, 0xc7 },
+		{ R0D_AGC12, 0x5d },
+		{ R0E_AGC13, 0x40 },
+		{ R0F_AGC14, 0x0e },
+		{ R10_LT1, 0x47 },
+		{ R11_LT2, 0x4e },
+		{ R12_AGC21, 0x26 },
+		{ R13_AGC22, 0x60 },
+		{ R18_AGC32, 0x37 },
+		{ R19_AGC33, 0x09 },
+		{ R1A_AGCK, 0x00 },
+		{ R1E_WI_FI, 0x29 },
+		{ R1F_RF_BPF, 0x06 },
+		{ R20_IR_MIX, 0xc6 },
+		{ R21_IF_AGC, 0x00 },
+		{ R2C_PS1, 0x75 },
+		{ R2D_PS2, 0x06 },
+		{ R2E_PS3, 0x07 },
+		{ R30_RSSI2, 0x0e },
+		{ R31_IRQ_CTRL, 0x00 },
+		{ R39_SD5, 0x00 },
+		{ R3B_REGU, 0x55 },
+		{ R3C_RCCAL1, 0xa7 },
+		{ R3F_IRCAL2, 0x85 },
+		{ R40_IRCAL3, 0x87 },
+		{ R41_IRCAL4, 0xc0 },
+		{ R43_PD1, 0x40 },
+		{ R44_PD2, 0xc0 },
+		{ R46_CPUMP, 0x0c },
+		{ R47_LNAPOL, 0x64 },
+		{ R4B_XTALOSC1, 0x30 },
+		{ R59_AGC2_UP2, 0x05 },
+		{ R5B_AGC_AUTO, 0x07 },
+		{ R5C_AGC_DEBUG, 0x00 },
+	};
+
+	/* crystal related regs depend on frequency */
+	static const u8 xtal_regs[][5] = {
+					/* reg:   4d    4e    4f    50    51 */
+		[TDA18250_XTAL_FREQ_16MHZ]  = { 0x3e, 0x80, 0x50, 0x00, 0x20 },
+		[TDA18250_XTAL_FREQ_24MHZ]  = { 0x5d, 0xc0, 0xec, 0x00, 0x18 },
+		[TDA18250_XTAL_FREQ_25MHZ]  = { 0x61, 0xa8, 0xec, 0x80, 0x19 },
+		[TDA18250_XTAL_FREQ_27MHZ]  = { 0x69, 0x78, 0x8d, 0x80, 0x1b },
+		[TDA18250_XTAL_FREQ_30MHZ]  = { 0x75, 0x30, 0x8f, 0x00, 0x1e },
+	};
+
+	dev_dbg(&client->dev, "\n");
+
+	ret = tda18250_power_control(fe, TDA18250_POWER_NORMAL);
+	if (ret)
+		goto err;
+
+	msleep(20);
+
+	if (dev->warm)
+		goto warm;
+
+	/* set initial register values */
+	for (i = 0; i < ARRAY_SIZE(init_regs); i++) {
+		ret = regmap_write(dev->regmap, init_regs[i][0],
+				init_regs[i][1]);
+		if (ret)
+			goto err;
+	}
+
+	/* set xtal related regs */
+	ret = regmap_bulk_write(dev->regmap, R4D_XTALFLX1,
+			xtal_regs[dev->xtal_freq], 5);
+	if (ret)
+		goto err;
+
+	ret = regmap_write_bits(dev->regmap, R10_LT1, 0x80,
+			dev->loopthrough ? 0x00 : 0x80);
+	if (ret)
+		goto err;
+
+	/* clear IRQ */
+	ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_HW_INIT);
+	if (ret)
+		goto err;
+
+	/* start HW init */
+	ret = regmap_write(dev->regmap, R2A_MSM1, 0x70);
+	if (ret)
+		goto err;
+
+	ret = regmap_write(dev->regmap, R2B_MSM2, 0x01);
+	if (ret)
+		goto err;
+
+	ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_HW_INIT);
+	if (ret)
+		goto err;
+
+	/* tuner calibration */
+	ret = regmap_write(dev->regmap, R2A_MSM1, 0x02);
+	if (ret)
+		goto err;
+
+	ret = regmap_write(dev->regmap, R2B_MSM2, 0x01);
+	if (ret)
+		goto err;
+
+	ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_CAL);
+	if (ret)
+		goto err;
+
+	dev->warm = true;
+
+warm:
+	/* power up LNA */
+	ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x80, 0x00);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	dev_dbg(&client->dev, "failed=%d", ret);
+	return ret;
+}
+
+static int tda18250_set_agc(struct dvb_frontend *fe)
+{
+	struct i2c_client *client = fe->tuner_priv;
+	struct tda18250_dev *dev = i2c_get_clientdata(client);
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret;
+	u8 utmp, utmp2;
+
+	dev_dbg(&client->dev, "\n");
+
+	ret = regmap_write_bits(dev->regmap, R1F_RF_BPF, 0x87, 0x06);
+	if (ret)
+		goto err;
+
+	utmp = ((c->frequency < 100000000) &&
+			((c->delivery_system == SYS_DVBC_ANNEX_A) ||
+			(c->delivery_system == SYS_DVBC_ANNEX_C)) &&
+			(c->bandwidth_hz == 6000000)) ? 0x80 : 0x00;
+	ret = regmap_write(dev->regmap, R5A_H3H5, utmp);
+	if (ret)
+		goto err;
+
+	/* AGC1 */
+	switch (c->delivery_system) {
+	case SYS_ATSC:
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		utmp = 4;
+		break;
+	default: /* DVB-C/QAM */
+		switch (c->bandwidth_hz) {
+		case 6000000:
+			utmp = (c->frequency < 800000000) ? 6 : 4;
+			break;
+		default: /* 7.935 and 8 MHz */
+			utmp = (c->frequency < 100000000) ? 2 : 3;
+			break;
+		}
+		break;
+	}
+
+	ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x07, utmp);
+	if (ret)
+		goto err;
+
+	/* AGC2 */
+	switch (c->delivery_system) {
+	case SYS_ATSC:
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		utmp = (c->frequency < 320000000) ? 20 : 16;
+		utmp2 = (c->frequency < 320000000) ? 22 : 18;
+		break;
+	default: /* DVB-C/QAM */
+		switch (c->bandwidth_hz) {
+		case 6000000:
+			if (c->frequency < 600000000) {
+				utmp = 18;
+				utmp2 = 22;
+			} else if (c->frequency < 800000000) {
+				utmp = 16;
+				utmp2 = 20;
+			} else {
+				utmp = 14;
+				utmp2 = 16;
+			}
+			break;
+		default: /* 7.935 and 8 MHz */
+			utmp = (c->frequency < 320000000) ? 16 : 18;
+			utmp2 = (c->frequency < 320000000) ? 18 : 20;
+			break;
+		}
+		break;
+	}
+	ret = regmap_write_bits(dev->regmap, R58_AGC2_UP1, 0x1f, utmp2+8);
+	if (ret)
+		goto err;
+	ret = regmap_write_bits(dev->regmap, R13_AGC22, 0x1f, utmp);
+	if (ret)
+		goto err;
+	ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x1f, utmp2);
+	if (ret)
+		goto err;
+
+	switch (c->delivery_system) {
+	case SYS_ATSC:
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		utmp = 98;
+		break;
+	default: /* DVB-C/QAM */
+		utmp = 90;
+		break;
+	}
+	ret = regmap_write_bits(dev->regmap, R16_AGC25, 0xf8, utmp);
+	if (ret)
+		goto err;
+
+	ret = regmap_write_bits(dev->regmap, R12_AGC21, 0x60,
+			(c->frequency > 800000000) ? 0x40 : 0x20);
+	if (ret)
+		goto err;
+
+	/* AGC3 */
+	switch (c->delivery_system) {
+	case SYS_ATSC:
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		utmp = (c->frequency < 320000000) ? 5 : 7;
+		utmp2 = (c->frequency < 320000000) ? 10 : 12;
+		break;
+	default: /* DVB-C/QAM */
+		utmp = 7;
+		utmp2 = 12;
+		break;
+	}
+	ret = regmap_write(dev->regmap, R17_AGC31, (utmp << 4) | utmp2);
+	if (ret)
+		goto err;
+
+	/* S2D */
+	switch (c->delivery_system) {
+	case SYS_ATSC:
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		if (c->bandwidth_hz == 8000000)
+			utmp = 0x04;
+		else
+			utmp = (c->frequency < 320000000) ? 0x04 : 0x02;
+		break;
+	default: /* DVB-C/QAM */
+		if (c->bandwidth_hz == 6000000)
+			utmp = ((c->frequency > 172544000) &&
+				(c->frequency < 320000000)) ? 0x04 : 0x02;
+		else /* 7.935 and 8 MHz */
+			utmp = ((c->frequency > 320000000) &&
+				(c->frequency < 600000000)) ? 0x02 : 0x04;
+		break;
+	}
+	ret = regmap_write_bits(dev->regmap, R20_IR_MIX, 0x06, utmp);
+	if (ret)
+		goto err;
+
+	switch (c->delivery_system) {
+	case SYS_ATSC:
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		utmp = 0;
+		break;
+	default: /* DVB-C/QAM */
+		utmp = (c->frequency < 600000000) ? 0 : 3;
+		break;
+	}
+	ret = regmap_write_bits(dev->regmap, R16_AGC25, 0x03, utmp);
+	if (ret)
+		goto err;
+
+	utmp = 0x09;
+	switch (c->delivery_system) {
+	case SYS_ATSC:
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		if (c->bandwidth_hz == 8000000)
+			utmp = 0x0c;
+		break;
+	default: /* DVB-C/QAM */
+		utmp = 0x0c;
+		break;
+	}
+	ret = regmap_write_bits(dev->regmap, R0F_AGC14, 0x3f, utmp);
+	if (ret)
+		goto err;
+
+	return 0;
+err:
+	dev_dbg(&client->dev, "failed=%d", ret);
+	return ret;
+}
+
+static int tda18250_pll_calc(struct dvb_frontend *fe, u8 *rdiv,
+		u8 *ndiv, u8 *icp)
+{
+	struct i2c_client *client = fe->tuner_priv;
+	struct tda18250_dev *dev = i2c_get_clientdata(client);
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret;
+	unsigned int uval, exp, lopd, scale;
+	unsigned long fvco;
+
+	ret = regmap_read(dev->regmap, R34_MD1, &uval);
+	if (ret)
+		goto err;
+
+	exp = (uval & 0x70) >> 4;
+	if (exp > 5)
+		exp = 0;
+	lopd = 1 << (exp - 1);
+	scale = uval & 0x0f;
+	fvco = lopd * scale * ((c->frequency / 1000) + dev->if_frequency);
+
+	switch (dev->xtal_freq) {
+	case TDA18250_XTAL_FREQ_16MHZ:
+		*rdiv = 1;
+		*ndiv = 0;
+		*icp = (fvco < 6622000) ? 0x05 : 0x02;
+	break;
+	case TDA18250_XTAL_FREQ_24MHZ:
+	case TDA18250_XTAL_FREQ_25MHZ:
+		*rdiv = 3;
+		*ndiv = 1;
+		*icp = (fvco < 6622000) ? 0x05 : 0x02;
+	break;
+	case TDA18250_XTAL_FREQ_27MHZ:
+		if (fvco < 6643000) {
+			*rdiv = 2;
+			*ndiv = 0;
+			*icp = 0x05;
+		} else if (fvco < 6811000) {
+			*rdiv = 2;
+			*ndiv = 0;
+			*icp = 0x06;
+		} else {
+			*rdiv = 3;
+			*ndiv = 1;
+			*icp = 0x02;
+		}
+	break;
+	case TDA18250_XTAL_FREQ_30MHZ:
+		*rdiv = 2;
+		*ndiv = 0;
+		*icp = (fvco < 6811000) ? 0x05 : 0x02;
+	break;
+	default:
+		return -EINVAL;
+	}
+
+	dev_dbg(&client->dev,
+			"lopd=%d scale=%u fvco=%lu, rdiv=%d ndiv=%d icp=%d",
+			lopd, scale, fvco, *rdiv, *ndiv, *icp);
+	return 0;
+err:
+	return ret;
+}
+
+static int tda18250_set_params(struct dvb_frontend *fe)
+{
+	struct i2c_client *client = fe->tuner_priv;
+	struct tda18250_dev *dev = i2c_get_clientdata(client);
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	u32 if_khz;
+	int ret;
+	unsigned int i, j;
+	u8 utmp;
+	u8 buf[3];
+
+	#define REG      0
+	#define MASK     1
+	#define DVBT_6   2
+	#define DVBT_7   3
+	#define DVBT_8   4
+	#define DVBC_6   5
+	#define DVBC_8   6
+	#define ATSC     7
+
+	static const u8 delsys_params[][16] = {
+		[REG]    = { 0x22, 0x23, 0x24, 0x21, 0x0d, 0x0c, 0x0f, 0x14,
+			     0x0e, 0x12, 0x58, 0x59, 0x1a, 0x19, 0x1e, 0x30 },
+		[MASK]   = { 0x77, 0xff, 0xff, 0x87, 0xf0, 0x78, 0x07, 0xe0,
+			     0x60, 0x0f, 0x60, 0x0f, 0x33, 0x30, 0x80, 0x06 },
+		[DVBT_6] = { 0x51, 0x03, 0x83, 0x82, 0x40, 0x48, 0x01, 0xe0,
+			     0x60, 0x0f, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 },
+		[DVBT_7] = { 0x52, 0x03, 0x85, 0x82, 0x40, 0x48, 0x01, 0xe0,
+			     0x60, 0x0f, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 },
+		[DVBT_8] = { 0x53, 0x03, 0x87, 0x82, 0x40, 0x48, 0x06, 0xe0,
+			     0x60, 0x07, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 },
+		[DVBC_6] = { 0x32, 0x05, 0x86, 0x82, 0x50, 0x00, 0x06, 0x60,
+			     0x40, 0x0e, 0x60, 0x05, 0x33, 0x10, 0x00, 0x04 },
+		[DVBC_8] = { 0x53, 0x03, 0x88, 0x82, 0x50, 0x00, 0x06, 0x60,
+			     0x40, 0x0e, 0x60, 0x05, 0x33, 0x10, 0x00, 0x04 },
+		[ATSC]   = { 0x51, 0x03, 0x83, 0x82, 0x40, 0x48, 0x01, 0xe0,
+			     0x40, 0x0e, 0x60, 0x05, 0x03, 0x00, 0x80, 0x04 },
+	};
+
+	dev_dbg(&client->dev,
+			"delivery_system=%d frequency=%u bandwidth_hz=%u",
+			c->delivery_system, c->frequency, c->bandwidth_hz);
+
+
+	switch (c->delivery_system) {
+	case SYS_ATSC:
+		j = ATSC;
+		if_khz = dev->if_atsc;
+		break;
+	case SYS_DVBT:
+	case SYS_DVBT2:
+		if (c->bandwidth_hz == 0) {
+			ret = -EINVAL;
+			goto err;
+		} else if (c->bandwidth_hz <= 6000000) {
+			j = DVBT_6;
+			if_khz = dev->if_dvbt_6;
+		} else if (c->bandwidth_hz <= 7000000) {
+			j = DVBT_7;
+			if_khz = dev->if_dvbt_7;
+		} else if (c->bandwidth_hz <= 8000000) {
+			j = DVBT_8;
+			if_khz = dev->if_dvbt_8;
+		} else {
+			ret = -EINVAL;
+			goto err;
+		}
+		break;
+	case SYS_DVBC_ANNEX_A:
+	case SYS_DVBC_ANNEX_C:
+		if (c->bandwidth_hz == 0) {
+			ret = -EINVAL;
+			goto err;
+		} else if (c->bandwidth_hz <= 6000000) {
+			j = DVBC_6;
+			if_khz = dev->if_dvbc_6;
+		} else if (c->bandwidth_hz <= 8000000) {
+			j = DVBC_8;
+			if_khz = dev->if_dvbc_8;
+		} else {
+			ret = -EINVAL;
+			goto err;
+		}
+		break;
+	default:
+		ret = -EINVAL;
+		dev_err(&client->dev, "unsupported delivery system=%d",
+				c->delivery_system);
+		goto err;
+	}
+
+	/* set delivery system dependent registers */
+	for (i = 0; i < 16; i++) {
+		ret = regmap_write_bits(dev->regmap, delsys_params[REG][i],
+			 delsys_params[MASK][i],  delsys_params[j][i]);
+		if (ret)
+			goto err;
+	}
+
+	/* set IF if needed */
+	if (dev->if_frequency != if_khz) {
+		utmp = DIV_ROUND_CLOSEST(if_khz, 50);
+		ret = regmap_write(dev->regmap, R26_IF, utmp);
+		if (ret)
+			goto err;
+		dev->if_frequency = if_khz;
+		dev_dbg(&client->dev, "set IF=%u kHz", if_khz);
+
+	}
+
+	ret = tda18250_set_agc(fe);
+	if (ret)
+		goto err;
+
+	ret = regmap_write_bits(dev->regmap, R1A_AGCK, 0x03, 0x01);
+	if (ret)
+		goto err;
+
+	ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x40, 0x00);
+	if (ret)
+		goto err;
+
+	/* set frequency */
+	buf[0] = ((c->frequency / 1000) >> 16) & 0xff;
+	buf[1] = ((c->frequency / 1000) >>  8) & 0xff;
+	buf[2] = ((c->frequency / 1000) >>  0) & 0xff;
+	ret = regmap_bulk_write(dev->regmap, R27_RF1, buf, 3);
+	if (ret)
+		goto err;
+
+	ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_TUNE);
+	if (ret)
+		goto err;
+
+	/* initial tune */
+	ret = regmap_write(dev->regmap, R2A_MSM1, 0x01);
+	if (ret)
+		goto err;
+
+	ret = regmap_write(dev->regmap, R2B_MSM2, 0x01);
+	if (ret)
+		goto err;
+
+	ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_TUNE);
+	if (ret)
+		goto err;
+
+	/* calc ndiv and rdiv */
+	ret = tda18250_pll_calc(fe, &buf[0], &buf[1], &buf[2]);
+	if (ret)
+		goto err;
+
+	ret = regmap_write_bits(dev->regmap, R4F_XTALFLX3, 0xe0,
+			(buf[0] << 6) | (buf[1] << 5));
+	if (ret)
+		goto err;
+
+	/* clear IRQ */
+	ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_TUNE);
+	if (ret)
+		goto err;
+
+	ret = regmap_write_bits(dev->regmap, R46_CPUMP, 0x07, 0x00);
+	if (ret)
+		goto err;
+
+	ret = regmap_write_bits(dev->regmap, R39_SD5, 0x03, 0x00);
+	if (ret)
+		goto err;
+
+	/* tune again */
+	ret = regmap_write(dev->regmap, R2A_MSM1, 0x01); /* tune */
+	if (ret)
+		goto err;
+
+	ret = regmap_write(dev->regmap, R2B_MSM2, 0x01); /* go */
+	if (ret)
+		goto err;
+
+	ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_TUNE);
+	if (ret)
+		goto err;
+
+	/* pll locking */
+	msleep(20);
+
+	ret = regmap_write_bits(dev->regmap, R2B_MSM2, 0x04, 0x04);
+	if (ret)
+		goto err;
+
+	msleep(20);
+
+	/* restore AGCK */
+	ret = regmap_write_bits(dev->regmap, R1A_AGCK, 0x03, 0x03);
+	if (ret)
+		goto err;
+
+	ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x40, 0x40);
+	if (ret)
+		goto err;
+
+	/* charge pump */
+	ret = regmap_write_bits(dev->regmap, R46_CPUMP, 0x07, buf[2]);
+
+	return 0;
+err:
+	return ret;
+}
+
+static int tda18250_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+	struct i2c_client *client = fe->tuner_priv;
+	struct tda18250_dev *dev = i2c_get_clientdata(client);
+
+	*frequency = dev->if_frequency * 1000;
+	return 0;
+}
+
+static int tda18250_sleep(struct dvb_frontend *fe)
+{
+	struct i2c_client *client = fe->tuner_priv;
+	struct tda18250_dev *dev = i2c_get_clientdata(client);
+	int ret;
+
+	dev_dbg(&client->dev, "\n");
+
+	/* power down LNA */
+	ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x80, 0x00);
+	if (ret)
+		return ret;
+
+	/* set if freq to 0 in order to make sure it's set after wake up */
+	dev->if_frequency = 0;
+
+	ret = tda18250_power_control(fe, TDA18250_POWER_STANDBY);
+	return ret;
+}
+
+static const struct dvb_tuner_ops tda18250_ops = {
+	.info = {
+		.name           = "NXP TDA18250",
+		.frequency_min  = 42000000,
+		.frequency_max  = 870000000,
+	},
+
+	.init = tda18250_init,
+	.set_params = tda18250_set_params,
+	.get_if_frequency = tda18250_get_if_frequency,
+	.sleep = tda18250_sleep,
+};
+
+static int tda18250_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct tda18250_config *cfg = client->dev.platform_data;
+	struct dvb_frontend *fe = cfg->fe;
+	struct tda18250_dev *dev;
+	int ret;
+	unsigned char chip_id[3];
+
+	/* some registers are always read from HW */
+	static const struct regmap_range tda18250_yes_ranges[] = {
+		regmap_reg_range(R05_POWER1, R0B_IRQ4),
+		regmap_reg_range(R21_IF_AGC, R21_IF_AGC),
+		regmap_reg_range(R2A_MSM1, R2B_MSM2),
+		regmap_reg_range(R2F_RSSI1, R31_IRQ_CTRL),
+	};
+
+	static const struct regmap_access_table tda18250_volatile_table = {
+		.yes_ranges = tda18250_yes_ranges,
+		.n_yes_ranges = ARRAY_SIZE(tda18250_yes_ranges),
+	};
+
+	static const struct regmap_config tda18250_regmap_config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+		.max_register = TDA18250_NUM_REGS - 1,
+		.volatile_table = &tda18250_volatile_table,
+	};
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	i2c_set_clientdata(client, dev);
+
+	dev->fe = cfg->fe;
+	dev->loopthrough = cfg->loopthrough;
+	if (cfg->xtal_freq < TDA18250_XTAL_FREQ_MAX) {
+		dev->xtal_freq = cfg->xtal_freq;
+	} else {
+		ret = -EINVAL;
+		dev_err(&client->dev, "xtal_freq invalid=%d", cfg->xtal_freq);
+		goto err_kfree;
+	}
+	dev->if_dvbt_6 = cfg->if_dvbt_6;
+	dev->if_dvbt_7 = cfg->if_dvbt_7;
+	dev->if_dvbt_8 = cfg->if_dvbt_8;
+	dev->if_dvbc_6 = cfg->if_dvbc_6;
+	dev->if_dvbc_8 = cfg->if_dvbc_8;
+	dev->if_atsc = cfg->if_atsc;
+
+	dev->if_frequency = 0;
+	dev->warm = false;
+
+	dev->regmap = devm_regmap_init_i2c(client, &tda18250_regmap_config);
+	if (IS_ERR(dev->regmap)) {
+		ret = PTR_ERR(dev->regmap);
+		goto err_kfree;
+	}
+
+	/* read the three chip ID registers */
+	regmap_bulk_read(dev->regmap, R00_ID1, &chip_id, 3);
+	dev_dbg(&client->dev, "chip_id=%02x:%02x:%02x",
+			chip_id[0], chip_id[1], chip_id[2]);
+
+	switch (chip_id[0]) {
+	case 0xc7:
+		dev->slave = false;
+		break;
+	case 0x47:
+		dev->slave = true;
+		break;
+	default:
+		ret = -ENODEV;
+		goto err_kfree;
+	}
+
+	if (chip_id[1] != 0x4a) {
+		ret = -ENODEV;
+		goto err_kfree;
+	}
+
+	switch (chip_id[2]) {
+	case 0x20:
+		dev_info(&client->dev,
+				"NXP TDA18250AHN/%s successfully identified",
+				dev->slave ? "S" : "M");
+		break;
+	case 0x21:
+		dev_info(&client->dev,
+				"NXP TDA18250BHN/%s successfully identified",
+				dev->slave ? "S" : "M");
+		break;
+	default:
+		ret = -ENODEV;
+		goto err_kfree;
+	}
+
+	fe->tuner_priv = client;
+	memcpy(&fe->ops.tuner_ops, &tda18250_ops,
+			sizeof(struct dvb_tuner_ops));
+
+	/* put the tuner in standby */
+	tda18250_power_control(fe, TDA18250_POWER_STANDBY);
+
+	return 0;
+err_kfree:
+	kfree(dev);
+err:
+	dev_dbg(&client->dev, "failed=%d", ret);
+	return ret;
+}
+
+static int tda18250_remove(struct i2c_client *client)
+{
+	struct tda18250_dev *dev = i2c_get_clientdata(client);
+	struct dvb_frontend *fe = dev->fe;
+
+	dev_dbg(&client->dev, "\n");
+
+	memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
+	fe->tuner_priv = NULL;
+	kfree(dev);
+
+	return 0;
+}
+
+static const struct i2c_device_id tda18250_id_table[] = {
+	{"tda18250", 0},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, tda18250_id_table);
+
+static struct i2c_driver tda18250_driver = {
+	.driver = {
+		.name	= "tda18250",
+	},
+	.probe		= tda18250_probe,
+	.remove		= tda18250_remove,
+	.id_table	= tda18250_id_table,
+};
+
+module_i2c_driver(tda18250_driver);
+
+MODULE_DESCRIPTION("NXP TDA18250 silicon tuner driver");
+MODULE_AUTHOR("Olli Salonen <olli.salonen@iki.fi>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tda18250.h b/drivers/media/tuners/tda18250.h
new file mode 100644
index 0000000..961806a8
--- /dev/null
+++ b/drivers/media/tuners/tda18250.h
@@ -0,0 +1,51 @@
+/*
+ * NXP TDA18250BHN silicon tuner driver
+ *
+ * Copyright (C) 2017 Olli Salonen <olli.salonen@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#ifndef TDA18250_H
+#define TDA18250_H
+
+#include <linux/kconfig.h>
+#include <media/media-device.h>
+#include <media/dvb_frontend.h>
+
+#define TDA18250_XTAL_FREQ_16MHZ 0
+#define TDA18250_XTAL_FREQ_24MHZ 1
+#define TDA18250_XTAL_FREQ_25MHZ 2
+#define TDA18250_XTAL_FREQ_27MHZ 3
+#define TDA18250_XTAL_FREQ_30MHZ 4
+#define TDA18250_XTAL_FREQ_MAX 5
+
+struct tda18250_config {
+	u16 if_dvbt_6;
+	u16 if_dvbt_7;
+	u16 if_dvbt_8;
+	u16 if_dvbc_6;
+	u16 if_dvbc_8;
+	u16 if_atsc;
+	u8 xtal_freq;
+	bool loopthrough;
+
+	/*
+	 * frontend
+	 */
+	struct dvb_frontend *fe;
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	struct media_device *mdev;
+#endif
+};
+
+#endif
diff --git a/drivers/media/tuners/tda18250_priv.h b/drivers/media/tuners/tda18250_priv.h
new file mode 100644
index 0000000..4a6f801
--- /dev/null
+++ b/drivers/media/tuners/tda18250_priv.h
@@ -0,0 +1,145 @@
+/*
+ * NXP TDA18250BHN silicon tuner driver
+ *
+ * Copyright (C) 2017 Olli Salonen <olli.salonen@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ */
+
+#ifndef TDA18250_PRIV_H
+#define TDA18250_PRIV_H
+
+#include "tda18250.h"
+
+#define R00_ID1		0x00	/* ID byte 1 */
+#define R01_ID2		0x01	/* ID byte 2 */
+#define R02_ID3		0x02	/* ID byte 3 */
+#define R03_THERMO1	0x03	/* Thermo byte 1 */
+#define R04_THERMO2	0x04	/* Thermo byte 2 */
+#define R05_POWER1	0x05	/* Power byte 1 */
+#define R06_POWER2	0x06	/* Power byte 2 */
+#define R07_GPIO	0x07	/* GPIO */
+#define R08_IRQ1	0x08	/* IRQ */
+#define R09_IRQ2	0x09	/* IRQ */
+#define R0A_IRQ3	0x0a	/* IRQ */
+#define R0B_IRQ4	0x0b	/* IRQ */
+#define R0C_AGC11	0x0c	/* AGC1 byte 1 */
+#define R0D_AGC12	0x0d	/* AGC1 byte 2 */
+#define R0E_AGC13	0x0e	/* AGC1 byte 3 */
+#define R0F_AGC14	0x0f	/* AGC1 byte 4 */
+#define R10_LT1		0x10	/* LT byte 1 */
+#define R11_LT2		0x11	/* LT byte 2 */
+#define R12_AGC21	0x12	/* AGC2 byte 1 */
+#define R13_AGC22	0x13	/* AGC2 byte 2 */
+#define R14_AGC23	0x14	/* AGC2 byte 3 */
+#define R15_AGC24	0x15	/* AGC2 byte 4 */
+#define R16_AGC25	0x16	/* AGC2 byte 5 */
+#define R17_AGC31	0x17	/* AGC3 byte 1 */
+#define R18_AGC32	0x18	/* AGC3 byte 2 */
+#define R19_AGC33	0x19	/* AGC3 byte 3 */
+#define R1A_AGCK	0x1a
+#define R1B_GAIN1	0x1b
+#define R1C_GAIN2	0x1c
+#define R1D_GAIN3	0x1d
+#define R1E_WI_FI	0x1e	/* Wireless Filter */
+#define R1F_RF_BPF	0x1f	/* RF Band Pass Filter */
+#define R20_IR_MIX	0x20	/* IR Mixer */
+#define R21_IF_AGC	0x21
+#define R22_IF1		0x22	/* IF byte 1 */
+#define R23_IF2		0x23	/* IF byte 2 */
+#define R24_IF3		0x24	/* IF byte 3 */
+#define R25_REF		0x25	/* reference byte */
+#define R26_IF		0x26	/* IF frequency */
+#define R27_RF1		0x27	/* RF frequency byte 1 */
+#define R28_RF2		0x28	/* RF frequency byte 2 */
+#define R29_RF3		0x29	/* RF frequency byte 3 */
+#define R2A_MSM1	0x2a
+#define R2B_MSM2	0x2b
+#define R2C_PS1		0x2c	/* power saving mode byte 1 */
+#define R2D_PS2		0x2d	/* power saving mode byte 2 */
+#define R2E_PS3		0x2e	/* power saving mode byte 3 */
+#define R2F_RSSI1	0x2f
+#define R30_RSSI2	0x30
+#define R31_IRQ_CTRL	0x31
+#define R32_DUMMY	0x32
+#define R33_TEST	0x33
+#define R34_MD1		0x34
+#define R35_SD1		0x35
+#define R36_SD2		0x36
+#define R37_SD3		0x37
+#define R38_SD4		0x38
+#define R39_SD5		0x39
+#define R3A_SD_TEST	0x3a
+#define R3B_REGU	0x3b
+#define R3C_RCCAL1	0x3c
+#define R3D_RCCAL2	0x3d
+#define R3E_IRCAL1	0x3e
+#define R3F_IRCAL2	0x3f
+#define R40_IRCAL3	0x40
+#define R41_IRCAL4	0x41
+#define R42_IRCAL5	0x42
+#define R43_PD1		0x43	/* power down byte 1 */
+#define R44_PD2		0x44	/* power down byte 2 */
+#define R45_PD		0x45	/* power down */
+#define R46_CPUMP	0x46	/* charge pump */
+#define R47_LNAPOL	0x47	/* LNA polar casc */
+#define R48_SMOOTH1	0x48	/* smooth test byte 1 */
+#define R49_SMOOTH2	0x49	/* smooth test byte 2 */
+#define R4A_SMOOTH3	0x4a	/* smooth test byte 3 */
+#define R4B_XTALOSC1	0x4b
+#define R4C_XTALOSC2	0x4c
+#define R4D_XTALFLX1	0x4d
+#define R4E_XTALFLX2	0x4e
+#define R4F_XTALFLX3	0x4f
+#define R50_XTALFLX4	0x50
+#define R51_XTALFLX5	0x51
+#define R52_IRLOOP0	0x52
+#define R53_IRLOOP1	0x53
+#define R54_IRLOOP2	0x54
+#define R55_IRLOOP3	0x55
+#define R56_IRLOOP4	0x56
+#define R57_PLL_LOG	0x57
+#define R58_AGC2_UP1	0x58
+#define R59_AGC2_UP2	0x59
+#define R5A_H3H5	0x5a
+#define R5B_AGC_AUTO	0x5b
+#define R5C_AGC_DEBUG	0x5c
+
+#define TDA18250_NUM_REGS 93
+
+#define TDA18250_POWER_STANDBY 0
+#define TDA18250_POWER_NORMAL 1
+
+#define TDA18250_IRQ_CAL     0x81
+#define TDA18250_IRQ_HW_INIT 0x82
+#define TDA18250_IRQ_TUNE    0x88
+
+struct tda18250_dev {
+	struct mutex i2c_mutex;
+	struct dvb_frontend *fe;
+	struct i2c_adapter *i2c;
+	struct regmap *regmap;
+	u8 xtal_freq;
+	/* IF in kHz */
+	u16 if_dvbt_6;
+	u16 if_dvbt_7;
+	u16 if_dvbt_8;
+	u16 if_dvbc_6;
+	u16 if_dvbc_8;
+	u16 if_atsc;
+	u16 if_frequency;
+	bool slave;
+	bool loopthrough;
+	bool warm;
+	u8 regs[TDA18250_NUM_REGS];
+};
+
+#endif
diff --git a/drivers/media/tuners/tda18271.h b/drivers/media/tuners/tda18271.h
index 0a84633..7e07966 100644
--- a/drivers/media/tuners/tda18271.h
+++ b/drivers/media/tuners/tda18271.h
@@ -22,7 +22,7 @@
 #define __TDA18271_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 struct tda18271_std_map_item {
 	u16 if_freq;
diff --git a/drivers/media/tuners/tda827x.h b/drivers/media/tuners/tda827x.h
index abf2e2f..a08d3f9 100644
--- a/drivers/media/tuners/tda827x.h
+++ b/drivers/media/tuners/tda827x.h
@@ -25,7 +25,7 @@
 #define __DVB_TDA827X_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda8290.h"
 
 struct tda827x_config
@@ -36,7 +36,7 @@ struct tda827x_config
 
 	/* interface to tda829x driver */
 	enum tda8290_lna config;
-	int 	     switch_addr;
+	int	     switch_addr;
 
 	void (*agcf)(struct dvb_frontend *fe);
 };
diff --git a/drivers/media/tuners/tda8290.c b/drivers/media/tuners/tda8290.c
index a59c567..9f1f1d2 100644
--- a/drivers/media/tuners/tda8290.c
+++ b/drivers/media/tuners/tda8290.c
@@ -63,8 +63,8 @@ static int tda8290_i2c_bridge(struct dvb_frontend *fe, int close)
 {
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 
-	unsigned char  enable[2] = { 0x21, 0xC0 };
-	unsigned char disable[2] = { 0x21, 0x00 };
+	static unsigned char  enable[2] = { 0x21, 0xC0 };
+	static unsigned char disable[2] = { 0x21, 0x00 };
 	unsigned char *msg;
 
 	if (close) {
@@ -84,9 +84,9 @@ static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close)
 {
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 
-	unsigned char  enable[2] = { 0x45, 0xc1 };
-	unsigned char disable[2] = { 0x46, 0x00 };
-	unsigned char buf[3] = { 0x45, 0x01, 0x00 };
+	static unsigned char  enable[2] = { 0x45, 0xc1 };
+	static unsigned char disable[2] = { 0x46, 0x00 };
+	static unsigned char buf[3] = { 0x45, 0x01, 0x00 };
 	unsigned char *msg;
 
 	if (close) {
@@ -178,25 +178,25 @@ static void tda8290_set_params(struct dvb_frontend *fe,
 {
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 
-	unsigned char soft_reset[]  = { 0x00, 0x00 };
+	static unsigned char soft_reset[]  = { 0x00, 0x00 };
 	unsigned char easy_mode[]   = { 0x01, priv->tda8290_easy_mode };
-	unsigned char expert_mode[] = { 0x01, 0x80 };
-	unsigned char agc_out_on[]  = { 0x02, 0x00 };
-	unsigned char gainset_off[] = { 0x28, 0x14 };
-	unsigned char if_agc_spd[]  = { 0x0f, 0x88 };
-	unsigned char adc_head_6[]  = { 0x05, 0x04 };
-	unsigned char adc_head_9[]  = { 0x05, 0x02 };
-	unsigned char adc_head_12[] = { 0x05, 0x01 };
-	unsigned char pll_bw_nom[]  = { 0x0d, 0x47 };
-	unsigned char pll_bw_low[]  = { 0x0d, 0x27 };
-	unsigned char gainset_2[]   = { 0x28, 0x64 };
-	unsigned char agc_rst_on[]  = { 0x0e, 0x0b };
-	unsigned char agc_rst_off[] = { 0x0e, 0x09 };
-	unsigned char if_agc_set[]  = { 0x0f, 0x81 };
-	unsigned char addr_adc_sat  = 0x1a;
-	unsigned char addr_agc_stat = 0x1d;
-	unsigned char addr_pll_stat = 0x1b;
-	unsigned char adc_sat, agc_stat,
+	static unsigned char expert_mode[] = { 0x01, 0x80 };
+	static unsigned char agc_out_on[]  = { 0x02, 0x00 };
+	static unsigned char gainset_off[] = { 0x28, 0x14 };
+	static unsigned char if_agc_spd[]  = { 0x0f, 0x88 };
+	static unsigned char adc_head_6[]  = { 0x05, 0x04 };
+	static unsigned char adc_head_9[]  = { 0x05, 0x02 };
+	static unsigned char adc_head_12[] = { 0x05, 0x01 };
+	static unsigned char pll_bw_nom[]  = { 0x0d, 0x47 };
+	static unsigned char pll_bw_low[]  = { 0x0d, 0x27 };
+	static unsigned char gainset_2[]   = { 0x28, 0x64 };
+	static unsigned char agc_rst_on[]  = { 0x0e, 0x0b };
+	static unsigned char agc_rst_off[] = { 0x0e, 0x09 };
+	static unsigned char if_agc_set[]  = { 0x0f, 0x81 };
+	static unsigned char addr_adc_sat  = 0x1a;
+	static unsigned char addr_agc_stat = 0x1d;
+	static unsigned char addr_pll_stat = 0x1b;
+	static unsigned char adc_sat = 0, agc_stat = 0,
 		      pll_stat;
 	int i;
 
@@ -468,9 +468,9 @@ static void tda8290_standby(struct dvb_frontend *fe)
 {
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 
-	unsigned char cb1[] = { 0x30, 0xD0 };
-	unsigned char tda8290_standby[] = { 0x00, 0x02 };
-	unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
+	static unsigned char cb1[] = { 0x30, 0xD0 };
+	static unsigned char tda8290_standby[] = { 0x00, 0x02 };
+	static unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
 	struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
 
 	if (fe->ops.analog_ops.i2c_gate_ctrl)
@@ -495,9 +495,9 @@ static void tda8290_init_if(struct dvb_frontend *fe)
 {
 	struct tda8290_priv *priv = fe->analog_demod_priv;
 
-	unsigned char set_VS[] = { 0x30, 0x6F };
-	unsigned char set_GP00_CF[] = { 0x20, 0x01 };
-	unsigned char set_GP01_CF[] = { 0x20, 0x0B };
+	static unsigned char set_VS[] = { 0x30, 0x6F };
+	static unsigned char set_GP00_CF[] = { 0x20, 0x01 };
+	static unsigned char set_GP01_CF[] = { 0x20, 0x0B };
 
 	if ((priv->cfg.config == TDA8290_LNA_GP0_HIGH_ON) ||
 	    (priv->cfg.config == TDA8290_LNA_GP0_HIGH_OFF))
@@ -539,10 +539,12 @@ static void tda8295_init_if(struct dvb_frontend *fe)
 static void tda8290_init_tuner(struct dvb_frontend *fe)
 {
 	struct tda8290_priv *priv = fe->analog_demod_priv;
-	unsigned char tda8275_init[]  = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
-					  0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
-	unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
-					  0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
+	static unsigned char tda8275_init[]  =
+		{ 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
+		  0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
+	static unsigned char tda8275a_init[] =
+		 { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
+		   0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
 	struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0,
 			      .buf=tda8275_init, .len = 14};
 	if (priv->ver & TDA8275A)
@@ -834,11 +836,11 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
 		.addr = i2c_addr,
 	};
 
-	unsigned char soft_reset[]   = { 0x00, 0x00 };
-	unsigned char easy_mode_b[]  = { 0x01, 0x02 };
-	unsigned char easy_mode_g[]  = { 0x01, 0x04 };
-	unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 };
-	unsigned char addr_dto_lsb = 0x07;
+	static unsigned char soft_reset[]   = { 0x00, 0x00 };
+	static unsigned char easy_mode_b[]  = { 0x01, 0x02 };
+	static unsigned char easy_mode_g[]  = { 0x01, 0x04 };
+	static unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 };
+	static unsigned char addr_dto_lsb = 0x07;
 	unsigned char data;
 #define PROBE_BUFFER_SIZE 8
 	unsigned char buf[PROBE_BUFFER_SIZE];
diff --git a/drivers/media/tuners/tda8290.h b/drivers/media/tuners/tda8290.h
index 901b8ca..5db79f1 100644
--- a/drivers/media/tuners/tda8290.h
+++ b/drivers/media/tuners/tda8290.h
@@ -18,7 +18,7 @@
 #define __TDA8290_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "tda18271.h"
 
 enum tda8290_lna {
diff --git a/drivers/media/tuners/tda9887.c b/drivers/media/tuners/tda9887.c
index c0e815f..9777da0 100644
--- a/drivers/media/tuners/tda9887.c
+++ b/drivers/media/tuners/tda9887.c
@@ -31,7 +31,7 @@ struct tda9887_priv {
 	struct tuner_i2c_props i2c_props;
 	struct list_head hybrid_tuner_instance_list;
 
-	unsigned char 	   data[4];
+	unsigned char	   data[4];
 	unsigned int       config;
 	unsigned int       mode;
 	unsigned int       audmode;
@@ -94,7 +94,7 @@ struct tvnorm {
 #define cAudioGain6             0x80    // bit c7
 
 #define cTopMask                0x1f    // bit c0:4
-#define cTopDefault		0x10 	// bit c0:4
+#define cTopDefault		0x10	// bit c0:4
 
 //// third reg (e)
 #define cAudioIF_4_5             0x00    // bit e0:1
diff --git a/drivers/media/tuners/tda9887.h b/drivers/media/tuners/tda9887.h
index 95070ec..2a143f8 100644
--- a/drivers/media/tuners/tda9887.h
+++ b/drivers/media/tuners/tda9887.h
@@ -18,7 +18,7 @@
 #define __TDA9887_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /* ------------------------------------------------------------------------ */
 #if IS_REACHABLE(CONFIG_MEDIA_TUNER_TDA9887)
diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c
index a9b1bb1..88b3e80 100644
--- a/drivers/media/tuners/tea5761.c
+++ b/drivers/media/tuners/tea5761.c
@@ -1,11 +1,8 @@
-/*
- * For Philips TEA5761 FM Chip
- * I2C address is allways 0x20 (0x10 at 7-bit mode).
- *
- * Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNUv2 General Public License
- *
- */
+// SPDX-License-Identifier: GPL-2.0
+// For Philips TEA5761 FM Chip
+// I2C address is always 0x20 (0x10 at 7-bit mode).
+//
+// Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org)
 
 #include <linux/i2c.h>
 #include <linux/slab.h>
@@ -341,4 +338,4 @@ EXPORT_SYMBOL_GPL(tea5761_autodetection);
 
 MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver");
 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/tuners/tea5761.h b/drivers/media/tuners/tea5761.h
index 2d624d9..4bcf835 100644
--- a/drivers/media/tuners/tea5761.h
+++ b/drivers/media/tuners/tea5761.h
@@ -18,7 +18,7 @@
 #define __TEA5761_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #if IS_REACHABLE(CONFIG_MEDIA_TUNER_TEA5761)
 extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
diff --git a/drivers/media/tuners/tea5767.c b/drivers/media/tuners/tea5767.c
index 525b7ab..2b2c064 100644
--- a/drivers/media/tuners/tea5767.c
+++ b/drivers/media/tuners/tea5767.c
@@ -1,14 +1,11 @@
-/*
- * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
- * I2C address is allways 0xC0.
- *
- *
- * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License
- *
- * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
- * from their contributions on DScaler.
- */
+// SPDX-License-Identifier: GPL-2.0
+// For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
+// I2C address is always 0xC0.
+//
+// Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
+//
+// tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
+// from their contributions on DScaler.
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -473,4 +470,4 @@ EXPORT_SYMBOL_GPL(tea5767_autodetection);
 
 MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver");
 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/tuners/tea5767.h b/drivers/media/tuners/tea5767.h
index 4f6f6c9..216a319 100644
--- a/drivers/media/tuners/tea5767.h
+++ b/drivers/media/tuners/tea5767.h
@@ -18,7 +18,7 @@
 #define __TEA5767_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 enum tea5767_xtal {
 	TEA5767_LOW_LO_32768    = 0,
diff --git a/drivers/media/tuners/tua9001.h b/drivers/media/tuners/tua9001.h
index 7b05481..4df2c16 100644
--- a/drivers/media/tuners/tua9001.h
+++ b/drivers/media/tuners/tua9001.h
@@ -17,7 +17,7 @@
 #ifndef TUA9001_H
 #define TUA9001_H
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /*
  * I2C address
diff --git a/drivers/media/tuners/tuner-i2c.h b/drivers/media/tuners/tuner-i2c.h
index bda67a5..56dc233 100644
--- a/drivers/media/tuners/tuner-i2c.h
+++ b/drivers/media/tuners/tuner-i2c.h
@@ -75,7 +75,7 @@ static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props,
  *
  * state structure must contain the following:
  *
- * 	struct list_head	hybrid_tuner_instance_list;
+ *	struct list_head	hybrid_tuner_instance_list;
  *	struct tuner_i2c_props	i2c_props;
  *
  * hybrid_tuner_instance_list (both within state structure and globally)
diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c
index cf44d36..36b88f8 100644
--- a/drivers/media/tuners/tuner-simple.c
+++ b/drivers/media/tuners/tuner-simple.c
@@ -53,7 +53,7 @@ MODULE_PARM_DESC(dtv_input, "specify dtv rf input, 0 for autoselect");
 /* tv tuner system standard selection for Philips FQ1216ME
    this value takes the low bits of control byte 2
    from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
-     standard 		BG	DK	I	L	L`
+     standard		BG	DK	I	L	L`
      picture carrier	38.90	38.90	38.90	38.90	33.95
      colour		34.47	34.47	34.47	34.47	38.38
      sound 1		33.40	32.40	32.90	32.40	40.45
diff --git a/drivers/media/tuners/tuner-simple.h b/drivers/media/tuners/tuner-simple.h
index 6399b45..fd71b34 100644
--- a/drivers/media/tuners/tuner-simple.h
+++ b/drivers/media/tuners/tuner-simple.h
@@ -18,7 +18,7 @@
 #define __TUNER_SIMPLE_H__
 
 #include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #if IS_REACHABLE(CONFIG_MEDIA_TUNER_SIMPLE)
 extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/tuners/tuner-xc2028-types.h b/drivers/media/tuners/tuner-xc2028-types.h
index 7e47987..bb0437c 100644
--- a/drivers/media/tuners/tuner-xc2028-types.h
+++ b/drivers/media/tuners/tuner-xc2028-types.h
@@ -1,10 +1,11 @@
-/* tuner-xc2028_types
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * tuner-xc2028_types
  *
  * This file includes internal tipes to be used inside tuner-xc2028.
  * Shouldn't be included outside tuner-xc2028
  *
  * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
  */
 
 /* xc3028 firmware types */
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
index b5b62b0..fca85e0 100644
--- a/drivers/media/tuners/tuner-xc2028.c
+++ b/drivers/media/tuners/tuner-xc2028.c
@@ -1,12 +1,10 @@
-/* tuner-xc2028
- *
- * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
- *
- * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
- *       - frontend interface
- *
- * This code is placed under the terms of the GNU General Public License v2
- */
+// SPDX-License-Identifier: GPL-2.0
+// tuner-xc2028
+//
+// Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
+//
+// Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
+//       - frontend interface
 
 #include <linux/i2c.h>
 #include <asm/div64.h>
@@ -22,7 +20,7 @@
 #include "tuner-xc2028-types.h"
 
 #include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 /* Max transfer size done by I2C transfer functions */
 #define MAX_XFER_SIZE  80
@@ -89,7 +87,7 @@ struct firmware_properties {
 	v4l2_std_id	std_req;
 	__u16		int_freq;
 	unsigned int	scode_table;
-	int 		scode_nr;
+	int		scode_nr;
 };
 
 enum xc2028_state {
@@ -139,7 +137,7 @@ struct xc2028_data {
 				       ibuf, isize);			\
 	if (isize != _rc)						\
 		tuner_err("i2c input error: rc = %d (should be %d)\n",	\
-			   _rc, (int)isize); 				\
+			   _rc, (int)isize);				\
 	if (priv->ctrl.msleep)						\
 		msleep(priv->ctrl.msleep);				\
 	_rc;								\
@@ -174,7 +172,7 @@ static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val)
 	return 0;
 }
 
-#define dump_firm_type(t) 	dump_firm_type_and_int_freq(t, 0)
+#define dump_firm_type(t)	dump_firm_type_and_int_freq(t, 0)
 static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
 {
 	if (type & BASE)
@@ -1521,6 +1519,6 @@ EXPORT_SYMBOL(xc2028_attach);
 MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
 MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE);
 MODULE_FIRMWARE(XC3028L_DEFAULT_FIRMWARE);
diff --git a/drivers/media/tuners/tuner-xc2028.h b/drivers/media/tuners/tuner-xc2028.h
index 98e4eff..03fd6d4 100644
--- a/drivers/media/tuners/tuner-xc2028.h
+++ b/drivers/media/tuners/tuner-xc2028.h
@@ -1,13 +1,14 @@
-/* tuner-xc2028
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * tuner-xc2028
  *
  * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
  */
 
 #ifndef __TUNER_XC2028_H__
 #define __TUNER_XC2028_H__
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw"
 #define XC3028L_DEFAULT_FIRMWARE "xc3028L-v36.fw"
@@ -47,7 +48,7 @@ struct xc2028_ctrl {
 
 struct xc2028_config {
 	struct i2c_adapter *i2c_adap;
-	u8 		   i2c_addr;
+	u8		   i2c_addr;
 	struct xc2028_ctrl *ctrl;
 };
 
diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
index e30948e..f0fa8da 100644
--- a/drivers/media/tuners/xc4000.c
+++ b/drivers/media/tuners/xc4000.c
@@ -27,7 +27,7 @@
 #include <linux/mutex.h>
 #include <asm/unaligned.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "xc4000.h"
 #include "tuner-i2c.h"
@@ -1036,7 +1036,10 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type,
 		dprintk(1, "load scode failed %d\n", rc);
 
 check_device:
-	rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
+	if (xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel) < 0) {
+		printk(KERN_ERR "Unable to read tuner registers.\n");
+		goto fail;
+	}
 
 	if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
 			   &fw_minor) != 0) {
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 0e7e4fd..f7a8d05d 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -25,7 +25,7 @@
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "xc5000.h"
 #include "tuner-i2c.h"
@@ -685,8 +685,8 @@ static void xc_debug_dump(struct xc5000_priv *priv)
 		(totalgain % 256) * 100 / 256);
 
 	if (priv->pll_register_no) {
-		xc5000_readreg(priv, priv->pll_register_no, &regval);
-		dprintk(1, "*** PLL lock status = 0x%04x\n", regval);
+		if (!xc5000_readreg(priv, priv->pll_register_no, &regval))
+			dprintk(1, "*** PLL lock status = 0x%04x\n", regval);
 	}
 }
 
@@ -831,15 +831,16 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
 	u16 id;
 
 	ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
-	if (ret == 0) {
+	if (!ret) {
 		if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
 			ret = -ENOENT;
 		else
 			ret = 0;
+		dprintk(1, "%s() returns id = 0x%x\n", __func__, id);
+	} else {
+		dprintk(1, "%s() returns error %d\n", __func__, ret);
 	}
 
-	dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
-		ret == 0 ? "True" : "False", id);
 	return ret;
 }
 
@@ -935,7 +936,10 @@ static int xc5000_set_tv_freq(struct dvb_frontend *fe)
 
 	if (priv->pll_register_no != 0) {
 		msleep(20);
-		xc5000_readreg(priv, priv->pll_register_no, &pll_lock_status);
+		ret = xc5000_readreg(priv, priv->pll_register_no,
+				     &pll_lock_status);
+		if (ret)
+			return ret;
 		if (pll_lock_status > 63) {
 			/* PLL is unlocked, force reload of the firmware */
 			dprintk(1, "xc5000: PLL not locked (0x%x).  Reloading...\n",
@@ -1190,8 +1194,10 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
 		}
 
 		if (priv->pll_register_no) {
-			xc5000_readreg(priv, priv->pll_register_no,
-				       &pll_lock_status);
+			ret = xc5000_readreg(priv, priv->pll_register_no,
+					     &pll_lock_status);
+			if (ret)
+				continue;
 			if (pll_lock_status > 63) {
 				/* PLL is unlocked, force reload of the firmware */
 				printk(KERN_ERR
diff --git a/drivers/media/usb/as102/Makefile b/drivers/media/usb/as102/Makefile
index 56bd2d0..b0b3196 100644
--- a/drivers/media/usb/as102/Makefile
+++ b/drivers/media/usb/as102/Makefile
@@ -4,5 +4,4 @@
 
 obj-$(CONFIG_DVB_AS102) += dvb-as102.o
 
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/as102/as102_drv.c b/drivers/media/usb/as102/as102_drv.c
index 9dd7c7c..48b0c4e 100644
--- a/drivers/media/usb/as102/as102_drv.c
+++ b/drivers/media/usb/as102/as102_drv.c
@@ -27,7 +27,7 @@
 #include "as10x_cmd.h"
 #include "as102_fe.h"
 #include "as102_fw.h"
-#include "dvbdev.h"
+#include <media/dvbdev.h>
 
 int dual_tuner;
 module_param_named(dual_tuner, dual_tuner, int, 0644);
diff --git a/drivers/media/usb/as102/as102_drv.h b/drivers/media/usb/as102/as102_drv.h
index 8def19d..c92a1e4 100644
--- a/drivers/media/usb/as102/as102_drv.h
+++ b/drivers/media/usb/as102/as102_drv.h
@@ -16,9 +16,9 @@
 #ifndef _AS102_DRV_H
 #define _AS102_DRV_H
 #include <linux/usb.h>
-#include <dvb_demux.h>
-#include <dvb_frontend.h>
-#include <dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dmxdev.h>
 #include "as10x_handle.h"
 #include "as10x_cmd.h"
 #include "as102_usb_drv.h"
diff --git a/drivers/media/usb/as102/as10x_cmd_cfg.c b/drivers/media/usb/as102/as10x_cmd_cfg.c
index c87f2ca..fabbfead 100644
--- a/drivers/media/usb/as102/as10x_cmd_cfg.c
+++ b/drivers/media/usb/as102/as10x_cmd_cfg.c
@@ -133,9 +133,9 @@ int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap, uint16_t tag,
  * as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x
  * @adap:      pointer to AS10x bus adapter
  * @mode:      mode selected:
- *	        - ON    : 0x0 => eLNA always ON
- *	        - OFF   : 0x1 => eLNA always OFF
- *	        - AUTO  : 0x2 => eLNA follow hysteresis parameters
+ *		- ON    : 0x0 => eLNA always ON
+ *		- OFF   : 0x1 => eLNA always OFF
+ *		- AUTO  : 0x2 => eLNA follow hysteresis parameters
  *				 to be ON or OFF
  *
  * Return 0 on success or negative value in case of error.
diff --git a/drivers/media/usb/au0828/Makefile b/drivers/media/usb/au0828/Makefile
index c06ef66..5691881 100644
--- a/drivers/media/usb/au0828/Makefile
+++ b/drivers/media/usb/au0828/Makefile
@@ -12,7 +12,6 @@
 obj-$(CONFIG_VIDEO_AU0828) += au0828.o
 
 ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 
 ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/usb/au0828/au0828-cards.h b/drivers/media/usb/au0828/au0828-cards.h
index 1f4412e..dbd8a90 100644
--- a/drivers/media/usb/au0828/au0828-cards.h
+++ b/drivers/media/usb/au0828/au0828-cards.h
@@ -17,7 +17,7 @@
 
 #define AU0828_BOARD_UNKNOWN		0
 #define AU0828_BOARD_HAUPPAUGE_HVR950Q	1
-#define AU0828_BOARD_HAUPPAUGE_HVR850 	2
+#define AU0828_BOARD_HAUPPAUGE_HVR850	2
 #define AU0828_BOARD_DVICO_FUSIONHDTV7	3
 #define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL	4
 #define AU0828_BOARD_HAUPPAUGE_WOODBURY	5
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index af68afe0..832ed9f 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -1,21 +1,10 @@
-/*
-  handle au0828 IR remotes via linux kernel input layer.
-
-   Copyright (C) 2014 Mauro Carvalho Chehab <mchehab@samsung.com>
-   Copyright (c) 2014 Samsung Electronics Co., Ltd.
-
-  Based on em28xx-input.c.
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  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.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// handle au0828 IR remotes via linux kernel input layer.
+//
+// Copyright (c) 2014 Mauro Carvalho Chehab <mchehab@samsung.com>
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Based on em28xx-input.c.
 
 #include "au0828.h"
 
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index a2401538..c765d54 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -1797,7 +1797,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 static const struct video_device au0828_video_template = {
 	.fops                       = &au0828_v4l_fops,
 	.release                    = video_device_release_empty,
-	.ioctl_ops 		    = &video_ioctl_ops,
+	.ioctl_ops		    = &video_ioctl_ops,
 	.tvnorms                    = V4L2_STD_NTSC_M | V4L2_STD_PAL_M,
 };
 
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index f6f37e8e..004eade 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -33,12 +33,12 @@
 #include <media/media-device.h>
 
 /* DVB */
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
 
 #include "au0828-reg.h"
 #include "au0828-cards.h"
@@ -190,7 +190,7 @@ struct au0828_dev {
 	struct i2c_adapter		i2c_adap;
 	struct i2c_algorithm		i2c_algo;
 	struct i2c_client		i2c_client;
-	u32 				i2c_rc;
+	u32				i2c_rc;
 
 	/* Digital */
 	struct au0828_dvb		dvb;
@@ -293,8 +293,8 @@ struct au0828_dev {
 /* ----------------------------------------------------------- */
 #define au0828_read(dev, reg) au0828_readreg(dev, reg)
 #define au0828_write(dev, reg, value) au0828_writereg(dev, reg, value)
-#define au0828_andor(dev, reg, mask, value) 				\
-	 au0828_writereg(dev, reg, 					\
+#define au0828_andor(dev, reg, mask, value)				\
+	 au0828_writereg(dev, reg,					\
 	(au0828_readreg(dev, reg) & ~(mask)) | ((value) & (mask)))
 
 #define au0828_set(dev, reg, bit) au0828_andor(dev, (reg), (bit), (bit))
diff --git a/drivers/media/usb/b2c2/Makefile b/drivers/media/usb/b2c2/Makefile
index 2778c19..f3cef05 100644
--- a/drivers/media/usb/b2c2/Makefile
+++ b/drivers/media/usb/b2c2/Makefile
@@ -1,5 +1,4 @@
 b2c2-flexcop-usb-objs := flexcop-usb.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
 
-ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/common/b2c2/
diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c
index 6089036..f3a1e5b 100644
--- a/drivers/media/usb/cpia2/cpia2_usb.c
+++ b/drivers/media/usb/cpia2/cpia2_usb.c
@@ -33,13 +33,13 @@
 
 static int frame_sizes[] = {
 	0,	// USBIF_CMDONLY
-	0, 	// USBIF_BULK
-	128, 	// USBIF_ISO_1
-	384, 	// USBIF_ISO_2
-	640, 	// USBIF_ISO_3
-	768, 	// USBIF_ISO_4
-	896, 	// USBIF_ISO_5
-	1023, 	// USBIF_ISO_6
+	0,	// USBIF_BULK
+	128,	// USBIF_ISO_1
+	384,	// USBIF_ISO_2
+	640,	// USBIF_ISO_3
+	768,	// USBIF_ISO_4
+	896,	// USBIF_ISO_5
+	1023,	// USBIF_ISO_6
 };
 
 #define FRAMES_PER_DESC    10
diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c
index 74c9756..99f106b1 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -808,7 +808,7 @@ static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
 	struct camera_data *cam = video_drvdata(file);
 
 	if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
-	   buf->index > cam->num_frames)
+	   buf->index >= cam->num_frames)
 		return -EINVAL;
 
 	buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
@@ -859,7 +859,7 @@ static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
 
 	if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
 	   buf->memory != V4L2_MEMORY_MMAP ||
-	   buf->index > cam->num_frames)
+	   buf->index >= cam->num_frames)
 		return -EINVAL;
 
 	DBG("QBUF #%d\n", buf->index);
diff --git a/drivers/media/usb/cx231xx/Makefile b/drivers/media/usb/cx231xx/Makefile
index 19e8c35..c023d97 100644
--- a/drivers/media/usb/cx231xx/Makefile
+++ b/drivers/media/usb/cx231xx/Makefile
@@ -9,8 +9,6 @@
 obj-$(CONFIG_VIDEO_CX231XX_ALSA) += cx231xx-alsa.o
 obj-$(CONFIG_VIDEO_CX231XX_DVB) += cx231xx-dvb.o
 
-ccflags-y += -Idrivers/media/i2c
 ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
 ccflags-y += -Idrivers/media/usb/dvb-usb
diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c
index 06f10d7..d96236d 100644
--- a/drivers/media/usb/cx231xx/cx231xx-audio.c
+++ b/drivers/media/usb/cx231xx/cx231xx-audio.c
@@ -404,9 +404,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
 }
 
 static const struct snd_pcm_hardware snd_cx231xx_hw_capture = {
-	.info = SNDRV_PCM_INFO_BLOCK_TRANSFER 	|
-	    SNDRV_PCM_INFO_MMAP 		|
-	    SNDRV_PCM_INFO_INTERLEAVED 		|
+	.info = SNDRV_PCM_INFO_BLOCK_TRANSFER	|
+	    SNDRV_PCM_INFO_MMAP			|
+	    SNDRV_PCM_INFO_INTERLEAVED		|
 	    SNDRV_PCM_INFO_MMAP_VALID,
 
 	.formats = SNDRV_PCM_FMTBIT_S16_LE,
diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c
index 2f52d66..fdd3c22 100644
--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c
@@ -105,7 +105,7 @@ void uninitGPIO(struct cx231xx *dev)
 
 /******************************************************************************
  *                    A F E - B L O C K    C O N T R O L   functions          *
- * 				[ANALOG FRONT END]			      *
+ *				[ANALOG FRONT END]			      *
  ******************************************************************************/
 static int afe_write_byte(struct cx231xx *dev, u16 saddr, u8 data)
 {
@@ -2168,7 +2168,7 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev)
 }
 
 /******************************************************************************
- *        	    I 2 S - B L O C K    C O N T R O L   functions            *
+ *		    I 2 S - B L O C K    C O N T R O L   functions            *
  ******************************************************************************/
 int cx231xx_i2s_blk_initialize(struct cx231xx *dev)
 {
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 54d9d0c..f9ec7fe 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -31,7 +31,7 @@
 #include <media/v4l2-common.h>
 
 #include <media/drv-intf/cx25840.h>
-#include "dvb-usb-ids.h"
+#include <media/dvb-usb-ids.h>
 #include "xc5000.h"
 #include "tda18271.h"
 
@@ -896,6 +896,32 @@ struct cx231xx_board cx231xx_boards[] = {
 			},
 		},
 	},
+	[CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO] = {
+		.name = "The Imaging Source DFG/USB2pro",
+		.tuner_type = TUNER_ABSENT,
+		.decoder = CX231XX_AVDECODER,
+		.output_mode = OUT_MODE_VIP11,
+		.demod_xfer_mode = 0,
+		.ctl_pin_status_mask = 0xFFFFFFC4,
+		.agc_analog_digital_select_gpio = 0x0c,
+		.gpio_pin_status_mask = 0x4001000,
+		.norm = V4L2_STD_PAL,
+		.no_alt_vanc = 1,
+		.external_av = 1,
+		.input = {{
+			.type = CX231XX_VMUX_COMPOSITE1,
+			.vmux = CX231XX_VIN_1_1,
+			.amux = CX231XX_AMUX_LINE_IN,
+			.gpio = NULL,
+		}, {
+			.type = CX231XX_VMUX_SVIDEO,
+			.vmux = CX231XX_VIN_2_1 |
+				(CX231XX_VIN_2_2 << 8) |
+				CX25840_SVIDEO_ON,
+			.amux = CX231XX_AMUX_LINE_IN,
+			.gpio = NULL,
+		} },
+	},
 };
 const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
 
@@ -967,6 +993,8 @@ struct usb_device_id cx231xx_id_table[] = {
 	.driver_info = CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD},
 	{USB_DEVICE(0x15f4, 0x0135),
 	.driver_info = CX231XX_BOARD_ASTROMETA_T2HYBRID},
+	{USB_DEVICE(0x199e, 0x8002),
+	 .driver_info = CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO},
 	{},
 };
 
diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c
index f372ad3..4f43668 100644
--- a/drivers/media/usb/cx231xx/cx231xx-core.c
+++ b/drivers/media/usb/cx231xx/cx231xx-core.c
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
 			 dev->name, __func__ , ##arg); } while (0)
 
 /*****************************************************************
-*             Device control list functions     				 *
+*             Device control list functions					 *
 ******************************************************************/
 
 LIST_HEAD(cx231xx_devlist);
diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c
index 54abc1a..fb56540 100644
--- a/drivers/media/usb/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c
@@ -762,8 +762,8 @@ static int dvb_init(struct cx231xx *dev)
 		/* attach demod */
 		memset(&si2165_pdata, 0, sizeof(si2165_pdata));
 		si2165_pdata.fe = &dev->dvb->frontend;
-		si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL,
-		si2165_pdata.ref_freq_Hz = 16000000,
+		si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL;
+		si2165_pdata.ref_freq_hz = 16000000;
 
 		memset(&info, 0, sizeof(struct i2c_board_info));
 		strlcpy(info.type, "si2165", I2C_NAME_SIZE);
@@ -809,8 +809,8 @@ static int dvb_init(struct cx231xx *dev)
 		/* attach demod */
 		memset(&si2165_pdata, 0, sizeof(si2165_pdata));
 		si2165_pdata.fe = &dev->dvb->frontend;
-		si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT,
-		si2165_pdata.ref_freq_Hz = 24000000,
+		si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT;
+		si2165_pdata.ref_freq_hz = 24000000;
 
 		memset(&info, 0, sizeof(struct i2c_board_info));
 		strlcpy(info.type, "si2165", I2C_NAME_SIZE);
diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c
index 23648da..6e1bef2 100644
--- a/drivers/media/usb/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c
@@ -51,7 +51,7 @@ do {							\
 	if (i2c_debug >= lvl) {				\
 		printk(KERN_DEBUG "%s at %s: " fmt,	\
 		       dev->name, __func__ , ##args);	\
-      } 						\
+      }							\
 } while (0)
 
 static inline int get_real_i2c_port(struct cx231xx *dev, int bus_nr)
diff --git a/drivers/media/usb/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c
index 02ebeb1..3e9b73a 100644
--- a/drivers/media/usb/cx231xx/cx231xx-input.c
+++ b/drivers/media/usb/cx231xx/cx231xx-input.c
@@ -1,22 +1,12 @@
-/*
- *   cx231xx IR glue driver
- *
- *   Copyright (C) 2010 Mauro Carvalho Chehab
- *
- *   Polaris (cx231xx) has its support for IR's with a design close to MCE.
- *   however, a few designs are using an external I2C chip for IR, instead
- *   of using the one provided by the chip.
- *   This driver provides support for those extra devices
- *
- *   This program is free software; 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// cx231xx IR glue driver
+//
+// Copyright (c) 2010 Mauro Carvalho Chehab <mchehab@kernel.org>
+//
+// Polaris (cx231xx) has its support for IR's with a design close to MCE.
+// however, a few designs are using an external I2C chip for IR, instead
+// of using the one provided by the chip.
+// This driver provides support for those extra devices
 
 #include "cx231xx.h"
 #include <linux/slab.h>
diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
index 4511dc5..8f00b1d 100644
--- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
+++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
@@ -144,7 +144,7 @@ enum AVDEC_STATUS{
 #define SOURCE_EXTERNAL         0x8
 #define SOURCE_TS_BDA			0x10
 #define SOURCE_TS_ENCODE		0x20
-#define SOURCE_TS_EXTERNAL   	0x40
+#define SOURCE_TS_EXTERNAL	0x40
 
 /***************************************************************************
 				* interface information define *
diff --git a/drivers/media/usb/cx231xx/cx231xx-reg.h b/drivers/media/usb/cx231xx/cx231xx-reg.h
index 750c5d3..db5af8d 100644
--- a/drivers/media/usb/cx231xx/cx231xx-reg.h
+++ b/drivers/media/usb/cx231xx/cx231xx-reg.h
@@ -1433,16 +1433,16 @@
 #define      FLD_AC97_SHUTDOWN        0x00000001
 
 /* Cx231xx redefine */
-#define      QPSK_IAGC_CTL1  		0x94c
-#define      QPSK_IAGC_CTL2  		0x950
-#define      QPSK_FEPR_FREQ  		0x954
-#define      QPSK_BTL_CTL1  		0x958
-#define      QPSK_BTL_CTL2  		0x95c
-#define      QPSK_CTL_CTL1  		0x960
-#define      QPSK_CTL_CTL2  		0x964
-#define      QPSK_MF_FAGC_CTL 		0x968
-#define      QPSK_EQ_CTL  		0x96c
-#define      QPSK_LOCK_CTL  		0x970
+#define      QPSK_IAGC_CTL1		0x94c
+#define      QPSK_IAGC_CTL2		0x950
+#define      QPSK_FEPR_FREQ		0x954
+#define      QPSK_BTL_CTL1		0x958
+#define      QPSK_BTL_CTL2		0x95c
+#define      QPSK_CTL_CTL1		0x960
+#define      QPSK_CTL_CTL2		0x964
+#define      QPSK_MF_FAGC_CTL		0x968
+#define      QPSK_EQ_CTL		0x96c
+#define      QPSK_LOCK_CTL		0x970
 
 /*****************************************************************************/
 #define      FM1_DFT_CTL              0x9a8
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index d7b2e69..271f352 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -39,7 +39,7 @@
 #include <media/drv-intf/msp3400.h>
 #include <media/tuner.h>
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 
 #include "cx231xx-vbi.h"
 
@@ -1756,6 +1756,8 @@ static int cx231xx_v4l2_open(struct file *filp)
 	case VFL_TYPE_RADIO:
 		radio = 1;
 		break;
+	default:
+		return -EINVAL;
 	}
 
 	cx231xx_videodbg("open dev=%s type=%s users=%d\n",
diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h
index 72d5937..65b039c 100644
--- a/drivers/media/usb/cx231xx/cx231xx.h
+++ b/drivers/media/usb/cx231xx/cx231xx.h
@@ -80,6 +80,7 @@
 #define CX231XX_BOARD_TERRATEC_GRABBY 22
 #define CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD 23
 #define CX231XX_BOARD_ASTROMETA_T2HYBRID 24
+#define CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO 25
 
 /* Limits minimum and default number of buffers */
 #define CX231XX_MIN_BUF                 4
diff --git a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile
index bed4460..58c0140 100644
--- a/drivers/media/usb/dvb-usb-v2/Makefile
+++ b/drivers/media/usb/dvb-usb-v2/Makefile
@@ -44,7 +44,6 @@
 dvb-usb-zd1301-objs := zd1301.o
 obj-$(CONFIG_DVB_USB_ZD1301) += zd1301.o
 
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 ccflags-y += -I$(srctree)/drivers/media/tuners
 ccflags-y += -I$(srctree)/drivers/media/common
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.h b/drivers/media/usb/dvb-usb-v2/anysee.h
index 393e2fc..2312c55 100644
--- a/drivers/media/usb/dvb-usb-v2/anysee.h
+++ b/drivers/media/usb/dvb-usb-v2/anysee.h
@@ -32,7 +32,7 @@
 
 #define DVB_USB_LOG_PREFIX "anysee"
 #include "dvb_usb.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 
 enum cmd {
 	CMD_I2C_READ            = 0x33,
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
index 1414d59..7469263 100644
--- a/drivers/media/usb/dvb-usb-v2/az6007.c
+++ b/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -23,7 +23,7 @@
 
 #include "drxk.h"
 #include "mt2063.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 #include "dvb_usb.h"
 #include "cypress_firmware.h"
 
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
index 0005bdb..d2e8053 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
@@ -27,11 +27,11 @@
 #include <media/rc-core.h>
 #include <media/media-device.h>
 
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
-#include "dvb-usb-ids.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dmxdev.h>
+#include <media/dvb-usb-ids.h>
 
 /*
  * device file: /dev/dvb/adapter[0-1]/frontend[0-2]
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
index 131b6c0..43eb828 100644
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
@@ -309,7 +309,7 @@ static int dvbsky_s960_attach(struct dvb_usb_adapter *adap)
 	struct dvb_usb_device *d = adap_to_d(adap);
 	int ret = 0;
 	/* demod I2C adapter */
-	struct i2c_adapter *i2c_adapter;
+	struct i2c_adapter *i2c_adapter = NULL;
 	struct i2c_client *client;
 	struct i2c_board_info info;
 	struct ts2020_config ts2020_config = {};
@@ -431,7 +431,7 @@ static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap)
 	struct dvb_usb_device *d = adap_to_d(adap);
 	int ret = 0;
 	/* demod I2C adapter */
-	struct i2c_adapter *i2c_adapter;
+	struct i2c_adapter *i2c_adapter = NULL;
 	struct i2c_client *client_tuner, *client_ci;
 	struct i2c_board_info info;
 	struct sp2_config sp2_config;
@@ -661,6 +661,65 @@ static int dvbsky_t330_attach(struct dvb_usb_adapter *adap)
 	return ret;
 }
 
+static int dvbsky_mygica_t230c_attach(struct dvb_usb_adapter *adap)
+{
+	struct dvbsky_state *state = adap_to_priv(adap);
+	struct dvb_usb_device *d = adap_to_d(adap);
+	struct i2c_adapter *i2c_adapter;
+	struct i2c_client *client_demod, *client_tuner;
+	struct i2c_board_info info;
+	struct si2168_config si2168_config;
+	struct si2157_config si2157_config;
+
+	/* attach demod */
+	memset(&si2168_config, 0, sizeof(si2168_config));
+	si2168_config.i2c_adapter = &i2c_adapter;
+	si2168_config.fe = &adap->fe[0];
+	si2168_config.ts_mode = SI2168_TS_PARALLEL;
+	si2168_config.ts_clock_inv = 1;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2168", sizeof(info.type));
+	info.addr = 0x64;
+	info.platform_data = &si2168_config;
+
+	request_module("si2168");
+	client_demod = i2c_new_device(&d->i2c_adap, &info);
+	if (!client_demod || !client_demod->dev.driver)
+		goto fail_demod_device;
+	if (!try_module_get(client_demod->dev.driver->owner))
+		goto fail_demod_module;
+
+	/* attach tuner */
+	memset(&si2157_config, 0, sizeof(si2157_config));
+	si2157_config.fe = adap->fe[0];
+	si2157_config.if_port = 0;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "si2141", sizeof(info.type));
+	info.addr = 0x60;
+	info.platform_data = &si2157_config;
+
+	request_module("si2157");
+	client_tuner = i2c_new_device(i2c_adapter, &info);
+	if (!client_tuner || !client_tuner->dev.driver)
+		goto fail_tuner_device;
+	if (!try_module_get(client_tuner->dev.driver->owner))
+		goto fail_tuner_module;
+
+	state->i2c_client_demod = client_demod;
+	state->i2c_client_tuner = client_tuner;
+	return 0;
+
+fail_tuner_module:
+	i2c_unregister_device(client_tuner);
+fail_tuner_device:
+	module_put(client_demod->dev.driver->owner);
+fail_demod_module:
+	i2c_unregister_device(client_demod);
+fail_demod_device:
+	return -ENODEV;
+}
+
+
 static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
 {
 	dvbsky_gpio_ctrl(d, 0x04, 1);
@@ -826,6 +885,32 @@ static struct dvb_usb_device_properties dvbsky_t330_props = {
 	}
 };
 
+static struct dvb_usb_device_properties mygica_t230c_props = {
+	.driver_name = KBUILD_MODNAME,
+	.owner = THIS_MODULE,
+	.adapter_nr = adapter_nr,
+	.size_of_priv = sizeof(struct dvbsky_state),
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	.generic_bulk_ctrl_endpoint_response = 0x81,
+	.generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY,
+
+	.i2c_algo         = &dvbsky_i2c_algo,
+	.frontend_attach  = dvbsky_mygica_t230c_attach,
+	.init             = dvbsky_init,
+	.get_rc_config    = dvbsky_get_rc_config,
+	.streaming_ctrl   = dvbsky_streaming_ctrl,
+	.identify_state	  = dvbsky_identify_state,
+	.exit             = dvbsky_exit,
+
+	.num_adapters = 1,
+	.adapter = {
+		{
+			.stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
+		}
+	}
+};
+
 static const struct usb_device_id dvbsky_id_table[] = {
 	{ DVB_USB_DEVICE(0x0572, 0x6831,
 		&dvbsky_s960_props, "DVBSky S960/S860", RC_MAP_DVBSKY) },
@@ -858,6 +943,9 @@ static const struct usb_device_id dvbsky_id_table[] = {
 	{ 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_T230C,
+		&mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C",
+		RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
 	{ }
 };
 MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index 5e320fa..be26c02 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -494,18 +494,23 @@ static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
 
 static int lme2510_return_status(struct dvb_usb_device *d)
 {
-	int ret = 0;
+	int ret;
 	u8 *data;
 
-	data = kzalloc(10, GFP_KERNEL);
+	data = kzalloc(6, GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
 
-	ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
-			0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
-	info("Firmware Status: %x (%x)", ret , data[2]);
+	ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+			      0x06, 0x80, 0x0302, 0x00,
+			      data, 0x6, 200);
+	if (ret != 6)
+		ret = -EINVAL;
+	else
+		ret = data[2];
 
-	ret = (ret < 0) ? -ENODEV : data[2];
+	info("Firmware Status: %6ph", data);
+
 	kfree(data);
 	return ret;
 }
@@ -1071,8 +1076,6 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
 
 		if (adap->fe[0]) {
 			info("FE Found M88RS2000");
-			dvb_attach(ts2020_attach, adap->fe[0], &ts2020_config,
-					&d->i2c_adap);
 			st->i2c_tuner_gate_w = 5;
 			st->i2c_tuner_gate_r = 5;
 			st->i2c_tuner_addr = 0x60;
@@ -1138,17 +1141,18 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
 			ret = st->tuner_config;
 		break;
 	case TUNER_RS2000:
-		ret = st->tuner_config;
+		if (dvb_attach(ts2020_attach, adap->fe[0],
+			       &ts2020_config, &d->i2c_adap))
+			ret = st->tuner_config;
 		break;
 	default:
 		break;
 	}
 
-	if (ret)
+	if (ret) {
 		info("TUN Found %s tuner", tun_msg[ret]);
-	else {
-		info("TUN No tuner found --- resetting device");
-		lme_coldreset(d);
+	} else {
+		info("TUN No tuner found");
 		return -ENODEV;
 	}
 
@@ -1189,6 +1193,7 @@ static int lme2510_get_adapter_count(struct dvb_usb_device *d)
 static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
 {
 	struct lme2510_state *st = d->priv;
+	int status;
 
 	usb_reset_configuration(d->udev);
 
@@ -1197,12 +1202,16 @@ static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
 
 	st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
 
-	if (lme2510_return_status(d) == 0x44) {
+	status = lme2510_return_status(d);
+	if (status == 0x44) {
 		*name = lme_firmware_switch(d, 0);
 		return COLD;
 	}
 
-	return 0;
+	if (status != 0x47)
+		return -EINVAL;
+
+	return WARM;
 }
 
 static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
index f0ed37d..221cf46 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
@@ -477,10 +477,15 @@ static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe,
 {
 	struct mxl111sf_demod_state *state = fe->demodulator_priv;
 	enum fe_modulation modulation;
+	int ret;
 	u16 snr;
 
-	mxl111sf_demod_calc_snr(state, &snr);
-	mxl1x1sf_demod_get_tps_modulation(state, &modulation);
+	ret = mxl111sf_demod_calc_snr(state, &snr);
+	if (ret < 0)
+		return ret;
+	ret = mxl1x1sf_demod_get_tps_modulation(state, &modulation);
+	if (ret < 0)
+		return ret;
 
 	switch (modulation) {
 	case QPSK:
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
index 9cb4972..95888b8 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
@@ -17,7 +17,7 @@
 #ifndef __MXL111SF_DEMOD_H__
 #define __MXL111SF_DEMOD_H__
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mxl111sf.h"
 
 struct mxl111sf_demod_config {
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
index 11ea07a..87c1b16 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
@@ -17,7 +17,7 @@
 #ifndef __MXL111SF_TUNER_H__
 #define __MXL111SF_TUNER_H__
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "mxl111sf.h"
 
 enum mxl_if_freq {
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
index 959fa09..2651ae2 100644
--- a/drivers/media/usb/dvb-usb/Kconfig
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -86,6 +86,7 @@
 	select DVB_USB_DIB3000MC if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT
+	select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TUNER_DIB0070 if MEDIA_SUBDRV_AUTOSELECT
 	select DVB_TUNER_DIB0090 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
@@ -94,6 +95,7 @@
 	select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_XC4000 if MEDIA_SUBDRV_AUTOSELECT
 	select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT
+	select MEDIA_TUNER_TDA18250 if MEDIA_SUBDRV_AUTOSELECT
 	help
 	  Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
 	  USB bridge is also present in devices having the DiB7700 DVB-T-USB
diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
index 16de1e4..9ad2618 100644
--- a/drivers/media/usb/dvb-usb/Makefile
+++ b/drivers/media/usb/dvb-usb/Makefile
@@ -80,7 +80,6 @@
 dvb-usb-technisat-usb2-objs := technisat-usb2.o
 obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
 
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
 # due to tuner-xc3028
 ccflags-y += -I$(srctree)/drivers/media/tuners
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
index 2e71136..f0d10ac 100644
--- a/drivers/media/usb/dvb-usb/az6027.c
+++ b/drivers/media/usb/dvb-usb/az6027.c
@@ -17,7 +17,7 @@
 
 #include "stb6100.h"
 #include "stb6100_cfg.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 
 int dvb_usb_az6027_debug;
 module_param_named(debug, dvb_usb_az6027_debug, int, 0644);
@@ -36,70 +36,70 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = {
 	/* 0x0000000b, SYSREG */
 	{ STB0899_DEV_ID		, 0x30 },
 	{ STB0899_DISCNTRL1		, 0x32 },
-	{ STB0899_DISCNTRL2     	, 0x80 },
-	{ STB0899_DISRX_ST0     	, 0x04 },
-	{ STB0899_DISRX_ST1     	, 0x00 },
-	{ STB0899_DISPARITY     	, 0x00 },
+	{ STB0899_DISCNTRL2		, 0x80 },
+	{ STB0899_DISRX_ST0		, 0x04 },
+	{ STB0899_DISRX_ST1		, 0x00 },
+	{ STB0899_DISPARITY		, 0x00 },
 	{ STB0899_DISSTATUS		, 0x20 },
-	{ STB0899_DISF22        	, 0x99 },
-	{ STB0899_DISF22RX      	, 0xa8 },
+	{ STB0899_DISF22		, 0x99 },
+	{ STB0899_DISF22RX		, 0xa8 },
 	/* SYSREG ? */
-	{ STB0899_ACRPRESC      	, 0x11 },
-	{ STB0899_ACRDIV1       	, 0x0a },
-	{ STB0899_ACRDIV2       	, 0x05 },
-	{ STB0899_DACR1         	, 0x00 },
-	{ STB0899_DACR2         	, 0x00 },
-	{ STB0899_OUTCFG        	, 0x00 },
-	{ STB0899_MODECFG       	, 0x00 },
+	{ STB0899_ACRPRESC		, 0x11 },
+	{ STB0899_ACRDIV1		, 0x0a },
+	{ STB0899_ACRDIV2		, 0x05 },
+	{ STB0899_DACR1			, 0x00 },
+	{ STB0899_DACR2			, 0x00 },
+	{ STB0899_OUTCFG		, 0x00 },
+	{ STB0899_MODECFG		, 0x00 },
 	{ STB0899_IRQSTATUS_3		, 0xfe },
 	{ STB0899_IRQSTATUS_2		, 0x03 },
 	{ STB0899_IRQSTATUS_1		, 0x7c },
 	{ STB0899_IRQSTATUS_0		, 0xf4 },
-	{ STB0899_IRQMSK_3      	, 0xf3 },
-	{ STB0899_IRQMSK_2      	, 0xfc },
-	{ STB0899_IRQMSK_1      	, 0xff },
+	{ STB0899_IRQMSK_3		, 0xf3 },
+	{ STB0899_IRQMSK_2		, 0xfc },
+	{ STB0899_IRQMSK_1		, 0xff },
 	{ STB0899_IRQMSK_0		, 0xff },
 	{ STB0899_IRQCFG		, 0x00 },
-	{ STB0899_I2CCFG        	, 0x88 },
-	{ STB0899_I2CRPT        	, 0x58 },
+	{ STB0899_I2CCFG		, 0x88 },
+	{ STB0899_I2CRPT		, 0x58 },
 	{ STB0899_IOPVALUE5		, 0x00 },
 	{ STB0899_IOPVALUE4		, 0x33 },
 	{ STB0899_IOPVALUE3		, 0x6d },
 	{ STB0899_IOPVALUE2		, 0x90 },
 	{ STB0899_IOPVALUE1		, 0x60 },
 	{ STB0899_IOPVALUE0		, 0x00 },
-	{ STB0899_GPIO00CFG     	, 0x82 },
-	{ STB0899_GPIO01CFG     	, 0x82 },
-	{ STB0899_GPIO02CFG     	, 0x82 },
-	{ STB0899_GPIO03CFG     	, 0x82 },
-	{ STB0899_GPIO04CFG     	, 0x82 },
-	{ STB0899_GPIO05CFG     	, 0x82 },
-	{ STB0899_GPIO06CFG     	, 0x82 },
-	{ STB0899_GPIO07CFG     	, 0x82 },
-	{ STB0899_GPIO08CFG     	, 0x82 },
-	{ STB0899_GPIO09CFG     	, 0x82 },
-	{ STB0899_GPIO10CFG     	, 0x82 },
-	{ STB0899_GPIO11CFG     	, 0x82 },
-	{ STB0899_GPIO12CFG     	, 0x82 },
-	{ STB0899_GPIO13CFG     	, 0x82 },
-	{ STB0899_GPIO14CFG     	, 0x82 },
-	{ STB0899_GPIO15CFG     	, 0x82 },
-	{ STB0899_GPIO16CFG     	, 0x82 },
-	{ STB0899_GPIO17CFG     	, 0x82 },
-	{ STB0899_GPIO18CFG     	, 0x82 },
-	{ STB0899_GPIO19CFG     	, 0x82 },
-	{ STB0899_GPIO20CFG     	, 0x82 },
-	{ STB0899_SDATCFG       	, 0xb8 },
-	{ STB0899_SCLTCFG       	, 0xba },
-	{ STB0899_AGCRFCFG      	, 0x1c }, /* 0x11 */
-	{ STB0899_GPIO22        	, 0x82 }, /* AGCBB2CFG */
-	{ STB0899_GPIO21        	, 0x91 }, /* AGCBB1CFG */
-	{ STB0899_DIRCLKCFG     	, 0x82 },
-	{ STB0899_CLKOUT27CFG   	, 0x7e },
-	{ STB0899_STDBYCFG      	, 0x82 },
-	{ STB0899_CS0CFG        	, 0x82 },
-	{ STB0899_CS1CFG        	, 0x82 },
-	{ STB0899_DISEQCOCFG    	, 0x20 },
+	{ STB0899_GPIO00CFG		, 0x82 },
+	{ STB0899_GPIO01CFG		, 0x82 },
+	{ STB0899_GPIO02CFG		, 0x82 },
+	{ STB0899_GPIO03CFG		, 0x82 },
+	{ STB0899_GPIO04CFG		, 0x82 },
+	{ STB0899_GPIO05CFG		, 0x82 },
+	{ STB0899_GPIO06CFG		, 0x82 },
+	{ STB0899_GPIO07CFG		, 0x82 },
+	{ STB0899_GPIO08CFG		, 0x82 },
+	{ STB0899_GPIO09CFG		, 0x82 },
+	{ STB0899_GPIO10CFG		, 0x82 },
+	{ STB0899_GPIO11CFG		, 0x82 },
+	{ STB0899_GPIO12CFG		, 0x82 },
+	{ STB0899_GPIO13CFG		, 0x82 },
+	{ STB0899_GPIO14CFG		, 0x82 },
+	{ STB0899_GPIO15CFG		, 0x82 },
+	{ STB0899_GPIO16CFG		, 0x82 },
+	{ STB0899_GPIO17CFG		, 0x82 },
+	{ STB0899_GPIO18CFG		, 0x82 },
+	{ STB0899_GPIO19CFG		, 0x82 },
+	{ STB0899_GPIO20CFG		, 0x82 },
+	{ STB0899_SDATCFG		, 0xb8 },
+	{ STB0899_SCLTCFG		, 0xba },
+	{ STB0899_AGCRFCFG		, 0x1c }, /* 0x11 */
+	{ STB0899_GPIO22		, 0x82 }, /* AGCBB2CFG */
+	{ STB0899_GPIO21		, 0x91 }, /* AGCBB1CFG */
+	{ STB0899_DIRCLKCFG		, 0x82 },
+	{ STB0899_CLKOUT27CFG		, 0x7e },
+	{ STB0899_STDBYCFG		, 0x82 },
+	{ STB0899_CS0CFG		, 0x82 },
+	{ STB0899_CS1CFG		, 0x82 },
+	{ STB0899_DISEQCOCFG		, 0x20 },
 	{ STB0899_GPIO32CFG		, 0x82 },
 	{ STB0899_GPIO33CFG		, 0x82 },
 	{ STB0899_GPIO34CFG		, 0x82 },
@@ -108,35 +108,35 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = {
 	{ STB0899_GPIO37CFG		, 0x82 },
 	{ STB0899_GPIO38CFG		, 0x82 },
 	{ STB0899_GPIO39CFG		, 0x82 },
-	{ STB0899_NCOARSE       	, 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
-	{ STB0899_SYNTCTRL      	, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
-	{ STB0899_FILTCTRL      	, 0x00 },
-	{ STB0899_SYSCTRL       	, 0x01 },
-	{ STB0899_STOPCLK1      	, 0x20 },
-	{ STB0899_STOPCLK2      	, 0x00 },
+	{ STB0899_NCOARSE		, 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+	{ STB0899_SYNTCTRL		, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+	{ STB0899_FILTCTRL		, 0x00 },
+	{ STB0899_SYSCTRL		, 0x01 },
+	{ STB0899_STOPCLK1		, 0x20 },
+	{ STB0899_STOPCLK2		, 0x00 },
 	{ STB0899_INTBUFSTATUS		, 0x00 },
-	{ STB0899_INTBUFCTRL    	, 0x0a },
+	{ STB0899_INTBUFCTRL		, 0x0a },
 	{ 0xffff			, 0xff },
 };
 
 static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
-	{ STB0899_DEMOD         	, 0x00 },
-	{ STB0899_RCOMPC        	, 0xc9 },
-	{ STB0899_AGC1CN        	, 0x01 },
-	{ STB0899_AGC1REF       	, 0x10 },
+	{ STB0899_DEMOD			, 0x00 },
+	{ STB0899_RCOMPC		, 0xc9 },
+	{ STB0899_AGC1CN		, 0x01 },
+	{ STB0899_AGC1REF		, 0x10 },
 	{ STB0899_RTC			, 0x23 },
-	{ STB0899_TMGCFG        	, 0x4e },
-	{ STB0899_AGC2REF       	, 0x34 },
-	{ STB0899_TLSR          	, 0x84 },
-	{ STB0899_CFD           	, 0xf7 },
+	{ STB0899_TMGCFG		, 0x4e },
+	{ STB0899_AGC2REF		, 0x34 },
+	{ STB0899_TLSR			, 0x84 },
+	{ STB0899_CFD			, 0xf7 },
 	{ STB0899_ACLC			, 0x87 },
-	{ STB0899_BCLC          	, 0x94 },
-	{ STB0899_EQON          	, 0x41 },
-	{ STB0899_LDT           	, 0xf1 },
-	{ STB0899_LDT2          	, 0xe3 },
-	{ STB0899_EQUALREF      	, 0xb4 },
-	{ STB0899_TMGRAMP       	, 0x10 },
-	{ STB0899_TMGTHD        	, 0x30 },
+	{ STB0899_BCLC			, 0x94 },
+	{ STB0899_EQON			, 0x41 },
+	{ STB0899_LDT			, 0xf1 },
+	{ STB0899_LDT2			, 0xe3 },
+	{ STB0899_EQUALREF		, 0xb4 },
+	{ STB0899_TMGRAMP		, 0x10 },
+	{ STB0899_TMGTHD		, 0x30 },
 	{ STB0899_IDCCOMP		, 0xfd },
 	{ STB0899_QDCCOMP		, 0xff },
 	{ STB0899_POWERI		, 0x0c },
@@ -155,12 +155,12 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
 	{ STB0899_NIRL			, 0x80 },
 	{ STB0899_ISYMB			, 0x1d },
 	{ STB0899_QSYMB			, 0xa6 },
-	{ STB0899_SFRH          	, 0x2f },
-	{ STB0899_SFRM          	, 0x68 },
-	{ STB0899_SFRL          	, 0x40 },
-	{ STB0899_SFRUPH        	, 0x2f },
-	{ STB0899_SFRUPM        	, 0x68 },
-	{ STB0899_SFRUPL        	, 0x40 },
+	{ STB0899_SFRH			, 0x2f },
+	{ STB0899_SFRM			, 0x68 },
+	{ STB0899_SFRL			, 0x40 },
+	{ STB0899_SFRUPH		, 0x2f },
+	{ STB0899_SFRUPM		, 0x68 },
+	{ STB0899_SFRUPL		, 0x40 },
 	{ STB0899_EQUAI1		, 0x02 },
 	{ STB0899_EQUAQ1		, 0xff },
 	{ STB0899_EQUAI2		, 0x04 },
@@ -172,7 +172,7 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
 	{ STB0899_EQUAI5		, 0x08 },
 	{ STB0899_EQUAQ5		, 0xf5 },
 	{ STB0899_DSTATUS2		, 0x00 },
-	{ STB0899_VSTATUS       	, 0x00 },
+	{ STB0899_VSTATUS		, 0x00 },
 	{ STB0899_VERROR		, 0x86 },
 	{ STB0899_IQSWAP		, 0x2a },
 	{ STB0899_ECNT1M		, 0x00 },
@@ -181,26 +181,26 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
 	{ STB0899_ECNT2L		, 0x00 },
 	{ STB0899_ECNT3M		, 0x0a },
 	{ STB0899_ECNT3L		, 0xad },
-	{ STB0899_FECAUTO1      	, 0x06 },
+	{ STB0899_FECAUTO1		, 0x06 },
 	{ STB0899_FECM			, 0x01 },
-	{ STB0899_VTH12         	, 0xb0 },
-	{ STB0899_VTH23         	, 0x7a },
+	{ STB0899_VTH12			, 0xb0 },
+	{ STB0899_VTH23			, 0x7a },
 	{ STB0899_VTH34			, 0x58 },
-	{ STB0899_VTH56         	, 0x38 },
-	{ STB0899_VTH67         	, 0x34 },
-	{ STB0899_VTH78         	, 0x24 },
-	{ STB0899_PRVIT         	, 0xff },
-	{ STB0899_VITSYNC       	, 0x19 },
-	{ STB0899_RSULC         	, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
-	{ STB0899_TSULC         	, 0x42 },
-	{ STB0899_RSLLC         	, 0x41 },
+	{ STB0899_VTH56			, 0x38 },
+	{ STB0899_VTH67			, 0x34 },
+	{ STB0899_VTH78			, 0x24 },
+	{ STB0899_PRVIT			, 0xff },
+	{ STB0899_VITSYNC		, 0x19 },
+	{ STB0899_RSULC			, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+	{ STB0899_TSULC			, 0x42 },
+	{ STB0899_RSLLC			, 0x41 },
 	{ STB0899_TSLPL			, 0x12 },
-	{ STB0899_TSCFGH        	, 0x0c },
-	{ STB0899_TSCFGM        	, 0x00 },
-	{ STB0899_TSCFGL        	, 0x00 },
+	{ STB0899_TSCFGH		, 0x0c },
+	{ STB0899_TSCFGM		, 0x00 },
+	{ STB0899_TSCFGL		, 0x00 },
 	{ STB0899_TSOUT			, 0x69 }, /* 0x0d for CAM */
-	{ STB0899_RSSYNCDEL     	, 0x00 },
-	{ STB0899_TSINHDELH     	, 0x02 },
+	{ STB0899_RSSYNCDEL		, 0x00 },
+	{ STB0899_TSINHDELH		, 0x02 },
 	{ STB0899_TSINHDELM		, 0x00 },
 	{ STB0899_TSINHDELL		, 0x00 },
 	{ STB0899_TSLLSTKM		, 0x1b },
@@ -211,18 +211,18 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
 	{ STB0899_PCKLENLL		, 0xcc },
 	{ STB0899_RSPCKLEN		, 0xbd },
 	{ STB0899_TSSTATUS		, 0x90 },
-	{ STB0899_ERRCTRL1      	, 0xb6 },
-	{ STB0899_ERRCTRL2      	, 0x95 },
-	{ STB0899_ERRCTRL3      	, 0x8d },
+	{ STB0899_ERRCTRL1		, 0xb6 },
+	{ STB0899_ERRCTRL2		, 0x95 },
+	{ STB0899_ERRCTRL3		, 0x8d },
 	{ STB0899_DMONMSK1		, 0x27 },
 	{ STB0899_DMONMSK0		, 0x03 },
-	{ STB0899_DEMAPVIT      	, 0x5c },
+	{ STB0899_DEMAPVIT		, 0x5c },
 	{ STB0899_PLPARM		, 0x19 },
-	{ STB0899_PDELCTRL      	, 0x48 },
-	{ STB0899_PDELCTRL2     	, 0x00 },
-	{ STB0899_BBHCTRL1      	, 0x00 },
-	{ STB0899_BBHCTRL2      	, 0x00 },
-	{ STB0899_HYSTTHRESH    	, 0x77 },
+	{ STB0899_PDELCTRL		, 0x48 },
+	{ STB0899_PDELCTRL2		, 0x00 },
+	{ STB0899_BBHCTRL1		, 0x00 },
+	{ STB0899_BBHCTRL2		, 0x00 },
+	{ STB0899_HYSTTHRESH		, 0x77 },
 	{ STB0899_MATCSTM		, 0x00 },
 	{ STB0899_MATCSTL		, 0x00 },
 	{ STB0899_UPLCSTM		, 0x00 },
@@ -261,7 +261,7 @@ static struct stb0899_config az6027_stb0899_config = {
 	.init_s2_fec		= stb0899_s2_init_4,
 	.init_tst		= stb0899_s1_init_5,
 
-	.demod_address 		= 0xd0, /* 0x68, 0xd0 >> 1 */
+	.demod_address		= 0xd0, /* 0x68, 0xd0 >> 1 */
 
 	.xtal_freq		= 27000000,
 	.inversion		= IQ_SWAP_ON,
@@ -1181,9 +1181,9 @@ static struct dvb_usb_device_properties az6027_properties = {
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver az6027_usb_driver = {
 	.name		= "dvb_usb_az6027",
-	.probe 		= az6027_usb_probe,
-	.disconnect 	= az6027_usb_disconnect,
-	.id_table 	= az6027_usb_table,
+	.probe		= az6027_usb_probe,
+	.disconnect	= az6027_usb_disconnect,
+	.id_table	= az6027_usb_table,
 };
 
 module_usb_driver(az6027_usb_driver);
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index 37dea0a..2abd15c 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -26,6 +26,7 @@
 #include <media/tuner.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
+#include <linux/kernel.h>
 
 #include "cxusb.h"
 
@@ -56,7 +57,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 #define deb_i2c(args...)    dprintk(dvb_usb_cxusb_debug, 0x02, args)
 
 static int cxusb_ctrl_msg(struct dvb_usb_device *d,
-			  u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+			  u8 cmd, const u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
 	struct cxusb_state *st = d->priv;
 	int ret;
@@ -290,7 +291,8 @@ static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
 		/* FIXME: We don't know why, but we need to configure the
 		 * lgdt3303 with the register settings below on resume */
 		int i;
-		u8 buf, bufs[] = {
+		u8 buf;
+		static const u8 bufs[] = {
 			0x0e, 0x2, 0x00, 0x7f,
 			0x0e, 0x2, 0x02, 0xfe,
 			0x0e, 0x2, 0x02, 0x01,
@@ -303,7 +305,7 @@ static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
 			0x0e, 0x2, 0x47, 0x88,
 		};
 		msleep(20);
-		for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
+		for (i = 0; i < ARRAY_SIZE(bufs); i += 4 / sizeof(u8)) {
 			ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
 					     bufs+i, 4, &buf, 1);
 			if (ret)
@@ -677,6 +679,8 @@ static int dvico_bluebird_xc2028_callback(void *ptr, int component,
 	case XC2028_RESET_CLK:
 		deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
 		break;
+	case XC2028_I2C_FLUSH:
+		break;
 	default:
 		deb_info("%s: unknown command %d, arg %d\n", __func__,
 			 command, arg);
diff --git a/drivers/media/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h
index f89ab3b..3a9d4c2 100644
--- a/drivers/media/usb/dvb-usb/dib0700.h
+++ b/drivers/media/usb/dvb-usb/dib0700.h
@@ -51,6 +51,8 @@ struct dib0700_state {
 	int (*read_status)(struct dvb_frontend *, enum fe_status *);
 	int (*sleep)(struct dvb_frontend* fe);
 	u8 buf[255];
+	struct i2c_client *i2c_client_demod;
+	struct i2c_client *i2c_client_tuner;
 };
 
 extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index 1ee7ec5..94bd176 100644
--- a/drivers/media/usb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -911,10 +911,34 @@ static int dib0700_probe(struct usb_interface *intf,
 	return -ENODEV;
 }
 
+static void dib0700_disconnect(struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+	struct dib0700_state *st = d->priv;
+	struct i2c_client *client;
+
+	/* remove I2C client for tuner */
+	client = st->i2c_client_tuner;
+	if (client) {
+		module_put(client->dev.driver->owner);
+		i2c_unregister_device(client);
+	}
+
+	/* remove I2C client for demodulator */
+	client = st->i2c_client_demod;
+	if (client) {
+		module_put(client->dev.driver->owner);
+		i2c_unregister_device(client);
+	}
+
+	dvb_usb_device_exit(intf);
+}
+
+
 static struct usb_driver dib0700_driver = {
 	.name       = "dvb_usb_dib0700",
 	.probe      = dib0700_probe,
-	.disconnect = dvb_usb_device_exit,
+	.disconnect = dib0700_disconnect,
 	.id_table   = dib0700_usb_id_table,
 };
 
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
index 366b055..3d99e14 100644
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -23,6 +23,9 @@
 #include "dib0090.h"
 #include "lgdt3305.h"
 #include "mxl5007t.h"
+#include "mn88472.h"
+#include "tda18250.h"
+
 
 static int force_lna_activation;
 module_param(force_lna_activation, int, 0644);
@@ -430,6 +433,7 @@ static int stk7700ph_xc3028_callback(void *ptr, int component,
 		state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
 		break;
 	case XC2028_RESET_CLK:
+	case XC2028_I2C_FLUSH:
 		break;
 	default:
 		err("%s: unknown command %d, arg %d\n", __func__,
@@ -3725,6 +3729,90 @@ static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
 			  &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
 }
 
+static int xbox_one_attach(struct dvb_usb_adapter *adap)
+{
+	struct dib0700_state *st = adap->dev->priv;
+	struct i2c_client *client_demod, *client_tuner;
+	struct dvb_usb_device *d = adap->dev;
+	struct mn88472_config mn88472_config = { };
+	struct tda18250_config tda18250_config;
+	struct i2c_board_info info;
+
+	st->fw_use_new_i2c_api = 1;
+	st->disable_streaming_master_mode = 1;
+
+	/* fe power enable */
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+	msleep(30);
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+	msleep(30);
+
+	/* demod reset */
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(30);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+	msleep(30);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(30);
+
+	/* attach demod */
+	mn88472_config.fe = &adap->fe_adap[0].fe;
+	mn88472_config.i2c_wr_max = 22;
+	mn88472_config.xtal = 20500000;
+	mn88472_config.ts_mode = PARALLEL_TS_MODE;
+	mn88472_config.ts_clock = FIXED_TS_CLOCK;
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
+	info.addr = 0x18;
+	info.platform_data = &mn88472_config;
+	request_module(info.type);
+	client_demod = i2c_new_device(&d->i2c_adap, &info);
+	if (client_demod == NULL || client_demod->dev.driver == NULL)
+		goto fail_demod_device;
+	if (!try_module_get(client_demod->dev.driver->owner))
+		goto fail_demod_module;
+
+	st->i2c_client_demod = client_demod;
+
+	adap->fe_adap[0].fe = mn88472_config.get_dvb_frontend(client_demod);
+
+	/* attach tuner */
+	memset(&tda18250_config, 0, sizeof(tda18250_config));
+	tda18250_config.if_dvbt_6 = 3950;
+	tda18250_config.if_dvbt_7 = 4450;
+	tda18250_config.if_dvbt_8 = 4950;
+	tda18250_config.if_dvbc_6 = 4950;
+	tda18250_config.if_dvbc_8 = 4950;
+	tda18250_config.if_atsc = 4079;
+	tda18250_config.loopthrough = true;
+	tda18250_config.xtal_freq = TDA18250_XTAL_FREQ_27MHZ;
+	tda18250_config.fe = adap->fe_adap[0].fe;
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "tda18250", I2C_NAME_SIZE);
+	info.addr = 0x60;
+	info.platform_data = &tda18250_config;
+
+	request_module(info.type);
+	client_tuner = i2c_new_device(&adap->dev->i2c_adap, &info);
+	if (client_tuner == NULL || client_tuner->dev.driver == NULL)
+		goto fail_tuner_device;
+	if (!try_module_get(client_tuner->dev.driver->owner))
+		goto fail_tuner_module;
+
+	st->i2c_client_tuner = client_tuner;
+	return 0;
+
+fail_tuner_module:
+	i2c_unregister_device(client_tuner);
+fail_tuner_device:
+	module_put(client_demod->dev.driver->owner);
+fail_demod_module:
+	i2c_unregister_device(client_demod);
+fail_demod_device:
+	return -ENODEV;
+}
+
 
 /* DVB-USB and USB stuff follows */
 struct usb_device_id dib0700_usb_id_table[] = {
@@ -3816,7 +3904,8 @@ struct usb_device_id dib0700_usb_id_table[] = {
 	{ USB_DEVICE(USB_VID_PCTV,      USB_PID_PCTV_2002E_SE) },
 	{ USB_DEVICE(USB_VID_PCTV,      USB_PID_DIBCOM_STK8096PVR) },
 	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK8096PVR) },
-	{ USB_DEVICE(USB_VID_HAMA,	USB_PID_HAMA_DVBT_HYBRID) },
+/* 85 */{ USB_DEVICE(USB_VID_HAMA,	USB_PID_HAMA_DVBT_HYBRID) },
+	{ USB_DEVICE(USB_VID_MICROSOFT,	USB_PID_XBOX_ONE_TUNER) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -5040,6 +5129,25 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 				RC_PROTO_BIT_NEC,
 			.change_protocol  = dib0700_change_protocol,
 		},
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+		.num_adapters = 1,
+		.adapter = {
+			{
+				DIB0700_NUM_FRONTENDS(1),
+				.fe = {{
+					.frontend_attach = xbox_one_attach,
+
+					DIB0700_DEFAULT_STREAMING_CONFIG(0x82),
+				} },
+			},
+		},
+		.num_device_descs = 1,
+		.devices = {
+			{ "Microsoft Xbox One Digital TV Tuner",
+				{ &dib0700_usb_id_table[86], NULL },
+				{ NULL },
+			},
+		},
 	},
 };
 
diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
index e71fc86..317ed6a 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb.h
+++ b/drivers/media/usb/dvb-usb/dvb-usb.h
@@ -17,14 +17,14 @@
 #include <linux/mutex.h>
 #include <media/rc-core.h>
 
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dmxdev.h>
 
 #include "dvb-pll.h"
 
-#include "dvb-usb-ids.h"
+#include <media/dvb-usb-ids.h>
 
 /* debug */
 #ifdef CONFIG_DVB_USB_DEBUG
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index b421329b..346946f 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -13,7 +13,7 @@
  *
  * see Documentation/dvb/README.dvb-usb for more information
  */
-#include "dvb-usb-ids.h"
+#include <media/dvb-usb-ids.h>
 #include "dw2102.h"
 #include "si21xx.h"
 #include "stv0299.h"
diff --git a/drivers/media/usb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c
index b6046e0..b2830c1 100644
--- a/drivers/media/usb/dvb-usb/friio-fe.c
+++ b/drivers/media/usb/dvb-usb/friio-fe.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/kernel.h>
 
 #include "friio.h"
 
@@ -340,8 +341,6 @@ static u8 init_code[][2] = {
 	{0x76, 0x0C},
 };
 
-static const int init_code_len = sizeof(init_code) / sizeof(u8[2]);
-
 static int jdvbt90502_init(struct dvb_frontend *fe)
 {
 	int i = -1;
@@ -355,7 +354,7 @@ static int jdvbt90502_init(struct dvb_frontend *fe)
 	msg.addr = state->config.demod_address;
 	msg.flags = 0;
 	msg.len = 2;
-	for (i = 0; i < init_code_len; i++) {
+	for (i = 0; i < ARRAY_SIZE(init_code); i++) {
 		msg.buf = init_code[i];
 		ret = i2c_transfer(state->i2c, &msg, 1);
 		if (ret != 1)
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index 601ade7..0af7438 100644
--- a/drivers/media/usb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -26,7 +26,7 @@
 /* FE Power */
 #include "lnbp22.h"
 
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 #include "ttpci-eeprom.h"
 
 static int debug;
@@ -913,6 +913,14 @@ static int pctv452e_frontend_attach(struct dvb_usb_adapter *a)
 						&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/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c
index e7020f2..12de8966 100644
--- a/drivers/media/usb/dvb-usb/ttusb2.c
+++ b/drivers/media/usb/dvb-usb/ttusb2.c
@@ -34,7 +34,7 @@
 #include "tda827x.h"
 #include "lnbp21.h"
 /* CA */
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
 
 /* debug */
 static int dvb_usb_ttusb2_debug;
diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig
index 4cc029f..451e076 100644
--- a/drivers/media/usb/em28xx/Kconfig
+++ b/drivers/media/usb/em28xx/Kconfig
@@ -71,10 +71,10 @@
 	  Empiatech em28xx chips.
 
 config VIDEO_EM28XX_RC
-        tristate "EM28XX Remote Controller support"
-        depends on RC_CORE
-        depends on VIDEO_EM28XX
-        depends on !(RC_CORE=m && VIDEO_EM28XX=y)
-        default VIDEO_EM28XX
-        ---help---
-          Enables Remote Controller support on em28xx driver.
+	tristate "EM28XX Remote Controller support"
+	depends on RC_CORE
+	depends on VIDEO_EM28XX
+	depends on !(RC_CORE=m && VIDEO_EM28XX=y)
+	default VIDEO_EM28XX
+	---help---
+	  Enables Remote Controller support on em28xx driver.
diff --git a/drivers/media/usb/em28xx/Makefile b/drivers/media/usb/em28xx/Makefile
index 86bfc35..8a22400 100644
--- a/drivers/media/usb/em28xx/Makefile
+++ b/drivers/media/usb/em28xx/Makefile
@@ -11,7 +11,5 @@
 obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o
 obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o
 
-ccflags-y += -Idrivers/media/i2c
 ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 4c57fd7..34e16f6a 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -36,7 +36,6 @@
 #include <media/i2c/saa7115.h>
 #include <dt-bindings/media/tvp5150.h>
 #include <media/i2c/tvaudio.h>
-#include <media/i2c-addr.h>
 #include <media/tveeprom.h>
 #include <media/v4l2-common.h>
 #include <sound/ac97_codec.h>
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 9950a74..8a81c94 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -28,9 +28,9 @@
 #include <linux/usb.h>
 
 #include <media/v4l2-common.h>
-#include <dvb_demux.h>
-#include <dvb_net.h>
-#include <dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dmxdev.h>
 #include <media/tuner.h>
 #include "tuner-simple.h"
 #include <linux/gpio.h>
@@ -2105,6 +2105,8 @@ static int em28xx_dvb_fini(struct em28xx *dev)
 		}
 	}
 
+	em28xx_unregister_dvb(dvb);
+
 	/* remove I2C SEC */
 	client = dvb->i2c_client_sec;
 	if (client) {
@@ -2126,7 +2128,6 @@ static int em28xx_dvb_fini(struct em28xx *dev)
 		i2c_unregister_device(client);
 	}
 
-	em28xx_unregister_dvb(dvb);
 	kfree(dvb);
 	dev->dvb = NULL;
 	kref_put(&dev->ref, em28xx_free_device);
diff --git a/drivers/media/usb/gspca/autogain_functions.c b/drivers/media/usb/gspca/autogain_functions.c
index 427db74..6dfab2b 100644
--- a/drivers/media/usb/gspca/autogain_functions.c
+++ b/drivers/media/usb/gspca/autogain_functions.c
@@ -32,7 +32,7 @@ int gspca_expo_autogain(
 	int i, steps, retval = 0;
 
 	if (v4l2_ctrl_g_ctrl(gspca_dev->autogain) == 0)
-	        return 0;
+		return 0;
 
 	orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain);
 	orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
@@ -41,8 +41,8 @@ int gspca_expo_autogain(
 	   desired lumination fast (with the risc of a slight overshoot) */
 	steps = abs(desired_avg_lum - avg_lum) / deadzone;
 
-	PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
-		avg_lum, desired_avg_lum, steps);
+	gspca_dbg(gspca_dev, D_FRAM, "autogain: lum: %d, desired: %d, steps: %d\n",
+		  avg_lum, desired_avg_lum, steps);
 
 	for (i = 0; i < steps; i++) {
 		if (avg_lum > desired_avg_lum) {
@@ -75,17 +75,17 @@ int gspca_expo_autogain(
 	}
 
 	if (gain != orig_gain) {
-	        v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
+		v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
 		retval = 1;
 	}
 	if (exposure != orig_exposure) {
-	        v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
+		v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
 		retval = 1;
 	}
 
 	if (retval)
-		PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
-			gain, exposure);
+		gspca_dbg(gspca_dev, D_FRAM, "autogain: changed gain: %d, expo: %d\n",
+			  gain, exposure);
 	return retval;
 }
 EXPORT_SYMBOL(gspca_expo_autogain);
@@ -112,7 +112,7 @@ int gspca_coarse_grained_expo_autogain(
 	int steps, retval = 0;
 
 	if (v4l2_ctrl_g_ctrl(gspca_dev->autogain) == 0)
-	        return 0;
+		return 0;
 
 	orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain);
 	orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
@@ -126,8 +126,8 @@ int gspca_coarse_grained_expo_autogain(
 	   desired lumination fast (with the risc of a slight overshoot) */
 	steps = (desired_avg_lum - avg_lum) / deadzone;
 
-	PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
-		avg_lum, desired_avg_lum, steps);
+	gspca_dbg(gspca_dev, D_FRAM, "autogain: lum: %d, desired: %d, steps: %d\n",
+		  avg_lum, desired_avg_lum, steps);
 
 	if ((gain + steps) > gain_high &&
 	    exposure < gspca_dev->exposure->maximum) {
@@ -158,17 +158,17 @@ int gspca_coarse_grained_expo_autogain(
 	}
 
 	if (gain != orig_gain) {
-	        v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
+		v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
 		retval = 1;
 	}
 	if (exposure != orig_exposure) {
-	        v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
+		v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
 		retval = 1;
 	}
 
 	if (retval)
-		PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
-			gain, exposure);
+		gspca_dbg(gspca_dev, D_FRAM, "autogain: changed gain: %d, expo: %d\n",
+			  gain, exposure);
 	return retval;
 }
 EXPORT_SYMBOL(gspca_coarse_grained_expo_autogain);
diff --git a/drivers/media/usb/gspca/benq.c b/drivers/media/usb/gspca/benq.c
index 60a7282..8a8db5e 100644
--- a/drivers/media/usb/gspca/benq.c
+++ b/drivers/media/usb/gspca/benq.c
@@ -152,7 +152,7 @@ static void sd_isoc_irq(struct urb *urb)
 	u8 *data;
 	int i, st;
 
-	PDEBUG(D_PACK, "sd isoc irq");
+	gspca_dbg(gspca_dev, D_PACK, "sd isoc irq\n");
 	if (!gspca_dev->streaming)
 		return;
 	if (urb->status != 0) {
@@ -180,9 +180,9 @@ static void sd_isoc_irq(struct urb *urb)
 		/* check the packet status and length */
 		if (urb0->iso_frame_desc[i].actual_length != SD_PKT_SZ
 		    || urb->iso_frame_desc[i].actual_length != SD_PKT_SZ) {
-			PERR("ISOC bad lengths %d / %d",
-				urb0->iso_frame_desc[i].actual_length,
-				urb->iso_frame_desc[i].actual_length);
+			gspca_err(gspca_dev, "ISOC bad lengths %d / %d\n",
+				  urb0->iso_frame_desc[i].actual_length,
+				  urb->iso_frame_desc[i].actual_length);
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			continue;
 		}
diff --git a/drivers/media/usb/gspca/conex.c b/drivers/media/usb/gspca/conex.c
index bdcdf79..6df4e20 100644
--- a/drivers/media/usb/gspca/conex.c
+++ b/drivers/media/usb/gspca/conex.c
@@ -70,7 +70,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
 	struct usb_device *dev = gspca_dev->dev;
 
 	if (len > USB_BUF_SZ) {
-		PERR("reg_r: buffer overflow\n");
+		gspca_err(gspca_dev, "reg_r: buffer overflow\n");
 		return;
 	}
 
@@ -81,8 +81,8 @@ static void reg_r(struct gspca_dev *gspca_dev,
 			0,
 			index, gspca_dev->usb_buf, len,
 			500);
-	PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
-			index, gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_USBI, "reg read [%02x] -> %02x ..\n",
+		  index, gspca_dev->usb_buf[0]);
 }
 
 /* the bytes to write are in gspca_dev->usb_buf */
@@ -109,10 +109,11 @@ static void reg_w(struct gspca_dev *gspca_dev,
 	struct usb_device *dev = gspca_dev->dev;
 
 	if (len > USB_BUF_SZ) {
-		PERR("reg_w: buffer overflow\n");
+		gspca_err(gspca_dev, "reg_w: buffer overflow\n");
 		return;
 	}
-	PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
+	gspca_dbg(gspca_dev, D_USBO, "reg write [%02x] = %02x..\n",
+		  index, *buffer);
 
 	memcpy(gspca_dev->usb_buf, buffer, len);
 	usb_control_msg(dev,
@@ -683,7 +684,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev)
 		reg_w_val(gspca_dev, 0x0053, 0x00);
 	} while (--retry);
 	if (retry == 0)
-		PERR("Damned Errors sending jpeg Table");
+		gspca_err(gspca_dev, "Damned Errors sending jpeg Table\n");
 	/* send the qtable now */
 	reg_r(gspca_dev, 0x0001, 1);		/* -> 0x18 */
 	length = 8;
diff --git a/drivers/media/usb/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c
index e91d007..2b09af8 100644
--- a/drivers/media/usb/gspca/cpia1.c
+++ b/drivers/media/usb/gspca/cpia1.c
@@ -419,7 +419,8 @@ static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
 		pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
 		requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
 	} else {
-		PERR("Unexpected first byte of command: %x", command[0]);
+		gspca_err(gspca_dev, "Unexpected first byte of command: %x\n",
+			  command[0]);
 		return -EINVAL;
 	}
 
@@ -542,7 +543,7 @@ static int do_command(struct gspca_dev *gspca_dev, u16 command,
 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
 			input_sync(gspca_dev->input_dev);
 #endif
-	        	sd->params.qx3.button = a;
+			sd->params.qx3.button = a;
 		}
 		if (sd->params.qx3.button) {
 			/* button pressed - unlock the latch */
@@ -700,11 +701,11 @@ static void reset_camera_params(struct gspca_dev *gspca_dev)
 
 static void printstatus(struct gspca_dev *gspca_dev, struct cam_params *params)
 {
-	PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
-	       params->status.systemState, params->status.grabState,
-	       params->status.streamState, params->status.fatalError,
-	       params->status.cmdError, params->status.debugFlags,
-	       params->status.vpStatus, params->status.errorCode);
+	gspca_dbg(gspca_dev, D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x\n",
+		  params->status.systemState, params->status.grabState,
+		  params->status.streamState, params->status.fatalError,
+		  params->status.cmdError, params->status.debugFlags,
+		  params->status.vpStatus, params->status.errorCode);
 }
 
 static int goto_low_power(struct gspca_dev *gspca_dev)
@@ -722,14 +723,14 @@ static int goto_low_power(struct gspca_dev *gspca_dev)
 
 	if (sd->params.status.systemState != LO_POWER_STATE) {
 		if (sd->params.status.systemState != WARM_BOOT_STATE) {
-			PERR("unexpected state after lo power cmd: %02x",
-			     sd->params.status.systemState);
+			gspca_err(gspca_dev, "unexpected state after lo power cmd: %02x\n",
+				  sd->params.status.systemState);
 			printstatus(gspca_dev, &sd->params);
 		}
 		return -EIO;
 	}
 
-	PDEBUG(D_CONF, "camera now in LOW power state");
+	gspca_dbg(gspca_dev, D_CONF, "camera now in LOW power state\n");
 	return 0;
 }
 
@@ -752,13 +753,13 @@ static int goto_high_power(struct gspca_dev *gspca_dev)
 		return ret;
 
 	if (sd->params.status.systemState != HI_POWER_STATE) {
-		PERR("unexpected state after hi power cmd: %02x",
-		     sd->params.status.systemState);
+		gspca_err(gspca_dev, "unexpected state after hi power cmd: %02x\n",
+			  sd->params.status.systemState);
 		printstatus(gspca_dev, &sd->params);
 		return -EIO;
 	}
 
-	PDEBUG(D_CONF, "camera now in HIGH power state");
+	gspca_dbg(gspca_dev, D_CONF, "camera now in HIGH power state\n");
 	return 0;
 }
 
@@ -1301,7 +1302,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
 			sd->params.exposure.coarseExpHi = new_exposure >> 8;
 			setexp = 1;
 			sd->exposure_status = EXPOSURE_NORMAL;
-			PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
+			gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
 
 		} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
 			    sd->exposure_status == EXPOSURE_LIGHT) &&
@@ -1330,7 +1331,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
 			sd->params.exposure.coarseExpHi = new_exposure >> 8;
 			setexp = 1;
 			sd->exposure_status = EXPOSURE_NORMAL;
-			PDEBUG(D_CONF, "Automatically increasing sensor_fps");
+			gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
 		}
 	} else {
 		/* Flicker control off */
@@ -1348,7 +1349,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
 				setexp = 1;
 			}
 			sd->exposure_status = EXPOSURE_NORMAL;
-			PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
+			gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
 
 		} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
 			    sd->exposure_status == EXPOSURE_LIGHT) &&
@@ -1365,7 +1366,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
 				setexp = 1;
 			}
 			sd->exposure_status = EXPOSURE_NORMAL;
-			PDEBUG(D_CONF, "Automatically increasing sensor_fps");
+			gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
 		}
 	}
 
@@ -1433,8 +1434,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
 	reset_camera_params(gspca_dev);
 
-	PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
-	       id->idVendor, id->idProduct);
+	gspca_dbg(gspca_dev, D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)\n",
+		  id->idVendor, id->idProduct);
 
 	cam = &gspca_dev->cam;
 	cam->cam_mode = mode;
@@ -1445,8 +1446,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	sd->params.version.firmwareVersion = 0;
 	get_version_information(gspca_dev);
 	if (sd->params.version.firmwareVersion != 1) {
-		PERR("only firmware version 1 is supported (got: %d)",
-		     sd->params.version.firmwareVersion);
+		gspca_err(gspca_dev, "only firmware version 1 is supported (got: %d)\n",
+			  sd->params.version.firmwareVersion);
 		return -ENODEV;
 	}
 
@@ -1471,8 +1472,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	/* Start the camera in low power mode */
 	if (goto_low_power(gspca_dev)) {
 		if (sd->params.status.systemState != WARM_BOOT_STATE) {
-			PERR("unexpected systemstate: %02x",
-			     sd->params.status.systemState);
+			gspca_err(gspca_dev, "unexpected systemstate: %02x\n",
+				  sd->params.status.systemState);
 			printstatus(gspca_dev, &sd->params);
 			return -ENODEV;
 		}
@@ -1519,8 +1520,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		return ret;
 
 	if (sd->params.status.fatalError) {
-		PERR("fatal_error: %04x, vp_status: %04x",
-		     sd->params.status.fatalError, sd->params.status.vpStatus);
+		gspca_err(gspca_dev, "fatal_error: %04x, vp_status: %04x\n",
+			  sd->params.status.fatalError,
+			  sd->params.status.vpStatus);
 		return -EIO;
 	}
 
@@ -1667,18 +1669,18 @@ static int sd_init(struct gspca_dev *gspca_dev)
 
 	sd_stopN(gspca_dev);
 
-	PDEBUG(D_PROBE, "CPIA Version:             %d.%02d (%d.%d)",
-			sd->params.version.firmwareVersion,
-			sd->params.version.firmwareRevision,
-			sd->params.version.vcVersion,
-			sd->params.version.vcRevision);
-	PDEBUG(D_PROBE, "CPIA PnP-ID:              %04x:%04x:%04x",
-			sd->params.pnpID.vendor, sd->params.pnpID.product,
-			sd->params.pnpID.deviceRevision);
-	PDEBUG(D_PROBE, "VP-Version:               %d.%d %04x",
-			sd->params.vpVersion.vpVersion,
-			sd->params.vpVersion.vpRevision,
-			sd->params.vpVersion.cameraHeadID);
+	gspca_dbg(gspca_dev, D_PROBE, "CPIA Version:             %d.%02d (%d.%d)\n",
+		  sd->params.version.firmwareVersion,
+		  sd->params.version.firmwareRevision,
+		  sd->params.version.vcVersion,
+		  sd->params.version.vcRevision);
+	gspca_dbg(gspca_dev, D_PROBE, "CPIA PnP-ID:              %04x:%04x:%04x",
+		  sd->params.pnpID.vendor, sd->params.pnpID.product,
+		  sd->params.pnpID.deviceRevision);
+	gspca_dbg(gspca_dev, D_PROBE, "VP-Version:               %d.%d %04x",
+		  sd->params.vpVersion.vpVersion,
+		  sd->params.vpVersion.vpRevision,
+		  sd->params.vpVersion.cameraHeadID);
 
 	return 0;
 }
diff --git a/drivers/media/usb/gspca/dtcs033.c b/drivers/media/usb/gspca/dtcs033.c
index 96bfd4e..cdf27cf 100644
--- a/drivers/media/usb/gspca/dtcs033.c
+++ b/drivers/media/usb/gspca/dtcs033.c
@@ -71,18 +71,18 @@ static int reg_reqs(struct gspca_dev *gspca_dev,
 
 		if (gspca_dev->usb_err < 0) {
 
-			PERR("usb error request no: %d / %d\n",
-				i, n_reqs);
+			gspca_err(gspca_dev, "usb error request no: %d / %d\n",
+				  i, n_reqs);
 		} else if (preq->bRequestType & USB_DIR_IN) {
 
-			PDEBUG(D_STREAM,
-			"USB IN (%d) returned[%d] %02X %02X %02X %s",
-				i,
-				preq->wLength,
-				gspca_dev->usb_buf[0],
-				gspca_dev->usb_buf[1],
-				gspca_dev->usb_buf[2],
-				preq->wLength > 3 ? "...\n" : "\n");
+			gspca_dbg(gspca_dev, D_STREAM,
+				  "USB IN (%d) returned[%d] %02X %02X %02X %s\n",
+				  i,
+				  preq->wLength,
+				  gspca_dev->usb_buf[0],
+				  gspca_dev->usb_buf[1],
+				  gspca_dev->usb_buf[2],
+				  preq->wLength > 3 ? "...\n" : "\n");
 		}
 
 		i++;
@@ -176,12 +176,12 @@ static void dtcs033_setexposure(struct gspca_dev *gspca_dev,
 	reg_rw(gspca_dev,
 		bRequestType, bRequest, wValue, wIndex, 0);
 	if (gspca_dev->usb_err < 0)
-		PERR("usb error in setexposure(gain) sequence.\n");
+		gspca_err(gspca_dev, "usb error in setexposure(gain) sequence\n");
 
 	reg_rw(gspca_dev,
 		bRequestType, bRequest, (xtimeVal<<4), 0x6300, 0);
 	if (gspca_dev->usb_err < 0)
-		PERR("usb error in setexposure(time) sequence.\n");
+		gspca_err(gspca_dev, "usb error in setexposure(time) sequence\n");
 }
 
 /* specific webcam descriptor */
@@ -239,8 +239,8 @@ static int dtcs033_init_controls(struct gspca_dev *gspca_dev)
 				V4L2_CID_GAIN,
 				14,  33,  1,  24);/* [dB] */
 	if (hdl->error) {
-		PERR("Could not initialize controls: %d\n",
-			hdl->error);
+		gspca_err(gspca_dev, "Could not initialize controls: %d\n",
+			  hdl->error);
 		return hdl->error;
 	}
 
diff --git a/drivers/media/usb/gspca/etoms.c b/drivers/media/usb/gspca/etoms.c
index 8f84292..48b2889 100644
--- a/drivers/media/usb/gspca/etoms.c
+++ b/drivers/media/usb/gspca/etoms.c
@@ -160,7 +160,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
 	struct usb_device *dev = gspca_dev->dev;
 
 	if (len > USB_BUF_SZ) {
-		PERR("reg_r: buffer overflow\n");
+		gspca_err(gspca_dev, "reg_r: buffer overflow\n");
 		return;
 	}
 
@@ -170,8 +170,8 @@ static void reg_r(struct gspca_dev *gspca_dev,
 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
 			0,
 			index, gspca_dev->usb_buf, len, 500);
-	PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
-			index, gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_USBI, "reg read [%02x] -> %02x ..\n",
+		  index, gspca_dev->usb_buf[0]);
 }
 
 static void reg_w_val(struct gspca_dev *gspca_dev,
@@ -200,7 +200,8 @@ static void reg_w(struct gspca_dev *gspca_dev,
 		pr_err("reg_w: buffer overflow\n");
 		return;
 	}
-	PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
+	gspca_dbg(gspca_dev, D_USBO, "reg write [%02x] = %02x..\n",
+		  index, *buffer);
 
 	memcpy(gspca_dev->usb_buf, buffer, len);
 	usb_control_msg(dev,
@@ -268,7 +269,7 @@ static int et_video(struct gspca_dev *gspca_dev,
 		     : 0);		/* stopvideo */
 	ret = Et_WaitStatus(gspca_dev);
 	if (ret != 0)
-		PERR("timeout video on/off");
+		gspca_err(gspca_dev, "timeout video on/off\n");
 	return ret;
 }
 
@@ -277,7 +278,7 @@ static void Et_init2(struct gspca_dev *gspca_dev)
 	__u8 value;
 	static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 };
 
-	PDEBUG(D_STREAM, "Open Init2 ET");
+	gspca_dbg(gspca_dev, D_STREAM, "Open Init2 ET\n");
 	reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f);
 	reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10);
 	reg_r(gspca_dev, ET_GPIO_IN, 1);
@@ -416,8 +417,6 @@ static void setcolors(struct gspca_dev *gspca_dev, s32 val)
 		i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
 		i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1);
 	}
-/*	PDEBUG(D_CONF , "Etoms red %d blue %d green %d",
-		I2cc[3], I2cc[0], green); */
 }
 
 static s32 getcolors(struct gspca_dev *gspca_dev)
@@ -451,7 +450,7 @@ static void Et_init1(struct gspca_dev *gspca_dev)
 /*	__u8 I2c0 [] = {0x0a, 0x12, 0x05, 0xfe, 0xfe, 0xc0, 0x01, 0x00};
 						 * 1/60000 hmm ?? */
 
-	PDEBUG(D_STREAM, "Open Init1 ET");
+	gspca_dbg(gspca_dev, D_STREAM, "Open Init1 ET\n\n");
 	reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7);
 	reg_r(gspca_dev, ET_GPIO_IN, 1);
 	reg_w_val(gspca_dev, ET_RESET_ALL, 1);
@@ -463,9 +462,9 @@ static void Et_init1(struct gspca_dev *gspca_dev)
 		value = ET_COMP_VAL1;
 	else
 		value = ET_COMP_VAL0;
-	PDEBUG(D_STREAM, "Open mode %d Compression %d",
-	       gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv,
-	       value);
+	gspca_dbg(gspca_dev, D_STREAM, "Open mode %d Compression %d\n",
+		  gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv,
+		  value);
 	reg_w_val(gspca_dev, ET_COMP, value);
 	reg_w_val(gspca_dev, ET_MAXQt, 0x1d);
 	reg_w_val(gspca_dev, ET_MINQt, 0x02);
@@ -604,7 +603,8 @@ static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
 
 	if (sd->sensor == SENSOR_PAS106) {
 		i2c_r(gspca_dev, PAS106_REG0e);
-		PDEBUG(D_CONF, "Etoms gain G %d", gspca_dev->usb_buf[0]);
+		gspca_dbg(gspca_dev, D_CONF, "Etoms gain G %d\n",
+			  gspca_dev->usb_buf[0]);
 		return gspca_dev->usb_buf[0];
 	}
 	return 0x1f;
@@ -652,11 +652,11 @@ static void do_autogain(struct gspca_dev *gspca_dev)
 	b = ((b << 7) >> 10);
 	g = ((g << 9) + (g << 7) + (g << 5)) >> 10;
 	luma = LIMIT(r + g + b);
-	PDEBUG(D_FRAM, "Etoms luma G %d", luma);
+	gspca_dbg(gspca_dev, D_FRAM, "Etoms luma G %d\n", luma);
 	if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) {
 		Gbright += (luma_mean - luma) >> spring;
 		Gbright = BLIMIT(Gbright);
-		PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright);
+		gspca_dbg(gspca_dev, D_FRAM, "Etoms Gbright %d\n", Gbright);
 		Et_setgainG(gspca_dev, (__u8) Gbright);
 	}
 }
@@ -673,10 +673,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	seqframe = data[0] & 0x3f;
 	len = (int) (((data[0] & 0xc0) << 2) | data[1]);
 	if (seqframe == 0x3f) {
-		PDEBUG(D_FRAM,
-		       "header packet found datalength %d !!", len);
-		PDEBUG(D_FRAM, "G %d R %d G %d B %d",
-		       data[2], data[3], data[4], data[5]);
+		gspca_dbg(gspca_dev, D_FRAM,
+			  "header packet found datalength %d !!\n", len);
+		gspca_dbg(gspca_dev, D_FRAM, "G %d R %d G %d B %d",
+			  data[2], data[3], data[4], data[5]);
 		data += 30;
 		/* don't change datalength as the chips provided it */
 		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
diff --git a/drivers/media/usb/gspca/finepix.c b/drivers/media/usb/gspca/finepix.c
index 7bb469a..1ef1239 100644
--- a/drivers/media/usb/gspca/finepix.c
+++ b/drivers/media/usb/gspca/finepix.c
@@ -89,7 +89,7 @@ static void dostream(struct work_struct *work)
 	int ret = 0;
 	int len;
 
-	PDEBUG(D_STREAM, "dostream started");
+	gspca_dbg(gspca_dev, D_STREAM, "dostream started\n");
 
 	/* loop reading a frame */
 again:
@@ -160,7 +160,7 @@ static void dostream(struct work_struct *work)
 	}
 
 out:
-	PDEBUG(D_STREAM, "dostream stopped");
+	gspca_dbg(gspca_dev, D_STREAM, "dostream stopped\n");
 }
 
 /* this function is called at probe time */
diff --git a/drivers/media/usb/gspca/gl860/gl860.c b/drivers/media/usb/gspca/gl860/gl860.c
index cea8d7f..262200a 100644
--- a/drivers/media/usb/gspca/gl860/gl860.c
+++ b/drivers/media/usb/gspca/gl860/gl860.c
@@ -582,7 +582,7 @@ int gl860_RTx(struct gspca_dev *gspca_dev,
 		pr_err("ctrl transfer failed %4d [p%02x r%d v%04x i%04x len%d]\n",
 		       r, pref, req, val, index, len);
 	else if (len > 1 && r < len)
-		PERR("short ctrl transfer %d/%d", r, len);
+		gspca_err(gspca_dev, "short ctrl transfer %d/%d\n", r, len);
 
 	msleep(1);
 
@@ -661,7 +661,7 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
 		ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
 		msleep(56);
 
-		PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX");
+		gspca_dbg(gspca_dev, D_PROBE, "probing for sensor MI2020 or OVXXXX\n");
 		nOV = 0;
 		for (ntry = 0; ntry < 4; ntry++) {
 			ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
@@ -671,14 +671,14 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
 			ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
 			msleep(10);
 			ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
-			PDEBUG(D_PROBE, "probe=0x%02x", probe);
+			gspca_dbg(gspca_dev, D_PROBE, "probe=0x%02x\n", probe);
 			if (probe == 0xff)
 				nOV++;
 		}
 
 		if (nOV) {
-			PDEBUG(D_PROBE, "0xff -> OVXXXX");
-			PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655");
+			gspca_dbg(gspca_dev, D_PROBE, "0xff -> OVXXXX\n");
+			gspca_dbg(gspca_dev, D_PROBE, "probing for sensor OV2640 or OV9655");
 
 			nb26 = nb96 = 0;
 			for (ntry = 0; ntry < 4; ntry++) {
@@ -694,22 +694,23 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
 						1, &probe);
 
 				if (probe == 0x26 || probe == 0x40) {
-					PDEBUG(D_PROBE,
-						"probe=0x%02x -> OV2640",
-						probe);
+					gspca_dbg(gspca_dev, D_PROBE,
+						  "probe=0x%02x -> OV2640\n",
+						  probe);
 					sd->sensor = ID_OV2640;
 					nb26 += 4;
 					break;
 				}
 				if (probe == 0x96 || probe == 0x55) {
-					PDEBUG(D_PROBE,
-						"probe=0x%02x -> OV9655",
-						probe);
+					gspca_dbg(gspca_dev, D_PROBE,
+						  "probe=0x%02x -> OV9655\n",
+						  probe);
 					sd->sensor = ID_OV9655;
 					nb96 += 4;
 					break;
 				}
-				PDEBUG(D_PROBE, "probe=0x%02x", probe);
+				gspca_dbg(gspca_dev, D_PROBE, "probe=0x%02x\n",
+					  probe);
 				if (probe == 0x00)
 					nb26++;
 				if (probe == 0xff)
@@ -719,21 +720,21 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
 			if (nb26 < 4 && nb96 < 4)
 				return -1;
 		} else {
-			PDEBUG(D_PROBE, "Not any 0xff -> MI2020");
+			gspca_dbg(gspca_dev, D_PROBE, "Not any 0xff -> MI2020\n");
 			sd->sensor = ID_MI2020;
 		}
 	}
 
 	if (_MI1320_) {
-		PDEBUG(D_PROBE, "05e3:f191 sensor MI1320 (1.3M)");
+		gspca_dbg(gspca_dev, D_PROBE, "05e3:f191 sensor MI1320 (1.3M)\n");
 	} else if (_MI2020_) {
-		PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 (2.0M)");
+		gspca_dbg(gspca_dev, D_PROBE, "05e3:0503 sensor MI2020 (2.0M)\n");
 	} else if (_OV9655_) {
-		PDEBUG(D_PROBE, "05e3:0503 sensor OV9655 (1.3M)");
+		gspca_dbg(gspca_dev, D_PROBE, "05e3:0503 sensor OV9655 (1.3M)\n");
 	} else if (_OV2640_) {
-		PDEBUG(D_PROBE, "05e3:0503 sensor OV2640 (2.0M)");
+		gspca_dbg(gspca_dev, D_PROBE, "05e3:0503 sensor OV2640 (2.0M)\n");
 	} else {
-		PDEBUG(D_PROBE, "***** Unknown sensor *****");
+		gspca_dbg(gspca_dev, D_PROBE, "***** Unknown sensor *****\n");
 		return -1;
 	}
 
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index b72d02e..87e18d0 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -63,18 +63,18 @@ static void PDEBUG_MODE(struct gspca_dev *gspca_dev, int debug, char *txt,
 			__u32 pixfmt, int w, int h)
 {
 	if ((pixfmt >> 24) >= '0' && (pixfmt >> 24) <= 'z') {
-		PDEBUG(debug, "%s %c%c%c%c %dx%d",
-			txt,
-			pixfmt & 0xff,
-			(pixfmt >> 8) & 0xff,
-			(pixfmt >> 16) & 0xff,
-			pixfmt >> 24,
-			w, h);
+		gspca_dbg(gspca_dev, debug, "%s %c%c%c%c %dx%d\n",
+			  txt,
+			  pixfmt & 0xff,
+			  (pixfmt >> 8) & 0xff,
+			  (pixfmt >> 16) & 0xff,
+			  pixfmt >> 24,
+			  w, h);
 	} else {
-		PDEBUG(debug, "%s 0x%08x %dx%d",
-			txt,
-			pixfmt,
-			w, h);
+		gspca_dbg(gspca_dev, debug, "%s 0x%08x %dx%d\n",
+			  txt,
+			  pixfmt,
+			  w, h);
 	}
 }
 
@@ -122,7 +122,7 @@ static void int_irq(struct urb *urb)
 	case 0:
 		if (gspca_dev->sd_desc->int_pkt_scan(gspca_dev,
 		    urb->transfer_buffer, urb->actual_length) < 0) {
-			PERR("Unknown packet received");
+			gspca_err(gspca_dev, "Unknown packet received\n");
 		}
 		break;
 
@@ -136,7 +136,8 @@ static void int_irq(struct urb *urb)
 		break;
 
 	default:
-		PERR("URB error %i, resubmitting", urb->status);
+		gspca_err(gspca_dev, "URB error %i, resubmitting\n",
+			  urb->status);
 		urb->status = 0;
 		ret = 0;
 	}
@@ -197,8 +198,8 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
 
 	buffer_len = le16_to_cpu(ep->wMaxPacketSize);
 	interval = ep->bInterval;
-	PDEBUG(D_CONF, "found int in endpoint: 0x%x, buffer_len=%u, interval=%u",
-		ep->bEndpointAddress, buffer_len, interval);
+	gspca_dbg(gspca_dev, D_CONF, "found int in endpoint: 0x%x, buffer_len=%u, interval=%u\n",
+		  ep->bEndpointAddress, buffer_len, interval);
 
 	dev = gspca_dev->dev;
 
@@ -221,7 +222,8 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
 	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	ret = usb_submit_urb(urb, GFP_KERNEL);
 	if (ret < 0) {
-		PERR("submit int URB failed with error %i", ret);
+		gspca_err(gspca_dev, "submit int URB failed with error %i\n",
+			  ret);
 		goto error_submit;
 	}
 	gspca_dev->int_urb = urb;
@@ -307,7 +309,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
 		if (gspca_dev->frozen)
 			return;
 #endif
-		PERR("urb status: %d", urb->status);
+		gspca_err(gspca_dev, "urb status: %d\n", urb->status);
 		urb->status = 0;
 		goto resubmit;
 	}
@@ -330,8 +332,8 @@ static void fill_frame(struct gspca_dev *gspca_dev,
 		}
 
 		/* let the packet be analyzed by the subdriver */
-		PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
-			i, urb->iso_frame_desc[i].offset, len);
+		gspca_dbg(gspca_dev, D_PACK, "packet [%d] o:%d l:%d\n",
+			  i, urb->iso_frame_desc[i].offset, len);
 		data = (u8 *) urb->transfer_buffer
 					+ urb->iso_frame_desc[i].offset;
 		pkt_scan(gspca_dev, data, len);
@@ -353,7 +355,7 @@ static void isoc_irq(struct urb *urb)
 {
 	struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
 
-	PDEBUG(D_PACK, "isoc irq");
+	gspca_dbg(gspca_dev, D_PACK, "isoc irq\n");
 	if (!gspca_dev->streaming)
 		return;
 	fill_frame(gspca_dev, urb);
@@ -367,7 +369,7 @@ static void bulk_irq(struct urb *urb)
 	struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
 	int st;
 
-	PDEBUG(D_PACK, "bulk irq");
+	gspca_dbg(gspca_dev, D_PACK, "bulk irq\n");
 	if (!gspca_dev->streaming)
 		return;
 	switch (urb->status) {
@@ -380,12 +382,12 @@ static void bulk_irq(struct urb *urb)
 		if (gspca_dev->frozen)
 			return;
 #endif
-		PERR("urb status: %d", urb->status);
+		gspca_err(gspca_dev, "urb status: %d\n", urb->status);
 		urb->status = 0;
 		goto resubmit;
 	}
 
-	PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
+	gspca_dbg(gspca_dev, D_PACK, "packet l:%d\n", urb->actual_length);
 	gspca_dev->sd_desc->pkt_scan(gspca_dev,
 				urb->transfer_buffer,
 				urb->actual_length);
@@ -418,7 +420,7 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
 	struct gspca_frame *frame;
 	int i, j;
 
-	PDEBUG(D_PACK, "add t:%d l:%d",	packet_type, len);
+	gspca_dbg(gspca_dev, D_PACK, "add t:%d l:%d\n",	packet_type, len);
 
 	if (packet_type == FIRST_PACKET) {
 		i = atomic_read(&gspca_dev->fr_i);
@@ -452,9 +454,9 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
 	/* append the packet to the frame buffer */
 	if (len > 0) {
 		if (gspca_dev->image_len + len > gspca_dev->frsz) {
-			PERR("frame overflow %d > %d",
-				gspca_dev->image_len + len,
-				gspca_dev->frsz);
+			gspca_err(gspca_dev, "frame overflow %d > %d\n",
+				  gspca_dev->image_len + len,
+				  gspca_dev->frsz);
 			packet_type = DISCARD_PACKET;
 		} else {
 /* !! image is NULL only when last pkt is LAST or DISCARD
@@ -484,8 +486,8 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
 		i = (i + 1) % GSPCA_MAX_FRAMES;
 		atomic_set(&gspca_dev->fr_i, i);
 		wake_up_interruptible(&gspca_dev->wq);	/* event = new frame */
-		PDEBUG(D_FRAM, "frame complete len:%d",
-			frame->v4l2_buf.bytesused);
+		gspca_dbg(gspca_dev, D_FRAM, "frame complete len:%d\n",
+			  frame->v4l2_buf.bytesused);
 		gspca_dev->image = NULL;
 		gspca_dev->image_len = 0;
 	}
@@ -500,7 +502,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file,
 	int i;
 
 	frsz = gspca_dev->pixfmt.sizeimage;
-	PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
+	gspca_dbg(gspca_dev, D_STREAM, "frame alloc frsz: %d\n", frsz);
 	frsz = PAGE_ALIGN(frsz);
 	if (count >= GSPCA_MAX_FRAMES)
 		count = GSPCA_MAX_FRAMES - 1;
@@ -535,7 +537,7 @@ static void frame_free(struct gspca_dev *gspca_dev)
 {
 	int i;
 
-	PDEBUG(D_STREAM, "frame free");
+	gspca_dbg(gspca_dev, D_STREAM, "frame free\n");
 	if (gspca_dev->frbuf != NULL) {
 		vfree(gspca_dev->frbuf);
 		gspca_dev->frbuf = NULL;
@@ -553,7 +555,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
 	struct urb *urb;
 	unsigned int i;
 
-	PDEBUG(D_STREAM, "kill transfer");
+	gspca_dbg(gspca_dev, D_STREAM, "kill transfer\n");
 	for (i = 0; i < MAX_NURBS; i++) {
 		urb = gspca_dev->urb[i];
 		if (urb == NULL)
@@ -594,7 +596,7 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
 	gspca_input_create_urb(gspca_dev);
 	if (gspca_dev->sd_desc->stop0)
 		gspca_dev->sd_desc->stop0(gspca_dev);
-	PDEBUG(D_STREAM, "stream off OK");
+	gspca_dbg(gspca_dev, D_STREAM, "stream off OK\n");
 }
 
 /*
@@ -653,7 +655,7 @@ static u32 which_bandwidth(struct gspca_dev *gspca_dev)
 			bandwidth *= 30;		/* 30 fps */
 	}
 
-	PDEBUG(D_STREAM, "min bandwidth: %d", bandwidth);
+	gspca_dbg(gspca_dev, D_STREAM, "min bandwidth: %d\n", bandwidth);
 	return bandwidth;
 }
 
@@ -713,8 +715,8 @@ static int build_isoc_ep_tb(struct gspca_dev *gspca_dev,
 		}
 		if (!found)
 			break;
-		PDEBUG(D_STREAM, "alt %d bandwidth %d",
-				ep_tb->alt, ep_tb->bandwidth);
+		gspca_dbg(gspca_dev, D_STREAM, "alt %d bandwidth %d\n",
+			  ep_tb->alt, ep_tb->bandwidth);
 		last_bw = ep_tb->bandwidth;
 		i++;
 		ep_tb++;
@@ -732,7 +734,7 @@ static int build_isoc_ep_tb(struct gspca_dev *gspca_dev,
 			gspca_dev->dev->speed == USB_SPEED_FULL &&
 			last_bw >= 1000000 &&
 			i > 1) {
-		PDEBUG(D_STREAM, "dev has usb audio, skipping highest alt");
+		gspca_dbg(gspca_dev, D_STREAM, "dev has usb audio, skipping highest alt\n");
 		i--;
 		ep_tb--;
 	}
@@ -772,16 +774,16 @@ static int create_urbs(struct gspca_dev *gspca_dev,
 		if (npkt == 0)
 			npkt = 32;		/* default value */
 		bsize = psize * npkt;
-		PDEBUG(D_STREAM,
-			"isoc %d pkts size %d = bsize:%d",
-			npkt, psize, bsize);
+		gspca_dbg(gspca_dev, D_STREAM,
+			  "isoc %d pkts size %d = bsize:%d\n",
+			  npkt, psize, bsize);
 		nurbs = DEF_NURBS;
 	} else {				/* bulk */
 		npkt = 0;
 		bsize = gspca_dev->cam.bulk_size;
 		if (bsize == 0)
 			bsize = psize;
-		PDEBUG(D_STREAM, "bulk bsize:%d", bsize);
+		gspca_dbg(gspca_dev, D_STREAM, "bulk bsize:%d\n", bsize);
 		if (gspca_dev->cam.bulk_nurbs != 0)
 			nurbs = gspca_dev->cam.bulk_nurbs;
 		else
@@ -900,7 +902,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
 			}
 		}
 		if (!gspca_dev->cam.no_urb_create) {
-			PDEBUG(D_STREAM, "init transfer alt %d", alt);
+			gspca_dbg(gspca_dev, D_STREAM, "init transfer alt %d\n",
+				  alt);
 			ret = create_urbs(gspca_dev,
 				alt_xfer(&intf->altsetting[alt], xfer,
 					 gspca_dev->xfer_ep));
@@ -952,7 +955,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
 		/* the bandwidth is not wide enough
 		 * negotiate or try a lower alternate setting */
 retry:
-		PERR("alt %d - bandwidth not wide enough, trying again", alt);
+		gspca_err(gspca_dev, "alt %d - bandwidth not wide enough, trying again\n",
+			  alt);
 		msleep(20);	/* wait for kill complete */
 		if (gspca_dev->sd_desc->isoc_nego) {
 			ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);
@@ -1282,7 +1286,7 @@ static int dev_open(struct file *file)
 	struct gspca_dev *gspca_dev = video_drvdata(file);
 	int ret;
 
-	PDEBUG(D_STREAM, "[%s] open", current->comm);
+	gspca_dbg(gspca_dev, D_STREAM, "[%s] open\n", current->comm);
 
 	/* protect the subdriver against rmmod */
 	if (!try_module_get(gspca_dev->module))
@@ -1298,7 +1302,7 @@ static int dev_close(struct file *file)
 {
 	struct gspca_dev *gspca_dev = video_drvdata(file);
 
-	PDEBUG(D_STREAM, "[%s] close", current->comm);
+	gspca_dbg(gspca_dev, D_STREAM, "[%s] close\n", current->comm);
 
 	/* Needed for gspca_stream_off, always lock before queue_lock! */
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
@@ -1319,7 +1323,7 @@ static int dev_close(struct file *file)
 	mutex_unlock(&gspca_dev->queue_lock);
 	mutex_unlock(&gspca_dev->usb_lock);
 
-	PDEBUG(D_STREAM, "close done");
+	gspca_dbg(gspca_dev, D_STREAM, "close done\n");
 
 	return v4l2_fh_release(file);
 }
@@ -1440,7 +1444,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 	}
 out:
 	mutex_unlock(&gspca_dev->queue_lock);
-	PDEBUG(D_STREAM, "reqbufs st:%d c:%d", ret, rb->count);
+	gspca_dbg(gspca_dev, D_STREAM, "reqbufs st:%d c:%d\n", ret, rb->count);
 	return ret;
 }
 
@@ -1598,7 +1602,8 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
 
 	start = vma->vm_start;
 	size = vma->vm_end - vma->vm_start;
-	PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size);
+	gspca_dbg(gspca_dev, D_STREAM, "mmap start:%08x size:%d\n",
+		  (int) start, (int)size);
 
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 		return -ERESTARTSYS;
@@ -1610,7 +1615,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
 	frame = NULL;
 	for (i = 0; i < gspca_dev->nframes; ++i) {
 		if (gspca_dev->frame[i].v4l2_buf.memory != V4L2_MEMORY_MMAP) {
-			PDEBUG(D_STREAM, "mmap bad memory type");
+			gspca_dbg(gspca_dev, D_STREAM, "mmap bad memory type\n");
 			break;
 		}
 		if ((gspca_dev->frame[i].v4l2_buf.m.offset >> PAGE_SHIFT)
@@ -1620,12 +1625,12 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
 		}
 	}
 	if (frame == NULL) {
-		PDEBUG(D_STREAM, "mmap no frame buffer found");
+		gspca_dbg(gspca_dev, D_STREAM, "mmap no frame buffer found\n");
 		ret = -EINVAL;
 		goto out;
 	}
 	if (size != frame->v4l2_buf.length) {
-		PDEBUG(D_STREAM, "mmap bad size");
+		gspca_dbg(gspca_dev, D_STREAM, "mmap bad size\n");
 		ret = -EINVAL;
 		goto out;
 	}
@@ -1693,7 +1698,7 @@ static int vidioc_dqbuf(struct file *file, void *priv,
 	struct gspca_frame *frame;
 	int i, j, ret;
 
-	PDEBUG(D_FRAM, "dqbuf");
+	gspca_dbg(gspca_dev, D_FRAM, "dqbuf\n");
 
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 		return -ERESTARTSYS;
@@ -1731,14 +1736,14 @@ static int vidioc_dqbuf(struct file *file, void *priv,
 
 	frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
 	memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
-	PDEBUG(D_FRAM, "dqbuf %d", j);
+	gspca_dbg(gspca_dev, D_FRAM, "dqbuf %d\n", j);
 	ret = 0;
 
 	if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
 		if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,
 				 frame->data,
 				 frame->v4l2_buf.bytesused)) {
-			PERR("dqbuf cp to user failed");
+			gspca_err(gspca_dev, "dqbuf cp to user failed\n");
 			ret = -EFAULT;
 		}
 	}
@@ -1769,27 +1774,27 @@ static int vidioc_qbuf(struct file *file, void *priv,
 	struct gspca_frame *frame;
 	int i, index, ret;
 
-	PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index);
+	gspca_dbg(gspca_dev, D_FRAM, "qbuf %d\n", v4l2_buf->index);
 
 	if (mutex_lock_interruptible(&gspca_dev->queue_lock))
 		return -ERESTARTSYS;
 
 	index = v4l2_buf->index;
 	if ((unsigned) index >= gspca_dev->nframes) {
-		PDEBUG(D_FRAM,
-			"qbuf idx %d >= %d", index, gspca_dev->nframes);
+		gspca_dbg(gspca_dev, D_FRAM,
+			  "qbuf idx %d >= %d\n", index, gspca_dev->nframes);
 		ret = -EINVAL;
 		goto out;
 	}
 	if (v4l2_buf->memory != gspca_dev->memory) {
-		PDEBUG(D_FRAM, "qbuf bad memory type");
+		gspca_dbg(gspca_dev, D_FRAM, "qbuf bad memory type\n");
 		ret = -EINVAL;
 		goto out;
 	}
 
 	frame = &gspca_dev->frame[index];
 	if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) {
-		PDEBUG(D_FRAM, "qbuf bad state");
+		gspca_dbg(gspca_dev, D_FRAM, "qbuf bad state\n");
 		ret = -EINVAL;
 		goto out;
 	}
@@ -1823,7 +1828,7 @@ static int read_alloc(struct gspca_dev *gspca_dev,
 	struct v4l2_buffer v4l2_buf;
 	int i, ret;
 
-	PDEBUG(D_STREAM, "read alloc");
+	gspca_dbg(gspca_dev, D_STREAM, "read alloc\n");
 
 	if (mutex_lock_interruptible(&gspca_dev->usb_lock))
 		return -ERESTARTSYS;
@@ -1837,7 +1842,8 @@ static int read_alloc(struct gspca_dev *gspca_dev,
 		rb.memory = GSPCA_MEMORY_READ;
 		ret = vidioc_reqbufs(file, gspca_dev, &rb);
 		if (ret != 0) {
-			PDEBUG(D_STREAM, "read reqbuf err %d", ret);
+			gspca_dbg(gspca_dev, D_STREAM, "read reqbuf err %d\n",
+				  ret);
 			goto out;
 		}
 		memset(&v4l2_buf, 0, sizeof v4l2_buf);
@@ -1847,7 +1853,8 @@ static int read_alloc(struct gspca_dev *gspca_dev,
 			v4l2_buf.index = i;
 			ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
 			if (ret != 0) {
-				PDEBUG(D_STREAM, "read qbuf err: %d", ret);
+				gspca_dbg(gspca_dev, D_STREAM, "read qbuf err: %d\n",
+					  ret);
 				goto out;
 			}
 		}
@@ -1856,7 +1863,7 @@ static int read_alloc(struct gspca_dev *gspca_dev,
 	/* start streaming */
 	ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE);
 	if (ret != 0)
-		PDEBUG(D_STREAM, "read streamon err %d", ret);
+		gspca_dbg(gspca_dev, D_STREAM, "read streamon err %d\n", ret);
 out:
 	mutex_unlock(&gspca_dev->usb_lock);
 	return ret;
@@ -1868,7 +1875,7 @@ static __poll_t dev_poll(struct file *file, poll_table *wait)
 	__poll_t req_events = poll_requested_events(wait);
 	__poll_t ret = 0;
 
-	PDEBUG(D_FRAM, "poll");
+	gspca_dbg(gspca_dev, D_FRAM, "poll\n");
 
 	if (req_events & POLLPRI)
 		ret |= v4l2_ctrl_poll(file, wait);
@@ -1910,7 +1917,7 @@ static ssize_t dev_read(struct file *file, char __user *data,
 	struct timeval timestamp;
 	int n, ret, ret2;
 
-	PDEBUG(D_FRAM, "read (%zd)", count);
+	gspca_dbg(gspca_dev, D_FRAM, "read (%zd)\n", count);
 	if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */
 		ret = read_alloc(gspca_dev, file);
 		if (ret != 0)
@@ -1927,7 +1934,8 @@ static ssize_t dev_read(struct file *file, char __user *data,
 		v4l2_buf.memory = GSPCA_MEMORY_READ;
 		ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf);
 		if (ret != 0) {
-			PDEBUG(D_STREAM, "read dqbuf err %d", ret);
+			gspca_dbg(gspca_dev, D_STREAM, "read dqbuf err %d\n",
+				  ret);
 			return ret;
 		}
 
@@ -1940,7 +1948,8 @@ static ssize_t dev_read(struct file *file, char __user *data,
 			break;
 		ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
 		if (ret != 0) {
-			PDEBUG(D_STREAM, "read qbuf err %d", ret);
+			gspca_dbg(gspca_dev, D_STREAM, "read qbuf err %d\n",
+				  ret);
 			return ret;
 		}
 	}
@@ -1950,7 +1959,8 @@ static ssize_t dev_read(struct file *file, char __user *data,
 		count = frame->v4l2_buf.bytesused;
 	ret = copy_to_user(data, frame->data, count);
 	if (ret != 0) {
-		PERR("read cp to user lack %d / %zd", ret, count);
+		gspca_err(gspca_dev, "read cp to user lack %d / %zd\n",
+			  ret, count);
 		ret = -EFAULT;
 		goto out;
 	}
@@ -2128,7 +2138,8 @@ int gspca_dev_probe2(struct usb_interface *intf,
 	}
 
 	usb_set_intfdata(intf, gspca_dev);
-	PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev));
+	gspca_dbg(gspca_dev, D_PROBE, "%s created\n",
+		  video_device_node_name(&gspca_dev->vdev));
 
 	gspca_input_create_urb(gspca_dev);
 
@@ -2183,8 +2194,8 @@ void gspca_disconnect(struct usb_interface *intf)
 	struct input_dev *input_dev;
 #endif
 
-	PDEBUG(D_PROBE, "%s disconnect",
-		video_device_node_name(&gspca_dev->vdev));
+	gspca_dbg(gspca_dev, D_PROBE, "%s disconnect\n",
+		  video_device_node_name(&gspca_dev->vdev));
 
 	mutex_lock(&gspca_dev->usb_lock);
 
diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h
index 9e0cf71..249cb38a 100644
--- a/drivers/media/usb/gspca/gspca.h
+++ b/drivers/media/usb/gspca/gspca.h
@@ -26,11 +26,12 @@
 extern int gspca_debug;
 
 
-#define PDEBUG(level, fmt, ...) \
-	v4l2_dbg(level, gspca_debug, &gspca_dev->v4l2_dev, fmt, ##__VA_ARGS__)
+#define gspca_dbg(gspca_dev, level, fmt, ...)			\
+	v4l2_dbg(level, gspca_debug, &(gspca_dev)->v4l2_dev,	\
+		 fmt, ##__VA_ARGS__)
 
-#define PERR(fmt, ...) \
-	v4l2_err(&gspca_dev->v4l2_dev, fmt, ##__VA_ARGS__)
+#define gspca_err(gspca_dev, fmt, ...)				\
+	v4l2_err(&(gspca_dev)->v4l2_dev, fmt, ##__VA_ARGS__)
 
 #define GSPCA_MAX_FRAMES 16	/* maximum number of video frame buffers */
 /* image transfers */
diff --git a/drivers/media/usb/gspca/jeilinj.c b/drivers/media/usb/gspca/jeilinj.c
index 34e043b..86d0a0a 100644
--- a/drivers/media/usb/gspca/jeilinj.c
+++ b/drivers/media/usb/gspca/jeilinj.c
@@ -262,7 +262,7 @@ static int jlj_start(struct gspca_dev *gspca_dev)
 	msleep(2);
 	setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
 	if (gspca_dev->usb_err < 0)
-		PERR("Start streaming command failed");
+		gspca_err(gspca_dev, "Start streaming command failed\n");
 	return gspca_dev->usb_err;
 }
 
@@ -273,17 +273,18 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	int packet_type;
 	u32 header_marker;
 
-	PDEBUG(D_STREAM, "Got %d bytes out of %d for Block 0",
-			len, JEILINJ_MAX_TRANSFER);
+	gspca_dbg(gspca_dev, D_STREAM, "Got %d bytes out of %d for Block 0\n",
+		  len, JEILINJ_MAX_TRANSFER);
 	if (len != JEILINJ_MAX_TRANSFER) {
-		PDEBUG(D_PACK, "bad length");
+		gspca_dbg(gspca_dev, D_PACK, "bad length\n");
 		goto discard;
 	}
 	/* check if it's start of frame */
 	header_marker = ((u32 *)data)[0];
 	if (header_marker == FRAME_START) {
 		sd->blocks_left = data[0x0a] - 1;
-		PDEBUG(D_STREAM, "blocks_left = 0x%x", sd->blocks_left);
+		gspca_dbg(gspca_dev, D_STREAM, "blocks_left = 0x%x\n",
+			  sd->blocks_left);
 		/* Start a new frame, and add the JPEG header, first thing */
 		gspca_frame_add(gspca_dev, FIRST_PACKET,
 				sd->jpeg_hdr, JPEG_HDR_SZ);
@@ -292,8 +293,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 				data + FRAME_HEADER_LEN,
 				JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
 	} else if (sd->blocks_left > 0) {
-		PDEBUG(D_STREAM, "%d blocks remaining for frame",
-				sd->blocks_left);
+		gspca_dbg(gspca_dev, D_STREAM, "%d blocks remaining for frame\n",
+			  sd->blocks_left);
 		sd->blocks_left -= 1;
 		if (sd->blocks_left == 0)
 			packet_type = LAST_PACKET;
@@ -378,8 +379,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
 			gspca_dev->pixfmt.width,
 			0x21);          /* JPEG 422 */
 	jpeg_set_qual(dev->jpeg_hdr, dev->quality);
-	PDEBUG(D_STREAM, "Start streaming at %dx%d",
-		gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
+	gspca_dbg(gspca_dev, D_STREAM, "Start streaming at %dx%d\n",
+		  gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
 	jlj_start(gspca_dev);
 	return gspca_dev->usb_err;
 }
diff --git a/drivers/media/usb/gspca/jl2005bcd.c b/drivers/media/usb/gspca/jl2005bcd.c
index 17c7a95..d668589 100644
--- a/drivers/media/usb/gspca/jl2005bcd.c
+++ b/drivers/media/usb/gspca/jl2005bcd.c
@@ -149,7 +149,8 @@ static int jl2005c_start_new_frame(struct gspca_dev *gspca_dev)
 			return retval;
 		i++;
 	}
-	PDEBUG(D_FRAM, "frame_brightness is 0x%02x", gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_FRAM, "frame_brightness is 0x%02x\n",
+		  gspca_dev->usb_buf[0]);
 	return retval;
 }
 
@@ -176,10 +177,11 @@ static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev)
 	int retval = -1;
 	unsigned char regs_to_read[] = {0x57, 0x02, 0x03, 0x5d, 0x5e, 0x5f};
 
-	PDEBUG(D_PROBE, "Running jl2005c_get_firmware_id");
+	gspca_dbg(gspca_dev, D_PROBE, "Running jl2005c_get_firmware_id\n");
 	/* Read the first ID byte once for warmup */
 	retval = jl2005c_read_reg(gspca_dev, regs_to_read[0]);
-	PDEBUG(D_PROBE, "response is %02x", gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_PROBE, "response is %02x\n",
+		  gspca_dev->usb_buf[0]);
 	if (retval < 0)
 		return retval;
 	/* Now actually get the ID string */
@@ -189,13 +191,13 @@ static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev)
 			return retval;
 		sd->firmware_id[i] = gspca_dev->usb_buf[0];
 	}
-	PDEBUG(D_PROBE, "firmware ID is %02x%02x%02x%02x%02x%02x",
-						sd->firmware_id[0],
-						sd->firmware_id[1],
-						sd->firmware_id[2],
-						sd->firmware_id[3],
-						sd->firmware_id[4],
-						sd->firmware_id[5]);
+	gspca_dbg(gspca_dev, D_PROBE, "firmware ID is %02x%02x%02x%02x%02x%02x\n",
+		  sd->firmware_id[0],
+		  sd->firmware_id[1],
+		  sd->firmware_id[2],
+		  sd->firmware_id[3],
+		  sd->firmware_id[4],
+		  sd->firmware_id[5]);
 	return 0;
 }
 
@@ -341,9 +343,9 @@ static void jl2005c_dostream(struct work_struct *work)
 				usb_rcvbulkpipe(gspca_dev->dev, 0x82),
 				buffer, JL2005C_MAX_TRANSFER, &act_len,
 				JL2005C_DATA_TIMEOUT);
-			PDEBUG(D_PACK,
-				"Got %d bytes out of %d for header",
-					act_len, JL2005C_MAX_TRANSFER);
+			gspca_dbg(gspca_dev, D_PACK,
+				  "Got %d bytes out of %d for header\n",
+				  act_len, JL2005C_MAX_TRANSFER);
 			if (ret < 0 || act_len < JL2005C_MAX_TRANSFER)
 				goto quit_stream;
 			/* Check whether we actually got the first blodk */
@@ -354,7 +356,8 @@ static void jl2005c_dostream(struct work_struct *work)
 			/* total size to fetch is byte 7, times blocksize
 			 * of which we already got act_len */
 			bytes_left = buffer[0x07] * dev->block_size - act_len;
-			PDEBUG(D_PACK, "bytes_left = 0x%x", bytes_left);
+			gspca_dbg(gspca_dev, D_PACK, "bytes_left = 0x%x\n",
+				  bytes_left);
 			/* We keep the header. It has other information, too.*/
 			packet_type = FIRST_PACKET;
 			gspca_frame_add(gspca_dev, packet_type,
@@ -370,9 +373,9 @@ static void jl2005c_dostream(struct work_struct *work)
 				JL2005C_DATA_TIMEOUT);
 			if (ret < 0 || act_len < data_len)
 				goto quit_stream;
-			PDEBUG(D_PACK,
-				"Got %d bytes out of %d for frame",
-						data_len, bytes_left);
+			gspca_dbg(gspca_dev, D_PACK,
+				  "Got %d bytes out of %d for frame\n",
+				  data_len, bytes_left);
 			bytes_left -= data_len;
 			if (bytes_left == 0) {
 				packet_type = LAST_PACKET;
@@ -449,19 +452,19 @@ static int sd_start(struct gspca_dev *gspca_dev)
 
 	switch (gspca_dev->pixfmt.width) {
 	case 640:
-		PDEBUG(D_STREAM, "Start streaming at vga resolution");
+		gspca_dbg(gspca_dev, D_STREAM, "Start streaming at vga resolution\n");
 		jl2005c_stream_start_vga_lg(gspca_dev);
 		break;
 	case 320:
-		PDEBUG(D_STREAM, "Start streaming at qvga resolution");
+		gspca_dbg(gspca_dev, D_STREAM, "Start streaming at qvga resolution\n");
 		jl2005c_stream_start_vga_small(gspca_dev);
 		break;
 	case 352:
-		PDEBUG(D_STREAM, "Start streaming at cif resolution");
+		gspca_dbg(gspca_dev, D_STREAM, "Start streaming at cif resolution\n");
 		jl2005c_stream_start_cif_lg(gspca_dev);
 		break;
 	case 176:
-		PDEBUG(D_STREAM, "Start streaming at qcif resolution");
+		gspca_dbg(gspca_dev, D_STREAM, "Start streaming at qcif resolution\n");
 		jl2005c_stream_start_cif_small(gspca_dev);
 		break;
 	default:
diff --git a/drivers/media/usb/gspca/kinect.c b/drivers/media/usb/gspca/kinect.c
index 2f28b38..0cfdf8a 100644
--- a/drivers/media/usb/gspca/kinect.c
+++ b/drivers/media/usb/gspca/kinect.c
@@ -151,8 +151,9 @@ static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf,
 	memcpy(obuf+sizeof(*chdr), cmdbuf, cmd_len);
 
 	res = kinect_write(udev, obuf, cmd_len + sizeof(*chdr));
-	PDEBUG(D_USBO, "Control cmd=%04x tag=%04x len=%04x: %d", cmd,
-		sd->cam_tag, cmd_len, res);
+	gspca_dbg(gspca_dev, D_USBO, "Control cmd=%04x tag=%04x len=%04x: %d\n",
+		  cmd,
+		  sd->cam_tag, cmd_len, res);
 	if (res < 0) {
 		pr_err("send_cmd: Output control transfer failed (%d)\n", res);
 		return res;
@@ -161,7 +162,7 @@ static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf,
 	do {
 		actual_len = kinect_read(udev, ibuf, 0x200);
 	} while (actual_len == 0);
-	PDEBUG(D_USBO, "Control reply: %d", actual_len);
+	gspca_dbg(gspca_dev, D_USBO, "Control reply: %d\n", actual_len);
 	if (actual_len < sizeof(*rhdr)) {
 		pr_err("send_cmd: Input control transfer failed (%d)\n",
 		       actual_len);
@@ -213,7 +214,7 @@ static int write_register(struct gspca_dev *gspca_dev, uint16_t reg,
 	cmd[0] = cpu_to_le16(reg);
 	cmd[1] = cpu_to_le16(data);
 
-	PDEBUG(D_USBO, "Write Reg 0x%04x <= 0x%02x", reg, data);
+	gspca_dbg(gspca_dev, D_USBO, "Write Reg 0x%04x <= 0x%02x\n", reg, data);
 	res = send_cmd(gspca_dev, 0x03, cmd, 4, reply, 4);
 	if (res < 0)
 		return res;
@@ -274,7 +275,7 @@ static int sd_config_depth(struct gspca_dev *gspca_dev,
 /* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-	PDEBUG(D_PROBE, "Kinect Camera device.");
+	gspca_dbg(gspca_dev, D_PROBE, "Kinect Camera device.\n");
 
 	return 0;
 }
diff --git a/drivers/media/usb/gspca/konica.c b/drivers/media/usb/gspca/konica.c
index 31b2117..989ae99 100644
--- a/drivers/media/usb/gspca/konica.c
+++ b/drivers/media/usb/gspca/konica.c
@@ -263,7 +263,7 @@ static void sd_isoc_irq(struct urb *urb)
 	u8 *data;
 	int i, st;
 
-	PDEBUG(D_PACK, "sd isoc irq");
+	gspca_dbg(gspca_dev, D_PACK, "sd isoc irq\n");
 	if (!gspca_dev->streaming)
 		return;
 
@@ -274,7 +274,7 @@ static void sd_isoc_irq(struct urb *urb)
 		if (gspca_dev->frozen)
 			return;
 #endif
-		PERR("urb status: %d", urb->status);
+		gspca_err(gspca_dev, "urb status: %d\n", urb->status);
 		st = usb_submit_urb(urb, GFP_ATOMIC);
 		if (st < 0)
 			pr_err("resubmit urb error %d\n", st);
@@ -292,30 +292,31 @@ static void sd_isoc_irq(struct urb *urb)
 	sd->last_data_urb = NULL;
 
 	if (!data_urb || data_urb->start_frame != status_urb->start_frame) {
-		PERR("lost sync on frames");
+		gspca_err(gspca_dev, "lost sync on frames\n");
 		goto resubmit;
 	}
 
 	if (data_urb->number_of_packets != status_urb->number_of_packets) {
-		PERR("no packets does not match, data: %d, status: %d",
-		     data_urb->number_of_packets,
-		     status_urb->number_of_packets);
+		gspca_err(gspca_dev, "no packets does not match, data: %d, status: %d\n",
+			  data_urb->number_of_packets,
+			  status_urb->number_of_packets);
 		goto resubmit;
 	}
 
 	for (i = 0; i < status_urb->number_of_packets; i++) {
 		if (data_urb->iso_frame_desc[i].status ||
 		    status_urb->iso_frame_desc[i].status) {
-			PERR("pkt %d data-status %d, status-status %d", i,
-			     data_urb->iso_frame_desc[i].status,
-			     status_urb->iso_frame_desc[i].status);
+			gspca_err(gspca_dev, "pkt %d data-status %d, status-status %d\n",
+				  i,
+				  data_urb->iso_frame_desc[i].status,
+				  status_urb->iso_frame_desc[i].status);
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			continue;
 		}
 
 		if (status_urb->iso_frame_desc[i].actual_length != 1) {
-			PERR("bad status packet length %d",
-			     status_urb->iso_frame_desc[i].actual_length);
+			gspca_err(gspca_dev, "bad status packet length %d\n",
+				  status_urb->iso_frame_desc[i].actual_length);
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			continue;
 		}
@@ -360,11 +361,12 @@ static void sd_isoc_irq(struct urb *urb)
 	if (data_urb) {
 		st = usb_submit_urb(data_urb, GFP_ATOMIC);
 		if (st < 0)
-			PERR("usb_submit_urb(data_urb) ret %d", st);
+			gspca_err(gspca_dev, "usb_submit_urb(data_urb) ret %d\n",
+				  st);
 	}
 	st = usb_submit_urb(status_urb, GFP_ATOMIC);
 	if (st < 0)
-		PERR("usb_submit_urb(status_urb) ret %d\n", st);
+		gspca_err(gspca_dev, "usb_submit_urb(status_urb) ret %d\n", st);
 }
 
 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
diff --git a/drivers/media/usb/gspca/m5602/m5602_core.c b/drivers/media/usb/gspca/m5602/m5602_core.c
index f1dcd90..b83ec42 100644
--- a/drivers/media/usb/gspca/m5602/m5602_core.c
+++ b/drivers/media/usb/gspca/m5602/m5602_core.c
@@ -66,8 +66,8 @@ int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data)
 			      1, M5602_URB_MSG_TIMEOUT);
 	*i2c_data = buf[0];
 
-	PDEBUG(D_CONF, "Reading bridge register 0x%x containing 0x%x",
-	       address, *i2c_data);
+	gspca_dbg(gspca_dev, D_CONF, "Reading bridge register 0x%x containing 0x%x\n",
+		  address, *i2c_data);
 
 	/* usb_control_msg(...) returns the number of bytes sent upon success,
 	mask that and return zero instead*/
@@ -82,8 +82,8 @@ int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data)
 	struct usb_device *udev = sd->gspca_dev.dev;
 	__u8 *buf = sd->gspca_dev.usb_buf;
 
-	PDEBUG(D_CONF, "Writing bridge register 0x%x with 0x%x",
-	       address, i2c_data);
+	gspca_dbg(gspca_dev, D_CONF, "Writing bridge register 0x%x with 0x%x\n",
+		  address, i2c_data);
 
 	memcpy(buf, bridge_urb_skeleton,
 	       sizeof(bridge_urb_skeleton));
@@ -154,8 +154,8 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
 
 		err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
 
-		PDEBUG(D_CONF, "Reading sensor register 0x%x containing 0x%x ",
-		       address, *i2c_data);
+		gspca_dbg(gspca_dev, D_CONF, "Reading sensor register 0x%x containing 0x%x\n",
+			  address, *i2c_data);
 	}
 	return err;
 }
@@ -187,8 +187,8 @@ int m5602_write_sensor(struct sd *sd, const u8 address,
 		memcpy(p, sensor_urb_skeleton + 16, 4);
 		p[3] = i2c_data[i];
 		p += 4;
-		PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
-		       address, i2c_data[i]);
+		gspca_dbg(gspca_dev, D_CONF, "Writing sensor register 0x%x with 0x%x\n",
+			  address, i2c_data[i]);
 	}
 
 	/* Copy the tailer */
@@ -264,7 +264,7 @@ static int m5602_init(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 	int err;
 
-	PDEBUG(D_CONF, "Initializing ALi m5602 webcam");
+	gspca_dbg(gspca_dev, D_CONF, "Initializing ALi m5602 webcam\n");
 	/* Run the init sequence */
 	err = sd->sensor->init(sd);
 
@@ -299,7 +299,7 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev)
 			      0x04, 0x40, 0x19, 0x0000, buf,
 			      sizeof(buffer), M5602_URB_MSG_TIMEOUT);
 
-	PDEBUG(D_STREAM, "Transfer started");
+	gspca_dbg(gspca_dev, D_STREAM, "Transfer started\n");
 	return (err < 0) ? err : 0;
 }
 
@@ -309,14 +309,14 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	if (len < 6) {
-		PDEBUG(D_PACK, "Packet is less than 6 bytes");
+		gspca_dbg(gspca_dev, D_PACK, "Packet is less than 6 bytes\n");
 		return;
 	}
 
 	/* Frame delimiter: ff xx xx xx ff ff */
 	if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff &&
 	    data[2] != sd->frame_id) {
-		PDEBUG(D_FRAM, "Frame delimiter detected");
+		gspca_dbg(gspca_dev, D_FRAM, "Frame delimiter detected\n");
 		sd->frame_id = data[2];
 
 		/* Remove the extra fluff appended on each header */
@@ -331,8 +331,8 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
 		/* Create a new frame */
 		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 
-		PDEBUG(D_FRAM, "Starting new frame %d",
-		       sd->frame_count);
+		gspca_dbg(gspca_dev, D_FRAM, "Starting new frame %d\n",
+			  sd->frame_count);
 
 	} else {
 		int cur_frame_len;
@@ -343,8 +343,8 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
 		len -= 4;
 
 		if (cur_frame_len + len <= gspca_dev->frsz) {
-			PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
-			       sd->frame_count, len);
+			gspca_dbg(gspca_dev, D_FRAM, "Continuing frame %d copying %d bytes\n",
+				  sd->frame_count, len);
 
 			gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, len);
@@ -397,7 +397,7 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
 	return 0;
 
 fail:
-	PERR("ALi m5602 webcam failed");
+	gspca_err(gspca_dev, "ALi m5602 webcam failed\n");
 	cam->cam_mode = NULL;
 	cam->nmodes = 0;
 
diff --git a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c
index 7d01ddd..c9947c4 100644
--- a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c
@@ -212,7 +212,7 @@ int mt9m111_probe(struct sd *sd)
 		return -ENODEV;
 	}
 
-	PDEBUG(D_PROBE, "Probing for a mt9m111 sensor");
+	gspca_dbg(gspca_dev, D_PROBE, "Probing for a mt9m111 sensor\n");
 
 	/* Do the preinit */
 	for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
@@ -375,11 +375,11 @@ int mt9m111_start(struct sd *sd)
 
 	switch (width) {
 	case 640:
-		PDEBUG(D_CONF, "Configuring camera for VGA mode");
+		gspca_dbg(gspca_dev, D_CONF, "Configuring camera for VGA mode\n");
 		break;
 
 	case 320:
-		PDEBUG(D_CONF, "Configuring camera for QVGA mode");
+		gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QVGA mode\n");
 		break;
 	}
 	return err;
@@ -398,7 +398,8 @@ static int mt9m111_set_hvflip(struct gspca_dev *gspca_dev)
 	int hflip;
 	int vflip;
 
-	PDEBUG(D_CONF, "Set hvflip to %d %d", sd->hflip->val, sd->vflip->val);
+	gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d %d\n",
+		  sd->hflip->val, sd->vflip->val);
 
 	/* The mt9m111 is flipped by default */
 	hflip = !sd->hflip->val;
@@ -439,7 +440,7 @@ static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
 
 	err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
 
-	PDEBUG(D_CONF, "Set auto white balance %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set auto white balance %d\n", val);
 	return err;
 }
 
@@ -472,8 +473,8 @@ static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 
 	data[1] = (tmp & 0xff);
 	data[0] = (tmp & 0xff00) >> 8;
-	PDEBUG(D_CONF, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
-	       data[1], data[0]);
+	gspca_dbg(gspca_dev, D_CONF, "tmp=%d, data[1]=%d, data[0]=%d\n", tmp,
+		  data[1], data[0]);
 
 	err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
 				   data, 2);
@@ -490,7 +491,7 @@ static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
 	data[1] = (val & 0xff);
 	data[0] = (val & 0xff00) >> 8;
 
-	PDEBUG(D_CONF, "Set green balance %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set green balance %d\n", val);
 	err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
 				 data, 2);
 	if (err < 0)
@@ -508,7 +509,7 @@ static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	data[1] = (val & 0xff);
 	data[0] = (val & 0xff00) >> 8;
 
-	PDEBUG(D_CONF, "Set blue balance %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set blue balance %d\n", val);
 
 	return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN,
 				  data, 2);
@@ -522,7 +523,7 @@ static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 	data[1] = (val & 0xff);
 	data[0] = (val & 0xff00) >> 8;
 
-	PDEBUG(D_CONF, "Set red balance %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set red balance %d\n", val);
 
 	return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN,
 				  data, 2);
diff --git a/drivers/media/usb/gspca/m5602/m5602_ov7660.c b/drivers/media/usb/gspca/m5602/m5602_ov7660.c
index 672b7a5..aa1f569 100644
--- a/drivers/media/usb/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/usb/gspca/m5602/m5602_ov7660.c
@@ -330,7 +330,7 @@ static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data = val;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Setting gain to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val);
 
 	err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
 	return err;
@@ -343,7 +343,7 @@ static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Set auto white balance to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
 
 	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
 	if (err < 0)
@@ -361,7 +361,7 @@ static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Set auto gain control to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val);
 
 	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
 	if (err < 0)
@@ -379,7 +379,7 @@ static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev,
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Set auto exposure control to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val);
 
 	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
 	if (err < 0)
@@ -397,7 +397,8 @@ static int ov7660_set_hvflip(struct gspca_dev *gspca_dev)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Set hvflip to %d, %d", sd->hflip->val, sd->vflip->val);
+	gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d, %d\n",
+		  sd->hflip->val, sd->vflip->val);
 
 	i2c_data = (sd->hflip->val << 5) | (sd->vflip->val << 4);
 
diff --git a/drivers/media/usb/gspca/m5602/m5602_ov9650.c b/drivers/media/usb/gspca/m5602/m5602_ov9650.c
index 4544d3a..2ffbb54 100644
--- a/drivers/media/usb/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/usb/gspca/m5602/m5602_ov9650.c
@@ -311,7 +311,7 @@ int ov9650_probe(struct sd *sd)
 		return -ENODEV;
 	}
 
-	PDEBUG(D_PROBE, "Probing for an ov9650 sensor");
+	gspca_dbg(gspca_dev, D_PROBE, "Probing for an ov9650 sensor\n");
 
 	/* Run the pre-init before probing the sensor */
 	for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
@@ -505,7 +505,7 @@ int ov9650_start(struct sd *sd)
 
 	switch (width) {
 	case 640:
-		PDEBUG(D_CONF, "Configuring camera for VGA mode");
+		gspca_dbg(gspca_dev, D_CONF, "Configuring camera for VGA mode\n");
 
 		data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
 		       OV9650_RAW_RGB_SELECT;
@@ -513,7 +513,7 @@ int ov9650_start(struct sd *sd)
 		break;
 
 	case 352:
-		PDEBUG(D_CONF, "Configuring camera for CIF mode");
+		gspca_dbg(gspca_dev, D_CONF, "Configuring camera for CIF mode\n");
 
 		data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
 				OV9650_RAW_RGB_SELECT;
@@ -521,7 +521,7 @@ int ov9650_start(struct sd *sd)
 		break;
 
 	case 320:
-		PDEBUG(D_CONF, "Configuring camera for QVGA mode");
+		gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QVGA mode\n");
 
 		data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
 				OV9650_RAW_RGB_SELECT;
@@ -529,7 +529,7 @@ int ov9650_start(struct sd *sd)
 		break;
 
 	case 176:
-		PDEBUG(D_CONF, "Configuring camera for QCIF mode");
+		gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QCIF mode\n");
 
 		data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
 			OV9650_RAW_RGB_SELECT;
@@ -558,7 +558,7 @@ static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	int err;
 
-	PDEBUG(D_CONF, "Set exposure to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d\n", val);
 
 	/* The 6 MSBs */
 	i2c_data = (val >> 10) & 0x3f;
@@ -586,7 +586,7 @@ static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Setting gain to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val);
 
 	/* The 2 MSB */
 	/* Read the OV9650_VREF register first to avoid
@@ -614,7 +614,7 @@ static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Set red gain to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set red gain to %d\n", val);
 
 	i2c_data = val & 0xff;
 	err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
@@ -627,7 +627,7 @@ static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Set blue gain to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set blue gain to %d\n", val);
 
 	i2c_data = val & 0xff;
 	err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
@@ -642,7 +642,7 @@ static int ov9650_set_hvflip(struct gspca_dev *gspca_dev)
 	int hflip = sd->hflip->val;
 	int vflip = sd->vflip->val;
 
-	PDEBUG(D_CONF, "Set hvflip to %d %d", hflip, vflip);
+	gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d %d\n", hflip, vflip);
 
 	if (dmi_check_system(ov9650_flip_dmi_table))
 		vflip = !vflip;
@@ -666,7 +666,7 @@ static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Set auto exposure control to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val);
 
 	err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 	if (err < 0)
@@ -685,7 +685,7 @@ static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Set auto white balance to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
 
 	err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 	if (err < 0)
@@ -703,7 +703,7 @@ static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Set auto gain control to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val);
 
 	err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
 	if (err < 0)
diff --git a/drivers/media/usb/gspca/m5602/m5602_po1030.c b/drivers/media/usb/gspca/m5602/m5602_po1030.c
index a0a90dd..37d2891 100644
--- a/drivers/media/usb/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/usb/gspca/m5602/m5602_po1030.c
@@ -171,7 +171,7 @@ int po1030_probe(struct sd *sd)
 		return -ENODEV;
 	}
 
-	PDEBUG(D_PROBE, "Probing for a po1030 sensor");
+	gspca_dbg(gspca_dev, D_PROBE, "Probing for a po1030 sensor\n");
 
 	/* Run the pre-init to actually probe the unit */
 	for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
@@ -410,11 +410,11 @@ static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	u8 i2c_data;
 	int err;
 
-	PDEBUG(D_CONF, "Set exposure to %d", val & 0xffff);
+	gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d\n", val & 0xffff);
 
 	i2c_data = ((val & 0xff00) >> 8);
-	PDEBUG(D_CONF, "Set exposure to high byte to 0x%x",
-	       i2c_data);
+	gspca_dbg(gspca_dev, D_CONF, "Set exposure to high byte to 0x%x\n",
+		  i2c_data);
 
 	err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
 				  &i2c_data, 1);
@@ -422,8 +422,8 @@ static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 		return err;
 
 	i2c_data = (val & 0xff);
-	PDEBUG(D_CONF, "Set exposure to low byte to 0x%x",
-	       i2c_data);
+	gspca_dbg(gspca_dev, D_CONF, "Set exposure to low byte to 0x%x\n",
+		  i2c_data);
 	err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
 				  &i2c_data, 1);
 
@@ -437,7 +437,7 @@ static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	int err;
 
 	i2c_data = val & 0xff;
-	PDEBUG(D_CONF, "Set global gain to %d", i2c_data);
+	gspca_dbg(gspca_dev, D_CONF, "Set global gain to %d\n", i2c_data);
 	err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
 				 &i2c_data, 1);
 	return err;
@@ -449,7 +449,8 @@ static int po1030_set_hvflip(struct gspca_dev *gspca_dev)
 	u8 i2c_data;
 	int err;
 
-	PDEBUG(D_CONF, "Set hvflip %d %d", sd->hflip->val, sd->vflip->val);
+	gspca_dbg(gspca_dev, D_CONF, "Set hvflip %d %d\n",
+		  sd->hflip->val, sd->vflip->val);
 	err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
 	if (err < 0)
 		return err;
@@ -470,7 +471,7 @@ static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 	int err;
 
 	i2c_data = val & 0xff;
-	PDEBUG(D_CONF, "Set red gain to %d", i2c_data);
+	gspca_dbg(gspca_dev, D_CONF, "Set red gain to %d\n", i2c_data);
 	err = m5602_write_sensor(sd, PO1030_RED_GAIN,
 				  &i2c_data, 1);
 	return err;
@@ -483,7 +484,7 @@ static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 	int err;
 
 	i2c_data = val & 0xff;
-	PDEBUG(D_CONF, "Set blue gain to %d", i2c_data);
+	gspca_dbg(gspca_dev, D_CONF, "Set blue gain to %d\n", i2c_data);
 	err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
 				  &i2c_data, 1);
 
@@ -497,7 +498,7 @@ static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
 	int err;
 
 	i2c_data = val & 0xff;
-	PDEBUG(D_CONF, "Set green gain to %d", i2c_data);
+	gspca_dbg(gspca_dev, D_CONF, "Set green gain to %d\n", i2c_data);
 
 	err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
 			   &i2c_data, 1);
@@ -519,7 +520,7 @@ static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
 	if (err < 0)
 		return err;
 
-	PDEBUG(D_CONF, "Set auto white balance to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
 	i2c_data = (i2c_data & 0xfe) | (val & 0x01);
 	err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
 	return err;
@@ -536,7 +537,7 @@ static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
 	if (err < 0)
 		return err;
 
-	PDEBUG(D_CONF, "Set auto exposure to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set auto exposure to %d\n", val);
 	val = (val == V4L2_EXPOSURE_AUTO);
 	i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
 	return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c
index 8447b9c..cec4a58 100644
--- a/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c
@@ -357,7 +357,7 @@ int s5k4aa_probe(struct sd *sd)
 		return -ENODEV;
 	}
 
-	PDEBUG(D_PROBE, "Probing for a s5k4aa sensor");
+	gspca_dbg(gspca_dev, D_PROBE, "Probing for a s5k4aa sensor\n");
 
 	/* Preinit the sensor */
 	for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) {
@@ -419,7 +419,7 @@ int s5k4aa_start(struct sd *sd)
 
 	switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
 	case 1280:
-		PDEBUG(D_CONF, "Configuring camera for SXGA mode");
+		gspca_dbg(gspca_dev, D_CONF, "Configuring camera for SXGA mode\n");
 
 		for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) {
 			switch (SXGA_s5k4aa[i][0]) {
@@ -452,7 +452,7 @@ int s5k4aa_start(struct sd *sd)
 		break;
 
 	case 640:
-		PDEBUG(D_CONF, "Configuring camera for VGA mode");
+		gspca_dbg(gspca_dev, D_CONF, "Configuring camera for VGA mode\n");
 
 		for (i = 0; i < ARRAY_SIZE(VGA_s5k4aa); i++) {
 			switch (VGA_s5k4aa[i][0]) {
@@ -568,7 +568,7 @@ static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
-	PDEBUG(D_CONF, "Set exposure to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d\n", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
 		return err;
@@ -590,7 +590,7 @@ static int s5k4aa_set_hvflip(struct gspca_dev *gspca_dev)
 	int hflip = sd->hflip->val;
 	int vflip = sd->vflip->val;
 
-	PDEBUG(D_CONF, "Set hvflip %d %d", hflip, vflip);
+	gspca_dbg(gspca_dev, D_CONF, "Set hvflip %d %d\n", hflip, vflip);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
 		return err;
@@ -640,7 +640,7 @@ static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
-	PDEBUG(D_CONF, "Set gain to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set gain to %d\n", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
 		return err;
@@ -657,7 +657,7 @@ static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
-	PDEBUG(D_CONF, "Set brightness to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set brightness to %d\n", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
 		return err;
@@ -672,7 +672,7 @@ static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val)
 	u8 data = S5K4AA_PAGE_MAP_2;
 	int err;
 
-	PDEBUG(D_CONF, "Set noise to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set noise to %d\n", val);
 	err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
 	if (err < 0)
 		return err;
diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
index 6ad8d48..3d8ab18 100644
--- a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
@@ -187,7 +187,7 @@ int s5k83a_probe(struct sd *sd)
 		return -ENODEV;
 	}
 
-	PDEBUG(D_PROBE, "Probing for a s5k83a sensor");
+	gspca_dbg(gspca_dev, D_PROBE, "Probing for a s5k83a sensor\n");
 
 	/* Preinit the sensor */
 	for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
diff --git a/drivers/media/usb/gspca/mars.c b/drivers/media/usb/gspca/mars.c
index 25df55e..a537cb1 100644
--- a/drivers/media/usb/gspca/mars.c
+++ b/drivers/media/usb/gspca/mars.c
@@ -378,8 +378,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			    || data[5 + p] == 0x65
 			    || data[5 + p] == 0x66
 			    || data[5 + p] == 0x67) {
-				PDEBUG(D_PACK, "sof offset: %d len: %d",
-					p, len);
+				gspca_dbg(gspca_dev, D_PACK, "sof offset: %d len: %d\n",
+					  p, len);
 				gspca_frame_add(gspca_dev, LAST_PACKET,
 						data, p);
 
diff --git a/drivers/media/usb/gspca/mr97310a.c b/drivers/media/usb/gspca/mr97310a.c
index 8b0e32a..bea1963 100644
--- a/drivers/media/usb/gspca/mr97310a.c
+++ b/drivers/media/usb/gspca/mr97310a.c
@@ -221,10 +221,11 @@ static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
 		return err_code;
 
 	if (verbose)
-		PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
-		       gspca_dev->usb_buf[0],
-		       gspca_dev->usb_buf[1],
-		       gspca_dev->usb_buf[2]);
+		gspca_dbg(gspca_dev, D_PROBE, "Register: %02x reads %02x%02x%02x\n",
+			  reg,
+			  gspca_dev->usb_buf[0],
+			  gspca_dev->usb_buf[1],
+			  gspca_dev->usb_buf[2]);
 
 	return 0;
 }
@@ -284,7 +285,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
 			return err_code;
 	}
 	if (status != 0x0a)
-		PERR("status is %02x", status);
+		gspca_err(gspca_dev, "status is %02x\n", status);
 
 	tries = 0;
 	while (tries < 4) {
@@ -325,7 +326,7 @@ static void stream_stop(struct gspca_dev *gspca_dev)
 	gspca_dev->usb_buf[0] = 0x01;
 	gspca_dev->usb_buf[1] = 0x00;
 	if (mr_write(gspca_dev, 2) < 0)
-		PERR("Stream Stop failed");
+		gspca_err(gspca_dev, "Stream Stop failed\n");
 }
 
 static void lcd_stop(struct gspca_dev *gspca_dev)
@@ -333,7 +334,7 @@ static void lcd_stop(struct gspca_dev *gspca_dev)
 	gspca_dev->usb_buf[0] = 0x19;
 	gspca_dev->usb_buf[1] = 0x54;
 	if (mr_write(gspca_dev, 2) < 0)
-		PERR("LCD Stop failed");
+		gspca_err(gspca_dev, "LCD Stop failed\n");
 }
 
 static int isoc_enable(struct gspca_dev *gspca_dev)
@@ -413,8 +414,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
 			       gspca_dev->usb_buf[1]);
 			return -ENODEV;
 		}
-		PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
-		       sd->sensor_type);
+		gspca_dbg(gspca_dev, D_PROBE, "MR97310A CIF camera detected, sensor: %d\n",
+			  sd->sensor_type);
 	} else {
 		sd->cam_type = CAM_TYPE_VGA;
 
@@ -458,7 +459,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 			switch (gspca_dev->usb_buf[1]) {
 			case 0x50:
 				sd->sensor_type = 0;
-				PDEBUG(D_PROBE, "sensor_type corrected to 0");
+				gspca_dbg(gspca_dev, D_PROBE, "sensor_type corrected to 0\n");
 				break;
 			case 0x20:
 				/* Nothing to do here. */
@@ -470,16 +471,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
 				pr_err("Please report this\n");
 			}
 		}
-		PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
-		       sd->sensor_type);
+		gspca_dbg(gspca_dev, D_PROBE, "MR97310A VGA camera detected, sensor: %d\n",
+			  sd->sensor_type);
 	}
 	/* Stop streaming as we've started it only to probe the sensor type. */
 	sd_stopN(gspca_dev);
 
 	if (force_sensor_type != -1) {
 		sd->sensor_type = !!force_sensor_type;
-		PDEBUG(D_PROBE, "Forcing sensor type to: %d",
-		       sd->sensor_type);
+		gspca_dbg(gspca_dev, D_PROBE, "Forcing sensor type to: %d\n",
+			  sd->sensor_type);
 	}
 
 	return 0;
diff --git a/drivers/media/usb/gspca/nw80x.c b/drivers/media/usb/gspca/nw80x.c
index 5d2d0bc..bedc04a 100644
--- a/drivers/media/usb/gspca/nw80x.c
+++ b/drivers/media/usb/gspca/nw80x.c
@@ -1543,10 +1543,11 @@ static void reg_w(struct gspca_dev *gspca_dev,
 	if (gspca_dev->usb_err < 0)
 		return;
 	if (len == 1)
-		PDEBUG(D_USBO, "SET 00 0000 %04x %02x", index, *data);
+		gspca_dbg(gspca_dev, D_USBO, "SET 00 0000 %04x %02x\n",
+			  index, *data);
 	else
-		PDEBUG(D_USBO, "SET 00 0000 %04x %02x %02x ...",
-				index, *data, data[1]);
+		gspca_dbg(gspca_dev, D_USBO, "SET 00 0000 %04x %02x %02x ...\n",
+			  index, *data, data[1]);
 	memcpy(gspca_dev->usb_buf, data, len);
 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 			0x00,
@@ -1583,12 +1584,12 @@ static void reg_r(struct gspca_dev *gspca_dev,
 		return;
 	}
 	if (len == 1)
-		PDEBUG(D_USBI, "GET 00 0000 %04x %02x",
-				index, gspca_dev->usb_buf[0]);
+		gspca_dbg(gspca_dev, D_USBI, "GET 00 0000 %04x %02x\n",
+			  index, gspca_dev->usb_buf[0]);
 	else
-		PDEBUG(D_USBI, "GET 00 0000 %04x %02x %02x ..",
-				index, gspca_dev->usb_buf[0],
-				gspca_dev->usb_buf[1]);
+		gspca_dbg(gspca_dev, D_USBI, "GET 00 0000 %04x %02x %02x ..\n",
+			  index, gspca_dev->usb_buf[0],
+			  gspca_dev->usb_buf[1]);
 }
 
 static void i2c_w(struct gspca_dev *gspca_dev,
@@ -1762,8 +1763,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
 			sd->webcam = P35u;
 	} else if (id->idVendor == 0x06a5 && id->idProduct == 0xd800) {
 		reg_r(gspca_dev, 0x0403, 1);		/* GPIO */
-		PDEBUG(D_PROBE, "et31x110 sensor type %02x",
-				gspca_dev->usb_buf[0]);
+		gspca_dbg(gspca_dev, D_PROBE, "et31x110 sensor type %02x\n",
+			  gspca_dev->usb_buf[0]);
 		switch (gspca_dev->usb_buf[0] >> 1) {
 		case 0x00:				/* ?? */
 			if (sd->webcam == Generic800)
@@ -1785,7 +1786,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		gspca_dev->usb_err = -ENODEV;
 		return gspca_dev->usb_err;
 	}
-	PDEBUG(D_PROBE, "Bridge nw80%d - type: %d", sd->bridge, sd->webcam);
+	gspca_dbg(gspca_dev, D_PROBE, "Bridge nw80%d - type: %d\n",
+		  sd->bridge, sd->webcam);
 
 	if (sd->bridge == BRIDGE_NW800) {
 		switch (sd->webcam) {
diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c
index 1b30434..10fcbe9 100644
--- a/drivers/media/usb/gspca/ov519.c
+++ b/drivers/media/usb/gspca/ov519.c
@@ -2016,8 +2016,8 @@ static void reg_w(struct sd *sd, u16 index, u16 value)
 		req = 0x0a;
 		/* fall through */
 	case BRIDGE_W9968CF:
-		PDEBUG(D_USBO, "SET %02x %04x %04x",
-				req, value, index);
+		gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n",
+			  req, value, index);
 		ret = usb_control_msg(sd->gspca_dev.dev,
 			usb_sndctrlpipe(sd->gspca_dev.dev, 0),
 			req,
@@ -2028,8 +2028,8 @@ static void reg_w(struct sd *sd, u16 index, u16 value)
 		req = 1;
 	}
 
-	PDEBUG(D_USBO, "SET %02x 0000 %04x %02x",
-			req, index, value);
+	gspca_dbg(gspca_dev, D_USBO, "SET %02x 0000 %04x %02x\n",
+		  req, index, value);
 	sd->gspca_dev.usb_buf[0] = value;
 	ret = usb_control_msg(sd->gspca_dev.dev,
 			usb_sndctrlpipe(sd->gspca_dev.dev, 0),
@@ -2039,7 +2039,7 @@ static void reg_w(struct sd *sd, u16 index, u16 value)
 			sd->gspca_dev.usb_buf, 1, 500);
 leave:
 	if (ret < 0) {
-		PERR("reg_w %02x failed %d\n", index, ret);
+		gspca_err(gspca_dev, "reg_w %02x failed %d\n", index, ret);
 		sd->gspca_dev.usb_err = ret;
 		return;
 	}
@@ -2078,10 +2078,10 @@ static int reg_r(struct sd *sd, u16 index)
 
 	if (ret >= 0) {
 		ret = sd->gspca_dev.usb_buf[0];
-		PDEBUG(D_USBI, "GET %02x 0000 %04x %02x",
-			req, index, ret);
+		gspca_dbg(gspca_dev, D_USBI, "GET %02x 0000 %04x %02x\n",
+			  req, index, ret);
 	} else {
-		PERR("reg_r %02x failed %d\n", index, ret);
+		gspca_err(gspca_dev, "reg_r %02x failed %d\n", index, ret);
 		sd->gspca_dev.usb_err = ret;
 	}
 
@@ -2109,7 +2109,7 @@ static int reg_r8(struct sd *sd,
 	if (ret >= 0) {
 		ret = sd->gspca_dev.usb_buf[0];
 	} else {
-		PERR("reg_r8 %02x failed %d\n", index, ret);
+		gspca_err(gspca_dev, "reg_r8 %02x failed %d\n", index, ret);
 		sd->gspca_dev.usb_err = ret;
 	}
 
@@ -2165,7 +2165,7 @@ static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
 			0, index,
 			sd->gspca_dev.usb_buf, n, 500);
 	if (ret < 0) {
-		PERR("reg_w32 %02x failed %d\n", index, ret);
+		gspca_err(gspca_dev, "reg_w32 %02x failed %d\n", index, ret);
 		sd->gspca_dev.usb_err = ret;
 	}
 }
@@ -2175,7 +2175,7 @@ static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 	int rc, retries;
 
-	PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value);
+	gspca_dbg(gspca_dev, D_USBO, "ov511_i2c_w %02x %02x\n", reg, value);
 
 	/* Three byte write cycle */
 	for (retries = 6; ; ) {
@@ -2198,7 +2198,7 @@ static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
 		if ((rc & 2) == 0) /* Ack? */
 			break;
 		if (--retries < 0) {
-			PDEBUG(D_USBO, "i2c write retries exhausted");
+			gspca_dbg(gspca_dev, D_USBO, "i2c write retries exhausted\n");
 			return;
 		}
 	}
@@ -2231,7 +2231,7 @@ static int ov511_i2c_r(struct sd *sd, u8 reg)
 		reg_w(sd, R511_I2C_CTL, 0x10);
 
 		if (--retries < 0) {
-			PDEBUG(D_USBI, "i2c write retries exhausted");
+			gspca_dbg(gspca_dev, D_USBI, "i2c write retries exhausted\n");
 			return -1;
 		}
 	}
@@ -2255,14 +2255,14 @@ static int ov511_i2c_r(struct sd *sd, u8 reg)
 		reg_w(sd, R511_I2C_CTL, 0x10);
 
 		if (--retries < 0) {
-			PDEBUG(D_USBI, "i2c read retries exhausted");
+			gspca_dbg(gspca_dev, D_USBI, "i2c read retries exhausted\n");
 			return -1;
 		}
 	}
 
 	value = reg_r(sd, R51x_I2C_DATA);
 
-	PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value);
+	gspca_dbg(gspca_dev, D_USBI, "ov511_i2c_r %02x %02x\n", reg, value);
 
 	/* This is needed to make i2c_w() work */
 	reg_w(sd, R511_I2C_CTL, 0x05);
@@ -2281,7 +2281,7 @@ static void ov518_i2c_w(struct sd *sd,
 {
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 
-	PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value);
+	gspca_dbg(gspca_dev, D_USBO, "ov518_i2c_w %02x %02x\n", reg, value);
 
 	/* Select camera register */
 	reg_w(sd, R51x_I2C_SADDR_3, reg);
@@ -2321,7 +2321,7 @@ static int ov518_i2c_r(struct sd *sd, u8 reg)
 	reg_r8(sd, R518_I2C_CTL);
 
 	value = reg_r(sd, R51x_I2C_DATA);
-	PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value);
+	gspca_dbg(gspca_dev, D_USBI, "ov518_i2c_r %02x %02x\n", reg, value);
 	return value;
 }
 
@@ -2340,11 +2340,11 @@ static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
 			(u16) value, (u16) reg, NULL, 0, 500);
 
 	if (ret < 0) {
-		PERR("ovfx2_i2c_w %02x failed %d\n", reg, ret);
+		gspca_err(gspca_dev, "ovfx2_i2c_w %02x failed %d\n", reg, ret);
 		sd->gspca_dev.usb_err = ret;
 	}
 
-	PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value);
+	gspca_dbg(gspca_dev, D_USBO, "ovfx2_i2c_w %02x %02x\n", reg, value);
 }
 
 static int ovfx2_i2c_r(struct sd *sd, u8 reg)
@@ -2363,9 +2363,10 @@ static int ovfx2_i2c_r(struct sd *sd, u8 reg)
 
 	if (ret >= 0) {
 		ret = sd->gspca_dev.usb_buf[0];
-		PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret);
+		gspca_dbg(gspca_dev, D_USBI, "ovfx2_i2c_r %02x %02x\n",
+			  reg, ret);
 	} else {
-		PERR("ovfx2_i2c_r %02x failed %d\n", reg, ret);
+		gspca_err(gspca_dev, "ovfx2_i2c_r %02x failed %d\n", reg, ret);
 		sd->gspca_dev.usb_err = ret;
 	}
 
@@ -2464,7 +2465,7 @@ static inline void ov51x_stop(struct sd *sd)
 {
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 
-	PDEBUG(D_STREAM, "stopping");
+	gspca_dbg(gspca_dev, D_STREAM, "stopping\n");
 	sd->stopped = 1;
 	switch (sd->bridge) {
 	case BRIDGE_OV511:
@@ -2495,7 +2496,7 @@ static inline void ov51x_restart(struct sd *sd)
 {
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 
-	PDEBUG(D_STREAM, "restarting");
+	gspca_dbg(gspca_dev, D_STREAM, "restarting\n");
 	if (!sd->stopped)
 		return;
 	sd->stopped = 0;
@@ -2546,7 +2547,8 @@ static int init_ov_sensor(struct sd *sd, u8 slave)
 	for (i = 0; i < i2c_detect_tries; i++) {
 		if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
 		    i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
-			PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
+			gspca_dbg(gspca_dev, D_PROBE, "I2C synced in %d attempt(s)\n",
+				  i);
 			return 0;
 		}
 
@@ -2617,11 +2619,11 @@ static void ov_hires_configure(struct sd *sd)
 	int high, low;
 
 	if (sd->bridge != BRIDGE_OVFX2) {
-		PERR("error hires sensors only supported with ovfx2\n");
+		gspca_err(gspca_dev, "error hires sensors only supported with ovfx2\n");
 		return;
 	}
 
-	PDEBUG(D_PROBE, "starting ov hires configuration");
+	gspca_dbg(gspca_dev, D_PROBE, "starting ov hires configuration\n");
 
 	/* Detect sensor (sub)type */
 	high = i2c_r(sd, 0x0a);
@@ -2631,28 +2633,29 @@ static void ov_hires_configure(struct sd *sd)
 	case 0x96:
 		switch (low) {
 		case 0x40:
-			PDEBUG(D_PROBE, "Sensor is a OV2610");
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV2610\n");
 			sd->sensor = SEN_OV2610;
 			return;
 		case 0x41:
-			PDEBUG(D_PROBE, "Sensor is a OV2610AE");
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV2610AE\n");
 			sd->sensor = SEN_OV2610AE;
 			return;
 		case 0xb1:
-			PDEBUG(D_PROBE, "Sensor is a OV9600");
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV9600\n");
 			sd->sensor = SEN_OV9600;
 			return;
 		}
 		break;
 	case 0x36:
 		if ((low & 0x0f) == 0x00) {
-			PDEBUG(D_PROBE, "Sensor is a OV3610");
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV3610\n");
 			sd->sensor = SEN_OV3610;
 			return;
 		}
 		break;
 	}
-	PERR("Error unknown sensor type: %02x%02x\n", high, low);
+	gspca_err(gspca_dev, "Error unknown sensor type: %02x%02x\n",
+		  high, low);
 }
 
 /* This initializes the OV8110, OV8610 sensor. The OV8110 uses
@@ -2663,18 +2666,19 @@ static void ov8xx0_configure(struct sd *sd)
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 	int rc;
 
-	PDEBUG(D_PROBE, "starting ov8xx0 configuration");
+	gspca_dbg(gspca_dev, D_PROBE, "starting ov8xx0 configuration\n");
 
 	/* Detect sensor (sub)type */
 	rc = i2c_r(sd, OV7610_REG_COM_I);
 	if (rc < 0) {
-		PERR("Error detecting sensor type");
+		gspca_err(gspca_dev, "Error detecting sensor type\n");
 		return;
 	}
 	if ((rc & 3) == 1)
 		sd->sensor = SEN_OV8610;
 	else
-		PERR("Unknown image sensor version: %d\n", rc & 3);
+		gspca_err(gspca_dev, "Unknown image sensor version: %d\n",
+			  rc & 3);
 }
 
 /* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
@@ -2685,7 +2689,7 @@ static void ov7xx0_configure(struct sd *sd)
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 	int rc, high, low;
 
-	PDEBUG(D_PROBE, "starting OV7xx0 configuration");
+	gspca_dbg(gspca_dev, D_PROBE, "starting OV7xx0 configuration\n");
 
 	/* Detect sensor (sub)type */
 	rc = i2c_r(sd, OV7610_REG_COM_I);
@@ -2693,7 +2697,7 @@ static void ov7xx0_configure(struct sd *sd)
 	/* add OV7670 here
 	 * it appears to be wrongly detected as a 7610 by default */
 	if (rc < 0) {
-		PERR("Error detecting sensor type\n");
+		gspca_err(gspca_dev, "Error detecting sensor type\n");
 		return;
 	}
 	if ((rc & 3) == 3) {
@@ -2702,65 +2706,68 @@ static void ov7xx0_configure(struct sd *sd)
 		low = i2c_r(sd, 0x0b);
 		/* info("%x, %x", high, low); */
 		if (high == 0x76 && (low & 0xf0) == 0x70) {
-			PDEBUG(D_PROBE, "Sensor is an OV76%02x", low);
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV76%02x\n",
+				  low);
 			sd->sensor = SEN_OV7670;
 		} else {
-			PDEBUG(D_PROBE, "Sensor is an OV7610");
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7610\n");
 			sd->sensor = SEN_OV7610;
 		}
 	} else if ((rc & 3) == 1) {
 		/* I don't know what's different about the 76BE yet. */
 		if (i2c_r(sd, 0x15) & 1) {
-			PDEBUG(D_PROBE, "Sensor is an OV7620AE");
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7620AE\n");
 			sd->sensor = SEN_OV7620AE;
 		} else {
-			PDEBUG(D_PROBE, "Sensor is an OV76BE");
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV76BE\n");
 			sd->sensor = SEN_OV76BE;
 		}
 	} else if ((rc & 3) == 0) {
 		/* try to read product id registers */
 		high = i2c_r(sd, 0x0a);
 		if (high < 0) {
-			PERR("Error detecting camera chip PID\n");
+			gspca_err(gspca_dev, "Error detecting camera chip PID\n");
 			return;
 		}
 		low = i2c_r(sd, 0x0b);
 		if (low < 0) {
-			PERR("Error detecting camera chip VER\n");
+			gspca_err(gspca_dev, "Error detecting camera chip VER\n");
 			return;
 		}
 		if (high == 0x76) {
 			switch (low) {
 			case 0x30:
-				PERR("Sensor is an OV7630/OV7635\n");
-				PERR("7630 is not supported by this driver\n");
+				gspca_err(gspca_dev, "Sensor is an OV7630/OV7635\n");
+				gspca_err(gspca_dev, "7630 is not supported by this driver\n");
 				return;
 			case 0x40:
-				PDEBUG(D_PROBE, "Sensor is an OV7645");
+				gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7645\n");
 				sd->sensor = SEN_OV7640; /* FIXME */
 				break;
 			case 0x45:
-				PDEBUG(D_PROBE, "Sensor is an OV7645B");
+				gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7645B\n");
 				sd->sensor = SEN_OV7640; /* FIXME */
 				break;
 			case 0x48:
-				PDEBUG(D_PROBE, "Sensor is an OV7648");
+				gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7648\n");
 				sd->sensor = SEN_OV7648;
 				break;
 			case 0x60:
-				PDEBUG(D_PROBE, "Sensor is a OV7660");
+				gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV7660\n");
 				sd->sensor = SEN_OV7660;
 				break;
 			default:
-				PERR("Unknown sensor: 0x76%02x\n", low);
+				gspca_err(gspca_dev, "Unknown sensor: 0x76%02x\n",
+					  low);
 				return;
 			}
 		} else {
-			PDEBUG(D_PROBE, "Sensor is an OV7620");
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7620\n");
 			sd->sensor = SEN_OV7620;
 		}
 	} else {
-		PERR("Unknown image sensor version: %d\n", rc & 3);
+		gspca_err(gspca_dev, "Unknown image sensor version: %d\n",
+			  rc & 3);
 	}
 }
 
@@ -2770,12 +2777,12 @@ static void ov6xx0_configure(struct sd *sd)
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 	int rc;
 
-	PDEBUG(D_PROBE, "starting OV6xx0 configuration");
+	gspca_dbg(gspca_dev, D_PROBE, "starting OV6xx0 configuration\n");
 
 	/* Detect sensor (sub)type */
 	rc = i2c_r(sd, OV7610_REG_COM_I);
 	if (rc < 0) {
-		PERR("Error detecting sensor type\n");
+		gspca_err(gspca_dev, "Error detecting sensor type\n");
 		return;
 	}
 
@@ -2789,22 +2796,23 @@ static void ov6xx0_configure(struct sd *sd)
 		break;
 	case 0x01:
 		sd->sensor = SEN_OV6620;
-		PDEBUG(D_PROBE, "Sensor is an OV6620");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV6620\n");
 		break;
 	case 0x02:
 		sd->sensor = SEN_OV6630;
-		PDEBUG(D_PROBE, "Sensor is an OV66308AE");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV66308AE\n");
 		break;
 	case 0x03:
 		sd->sensor = SEN_OV66308AF;
-		PDEBUG(D_PROBE, "Sensor is an OV66308AF");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV66308AF\n");
 		break;
 	case 0x90:
 		sd->sensor = SEN_OV6630;
 		pr_warn("WARNING: Sensor is an OV66307. Your camera may have been misdetected in previous driver versions.\n");
 		break;
 	default:
-		PERR("FATAL: Unknown sensor version: 0x%02x\n", rc);
+		gspca_err(gspca_dev, "FATAL: Unknown sensor version: 0x%02x\n",
+			  rc);
 		return;
 	}
 
@@ -2906,7 +2914,7 @@ static void ov51x_upload_quan_tables(struct sd *sd)
 	unsigned char val0, val1;
 	int i, size, reg = R51x_COMP_LUT_BEGIN;
 
-	PDEBUG(D_PROBE, "Uploading quantization tables");
+	gspca_dbg(gspca_dev, D_PROBE, "Uploading quantization tables\n");
 
 	if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
 		pYTable = yQuanTable511;
@@ -2984,7 +2992,8 @@ static void ov511_configure(struct gspca_dev *gspca_dev)
 		{ 0x77, 0x04 },
 	};
 
-	PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
+	gspca_dbg(gspca_dev, D_PROBE, "Device custom id %x\n",
+		  reg_r(sd, R51x_SYS_CUST_ID));
 
 	write_regvals(sd, init_511, ARRAY_SIZE(init_511));
 
@@ -3054,7 +3063,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev)
 
 	/* First 5 bits of custom ID reg are a revision ID on OV518 */
 	sd->revision = reg_r(sd, R51x_SYS_CUST_ID) & 0x1f;
-	PDEBUG(D_PROBE, "Device revision %d", sd->revision);
+	gspca_dbg(gspca_dev, D_PROBE, "Device revision %d\n", sd->revision);
 
 	write_regvals(sd, init_518, ARRAY_SIZE(init_518));
 
@@ -3295,7 +3304,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	} else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
 		ov_hires_configure(sd);
 	} else {
-		PERR("Can't determine sensor slave IDs\n");
+		gspca_err(gspca_dev, "Can't determine sensor slave IDs\n");
 		goto error;
 	}
 
@@ -3428,7 +3437,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	}
 	return gspca_dev->usb_err;
 error:
-	PERR("OV519 Config failed");
+	gspca_err(gspca_dev, "OV519 Config failed\n");
 	return -EINVAL;
 }
 
@@ -3463,7 +3472,7 @@ static void ov511_mode_init_regs(struct sd *sd)
 	intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
 	alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
 	if (!alt) {
-		PERR("Couldn't get altsetting\n");
+		gspca_err(gspca_dev, "Couldn't get altsetting\n");
 		sd->gspca_dev.usb_err = -EIO;
 		return;
 	}
@@ -3589,7 +3598,7 @@ static void ov518_mode_init_regs(struct sd *sd)
 	intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
 	alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
 	if (!alt) {
-		PERR("Couldn't get altsetting\n");
+		gspca_err(gspca_dev, "Couldn't get altsetting\n");
 		sd->gspca_dev.usb_err = -EIO;
 		return;
 	}
@@ -3861,8 +3870,8 @@ static void ov519_mode_init_regs(struct sd *sd)
 		}
 		break;
 	case SEN_OV7670:		/* guesses, based on 7640 */
-		PDEBUG(D_STREAM, "Setting framerate to %d fps",
-				 (sd->frame_rate == 0) ? 15 : sd->frame_rate);
+		gspca_dbg(gspca_dev, D_STREAM, "Setting framerate to %d fps\n",
+			  (sd->frame_rate == 0) ? 15 : sd->frame_rate);
 		reg_w(sd, 0xa4, 0x10);
 		switch (sd->frame_rate) {
 		case 30:
@@ -4323,10 +4332,10 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
 			/* Frame end */
 			if ((in[9] + 1) * 8 != gspca_dev->pixfmt.width ||
 			    (in[10] + 1) * 8 != gspca_dev->pixfmt.height) {
-				PERR("Invalid frame size, got: %dx%d, requested: %dx%d\n",
-					(in[9] + 1) * 8, (in[10] + 1) * 8,
-					gspca_dev->pixfmt.width,
-					gspca_dev->pixfmt.height);
+				gspca_err(gspca_dev, "Invalid frame size, got: %dx%d, requested: %dx%d\n",
+					  (in[9] + 1) * 8, (in[10] + 1) * 8,
+					  gspca_dev->pixfmt.width,
+					  gspca_dev->pixfmt.height);
 				gspca_dev->last_packet_type = DISCARD_PACKET;
 				return;
 			}
@@ -4374,8 +4383,8 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
 		   except that they may contain part of the footer), are
 		   numbered 0 */
 		else if (sd->packet_nr == 0 || data[len]) {
-			PERR("Invalid packet nr: %d (expect: %d)",
-				(int)data[len], (int)sd->packet_nr);
+			gspca_err(gspca_dev, "Invalid packet nr: %d (expect: %d)\n",
+				  (int)data[len], (int)sd->packet_nr);
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		}
@@ -4918,7 +4927,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
 			QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
 
 	if (hdl->error) {
-		PERR("Could not initialize controls\n");
+		gspca_err(gspca_dev, "Could not initialize controls\n");
 		return hdl->error;
 	}
 	if (gspca_dev->autogain)
diff --git a/drivers/media/usb/gspca/ov534.c b/drivers/media/usb/gspca/ov534.c
index 32849ff..f293921 100644
--- a/drivers/media/usb/gspca/ov534.c
+++ b/drivers/media/usb/gspca/ov534.c
@@ -612,7 +612,7 @@ static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
 	if (gspca_dev->usb_err < 0)
 		return;
 
-	PDEBUG(D_USBO, "SET 01 0000 %04x %02x", reg, val);
+	gspca_dbg(gspca_dev, D_USBO, "SET 01 0000 %04x %02x\n", reg, val);
 	gspca_dev->usb_buf[0] = val;
 	ret = usb_control_msg(udev,
 			      usb_sndctrlpipe(udev, 0),
@@ -637,7 +637,8 @@ static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
 			      0x01,
 			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			      0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
-	PDEBUG(D_USBI, "GET 01 0000 %04x %02x", reg, gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_USBI, "GET 01 0000 %04x %02x\n",
+		  reg, gspca_dev->usb_buf[0]);
 	if (ret < 0) {
 		pr_err("read failed %d\n", ret);
 		gspca_dev->usb_err = ret;
@@ -651,7 +652,7 @@ static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
 {
 	u8 data;
 
-	PDEBUG(D_CONF, "led status: %d", status);
+	gspca_dbg(gspca_dev, D_CONF, "led status: %d\n", status);
 
 	data = ov534_reg_read(gspca_dev, 0x21);
 	data |= 0x80;
@@ -689,8 +690,8 @@ static int sccb_check_status(struct gspca_dev *gspca_dev)
 		case 0x03:
 			break;
 		default:
-			PERR("sccb status 0x%02x, attempt %d/5",
-			       data, i + 1);
+			gspca_err(gspca_dev, "sccb status 0x%02x, attempt %d/5\n",
+				  data, i + 1);
 		}
 	}
 	return 0;
@@ -698,7 +699,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev)
 
 static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 {
-	PDEBUG(D_USBO, "sccb write: %02x %02x", reg, val);
+	gspca_dbg(gspca_dev, D_USBO, "sccb write: %02x %02x\n", reg, val);
 	ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
 	ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
 	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
@@ -800,7 +801,7 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
 	sccb_reg_write(gspca_dev, 0x0d, r->r0d);
 	ov534_reg_write(gspca_dev, 0xe5, r->re5);
 
-	PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
+	gspca_dbg(gspca_dev, D_PROBE, "frame_rate: %d\n", r->fps);
 }
 
 static void sethue(struct gspca_dev *gspca_dev, s32 val)
@@ -1283,7 +1284,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8;
 	sccb_reg_read(gspca_dev, 0x0b);
 	sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
-	PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
+	gspca_dbg(gspca_dev, D_PROBE, "Sensor ID: %04x\n", sensor_id);
 
 	if ((sensor_id & 0xfff0) == 0x7670) {
 		sd->sensor = SENSOR_OV767x;
@@ -1407,19 +1408,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 
 		/* Verify UVC header.  Header length is always 12 */
 		if (data[0] != 12 || len < 12) {
-			PDEBUG(D_PACK, "bad header");
+			gspca_dbg(gspca_dev, D_PACK, "bad header\n");
 			goto discard;
 		}
 
 		/* Check errors */
 		if (data[1] & UVC_STREAM_ERR) {
-			PDEBUG(D_PACK, "payload error");
+			gspca_dbg(gspca_dev, D_PACK, "payload error\n");
 			goto discard;
 		}
 
 		/* Extract PTS and FID */
 		if (!(data[1] & UVC_STREAM_PTS)) {
-			PDEBUG(D_PACK, "PTS not present");
+			gspca_dbg(gspca_dev, D_PACK, "PTS not present\n");
 			goto discard;
 		}
 		this_pts = (data[5] << 24) | (data[4] << 16)
@@ -1442,7 +1443,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			 && gspca_dev->image_len + len - 12 !=
 				   gspca_dev->pixfmt.width *
 					gspca_dev->pixfmt.height * 2) {
-				PDEBUG(D_PACK, "wrong sized frame");
+				gspca_dbg(gspca_dev, D_PACK, "wrong sized frame\n");
 				goto discard;
 			}
 			gspca_frame_add(gspca_dev, LAST_PACKET,
diff --git a/drivers/media/usb/gspca/ov534_9.c b/drivers/media/usb/gspca/ov534_9.c
index b2a92e5..3d1364d 100644
--- a/drivers/media/usb/gspca/ov534_9.c
+++ b/drivers/media/usb/gspca/ov534_9.c
@@ -1133,7 +1133,7 @@ static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val)
 
 static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val)
 {
-	PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val);
+	gspca_dbg(gspca_dev, D_USBO, "reg_w [%04x] = %02x\n", reg, val);
 	reg_w_i(gspca_dev, reg, val);
 }
 
@@ -1149,7 +1149,8 @@ static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg)
 			      0x01,
 			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			      0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
-	PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_USBI, "reg_r [%04x] -> %02x\n",
+		  reg, gspca_dev->usb_buf[0]);
 	if (ret < 0) {
 		pr_err("reg_r err %d\n", ret);
 		gspca_dev->usb_err = ret;
@@ -1174,9 +1175,9 @@ static int sccb_check_status(struct gspca_dev *gspca_dev)
 		case 0x03:
 			break;
 		default:
-			PDEBUG(D_USBI|D_USBO,
-				"sccb status 0x%02x, attempt %d/5",
-				data, i + 1);
+			gspca_dbg(gspca_dev, D_USBI|D_USBO,
+				  "sccb status 0x%02x, attempt %d/5\n",
+				  data, i + 1);
 		}
 	}
 	return 0;
@@ -1184,7 +1185,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev)
 
 static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 {
-	PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val);
+	gspca_dbg(gspca_dev, D_USBO, "sccb_write [%02x] = %02x\n", reg, val);
 	reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg);
 	reg_w_i(gspca_dev, OV534_REG_WRITE, val);
 	reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
@@ -1238,7 +1239,7 @@ static void set_led(struct gspca_dev *gspca_dev, int status)
 {
 	u8 data;
 
-	PDEBUG(D_CONF, "led status: %d", status);
+	gspca_dbg(gspca_dev, D_CONF, "led status: %d\n", status);
 
 	data = reg_r(gspca_dev, 0x21);
 	data |= 0x80;
@@ -1423,7 +1424,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	sensor_id = sccb_read(gspca_dev, 0x0a) << 8;
 	sccb_read(gspca_dev, 0x0b);
 	sensor_id |= sccb_read(gspca_dev, 0x0b);
-	PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
+	gspca_dbg(gspca_dev, D_PROBE, "Sensor ID: %04x\n", sensor_id);
 
 	/* initialize */
 	if ((sensor_id & 0xfff0) == 0x9650) {
@@ -1651,19 +1652,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 
 		/* Verify UVC header.  Header length is always 12 */
 		if (data[0] != 12 || len < 12) {
-			PDEBUG(D_PACK, "bad header");
+			gspca_dbg(gspca_dev, D_PACK, "bad header\n");
 			goto discard;
 		}
 
 		/* Check errors */
 		if (data[1] & UVC_STREAM_ERR) {
-			PDEBUG(D_PACK, "payload error");
+			gspca_dbg(gspca_dev, D_PACK, "payload error\n");
 			goto discard;
 		}
 
 		/* Extract PTS and FID */
 		if (!(data[1] & UVC_STREAM_PTS)) {
-			PDEBUG(D_PACK, "PTS not present");
+			gspca_dbg(gspca_dev, D_PACK, "PTS not present\n");
 			goto discard;
 		}
 		this_pts = (data[5] << 24) | (data[4] << 16)
diff --git a/drivers/media/usb/gspca/pac207.c b/drivers/media/usb/gspca/pac207.c
index 01c185d..a1df7af 100644
--- a/drivers/media/usb/gspca/pac207.c
+++ b/drivers/media/usb/gspca/pac207.c
@@ -166,17 +166,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	idreg[1] = pac207_read_reg(gspca_dev, 0x0001);
 	idreg[0] = ((idreg[0] & 0x0f) << 4) | ((idreg[1] & 0xf0) >> 4);
 	idreg[1] = idreg[1] & 0x0f;
-	PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X",
-		idreg[0], idreg[1]);
+	gspca_dbg(gspca_dev, D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X\n",
+		  idreg[0], idreg[1]);
 
 	if (idreg[0] != 0x27) {
-		PDEBUG(D_PROBE, "Error invalid sensor ID!");
+		gspca_dbg(gspca_dev, D_PROBE, "Error invalid sensor ID!\n");
 		return -ENODEV;
 	}
 
-	PDEBUG(D_PROBE,
-		"Pixart PAC207BCA Image Processor and Control Chip detected (vid/pid 0x%04X:0x%04X)",
-		id->idVendor, id->idProduct);
+	gspca_dbg(gspca_dev, D_PROBE,
+		  "Pixart PAC207BCA Image Processor and Control Chip detected (vid/pid 0x%04X:0x%04X)\n",
+		  id->idVendor, id->idProduct);
 
 	cam = &gspca_dev->cam;
 	cam->cam_mode = sif_mode;
@@ -315,9 +315,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		mode = 0x02;
 	if (gspca_dev->pixfmt.width == 176) {	/* 176x144 */
 		mode |= 0x01;
-		PDEBUG(D_STREAM, "pac207_start mode 176x144");
+		gspca_dbg(gspca_dev, D_STREAM, "pac207_start mode 176x144\n");
 	} else {				/* 352x288 */
-		PDEBUG(D_STREAM, "pac207_start mode 352x288");
+		gspca_dbg(gspca_dev, D_STREAM, "pac207_start mode 352x288\n");
 	}
 	pac207_write_reg(gspca_dev, 0x41, mode);
 
diff --git a/drivers/media/usb/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c
index 595535e..b8ff201 100644
--- a/drivers/media/usb/gspca/pac7302.c
+++ b/drivers/media/usb/gspca/pac7302.c
@@ -339,7 +339,7 @@ static void reg_w_var(struct gspca_dev *gspca_dev,
 			break;
 		default:
 			if (len > USB_BUF_SZ) {
-				PERR("Incorrect variable sequence");
+				gspca_err(gspca_dev, "Incorrect variable sequence\n");
 				return;
 			}
 			while (len > 0) {
diff --git a/drivers/media/usb/gspca/pac7311.c b/drivers/media/usb/gspca/pac7311.c
index 8bac2d9..44db4f4 100644
--- a/drivers/media/usb/gspca/pac7311.c
+++ b/drivers/media/usb/gspca/pac7311.c
@@ -258,7 +258,7 @@ static void reg_w_var(struct gspca_dev *gspca_dev,
 			break;
 		default:
 			if (len > USB_BUF_SZ) {
-				PERR("Incorrect variable sequence");
+				gspca_err(gspca_dev, "Incorrect variable sequence\n");
 				return;
 			}
 			while (len > 0) {
diff --git a/drivers/media/usb/gspca/pac_common.h b/drivers/media/usb/gspca/pac_common.h
index 4047bcb..31f2a42 100644
--- a/drivers/media/usb/gspca/pac_common.h
+++ b/drivers/media/usb/gspca/pac_common.h
@@ -107,10 +107,9 @@ static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, u8 *sof_read,
 			switch (m[i]) {
 			case 0x96:
 				/* Pattern found */
-				PDEBUG(D_FRAM,
-					"SOF found, bytes to analyze: %u."
-					" Frame starts at byte #%u",
-					len, i + 1);
+				gspca_dbg(gspca_dev, D_FRAM,
+					  "SOF found, bytes to analyze: %u - Frame starts at byte #%u\n",
+					  len, i + 1);
 				*sof_read = 0;
 				return m + i + 1;
 				break;
diff --git a/drivers/media/usb/gspca/sn9c2028.c b/drivers/media/usb/gspca/sn9c2028.c
index 5d32dd3..a1f7189 100644
--- a/drivers/media/usb/gspca/sn9c2028.c
+++ b/drivers/media/usb/gspca/sn9c2028.c
@@ -69,8 +69,9 @@ static int sn9c2028_command(struct gspca_dev *gspca_dev, u8 *command)
 {
 	int rc;
 
-	PDEBUG(D_USBO, "sending command %02x%02x%02x%02x%02x%02x", command[0],
-	       command[1], command[2], command[3], command[4], command[5]);
+	gspca_dbg(gspca_dev, D_USBO, "sending command %02x%02x%02x%02x%02x%02x\n",
+		  command[0], command[1], command[2],
+		  command[3], command[4], command[5]);
 
 	memcpy(gspca_dev->usb_buf, command, 6);
 	rc = usb_control_msg(gspca_dev->dev,
@@ -100,7 +101,8 @@ static int sn9c2028_read1(struct gspca_dev *gspca_dev)
 		pr_err("read1 error %d\n", rc);
 		return (rc < 0) ? rc : -EIO;
 	}
-	PDEBUG(D_USBI, "read1 response %02x", gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_USBI, "read1 response %02x\n",
+		  gspca_dev->usb_buf[0]);
 	return gspca_dev->usb_buf[0];
 }
 
@@ -117,8 +119,8 @@ static int sn9c2028_read4(struct gspca_dev *gspca_dev, u8 *reading)
 		return (rc < 0) ? rc : -EIO;
 	}
 	memcpy(reading, gspca_dev->usb_buf, 4);
-	PDEBUG(D_USBI, "read4 response %02x%02x%02x%02x", reading[0],
-	       reading[1], reading[2], reading[3]);
+	gspca_dbg(gspca_dev, D_USBI, "read4 response %02x%02x%02x%02x\n",
+		  reading[0], reading[1], reading[2], reading[3]);
 	return rc;
 }
 
@@ -175,32 +177,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam = &gspca_dev->cam;
 
-	PDEBUG(D_PROBE, "SN9C2028 camera detected (vid/pid 0x%04X:0x%04X)",
-	       id->idVendor, id->idProduct);
+	gspca_dbg(gspca_dev, D_PROBE, "SN9C2028 camera detected (vid/pid 0x%04X:0x%04X)\n",
+		  id->idVendor, id->idProduct);
 
 	sd->model = id->idProduct;
 
 	switch (sd->model) {
 	case 0x7005:
-		PDEBUG(D_PROBE, "Genius Smart 300 camera");
+		gspca_dbg(gspca_dev, D_PROBE, "Genius Smart 300 camera\n");
 		break;
 	case 0x7003:
-		PDEBUG(D_PROBE, "Genius Videocam Live v2");
+		gspca_dbg(gspca_dev, D_PROBE, "Genius Videocam Live v2\n");
 		break;
 	case 0x8000:
-		PDEBUG(D_PROBE, "DC31VC");
+		gspca_dbg(gspca_dev, D_PROBE, "DC31VC\n");
 		break;
 	case 0x8001:
-		PDEBUG(D_PROBE, "Spy camera");
+		gspca_dbg(gspca_dev, D_PROBE, "Spy camera\n");
 		break;
 	case 0x8003:
-		PDEBUG(D_PROBE, "CIF camera");
+		gspca_dbg(gspca_dev, D_PROBE, "CIF camera\n");
 		break;
 	case 0x8008:
-		PDEBUG(D_PROBE, "Mini-Shotz ms-350 camera");
+		gspca_dbg(gspca_dev, D_PROBE, "Mini-Shotz ms-350 camera\n");
 		break;
 	case 0x800a:
-		PDEBUG(D_PROBE, "Vivitar 3350b type camera");
+		gspca_dbg(gspca_dev, D_PROBE, "Vivitar 3350b type camera\n");
 		cam->input_flags = V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
 		break;
 	}
@@ -849,13 +851,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 
 	result = sn9c2028_read1(gspca_dev);
 	if (result < 0)
-		PERR("Camera Stop read failed");
+		gspca_err(gspca_dev, "Camera Stop read failed\n");
 
 	memset(data, 0, 6);
 	data[0] = 0x14;
 	result = sn9c2028_command(gspca_dev, data);
 	if (result < 0)
-		PERR("Camera Stop command failed");
+		gspca_err(gspca_dev, "Camera Stop command failed\n");
 }
 
 static void do_autogain(struct gspca_dev *gspca_dev, int avg_lum)
diff --git a/drivers/media/usb/gspca/sn9c2028.h b/drivers/media/usb/gspca/sn9c2028.h
index 85761aa..29f1571 100644
--- a/drivers/media/usb/gspca/sn9c2028.h
+++ b/drivers/media/usb/gspca/sn9c2028.h
@@ -43,10 +43,9 @@ static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev,
 			if (sd->sof_read == 12)
 				sd->avg_lum = (m[i] << 8) + sd->avg_lum_l;
 			if (sd->sof_read == sizeof(sn9c2028_sof_marker)) {
-				PDEBUG(D_FRAM,
-					"SOF found, bytes to analyze: %u."
-					" Frame starts at byte #%u",
-					len, i + 1);
+				gspca_dbg(gspca_dev, D_FRAM,
+					  "SOF found, bytes to analyze: %u - Frame starts at byte #%u\n",
+					  len, i + 1);
 				sd->sof_read = 0;
 				return m + i + 1;
 			}
diff --git a/drivers/media/usb/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c
index c605f78..cfa2a04 100644
--- a/drivers/media/usb/gspca/sn9c20x.c
+++ b/drivers/media/usb/gspca/sn9c20x.c
@@ -2153,7 +2153,7 @@ static void qual_upd(struct work_struct *work)
 
 	/* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
 	mutex_lock(&gspca_dev->usb_lock);
-	PDEBUG(D_STREAM, "qual_upd %d%%", qual);
+	gspca_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", qual);
 	gspca_dev->usb_err = 0;
 	set_quality(gspca_dev, qual);
 	mutex_unlock(&gspca_dev->usb_lock);
diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c
index 5eeaf16..df8d848 100644
--- a/drivers/media/usb/gspca/sonixj.c
+++ b/drivers/media/usb/gspca/sonixj.c
@@ -1155,7 +1155,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
 	if (gspca_dev->usb_err < 0)
 		return;
 	if (len > USB_BUF_SZ) {
-		PERR("reg_r: buffer overflow\n");
+		gspca_err(gspca_dev, "reg_r: buffer overflow\n");
 		return;
 	}
 
@@ -1166,7 +1166,8 @@ static void reg_r(struct gspca_dev *gspca_dev,
 			value, 0,
 			gspca_dev->usb_buf, len,
 			500);
-	PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_USBI, "reg_r [%02x] -> %02x\n",
+		  value, gspca_dev->usb_buf[0]);
 	if (ret < 0) {
 		pr_err("reg_r err %d\n", ret);
 		gspca_dev->usb_err = ret;
@@ -1181,7 +1182,7 @@ static void reg_w1(struct gspca_dev *gspca_dev,
 
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
+	gspca_dbg(gspca_dev, D_USBO, "reg_w1 [%04x] = %02x\n", value, data);
 	gspca_dev->usb_buf[0] = data;
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -1205,11 +1206,11 @@ static void reg_w(struct gspca_dev *gspca_dev,
 
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
-		value, buffer[0], buffer[1]);
+	gspca_dbg(gspca_dev, D_USBO, "reg_w [%04x] = %02x %02x ..\n",
+		  value, buffer[0], buffer[1]);
 
 	if (len > USB_BUF_SZ) {
-		PERR("reg_w: buffer overflow\n");
+		gspca_err(gspca_dev, "reg_w: buffer overflow\n");
 		return;
 	}
 
@@ -1235,7 +1236,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
+	gspca_dbg(gspca_dev, D_USBO, "i2c_w1 [%02x] = %02x\n", reg, val);
 	switch (sd->sensor) {
 	case SENSOR_ADCM1700:
 	case SENSOR_OM6802:
@@ -1276,8 +1277,8 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
 
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
-		buffer[2], buffer[3]);
+	gspca_dbg(gspca_dev, D_USBO, "i2c_w8 [%02x] = %02x ..\n",
+		  buffer[2], buffer[3]);
 	memcpy(gspca_dev->usb_buf, buffer, 8);
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -1349,7 +1350,7 @@ static void hv7131r_probe(struct gspca_dev *gspca_dev)
 	if (gspca_dev->usb_buf[0] == 0x02	/* chip ID (02 is R) */
 	    && gspca_dev->usb_buf[1] == 0x09
 	    && gspca_dev->usb_buf[2] == 0x01) {
-		PDEBUG(D_PROBE, "Sensor HV7131R found");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor HV7131R found\n");
 		return;
 	}
 	pr_warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x\n",
@@ -1396,18 +1397,19 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
 		return;
 	switch (val) {
 	case 0x8221:
-		PDEBUG(D_PROBE, "Sensor mi0360b");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor mi0360b\n");
 		sd->sensor = SENSOR_MI0360B;
 		break;
 	case 0x823a:
-		PDEBUG(D_PROBE, "Sensor mt9v111");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor mt9v111\n");
 		sd->sensor = SENSOR_MT9V111;
 		break;
 	case 0x8243:
-		PDEBUG(D_PROBE, "Sensor mi0360");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor mi0360\n");
 		break;
 	default:
-		PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
+		gspca_dbg(gspca_dev, D_PROBE, "Unknown sensor %04x - forced to mi0360\n",
+			  val);
 		break;
 	}
 }
@@ -1432,10 +1434,10 @@ static void ov7630_probe(struct gspca_dev *gspca_dev)
 /*fixme: only valid for 0c45:613e?*/
 		gspca_dev->cam.input_flags =
 				V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
-		PDEBUG(D_PROBE, "Sensor soi768");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor soi768\n");
 		return;
 	}
-	PDEBUG(D_PROBE, "Sensor ov%04x", val);
+	gspca_dbg(gspca_dev, D_PROBE, "Sensor ov%04x\n", val);
 }
 
 static void ov7648_probe(struct gspca_dev *gspca_dev)
@@ -1452,7 +1454,7 @@ static void ov7648_probe(struct gspca_dev *gspca_dev)
 	reg_w1(gspca_dev, 0x01, 0x29);
 	reg_w1(gspca_dev, 0x17, 0x42);
 	if ((val & 0xff00) == 0x7600) {		/* ov76xx */
-		PDEBUG(D_PROBE, "Sensor ov%04x", val);
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor ov%04x\n", val);
 		return;
 	}
 
@@ -1467,7 +1469,7 @@ static void ov7648_probe(struct gspca_dev *gspca_dev)
 	if (gspca_dev->usb_err < 0)
 		return;
 	if (val == 0x1030) {			/* po1030 */
-		PDEBUG(D_PROBE, "Sensor po1030");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor po1030\n");
 		sd->sensor = SENSOR_PO1030;
 		return;
 	}
@@ -1490,7 +1492,7 @@ static void po2030n_probe(struct gspca_dev *gspca_dev)
 	reg_w1(gspca_dev, 0x01, 0x29);		/* reset */
 	reg_w1(gspca_dev, 0x17, 0x42);
 	if (val == 0x99) {			/* gc0307 (?) */
-		PDEBUG(D_PROBE, "Sensor gc0307");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor gc0307\n");
 		sd->sensor = SENSOR_GC0307;
 		return;
 	}
@@ -1506,7 +1508,7 @@ static void po2030n_probe(struct gspca_dev *gspca_dev)
 	if (gspca_dev->usb_err < 0)
 		return;
 	if (val == 0x2030) {
-		PDEBUG(D_PROBE, "Sensor po2030n");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor po2030n\n");
 /*		sd->sensor = SENSOR_PO2030N; */
 	} else {
 		pr_err("Unknown sensor ID %04x\n", val);
@@ -1558,7 +1560,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	regF1 = gspca_dev->usb_buf[0];
 	if (gspca_dev->usb_err < 0)
 		return gspca_dev->usb_err;
-	PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
+	gspca_dbg(gspca_dev, D_PROBE, "Sonix chip id: %02x\n", regF1);
 	if (gspca_dev->audio)
 		regGpio[1] |= 0x04;		/* with audio */
 	switch (sd->bridge) {
@@ -1758,10 +1760,10 @@ static u32 expo_adjust(struct gspca_dev *gspca_dev,
 				| ((expo & 0x0003) << 4);
 		i2c_w8(gspca_dev, expoMo10);
 		i2c_w8(gspca_dev, gainMo);
-		PDEBUG(D_FRAM, "set exposure %d",
-			((expoMo10[3] & 0x07) << 10)
-			| (expoMof[3] << 2)
-			| ((expoMo10[3] & 0x30) >> 4));
+		gspca_dbg(gspca_dev, D_FRAM, "set exposure %d\n",
+			  ((expoMo10[3] & 0x07) << 10)
+			  | (expoMof[3] << 2)
+			  | ((expoMo10[3] & 0x30) >> 4));
 		break;
 	    }
 	case SENSOR_MT9V111: {
@@ -1789,7 +1791,7 @@ static u32 expo_adjust(struct gspca_dev *gspca_dev,
 		gainOm[3] = expo >> 2;
 		i2c_w8(gspca_dev, gainOm);
 		reg_w1(gspca_dev, 0x96, expo >> 5);
-		PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
+		gspca_dbg(gspca_dev, D_FRAM, "set exposure %d\n", gainOm[3]);
 		break;
 	    }
 	}
@@ -2162,7 +2164,7 @@ static void qual_upd(struct work_struct *work)
 
 	/* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
 	mutex_lock(&gspca_dev->usb_lock);
-	PDEBUG(D_STREAM, "qual_upd %d%%", sd->quality);
+	gspca_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", sd->quality);
 	gspca_dev->usb_err = 0;
 	setjpegqual(gspca_dev);
 	mutex_unlock(&gspca_dev->usb_lock);
@@ -2584,7 +2586,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
 	sd->ag_cnt = AG_CNT_START;
 
 	delta = atomic_read(&sd->avg_lum);
-	PDEBUG(D_FRAM, "mean lum %d", delta);
+	gspca_dbg(gspca_dev, D_FRAM, "mean lum %d\n", delta);
 
 	if (sd->sensor == SENSOR_PO2030N) {
 		gspca_expo_autogain(gspca_dev, delta, luma_mean, luma_delta,
diff --git a/drivers/media/usb/gspca/spca1528.c b/drivers/media/usb/gspca/spca1528.c
index 327ec90..d25924e 100644
--- a/drivers/media/usb/gspca/spca1528.c
+++ b/drivers/media/usb/gspca/spca1528.c
@@ -75,8 +75,8 @@ static void reg_r(struct gspca_dev *gspca_dev,
 			index,
 			gspca_dev->usb_buf, len,
 			500);
-	PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", req, index,
-			 gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_USBI, "GET %02x 0000 %04x %02x\n", req, index,
+		  gspca_dev->usb_buf[0]);
 	if (ret < 0) {
 		pr_err("reg_r err %d\n", ret);
 		gspca_dev->usb_err = ret;
@@ -93,7 +93,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
 
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index);
+	gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n", req, value, index);
 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 			req,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -116,7 +116,8 @@ static void reg_wb(struct gspca_dev *gspca_dev,
 
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_USBO, "SET %02x %04x %04x %02x", req, value, index, byte);
+	gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x %02x\n",
+		  req, value, index, byte);
 	gspca_dev->usb_buf[0] = byte;
 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 			req,
@@ -142,7 +143,7 @@ static void wait_status_0(struct gspca_dev *gspca_dev)
 		w += 15;
 		msleep(w);
 	} while (--i > 0);
-	PERR("wait_status_0 timeout");
+	gspca_err(gspca_dev, "wait_status_0 timeout\n");
 	gspca_dev->usb_err = -ETIME;
 }
 
@@ -160,7 +161,7 @@ static void wait_status_1(struct gspca_dev *gspca_dev)
 			return;
 		}
 	} while (--i > 0);
-	PERR("wait_status_1 timeout");
+	gspca_err(gspca_dev, "wait_status_1 timeout\n");
 	gspca_dev->usb_err = -ETIME;
 }
 
@@ -216,8 +217,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	reg_r(gspca_dev, 0x20, 0x0000, 1);
 	reg_r(gspca_dev, 0x20, 0x0000, 5);
 	reg_r(gspca_dev, 0x23, 0x0000, 64);
-	PDEBUG(D_PROBE, "%s%s", &gspca_dev->usb_buf[0x1c],
-				&gspca_dev->usb_buf[0x30]);
+	gspca_dbg(gspca_dev, D_PROBE, "%s%s\n", &gspca_dev->usb_buf[0x1c],
+		  &gspca_dev->usb_buf[0x30]);
 	reg_r(gspca_dev, 0x23, 0x0001, 64);
 	return gspca_dev->usb_err;
 }
diff --git a/drivers/media/usb/gspca/spca500.c b/drivers/media/usb/gspca/spca500.c
index da2d902..e90d2f3 100644
--- a/drivers/media/usb/gspca/spca500.c
+++ b/drivers/media/usb/gspca/spca500.c
@@ -328,7 +328,8 @@ static int reg_w(struct gspca_dev *gspca_dev,
 {
 	int ret;
 
-	PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
+	gspca_dbg(gspca_dev, D_USBO, "reg write: [0x%02x] = 0x%02x\n",
+		  index, value);
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			req,
@@ -423,15 +424,15 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
 static void spca500_ping310(struct gspca_dev *gspca_dev)
 {
 	reg_r(gspca_dev, 0x0d04, 2);
-	PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
-		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+	gspca_dbg(gspca_dev, D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x\n",
+		  gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
 }
 
 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
 {
 	reg_r(gspca_dev, 0x0d05, 2);
-	PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
-		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+	gspca_dbg(gspca_dev, D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x\n",
+		  gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
 	reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
 	spca500_ping310(gspca_dev);
 
@@ -485,7 +486,7 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev)
 		return err;
 	err = reg_r_wait(gspca_dev, 0x06, 0, 0);
 	if (err < 0) {
-		PERR("reg_r_wait() failed");
+		gspca_err(gspca_dev, "reg_r_wait() failed\n");
 		return err;
 	}
 	/* all ok */
@@ -501,7 +502,7 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev)
 static int spca500_synch310(struct gspca_dev *gspca_dev)
 {
 	if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
-		PERR("Set packet size: set interface error");
+		gspca_err(gspca_dev, "Set packet size: set interface error\n");
 		goto error;
 	}
 	spca500_ping310(gspca_dev);
@@ -509,13 +510,14 @@ static int spca500_synch310(struct gspca_dev *gspca_dev)
 	reg_r(gspca_dev, 0x0d00, 1);
 
 	/* need alt setting here */
-	PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
+	gspca_dbg(gspca_dev, D_PACK, "ClickSmart310 sync alt: %d\n",
+		  gspca_dev->alt);
 
 	/* Windoze use pipe with altsetting 6 why 7 here */
 	if (usb_set_interface(gspca_dev->dev,
 				gspca_dev->iface,
 				gspca_dev->alt) < 0) {
-		PERR("Set packet size: set interface error");
+		gspca_err(gspca_dev, "Set packet size: set interface error\n");
 		goto error;
 	}
 	return 0;
@@ -540,7 +542,7 @@ static void spca500_reinit(struct gspca_dev *gspca_dev)
 	err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
 				 qtable_pocketdv);
 	if (err < 0)
-		PERR("spca50x_setup_qtable failed on init");
+		gspca_err(gspca_dev, "spca50x_setup_qtable failed on init\n");
 
 	/* set qtable index */
 	reg_w(gspca_dev, 0x00, 0x8880, 2);
@@ -587,12 +589,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	/* initialisation of spca500 based cameras is deferred */
-	PDEBUG(D_STREAM, "SPCA500 init");
+	gspca_dbg(gspca_dev, D_STREAM, "SPCA500 init\n");
 	if (sd->subtype == LogitechClickSmart310)
 		spca500_clksmart310_init(gspca_dev);
 /*	else
 		spca500_initialise(gspca_dev); */
-	PDEBUG(D_STREAM, "SPCA500 init done");
+	gspca_dbg(gspca_dev, D_STREAM, "SPCA500 init done\n");
 	return 0;
 }
 
@@ -619,10 +621,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
 
 	/* is there a sensor here ? */
 	reg_r(gspca_dev, 0x8a04, 1);
-	PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
-		gspca_dev->usb_buf[0]);
-	PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
-		gspca_dev->curr_mode, xmult, ymult);
+	gspca_dbg(gspca_dev, D_STREAM, "Spca500 Sensor Address 0x%02x\n",
+		  gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
+		  gspca_dev->curr_mode, xmult, ymult);
 
 	/* setup qtable */
 	switch (sd->subtype) {
@@ -636,7 +638,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 					   0x00, 0x8800, 0x8840,
 					   qtable_creative_pccam);
 		if (err < 0)
-			PERR("spca50x_setup_qtable failed");
+			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
 		/* Init SDRAM - needed for SDRAM access */
 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
 
@@ -644,7 +646,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 		msleep(500);
 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
-			PERR("reg_r_wait() failed");
+			gspca_err(gspca_dev, "reg_r_wait() failed\n");
 
 		reg_r(gspca_dev, 0x816b, 1);
 		Data = gspca_dev->usb_buf[0];
@@ -657,13 +659,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		/* enable drop packet */
 		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 		if (err < 0)
-			PERR("failed to enable drop packet");
+			gspca_err(gspca_dev, "failed to enable drop packet\n");
 		reg_w(gspca_dev, 0x00, 0x8880, 3);
 		err = spca50x_setup_qtable(gspca_dev,
 					   0x00, 0x8800, 0x8840,
 					   qtable_creative_pccam);
 		if (err < 0)
-			PERR("spca50x_setup_qtable failed");
+			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
 
 		/* Init SDRAM - needed for SDRAM access */
 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
@@ -672,7 +674,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 
 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
-			PERR("reg_r_wait() failed");
+			gspca_err(gspca_dev, "reg_r_wait() failed\n");
 
 		reg_r(gspca_dev, 0x816b, 1);
 		Data = gspca_dev->usb_buf[0];
@@ -686,18 +688,18 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		/* do a full reset */
 		err = spca500_full_reset(gspca_dev);
 		if (err < 0)
-			PERR("spca500_full_reset failed");
+			gspca_err(gspca_dev, "spca500_full_reset failed\n");
 
 		/* enable drop packet */
 		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 		if (err < 0)
-			PERR("failed to enable drop packet");
+			gspca_err(gspca_dev, "failed to enable drop packet\n");
 		reg_w(gspca_dev, 0x00, 0x8880, 3);
 		err = spca50x_setup_qtable(gspca_dev,
 					   0x00, 0x8800, 0x8840,
 					   qtable_creative_pccam);
 		if (err < 0)
-			PERR("spca50x_setup_qtable failed");
+			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
 
 		spca500_setmode(gspca_dev, xmult, ymult);
 		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
@@ -706,7 +708,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 
 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
-			PERR("reg_r_wait() failed");
+			gspca_err(gspca_dev, "reg_r_wait() failed\n");
 
 		reg_r(gspca_dev, 0x816b, 1);
 		Data = gspca_dev->usb_buf[0];
@@ -719,7 +721,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		/* do a full reset */
 		err = spca500_full_reset(gspca_dev);
 		if (err < 0)
-			PERR("spca500_full_reset failed");
+			gspca_err(gspca_dev, "spca500_full_reset failed\n");
 		/* enable drop packet */
 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
 		reg_w(gspca_dev, 0x00, 0x8880, 0);
@@ -727,7 +729,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 					   0x00, 0x8800, 0x8840,
 					   qtable_kodak_ez200);
 		if (err < 0)
-			PERR("spca50x_setup_qtable failed");
+			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
 		spca500_setmode(gspca_dev, xmult, ymult);
 
 		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
@@ -736,7 +738,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 
 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
-			PERR("reg_r_wait() failed");
+			gspca_err(gspca_dev, "reg_r_wait() failed\n");
 
 		reg_r(gspca_dev, 0x816b, 1);
 		Data = gspca_dev->usb_buf[0];
@@ -762,7 +764,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		err = spca50x_setup_qtable(gspca_dev,
 				   0x00, 0x8800, 0x8840, qtable_pocketdv);
 		if (err < 0)
-			PERR("spca50x_setup_qtable failed");
+			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
 		reg_w(gspca_dev, 0x00, 0x8880, 2);
 
 		/* familycam Quicksmart pocketDV stuff */
@@ -792,7 +794,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 					0x00, 0x8800,
 					0x8840, qtable_creative_pccam);
 		if (err < 0)
-			PERR("spca50x_setup_qtable failed");
+			gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
 		reg_w(gspca_dev, 0x00, 0x8880, 3);
 		reg_w(gspca_dev, 0x00, 0x800a, 0x00);
 		/* Init SDRAM - needed for SDRAM access */
@@ -820,8 +822,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 	/* switch to video camera mode */
 	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
 	reg_r(gspca_dev, 0x8000, 1);
-	PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
-		gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_STREAM, "stop SPCA500 done reg8000: 0x%2x\n",
+		  gspca_dev->usb_buf[0]);
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
diff --git a/drivers/media/usb/gspca/spca501.c b/drivers/media/usb/gspca/spca501.c
index ae5a809..2cce74b 100644
--- a/drivers/media/usb/gspca/spca501.c
+++ b/drivers/media/usb/gspca/spca501.c
@@ -1763,8 +1763,8 @@ static int reg_write(struct gspca_dev *gspca_dev,
 			req,
 			USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			value, index, NULL, 0, 500);
-	PDEBUG(D_USBO, "reg write: 0x%02x 0x%02x 0x%02x",
-		req, index, value);
+	gspca_dbg(gspca_dev, D_USBO, "reg write: 0x%02x 0x%02x 0x%02x\n",
+		  req, index, value);
 	if (ret < 0)
 		pr_err("reg write: error %d\n", ret);
 	return ret;
@@ -1779,8 +1779,8 @@ static int write_vector(struct gspca_dev *gspca_dev, const __u16 data[][3])
 		ret = reg_write(gspca_dev, data[i][0], data[i][2],
 								data[i][1]);
 		if (ret < 0) {
-			PERR("Reg write failed for 0x%02x,0x%02x,0x%02x",
-				data[i][0], data[i][1], data[i][2]);
+			gspca_err(gspca_dev, "Reg write failed for 0x%02x,0x%02x,0x%02x\n",
+				  data[i][0], data[i][1], data[i][2]);
 			return ret;
 		}
 		i++;
@@ -1852,7 +1852,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 			goto error;
 		break;
 	}
-	PDEBUG(D_STREAM, "Initializing SPCA501 finished");
+	gspca_dbg(gspca_dev, D_STREAM, "Initializing SPCA501 finished\n");
 	return 0;
 error:
 	return -EINVAL;
diff --git a/drivers/media/usb/gspca/spca505.c b/drivers/media/usb/gspca/spca505.c
index 1553cc7..07aae9c 100644
--- a/drivers/media/usb/gspca/spca505.c
+++ b/drivers/media/usb/gspca/spca505.c
@@ -551,8 +551,8 @@ static int reg_write(struct gspca_dev *gspca_dev,
 			req,
 			USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			value, index, NULL, 0, 500);
-	PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
-		req, index, value, ret);
+	gspca_dbg(gspca_dev, D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d\n",
+		  req, index, value, ret);
 	if (ret < 0)
 		pr_err("reg write: error %d\n", ret);
 	return ret;
@@ -650,7 +650,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	ret = reg_read(gspca_dev, 0x06, 0x16);
 
 	if (ret < 0) {
-		PERR("register read failed err: %d", ret);
+		gspca_err(gspca_dev, "register read failed err: %d\n", ret);
 		return ret;
 	}
 	if (ret != 0x0101) {
diff --git a/drivers/media/usb/gspca/spca506.c b/drivers/media/usb/gspca/spca506.c
index 843c93f..6332b3f 100644
--- a/drivers/media/usb/gspca/spca506.c
+++ b/drivers/media/usb/gspca/spca506.c
@@ -126,7 +126,7 @@ static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
 	__u8 setbit1 = 0x00;
 	__u8 videomask = 0x00;
 
-	PDEBUG(D_STREAM, "** Open Set Norme **");
+	gspca_dbg(gspca_dev, D_STREAM, "** Open Set Norme **\n");
 	spca506_Initi2c(gspca_dev);
 	/* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */
 	/* Composite channel bit1 -> 1 S-video bit 1 -> 0 */
@@ -153,8 +153,9 @@ static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
 
 	sd->norme = norme;
 	sd->channel = channel;
-	PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask);
-	PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel);
+	gspca_dbg(gspca_dev, D_STREAM, "Set Video Byte to 0x%2x\n", videomask);
+	gspca_dbg(gspca_dev, D_STREAM, "Set Norme: %08x Channel %d",
+		  norme, channel);
 }
 
 static void spca506_GetNormeInput(struct gspca_dev *gspca_dev,
@@ -166,7 +167,8 @@ static void spca506_GetNormeInput(struct gspca_dev *gspca_dev,
 	   we use your own copy in spca50x struct */
 	*norme = sd->norme;
 	*channel = sd->channel;
-	PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel);
+	gspca_dbg(gspca_dev, D_STREAM, "Get Norme: %d Channel %d\n",
+		  *norme, *channel);
 }
 
 static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code,
@@ -174,7 +176,7 @@ static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code,
 {
 	struct usb_device *dev = gspca_dev->dev;
 
-	PDEBUG(D_STREAM, "** SetSize **");
+	gspca_dbg(gspca_dev, D_STREAM, "** SetSize **\n");
 	reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000);
 	/* Soft snap 0x40 Hard 0x41 */
 	reg_w(dev, 0x04, 0x41, 0x0001);
@@ -317,7 +319,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	spca506_WriteI2c(gspca_dev, 0x00, 0x60);
 	spca506_WriteI2c(gspca_dev, 0x05, 0x61);
 	spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
-	PDEBUG(D_STREAM, "** Close Init *");
+	gspca_dbg(gspca_dev, D_STREAM, "** Close Init *\n");
 	return 0;
 }
 
@@ -445,7 +447,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	reg_w(dev, 0x02, 0x01, 0x0000);
 	reg_w(dev, 0x03, 0x12, 0x0000);
 	reg_r(gspca_dev, 0x04, 0x0001, 2);
-	PDEBUG(D_STREAM, "webcam started");
+	gspca_dbg(gspca_dev, D_STREAM, "webcam started\n");
 	spca506_GetNormeInput(gspca_dev, &norme, &channel);
 	spca506_SetNormeInput(gspca_dev, norme, channel);
 	return 0;
diff --git a/drivers/media/usb/gspca/spca508.c b/drivers/media/usb/gspca/spca508.c
index 1e0ba6b..d80fd39 100644
--- a/drivers/media/usb/gspca/spca508.c
+++ b/drivers/media/usb/gspca/spca508.c
@@ -1247,8 +1247,8 @@ static int reg_write(struct gspca_dev *gspca_dev, u16 index, u16 value)
 			0,		/* request */
 			USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			value, index, NULL, 0, 500);
-	PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x",
-		index, value);
+	gspca_dbg(gspca_dev, D_USBO, "reg write i:0x%04x = 0x%02x\n",
+		  index, value);
 	if (ret < 0)
 		pr_err("reg write: error %d\n", ret);
 	return ret;
@@ -1269,8 +1269,8 @@ static int reg_read(struct gspca_dev *gspca_dev,
 			index,
 			gspca_dev->usb_buf, 1,
 			500);			/* timeout */
-	PDEBUG(D_USBI, "reg read i:%04x --> %02x",
-		index, gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_USBI, "reg read i:%04x --> %02x\n",
+		  index, gspca_dev->usb_buf[0]);
 	if (ret < 0) {
 		pr_err("reg_read err %d\n", ret);
 		return ret;
@@ -1309,7 +1309,8 @@ static int ssi_w(struct gspca_dev *gspca_dev,
 		if (gspca_dev->usb_buf[0] == 0)
 			break;
 		if (--retry <= 0) {
-			PERR("ssi_w busy %02x", gspca_dev->usb_buf[0]);
+			gspca_err(gspca_dev, "ssi_w busy %02x\n",
+				  gspca_dev->usb_buf[0]);
 			ret = -1;
 			break;
 		}
@@ -1365,14 +1366,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	 * is a 508. */
 	data1 = reg_read(gspca_dev, 0x8104);
 	data2 = reg_read(gspca_dev, 0x8105);
-	PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1);
+	gspca_dbg(gspca_dev, D_PROBE, "Webcam Vendor ID: 0x%02x%02x\n",
+		  data2, data1);
 
 	data1 = reg_read(gspca_dev, 0x8106);
 	data2 = reg_read(gspca_dev, 0x8107);
-	PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1);
+	gspca_dbg(gspca_dev, D_PROBE, "Webcam Product ID: 0x%02x%02x\n",
+		  data2, data1);
 
 	data1 = reg_read(gspca_dev, 0x8621);
-	PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
+	gspca_dbg(gspca_dev, D_PROBE, "Window 1 average luminance: %d\n",
+		  data1);
 
 	cam = &gspca_dev->cam;
 	cam->cam_mode = sif_mode;
diff --git a/drivers/media/usb/gspca/spca561.c b/drivers/media/usb/gspca/spca561.c
index 4ff704c..f389a8d 100644
--- a/drivers/media/usb/gspca/spca561.c
+++ b/drivers/media/usb/gspca/spca561.c
@@ -290,7 +290,8 @@ static void reg_w_val(struct gspca_dev *gspca_dev, __u16 index, __u8 value)
 			      0,		/* request */
 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			      value, index, NULL, 0, 500);
-	PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
+	gspca_dbg(gspca_dev, D_USBO, "reg write: 0x%02x:0x%02x\n",
+		  index, value);
 	if (ret < 0)
 		pr_err("reg write: error %d\n", ret);
 }
@@ -420,7 +421,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	data2 = gspca_dev->usb_buf[0];
 	product = (data2 << 8) | data1;
 	if (vendor != id->idVendor || product != id->idProduct) {
-		PDEBUG(D_PROBE, "Bad vendor / product from device");
+		gspca_dbg(gspca_dev, D_PROBE, "Bad vendor / product from device\n");
 		return -EINVAL;
 	}
 
@@ -442,13 +443,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
 /* this function is called at probe and resume time */
 static int sd_init_12a(struct gspca_dev *gspca_dev)
 {
-	PDEBUG(D_STREAM, "Chip revision: 012a");
+	gspca_dbg(gspca_dev, D_STREAM, "Chip revision: 012a\n");
 	init_161rev12A(gspca_dev);
 	return 0;
 }
 static int sd_init_72a(struct gspca_dev *gspca_dev)
 {
-	PDEBUG(D_STREAM, "Chip revision: 072a");
+	gspca_dbg(gspca_dev, D_STREAM, "Chip revision: 072a\n");
 	write_vector(gspca_dev, rev72a_reset);
 	msleep(200);
 	write_vector(gspca_dev, rev72a_init_data1);
@@ -679,25 +680,16 @@ static void do_autogain(struct gspca_dev *gspca_dev)
 		y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
 		/* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
 		/* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
-		/* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
 
 		if (y < luma_mean - luma_delta ||
 		    y > luma_mean + luma_delta) {
 			expotimes = i2c_read(gspca_dev, 0x09, 0x10);
 			pixelclk = 0x0800;
 			expotimes = expotimes & 0x07ff;
-			/* PDEBUG(D_PACK,
-				"Exposition Times 0x%03X Clock 0x%04X ",
-				expotimes,pixelclk); */
 			gainG = i2c_read(gspca_dev, 0x35, 0x10);
-			/* PDEBUG(D_PACK,
-				"reading Gain register %d", gainG); */
 
 			expotimes += (luma_mean - y) >> spring;
 			gainG += (luma_mean - y) / 50;
-			/* PDEBUG(D_PACK,
-				"compute expotimes %d gain %d",
-				expotimes,gainG); */
 
 			if (gainG > 0x3f)
 				gainG = 0x3f;
@@ -728,7 +720,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 
 		/* This should never happen */
 		if (len < 2) {
-			PERR("Short SOF packet, ignoring");
+			gspca_err(gspca_dev, "Short SOF packet, ignoring\n\n\n\n\n");
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		}
diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c
index f1da34a..cc8ff41 100644
--- a/drivers/media/usb/gspca/sq905.c
+++ b/drivers/media/usb/gspca/sq905.c
@@ -246,9 +246,9 @@ static void sq905_dostream(struct work_struct *work)
 			ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
 			if (ret < 0)
 				goto quit_stream;
-			PDEBUG(D_PACK,
-				"Got %d bytes out of %d for frame",
-				data_len, bytes_left);
+			gspca_dbg(gspca_dev, D_PACK,
+				  "Got %d bytes out of %d for frame\n",
+				  data_len, bytes_left);
 			bytes_left -= data_len;
 			data = buffer;
 			if (!header_read) {
@@ -345,7 +345,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	ret = sq905_command(gspca_dev, SQ905_CLEAR);
 	if (ret < 0)
 		return ret;
-	PDEBUG(D_CONF, "SQ905 camera ID %08x detected", ident);
+	gspca_dbg(gspca_dev, D_CONF, "SQ905 camera ID %08x detected\n", ident);
 	gspca_dev->cam.cam_mode = sq905_mode;
 	gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode);
 	if (!(ident & SQ905_HIRES_MASK))
@@ -369,20 +369,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	switch (gspca_dev->curr_mode) {
 	default:
 /*	case 2: */
-		PDEBUG(D_STREAM, "Start streaming at high resolution");
+		gspca_dbg(gspca_dev, D_STREAM, "Start streaming at high resolution\n");
 		ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_HIGH);
 		break;
 	case 1:
-		PDEBUG(D_STREAM, "Start streaming at medium resolution");
+		gspca_dbg(gspca_dev, D_STREAM, "Start streaming at medium resolution\n");
 		ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED);
 		break;
 	case 0:
-		PDEBUG(D_STREAM, "Start streaming at low resolution");
+		gspca_dbg(gspca_dev, D_STREAM, "Start streaming at low resolution\n");
 		ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_LOW);
 	}
 
 	if (ret < 0) {
-		PERR("Start streaming command failed");
+		gspca_err(gspca_dev, "Start streaming command failed\n");
 		return ret;
 	}
 	/* Start the workqueue function to do the streaming */
diff --git a/drivers/media/usb/gspca/sq905c.c b/drivers/media/usb/gspca/sq905c.c
index 8b4e494..5e1269e 100644
--- a/drivers/media/usb/gspca/sq905c.c
+++ b/drivers/media/usb/gspca/sq905c.c
@@ -154,15 +154,16 @@ static void sq905c_dostream(struct work_struct *work)
 				usb_rcvbulkpipe(gspca_dev->dev, 0x81),
 				buffer, FRAME_HEADER_LEN, &act_len,
 				SQ905C_DATA_TIMEOUT);
-		PDEBUG(D_STREAM,
-			"Got %d bytes out of %d for header",
-			act_len, FRAME_HEADER_LEN);
+		gspca_dbg(gspca_dev, D_STREAM,
+			  "Got %d bytes out of %d for header\n",
+			  act_len, FRAME_HEADER_LEN);
 		if (ret < 0 || act_len < FRAME_HEADER_LEN)
 			goto quit_stream;
 		/* size is read from 4 bytes starting 0x40, little endian */
 		bytes_left = buffer[0x40]|(buffer[0x41]<<8)|(buffer[0x42]<<16)
 					|(buffer[0x43]<<24);
-		PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left);
+		gspca_dbg(gspca_dev, D_STREAM, "bytes_left = 0x%x\n",
+			  bytes_left);
 		/* We keep the header. It has other information, too. */
 		packet_type = FIRST_PACKET;
 		gspca_frame_add(gspca_dev, packet_type,
@@ -176,9 +177,9 @@ static void sq905c_dostream(struct work_struct *work)
 				SQ905C_DATA_TIMEOUT);
 			if (ret < 0 || act_len < data_len)
 				goto quit_stream;
-			PDEBUG(D_STREAM,
-				"Got %d bytes out of %d for frame",
-				data_len, bytes_left);
+			gspca_dbg(gspca_dev, D_STREAM,
+				  "Got %d bytes out of %d for frame\n",
+				  data_len, bytes_left);
 			bytes_left -= data_len;
 			if (bytes_left == 0)
 				packet_type = LAST_PACKET;
@@ -205,25 +206,25 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	struct sd *dev = (struct sd *) gspca_dev;
 	int ret;
 
-	PDEBUG(D_PROBE,
-	       "SQ9050 camera detected (vid/pid 0x%04X:0x%04X)",
-	       id->idVendor, id->idProduct);
+	gspca_dbg(gspca_dev, D_PROBE,
+		  "SQ9050 camera detected (vid/pid 0x%04X:0x%04X)\n",
+		  id->idVendor, id->idProduct);
 
 	ret = sq905c_command(gspca_dev, SQ905C_GET_ID, 0);
 	if (ret < 0) {
-		PERR("Get version command failed");
+		gspca_err(gspca_dev, "Get version command failed\n");
 		return ret;
 	}
 
 	ret = sq905c_read(gspca_dev, 0xf5, 0, 20);
 	if (ret < 0) {
-		PERR("Reading version command failed");
+		gspca_err(gspca_dev, "Reading version command failed\n");
 		return ret;
 	}
 	/* Note we leave out the usb id and the manufacturing date */
-	PDEBUG(D_PROBE,
-	       "SQ9050 ID string: %02x - %*ph",
-		gspca_dev->usb_buf[3], 6, gspca_dev->usb_buf + 14);
+	gspca_dbg(gspca_dev, D_PROBE,
+		  "SQ9050 ID string: %02x - %*ph\n",
+		  gspca_dev->usb_buf[3], 6, gspca_dev->usb_buf + 14);
 
 	cam->cam_mode = sq905c_mode;
 	cam->nmodes = 2;
@@ -267,19 +268,19 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	/* "Open the shutter" and set size, to start capture */
 	switch (gspca_dev->pixfmt.width) {
 	case 640:
-		PDEBUG(D_STREAM, "Start streaming at high resolution");
+		gspca_dbg(gspca_dev, D_STREAM, "Start streaming at high resolution\n");
 		dev->cap_mode++;
 		ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_HI,
 						SQ905C_CAPTURE_INDEX);
 		break;
 	default: /* 320 */
-	PDEBUG(D_STREAM, "Start streaming at medium resolution");
+		gspca_dbg(gspca_dev, D_STREAM, "Start streaming at medium resolution\n");
 		ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_MED,
 						SQ905C_CAPTURE_INDEX);
 	}
 
 	if (ret < 0) {
-		PERR("Start streaming command failed");
+		gspca_err(gspca_dev, "Start streaming command failed\n");
 		return ret;
 	}
 	/* Start the workqueue function to do the streaming */
diff --git a/drivers/media/usb/gspca/sq930x.c b/drivers/media/usb/gspca/sq930x.c
index aa9a941..d7cbcf2 100644
--- a/drivers/media/usb/gspca/sq930x.c
+++ b/drivers/media/usb/gspca/sq930x.c
@@ -443,7 +443,7 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
 
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_USBO, "reg_w v: %04x i: %04x", value, index);
+	gspca_dbg(gspca_dev, D_USBO, "reg_w v: %04x i: %04x\n", value, index);
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			0x0c,			/* request */
@@ -464,8 +464,8 @@ static void reg_wb(struct gspca_dev *gspca_dev, u16 value, u16 index,
 
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_USBO, "reg_wb v: %04x i: %04x %02x...%02x",
-			value, index, *data, data[len - 1]);
+	gspca_dbg(gspca_dev, D_USBO, "reg_wb v: %04x i: %04x %02x...%02x\n",
+		  value, index, *data, data[len - 1]);
 	memcpy(gspca_dev->usb_buf, data, len);
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -510,8 +510,8 @@ static void i2c_write(struct sd *sd,
 		*buf++ = cmd->val;
 	}
 
-	PDEBUG(D_USBO, "i2c_w v: %04x i: %04x %02x...%02x",
-			val, idx, gspca_dev->usb_buf[0], buf[-1]);
+	gspca_dbg(gspca_dev, D_USBO, "i2c_w v: %04x i: %04x %02x...%02x\n",
+		  val, idx, gspca_dev->usb_buf[0], buf[-1]);
 	ret = usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			0x0c,			/* request */
@@ -538,7 +538,7 @@ static void ucbus_write(struct gspca_dev *gspca_dev,
 		return;
 
 	if ((batchsize - 1) * 3 > USB_BUF_SZ) {
-		PERR("Bug: usb_buf overflow\n");
+		gspca_err(gspca_dev, "Bug: usb_buf overflow\n");
 		gspca_dev->usb_err = -ENOMEM;
 		return;
 	}
@@ -560,12 +560,12 @@ static void ucbus_write(struct gspca_dev *gspca_dev,
 			*buf++ = cmd->bw_data;
 		}
 		if (buf != gspca_dev->usb_buf)
-			PDEBUG(D_USBO, "ucbus v: %04x i: %04x %02x...%02x",
-					val, idx,
-					gspca_dev->usb_buf[0], buf[-1]);
+			gspca_dbg(gspca_dev, D_USBO, "ucbus v: %04x i: %04x %02x...%02x\n",
+				  val, idx,
+				  gspca_dev->usb_buf[0], buf[-1]);
 		else
-			PDEBUG(D_USBO, "ucbus v: %04x i: %04x",
-					val, idx);
+			gspca_dbg(gspca_dev, D_USBO, "ucbus v: %04x i: %04x\n",
+				  val, idx);
 		ret = usb_control_msg(gspca_dev->dev,
 				usb_sndctrlpipe(gspca_dev->dev, 0),
 				0x0c,			/* request */
@@ -691,7 +691,7 @@ static void mt9v111_init(struct gspca_dev *gspca_dev)
 			 || gspca_dev->usb_err != 0)
 				break;
 			if (--nwait < 0) {
-				PDEBUG(D_PROBE, "mt9v111_init timeout");
+				gspca_dbg(gspca_dev, D_PROBE, "mt9v111_init timeout\n");
 				gspca_dev->usb_err = -ETIME;
 				return;
 			}
@@ -857,7 +857,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
  * 6: c8 / c9 / ca / cf = mode webcam?, sensor? webcam?
  * 7: 00
  */
-	PDEBUG(D_PROBE, "info: %*ph", 8, gspca_dev->usb_buf);
+	gspca_dbg(gspca_dev, D_PROBE, "info: %*ph\n", 8, gspca_dev->usb_buf);
 
 	bridge_init(sd);
 
@@ -870,7 +870,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
 			cmos_probe(gspca_dev);
 	}
 	if (gspca_dev->usb_err >= 0) {
-		PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name);
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor %s\n",
+			  sensor_tb[sd->sensor].name);
 		global_init(sd, 1);
 	}
 	return gspca_dev->usb_err;
diff --git a/drivers/media/usb/gspca/stk014.c b/drivers/media/usb/gspca/stk014.c
index daf45db..0d8f489 100644
--- a/drivers/media/usb/gspca/stk014.c
+++ b/drivers/media/usb/gspca/stk014.c
@@ -290,8 +290,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	set_par(gspca_dev, 0x01000000);
 	set_par(gspca_dev, 0x01000000);
 	if (gspca_dev->usb_err >= 0)
-		PDEBUG(D_STREAM, "camera started alt: 0x%02x",
-				gspca_dev->alt);
+		gspca_dbg(gspca_dev, D_STREAM, "camera started alt: 0x%02x\n",
+			  gspca_dev->alt);
 out:
 	return gspca_dev->usb_err;
 }
@@ -312,7 +312,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 	reg_w(gspca_dev, 0x0640, 0);
 	reg_w(gspca_dev, 0x0650, 0);
 	reg_w(gspca_dev, 0x0660, 0);
-	PDEBUG(D_STREAM, "camera stopped");
+	gspca_dbg(gspca_dev, D_STREAM, "camera stopped\n");
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
diff --git a/drivers/media/usb/gspca/stk1135.c b/drivers/media/usb/gspca/stk1135.c
index 3ab5ec2..6f52a48 100644
--- a/drivers/media/usb/gspca/stk1135.c
+++ b/drivers/media/usb/gspca/stk1135.c
@@ -67,7 +67,8 @@ static u8 reg_r(struct gspca_dev *gspca_dev, u16 index)
 			gspca_dev->usb_buf, 1,
 			500);
 
-	PDEBUG(D_USBI, "reg_r 0x%x=0x%02x", index, gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_USBI, "reg_r 0x%x=0x%02x\n",
+		  index, gspca_dev->usb_buf[0]);
 	if (ret < 0) {
 		pr_err("reg_r 0x%x err %d\n", index, ret);
 		gspca_dev->usb_err = ret;
@@ -93,7 +94,7 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 index, u8 val)
 			NULL,
 			0,
 			500);
-	PDEBUG(D_USBO, "reg_w 0x%x:=0x%02x", index, val);
+	gspca_dbg(gspca_dev, D_USBO, "reg_w 0x%x:=0x%02x\n", index, val);
 	if (ret < 0) {
 		pr_err("reg_w 0x%x err %d\n", index, ret);
 		gspca_dev->usb_err = ret;
@@ -468,8 +469,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	reg_w_mask(gspca_dev, STK1135_REG_SCTRL, 0x80, 0x80);
 
 	if (gspca_dev->usb_err >= 0)
-		PDEBUG(D_STREAM, "camera started alt: 0x%02x",
-				gspca_dev->alt);
+		gspca_dbg(gspca_dev, D_STREAM, "camera started alt: 0x%02x\n",
+			  gspca_dev->alt);
 
 	sd->pkt_seq = 0;
 
@@ -484,7 +485,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 
 	stk1135_camera_disable(gspca_dev);
 
-	PDEBUG(D_STREAM, "camera stopped");
+	gspca_dbg(gspca_dev, D_STREAM, "camera stopped\n");
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -499,7 +500,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	u8 seq;
 
 	if (len < 4) {
-		PDEBUG(D_PACK, "received short packet (less than 4 bytes)");
+		gspca_dbg(gspca_dev, D_PACK, "received short packet (less than 4 bytes)\n");
 		return;
 	}
 
@@ -515,7 +516,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	if (!(hdr->flags & STK1135_HDR_FRAME_START)) {
 		seq = hdr->seq & STK1135_HDR_SEQ_MASK;
 		if (seq != sd->pkt_seq) {
-			PDEBUG(D_PACK, "received out-of-sequence packet");
+			gspca_dbg(gspca_dev, D_PACK, "received out-of-sequence packet\n");
 			/* resync sequence and discard packet */
 			sd->pkt_seq = seq;
 			gspca_dev->last_packet_type = DISCARD_PACKET;
diff --git a/drivers/media/usb/gspca/stv0680.c b/drivers/media/usb/gspca/stv0680.c
index 29a65d0..3ff5ed7 100644
--- a/drivers/media/usb/gspca/stv0680.c
+++ b/drivers/media/usb/gspca/stv0680.c
@@ -82,8 +82,8 @@ static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
 static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret)
 {
 	stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */
-	PERR("last error: %i,  command = 0x%x",
-	       gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+	gspca_err(gspca_dev, "last error: %i,  command = 0x%x\n",
+		  gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
 	return ret;
 }
 
@@ -94,7 +94,7 @@ static int stv0680_get_video_mode(struct gspca_dev *gspca_dev)
 	gspca_dev->usb_buf[0] = 0x0f;
 
 	if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) {
-		PERR("Get_Camera_Mode failed");
+		gspca_err(gspca_dev, "Get_Camera_Mode failed\n");
 		return stv0680_handle_error(gspca_dev, -EIO);
 	}
 
@@ -112,13 +112,13 @@ static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode)
 	gspca_dev->usb_buf[0] = mode;
 
 	if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) {
-		PERR("Set_Camera_Mode failed");
+		gspca_err(gspca_dev, "Set_Camera_Mode failed\n");
 		return stv0680_handle_error(gspca_dev, -EIO);
 	}
 
 	/* Verify we got what we've asked for */
 	if (stv0680_get_video_mode(gspca_dev) != mode) {
-		PERR("Error setting camera video mode!");
+		gspca_err(gspca_dev, "Error setting camera video mode!\n");
 		return -EIO;
 	}
 
@@ -142,7 +142,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	/* ping camera to be sure STV0680 is present */
 	if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
 	    gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
-		PERR("STV(e): camera ping failed!!");
+		gspca_err(gspca_dev, "STV(e): camera ping failed!!\n");
 		return stv0680_handle_error(gspca_dev, -ENODEV);
 	}
 
@@ -152,7 +152,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 
 	if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 ||
 	    gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) {
-		PERR("Could not get descriptor 0200.");
+		gspca_err(gspca_dev, "Could not get descriptor 0200\n");
 		return stv0680_handle_error(gspca_dev, -ENODEV);
 	}
 	if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02)
@@ -163,17 +163,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		return stv0680_handle_error(gspca_dev, -ENODEV);
 
 	if (!(gspca_dev->usb_buf[7] & 0x09)) {
-		PERR("Camera supports neither CIF nor QVGA mode");
+		gspca_err(gspca_dev, "Camera supports neither CIF nor QVGA mode\n");
 		return -ENODEV;
 	}
 	if (gspca_dev->usb_buf[7] & 0x01)
-		PDEBUG(D_PROBE, "Camera supports CIF mode");
+		gspca_dbg(gspca_dev, D_PROBE, "Camera supports CIF mode\n");
 	if (gspca_dev->usb_buf[7] & 0x02)
-		PDEBUG(D_PROBE, "Camera supports VGA mode");
+		gspca_dbg(gspca_dev, D_PROBE, "Camera supports VGA mode\n");
 	if (gspca_dev->usb_buf[7] & 0x04)
-		PDEBUG(D_PROBE, "Camera supports QCIF mode");
+		gspca_dbg(gspca_dev, D_PROBE, "Camera supports QCIF mode\n");
 	if (gspca_dev->usb_buf[7] & 0x08)
-		PDEBUG(D_PROBE, "Camera supports QVGA mode");
+		gspca_dbg(gspca_dev, D_PROBE, "Camera supports QVGA mode\n");
 
 	if (gspca_dev->usb_buf[7] & 0x01)
 		sd->video_mode = 0x00; /* CIF */
@@ -181,12 +181,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		sd->video_mode = 0x03; /* QVGA */
 
 	/* FW rev, ASIC rev, sensor ID  */
-	PDEBUG(D_PROBE, "Firmware rev is %i.%i",
-	       gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
-	PDEBUG(D_PROBE, "ASIC rev is %i.%i",
-	       gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
-	PDEBUG(D_PROBE, "Sensor ID is %i",
-	       (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
+	gspca_dbg(gspca_dev, D_PROBE, "Firmware rev is %i.%i\n",
+		  gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+	gspca_dbg(gspca_dev, D_PROBE, "ASIC rev is %i.%i",
+		  gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
+	gspca_dbg(gspca_dev, D_PROBE, "Sensor ID is %i",
+		  (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
 
 
 	ret = stv0680_get_video_mode(gspca_dev);
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c
index e72c3e1..6080a35 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c
@@ -51,8 +51,8 @@ int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data)
 			      0x04, 0x40, address, 0, buf, len,
 			      STV06XX_URB_MSG_TIMEOUT);
 
-	PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d",
-	       i2c_data, address, err);
+	gspca_dbg(gspca_dev, D_CONF, "Written 0x%x to address 0x%x, status: %d\n",
+		  i2c_data, address, err);
 
 	return (err < 0) ? err : 0;
 }
@@ -70,8 +70,8 @@ int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data)
 
 	*i2c_data = buf[0];
 
-	PDEBUG(D_CONF, "Reading 0x%x from address 0x%x, status %d",
-	       *i2c_data, address, err);
+	gspca_dbg(gspca_dev, D_CONF, "Reading 0x%x from address 0x%x, status %d\n",
+		  *i2c_data, address, err);
 
 	return (err < 0) ? err : 0;
 }
@@ -113,15 +113,16 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
 	struct usb_device *udev = sd->gspca_dev.dev;
 	__u8 *buf = sd->gspca_dev.usb_buf;
 
-	PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
+	gspca_dbg(gspca_dev, D_CONF, "I2C: Command buffer contains %d entries\n",
+		  len);
 	for (i = 0; i < len;) {
 		/* Build the command buffer */
 		memset(buf, 0, I2C_BUFFER_LENGTH);
 		for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) {
 			buf[j] = data[2*i];
 			buf[0x10 + j] = data[2*i+1];
-			PDEBUG(D_CONF, "I2C: Writing 0x%02x to reg 0x%02x",
-			data[2*i+1], data[2*i]);
+			gspca_dbg(gspca_dev, D_CONF, "I2C: Writing 0x%02x to reg 0x%02x\n",
+				  data[2*i+1], data[2*i]);
 		}
 		buf[0x20] = sd->sensor->i2c_addr;
 		buf[0x21] = j - 1; /* Number of commands to send - 1 */
@@ -143,7 +144,8 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
 	struct usb_device *udev = sd->gspca_dev.dev;
 	__u8 *buf = sd->gspca_dev.usb_buf;
 
-	PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
+	gspca_dbg(gspca_dev, D_CONF, "I2C: Command buffer contains %d entries\n",
+		  len);
 
 	for (i = 0; i < len;) {
 		/* Build the command buffer */
@@ -152,8 +154,8 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
 			buf[j] = data[2*i];
 			buf[0x10 + j * 2] = data[2*i+1];
 			buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8;
-			PDEBUG(D_CONF, "I2C: Writing 0x%04x to reg 0x%02x",
-				data[2*i+1], data[2*i]);
+			gspca_dbg(gspca_dev, D_CONF, "I2C: Writing 0x%04x to reg 0x%02x\n",
+				  data[2*i+1], data[2*i]);
 		}
 		buf[0x20] = sd->sensor->i2c_addr;
 		buf[0x21] = j - 1; /* Number of commands to send - 1 */
@@ -205,8 +207,8 @@ int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
 	else
 		*value = buf[0];
 
-	PDEBUG(D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d",
-	       *value, address, err);
+	gspca_dbg(gspca_dev, D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d\n",
+		  *value, address, err);
 
 	return (err < 0) ? err : 0;
 }
@@ -249,7 +251,7 @@ static int stv06xx_init(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 	int err;
 
-	PDEBUG(D_PROBE, "Initializing camera");
+	gspca_dbg(gspca_dev, D_PROBE, "Initializing camera\n");
 
 	/* Let the usb init settle for a bit
 	   before performing the initialization */
@@ -268,7 +270,7 @@ static int stv06xx_init_controls(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_PROBE, "Initializing controls");
+	gspca_dbg(gspca_dev, D_PROBE, "Initializing controls\n");
 
 	gspca_dev->vdev.ctrl_handler = &gspca_dev->ctrl_handler;
 	return sd->sensor->init_controls(sd);
@@ -285,7 +287,7 @@ static int stv06xx_start(struct gspca_dev *gspca_dev)
 	intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
 	alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
 	if (!alt) {
-		PERR("Couldn't get altsetting");
+		gspca_err(gspca_dev, "Couldn't get altsetting\n");
 		return -EIO;
 	}
 
@@ -304,9 +306,9 @@ static int stv06xx_start(struct gspca_dev *gspca_dev)
 
 out:
 	if (err < 0)
-		PDEBUG(D_STREAM, "Starting stream failed");
+		gspca_dbg(gspca_dev, D_STREAM, "Starting stream failed\n");
 	else
-		PDEBUG(D_STREAM, "Started streaming");
+		gspca_dbg(gspca_dev, D_STREAM, "Started streaming\n");
 
 	return (err < 0) ? err : 0;
 }
@@ -343,7 +345,7 @@ static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev)
 
 	ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
 	if (ret < 0)
-		PERR("set alt 1 err %d", ret);
+		gspca_err(gspca_dev, "set alt 1 err %d\n", ret);
 
 	return ret;
 }
@@ -362,9 +364,9 @@ static void stv06xx_stopN(struct gspca_dev *gspca_dev)
 
 out:
 	if (err < 0)
-		PDEBUG(D_STREAM, "Failed to stop stream");
+		gspca_dbg(gspca_dev, D_STREAM, "Failed to stop stream\n");
 	else
-		PDEBUG(D_STREAM, "Stopped streaming");
+		gspca_dbg(gspca_dev, D_STREAM, "Stopped streaming\n");
 }
 
 /*
@@ -385,7 +387,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_PACK, "Packet of length %d arrived", len);
+	gspca_dbg(gspca_dev, D_PACK, "Packet of length %d arrived\n", len);
 
 	/* A packet may contain several frames
 	   loop until the whole packet is reached */
@@ -393,7 +395,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
 		int id, chunk_len;
 
 		if (len < 4) {
-			PDEBUG(D_PACK, "Packet is smaller than 4 bytes");
+			gspca_dbg(gspca_dev, D_PACK, "Packet is smaller than 4 bytes\n");
 			return;
 		}
 
@@ -402,13 +404,14 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
 
 		/* Capture the chunk length */
 		chunk_len = (data[2] << 8) | data[3];
-		PDEBUG(D_PACK, "Chunk id: %x, length: %d", id, chunk_len);
+		gspca_dbg(gspca_dev, D_PACK, "Chunk id: %x, length: %d\n",
+			  id, chunk_len);
 
 		data += 4;
 		len -= 4;
 
 		if (len < chunk_len) {
-			PERR("URB packet length is smaller than the specified chunk length");
+			gspca_err(gspca_dev, "URB packet length is smaller than the specified chunk length\n");
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		}
@@ -421,7 +424,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
 		case 0x0200:
 		case 0x4200:
 frame_data:
-			PDEBUG(D_PACK, "Frame data packet detected");
+			gspca_dbg(gspca_dev, D_PACK, "Frame data packet detected\n");
 
 			if (sd->to_skip) {
 				int skip = (sd->to_skip < chunk_len) ?
@@ -440,7 +443,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
 		case 0x8005:
 		case 0xc001:
 		case 0xc005:
-			PDEBUG(D_PACK, "Starting new frame");
+			gspca_dbg(gspca_dev, D_PACK, "Starting new frame\n");
 
 			/* Create a new frame, chunk length should be zero */
 			gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -450,40 +453,41 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
 				sd->to_skip = gspca_dev->pixfmt.width * 4;
 
 			if (chunk_len)
-				PERR("Chunk length is non-zero on a SOF");
+				gspca_err(gspca_dev, "Chunk length is non-zero on a SOF\n");
 			break;
 
 		case 0x8002:
 		case 0x8006:
 		case 0xc002:
-			PDEBUG(D_PACK, "End of frame detected");
+			gspca_dbg(gspca_dev, D_PACK, "End of frame detected\n");
 
 			/* Complete the last frame (if any) */
 			gspca_frame_add(gspca_dev, LAST_PACKET,
 					NULL, 0);
 
 			if (chunk_len)
-				PERR("Chunk length is non-zero on a EOF");
+				gspca_err(gspca_dev, "Chunk length is non-zero on a EOF\n");
 			break;
 
 		case 0x0005:
-			PDEBUG(D_PACK, "Chunk 0x005 detected");
+			gspca_dbg(gspca_dev, D_PACK, "Chunk 0x005 detected\n");
 			/* Unknown chunk with 11 bytes of data,
 			   occurs just before end of each frame
 			   in compressed mode */
 			break;
 
 		case 0x0100:
-			PDEBUG(D_PACK, "Chunk 0x0100 detected");
+			gspca_dbg(gspca_dev, D_PACK, "Chunk 0x0100 detected\n");
 			/* Unknown chunk with 2 bytes of data,
 			   occurs 2-3 times per USB interrupt */
 			break;
 		case 0x42ff:
-			PDEBUG(D_PACK, "Chunk 0x42ff detected");
+			gspca_dbg(gspca_dev, D_PACK, "Chunk 0x42ff detected\n");
 			/* Special chunk seen sometimes on the ST6422 */
 			break;
 		default:
-			PDEBUG(D_PACK, "Unknown chunk 0x%04x detected", id);
+			gspca_dbg(gspca_dev, D_PACK, "Unknown chunk 0x%04x detected\n",
+				  id);
 			/* Unknown chunk */
 		}
 		data    += chunk_len;
@@ -539,7 +543,7 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_PROBE, "Configuring camera");
+	gspca_dbg(gspca_dev, D_PROBE, "Configuring camera\n");
 
 	sd->bridge = id->driver_info;
 	gspca_dev->sd_desc = &sd_desc;
@@ -575,7 +579,7 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
 
 /* -- module initialisation -- */
 static const struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, 	/* QuickCam Express */
+	{USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 },	/* QuickCam Express */
 	{USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 },	/* LEGO cam / QuickCam Web */
 	{USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 },	/* Dexxa WebCam USB */
 	{USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 },	/* QuickCam Messenger */
@@ -598,7 +602,7 @@ static void sd_disconnect(struct usb_interface *intf)
 	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
 	struct sd *sd = (struct sd *) gspca_dev;
 	void *priv = sd->sensor_priv;
-	PDEBUG(D_PROBE, "Disconnecting the stv06xx device");
+	gspca_dbg(gspca_dev, D_PROBE, "Disconnecting the stv06xx device\n");
 
 	sd->sensor = NULL;
 	gspca_disconnect(intf);
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.h b/drivers/media/usb/gspca/stv06xx/stv06xx.h
index f9d74e4d..4801867 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx.h
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx.h
@@ -59,7 +59,7 @@
 
 /* Refers to the CIF 352x288 and QCIF 176x144 */
 /* 1: 288 lines, 2: 144 lines */
-#define STV_Y_CTRL		        0x15c3
+#define STV_Y_CTRL			0x15c3
 
 #define STV_RESET                       0x1620
 
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
index 28252f6..d8db2c8 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
@@ -251,8 +251,8 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 		if (err < 0)
 			return err;
 	}
-	PDEBUG(D_CONF, "Writing exposure %d, rowexp %d, srowexp %d",
-	       val, rowexp, srowexp);
+	gspca_dbg(gspca_dev, D_CONF, "Writing exposure %d, rowexp %d, srowexp %d\n",
+		  val, rowexp, srowexp);
 	return err;
 }
 
@@ -276,7 +276,7 @@ static int hdcs_set_gains(struct sd *sd, u8 g)
 
 static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
-	PDEBUG(D_CONF, "Writing gain %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Writing gain %d\n", val);
 	return hdcs_set_gains((struct sd *) gspca_dev,
 			       val & 0xff);
 }
@@ -465,7 +465,7 @@ static int hdcs_start(struct sd *sd)
 {
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 
-	PDEBUG(D_STREAM, "Starting stream");
+	gspca_dbg(gspca_dev, D_STREAM, "Starting stream\n");
 
 	return hdcs_set_state(sd, HDCS_STATE_RUN);
 }
@@ -474,7 +474,7 @@ static int hdcs_stop(struct sd *sd)
 {
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 
-	PDEBUG(D_STREAM, "Halting stream");
+	gspca_dbg(gspca_dev, D_STREAM, "Halting stream\n");
 
 	return hdcs_set_state(sd, HDCS_STATE_SLEEP);
 }
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
index e1ce96e..7374aeb 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
@@ -229,7 +229,7 @@ static int pb0100_start(struct sd *sd)
 	}
 
 	err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
-	PDEBUG(D_STREAM, "Started stream, status: %d", err);
+	gspca_dbg(gspca_dev, D_STREAM, "Started stream, status: %d\n", err);
 
 	return (err < 0) ? err : 0;
 }
@@ -247,7 +247,7 @@ static int pb0100_stop(struct sd *sd)
 	/* Set bit 1 to zero */
 	err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
 
-	PDEBUG(D_STREAM, "Halting stream");
+	gspca_dbg(gspca_dev, D_STREAM, "Halting stream\n");
 out:
 	return (err < 0) ? err : 0;
 }
@@ -332,7 +332,8 @@ static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
 	if (!err)
 		err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
-	PDEBUG(D_CONF, "Set green gain to %d, status: %d", val, err);
+	gspca_dbg(gspca_dev, D_CONF, "Set green gain to %d, status: %d\n",
+		  val, err);
 
 	if (!err)
 		err = pb0100_set_red_balance(gspca_dev, ctrls->red->val);
@@ -355,7 +356,8 @@ static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 		val = 255;
 
 	err = stv06xx_write_sensor(sd, PB_RGAIN, val);
-	PDEBUG(D_CONF, "Set red gain to %d, status: %d", val, err);
+	gspca_dbg(gspca_dev, D_CONF, "Set red gain to %d, status: %d\n",
+		  val, err);
 
 	return err;
 }
@@ -373,7 +375,8 @@ static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 		val = 255;
 
 	err = stv06xx_write_sensor(sd, PB_BGAIN, val);
-	PDEBUG(D_CONF, "Set blue gain to %d, status: %d", val, err);
+	gspca_dbg(gspca_dev, D_CONF, "Set blue gain to %d, status: %d\n",
+		  val, err);
 
 	return err;
 }
@@ -384,7 +387,8 @@ static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	int err;
 
 	err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
-	PDEBUG(D_CONF, "Set exposure to %d, status: %d", val, err);
+	gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d, status: %d\n",
+		  val, err);
 
 	return err;
 }
@@ -404,8 +408,8 @@ static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
 		val = 0;
 
 	err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
-	PDEBUG(D_CONF, "Set autogain to %d (natural: %d), status: %d",
-	       val, ctrls->natural->val, err);
+	gspca_dbg(gspca_dev, D_CONF, "Set autogain to %d (natural: %d), status: %d\n",
+		  val, ctrls->natural->val, err);
 
 	return err;
 }
@@ -426,7 +430,8 @@ static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
 	if (!err)
 		err = stv06xx_write_sensor(sd, PB_R22, darkpixels);
 
-	PDEBUG(D_CONF, "Set autogain target to %d, status: %d", val, err);
+	gspca_dbg(gspca_dev, D_CONF, "Set autogain target to %d, status: %d\n",
+		  val, err);
 
 	return err;
 }
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c
index 4b76070..51a135c 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c
@@ -277,7 +277,7 @@ static int st6422_stop(struct sd *sd)
 {
 	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
 
-	PDEBUG(D_STREAM, "Halting stream");
+	gspca_dbg(gspca_dev, D_STREAM, "Halting stream\n");
 
 	return 0;
 }
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c
index d265e6b..b2f16c2 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c
@@ -129,7 +129,7 @@ static int vv6410_start(struct sd *sd)
 	u32 priv = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
 
 	if (priv & VV6410_SUBSAMPLE) {
-		PDEBUG(D_CONF, "Enabling subsampling");
+		gspca_dbg(gspca_dev, D_CONF, "Enabling subsampling\n");
 		stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02);
 		stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
 
@@ -150,7 +150,7 @@ static int vv6410_start(struct sd *sd)
 	if (err < 0)
 		return err;
 
-	PDEBUG(D_STREAM, "Starting stream");
+	gspca_dbg(gspca_dev, D_STREAM, "Starting stream\n");
 
 	return 0;
 }
@@ -169,7 +169,7 @@ static int vv6410_stop(struct sd *sd)
 	if (err < 0)
 		return err;
 
-	PDEBUG(D_STREAM, "Halting stream");
+	gspca_dbg(gspca_dev, D_STREAM, "Halting stream\n");
 
 	return 0;
 }
@@ -203,7 +203,7 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 	else
 		i2c_data &= ~VV6410_HFLIP;
 
-	PDEBUG(D_CONF, "Set horizontal flip to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set horizontal flip to %d\n", val);
 	err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data);
 
 	return (err < 0) ? err : 0;
@@ -224,7 +224,7 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 	else
 		i2c_data &= ~VV6410_VFLIP;
 
-	PDEBUG(D_CONF, "Set vertical flip to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set vertical flip to %d\n", val);
 	err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data);
 
 	return (err < 0) ? err : 0;
@@ -235,7 +235,7 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
 	int err;
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	PDEBUG(D_CONF, "Set analog gain to %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Set analog gain to %d\n", val);
 	err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
 
 	return (err < 0) ? err : 0;
@@ -252,8 +252,8 @@ static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	fine = val % VV6410_CIF_LINELENGTH;
 	coarse = min(512, val / VV6410_CIF_LINELENGTH);
 
-	PDEBUG(D_CONF, "Set coarse exposure to %d, fine exposure to %d",
-	       coarse, fine);
+	gspca_dbg(gspca_dev, D_CONF, "Set coarse exposure to %d, fine exposure to %d\n",
+		  coarse, fine);
 
 	err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8);
 	if (err < 0)
diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c
index 8c2785a..437a336 100644
--- a/drivers/media/usb/gspca/sunplus.c
+++ b/drivers/media/usb/gspca/sunplus.c
@@ -248,7 +248,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
 	int ret;
 
 	if (len > USB_BUF_SZ) {
-		PERR("reg_r: buffer overflow\n");
+		gspca_err(gspca_dev, "reg_r: buffer overflow\n");
 		return;
 	}
 	if (gspca_dev->usb_err < 0)
@@ -311,8 +311,8 @@ static void reg_w_riv(struct gspca_dev *gspca_dev,
 		gspca_dev->usb_err = ret;
 		return;
 	}
-	PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x",
-		req, index, value);
+	gspca_dbg(gspca_dev, D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x\n",
+		  req, index, value);
 }
 
 static void write_vector(struct gspca_dev *gspca_dev,
@@ -343,12 +343,14 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
 {
 	reg_w_riv(gspca_dev, req, idx, val);
 	reg_r(gspca_dev, 0x01, 0x0001, 1);
-	PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_FRAM, "before wait 0x%04x\n",
+		  gspca_dev->usb_buf[0]);
 	reg_w_riv(gspca_dev, req, idx, val);
 
 	msleep(200);
 	reg_r(gspca_dev, 0x01, 0x0001, 1);
-	PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_FRAM, "after wait 0x%04x\n",
+		  gspca_dev->usb_buf[0]);
 }
 
 static void spca504_read_info(struct gspca_dev *gspca_dev)
@@ -363,10 +365,10 @@ static void spca504_read_info(struct gspca_dev *gspca_dev)
 		reg_r(gspca_dev, 0, i, 1);
 		info[i] = gspca_dev->usb_buf[0];
 	}
-	PDEBUG(D_STREAM,
-		"Read info: %d %d %d %d %d %d. Should be 1,0,2,2,0,0",
-		info[0], info[1], info[2],
-		info[3], info[4], info[5]);
+	gspca_dbg(gspca_dev, D_STREAM,
+		  "Read info: %d %d %d %d %d %d. Should be 1,0,2,2,0,0\n",
+		  info[0], info[1], info[2],
+		  info[3], info[4], info[5]);
 }
 
 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
@@ -379,8 +381,8 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
 	reg_r(gspca_dev, 0x01, 0x0001, 1);
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x",
-			gspca_dev->usb_buf[0], endcode);
+	gspca_dbg(gspca_dev, D_FRAM, "Status 0x%02x Need 0x%02x\n",
+		  gspca_dev->usb_buf[0], endcode);
 	if (!count)
 		return;
 	count = 200;
@@ -391,8 +393,8 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
 		reg_r(gspca_dev, 0x01, 0x0001, 1);
 		status = gspca_dev->usb_buf[0];
 		if (status == endcode) {
-			PDEBUG(D_FRAM, "status 0x%04x after wait %d",
-				status, 200 - count);
+			gspca_dbg(gspca_dev, D_FRAM, "status 0x%04x after wait %d\n",
+				  status, 200 - count);
 				break;
 		}
 	}
@@ -435,8 +437,8 @@ static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
 
 	data = gspca_dev->usb_buf;
 	reg_r(gspca_dev, 0x20, 0, 5);
-	PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d",
-		data[0], data[1], data[2], data[3], data[4]);
+	gspca_dbg(gspca_dev, D_STREAM, "FirmWare: %d %d %d %d %d\n",
+		  data[0], data[1], data[2], data[3], data[4]);
 	reg_r(gspca_dev, 0x23, 0, 64);
 	reg_r(gspca_dev, 0x23, 1, 64);
 }
@@ -651,7 +653,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		spca504B_WaitCmdStatus(gspca_dev);
 		break;
 	case BRIDGE_SPCA504C:	/* pccam600 */
-		PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
+		gspca_dbg(gspca_dev, D_STREAM, "Opening SPCA504 (PC-CAM 600)\n");
 		reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
 		reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001);	/* reset */
 		spca504_wait_status(gspca_dev);
@@ -666,7 +668,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		break;
 	default:
 /*	case BRIDGE_SPCA504: */
-		PDEBUG(D_STREAM, "Opening SPCA504");
+		gspca_dbg(gspca_dev, D_STREAM, "Opening SPCA504\n");
 		if (sd->subtype == AiptekMiniPenCam13) {
 			spca504_read_info(gspca_dev);
 
diff --git a/drivers/media/usb/gspca/t613.c b/drivers/media/usb/gspca/t613.c
index 46fb763..0ae557c 100644
--- a/drivers/media/usb/gspca/t613.c
+++ b/drivers/media/usb/gspca/t613.c
@@ -490,7 +490,7 @@ static void setcolors(struct gspca_dev *gspca_dev, s32 val)
 
 static void setgamma(struct gspca_dev *gspca_dev, s32 val)
 {
-	PDEBUG(D_CONF, "Gamma: %d", val);
+	gspca_dbg(gspca_dev, D_CONF, "Gamma: %d\n", val);
 	reg_w_ixbuf(gspca_dev, 0x90,
 		gamma_table[val], sizeof gamma_table[0]);
 }
@@ -592,19 +592,19 @@ static int sd_init(struct gspca_dev *gspca_dev)
 			| reg_r(gspca_dev, 0x07);
 	switch (sensor_id & 0xff0f) {
 	case 0x0801:
-		PDEBUG(D_PROBE, "sensor tas5130a");
+		gspca_dbg(gspca_dev, D_PROBE, "sensor tas5130a\n");
 		sd->sensor = SENSOR_TAS5130A;
 		break;
 	case 0x0802:
-		PDEBUG(D_PROBE, "sensor lt168g");
+		gspca_dbg(gspca_dev, D_PROBE, "sensor lt168g\n");
 		sd->sensor = SENSOR_LT168G;
 		break;
 	case 0x0803:
-		PDEBUG(D_PROBE, "sensor 'other'");
+		gspca_dbg(gspca_dev, D_PROBE, "sensor 'other'\n");
 		sd->sensor = SENSOR_OTHER;
 		break;
 	case 0x0807:
-		PDEBUG(D_PROBE, "sensor om6802");
+		gspca_dbg(gspca_dev, D_PROBE, "sensor om6802\n");
 		sd->sensor = SENSOR_OM6802;
 		break;
 	default:
@@ -632,8 +632,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	i = 0;
 	while (read_indexs[i] != 0x00) {
 		test_byte = reg_r(gspca_dev, read_indexs[i]);
-		PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
-		       test_byte);
+		gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n",
+			  read_indexs[i], test_byte);
 		i++;
 	}
 
@@ -643,8 +643,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
 
 	if (sd->sensor == SENSOR_LT168G) {
 		test_byte = reg_r(gspca_dev, 0x80);
-		PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
-		       test_byte);
+		gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n", 0x80,
+			  test_byte);
 		reg_w(gspca_dev, 0x6c80);
 	}
 
@@ -665,8 +665,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
 
 	if (sd->sensor == SENSOR_LT168G) {
 		test_byte = reg_r(gspca_dev, 0x80);
-		PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
-		       test_byte);
+		gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n", 0x80,
+			  test_byte);
 		reg_w(gspca_dev, 0x6c80);
 	}
 
@@ -737,7 +737,7 @@ static void poll_sensor(struct gspca_dev *gspca_dev)
 		 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
 		 0xc2, 0x80, 0xc3, 0x10};
 
-	PDEBUG(D_STREAM, "[Sensor requires polling]");
+	gspca_dbg(gspca_dev, D_STREAM, "[Sensor requires polling]\n");
 	reg_w_buf(gspca_dev, poll1, sizeof poll1);
 	reg_w_buf(gspca_dev, poll2, sizeof poll2);
 	reg_w_buf(gspca_dev, noise03, sizeof noise03);
diff --git a/drivers/media/usb/gspca/topro.c b/drivers/media/usb/gspca/topro.c
index 983fc6b..82e2be1 100644
--- a/drivers/media/usb/gspca/topro.c
+++ b/drivers/media/usb/gspca/topro.c
@@ -1453,7 +1453,7 @@ static void set_dqt(struct gspca_dev *gspca_dev, u8 q)
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	/* update the jpeg quantization tables */
-	PDEBUG(D_STREAM, "q %d -> %d", sd->quality, q);
+	gspca_dbg(gspca_dev, D_STREAM, "q %d -> %d\n", sd->quality, q);
 	sd->quality = q;
 	if (q > 16)
 		q = 16;
@@ -4053,7 +4053,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 				ARRAY_SIZE(tp6810_preinit));
 	msleep(15);
 	reg_r(gspca_dev, TP6800_R18_GPIO_DATA);
-	PDEBUG(D_PROBE, "gpio: %02x", gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_PROBE, "gpio: %02x\n", gspca_dev->usb_buf[0]);
 /* values:
  *	0x80: snapshot button
  *	0x40: LED
@@ -4627,7 +4627,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			if (*data == 0xaa || *data == 0x00)
 				return;
 			if (*data > 0xc0) {
-				PDEBUG(D_FRAM, "bad frame");
+				gspca_dbg(gspca_dev, D_FRAM, "bad frame\n");
 				gspca_dev->last_packet_type = DISCARD_PACKET;
 				return;
 			}
diff --git a/drivers/media/usb/gspca/touptek.c b/drivers/media/usb/gspca/touptek.c
index b8af437..d1b9032 100644
--- a/drivers/media/usb/gspca/touptek.c
+++ b/drivers/media/usb/gspca/touptek.c
@@ -195,15 +195,15 @@ static const struct v4l2_pix_format vga_mode[] = {
 static int val_reply(struct gspca_dev *gspca_dev, const char *reply, int rc)
 {
 	if (rc < 0) {
-		PERR("reply has error %d", rc);
+		gspca_err(gspca_dev, "reply has error %d\n", rc);
 		return -EIO;
 	}
 	if (rc != 1) {
-		PERR("Bad reply size %d", rc);
+		gspca_err(gspca_dev, "Bad reply size %d\n", rc);
 		return -EIO;
 	}
 	if (reply[0] != 0x08) {
-		PERR("Bad reply 0x%02x", (int)reply[0]);
+		gspca_err(gspca_dev, "Bad reply 0x%02x\n", (int)reply[0]);
 		return -EIO;
 	}
 	return 0;
@@ -214,21 +214,21 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
 	char *buff = gspca_dev->usb_buf;
 	int rc;
 
-	PDEBUG(D_USBO,
-		"reg_w bReq=0x0B, bReqT=0xC0, wVal=0x%04X, wInd=0x%04X\n",
-		value, index);
+	gspca_dbg(gspca_dev, D_USBO,
+		  "reg_w bReq=0x0B, bReqT=0xC0, wVal=0x%04X, wInd=0x%04X\n\n",
+		  value, index);
 	rc = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0),
 		0x0B, 0xC0, value, index, buff, 1, 500);
-	PDEBUG(D_USBO, "rc=%d, ret={0x%02x}", rc, (int)buff[0]);
+	gspca_dbg(gspca_dev, D_USBO, "rc=%d, ret={0x%02x}\n", rc, (int)buff[0]);
 	if (rc < 0) {
-		PERR("Failed reg_w(0x0B, 0xC0, 0x%04X, 0x%04X) w/ rc %d\n",
-			value, index, rc);
+		gspca_err(gspca_dev, "Failed reg_w(0x0B, 0xC0, 0x%04X, 0x%04X) w/ rc %d\n",
+			  value, index, rc);
 		gspca_dev->usb_err = rc;
 		return;
 	}
 	if (val_reply(gspca_dev, buff, rc)) {
-		PERR("Bad reply to reg_w(0x0B, 0xC0, 0x%04X, 0x%04X\n",
-			value, index);
+		gspca_err(gspca_dev, "Bad reply to reg_w(0x0B, 0xC0, 0x%04X, 0x%04X\n",
+			  value, index);
 		gspca_dev->usb_err = -EIO;
 	}
 }
@@ -254,11 +254,11 @@ static void setexposure(struct gspca_dev *gspca_dev, s32 val)
 	else if (w == 3264)
 		value = val * 3 / 2;
 	else {
-		PERR("Invalid width %u\n", w);
+		gspca_err(gspca_dev, "Invalid width %u\n", w);
 		gspca_dev->usb_err = -EINVAL;
 		return;
 	}
-	PDEBUG(D_STREAM, "exposure: 0x%04X ms\n", value);
+	gspca_dbg(gspca_dev, D_STREAM, "exposure: 0x%04X ms\n\n", value);
 	/* Wonder if theres a good reason for sending it twice */
 	/* probably not but leave it in because...why not */
 	reg_w(gspca_dev, value, REG_COARSE_INTEGRATION_TIME_);
@@ -286,9 +286,9 @@ static void setggain(struct gspca_dev *gspca_dev, u16 global_gain)
 	u16 normalized;
 
 	normalized = gainify(global_gain);
-	PDEBUG(D_STREAM, "gain G1/G2 (0x%04X): 0x%04X (src 0x%04X)\n",
-		 REG_GREEN1_GAIN,
-		 normalized, global_gain);
+	gspca_dbg(gspca_dev, D_STREAM, "gain G1/G2 (0x%04X): 0x%04X (src 0x%04X)\n\n",
+		  REG_GREEN1_GAIN,
+		  normalized, global_gain);
 
 	reg_w(gspca_dev, normalized, REG_GREEN1_GAIN);
 	reg_w(gspca_dev, normalized, REG_GREEN2_GAIN);
@@ -302,13 +302,13 @@ static void setbgain(struct gspca_dev *gspca_dev,
 	normalized = global_gain +
 		((u32)global_gain) * gain / GAIN_MAX;
 	if (normalized > GAIN_MAX) {
-		PDEBUG(D_STREAM, "Truncating blue 0x%04X w/ value 0x%04X\n",
-			 GAIN_MAX, normalized);
+		gspca_dbg(gspca_dev, D_STREAM, "Truncating blue 0x%04X w/ value 0x%04X\n\n",
+			  GAIN_MAX, normalized);
 		normalized = GAIN_MAX;
 	}
 	normalized = gainify(normalized);
-	PDEBUG(D_STREAM, "gain B (0x%04X): 0x%04X w/ source 0x%04X\n",
-		 REG_BLUE_GAIN, normalized, gain);
+	gspca_dbg(gspca_dev, D_STREAM, "gain B (0x%04X): 0x%04X w/ source 0x%04X\n\n",
+		  REG_BLUE_GAIN, normalized, gain);
 
 	reg_w(gspca_dev, normalized, REG_BLUE_GAIN);
 }
@@ -321,13 +321,13 @@ static void setrgain(struct gspca_dev *gspca_dev,
 	normalized = global_gain +
 		((u32)global_gain) * gain / GAIN_MAX;
 	if (normalized > GAIN_MAX) {
-		PDEBUG(D_STREAM, "Truncating gain 0x%04X w/ value 0x%04X\n",
-			 GAIN_MAX, normalized);
+		gspca_dbg(gspca_dev, D_STREAM, "Truncating gain 0x%04X w/ value 0x%04X\n\n",
+			  GAIN_MAX, normalized);
 		normalized = GAIN_MAX;
 	}
 	normalized = gainify(normalized);
-	PDEBUG(D_STREAM, "gain R (0x%04X): 0x%04X w / source 0x%04X\n",
-		 REG_RED_GAIN, normalized, gain);
+	gspca_dbg(gspca_dev, D_STREAM, "gain R (0x%04X): 0x%04X w / source 0x%04X\n\n",
+		  REG_RED_GAIN, normalized, gain);
 
 	reg_w(gspca_dev, normalized, REG_RED_GAIN);
 }
@@ -336,7 +336,7 @@ static void configure_wh(struct gspca_dev *gspca_dev)
 {
 	unsigned int w = gspca_dev->pixfmt.width;
 
-	PDEBUG(D_STREAM, "configure_wh\n");
+	gspca_dbg(gspca_dev, D_STREAM, "configure_wh\n\n");
 
 	if (w == 800) {
 		static const struct cmd reg_init_res[] = {
@@ -372,7 +372,7 @@ static void configure_wh(struct gspca_dev *gspca_dev)
 		reg_w_buf(gspca_dev,
 			       reg_init_res, ARRAY_SIZE(reg_init_res));
 	} else {
-		PERR("bad width %u\n", w);
+		gspca_err(gspca_dev, "bad width %u\n", w);
 		gspca_dev->usb_err = -EINVAL;
 		return;
 	}
@@ -392,7 +392,7 @@ static void configure_wh(struct gspca_dev *gspca_dev)
 		reg_w(gspca_dev, 0x0B4B, REG_FRAME_LENGTH_LINES_);
 		reg_w(gspca_dev, 0x1F40, REG_LINE_LENGTH_PCK_);
 	} else {
-		PERR("bad width %u\n", w);
+		gspca_err(gspca_dev, "bad width %u\n", w);
 		gspca_dev->usb_err = -EINVAL;
 		return;
 	}
@@ -425,14 +425,15 @@ static void configure_encrypted(struct gspca_dev *gspca_dev)
 		{0x0100, REG_MODE_SELECT},
 	};
 
-	PDEBUG(D_STREAM, "Encrypted begin, w = %u\n", gspca_dev->pixfmt.width);
+	gspca_dbg(gspca_dev, D_STREAM, "Encrypted begin, w = %u\n\n",
+		  gspca_dev->pixfmt.width);
 	reg_w_buf(gspca_dev, reg_init_begin, ARRAY_SIZE(reg_init_begin));
 	configure_wh(gspca_dev);
 	reg_w_buf(gspca_dev, reg_init_end, ARRAY_SIZE(reg_init_end));
 	reg_w(gspca_dev, 0x0100, REG_GROUPED_PARAMETER_HOLD);
 	reg_w(gspca_dev, 0x0000, REG_GROUPED_PARAMETER_HOLD);
 
-	PDEBUG(D_STREAM, "Encrypted end\n");
+	gspca_dbg(gspca_dev, D_STREAM, "Encrypted end\n\n");
 }
 
 static int configure(struct gspca_dev *gspca_dev)
@@ -440,7 +441,7 @@ static int configure(struct gspca_dev *gspca_dev)
 	int rc;
 	char *buff = gspca_dev->usb_buf;
 
-	PDEBUG(D_STREAM, "configure()\n");
+	gspca_dbg(gspca_dev, D_STREAM, "configure()\n\n");
 
 	/*
 	 * First driver sets a sort of encryption key
@@ -458,7 +459,7 @@ static int configure(struct gspca_dev *gspca_dev)
 	rc = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0),
 			     0x16, 0xC0, 0x0000, 0x0000, buff, 2, 500);
 	if (val_reply(gspca_dev, buff, rc)) {
-		PERR("failed key req");
+		gspca_err(gspca_dev, "failed key req\n");
 		return -EIO;
 	}
 
@@ -475,21 +476,24 @@ static int configure(struct gspca_dev *gspca_dev)
 	rc = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
 			     0x01, 0x40, 0x0001, 0x000F, NULL, 0, 500);
 	if (rc < 0) {
-		PERR("failed to replay packet 176 w/ rc %d\n", rc);
+		gspca_err(gspca_dev, "failed to replay packet 176 w/ rc %d\n",
+			  rc);
 		return rc;
 	}
 
 	rc = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
 			     0x01, 0x40, 0x0000, 0x000F, NULL, 0, 500);
 	if (rc < 0) {
-		PERR("failed to replay packet 178 w/ rc %d\n", rc);
+		gspca_err(gspca_dev, "failed to replay packet 178 w/ rc %d\n",
+			  rc);
 		return rc;
 	}
 
 	rc = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
 			     0x01, 0x40, 0x0001, 0x000F, NULL, 0, 500);
 	if (rc < 0) {
-		PERR("failed to replay packet 180 w/ rc %d\n", rc);
+		gspca_err(gspca_dev, "failed to replay packet 180 w/ rc %d\n",
+			  rc);
 		return rc;
 	}
 
@@ -511,11 +515,12 @@ static int configure(struct gspca_dev *gspca_dev)
 	rc = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
 			     0x01, 0x40, 0x0003, 0x000F, NULL, 0, 500);
 	if (rc < 0) {
-		PERR("failed to replay final packet w/ rc %d\n", rc);
+		gspca_err(gspca_dev, "failed to replay final packet w/ rc %d\n",
+			  rc);
 		return rc;
 	}
 
-	PDEBUG(D_STREAM, "Configure complete\n");
+	gspca_dbg(gspca_dev, D_STREAM, "Configure complete\n\n");
 	return 0;
 }
 
@@ -545,7 +550,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 
 	rc = configure(gspca_dev);
 	if (rc < 0) {
-		PERR("Failed configure");
+		gspca_err(gspca_dev, "Failed configure\n");
 		return rc;
 	}
 	/* First two frames have messed up gains
@@ -563,13 +568,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 		/* can we finish a frame? */
 		if (sd->this_f + len == gspca_dev->pixfmt.sizeimage) {
 			gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
-			PDEBUG(D_FRAM, "finish frame sz %u/%u w/ len %u\n",
-				 sd->this_f, gspca_dev->pixfmt.sizeimage, len);
+			gspca_dbg(gspca_dev, D_FRAM, "finish frame sz %u/%u w/ len %u\n\n",
+				  sd->this_f, gspca_dev->pixfmt.sizeimage, len);
 		/* lost some data, discard the frame */
 		} else {
 			gspca_frame_add(gspca_dev, DISCARD_PACKET, NULL, 0);
-			PDEBUG(D_FRAM, "abort frame sz %u/%u w/ len %u\n",
-				 sd->this_f, gspca_dev->pixfmt.sizeimage, len);
+			gspca_dbg(gspca_dev, D_FRAM, "abort frame sz %u/%u w/ len %u\n\n",
+				  sd->this_f, gspca_dev->pixfmt.sizeimage, len);
 		}
 		sd->this_f = 0;
 	} else {
@@ -641,7 +646,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
 			V4L2_CID_RED_BALANCE, 0, 1023, 1, 295);
 
 	if (hdl->error) {
-		PERR("Could not initialize controls\n");
+		gspca_err(gspca_dev, "Could not initialize controls\n");
 		return hdl->error;
 	}
 	return 0;
diff --git a/drivers/media/usb/gspca/vc032x.c b/drivers/media/usb/gspca/vc032x.c
index b935feb..6b11597 100644
--- a/drivers/media/usb/gspca/vc032x.c
+++ b/drivers/media/usb/gspca/vc032x.c
@@ -2926,11 +2926,12 @@ static void reg_r(struct gspca_dev *gspca_dev,
 	if (gspca_dev->usb_err < 0)
 		return;
 	if (len == 1)
-		PDEBUG(D_USBI, "GET %02x 0001 %04x %02x", req, index,
-				gspca_dev->usb_buf[0]);
+		gspca_dbg(gspca_dev, D_USBI, "GET %02x 0001 %04x %02x\n",
+			  req, index,
+			  gspca_dev->usb_buf[0]);
 	else
-		PDEBUG(D_USBI, "GET %02x 0001 %04x %*ph",
-				req, index, 3, gspca_dev->usb_buf);
+		gspca_dbg(gspca_dev, D_USBI, "GET %02x 0001 %04x %*ph\n",
+			  req, index, 3, gspca_dev->usb_buf);
 }
 
 static void reg_w_i(struct gspca_dev *gspca_dev,
@@ -2960,7 +2961,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
 {
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index);
+	gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n", req, value, index);
 	reg_w_i(gspca_dev, req, value, index);
 }
 
@@ -2992,8 +2993,8 @@ static u16 read_sensor_register(struct gspca_dev *gspca_dev,
 	reg_r(gspca_dev, 0xa1, 0xb33c, 1);
 	hdata = gspca_dev->usb_buf[0];
 	if (hdata != 0 && mdata != 0 && ldata != 0)
-		PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
-			hdata, mdata, ldata);
+		gspca_dbg(gspca_dev, D_PROBE, "Read Sensor %02x%02x %02x\n",
+			  hdata, mdata, ldata);
 	reg_r(gspca_dev, 0xa1, 0xb334, 1);
 	if (gspca_dev->usb_buf[0] == 0x02)
 		return (hdata << 8) + mdata;
@@ -3015,8 +3016,8 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
 	}
 
 	reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
-	PDEBUG(D_PROBE, "vc032%d check sensor header %02x",
-		sd->bridge == BRIDGE_VC0321 ? 1 : 3, gspca_dev->usb_buf[0]);
+	gspca_dbg(gspca_dev, D_PROBE, "vc032%d check sensor header %02x\n",
+		  sd->bridge == BRIDGE_VC0321 ? 1 : 3, gspca_dev->usb_buf[0]);
 	if (sd->bridge == BRIDGE_VC0321) {
 		ptsensor_info = vc0321_probe_data;
 		n = ARRAY_SIZE(vc0321_probe_data);
@@ -3036,7 +3037,8 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
 		if (value == 0 && ptsensor_info->IdAdd == 0x82)
 			value = read_sensor_register(gspca_dev, 0x83);
 		if (value != 0) {
-			PDEBUG(D_PROBE, "Sensor ID %04x (%d)", value, i);
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor ID %04x (%d)\n",
+				  value, i);
 			if (value == ptsensor_info->VpId)
 				return ptsensor_info->sensorId;
 
@@ -3063,9 +3065,10 @@ static void i2c_write(struct gspca_dev *gspca_dev,
 	if (gspca_dev->usb_err < 0)
 		return;
 	if (size == 1)
-		PDEBUG(D_USBO, "i2c_w %02x %02x", reg, *val);
+		gspca_dbg(gspca_dev, D_USBO, "i2c_w %02x %02x\n", reg, *val);
 	else
-		PDEBUG(D_USBO, "i2c_w %02x %02x%02x", reg, *val, val[1]);
+		gspca_dbg(gspca_dev, D_USBO, "i2c_w %02x %02x%02x\n",
+			  reg, *val, val[1]);
 	reg_r_i(gspca_dev, 0xa1, 0xb33f, 1);
 /*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/
 	reg_w_i(gspca_dev, 0xa0, size, 0xb334);
@@ -3170,35 +3173,35 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		pr_err("Unknown sensor...\n");
 		return -EINVAL;
 	case SENSOR_HV7131R:
-		PDEBUG(D_PROBE, "Find Sensor HV7131R");
+		gspca_dbg(gspca_dev, D_PROBE, "Find Sensor HV7131R\n");
 		break;
 	case SENSOR_MI0360:
-		PDEBUG(D_PROBE, "Find Sensor MI0360");
+		gspca_dbg(gspca_dev, D_PROBE, "Find Sensor MI0360\n");
 		sd->bridge = BRIDGE_VC0323;
 		break;
 	case SENSOR_MI1310_SOC:
-		PDEBUG(D_PROBE, "Find Sensor MI1310_SOC");
+		gspca_dbg(gspca_dev, D_PROBE, "Find Sensor MI1310_SOC\n");
 		break;
 	case SENSOR_MI1320:
-		PDEBUG(D_PROBE, "Find Sensor MI1320");
+		gspca_dbg(gspca_dev, D_PROBE, "Find Sensor MI1320\n");
 		break;
 	case SENSOR_MI1320_SOC:
-		PDEBUG(D_PROBE, "Find Sensor MI1320_SOC");
+		gspca_dbg(gspca_dev, D_PROBE, "Find Sensor MI1320_SOC\n");
 		break;
 	case SENSOR_OV7660:
-		PDEBUG(D_PROBE, "Find Sensor OV7660");
+		gspca_dbg(gspca_dev, D_PROBE, "Find Sensor OV7660\n");
 		break;
 	case SENSOR_OV7670:
-		PDEBUG(D_PROBE, "Find Sensor OV7670");
+		gspca_dbg(gspca_dev, D_PROBE, "Find Sensor OV7670\n");
 		break;
 	case SENSOR_PO1200:
-		PDEBUG(D_PROBE, "Find Sensor PO1200");
+		gspca_dbg(gspca_dev, D_PROBE, "Find Sensor PO1200\n");
 		break;
 	case SENSOR_PO3130NC:
-		PDEBUG(D_PROBE, "Find Sensor PO3130NC");
+		gspca_dbg(gspca_dev, D_PROBE, "Find Sensor PO3130NC\n");
 		break;
 	case SENSOR_POxxxx:
-		PDEBUG(D_PROBE, "Sensor POxxxx");
+		gspca_dbg(gspca_dev, D_PROBE, "Sensor POxxxx\n");
 		break;
 	}
 	sd->sensor = sensor;
@@ -3624,8 +3627,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	if (data[0] == 0xff && data[1] == 0xd8) {
-		PDEBUG(D_PACK,
-			"vc032x header packet found len %d", len);
+		gspca_dbg(gspca_dev, D_PACK,
+			  "vc032x header packet found len %d\n", len);
 		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 		data += sd->image_offset;
 		len -= sd->image_offset;
diff --git a/drivers/media/usb/gspca/w996Xcf.c b/drivers/media/usb/gspca/w996Xcf.c
index 728d232..abfab3d 100644
--- a/drivers/media/usb/gspca/w996Xcf.c
+++ b/drivers/media/usb/gspca/w996Xcf.c
@@ -245,7 +245,7 @@ static void w9968cf_smbus_read_ack(struct sd *sd)
 	sda = w9968cf_read_sb(sd);
 	w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
 	if (sda >= 0 && (sda & 0x08)) {
-		PDEBUG(D_USBI, "Did not receive i2c ACK");
+		gspca_dbg(gspca_dev, D_USBI, "Did not receive i2c ACK\n");
 		sd->gspca_dev.usb_err = -EIO;
 	}
 }
@@ -297,7 +297,7 @@ static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
 
 	w9968cf_write_fsb(sd, data);
 
-	PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+	gspca_dbg(gspca_dev, D_USBO, "i2c 0x%02x -> [0x%02x]\n", value, reg);
 }
 
 /* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
@@ -331,9 +331,10 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg)
 
 	if (sd->gspca_dev.usb_err >= 0) {
 		ret = value;
-		PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+		gspca_dbg(gspca_dev, D_USBI, "i2c [0x%02X] -> 0x%02X\n",
+			  reg, value);
 	} else
-		PERR("i2c read [0x%02x] failed", reg);
+		gspca_err(gspca_dev, "i2c read [0x%02x] failed\n", reg);
 
 	return ret;
 }
diff --git a/drivers/media/usb/gspca/xirlink_cit.c b/drivers/media/usb/gspca/xirlink_cit.c
index 68656e7..58deb0c 100644
--- a/drivers/media/usb/gspca/xirlink_cit.c
+++ b/drivers/media/usb/gspca/xirlink_cit.c
@@ -704,7 +704,8 @@ static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
 	}
 
 	if (verbose)
-		PDEBUG(D_PROBE, "Register %04x value: %02x", index, buf[0]);
+		gspca_dbg(gspca_dev, D_PROBE, "Register %04x value: %02x\n",
+			  index, buf[0]);
 
 	return 0;
 }
@@ -1471,10 +1472,11 @@ static int cit_get_clock_div(struct gspca_dev *gspca_dev)
 			fps[clock_div - 1] * 3 / 2)
 		clock_div--;
 
-	PDEBUG(D_PROBE,
-	       "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)",
-	       packet_size, gspca_dev->pixfmt.width, gspca_dev->pixfmt.height,
-	       clock_div, fps[clock_div]);
+	gspca_dbg(gspca_dev, D_PROBE,
+		  "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)\n",
+		  packet_size,
+		  gspca_dev->pixfmt.width, gspca_dev->pixfmt.height,
+		  clock_div, fps[clock_div]);
 
 	return clock_div;
 }
@@ -2865,17 +2867,17 @@ static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
 				sd->sof_read = 0;
 				if (data[i] == 0xff) {
 					if (i >= 4)
-						PDEBUG(D_FRAM,
-						       "header found at offset: %d: %02x %02x 00 %3ph\n",
-						       i - 1,
-						       data[i - 4],
-						       data[i - 3],
-						       &data[i]);
+						gspca_dbg(gspca_dev, D_FRAM,
+							  "header found at offset: %d: %02x %02x 00 %3ph\n\n",
+							  i - 1,
+							  data[i - 4],
+							  data[i - 3],
+							  &data[i]);
 					else
-						PDEBUG(D_FRAM,
-						       "header found at offset: %d: 00 %3ph\n",
-						       i - 1,
-						       &data[i]);
+						gspca_dbg(gspca_dev, D_FRAM,
+							  "header found at offset: %d: 00 %3ph\n\n",
+							  i - 1,
+							  &data[i]);
 					return data + i + (sd->sof_len - 1);
 				}
 				break;
diff --git a/drivers/media/usb/gspca/zc3xx.c b/drivers/media/usb/gspca/zc3xx.c
index e2d486b..25b4dbe 100644
--- a/drivers/media/usb/gspca/zc3xx.c
+++ b/drivers/media/usb/gspca/zc3xx.c
@@ -6041,7 +6041,7 @@ static int sif_probe(struct gspca_dev *gspca_dev)
 	msleep(150);
 	checkword = ((i2c_read(gspca_dev, 0x00) & 0x0f) << 4)
 			| ((i2c_read(gspca_dev, 0x01) & 0xf0) >> 4);
-	PDEBUG(D_PROBE, "probe sif 0x%04x", checkword);
+	gspca_dbg(gspca_dev, D_PROBE, "probe sif 0x%04x\n", checkword);
 	if (checkword == 0x0007) {
 		send_unknown(gspca_dev, SENSOR_PAS106);
 		return 0x0f;			/* PAS106 */
@@ -6129,7 +6129,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
 	i2c_write(gspca_dev, 0x12, 0x80, 0x00);	/* sensor reset */
 	retword = i2c_read(gspca_dev, 0x0a) << 8;
 	retword |= i2c_read(gspca_dev, 0x0b);
-	PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword);
+	gspca_dbg(gspca_dev, D_PROBE, "probe 2wr ov vga 0x%04x\n", retword);
 	switch (retword) {
 	case 0x7631:				/* OV7630C */
 		reg_w(gspca_dev, 0x06, 0x0010);
@@ -6186,7 +6186,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
 	reg_w(gspca_dev, 0x02, 0x0010);
 	retword = reg_r(gspca_dev, 0x000b) << 8;
 	retword |= reg_r(gspca_dev, 0x000a);
-	PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
+	gspca_dbg(gspca_dev, D_PROBE, "probe 3wr vga 1 0x%04x\n", retword);
 	reg_r(gspca_dev, 0x0010);
 	if ((retword & 0xff00) == 0x6400)
 		return 0x02;		/* TAS5130C */
@@ -6206,7 +6206,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
 	reg_w(gspca_dev, 0x01, 0x0012);
 	retword = i2c_read(gspca_dev, 0x00);
 	if (retword != 0) {
-		PDEBUG(D_PROBE, "probe 3wr vga type 0a");
+		gspca_dbg(gspca_dev, D_PROBE, "probe 3wr vga type 0a\n");
 		return 0x0a;			/* PB0330 */
 	}
 
@@ -6220,7 +6220,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
 	reg_w(gspca_dev, 0x01, 0x0012);
 	retword = i2c_read(gspca_dev, 0x00);
 	if (retword != 0) {
-		PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword);
+		gspca_dbg(gspca_dev, D_PROBE, "probe 3wr vga type %02x\n",
+			  retword);
 		if (retword == 0x0011)			/* gc0303 */
 			return 0x0303;
 		if (retword == 0x0029)			/* gc0305 */
@@ -6251,12 +6252,13 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
 	reg_w(gspca_dev, 0x05, 0x0012);
 	retword = i2c_read(gspca_dev, 0x00) << 8;	/* ID 0 */
 	retword |= i2c_read(gspca_dev, 0x01);		/* ID 1 */
-	PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
+	gspca_dbg(gspca_dev, D_PROBE, "probe 3wr vga 2 0x%04x\n", retword);
 	if (retword == 0x2030) {
 		u8 retbyte;
 
 		retbyte = i2c_read(gspca_dev, 0x02);	/* revision number */
-		PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
+		gspca_dbg(gspca_dev, D_PROBE, "sensor PO2030 rev 0x%02x\n",
+			  retbyte);
 
 		send_unknown(gspca_dev, SENSOR_PO2030);
 		return retword;
@@ -6272,7 +6274,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
 	reg_w(gspca_dev, 0xd3, 0x008b);
 	retword = i2c_read(gspca_dev, 0x01);
 	if (retword != 0) {
-		PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
+		gspca_dbg(gspca_dev, D_PROBE, "probe 3wr vga type 0a ? ret: %04x\n",
+			  retword);
 		return 0x16;			/* adcm2700 (6100/6200) */
 	}
 	return -1;
@@ -6490,19 +6493,20 @@ static int sd_init(struct gspca_dev *gspca_dev)
 
 	sensor = zcxx_probeSensor(gspca_dev);
 	if (sensor >= 0)
-		PDEBUG(D_PROBE, "probe sensor -> %04x", sensor);
+		gspca_dbg(gspca_dev, D_PROBE, "probe sensor -> %04x\n", sensor);
 	if ((unsigned) force_sensor < SENSOR_MAX) {
 		sd->sensor = force_sensor;
-		PDEBUG(D_PROBE, "sensor forced to %d", force_sensor);
+		gspca_dbg(gspca_dev, D_PROBE, "sensor forced to %d\n",
+			  force_sensor);
 	} else {
 		switch (sensor) {
 		case -1:
 			switch (sd->sensor) {
 			case SENSOR_MC501CB:
-				PDEBUG(D_PROBE, "Sensor MC501CB");
+				gspca_dbg(gspca_dev, D_PROBE, "Sensor MC501CB\n");
 				break;
 			case SENSOR_GC0303:
-				PDEBUG(D_PROBE, "Sensor GC0303");
+				gspca_dbg(gspca_dev, D_PROBE, "Sensor GC0303\n");
 				break;
 			default:
 				pr_warn("Unknown sensor - set to TAS5130C\n");
@@ -6512,100 +6516,101 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		case 0:
 			/* check the sensor type */
 			sensor = i2c_read(gspca_dev, 0x00);
-			PDEBUG(D_PROBE, "Sensor hv7131 type %d", sensor);
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor hv7131 type %d\n",
+				  sensor);
 			switch (sensor) {
 			case 0:			/* hv7131b */
 			case 1:			/* hv7131e */
-				PDEBUG(D_PROBE, "Find Sensor HV7131B");
+				gspca_dbg(gspca_dev, D_PROBE, "Find Sensor HV7131B\n");
 				sd->sensor = SENSOR_HV7131B;
 				break;
 			default:
 /*			case 2:			 * hv7131r */
-				PDEBUG(D_PROBE, "Find Sensor HV7131R");
+				gspca_dbg(gspca_dev, D_PROBE, "Find Sensor HV7131R\n");
 				sd->sensor = SENSOR_HV7131R;
 				break;
 			}
 			break;
 		case 0x02:
-			PDEBUG(D_PROBE, "Sensor TAS5130C");
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor TAS5130C\n");
 			sd->sensor = SENSOR_TAS5130C;
 			break;
 		case 0x04:
-			PDEBUG(D_PROBE, "Find Sensor CS2102");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor CS2102\n");
 			sd->sensor = SENSOR_CS2102;
 			break;
 		case 0x08:
-			PDEBUG(D_PROBE, "Find Sensor HDCS2020");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor HDCS2020\n");
 			sd->sensor = SENSOR_HDCS2020;
 			break;
 		case 0x0a:
-			PDEBUG(D_PROBE,
-				"Find Sensor PB0330. Chip revision %x",
-				sd->chip_revision);
+			gspca_dbg(gspca_dev, D_PROBE,
+				  "Find Sensor PB0330. Chip revision %x\n",
+				  sd->chip_revision);
 			sd->sensor = SENSOR_PB0330;
 			break;
 		case 0x0c:
-			PDEBUG(D_PROBE, "Find Sensor ICM105A");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor ICM105A\n");
 			sd->sensor = SENSOR_ICM105A;
 			break;
 		case 0x0e:
-			PDEBUG(D_PROBE, "Find Sensor PAS202B");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor PAS202B\n");
 			sd->sensor = SENSOR_PAS202B;
 			break;
 		case 0x0f:
-			PDEBUG(D_PROBE, "Find Sensor PAS106");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor PAS106\n");
 			sd->sensor = SENSOR_PAS106;
 			break;
 		case 0x10:
 		case 0x12:
-			PDEBUG(D_PROBE, "Find Sensor TAS5130C");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor TAS5130C\n");
 			sd->sensor = SENSOR_TAS5130C;
 			break;
 		case 0x11:
-			PDEBUG(D_PROBE, "Find Sensor HV7131R");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor HV7131R\n");
 			sd->sensor = SENSOR_HV7131R;
 			break;
 		case 0x13:
 		case 0x15:
-			PDEBUG(D_PROBE,
-				"Sensor MT9V111. Chip revision %04x",
-				sd->chip_revision);
+			gspca_dbg(gspca_dev, D_PROBE,
+				  "Sensor MT9V111. Chip revision %04x\n",
+				  sd->chip_revision);
 			sd->sensor = sd->bridge == BRIDGE_ZC301
 					? SENSOR_MT9V111_1
 					: SENSOR_MT9V111_3;
 			break;
 		case 0x14:
-			PDEBUG(D_PROBE,
-				"Find Sensor CS2102K?. Chip revision %x",
-				sd->chip_revision);
+			gspca_dbg(gspca_dev, D_PROBE,
+				  "Find Sensor CS2102K?. Chip revision %x\n",
+				  sd->chip_revision);
 			sd->sensor = SENSOR_CS2102K;
 			break;
 		case 0x16:
-			PDEBUG(D_PROBE, "Find Sensor ADCM2700");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor ADCM2700\n");
 			sd->sensor = SENSOR_ADCM2700;
 			break;
 		case 0x29:
-			PDEBUG(D_PROBE, "Find Sensor GC0305");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor GC0305\n");
 			sd->sensor = SENSOR_GC0305;
 			break;
 		case 0x0303:
-			PDEBUG(D_PROBE, "Sensor GC0303");
+			gspca_dbg(gspca_dev, D_PROBE, "Sensor GC0303\n");
 			sd->sensor =  SENSOR_GC0303;
 			break;
 		case 0x2030:
-			PDEBUG(D_PROBE, "Find Sensor PO2030");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor PO2030\n");
 			sd->sensor = SENSOR_PO2030;
 			break;
 		case 0x7620:
-			PDEBUG(D_PROBE, "Find Sensor OV7620");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor OV7620\n");
 			sd->sensor = SENSOR_OV7620;
 			break;
 		case 0x7631:
-			PDEBUG(D_PROBE, "Find Sensor OV7630C");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor OV7630C\n");
 			sd->sensor = SENSOR_OV7630C;
 			break;
 		case 0x7648:
-			PDEBUG(D_PROBE, "Find Sensor OV7648");
+			gspca_dbg(gspca_dev, D_PROBE, "Find Sensor OV7648\n");
 			sd->sensor = SENSOR_OV7620;	/* same sensor (?) */
 			break;
 		default:
diff --git a/drivers/media/usb/hdpvr/Makefile b/drivers/media/usb/hdpvr/Makefile
index 9b8d146..644dd99 100644
--- a/drivers/media/usb/hdpvr/Makefile
+++ b/drivers/media/usb/hdpvr/Makefile
@@ -1,7 +1,3 @@
 hdpvr-objs	:= hdpvr-control.o hdpvr-core.o hdpvr-video.o hdpvr-i2c.o
 
 obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o
-
-ccflags-y += -Idrivers/media/i2c
-
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c
index dbe29c6..29ac7fc 100644
--- a/drivers/media/usb/hdpvr/hdpvr-core.c
+++ b/drivers/media/usb/hdpvr/hdpvr-core.c
@@ -292,7 +292,7 @@ static int hdpvr_probe(struct usb_interface *interface,
 	/* register v4l2_device early so it can be used for printks */
 	if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
 		dev_err(&interface->dev, "v4l2_device_register failed\n");
-		goto error;
+		goto error_free_dev;
 	}
 
 	mutex_init(&dev->io_mutex);
@@ -301,7 +301,7 @@ static int hdpvr_probe(struct usb_interface *interface,
 	dev->usbc_buf = kmalloc(64, GFP_KERNEL);
 	if (!dev->usbc_buf) {
 		v4l2_err(&dev->v4l2_dev, "Out of memory\n");
-		goto error;
+		goto error_v4l2_unregister;
 	}
 
 	init_waitqueue_head(&dev->wait_buffer);
@@ -339,13 +339,13 @@ static int hdpvr_probe(struct usb_interface *interface,
 	}
 	if (!dev->bulk_in_endpointAddr) {
 		v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n");
-		goto error;
+		goto error_put_usb;
 	}
 
 	/* init the device */
 	if (hdpvr_device_init(dev)) {
 		v4l2_err(&dev->v4l2_dev, "device init failed\n");
-		goto error;
+		goto error_put_usb;
 	}
 
 	mutex_lock(&dev->io_mutex);
@@ -353,7 +353,7 @@ static int hdpvr_probe(struct usb_interface *interface,
 		mutex_unlock(&dev->io_mutex);
 		v4l2_err(&dev->v4l2_dev,
 			 "allocating transfer buffers failed\n");
-		goto error;
+		goto error_put_usb;
 	}
 	mutex_unlock(&dev->io_mutex);
 
@@ -361,19 +361,12 @@ static int hdpvr_probe(struct usb_interface *interface,
 	retval = hdpvr_register_i2c_adapter(dev);
 	if (retval < 0) {
 		v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n");
-		goto error;
+		goto error_free_buffers;
 	}
 
-	client = hdpvr_register_ir_rx_i2c(dev);
+	client = hdpvr_register_ir_i2c(dev);
 	if (!client) {
-		v4l2_err(&dev->v4l2_dev, "i2c IR RX device register failed\n");
-		retval = -ENODEV;
-		goto reg_fail;
-	}
-
-	client = hdpvr_register_ir_tx_i2c(dev);
-	if (!client) {
-		v4l2_err(&dev->v4l2_dev, "i2c IR TX device register failed\n");
+		v4l2_err(&dev->v4l2_dev, "i2c IR device register failed\n");
 		retval = -ENODEV;
 		goto reg_fail;
 	}
@@ -394,13 +387,17 @@ static int hdpvr_probe(struct usb_interface *interface,
 reg_fail:
 #if IS_ENABLED(CONFIG_I2C)
 	i2c_del_adapter(&dev->i2c_adapter);
+error_free_buffers:
 #endif
+	hdpvr_free_buffers(dev);
+error_put_usb:
+	usb_put_dev(dev->udev);
+	kfree(dev->usbc_buf);
+error_v4l2_unregister:
+	v4l2_device_unregister(&dev->v4l2_dev);
+error_free_dev:
+	kfree(dev);
 error:
-	if (dev) {
-		flush_work(&dev->worker);
-		/* this frees allocated memory */
-		hdpvr_delete(dev);
-	}
 	return retval;
 }
 
diff --git a/drivers/media/usb/hdpvr/hdpvr-i2c.c b/drivers/media/usb/hdpvr/hdpvr-i2c.c
index 1db49ed..4720d79 100644
--- a/drivers/media/usb/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/usb/hdpvr/hdpvr-i2c.c
@@ -32,24 +32,11 @@
 #define Z8F0811_IR_RX_I2C_ADDR	0x71
 
 
-struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev)
+struct i2c_client *hdpvr_register_ir_i2c(struct hdpvr_device *dev)
 {
 	struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
-	struct i2c_board_info hdpvr_ir_tx_i2c_board_info = {
-		I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
-	};
-
-	init_data->name = "HD-PVR";
-	hdpvr_ir_tx_i2c_board_info.platform_data = init_data;
-
-	return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_tx_i2c_board_info);
-}
-
-struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev)
-{
-	struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
-	struct i2c_board_info hdpvr_ir_rx_i2c_board_info = {
-		I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
+	struct i2c_board_info info = {
+		I2C_BOARD_INFO("ir_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
 	};
 
 	/* Our default information for ir-kbd-i2c.c to use */
@@ -59,9 +46,9 @@ struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev)
 			  RC_PROTO_BIT_RC6_6A_32;
 	init_data->name = "HD-PVR";
 	init_data->polling_interval = 405; /* ms, duplicated from Windows */
-	hdpvr_ir_rx_i2c_board_info.platform_data = init_data;
+	info.platform_data = init_data;
 
-	return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info);
+	return i2c_new_device(&dev->i2c_adapter, &info);
 }
 
 static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
index d0d638c..660d4a6 100644
--- a/drivers/media/usb/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -941,18 +941,18 @@ static int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl)
 		return 0;
 	case V4L2_CID_MPEG_VIDEO_ENCODING:
 		return 0;
-/* 	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
-/* 		if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
-/* 			opt->gop_mode |= 0x2; */
-/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
-/* 					  opt->gop_mode); */
-/* 		} */
-/* 		if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
-/* 			opt->gop_mode &= ~0x2; */
-/* 			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
-/* 					  opt->gop_mode); */
-/* 		} */
-/* 		break; */
+/*	case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/*		if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
+/*			opt->gop_mode |= 0x2; */
+/*			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
+/*					  opt->gop_mode); */
+/*		} */
+/*		if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
+/*			opt->gop_mode &= ~0x2; */
+/*			hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
+/*					  opt->gop_mode); */
+/*		} */
+/*		break; */
 	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: {
 		uint peak_bitrate = dev->video_bitrate_peak->val / 100000;
 		uint bitrate = dev->video_bitrate->val / 100000;
@@ -1154,7 +1154,7 @@ static void hdpvr_device_release(struct video_device *vdev)
 static const struct video_device hdpvr_video_template = {
 	.fops			= &hdpvr_fops,
 	.release		= hdpvr_device_release,
-	.ioctl_ops 		= &hdpvr_ioctl_ops,
+	.ioctl_ops		= &hdpvr_ioctl_ops,
 	.tvnorms		= V4L2_STD_ALL,
 };
 
diff --git a/drivers/media/usb/hdpvr/hdpvr.h b/drivers/media/usb/hdpvr/hdpvr.h
index a12e0af..1d65b41 100644
--- a/drivers/media/usb/hdpvr/hdpvr.h
+++ b/drivers/media/usb/hdpvr/hdpvr.h
@@ -232,15 +232,15 @@ enum {
 
 
 /* :0 s 38 d3 0000 0000 0001 1 = 00 */
-/* 		ret = usb_control_msg(dev->udev, */
-/* 				      usb_sndctrlpipe(dev->udev, 0), */
-/* 				      0xd3, 0x38, */
-/* 				      0, 0, */
-/* 				      "\0", 1, */
-/* 				      1000); */
+/*		ret = usb_control_msg(dev->udev, */
+/*				      usb_sndctrlpipe(dev->udev, 0), */
+/*				      0xd3, 0x38, */
+/*				      0, 0, */
+/*				      "\0", 1, */
+/*				      1000); */
 
-/* 		info("control request returned %d", ret); */
-/* 		msleep(5000); */
+/*		info("control request returned %d", ret); */
+/*		msleep(5000); */
 
 
 	/* :0 s b8 81 1400 0003 0005 5 <
@@ -320,8 +320,7 @@ int hdpvr_cancel_queue(struct hdpvr_device *dev);
 /* i2c adapter registration */
 int hdpvr_register_i2c_adapter(struct hdpvr_device *dev);
 
-struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev);
-struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev);
+struct i2c_client *hdpvr_register_ir_i2c(struct hdpvr_device *dev);
 
 /*========================================================================*/
 /* buffer management */
diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c
index 50146f2..3506358 100644
--- a/drivers/media/usb/pulse8-cec/pulse8-cec.c
+++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c
@@ -329,7 +329,7 @@ static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio,
 	u8 cmd[2];
 	int err;
 	struct tm tm;
-	time_t date;
+	time64_t date;
 
 	pulse8->vers = 0;
 
@@ -349,7 +349,7 @@ static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio,
 	if (err)
 		return err;
 	date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
-	time_to_tm(date, 0, &tm);
+	time64_to_tm(date, 0, &tm);
 	dev_info(pulse8->dev, "Firmware build date %04ld.%02d.%02d %02d:%02d:%02d\n",
 		 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
 		 tm.tm_hour, tm.tm_min, tm.tm_sec);
diff --git a/drivers/media/usb/pvrusb2/Makefile b/drivers/media/usb/pvrusb2/Makefile
index 0d84064..9facf68 100644
--- a/drivers/media/usb/pvrusb2/Makefile
+++ b/drivers/media/usb/pvrusb2/Makefile
@@ -17,7 +17,5 @@
 
 obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o
 
-ccflags-y += -Idrivers/media/i2c
 ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index 51b3312..7153709 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -319,12 +319,12 @@ static struct tda829x_config tda829x_no_probe = {
 };
 
 static struct tda18271_std_map hauppauge_tda18271_dvbt_std_map = {
-        .dvbt_6   = { .if_freq = 3300, .agc_mode = 3, .std = 4,
-                      .if_lvl = 1, .rfagc_top = 0x37, },
-        .dvbt_7   = { .if_freq = 3800, .agc_mode = 3, .std = 5,
-                      .if_lvl = 1, .rfagc_top = 0x37, },
-        .dvbt_8   = { .if_freq = 4300, .agc_mode = 3, .std = 6,
-                      .if_lvl = 1, .rfagc_top = 0x37, },
+	.dvbt_6   = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+	.dvbt_7   = { .if_freq = 3800, .agc_mode = 3, .std = 5,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
+	.dvbt_8   = { .if_freq = 4300, .agc_mode = 3, .std = 6,
+		      .if_lvl = 1, .rfagc_top = 0x37, },
 };
 
 static struct tda18271_config hauppauge_tda18271_dvb_config = {
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index 56c7505..4b32b21 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -18,7 +18,7 @@
 #include <linux/freezer.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
-#include "dvbdev.h"
+#include <media/dvbdev.h>
 #include "pvrusb2-debug.h"
 #include "pvrusb2-hdw-internal.h"
 #include "pvrusb2-hdw.h"
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index b500c86d4..e7f71fb 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -2,10 +2,10 @@
 #ifndef __PVRUSB2_DVB_H__
 #define __PVRUSB2_DVB_H__
 
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dmxdev.h>
 #include "pvrusb2-context.h"
 
 #define PVR2_DVB_BUFFER_COUNT 32
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index 8289ee4..e035316 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -2351,7 +2351,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
 
 	if (hdw_desc == NULL) {
 		pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_create: No device description pointer, unable to continue.");
-		pvr2_trace(PVR2_TRACE_INIT, "If you have a new device type, please contact Mike Isely <isely@pobox.com> to get it included in the driver\n");
+		pvr2_trace(PVR2_TRACE_INIT,
+			   "If you have a new device type, please contact Mike Isely <isely@pobox.com> to get it included in the driver");
 		goto fail;
 	}
 
@@ -3648,6 +3649,12 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
 				  hdw);
 		hdw->ctl_write_urb->actual_length = 0;
 		hdw->ctl_write_pend_flag = !0;
+		if (usb_urb_ep_type_check(hdw->ctl_write_urb)) {
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"Invalid write control endpoint");
+			return -EINVAL;
+		}
 		status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
 		if (status < 0) {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
@@ -3672,6 +3679,12 @@ status);
 				  hdw);
 		hdw->ctl_read_urb->actual_length = 0;
 		hdw->ctl_read_pend_flag = !0;
+		if (usb_urb_ep_type_check(hdw->ctl_read_urb)) {
+			pvr2_trace(
+				PVR2_TRACE_ERROR_LEGS,
+				"Invalid read control endpoint");
+			return -EINVAL;
+		}
 		status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
 		if (status < 0) {
 			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
index ff7b4d1..f3003ca 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
@@ -585,17 +585,10 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
 		init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE |
 							RC_PROTO_BIT_RC6_6A_32;
 		init_data->name = hdw->hdw_desc->description;
-		/* IR Receiver */
-		info.addr          = 0x71;
+		/* IR Transceiver */
+		info.addr = 0x71;
 		info.platform_data = init_data;
-		strlcpy(info.type, "ir_rx_z8f0811_haup", I2C_NAME_SIZE);
-		pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
-			   info.type, info.addr);
-		i2c_new_device(&hdw->i2c_adap, &info);
-		/* IR Trasmitter */
-		info.addr          = 0x70;
-		info.platform_data = init_data;
-		strlcpy(info.type, "ir_tx_z8f0811_haup", I2C_NAME_SIZE);
+		strlcpy(info.type, "ir_z8f0811_haup", I2C_NAME_SIZE);
 		pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
 			   info.type, info.addr);
 		i2c_new_device(&hdw->i2c_adap, &info);
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
index 11cdfe3..ad6290e 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -78,18 +78,6 @@ static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
 module_param_array(vbi_nr, int, NULL, 0444);
 MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
 
-static struct v4l2_fmtdesc pvr_fmtdesc [] = {
-	{
-		.index          = 0,
-		.type           = V4L2_BUF_TYPE_VIDEO_CAPTURE,
-		.flags          = V4L2_FMT_FLAG_COMPRESSED,
-		.description    = "MPEG1/2",
-		// This should really be V4L2_PIX_FMT_MPEG, but xawtv
-		// breaks when I do that.
-		.pixelformat    = 0, // V4L2_PIX_FMT_MPEG,
-	}
-};
-
 #define PVR_FORMAT_PIX  0
 #define PVR_FORMAT_VBI  1
 
@@ -99,17 +87,11 @@ static struct v4l2_format pvr_format [] = {
 		.fmt    = {
 			.pix        = {
 				.width          = 720,
-				.height             = 576,
-				// This should really be V4L2_PIX_FMT_MPEG,
-				// but xawtv breaks when I do that.
-				.pixelformat    = 0, // V4L2_PIX_FMT_MPEG,
+				.height         = 576,
+				.pixelformat    = V4L2_PIX_FMT_MPEG,
 				.field          = V4L2_FIELD_INTERLACED,
-				.bytesperline   = 0,  // doesn't make sense
-						      // here
-				//FIXME : Don't know what to put here...
-				.sizeimage          = (32*1024),
-				.colorspace     = 0, // doesn't make sense here
-				.priv           = 0
+				/* FIXME : Don't know what to put here... */
+				.sizeimage      = 32 * 1024,
 			}
 		}
 	},
@@ -153,6 +135,8 @@ static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *
 	case VFL_TYPE_RADIO:
 		cap->device_caps = V4L2_CAP_RADIO;
 		break;
+	default:
+		return -EINVAL;
 	}
 	cap->device_caps |= V4L2_CAP_TUNER | V4L2_CAP_READWRITE;
 	return 0;
@@ -407,11 +391,11 @@ static int pvr2_g_frequency(struct file *file, void *priv, struct v4l2_frequency
 
 static int pvr2_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fd)
 {
-	/* Only one format is supported : mpeg.*/
-	if (fd->index != 0)
+	/* Only one format is supported: MPEG. */
+	if (fd->index)
 		return -EINVAL;
 
-	memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
+	fd->pixelformat = V4L2_PIX_FMT_MPEG;
 	return 0;
 }
 
diff --git a/drivers/media/usb/pwc/pwc.h b/drivers/media/usb/pwc/pwc.h
index 3c73bda..6701001 100644
--- a/drivers/media/usb/pwc/pwc.h
+++ b/drivers/media/usb/pwc/pwc.h
@@ -50,7 +50,7 @@
 
 /* Version block */
 #define PWC_VERSION	"10.0.15"
-#define PWC_NAME 	"pwc"
+#define PWC_NAME	"pwc"
 #define PFX		PWC_NAME ": "
 
 
@@ -120,10 +120,10 @@
 #define MAX_ISO_BUFS		3
 #define ISO_FRAMES_PER_DESC	10
 #define ISO_MAX_FRAME_SIZE	960
-#define ISO_BUFFER_SIZE 	(ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
+#define ISO_BUFFER_SIZE		(ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
 
 /* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
-#define PWC_FRAME_SIZE 		(460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
+#define PWC_FRAME_SIZE		(460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
 
 /* Absolute minimum and maximum number of buffers available for mmap() */
 #define MIN_FRAMES		2
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index 7fee576..8c2a86d 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -350,7 +350,7 @@ static void s2255_fillbuff(struct s2255_vc *vc, struct s2255_buffer *buf,
 			   int jpgsize);
 static int s2255_set_mode(struct s2255_vc *vc, struct s2255_mode *mode);
 static int s2255_board_shutdown(struct s2255_dev *dev);
-static void s2255_fwload_start(struct s2255_dev *dev, int reset);
+static void s2255_fwload_start(struct s2255_dev *dev);
 static void s2255_destroy(struct s2255_dev *dev);
 static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
 			     u16 index, u16 value, void *buf,
@@ -476,7 +476,7 @@ static void planar422p_to_yuv_packed(const unsigned char *in,
 static void s2255_reset_dsppower(struct s2255_dev *dev)
 {
 	s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
-	msleep(20);
+	msleep(50);
 	s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
 	msleep(600);
 	s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
@@ -1450,7 +1450,7 @@ static int s2255_open(struct file *file)
 	case S2255_FW_FAILED:
 		s2255_dev_err(&dev->udev->dev,
 			"firmware load failed. retrying.\n");
-		s2255_fwload_start(dev, 1);
+		s2255_fwload_start(dev);
 		wait_event_timeout(dev->fw_data->wait_fw,
 				   ((atomic_read(&dev->fw_data->fw_state)
 				     == S2255_FW_SUCCESS) ||
@@ -2209,10 +2209,9 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
 	return;
 }
 
-static void s2255_fwload_start(struct s2255_dev *dev, int reset)
+static void s2255_fwload_start(struct s2255_dev *dev)
 {
-	if (reset)
-		s2255_reset_dsppower(dev);
+	s2255_reset_dsppower(dev);
 	dev->fw_data->fw_size = dev->fw_data->fw->size;
 	atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
 	memcpy(dev->fw_data->pfw_data,
@@ -2337,7 +2336,7 @@ static int s2255_probe(struct usb_interface *interface,
 	retval = s2255_board_init(dev);
 	if (retval)
 		goto errorBOARDINIT;
-	s2255_fwload_start(dev, 0);
+	s2255_fwload_start(dev);
 	/* loads v4l specific */
 	retval = s2255_probe_v4l(dev);
 	if (retval)
diff --git a/drivers/media/usb/siano/Makefile b/drivers/media/usb/siano/Makefile
index 758b6a0..7d48864 100644
--- a/drivers/media/usb/siano/Makefile
+++ b/drivers/media/usb/siano/Makefile
@@ -1,6 +1,5 @@
 obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
 
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/common/siano
 ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
 
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
index d07349c..f13e4b0 100644
--- a/drivers/media/usb/siano/smsusb.c
+++ b/drivers/media/usb/siano/smsusb.c
@@ -61,7 +61,7 @@ struct smsusb_device_t {
 	struct usb_device *udev;
 	struct smscore_device_t *coredev;
 
-	struct smsusb_urb_t 	surbs[MAX_URBS];
+	struct smsusb_urb_t	surbs[MAX_URBS];
 
 	int		response_alignment;
 	int		buffer_size;
diff --git a/drivers/media/usb/stk1160/Makefile b/drivers/media/usb/stk1160/Makefile
index 61347152..b943db0 100644
--- a/drivers/media/usb/stk1160/Makefile
+++ b/drivers/media/usb/stk1160/Makefile
@@ -1,10 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
-stk1160-y := 	stk1160-core.o \
+stk1160-y :=	stk1160-core.o \
 		stk1160-v4l.o \
 		stk1160-video.o \
 		stk1160-i2c.o \
 		stk1160-ac97.o
 
 obj-$(CONFIG_VIDEO_STK1160) += stk1160.o
-
-ccflags-y += -Idrivers/media/i2c
diff --git a/drivers/media/usb/stkwebcam/stk-sensor.c b/drivers/media/usb/stkwebcam/stk-sensor.c
index c1d4505f..9a7dbeff 100644
--- a/drivers/media/usb/stkwebcam/stk-sensor.c
+++ b/drivers/media/usb/stkwebcam/stk-sensor.c
@@ -397,12 +397,12 @@ int stk_sensor_init(struct stk_camera *dev)
 /* V4L2_PIX_FMT_UYVY */
 static struct regval ov_fmt_uyvy[] = {
 	{REG_TSLB, TSLB_YLAST|0x08 },
-	{ 0x4f, 0x80 }, 	/* "matrix coefficient 1" */
-	{ 0x50, 0x80 }, 	/* "matrix coefficient 2" */
+	{ 0x4f, 0x80 },		/* "matrix coefficient 1" */
+	{ 0x50, 0x80 },		/* "matrix coefficient 2" */
 	{ 0x51, 0    },		/* vb */
-	{ 0x52, 0x22 }, 	/* "matrix coefficient 4" */
-	{ 0x53, 0x5e }, 	/* "matrix coefficient 5" */
-	{ 0x54, 0x80 }, 	/* "matrix coefficient 6" */
+	{ 0x52, 0x22 },		/* "matrix coefficient 4" */
+	{ 0x53, 0x5e },		/* "matrix coefficient 5" */
+	{ 0x54, 0x80 },		/* "matrix coefficient 6" */
 	{REG_COM13, COM13_UVSAT|COM13_CMATRIX},
 	{REG_COM15, COM15_R00FF },
 	{0xff, 0xff}, /* END MARKER */
@@ -410,12 +410,12 @@ static struct regval ov_fmt_uyvy[] = {
 /* V4L2_PIX_FMT_YUYV */
 static struct regval ov_fmt_yuyv[] = {
 	{REG_TSLB, 0 },
-	{ 0x4f, 0x80 }, 	/* "matrix coefficient 1" */
-	{ 0x50, 0x80 }, 	/* "matrix coefficient 2" */
+	{ 0x4f, 0x80 },		/* "matrix coefficient 1" */
+	{ 0x50, 0x80 },		/* "matrix coefficient 2" */
 	{ 0x51, 0    },		/* vb */
-	{ 0x52, 0x22 }, 	/* "matrix coefficient 4" */
-	{ 0x53, 0x5e }, 	/* "matrix coefficient 5" */
-	{ 0x54, 0x80 }, 	/* "matrix coefficient 6" */
+	{ 0x52, 0x22 },		/* "matrix coefficient 4" */
+	{ 0x53, 0x5e },		/* "matrix coefficient 5" */
+	{ 0x54, 0x80 },		/* "matrix coefficient 6" */
 	{REG_COM13, COM13_UVSAT|COM13_CMATRIX},
 	{REG_COM15, COM15_R00FF },
 	{0xff, 0xff}, /* END MARKER */
@@ -426,13 +426,13 @@ static struct regval ov_fmt_rgbr[] = {
 	{ REG_RGB444, 0 },	/* No RGB444 please */
 	{REG_TSLB, 0x00},
 	{ REG_COM1, 0x0 },
-	{ REG_COM9, 0x38 }, 	/* 16x gain ceiling; 0x8 is reserved bit */
-	{ 0x4f, 0xb3 }, 	/* "matrix coefficient 1" */
-	{ 0x50, 0xb3 }, 	/* "matrix coefficient 2" */
+	{ REG_COM9, 0x38 },	/* 16x gain ceiling; 0x8 is reserved bit */
+	{ 0x4f, 0xb3 },		/* "matrix coefficient 1" */
+	{ 0x50, 0xb3 },		/* "matrix coefficient 2" */
 	{ 0x51, 0    },		/* vb */
-	{ 0x52, 0x3d }, 	/* "matrix coefficient 4" */
-	{ 0x53, 0xa7 }, 	/* "matrix coefficient 5" */
-	{ 0x54, 0xe4 }, 	/* "matrix coefficient 6" */
+	{ 0x52, 0x3d },		/* "matrix coefficient 4" */
+	{ 0x53, 0xa7 },		/* "matrix coefficient 5" */
+	{ 0x54, 0xe4 },		/* "matrix coefficient 6" */
 	{ REG_COM13, COM13_GAMMA },
 	{ REG_COM15, COM15_RGB565|COM15_R00FF },
 	{ 0xff, 0xff },
@@ -443,13 +443,13 @@ static struct regval ov_fmt_rgbp[] = {
 	{ REG_RGB444, 0 },	/* No RGB444 please */
 	{REG_TSLB, TSLB_BYTEORD },
 	{ REG_COM1, 0x0 },
-	{ REG_COM9, 0x38 }, 	/* 16x gain ceiling; 0x8 is reserved bit */
-	{ 0x4f, 0xb3 }, 	/* "matrix coefficient 1" */
-	{ 0x50, 0xb3 }, 	/* "matrix coefficient 2" */
+	{ REG_COM9, 0x38 },	/* 16x gain ceiling; 0x8 is reserved bit */
+	{ 0x4f, 0xb3 },		/* "matrix coefficient 1" */
+	{ 0x50, 0xb3 },		/* "matrix coefficient 2" */
 	{ 0x51, 0    },		/* vb */
-	{ 0x52, 0x3d }, 	/* "matrix coefficient 4" */
-	{ 0x53, 0xa7 }, 	/* "matrix coefficient 5" */
-	{ 0x54, 0xe4 }, 	/* "matrix coefficient 6" */
+	{ 0x52, 0x3d },		/* "matrix coefficient 4" */
+	{ 0x53, 0xa7 },		/* "matrix coefficient 5" */
+	{ 0x54, 0xe4 },		/* "matrix coefficient 6" */
 	{ REG_COM13, COM13_GAMMA },
 	{ REG_COM15, COM15_RGB565|COM15_R00FF },
 	{ 0xff, 0xff },
diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c
index cba0916..17ad978 100644
--- a/drivers/media/usb/stkwebcam/stk-webcam.c
+++ b/drivers/media/usb/stkwebcam/stk-webcam.c
@@ -1241,7 +1241,6 @@ static void stk_v4l_dev_release(struct video_device *vd)
 	if (dev->sio_bufs != NULL || dev->isobufs != NULL)
 		pr_err("We are leaking memory\n");
 	usb_put_intf(dev->interface);
-	kfree(dev);
 }
 
 static const struct video_device stk_v4l_data = {
@@ -1391,6 +1390,7 @@ static void stk_camera_disconnect(struct usb_interface *interface)
 	video_unregister_device(&dev->vdev);
 	v4l2_ctrl_handler_free(&dev->hdl);
 	v4l2_device_unregister(&dev->v4l2_dev);
+	kfree(dev);
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/media/usb/tm6000/Makefile b/drivers/media/usb/tm6000/Makefile
index 05322a7..744c039 100644
--- a/drivers/media/usb/tm6000/Makefile
+++ b/drivers/media/usb/tm6000/Makefile
@@ -10,7 +10,5 @@
 obj-$(CONFIG_VIDEO_TM6000_ALSA) += tm6000-alsa.o
 obj-$(CONFIG_VIDEO_TM6000_DVB) += tm6000-dvb.o
 
-ccflags-y += -Idrivers/media/i2c
 ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
 ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/tm6000/tm6000-alsa.c b/drivers/media/usb/tm6000/tm6000-alsa.c
index 3717a68..f18cffae 100644
--- a/drivers/media/usb/tm6000/tm6000-alsa.c
+++ b/drivers/media/usb/tm6000/tm6000-alsa.c
@@ -1,14 +1,8 @@
-/*
- *
- *  Support for audio capture for tm5600/6000/6010
- *    (c) 2007-2008 Mauro Carvalho Chehab
- *
- *  Based on cx88-alsa.c
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- */
+// SPDX-License-Identifier: GPL-2.0
+// Support for audio capture for tm5600/6000/6010
+// Copyright (c) 2007-2008 Mauro Carvalho Chehab <mchehab@kernel.org>
+//
+// Based on cx88-alsa.c
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -57,7 +51,7 @@ MODULE_PARM_DESC(index, "Index value for tm6000x capture interface(s).");
 
 MODULE_DESCRIPTION("ALSA driver module for tm5600/tm6000/tm6010 based TV cards");
 MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_SUPPORTED_DEVICE("{{Trident,tm5600},{{Trident,tm6000},{{Trident,tm6010}");
 static unsigned int debug;
 module_param(debug, int, 0644);
diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c
index 773475419..4d5f4cc 100644
--- a/drivers/media/usb/tm6000/tm6000-cards.c
+++ b/drivers/media/usb/tm6000/tm6000-cards.c
@@ -1,17 +1,7 @@
-/*
- *  tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- *  Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0
+// tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+//
+// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
 
 #include <linux/init.h>
 #include <linux/module.h>
@@ -23,7 +13,6 @@
 #include <media/v4l2-common.h>
 #include <media/tuner.h>
 #include <media/i2c/tvaudio.h>
-#include <media/i2c-addr.h>
 #include <media/rc-map.h>
 
 #include "tm6000.h"
@@ -1405,4 +1394,4 @@ module_usb_driver(tm6000_usb_driver);
 
 MODULE_DESCRIPTION("Trident TVMaster TM5600/TM6000/TM6010 USB2 adapter");
 MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/usb/tm6000/tm6000-core.c b/drivers/media/usb/tm6000/tm6000-core.c
index 8c265bd..23a1332 100644
--- a/drivers/media/usb/tm6000/tm6000-core.c
+++ b/drivers/media/usb/tm6000/tm6000-core.c
@@ -1,20 +1,10 @@
-/*
- *  tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- *  Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- *  Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- *      - DVB-T support
- *
- *  This program is free software; 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+//
+// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
+//
+// Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com>
+//     - DVB-T support
 
 #include <linux/module.h>
 #include <linux/kernel.h>
diff --git a/drivers/media/usb/tm6000/tm6000-i2c.c b/drivers/media/usb/tm6000/tm6000-i2c.c
index cbcc147..c9a62bb 100644
--- a/drivers/media/usb/tm6000/tm6000-i2c.c
+++ b/drivers/media/usb/tm6000/tm6000-i2c.c
@@ -1,20 +1,10 @@
-/*
- *  tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- *  Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- *  Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- *	- Fix SMBus Read Byte command
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+//
+// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
+//
+// Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com>
+//	- Fix SMBus Read Byte command
 
 #include <linux/module.h>
 #include <linux/kernel.h>
diff --git a/drivers/media/usb/tm6000/tm6000-regs.h b/drivers/media/usb/tm6000/tm6000-regs.h
index ab3fb74..21587fc 100644
--- a/drivers/media/usb/tm6000/tm6000-regs.h
+++ b/drivers/media/usb/tm6000/tm6000-regs.h
@@ -1,16 +1,8 @@
 /*
- *  tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices
+ * SPDX-License-Identifier: GPL-2.0
+ * tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices
  *
- *  Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
  */
 
 /*
diff --git a/drivers/media/usb/tm6000/tm6000-stds.c b/drivers/media/usb/tm6000/tm6000-stds.c
index aa43810..c0c7595 100644
--- a/drivers/media/usb/tm6000/tm6000-stds.c
+++ b/drivers/media/usb/tm6000/tm6000-stds.c
@@ -1,17 +1,7 @@
-/*
- *  tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- *  Copyright (C) 2007 Mauro Carvalho Chehab
- *
- *  This program is free software; 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+//
+// Copyright (c) 2007 Mauro Carvalho Chehab <mchehab@kernel.org>
 
 #include <linux/module.h>
 #include <linux/kernel.h>
diff --git a/drivers/media/usb/tm6000/tm6000-usb-isoc.h b/drivers/media/usb/tm6000/tm6000-usb-isoc.h
index 6a13a27..5c615b0 100644
--- a/drivers/media/usb/tm6000/tm6000-usb-isoc.h
+++ b/drivers/media/usb/tm6000/tm6000-usb-isoc.h
@@ -1,16 +1,8 @@
 /*
- *  tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+ * SPDX-License-Identifier: GPL-2.0
+ * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices
  *
- *  Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation version 2
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
  */
 
 #include <linux/videodev2.h>
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index 317bf5a..96266fa 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -1,20 +1,10 @@
-/*
- *   tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- *  Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- *  Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- *	- Fixed module load/unload
- *
- *  This program is free software; 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+//
+// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
+//
+// Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com>
+//	- Fixed module load/unload
 
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -1323,6 +1313,8 @@ static int __tm6000_open(struct file *file)
 	case VFL_TYPE_RADIO:
 		radio = 1;
 		break;
+	default:
+		return -EINVAL;
 	}
 
 	/* If more than one user, mutex should be added */
diff --git a/drivers/media/usb/tm6000/tm6000.h b/drivers/media/usb/tm6000/tm6000.h
index 7ec478d..e1e4577 100644
--- a/drivers/media/usb/tm6000/tm6000.h
+++ b/drivers/media/usb/tm6000/tm6000.h
@@ -1,19 +1,11 @@
 /*
- *  tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices
+ * SPDX-License-Identifier: GPL-2.0
+ * tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices
  *
- *  Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
+ * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
  *
- *  Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
+ * Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com>
  *	- DVB-T support
- *
- *  This program is free software; 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.
  */
 
 #include <linux/videodev2.h>
@@ -27,9 +19,9 @@
 #include <media/v4l2-fh.h>
 
 #include <linux/dvb/frontend.h>
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dmxdev.h"
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dmxdev.h>
 
 /* Inputs */
 enum tm6000_itype {
@@ -185,7 +177,7 @@ struct tm6000_core {
 	struct tm6000_capabilities	caps;
 
 	/* Used to load alsa/dvb */
-        struct work_struct		request_module_wk;
+	struct work_struct		request_module_wk;
 
 	/* Tuner configuration */
 	int				tuner_type;		/* type of the tuner */
diff --git a/drivers/media/usb/ttusb-budget/Makefile b/drivers/media/usb/ttusb-budget/Makefile
index f47bbf6..fe4372d 100644
--- a/drivers/media/usb/ttusb-budget/Makefile
+++ b/drivers/media/usb/ttusb-budget/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
 
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
index a142b9d..eed5689 100644
--- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
@@ -22,10 +22,10 @@
 #include <linux/mutex.h>
 #include <linux/firmware.h>
 
-#include "dvb_frontend.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
+#include <media/dvb_frontend.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
 #include "ves1820.h"
 #include "cx22700.h"
 #include "tda1004x.h"
@@ -102,7 +102,6 @@ struct ttusb {
 	unsigned int isoc_in_pipe;
 
 	void *iso_buffer;
-	dma_addr_t iso_dma_handle;
 
 	struct urb *iso_urb[ISO_BUF_COUNT];
 
@@ -792,26 +791,17 @@ static void ttusb_free_iso_urbs(struct ttusb *ttusb)
 
 	for (i = 0; i < ISO_BUF_COUNT; i++)
 		usb_free_urb(ttusb->iso_urb[i]);
-
-	pci_free_consistent(NULL,
-			    ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
-			    ISO_BUF_COUNT, ttusb->iso_buffer,
-			    ttusb->iso_dma_handle);
+	kfree(ttusb->iso_buffer);
 }
 
 static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
 {
 	int i;
 
-	ttusb->iso_buffer = pci_zalloc_consistent(NULL,
-						  ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
-						  &ttusb->iso_dma_handle);
-
-	if (!ttusb->iso_buffer) {
-		dprintk("%s: pci_alloc_consistent - not enough memory\n",
-			__func__);
+	ttusb->iso_buffer = kcalloc(FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
+			ISO_FRAME_SIZE, GFP_KERNEL);
+	if (!ttusb->iso_buffer)
 		return -ENOMEM;
-	}
 
 	for (i = 0; i < ISO_BUF_COUNT; i++) {
 		struct urb *urb;
diff --git a/drivers/media/usb/ttusb-dec/Makefile b/drivers/media/usb/ttusb-dec/Makefile
index 5352740..dde9168 100644
--- a/drivers/media/usb/ttusb-dec/Makefile
+++ b/drivers/media/usb/ttusb-dec/Makefile
@@ -1,3 +1 @@
 obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o
-
-ccflags-y += -Idrivers/media/dvb-core/
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c
index cdefb5d..a8900f5 100644
--- a/drivers/media/usb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c
@@ -30,10 +30,10 @@
 
 #include <linux/mutex.h>
 
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
 #include "ttusbdecfe.h"
 
 static int debug;
@@ -127,7 +127,6 @@ struct ttusb_dec {
 	struct urb		*irq_urb;
 	dma_addr_t		irq_dma_handle;
 	void			*iso_buffer;
-	dma_addr_t		iso_dma_handle;
 	struct urb		*iso_urb[ISO_BUF_COUNT];
 	int			iso_stream_count;
 	struct mutex		iso_mutex;
@@ -1185,11 +1184,7 @@ static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
 
 	for (i = 0; i < ISO_BUF_COUNT; i++)
 		usb_free_urb(dec->iso_urb[i]);
-
-	pci_free_consistent(NULL,
-			    ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
-					      ISO_BUF_COUNT),
-			    dec->iso_buffer, dec->iso_dma_handle);
+	kfree(dec->iso_buffer);
 }
 
 static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
@@ -1198,15 +1193,10 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
 
 	dprintk("%s\n", __func__);
 
-	dec->iso_buffer = pci_zalloc_consistent(NULL,
-						ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT),
-						&dec->iso_dma_handle);
-
-	if (!dec->iso_buffer) {
-		dprintk("%s: pci_alloc_consistent - not enough memory\n",
-			__func__);
+	dec->iso_buffer = kcalloc(FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
+			ISO_FRAME_SIZE, GFP_KERNEL);
+	if (!dec->iso_buffer)
 		return -ENOMEM;
-	}
 
 	for (i = 0; i < ISO_BUF_COUNT; i++) {
 		struct urb *urb;
diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.c b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
index 09693ca..6ea05d9 100644
--- a/drivers/media/usb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
@@ -15,7 +15,7 @@
  *
  */
 
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
 #include "ttusbdecfe.h"
 
 
diff --git a/drivers/media/usb/usbtv/Kconfig b/drivers/media/usb/usbtv/Kconfig
index b833c5b..14a0941 100644
--- a/drivers/media/usb/usbtv/Kconfig
+++ b/drivers/media/usb/usbtv/Kconfig
@@ -1,11 +1,11 @@
 config VIDEO_USBTV
-        tristate "USBTV007 video capture support"
-        depends on VIDEO_V4L2 && SND
-        select SND_PCM
-        select VIDEOBUF2_VMALLOC
+	tristate "USBTV007 video capture support"
+	depends on VIDEO_V4L2 && SND
+	select SND_PCM
+	select VIDEOBUF2_VMALLOC
 
-        ---help---
-          This is a video4linux2 driver for USBTV007 based video capture devices.
+	---help---
+	  This is a video4linux2 driver for USBTV007 based video capture devices.
 
-          To compile this driver as a module, choose M here: the
-          module will be called usbtv
+	  To compile this driver as a module, choose M here: the
+	  module will be called usbtv
diff --git a/drivers/media/usb/usbvision/Makefile b/drivers/media/usb/usbvision/Makefile
index 9b3a558..494d030 100644
--- a/drivers/media/usb/usbvision/Makefile
+++ b/drivers/media/usb/usbvision/Makefile
@@ -2,5 +2,4 @@
 
 obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o
 
-ccflags-y += -Idrivers/media/i2c
 ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index 960272d..0f5954a 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -72,7 +72,6 @@
 #define DRIVER_NAME "usbvision"
 #define DRIVER_ALIAS "USBVision"
 #define DRIVER_DESC "USBVision USB Video Device Driver for Linux"
-#define DRIVER_LICENSE "GPL"
 #define USBVISION_VERSION_STRING "0.9.11"
 
 #define	ENABLE_HEXDUMP	0	/* Enable if you need it */
@@ -141,7 +140,7 @@ MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX).  Default: -1
 /* Misc stuff */
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
+MODULE_LICENSE("GPL");
 MODULE_VERSION(USBVISION_VERSION_STRING);
 MODULE_ALIAS(DRIVER_ALIAS);
 
diff --git a/drivers/media/usb/uvc/Makefile b/drivers/media/usb/uvc/Makefile
index a4fe5b5..4f9eee4 100644
--- a/drivers/media/usb/uvc/Makefile
+++ b/drivers/media/usb/uvc/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 uvcvideo-objs  := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \
-		  uvc_status.o uvc_isight.o uvc_debugfs.o
+		  uvc_status.o uvc_isight.o uvc_debugfs.o uvc_metadata.o
 ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
 uvcvideo-objs  += uvc_entity.o
 endif
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 28b91b7..fd387bf 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -24,6 +24,7 @@
 #include <asm/unaligned.h>
 
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
 
 #include "uvcvideo.h"
 
@@ -94,6 +95,11 @@ static struct uvc_format_desc uvc_fmts[] = {
 		.fcc		= V4L2_PIX_FMT_GREY,
 	},
 	{
+		.name		= "Greyscale 8-bit (D3DFMT_L8)",
+		.guid		= UVC_GUID_FORMAT_D3DFMT_L8,
+		.fcc		= V4L2_PIX_FMT_GREY,
+	},
+	{
 		.name		= "Greyscale 10-bit (Y10 )",
 		.guid		= UVC_GUID_FORMAT_Y10,
 		.fcc		= V4L2_PIX_FMT_Y10,
@@ -957,11 +963,11 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
 		 *	Size of this descriptor, in bytes: 24+p+n*2
 		 * ----------------------------------------------------------
 		 * 23+p+n	bmControlsType	N	Bitmap
-		 * 	Individual bits in the set are defined:
-		 * 	0: Absolute
-		 * 	1: Relative
+		 *	Individual bits in the set are defined:
+		 *	0: Absolute
+		 *	1: Relative
 		 *
-		 * 	This bitset is mapped exactly the same as bmControls.
+		 *	This bitset is mapped exactly the same as bmControls.
 		 * ----------------------------------------------------------
 		 * 23+p+n*2	bReserved	1	Boolean
 		 * ----------------------------------------------------------
@@ -1877,6 +1883,7 @@ static void uvc_unregister_video(struct uvc_device *dev)
 			continue;
 
 		video_unregister_device(&stream->vdev);
+		video_unregister_device(&stream->meta.vdev);
 
 		uvc_debugfs_cleanup_stream(stream);
 	}
@@ -1884,63 +1891,95 @@ static void uvc_unregister_video(struct uvc_device *dev)
 	kref_put(&dev->ref, uvc_delete);
 }
 
-static int uvc_register_video(struct uvc_device *dev,
-		struct uvc_streaming *stream)
+int uvc_register_video_device(struct uvc_device *dev,
+			      struct uvc_streaming *stream,
+			      struct video_device *vdev,
+			      struct uvc_video_queue *queue,
+			      enum v4l2_buf_type type,
+			      const struct v4l2_file_operations *fops,
+			      const struct v4l2_ioctl_ops *ioctl_ops)
 {
-	struct video_device *vdev = &stream->vdev;
 	int ret;
 
 	/* Initialize the video buffers queue. */
-	ret = uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param);
+	ret = uvc_queue_init(queue, type, !uvc_no_drop_param);
 	if (ret)
 		return ret;
 
-	/* Initialize the streaming interface with default streaming
-	 * parameters.
-	 */
-	ret = uvc_video_init(stream);
-	if (ret < 0) {
-		uvc_printk(KERN_ERR, "Failed to initialize the device "
-			"(%d).\n", ret);
-		return ret;
-	}
-
-	uvc_debugfs_init_stream(stream);
-
 	/* Register the device with V4L. */
 
-	/* We already hold a reference to dev->udev. The video device will be
+	/*
+	 * We already hold a reference to dev->udev. The video device will be
 	 * unregistered before the reference is released, so we don't need to
 	 * get another one.
 	 */
 	vdev->v4l2_dev = &dev->vdev;
-	vdev->fops = &uvc_fops;
-	vdev->ioctl_ops = &uvc_ioctl_ops;
+	vdev->fops = fops;
+	vdev->ioctl_ops = ioctl_ops;
 	vdev->release = uvc_release;
 	vdev->prio = &stream->chain->prio;
-	if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
 		vdev->vfl_dir = VFL_DIR_TX;
+	else
+		vdev->vfl_dir = VFL_DIR_RX;
+
+	switch (type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+	default:
+		vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+		break;
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+		vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+		break;
+	case V4L2_BUF_TYPE_META_CAPTURE:
+		vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
+		break;
+	}
+
 	strlcpy(vdev->name, dev->name, sizeof vdev->name);
 
-	/* Set the driver data before calling video_register_device, otherwise
-	 * uvc_v4l2_open might race us.
+	/*
+	 * Set the driver data before calling video_register_device, otherwise
+	 * the file open() handler might race us.
 	 */
 	video_set_drvdata(vdev, stream);
 
 	ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
 	if (ret < 0) {
-		uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",
+		uvc_printk(KERN_ERR, "Failed to register %s device (%d).\n",
+			   v4l2_type_names[type], ret);
+		return ret;
+	}
+
+	kref_get(&dev->ref);
+	return 0;
+}
+
+static int uvc_register_video(struct uvc_device *dev,
+		struct uvc_streaming *stream)
+{
+	int ret;
+
+	/* Initialize the streaming interface with default parameters. */
+	ret = uvc_video_init(stream);
+	if (ret < 0) {
+		uvc_printk(KERN_ERR, "Failed to initialize the device (%d).\n",
 			   ret);
 		return ret;
 	}
 
 	if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE;
+		stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE
+			| V4L2_CAP_META_CAPTURE;
 	else
 		stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT;
 
-	kref_get(&dev->ref);
-	return 0;
+	uvc_debugfs_init_stream(stream);
+
+	/* Register the device with V4L. */
+	return uvc_register_video_device(dev, stream, &stream->vdev,
+					 &stream->queue, stream->type,
+					 &uvc_fops, &uvc_ioctl_ops);
 }
 
 /*
@@ -1969,6 +2008,11 @@ static int uvc_register_terms(struct uvc_device *dev,
 		if (ret < 0)
 			return ret;
 
+		/* Register a metadata node, but ignore a possible failure,
+		 * complete registration of video nodes anyway.
+		 */
+		uvc_meta_register(stream);
+
 		term->vdev = &stream->vdev;
 	}
 
@@ -2001,11 +2045,19 @@ static int uvc_register_chains(struct uvc_device *dev)
  * USB probe, disconnect, suspend and resume
  */
 
+struct uvc_device_info {
+	u32	quirks;
+	u32	meta_format;
+};
+
 static int uvc_probe(struct usb_interface *intf,
 		     const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct uvc_device *dev;
+	const struct uvc_device_info *info =
+		(const struct uvc_device_info *)id->driver_info;
+	u32 quirks = info ? info->quirks : 0;
 	int function;
 	int ret;
 
@@ -2032,7 +2084,9 @@ static int uvc_probe(struct usb_interface *intf,
 	dev->intf = usb_get_intf(intf);
 	dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
 	dev->quirks = (uvc_quirks_param == -1)
-		    ? id->driver_info : uvc_quirks_param;
+		    ? quirks : uvc_quirks_param;
+	if (info)
+		dev->meta_format = info->meta_format;
 
 	if (udev->product != NULL)
 		strlcpy(dev->name, udev->product, sizeof dev->name);
@@ -2073,7 +2127,7 @@ static int uvc_probe(struct usb_interface *intf,
 		le16_to_cpu(udev->descriptor.idVendor),
 		le16_to_cpu(udev->descriptor.idProduct));
 
-	if (dev->quirks != id->driver_info) {
+	if (dev->quirks != quirks) {
 		uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module "
 			"parameter for testing purpose.\n", dev->quirks);
 		uvc_printk(KERN_INFO, "Please report required quirks to the "
@@ -2271,6 +2325,28 @@ MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
  * Driver initialization and cleanup
  */
 
+static const struct uvc_device_info uvc_quirk_probe_minmax = {
+	.quirks = UVC_QUIRK_PROBE_MINMAX,
+};
+
+static const struct uvc_device_info uvc_quirk_fix_bandwidth = {
+	.quirks = UVC_QUIRK_FIX_BANDWIDTH,
+};
+
+static const struct uvc_device_info uvc_quirk_probe_def = {
+	.quirks = UVC_QUIRK_PROBE_DEF,
+};
+
+static const struct uvc_device_info uvc_quirk_stream_no_fid = {
+	.quirks = UVC_QUIRK_STREAM_NO_FID,
+};
+
+static const struct uvc_device_info uvc_quirk_force_y8 = {
+	.quirks = UVC_QUIRK_FORCE_Y8,
+};
+
+#define UVC_QUIRK_INFO(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q}
+
 /*
  * The Logitech cameras listed below have their interface class set to
  * VENDOR_SPEC because they don't announce themselves as UVC devices, even
@@ -2285,7 +2361,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* Genius eFace 2025 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2294,7 +2370,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* Microsoft Lifecam NX-6000 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2303,7 +2379,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* Microsoft Lifecam NX-3000 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2312,7 +2388,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_DEF },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_def },
 	/* Microsoft Lifecam VX-7000 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2321,7 +2397,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* Logitech Quickcam Fusion */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2378,7 +2454,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_RESTORE_CTRLS_ON_INIT },
+	  .driver_info		= UVC_QUIRK_INFO(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) },
 	/* Chicony CNF7129 (Asus EEE 100HE) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2387,7 +2463,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_RESTRICT_FRAME_RATE },
+	  .driver_info		= UVC_QUIRK_INFO(UVC_QUIRK_RESTRICT_FRAME_RATE) },
 	/* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2396,7 +2472,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* Dell XPS m1530 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2405,7 +2481,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info 		= UVC_QUIRK_PROBE_DEF },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_def },
 	/* Dell SP2008WFP Monitor */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2414,7 +2490,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info 		= UVC_QUIRK_PROBE_DEF },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_def },
 	/* Dell Alienware X51 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2423,7 +2499,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info	= UVC_QUIRK_PROBE_DEF },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_def },
 	/* Dell Studio Hybrid 140g (OmniVision webcam) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2432,7 +2508,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_DEF },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_def },
 	/* Dell XPS M1330 (OmniVision OV7670 webcam) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2441,7 +2517,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_DEF },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_def },
 	/* Apple Built-In iSight */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2450,8 +2526,8 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info 		= UVC_QUIRK_PROBE_MINMAX
-				| UVC_QUIRK_BUILTIN_ISIGHT },
+	  .driver_info		= UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+					| UVC_QUIRK_BUILTIN_ISIGHT) },
 	/* Apple Built-In iSight via iBridge */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2460,7 +2536,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_DEF },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_def },
 	/* Foxlink ("HP Webcam" on HP Mini 5103) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2469,7 +2545,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_FIX_BANDWIDTH },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
 	/* Genesys Logic USB 2.0 PC Camera */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2478,7 +2554,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_stream_no_fid },
 	/* Hercules Classic Silver */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2487,7 +2563,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_FIX_BANDWIDTH },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
 	/* ViMicro Vega */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2496,7 +2572,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_FIX_BANDWIDTH },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
 	/* ViMicro - Minoru3D */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2505,7 +2581,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_FIX_BANDWIDTH },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
 	/* ViMicro Venus - Minoru3D */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2514,7 +2590,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_FIX_BANDWIDTH },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
 	/* Ophir Optronics - SPCAM 620U */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2523,7 +2599,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* MT6227 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2532,8 +2608,8 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX
-				| UVC_QUIRK_PROBE_DEF },
+	  .driver_info		= UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+					| UVC_QUIRK_PROBE_DEF) },
 	/* IMC Networks (Medion Akoya) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2542,7 +2618,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_stream_no_fid },
 	/* JMicron USB2.0 XGA WebCam */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2551,7 +2627,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* Syntek (HP Spartan) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2560,7 +2636,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_stream_no_fid },
 	/* Syntek (Samsung Q310) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2569,7 +2645,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_stream_no_fid },
 	/* Syntek (Packard Bell EasyNote MX52 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2578,7 +2654,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_stream_no_fid },
 	/* Syntek (Asus F9SG) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2587,7 +2663,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_stream_no_fid },
 	/* Syntek (Asus U3S) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2596,7 +2672,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_stream_no_fid },
 	/* Syntek (JAOtech Smart Terminal) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2605,7 +2681,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_stream_no_fid },
 	/* Miricle 307K */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2614,7 +2690,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_stream_no_fid },
 	/* Lenovo Thinkpad SL400/SL500 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2623,7 +2699,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_stream_no_fid },
 	/* Aveo Technology USB 2.0 Camera */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2632,8 +2708,8 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX
-				| UVC_QUIRK_PROBE_EXTRAFIELDS },
+	  .driver_info		= UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+					| UVC_QUIRK_PROBE_EXTRAFIELDS) },
 	/* Aveo Technology USB 2.0 Camera (Tasco USB Microscope) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2650,7 +2726,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_EXTRAFIELDS },
+	  .driver_info		= UVC_QUIRK_INFO(UVC_QUIRK_PROBE_EXTRAFIELDS) },
 	/* Manta MM-353 Plako */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2659,7 +2735,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* FSC WebCam V30S */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2668,7 +2744,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* Arkmicro unbranded */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2677,7 +2753,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_DEF },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_def },
 	/* The Imaging Source USB CCD cameras */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2696,7 +2772,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_STATUS_INTERVAL },
+	  .driver_info		= UVC_QUIRK_INFO(UVC_QUIRK_STATUS_INTERVAL) },
 	/* MSI StarCam 370i */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2705,7 +2781,16 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
+	/* Generalplus Technology Inc. 808 Camera */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x1b3f,
+	  .idProduct		= 0x2002,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* SiGma Micro USB Web Camera */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2714,8 +2799,8 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX
-				| UVC_QUIRK_IGNORE_SELECTOR_UNIT },
+	  .driver_info		= UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+					| UVC_QUIRK_IGNORE_SELECTOR_UNIT) },
 	/* Oculus VR Positional Tracker DK2 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2724,7 +2809,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_FORCE_Y8 },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_force_y8 },
 	/* Oculus VR Rift Sensor */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2733,7 +2818,7 @@ static const struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_FORCE_Y8 },
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_force_y8 },
 	/* Generic USB Video Class */
 	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
 	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c
index 8510e725..5059fbf 100644
--- a/drivers/media/usb/uvc/uvc_isight.c
+++ b/drivers/media/usb/uvc/uvc_isight.c
@@ -27,11 +27,11 @@
  *
  * Offset   Size (bytes)	Description
  * ------------------------------------------------------------------
- * 0x00 	1   	Header length
- * 0x01 	1   	Flags (UVC-compliant)
- * 0x02 	4   	Always equal to '11223344'
- * 0x06 	8   	Always equal to 'deadbeefdeadface'
- * 0x0e 	16  	Unknown
+ * 0x00	1	Header length
+ * 0x01	1	Flags (UVC-compliant)
+ * 0x02	4	Always equal to '11223344'
+ * 0x06	8	Always equal to 'deadbeefdeadface'
+ * 0x0e	16	Unknown
  *
  * The header can be prefixed by an optional, unknown-purpose byte.
  */
@@ -100,7 +100,7 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
 }
 
 void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
-		struct uvc_buffer *buf)
+			struct uvc_buffer *buf, struct uvc_buffer *meta_buf)
 {
 	int ret, i;
 
diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c
new file mode 100644
index 0000000..cd1aec1
--- /dev/null
+++ b/drivers/media/usb/uvc/uvc_metadata.c
@@ -0,0 +1,179 @@
+/*
+ *      uvc_metadata.c  --  USB Video Class driver - Metadata handling
+ *
+ *      Copyright (C) 2016
+ *          Guennadi Liakhovetski (guennadi.liakhovetski@intel.com)
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-vmalloc.h>
+
+#include "uvcvideo.h"
+
+/* -----------------------------------------------------------------------------
+ * V4L2 ioctls
+ */
+
+static int uvc_meta_v4l2_querycap(struct file *file, void *fh,
+				  struct v4l2_capability *cap)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
+	struct uvc_video_chain *chain = stream->chain;
+
+	strlcpy(cap->driver, "uvcvideo", sizeof(cap->driver));
+	strlcpy(cap->card, vfh->vdev->name, sizeof(cap->card));
+	usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
+	cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
+			  | chain->caps;
+
+	return 0;
+}
+
+static int uvc_meta_v4l2_get_format(struct file *file, void *fh,
+				    struct v4l2_format *format)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
+	struct v4l2_meta_format *fmt = &format->fmt.meta;
+
+	if (format->type != vfh->vdev->queue->type)
+		return -EINVAL;
+
+	memset(fmt, 0, sizeof(*fmt));
+
+	fmt->dataformat = stream->meta.format;
+	fmt->buffersize = UVC_METATADA_BUF_SIZE;
+
+	return 0;
+}
+
+static int uvc_meta_v4l2_try_format(struct file *file, void *fh,
+				    struct v4l2_format *format)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
+	struct uvc_device *dev = stream->dev;
+	struct v4l2_meta_format *fmt = &format->fmt.meta;
+	u32 fmeta = fmt->dataformat;
+
+	if (format->type != vfh->vdev->queue->type)
+		return -EINVAL;
+
+	memset(fmt, 0, sizeof(*fmt));
+
+	fmt->dataformat = fmeta == dev->meta_format ? fmeta : V4L2_META_FMT_UVC;
+	fmt->buffersize = UVC_METATADA_BUF_SIZE;
+
+	return 0;
+}
+
+static int uvc_meta_v4l2_set_format(struct file *file, void *fh,
+				    struct v4l2_format *format)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
+	struct v4l2_meta_format *fmt = &format->fmt.meta;
+	int ret;
+
+	ret = uvc_meta_v4l2_try_format(file, fh, format);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We could in principle switch at any time, also during streaming.
+	 * Metadata buffers would still be perfectly parseable, but it's more
+	 * consistent and cleaner to disallow that.
+	 */
+	mutex_lock(&stream->mutex);
+
+	if (uvc_queue_allocated(&stream->queue))
+		ret = -EBUSY;
+	else
+		stream->meta.format = fmt->dataformat;
+
+	mutex_unlock(&stream->mutex);
+
+	return ret;
+}
+
+static int uvc_meta_v4l2_enum_formats(struct file *file, void *fh,
+				      struct v4l2_fmtdesc *fdesc)
+{
+	struct v4l2_fh *vfh = file->private_data;
+	struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
+	struct uvc_device *dev = stream->dev;
+	u32 index = fdesc->index;
+
+	if (fdesc->type != vfh->vdev->queue->type ||
+	    index > 1U || (index && !dev->meta_format))
+		return -EINVAL;
+
+	memset(fdesc, 0, sizeof(*fdesc));
+
+	fdesc->type = vfh->vdev->queue->type;
+	fdesc->index = index;
+	fdesc->pixelformat = index ? dev->meta_format : V4L2_META_FMT_UVC;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops uvc_meta_ioctl_ops = {
+	.vidioc_querycap		= uvc_meta_v4l2_querycap,
+	.vidioc_g_fmt_meta_cap		= uvc_meta_v4l2_get_format,
+	.vidioc_s_fmt_meta_cap		= uvc_meta_v4l2_set_format,
+	.vidioc_try_fmt_meta_cap	= uvc_meta_v4l2_try_format,
+	.vidioc_enum_fmt_meta_cap	= uvc_meta_v4l2_enum_formats,
+	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
+	.vidioc_querybuf		= vb2_ioctl_querybuf,
+	.vidioc_qbuf			= vb2_ioctl_qbuf,
+	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
+	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
+	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
+	.vidioc_streamon		= vb2_ioctl_streamon,
+	.vidioc_streamoff		= vb2_ioctl_streamoff,
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 File Operations
+ */
+
+static const struct v4l2_file_operations uvc_meta_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = video_ioctl2,
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
+	.poll = vb2_fop_poll,
+	.mmap = vb2_fop_mmap,
+};
+
+int uvc_meta_register(struct uvc_streaming *stream)
+{
+	struct uvc_device *dev = stream->dev;
+	struct video_device *vdev = &stream->meta.vdev;
+	struct uvc_video_queue *queue = &stream->meta.queue;
+
+	stream->meta.format = V4L2_META_FMT_UVC;
+
+	/*
+	 * The video interface queue uses manual locking and thus does not set
+	 * the queue pointer. Set it manually here.
+	 */
+	vdev->queue = &queue->queue;
+
+	return uvc_register_video_device(dev, stream, vdev, queue,
+					 V4L2_BUF_TYPE_META_CAPTURE,
+					 &uvc_meta_fops, &uvc_meta_ioctl_ops);
+}
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index 692c463..fecccb5 100644
--- a/drivers/media/usb/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -79,8 +79,19 @@ static int uvc_queue_setup(struct vb2_queue *vq,
 			   unsigned int sizes[], struct device *alloc_devs[])
 {
 	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
-	struct uvc_streaming *stream = uvc_queue_to_stream(queue);
-	unsigned size = stream->ctrl.dwMaxVideoFrameSize;
+	struct uvc_streaming *stream;
+	unsigned int size;
+
+	switch (vq->type) {
+	case V4L2_BUF_TYPE_META_CAPTURE:
+		size = UVC_METATADA_BUF_SIZE;
+		break;
+
+	default:
+		stream = uvc_queue_to_stream(queue);
+		size = stream->ctrl.dwMaxVideoFrameSize;
+		break;
+	}
 
 	/*
 	 * When called with plane sizes, validate them. The driver supports
@@ -114,7 +125,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
 	buf->error = 0;
 	buf->mem = vb2_plane_vaddr(vb, 0);
 	buf->length = vb2_plane_size(vb, 0);
-	if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+	if (vb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
 		buf->bytesused = 0;
 	else
 		buf->bytesused = vb2_get_plane_payload(vb, 0);
@@ -177,10 +188,10 @@ static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count)
 static void uvc_stop_streaming(struct vb2_queue *vq)
 {
 	struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
-	struct uvc_streaming *stream = uvc_queue_to_stream(queue);
 	unsigned long flags;
 
-	uvc_video_enable(stream, 0);
+	if (vq->type != V4L2_BUF_TYPE_META_CAPTURE)
+		uvc_video_enable(uvc_queue_to_stream(queue), 0);
 
 	spin_lock_irqsave(&queue->irqlock, flags);
 	uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
@@ -198,20 +209,39 @@ static const struct vb2_ops uvc_queue_qops = {
 	.stop_streaming = uvc_stop_streaming,
 };
 
+static const struct vb2_ops uvc_meta_queue_qops = {
+	.queue_setup = uvc_queue_setup,
+	.buf_prepare = uvc_buffer_prepare,
+	.buf_queue = uvc_buffer_queue,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+	.stop_streaming = uvc_stop_streaming,
+};
+
 int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
 		    int drop_corrupted)
 {
 	int ret;
 
 	queue->queue.type = type;
-	queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
+	queue->queue.io_modes = VB2_MMAP | VB2_USERPTR;
 	queue->queue.drv_priv = queue;
 	queue->queue.buf_struct_size = sizeof(struct uvc_buffer);
-	queue->queue.ops = &uvc_queue_qops;
 	queue->queue.mem_ops = &vb2_vmalloc_memops;
 	queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
 		| V4L2_BUF_FLAG_TSTAMP_SRC_SOE;
 	queue->queue.lock = &queue->mutex;
+
+	switch (type) {
+	case V4L2_BUF_TYPE_META_CAPTURE:
+		queue->queue.ops = &uvc_meta_queue_qops;
+		break;
+	default:
+		queue->queue.io_modes |= VB2_DMABUF;
+		queue->queue.ops = &uvc_queue_qops;
+		break;
+	}
+
 	ret = vb2_queue_init(&queue->queue);
 	if (ret)
 		return ret;
diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c
index f552ab9..1ef20e7 100644
--- a/drivers/media/usb/uvc/uvc_status.c
+++ b/drivers/media/usb/uvc/uvc_status.c
@@ -93,8 +93,9 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len)
 			data[1], data[3] ? "pressed" : "released", len);
 		uvc_input_report_key(dev, KEY_CAMERA, data[3]);
 	} else {
-		uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x "
-			"len %d.\n", data[1], data[2], data[3], len);
+		uvc_trace(UVC_TRACE_STATUS,
+			  "Stream %u error event %02x len %d.\n",
+			  data[1], data[2], len);
 	}
 }
 
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index 381f614..a13ad4e 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -568,10 +568,6 @@ static int uvc_ioctl_querycap(struct file *file, void *fh,
 	usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
 	cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
 			  | chain->caps;
-	if (stream->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;
 }
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index fb86d6a..5441553 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -369,12 +369,12 @@ static int uvc_commit_video(struct uvc_streaming *stream,
  * Clocks and timestamps
  */
 
-static inline void uvc_video_get_ts(struct timespec *ts)
+static inline ktime_t uvc_video_get_time(void)
 {
 	if (uvc_clock_param == CLOCK_MONOTONIC)
-		ktime_get_ts(ts);
+		return ktime_get();
 	else
-		ktime_get_real_ts(ts);
+		return ktime_get_real();
 }
 
 static void
@@ -386,7 +386,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
 	bool has_pts = false;
 	bool has_scr = false;
 	unsigned long flags;
-	struct timespec ts;
+	ktime_t time;
 	u16 host_sof;
 	u16 dev_sof;
 
@@ -436,7 +436,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
 	stream->clock.last_sof = dev_sof;
 
 	host_sof = usb_get_current_frame_number(stream->dev->udev);
-	uvc_video_get_ts(&ts);
+	time = uvc_video_get_time();
 
 	/* The UVC specification allows device implementations that can't obtain
 	 * the USB frame number to keep their own frame counters as long as they
@@ -473,7 +473,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
 	sample->dev_stc = get_unaligned_le32(&data[header_size - 6]);
 	sample->dev_sof = dev_sof;
 	sample->host_sof = host_sof;
-	sample->host_ts = ts;
+	sample->host_time = time;
 
 	/* Update the sliding window head and count. */
 	stream->clock.head = (stream->clock.head + 1) % stream->clock.size;
@@ -613,14 +613,12 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
 	struct uvc_clock_sample *first;
 	struct uvc_clock_sample *last;
 	unsigned long flags;
-	struct timespec ts;
+	u64 timestamp;
 	u32 delta_stc;
 	u32 y1, y2;
 	u32 x1, x2;
 	u32 mean;
 	u32 sof;
-	u32 div;
-	u32 rem;
 	u64 y;
 
 	if (!uvc_hw_timestamps_param)
@@ -667,9 +665,8 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
 	if (x1 == x2)
 		goto done;
 
-	ts = timespec_sub(last->host_ts, first->host_ts);
 	y1 = NSEC_PER_SEC;
-	y2 = (ts.tv_sec + 1) * NSEC_PER_SEC + ts.tv_nsec;
+	y2 = (u32)ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1;
 
 	/* Interpolated and host SOF timestamps can wrap around at slightly
 	 * different times. Handle this by adding or removing 2048 to or from
@@ -686,24 +683,18 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
 	  - (u64)y2 * (u64)x1;
 	y = div_u64(y, x2 - x1);
 
-	div = div_u64_rem(y, NSEC_PER_SEC, &rem);
-	ts.tv_sec = first->host_ts.tv_sec - 1 + div;
-	ts.tv_nsec = first->host_ts.tv_nsec + rem;
-	if (ts.tv_nsec >= NSEC_PER_SEC) {
-		ts.tv_sec++;
-		ts.tv_nsec -= NSEC_PER_SEC;
-	}
+	timestamp = ktime_to_ns(first->host_time) + y - y1;
 
 	uvc_trace(UVC_TRACE_CLOCK, "%s: SOF %u.%06llu y %llu ts %llu "
 		  "buf ts %llu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %u)\n",
 		  stream->dev->name,
 		  sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536),
-		  y, timespec_to_ns(&ts), vbuf->vb2_buf.timestamp,
+		  y, timestamp, vbuf->vb2_buf.timestamp,
 		  x1, first->host_sof, first->dev_sof,
 		  x2, last->host_sof, last->dev_sof, y1, y2);
 
 	/* Update the V4L2 buffer. */
-	vbuf->vb2_buf.timestamp = timespec_to_ns(&ts);
+	vbuf->vb2_buf.timestamp = timestamp;
 
 done:
 	spin_unlock_irqrestore(&clock->lock, flags);
@@ -725,7 +716,7 @@ static void uvc_video_stats_decode(struct uvc_streaming *stream,
 
 	if (stream->stats.stream.nb_frames == 0 &&
 	    stream->stats.frame.nb_packets == 0)
-		ktime_get_ts(&stream->stats.stream.start_ts);
+		stream->stats.stream.start_ts = ktime_get();
 
 	switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) {
 	case UVC_STREAM_PTS | UVC_STREAM_SCR:
@@ -865,16 +856,13 @@ size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf,
 {
 	unsigned int scr_sof_freq;
 	unsigned int duration;
-	struct timespec ts;
 	size_t count = 0;
 
-	ts = timespec_sub(stream->stats.stream.stop_ts,
-			  stream->stats.stream.start_ts);
-
 	/* Compute the SCR.SOF frequency estimate. At the nominal 1kHz SOF
 	 * frequency this will not overflow before more than 1h.
 	 */
-	duration = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
+	duration = ktime_ms_delta(stream->stats.stream.stop_ts,
+				  stream->stats.stream.start_ts);
 	if (duration != 0)
 		scr_sof_freq = stream->stats.stream.scr_sof_count * 1000
 			     / duration;
@@ -915,7 +903,7 @@ static void uvc_video_stats_start(struct uvc_streaming *stream)
 
 static void uvc_video_stats_stop(struct uvc_streaming *stream)
 {
-	ktime_get_ts(&stream->stats.stream.stop_ts);
+	stream->stats.stream.stop_ts = ktime_get();
 }
 
 /* ------------------------------------------------------------------------
@@ -1010,8 +998,6 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
 	 * when the EOF bit is set to force synchronisation on the next packet.
 	 */
 	if (buf->state != UVC_BUF_STATE_ACTIVE) {
-		struct timespec ts;
-
 		if (fid == stream->last_fid) {
 			uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of "
 				"sync).\n");
@@ -1021,11 +1007,9 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
 			return -ENODATA;
 		}
 
-		uvc_video_get_ts(&ts);
-
 		buf->buf.field = V4L2_FIELD_NONE;
 		buf->buf.sequence = stream->sequence;
-		buf->buf.vb2_buf.timestamp = timespec_to_ns(&ts);
+		buf->buf.vb2_buf.timestamp = uvc_video_get_time();
 
 		/* TODO: Handle PTS and SCR. */
 		buf->state = UVC_BUF_STATE_ACTIVE;
@@ -1077,6 +1061,7 @@ static void uvc_video_decode_data(struct uvc_streaming *stream,
 	/* Complete the current frame if the buffer size was exceeded. */
 	if (len > maxlen) {
 		uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
+		buf->error = 1;
 		buf->state = UVC_BUF_STATE_READY;
 	}
 }
@@ -1135,6 +1120,84 @@ static int uvc_video_encode_data(struct uvc_streaming *stream,
 }
 
 /* ------------------------------------------------------------------------
+ * Metadata
+ */
+
+/*
+ * Additionally to the payload headers we also want to provide the user with USB
+ * Frame Numbers and system time values. The resulting buffer is thus composed
+ * of blocks, containing a 64-bit timestamp in  nanoseconds, a 16-bit USB Frame
+ * Number, and a copy of the payload header.
+ *
+ * Ideally we want to capture all payload headers for each frame. However, their
+ * number is unknown and unbound. We thus drop headers that contain no vendor
+ * data and that either contain no SCR value or an SCR value identical to the
+ * previous header.
+ */
+static void uvc_video_decode_meta(struct uvc_streaming *stream,
+				  struct uvc_buffer *meta_buf,
+				  const u8 *mem, unsigned int length)
+{
+	struct uvc_meta_buf *meta;
+	size_t len_std = 2;
+	bool has_pts, has_scr;
+	unsigned long flags;
+	unsigned int sof;
+	ktime_t time;
+	const u8 *scr;
+
+	if (!meta_buf || length == 2)
+		return;
+
+	if (meta_buf->length - meta_buf->bytesused <
+	    length + sizeof(meta->ns) + sizeof(meta->sof)) {
+		meta_buf->error = 1;
+		return;
+	}
+
+	has_pts = mem[1] & UVC_STREAM_PTS;
+	has_scr = mem[1] & UVC_STREAM_SCR;
+
+	if (has_pts) {
+		len_std += 4;
+		scr = mem + 6;
+	} else {
+		scr = mem + 2;
+	}
+
+	if (has_scr)
+		len_std += 6;
+
+	if (stream->meta.format == V4L2_META_FMT_UVC)
+		length = len_std;
+
+	if (length == len_std && (!has_scr ||
+				  !memcmp(scr, stream->clock.last_scr, 6)))
+		return;
+
+	meta = (struct uvc_meta_buf *)((u8 *)meta_buf->mem + meta_buf->bytesused);
+	local_irq_save(flags);
+	time = uvc_video_get_time();
+	sof = usb_get_current_frame_number(stream->dev->udev);
+	local_irq_restore(flags);
+	put_unaligned(ktime_to_ns(time), &meta->ns);
+	put_unaligned(sof, &meta->sof);
+
+	if (has_scr)
+		memcpy(stream->clock.last_scr, scr, 6);
+
+	memcpy(&meta->length, mem, length);
+	meta_buf->bytesused += length + sizeof(meta->ns) + sizeof(meta->sof);
+
+	uvc_trace(UVC_TRACE_FRAME,
+		  "%s(): t-sys %lluns, SOF %u, len %u, flags 0x%x, PTS %u, STC %u frame SOF %u\n",
+		  __func__, time, meta->sof, meta->length, meta->flags,
+		  has_pts ? *(u32 *)meta->buf : 0,
+		  has_scr ? *(u32 *)scr : 0,
+		  has_scr ? *(u32 *)(scr + 4) & 0x7ff : 0);
+}
+
+/* ------------------------------------------------------------------------
  * URB handling
  */
 
@@ -1152,8 +1215,29 @@ static void uvc_video_validate_buffer(const struct uvc_streaming *stream,
 /*
  * Completion handler for video URBs.
  */
+
+static void uvc_video_next_buffers(struct uvc_streaming *stream,
+		struct uvc_buffer **video_buf, struct uvc_buffer **meta_buf)
+{
+	if (*meta_buf) {
+		struct vb2_v4l2_buffer *vb2_meta = &(*meta_buf)->buf;
+		const struct vb2_v4l2_buffer *vb2_video = &(*video_buf)->buf;
+
+		vb2_meta->sequence = vb2_video->sequence;
+		vb2_meta->field = vb2_video->field;
+		vb2_meta->vb2_buf.timestamp = vb2_video->vb2_buf.timestamp;
+
+		(*meta_buf)->state = UVC_BUF_STATE_READY;
+		if (!(*meta_buf)->error)
+			(*meta_buf)->error = (*video_buf)->error;
+		*meta_buf = uvc_queue_next_buffer(&stream->meta.queue,
+						  *meta_buf);
+	}
+	*video_buf = uvc_queue_next_buffer(&stream->queue, *video_buf);
+}
+
 static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream,
-	struct uvc_buffer *buf)
+			struct uvc_buffer *buf, struct uvc_buffer *meta_buf)
 {
 	u8 *mem;
 	int ret, i;
@@ -1175,14 +1259,15 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream,
 				urb->iso_frame_desc[i].actual_length);
 			if (ret == -EAGAIN) {
 				uvc_video_validate_buffer(stream, buf);
-				buf = uvc_queue_next_buffer(&stream->queue,
-							    buf);
+				uvc_video_next_buffers(stream, &buf, &meta_buf);
 			}
 		} while (ret == -EAGAIN);
 
 		if (ret < 0)
 			continue;
 
+		uvc_video_decode_meta(stream, meta_buf, mem, ret);
+
 		/* Decode the payload data. */
 		uvc_video_decode_data(stream, buf, mem + ret,
 			urb->iso_frame_desc[i].actual_length - ret);
@@ -1193,13 +1278,13 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream,
 
 		if (buf->state == UVC_BUF_STATE_READY) {
 			uvc_video_validate_buffer(stream, buf);
-			buf = uvc_queue_next_buffer(&stream->queue, buf);
+			uvc_video_next_buffers(stream, &buf, &meta_buf);
 		}
 	}
 }
 
 static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
-	struct uvc_buffer *buf)
+			struct uvc_buffer *buf, struct uvc_buffer *meta_buf)
 {
 	u8 *mem;
 	int len, ret;
@@ -1222,8 +1307,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
 		do {
 			ret = uvc_video_decode_start(stream, buf, mem, len);
 			if (ret == -EAGAIN)
-				buf = uvc_queue_next_buffer(&stream->queue,
-							    buf);
+				uvc_video_next_buffers(stream, &buf, &meta_buf);
 		} while (ret == -EAGAIN);
 
 		/* If an error occurred skip the rest of the payload. */
@@ -1233,6 +1317,8 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
 			memcpy(stream->bulk.header, mem, ret);
 			stream->bulk.header_size = ret;
 
+			uvc_video_decode_meta(stream, meta_buf, mem, ret);
+
 			mem += ret;
 			len -= ret;
 		}
@@ -1256,7 +1342,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
 			uvc_video_decode_end(stream, buf, stream->bulk.header,
 				stream->bulk.payload_size);
 			if (buf->state == UVC_BUF_STATE_READY)
-				uvc_queue_next_buffer(&stream->queue, buf);
+				uvc_video_next_buffers(stream, &buf, &meta_buf);
 		}
 
 		stream->bulk.header_size = 0;
@@ -1266,7 +1352,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
 }
 
 static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream,
-	struct uvc_buffer *buf)
+	struct uvc_buffer *buf, struct uvc_buffer *meta_buf)
 {
 	u8 *mem = urb->transfer_buffer;
 	int len = stream->urb_size, ret;
@@ -1312,7 +1398,10 @@ static void uvc_video_complete(struct urb *urb)
 {
 	struct uvc_streaming *stream = urb->context;
 	struct uvc_video_queue *queue = &stream->queue;
+	struct uvc_video_queue *qmeta = &stream->meta.queue;
+	struct vb2_queue *vb2_qmeta = stream->meta.vdev.queue;
 	struct uvc_buffer *buf = NULL;
+	struct uvc_buffer *buf_meta = NULL;
 	unsigned long flags;
 	int ret;
 
@@ -1331,6 +1420,8 @@ static void uvc_video_complete(struct urb *urb)
 	case -ECONNRESET:	/* usb_unlink_urb() called. */
 	case -ESHUTDOWN:	/* The endpoint is being disabled. */
 		uvc_queue_cancel(queue, urb->status == -ESHUTDOWN);
+		if (vb2_qmeta)
+			uvc_queue_cancel(qmeta, urb->status == -ESHUTDOWN);
 		return;
 	}
 
@@ -1340,7 +1431,15 @@ static void uvc_video_complete(struct urb *urb)
 				       queue);
 	spin_unlock_irqrestore(&queue->irqlock, flags);
 
-	stream->decode(urb, stream, buf);
+	if (vb2_qmeta) {
+		spin_lock_irqsave(&qmeta->irqlock, flags);
+		if (!list_empty(&qmeta->irqqueue))
+			buf_meta = list_first_entry(&qmeta->irqqueue,
+						    struct uvc_buffer, queue);
+		spin_unlock_irqrestore(&qmeta->irqlock, flags);
+	}
+
+	stream->decode(urb, stream, buf, buf_meta);
 
 	if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
 		uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n",
@@ -1469,13 +1568,13 @@ static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev,
 	case USB_SPEED_HIGH:
 		psize = usb_endpoint_maxp(&ep->desc);
 		mult = usb_endpoint_maxp_mult(&ep->desc);
-		return (psize & 0x07ff) * mult;
+		return psize * mult;
 	case USB_SPEED_WIRELESS:
 		psize = usb_endpoint_maxp(&ep->desc);
 		return psize;
 	default:
 		psize = usb_endpoint_maxp(&ep->desc);
-		return psize & 0x07ff;
+		return psize;
 	}
 }
 
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 9b44a7c..d9e7c70 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -154,6 +154,11 @@
 	{ 'I',  'N',  'V',  'I', 0xdb, 0x57, 0x49, 0x5e, \
 	 0x8e, 0x3f, 0xf4, 0x79, 0x53, 0x2b, 0x94, 0x6f}
 
+#define UVC_GUID_FORMAT_D3DFMT_L8 \
+	{0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \
+	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+
+
 /* ------------------------------------------------------------------------
  * Driver specific constants.
  */
@@ -452,8 +457,8 @@ struct uvc_stats_frame {
 };
 
 struct uvc_stats_stream {
-	struct timespec start_ts;	/* Stream start timestamp */
-	struct timespec stop_ts;	/* Stream stop timestamp */
+	ktime_t start_ts;		/* Stream start timestamp */
+	ktime_t stop_ts;		/* Stream stop timestamp */
 
 	unsigned int nb_frames;		/* Number of frames */
 
@@ -474,6 +479,8 @@ struct uvc_stats_stream {
 	unsigned int max_sof;		/* Maximum STC.SOF value */
 };
 
+#define UVC_METATADA_BUF_SIZE 1024
+
 struct uvc_streaming {
 	struct list_head list;
 	struct uvc_device *dev;
@@ -505,7 +512,13 @@ struct uvc_streaming {
 	unsigned int frozen : 1;
 	struct uvc_video_queue queue;
 	void (*decode) (struct urb *urb, struct uvc_streaming *video,
-			struct uvc_buffer *buf);
+			struct uvc_buffer *buf, struct uvc_buffer *meta_buf);
+
+	struct {
+		struct video_device vdev;
+		struct uvc_video_queue queue;
+		__u32 format;
+	} meta;
 
 	/* Context data used by the bulk completion handler. */
 	struct {
@@ -536,8 +549,8 @@ struct uvc_streaming {
 		struct uvc_clock_sample {
 			u32 dev_stc;
 			u16 dev_sof;
-			struct timespec host_ts;
 			u16 host_sof;
+			ktime_t host_time;
 		} *samples;
 
 		unsigned int head;
@@ -547,6 +560,8 @@ struct uvc_streaming {
 		u16 last_sof;
 		u16 sof_offset;
 
+		u8 last_scr[6];
+
 		spinlock_t lock;
 	} clock;
 };
@@ -556,6 +571,7 @@ struct uvc_device {
 	struct usb_interface *intf;
 	unsigned long warnings;
 	__u32 quirks;
+	__u32 meta_format;
 	int intfnum;
 	char name[32];
 
@@ -710,6 +726,15 @@ extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
 void uvc_video_clock_update(struct uvc_streaming *stream,
 			    struct vb2_v4l2_buffer *vbuf,
 			    struct uvc_buffer *buf);
+int uvc_meta_register(struct uvc_streaming *stream);
+
+int uvc_register_video_device(struct uvc_device *dev,
+			      struct uvc_streaming *stream,
+			      struct video_device *vdev,
+			      struct uvc_video_queue *queue,
+			      enum v4l2_buf_type type,
+			      const struct v4l2_file_operations *fops,
+			      const struct v4l2_ioctl_ops *ioctl_ops);
 
 /* Status */
 extern int uvc_status_init(struct uvc_device *dev);
@@ -764,7 +789,7 @@ extern struct usb_host_endpoint *uvc_find_endpoint(
 
 /* Quirks support */
 void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
-		struct uvc_buffer *buf);
+		struct uvc_buffer *buf, struct uvc_buffer *meta_buf);
 
 /* debugfs and statistics */
 void uvc_debugfs_init(void);
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index a35c336..bf52fbd 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -41,8 +41,8 @@
 
 # Used by drivers that need v4l2-mem2mem.ko
 config V4L2_MEM2MEM_DEV
-        tristate
-        depends on VIDEOBUF2_CORE
+	tristate
+	depends on VIDEOBUF2_CORE
 
 # Used by LED subsystem flash drivers
 config V4L2_FLASH_LED_CLASS
@@ -79,35 +79,3 @@
 config VIDEOBUF_DVB
 	tristate
 	select VIDEOBUF_GEN
-
-# Used by drivers that need Videobuf2 modules
-config VIDEOBUF2_CORE
-	select DMA_SHARED_BUFFER
-	tristate
-
-config VIDEOBUF2_MEMOPS
-	tristate
-	select FRAME_VECTOR
-
-config VIDEOBUF2_DMA_CONTIG
-	tristate
-	depends on HAS_DMA
-	select VIDEOBUF2_CORE
-	select VIDEOBUF2_MEMOPS
-	select DMA_SHARED_BUFFER
-
-config VIDEOBUF2_VMALLOC
-	tristate
-	select VIDEOBUF2_CORE
-	select VIDEOBUF2_MEMOPS
-	select DMA_SHARED_BUFFER
-
-config VIDEOBUF2_DMA_SG
-	tristate
-	depends on HAS_DMA
-	select VIDEOBUF2_CORE
-	select VIDEOBUF2_MEMOPS
-
-config VIDEOBUF2_DVB
-	tristate
-	select VIDEOBUF2_CORE
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 7730328..80de2cb 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -33,14 +33,6 @@
 obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
 obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
 
-obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o
-obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
-obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
-obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
-obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o
-obj-$(CONFIG_VIDEOBUF2_DVB) += videobuf2-dvb.o
-
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
 ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
 ccflags-y += -I$(srctree)/drivers/media/tuners
 
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index e5acfab..2b08d03 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -68,12 +68,12 @@ static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 static bool match_devname(struct v4l2_subdev *sd,
 			  struct v4l2_async_subdev *asd)
 {
-	return !strcmp(asd->match.device_name.name, dev_name(sd->dev));
+	return !strcmp(asd->match.device_name, dev_name(sd->dev));
 }
 
 static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
 {
-	return sd->fwnode == asd->match.fwnode.fwnode;
+	return sd->fwnode == asd->match.fwnode;
 }
 
 static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
@@ -319,7 +319,7 @@ static bool __v4l2_async_notifier_fwnode_has_async_subdev(
 		if (asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
 			continue;
 
-		if (asd->match.fwnode.fwnode == fwnode)
+		if (asd->match.fwnode == fwnode)
 			return true;
 	}
 
@@ -330,7 +330,7 @@ static bool __v4l2_async_notifier_fwnode_has_async_subdev(
 		if (sd->asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
 			continue;
 
-		if (sd->asd->match.fwnode.fwnode == fwnode)
+		if (sd->asd->match.fwnode == fwnode)
 			return true;
 	}
 
@@ -355,8 +355,8 @@ static bool v4l2_async_notifier_fwnode_has_async_subdev(
 		struct v4l2_async_subdev *other_asd = notifier->subdevs[j];
 
 		if (other_asd->match_type == V4L2_ASYNC_MATCH_FWNODE &&
-		    asd->match.fwnode.fwnode ==
-		    other_asd->match.fwnode.fwnode)
+		    asd->match.fwnode ==
+		    other_asd->match.fwnode)
 			return true;
 	}
 
@@ -395,7 +395,7 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
 			break;
 		case V4L2_ASYNC_MATCH_FWNODE:
 			if (v4l2_async_notifier_fwnode_has_async_subdev(
-				    notifier, asd->match.fwnode.fwnode, i)) {
+				    notifier, asd->match.fwnode, i)) {
 				dev_err(dev,
 					"fwnode has already been registered or in notifier's subdev list\n");
 				ret = -EEXIST;
@@ -510,7 +510,7 @@ void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
 
 		switch (asd->match_type) {
 		case V4L2_ASYNC_MATCH_FWNODE:
-			fwnode_handle_put(asd->match.fwnode.fwnode);
+			fwnode_handle_put(asd->match.fwnode);
 			break;
 		default:
 			WARN_ON_ONCE(true);
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index a5ea1f5..8650ad9 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -320,20 +320,6 @@ static unsigned int clamp_align(unsigned int x, unsigned int min,
 	return x;
 }
 
-/* Bound an image to have a width between wmin and wmax, and height between
- * hmin and hmax, inclusive.  Additionally, the width will be a multiple of
- * 2^walign, the height will be a multiple of 2^halign, and the overall size
- * (width*height) will be a multiple of 2^salign.  The image may be shrunk
- * or enlarged to fit the alignment constraints.
- *
- * The width or height maximum must not be smaller than the corresponding
- * minimum.  The alignments must not be so high there are no possible image
- * sizes within the allowed bounds.  wmin and hmin must be at least 1
- * (don't use 0).  If you don't care about a certain alignment, specify 0,
- * as 2^0 is 1 and one byte alignment is equivalent to no alignment.  If
- * you only want to adjust downward, specify a maximum that's the same as
- * the initial value.
- */
 void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
 			   unsigned int walign,
 			   u32 *h, unsigned int hmin, unsigned int hmax,
@@ -371,18 +357,19 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
 }
 EXPORT_SYMBOL_GPL(v4l_bound_align_image);
 
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
-		const struct v4l2_discrete_probe *probe,
-		s32 width, s32 height)
+const struct v4l2_frmsize_discrete *
+v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,
+			  size_t num_sizes,
+			  s32 width, s32 height)
 {
 	int i;
 	u32 error, min_error = UINT_MAX;
 	const struct v4l2_frmsize_discrete *size, *best = NULL;
 
-	if (!probe)
-		return best;
+	if (!sizes)
+		return NULL;
 
-	for (i = 0, size = probe->sizes; i < probe->num_sizes; i++, size++) {
+	for (i = 0, size = sizes; i < num_sizes; i++, size++) {
 		error = abs(size->width - width) + abs(size->height - height);
 		if (error < min_error) {
 			min_error = error;
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 821f2aa..5198c9e 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -18,8 +18,18 @@
 #include <linux/videodev2.h>
 #include <linux/v4l2-subdev.h>
 #include <media/v4l2-dev.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ctrls.h>
 #include <media/v4l2-ioctl.h>
 
+/* Use the same argument order as copy_in_user */
+#define assign_in_user(to, from)					\
+({									\
+	typeof(*from) __assign_tmp;					\
+									\
+	get_user(__assign_tmp, from) || put_user(__assign_tmp, to);	\
+})
+
 static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	long ret = -ENOIOCTLCMD;
@@ -33,12 +43,12 @@ static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
 struct v4l2_clip32 {
 	struct v4l2_rect        c;
-	compat_caddr_t 		next;
+	compat_caddr_t		next;
 };
 
 struct v4l2_window32 {
 	struct v4l2_rect        w;
-	__u32		  	field;	/* enum v4l2_field */
+	__u32			field;	/* enum v4l2_field */
 	__u32			chromakey;
 	compat_caddr_t		clips; /* actually struct v4l2_clip32 * */
 	__u32			clipcount;
@@ -46,135 +56,75 @@ struct v4l2_window32 {
 	__u8                    global_alpha;
 };
 
-static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
+static int get_v4l2_window32(struct v4l2_window __user *kp,
+			     struct v4l2_window32 __user *up,
+			     void __user *aux_buf, u32 aux_space)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||
-		copy_from_user(&kp->w, &up->w, sizeof(up->w)) ||
-		get_user(kp->field, &up->field) ||
-		get_user(kp->chromakey, &up->chromakey) ||
-		get_user(kp->clipcount, &up->clipcount) ||
-		get_user(kp->global_alpha, &up->global_alpha))
-			return -EFAULT;
-	if (kp->clipcount > 2048)
+	struct v4l2_clip32 __user *uclips;
+	struct v4l2_clip __user *kclips;
+	compat_caddr_t p;
+	u32 clipcount;
+
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    copy_in_user(&kp->w, &up->w, sizeof(up->w)) ||
+	    assign_in_user(&kp->field, &up->field) ||
+	    assign_in_user(&kp->chromakey, &up->chromakey) ||
+	    assign_in_user(&kp->global_alpha, &up->global_alpha) ||
+	    get_user(clipcount, &up->clipcount) ||
+	    put_user(clipcount, &kp->clipcount))
+		return -EFAULT;
+	if (clipcount > 2048)
 		return -EINVAL;
-	if (kp->clipcount) {
-		struct v4l2_clip32 __user *uclips;
-		struct v4l2_clip __user *kclips;
-		int n = kp->clipcount;
-		compat_caddr_t p;
+	if (!clipcount)
+		return put_user(NULL, &kp->clips);
 
-		if (get_user(p, &up->clips))
+	if (get_user(p, &up->clips))
+		return -EFAULT;
+	uclips = compat_ptr(p);
+	if (aux_space < clipcount * sizeof(*kclips))
+		return -EFAULT;
+	kclips = aux_buf;
+	if (put_user(kclips, &kp->clips))
+		return -EFAULT;
+
+	while (clipcount--) {
+		if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
 			return -EFAULT;
-		uclips = compat_ptr(p);
-		kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
-		kp->clips = kclips;
-		while (--n >= 0) {
-			if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
-				return -EFAULT;
-			if (put_user(n ? kclips + 1 : NULL, &kclips->next))
-				return -EFAULT;
-			uclips += 1;
-			kclips += 1;
-		}
-	} else
-		kp->clips = NULL;
-	return 0;
-}
-
-static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
-{
-	if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) ||
-		put_user(kp->field, &up->field) ||
-		put_user(kp->chromakey, &up->chromakey) ||
-		put_user(kp->clipcount, &up->clipcount) ||
-		put_user(kp->global_alpha, &up->global_alpha))
+		if (put_user(clipcount ? kclips + 1 : NULL, &kclips->next))
 			return -EFAULT;
+		uclips++;
+		kclips++;
+	}
 	return 0;
 }
 
-static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
+static int put_v4l2_window32(struct v4l2_window __user *kp,
+			     struct v4l2_window32 __user *up)
 {
-	if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
-		return -EFAULT;
-	return 0;
-}
+	struct v4l2_clip __user *kclips = kp->clips;
+	struct v4l2_clip32 __user *uclips;
+	compat_caddr_t p;
+	u32 clipcount;
 
-static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
-				struct v4l2_pix_format_mplane __user *up)
-{
-	if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
+	if (copy_in_user(&up->w, &kp->w, sizeof(kp->w)) ||
+	    assign_in_user(&up->field, &kp->field) ||
+	    assign_in_user(&up->chromakey, &kp->chromakey) ||
+	    assign_in_user(&up->global_alpha, &kp->global_alpha) ||
+	    get_user(clipcount, &kp->clipcount) ||
+	    put_user(clipcount, &up->clipcount))
 		return -EFAULT;
-	return 0;
-}
+	if (!clipcount)
+		return 0;
 
-static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
-{
-	if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
+	if (get_user(p, &up->clips))
 		return -EFAULT;
-	return 0;
-}
-
-static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
-				struct v4l2_pix_format_mplane __user *up)
-{
-	if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
-		return -EFAULT;
-	return 0;
-}
-
-static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
-{
-	if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
-		return -EFAULT;
-	return 0;
-}
-
-static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
-{
-	if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
-		return -EFAULT;
-	return 0;
-}
-
-static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
-{
-	if (copy_from_user(kp, up, sizeof(struct v4l2_sliced_vbi_format)))
-		return -EFAULT;
-	return 0;
-}
-
-static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
-{
-	if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format)))
-		return -EFAULT;
-	return 0;
-}
-
-static inline int get_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sdr_format __user *up)
-{
-	if (copy_from_user(kp, up, sizeof(struct v4l2_sdr_format)))
-		return -EFAULT;
-	return 0;
-}
-
-static inline int put_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sdr_format __user *up)
-{
-	if (copy_to_user(up, kp, sizeof(struct v4l2_sdr_format)))
-		return -EFAULT;
-	return 0;
-}
-
-static inline int get_v4l2_meta_format(struct v4l2_meta_format *kp, struct v4l2_meta_format __user *up)
-{
-	if (copy_from_user(kp, up, sizeof(struct v4l2_meta_format)))
-		return -EFAULT;
-	return 0;
-}
-
-static inline int put_v4l2_meta_format(struct v4l2_meta_format *kp, struct v4l2_meta_format __user *up)
-{
-	if (copy_to_user(up, kp, sizeof(struct v4l2_meta_format)))
-		return -EFAULT;
+	uclips = compat_ptr(p);
+	while (clipcount--) {
+		if (copy_in_user(&uclips->c, &kclips->c, sizeof(uclips->c)))
+			return -EFAULT;
+		uclips++;
+		kclips++;
+	}
 	return 0;
 }
 
@@ -209,101 +159,164 @@ struct v4l2_create_buffers32 {
 	__u32			reserved[8];
 };
 
-static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int __bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size)
 {
-	if (get_user(kp->type, &up->type))
+	u32 type;
+
+	if (get_user(type, &up->type))
 		return -EFAULT;
 
-	switch (kp->type) {
+	switch (type) {
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
+		u32 clipcount;
+
+		if (get_user(clipcount, &up->fmt.win.clipcount))
+			return -EFAULT;
+		if (clipcount > 2048)
+			return -EINVAL;
+		*size = clipcount * sizeof(struct v4l2_clip);
+		return 0;
+	}
+	default:
+		*size = 0;
+		return 0;
+	}
+}
+
+static int bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size)
+{
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
+		return -EFAULT;
+	return __bufsize_v4l2_format(up, size);
+}
+
+static int __get_v4l2_format32(struct v4l2_format __user *kp,
+			       struct v4l2_format32 __user *up,
+			       void __user *aux_buf, u32 aux_space)
+{
+	u32 type;
+
+	if (get_user(type, &up->type) || put_user(type, &kp->type))
+		return -EFAULT;
+
+	switch (type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
+		return copy_in_user(&kp->fmt.pix, &up->fmt.pix,
+				    sizeof(kp->fmt.pix)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		return get_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
-						  &up->fmt.pix_mp);
+		return copy_in_user(&kp->fmt.pix_mp, &up->fmt.pix_mp,
+				    sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-		return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
+		return get_v4l2_window32(&kp->fmt.win, &up->fmt.win,
+					 aux_buf, aux_space);
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
-		return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
+		return copy_in_user(&kp->fmt.vbi, &up->fmt.vbi,
+				    sizeof(kp->fmt.vbi)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-		return get_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
+		return copy_in_user(&kp->fmt.sliced, &up->fmt.sliced,
+				    sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_SDR_CAPTURE:
 	case V4L2_BUF_TYPE_SDR_OUTPUT:
-		return get_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
+		return copy_in_user(&kp->fmt.sdr, &up->fmt.sdr,
+				    sizeof(kp->fmt.sdr)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_META_CAPTURE:
-		return get_v4l2_meta_format(&kp->fmt.meta, &up->fmt.meta);
+		return copy_in_user(&kp->fmt.meta, &up->fmt.meta,
+				    sizeof(kp->fmt.meta)) ? -EFAULT : 0;
 	default:
-		pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
-								kp->type);
 		return -EINVAL;
 	}
 }
 
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format __user *kp,
+			     struct v4l2_format32 __user *up,
+			     void __user *aux_buf, u32 aux_space)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)))
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
 		return -EFAULT;
-	return __get_v4l2_format32(kp, up);
+	return __get_v4l2_format32(kp, up, aux_buf, aux_space);
 }
 
-static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+static int bufsize_v4l2_create(struct v4l2_create_buffers32 __user *up,
+			       u32 *size)
 {
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
-	    copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format)))
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
 		return -EFAULT;
-	return __get_v4l2_format32(&kp->format, &up->format);
+	return __bufsize_v4l2_format(&up->format, size);
 }
 
-static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_create32(struct v4l2_create_buffers __user *kp,
+			     struct v4l2_create_buffers32 __user *up,
+			     void __user *aux_buf, u32 aux_space)
 {
-	if (put_user(kp->type, &up->type))
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    copy_in_user(kp, up,
+			 offsetof(struct v4l2_create_buffers32, format)))
+		return -EFAULT;
+	return __get_v4l2_format32(&kp->format, &up->format,
+				   aux_buf, aux_space);
+}
+
+static int __put_v4l2_format32(struct v4l2_format __user *kp,
+			       struct v4l2_format32 __user *up)
+{
+	u32 type;
+
+	if (get_user(type, &kp->type))
 		return -EFAULT;
 
-	switch (kp->type) {
+	switch (type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
+		return copy_in_user(&up->fmt.pix, &kp->fmt.pix,
+				    sizeof(kp->fmt.pix)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		return put_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
-						  &up->fmt.pix_mp);
+		return copy_in_user(&up->fmt.pix_mp, &kp->fmt.pix_mp,
+				    sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
 		return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
-		return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
+		return copy_in_user(&up->fmt.vbi, &kp->fmt.vbi,
+				    sizeof(kp->fmt.vbi)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-		return put_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced);
+		return copy_in_user(&up->fmt.sliced, &kp->fmt.sliced,
+				    sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_SDR_CAPTURE:
 	case V4L2_BUF_TYPE_SDR_OUTPUT:
-		return put_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
+		return copy_in_user(&up->fmt.sdr, &kp->fmt.sdr,
+				    sizeof(kp->fmt.sdr)) ? -EFAULT : 0;
 	case V4L2_BUF_TYPE_META_CAPTURE:
-		return put_v4l2_meta_format(&kp->fmt.meta, &up->fmt.meta);
+		return copy_in_user(&up->fmt.meta, &kp->fmt.meta,
+				    sizeof(kp->fmt.meta)) ? -EFAULT : 0;
 	default:
-		pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
-								kp->type);
 		return -EINVAL;
 	}
 }
 
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int put_v4l2_format32(struct v4l2_format __user *kp,
+			     struct v4l2_format32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)))
+	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
 		return -EFAULT;
 	return __put_v4l2_format32(kp, up);
 }
 
-static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+static int put_v4l2_create32(struct v4l2_create_buffers __user *kp,
+			     struct v4l2_create_buffers32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
-	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format)) ||
-	    copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
+	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+	    copy_in_user(up, kp,
+			 offsetof(struct v4l2_create_buffers32, format)) ||
+	    copy_in_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
 		return -EFAULT;
 	return __put_v4l2_format32(&kp->format, &up->format);
 }
@@ -317,25 +330,28 @@ struct v4l2_standard32 {
 	__u32		     reserved[4];
 };
 
-static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
+static int get_v4l2_standard32(struct v4l2_standard __user *kp,
+			       struct v4l2_standard32 __user *up)
 {
 	/* other fields are not set by the user, nor used by the driver */
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) ||
-		get_user(kp->index, &up->index))
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    assign_in_user(&kp->index, &up->index))
 		return -EFAULT;
 	return 0;
 }
 
-static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
+static int put_v4l2_standard32(struct v4l2_standard __user *kp,
+			       struct v4l2_standard32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
-		put_user(kp->index, &up->index) ||
-		put_user(kp->id, &up->id) ||
-		copy_to_user(up->name, kp->name, 24) ||
-		copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||
-		put_user(kp->framelines, &up->framelines) ||
-		copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)))
-			return -EFAULT;
+	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+	    assign_in_user(&up->index, &kp->index) ||
+	    assign_in_user(&up->id, &kp->id) ||
+	    copy_in_user(up->name, kp->name, sizeof(up->name)) ||
+	    copy_in_user(&up->frameperiod, &kp->frameperiod,
+			 sizeof(up->frameperiod)) ||
+	    assign_in_user(&up->framelines, &kp->framelines) ||
+	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+		return -EFAULT;
 	return 0;
 }
 
@@ -374,136 +390,186 @@ struct v4l2_buffer32 {
 	__u32			reserved;
 };
 
-static int get_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
-				enum v4l2_memory memory)
+static int get_v4l2_plane32(struct v4l2_plane __user *up,
+			    struct v4l2_plane32 __user *up32,
+			    enum v4l2_memory memory)
 {
-	void __user *up_pln;
-	compat_long_t p;
+	compat_ulong_t p;
 
 	if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
-		copy_in_user(&up->data_offset, &up32->data_offset,
-				sizeof(__u32)))
+	    copy_in_user(&up->data_offset, &up32->data_offset,
+			 sizeof(up->data_offset)))
 		return -EFAULT;
 
-	if (memory == V4L2_MEMORY_USERPTR) {
-		if (get_user(p, &up32->m.userptr))
-			return -EFAULT;
-		up_pln = compat_ptr(p);
-		if (put_user((unsigned long)up_pln, &up->m.userptr))
-			return -EFAULT;
-	} else if (memory == V4L2_MEMORY_DMABUF) {
-		if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int)))
-			return -EFAULT;
-	} else {
+	switch (memory) {
+	case V4L2_MEMORY_MMAP:
+	case V4L2_MEMORY_OVERLAY:
 		if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
-					sizeof(__u32)))
+				 sizeof(up32->m.mem_offset)))
 			return -EFAULT;
+		break;
+	case V4L2_MEMORY_USERPTR:
+		if (get_user(p, &up32->m.userptr) ||
+		    put_user((unsigned long)compat_ptr(p), &up->m.userptr))
+			return -EFAULT;
+		break;
+	case V4L2_MEMORY_DMABUF:
+		if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(up32->m.fd)))
+			return -EFAULT;
+		break;
 	}
 
 	return 0;
 }
 
-static int put_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
-				enum v4l2_memory memory)
+static int put_v4l2_plane32(struct v4l2_plane __user *up,
+			    struct v4l2_plane32 __user *up32,
+			    enum v4l2_memory memory)
 {
+	unsigned long p;
+
 	if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
-		copy_in_user(&up32->data_offset, &up->data_offset,
-				sizeof(__u32)))
+	    copy_in_user(&up32->data_offset, &up->data_offset,
+			 sizeof(up->data_offset)))
 		return -EFAULT;
 
-	/* For MMAP, driver might've set up the offset, so copy it back.
-	 * USERPTR stays the same (was userspace-provided), so no copying. */
-	if (memory == V4L2_MEMORY_MMAP)
+	switch (memory) {
+	case V4L2_MEMORY_MMAP:
+	case V4L2_MEMORY_OVERLAY:
 		if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
-					sizeof(__u32)))
+				 sizeof(up->m.mem_offset)))
 			return -EFAULT;
-	/* For DMABUF, driver might've set up the fd, so copy it back. */
-	if (memory == V4L2_MEMORY_DMABUF)
-		if (copy_in_user(&up32->m.fd, &up->m.fd,
-					sizeof(int)))
+		break;
+	case V4L2_MEMORY_USERPTR:
+		if (get_user(p, &up->m.userptr) ||
+		    put_user((compat_ulong_t)ptr_to_compat((__force void *)p),
+			     &up32->m.userptr))
 			return -EFAULT;
+		break;
+	case V4L2_MEMORY_DMABUF:
+		if (copy_in_user(&up32->m.fd, &up->m.fd, sizeof(up->m.fd)))
+			return -EFAULT;
+		break;
+	}
 
 	return 0;
 }
 
-static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
+static int bufsize_v4l2_buffer(struct v4l2_buffer32 __user *up, u32 *size)
 {
+	u32 type;
+	u32 length;
+
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    get_user(type, &up->type) ||
+	    get_user(length, &up->length))
+		return -EFAULT;
+
+	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+		if (length > VIDEO_MAX_PLANES)
+			return -EINVAL;
+
+		/*
+		 * We don't really care if userspace decides to kill itself
+		 * by passing a very big length value
+		 */
+		*size = length * sizeof(struct v4l2_plane);
+	} else {
+		*size = 0;
+	}
+	return 0;
+}
+
+static int get_v4l2_buffer32(struct v4l2_buffer __user *kp,
+			     struct v4l2_buffer32 __user *up,
+			     void __user *aux_buf, u32 aux_space)
+{
+	u32 type;
+	u32 length;
+	enum v4l2_memory memory;
 	struct v4l2_plane32 __user *uplane32;
 	struct v4l2_plane __user *uplane;
 	compat_caddr_t p;
 	int ret;
 
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
-		get_user(kp->index, &up->index) ||
-		get_user(kp->type, &up->type) ||
-		get_user(kp->flags, &up->flags) ||
-		get_user(kp->memory, &up->memory) ||
-		get_user(kp->length, &up->length))
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    assign_in_user(&kp->index, &up->index) ||
+	    get_user(type, &up->type) ||
+	    put_user(type, &kp->type) ||
+	    assign_in_user(&kp->flags, &up->flags) ||
+	    get_user(memory, &up->memory) ||
+	    put_user(memory, &kp->memory) ||
+	    get_user(length, &up->length) ||
+	    put_user(length, &kp->length))
+		return -EFAULT;
+
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		if (assign_in_user(&kp->bytesused, &up->bytesused) ||
+		    assign_in_user(&kp->field, &up->field) ||
+		    assign_in_user(&kp->timestamp.tv_sec,
+				   &up->timestamp.tv_sec) ||
+		    assign_in_user(&kp->timestamp.tv_usec,
+				   &up->timestamp.tv_usec))
 			return -EFAULT;
 
-	if (V4L2_TYPE_IS_OUTPUT(kp->type))
-		if (get_user(kp->bytesused, &up->bytesused) ||
-			get_user(kp->field, &up->field) ||
-			get_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
-			get_user(kp->timestamp.tv_usec,
-					&up->timestamp.tv_usec))
-			return -EFAULT;
+	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+		u32 num_planes = length;
 
-	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
-		unsigned int num_planes;
-
-		if (kp->length == 0) {
-			kp->m.planes = NULL;
-			/* num_planes == 0 is legal, e.g. when userspace doesn't
-			 * need planes array on DQBUF*/
-			return 0;
-		} else if (kp->length > VIDEO_MAX_PLANES) {
-			return -EINVAL;
+		if (num_planes == 0) {
+			/*
+			 * num_planes == 0 is legal, e.g. when userspace doesn't
+			 * need planes array on DQBUF
+			 */
+			return put_user(NULL, &kp->m.planes);
 		}
+		if (num_planes > VIDEO_MAX_PLANES)
+			return -EINVAL;
 
 		if (get_user(p, &up->m.planes))
 			return -EFAULT;
 
 		uplane32 = compat_ptr(p);
 		if (!access_ok(VERIFY_READ, uplane32,
-				kp->length * sizeof(struct v4l2_plane32)))
+			       num_planes * sizeof(*uplane32)))
 			return -EFAULT;
 
-		/* We don't really care if userspace decides to kill itself
-		 * by passing a very big num_planes value */
-		uplane = compat_alloc_user_space(kp->length *
-						 sizeof(struct v4l2_plane));
-		kp->m.planes = (__force struct v4l2_plane *)uplane;
+		/*
+		 * We don't really care if userspace decides to kill itself
+		 * by passing a very big num_planes value
+		 */
+		if (aux_space < num_planes * sizeof(*uplane))
+			return -EFAULT;
 
-		for (num_planes = 0; num_planes < kp->length; num_planes++) {
-			ret = get_v4l2_plane32(uplane, uplane32, kp->memory);
+		uplane = aux_buf;
+		if (put_user((__force struct v4l2_plane *)uplane,
+			     &kp->m.planes))
+			return -EFAULT;
+
+		while (num_planes--) {
+			ret = get_v4l2_plane32(uplane, uplane32, memory);
 			if (ret)
 				return ret;
-			++uplane;
-			++uplane32;
+			uplane++;
+			uplane32++;
 		}
 	} else {
-		switch (kp->memory) {
+		switch (memory) {
 		case V4L2_MEMORY_MMAP:
-			if (get_user(kp->m.offset, &up->m.offset))
-				return -EFAULT;
-			break;
-		case V4L2_MEMORY_USERPTR:
-			{
-			compat_long_t tmp;
-
-			if (get_user(tmp, &up->m.userptr))
-				return -EFAULT;
-
-			kp->m.userptr = (unsigned long)compat_ptr(tmp);
-			}
-			break;
 		case V4L2_MEMORY_OVERLAY:
-			if (get_user(kp->m.offset, &up->m.offset))
+			if (assign_in_user(&kp->m.offset, &up->m.offset))
 				return -EFAULT;
 			break;
+		case V4L2_MEMORY_USERPTR: {
+			compat_ulong_t userptr;
+
+			if (get_user(userptr, &up->m.userptr) ||
+			    put_user((unsigned long)compat_ptr(userptr),
+				     &kp->m.userptr))
+				return -EFAULT;
+			break;
+		}
 		case V4L2_MEMORY_DMABUF:
-			if (get_user(kp->m.fd, &up->m.fd))
+			if (assign_in_user(&kp->m.fd, &up->m.fd))
 				return -EFAULT;
 			break;
 		}
@@ -512,65 +578,70 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
 	return 0;
 }
 
-static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
+static int put_v4l2_buffer32(struct v4l2_buffer __user *kp,
+			     struct v4l2_buffer32 __user *up)
 {
+	u32 type;
+	u32 length;
+	enum v4l2_memory memory;
 	struct v4l2_plane32 __user *uplane32;
 	struct v4l2_plane __user *uplane;
 	compat_caddr_t p;
-	int num_planes;
 	int ret;
 
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
-		put_user(kp->index, &up->index) ||
-		put_user(kp->type, &up->type) ||
-		put_user(kp->flags, &up->flags) ||
-		put_user(kp->memory, &up->memory))
-			return -EFAULT;
+	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+	    assign_in_user(&up->index, &kp->index) ||
+	    get_user(type, &kp->type) ||
+	    put_user(type, &up->type) ||
+	    assign_in_user(&up->flags, &kp->flags) ||
+	    get_user(memory, &kp->memory) ||
+	    put_user(memory, &up->memory))
+		return -EFAULT;
 
-	if (put_user(kp->bytesused, &up->bytesused) ||
-		put_user(kp->field, &up->field) ||
-		put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
-		put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) ||
-		copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
-		put_user(kp->sequence, &up->sequence) ||
-		put_user(kp->reserved2, &up->reserved2) ||
-		put_user(kp->reserved, &up->reserved) ||
-		put_user(kp->length, &up->length))
-			return -EFAULT;
+	if (assign_in_user(&up->bytesused, &kp->bytesused) ||
+	    assign_in_user(&up->field, &kp->field) ||
+	    assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
+	    assign_in_user(&up->timestamp.tv_usec, &kp->timestamp.tv_usec) ||
+	    copy_in_user(&up->timecode, &kp->timecode, sizeof(kp->timecode)) ||
+	    assign_in_user(&up->sequence, &kp->sequence) ||
+	    assign_in_user(&up->reserved2, &kp->reserved2) ||
+	    assign_in_user(&up->reserved, &kp->reserved) ||
+	    get_user(length, &kp->length) ||
+	    put_user(length, &up->length))
+		return -EFAULT;
 
-	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
-		num_planes = kp->length;
+	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+		u32 num_planes = length;
+
 		if (num_planes == 0)
 			return 0;
 
-		uplane = (__force struct v4l2_plane __user *)kp->m.planes;
+		if (get_user(uplane, ((__force struct v4l2_plane __user **)&kp->m.planes)))
+			return -EFAULT;
 		if (get_user(p, &up->m.planes))
 			return -EFAULT;
 		uplane32 = compat_ptr(p);
 
-		while (--num_planes >= 0) {
-			ret = put_v4l2_plane32(uplane, uplane32, kp->memory);
+		while (num_planes--) {
+			ret = put_v4l2_plane32(uplane, uplane32, memory);
 			if (ret)
 				return ret;
 			++uplane;
 			++uplane32;
 		}
 	} else {
-		switch (kp->memory) {
+		switch (memory) {
 		case V4L2_MEMORY_MMAP:
-			if (put_user(kp->m.offset, &up->m.offset))
+		case V4L2_MEMORY_OVERLAY:
+			if (assign_in_user(&up->m.offset, &kp->m.offset))
 				return -EFAULT;
 			break;
 		case V4L2_MEMORY_USERPTR:
-			if (put_user(kp->m.userptr, &up->m.userptr))
-				return -EFAULT;
-			break;
-		case V4L2_MEMORY_OVERLAY:
-			if (put_user(kp->m.offset, &up->m.offset))
+			if (assign_in_user(&up->m.userptr, &kp->m.userptr))
 				return -EFAULT;
 			break;
 		case V4L2_MEMORY_DMABUF:
-			if (put_user(kp->m.fd, &up->m.fd))
+			if (assign_in_user(&up->m.fd, &kp->m.fd))
 				return -EFAULT;
 			break;
 		}
@@ -582,7 +653,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
 struct v4l2_framebuffer32 {
 	__u32			capability;
 	__u32			flags;
-	compat_caddr_t 		base;
+	compat_caddr_t		base;
 	struct {
 		__u32		width;
 		__u32		height;
@@ -595,30 +666,33 @@ struct v4l2_framebuffer32 {
 	} fmt;
 };
 
-static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
+static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
+				  struct v4l2_framebuffer32 __user *up)
 {
-	u32 tmp;
+	compat_caddr_t tmp;
 
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
-		get_user(tmp, &up->base) ||
-		get_user(kp->capability, &up->capability) ||
-		get_user(kp->flags, &up->flags) ||
-		copy_from_user(&kp->fmt, &up->fmt, sizeof(up->fmt)))
-			return -EFAULT;
-	kp->base = (__force void *)compat_ptr(tmp);
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    get_user(tmp, &up->base) ||
+	    put_user((__force void *)compat_ptr(tmp), &kp->base) ||
+	    assign_in_user(&kp->capability, &up->capability) ||
+	    assign_in_user(&kp->flags, &up->flags) ||
+	    copy_in_user(&kp->fmt, &up->fmt, sizeof(kp->fmt)))
+		return -EFAULT;
 	return 0;
 }
 
-static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
+static int put_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
+				  struct v4l2_framebuffer32 __user *up)
 {
-	u32 tmp = (u32)((unsigned long)kp->base);
+	void *base;
 
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
-		put_user(tmp, &up->base) ||
-		put_user(kp->capability, &up->capability) ||
-		put_user(kp->flags, &up->flags) ||
-		copy_to_user(&up->fmt, &kp->fmt, sizeof(up->fmt)))
-			return -EFAULT;
+	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+	    get_user(base, &kp->base) ||
+	    put_user(ptr_to_compat(base), &up->base) ||
+	    assign_in_user(&up->capability, &kp->capability) ||
+	    assign_in_user(&up->flags, &kp->flags) ||
+	    copy_in_user(&up->fmt, &kp->fmt, sizeof(kp->fmt)))
+		return -EFAULT;
 	return 0;
 }
 
@@ -634,18 +708,22 @@ struct v4l2_input32 {
 	__u32	     reserved[3];
 };
 
-/* The 64-bit v4l2_input struct has extra padding at the end of the struct.
-   Otherwise it is identical to the 32-bit version. */
-static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
+/*
+ * The 64-bit v4l2_input struct has extra padding at the end of the struct.
+ * Otherwise it is identical to the 32-bit version.
+ */
+static inline int get_v4l2_input32(struct v4l2_input __user *kp,
+				   struct v4l2_input32 __user *up)
 {
-	if (copy_from_user(kp, up, sizeof(struct v4l2_input32)))
+	if (copy_in_user(kp, up, sizeof(*up)))
 		return -EFAULT;
 	return 0;
 }
 
-static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
+static inline int put_v4l2_input32(struct v4l2_input __user *kp,
+				   struct v4l2_input32 __user *up)
 {
-	if (copy_to_user(up, kp, sizeof(struct v4l2_input32)))
+	if (copy_in_user(up, kp, sizeof(*up)))
 		return -EFAULT;
 	return 0;
 }
@@ -669,60 +747,95 @@ struct v4l2_ext_control32 {
 	};
 } __attribute__ ((packed));
 
-/* The following function really belong in v4l2-common, but that causes
-   a circular dependency between modules. We need to think about this, but
-   for now this will do. */
-
-/* Return non-zero if this control is a pointer type. Currently only
-   type STRING is a pointer type. */
-static inline int ctrl_is_pointer(u32 id)
+/* Return true if this control is a pointer type. */
+static inline bool ctrl_is_pointer(struct file *file, u32 id)
 {
-	switch (id) {
-	case V4L2_CID_RDS_TX_PS_NAME:
-	case V4L2_CID_RDS_TX_RADIO_TEXT:
-		return 1;
-	default:
-		return 0;
+	struct video_device *vdev = video_devdata(file);
+	struct v4l2_fh *fh = NULL;
+	struct v4l2_ctrl_handler *hdl = NULL;
+	struct v4l2_query_ext_ctrl qec = { id };
+	const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
+
+	if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))
+		fh = file->private_data;
+
+	if (fh && fh->ctrl_handler)
+		hdl = fh->ctrl_handler;
+	else if (vdev->ctrl_handler)
+		hdl = vdev->ctrl_handler;
+
+	if (hdl) {
+		struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id);
+
+		return ctrl && ctrl->is_ptr;
 	}
+
+	if (!ops || !ops->vidioc_query_ext_ctrl)
+		return false;
+
+	return !ops->vidioc_query_ext_ctrl(file, fh, &qec) &&
+		(qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD);
 }
 
-static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
+static int bufsize_v4l2_ext_controls(struct v4l2_ext_controls32 __user *up,
+				     u32 *size)
+{
+	u32 count;
+
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    get_user(count, &up->count))
+		return -EFAULT;
+	if (count > V4L2_CID_MAX_CTRLS)
+		return -EINVAL;
+	*size = count * sizeof(struct v4l2_ext_control);
+	return 0;
+}
+
+static int get_v4l2_ext_controls32(struct file *file,
+				   struct v4l2_ext_controls __user *kp,
+				   struct v4l2_ext_controls32 __user *up,
+				   void __user *aux_buf, u32 aux_space)
 {
 	struct v4l2_ext_control32 __user *ucontrols;
 	struct v4l2_ext_control __user *kcontrols;
-	unsigned int n;
+	u32 count;
+	u32 n;
 	compat_caddr_t p;
 
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) ||
-		get_user(kp->which, &up->which) ||
-		get_user(kp->count, &up->count) ||
-		get_user(kp->error_idx, &up->error_idx) ||
-		copy_from_user(kp->reserved, up->reserved,
-			       sizeof(kp->reserved)))
-			return -EFAULT;
-	if (kp->count == 0) {
-		kp->controls = NULL;
-		return 0;
-	} else if (kp->count > V4L2_CID_MAX_CTRLS) {
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    assign_in_user(&kp->which, &up->which) ||
+	    get_user(count, &up->count) ||
+	    put_user(count, &kp->count) ||
+	    assign_in_user(&kp->error_idx, &up->error_idx) ||
+	    copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+		return -EFAULT;
+
+	if (count == 0)
+		return put_user(NULL, &kp->controls);
+	if (count > V4L2_CID_MAX_CTRLS)
 		return -EINVAL;
-	}
 	if (get_user(p, &up->controls))
 		return -EFAULT;
 	ucontrols = compat_ptr(p);
-	if (!access_ok(VERIFY_READ, ucontrols,
-			kp->count * sizeof(struct v4l2_ext_control32)))
+	if (!access_ok(VERIFY_READ, ucontrols, count * sizeof(*ucontrols)))
 		return -EFAULT;
-	kcontrols = compat_alloc_user_space(kp->count *
-					    sizeof(struct v4l2_ext_control));
-	kp->controls = (__force struct v4l2_ext_control *)kcontrols;
-	for (n = 0; n < kp->count; n++) {
+	if (aux_space < count * sizeof(*kcontrols))
+		return -EFAULT;
+	kcontrols = aux_buf;
+	if (put_user((__force struct v4l2_ext_control *)kcontrols,
+		     &kp->controls))
+		return -EFAULT;
+
+	for (n = 0; n < count; n++) {
 		u32 id;
 
 		if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
 			return -EFAULT;
+
 		if (get_user(id, &kcontrols->id))
 			return -EFAULT;
-		if (ctrl_is_pointer(id)) {
+
+		if (ctrl_is_pointer(file, id)) {
 			void __user *s;
 
 			if (get_user(p, &ucontrols->string))
@@ -737,43 +850,55 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
 	return 0;
 }
 
-static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
+static int put_v4l2_ext_controls32(struct file *file,
+				   struct v4l2_ext_controls __user *kp,
+				   struct v4l2_ext_controls32 __user *up)
 {
 	struct v4l2_ext_control32 __user *ucontrols;
-	struct v4l2_ext_control __user *kcontrols =
-		(__force struct v4l2_ext_control __user *)kp->controls;
-	int n = kp->count;
+	struct v4l2_ext_control __user *kcontrols;
+	u32 count;
+	u32 n;
 	compat_caddr_t p;
 
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_ext_controls32)) ||
-		put_user(kp->which, &up->which) ||
-		put_user(kp->count, &up->count) ||
-		put_user(kp->error_idx, &up->error_idx) ||
-		copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
-			return -EFAULT;
-	if (!kp->count)
-		return 0;
+	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+	    assign_in_user(&up->which, &kp->which) ||
+	    get_user(count, &kp->count) ||
+	    put_user(count, &up->count) ||
+	    assign_in_user(&up->error_idx, &kp->error_idx) ||
+	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)) ||
+	    get_user(kcontrols, &kp->controls))
+		return -EFAULT;
 
+	if (!count)
+		return 0;
 	if (get_user(p, &up->controls))
 		return -EFAULT;
 	ucontrols = compat_ptr(p);
-	if (!access_ok(VERIFY_WRITE, ucontrols,
-			n * sizeof(struct v4l2_ext_control32)))
+	if (!access_ok(VERIFY_WRITE, ucontrols, count * sizeof(*ucontrols)))
 		return -EFAULT;
 
-	while (--n >= 0) {
-		unsigned size = sizeof(*ucontrols);
+	for (n = 0; n < count; n++) {
+		unsigned int size = sizeof(*ucontrols);
 		u32 id;
 
-		if (get_user(id, &kcontrols->id))
+		if (get_user(id, &kcontrols->id) ||
+		    put_user(id, &ucontrols->id) ||
+		    assign_in_user(&ucontrols->size, &kcontrols->size) ||
+		    copy_in_user(&ucontrols->reserved2, &kcontrols->reserved2,
+				 sizeof(ucontrols->reserved2)))
 			return -EFAULT;
-		/* Do not modify the pointer when copying a pointer control.
-		   The contents of the pointer was changed, not the pointer
-		   itself. */
-		if (ctrl_is_pointer(id))
+
+		/*
+		 * Do not modify the pointer when copying a pointer control.
+		 * The contents of the pointer was changed, not the pointer
+		 * itself.
+		 */
+		if (ctrl_is_pointer(file, id))
 			size -= sizeof(ucontrols->value64);
+
 		if (copy_in_user(ucontrols, kcontrols, size))
 			return -EFAULT;
+
 		ucontrols++;
 		kcontrols++;
 	}
@@ -793,18 +918,19 @@ struct v4l2_event32 {
 	__u32				reserved[8];
 };
 
-static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *up)
+static int put_v4l2_event32(struct v4l2_event __user *kp,
+			    struct v4l2_event32 __user *up)
 {
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_event32)) ||
-		put_user(kp->type, &up->type) ||
-		copy_to_user(&up->u, &kp->u, sizeof(kp->u)) ||
-		put_user(kp->pending, &up->pending) ||
-		put_user(kp->sequence, &up->sequence) ||
-		put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
-		put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) ||
-		put_user(kp->id, &up->id) ||
-		copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32)))
-			return -EFAULT;
+	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+	    assign_in_user(&up->type, &kp->type) ||
+	    copy_in_user(&up->u, &kp->u, sizeof(kp->u)) ||
+	    assign_in_user(&up->pending, &kp->pending) ||
+	    assign_in_user(&up->sequence, &kp->sequence) ||
+	    assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
+	    assign_in_user(&up->timestamp.tv_nsec, &kp->timestamp.tv_nsec) ||
+	    assign_in_user(&up->id, &kp->id) ||
+	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+		return -EFAULT;
 	return 0;
 }
 
@@ -816,32 +942,35 @@ struct v4l2_edid32 {
 	compat_caddr_t edid;
 };
 
-static int get_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
+static int get_v4l2_edid32(struct v4l2_edid __user *kp,
+			   struct v4l2_edid32 __user *up)
 {
-	u32 tmp;
+	compat_uptr_t tmp;
 
-	if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_edid32)) ||
-		get_user(kp->pad, &up->pad) ||
-		get_user(kp->start_block, &up->start_block) ||
-		get_user(kp->blocks, &up->blocks) ||
-		get_user(tmp, &up->edid) ||
-		copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
-			return -EFAULT;
-	kp->edid = (__force u8 *)compat_ptr(tmp);
+	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+	    assign_in_user(&kp->pad, &up->pad) ||
+	    assign_in_user(&kp->start_block, &up->start_block) ||
+	    assign_in_user(&kp->blocks, &up->blocks) ||
+	    get_user(tmp, &up->edid) ||
+	    put_user(compat_ptr(tmp), &kp->edid) ||
+	    copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+		return -EFAULT;
 	return 0;
 }
 
-static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
+static int put_v4l2_edid32(struct v4l2_edid __user *kp,
+			   struct v4l2_edid32 __user *up)
 {
-	u32 tmp = (u32)((unsigned long)kp->edid);
+	void *edid;
 
-	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_edid32)) ||
-		put_user(kp->pad, &up->pad) ||
-		put_user(kp->start_block, &up->start_block) ||
-		put_user(kp->blocks, &up->blocks) ||
-		put_user(tmp, &up->edid) ||
-		copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
-			return -EFAULT;
+	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+	    assign_in_user(&up->pad, &kp->pad) ||
+	    assign_in_user(&up->start_block, &kp->start_block) ||
+	    assign_in_user(&up->blocks, &kp->blocks) ||
+	    get_user(edid, &kp->edid) ||
+	    put_user(ptr_to_compat(edid), &up->edid) ||
+	    copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+		return -EFAULT;
 	return 0;
 }
 
@@ -857,7 +986,7 @@ static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
 #define VIDIOC_ENUMINPUT32	_IOWR('V', 26, struct v4l2_input32)
 #define VIDIOC_G_EDID32		_IOWR('V', 40, struct v4l2_edid32)
 #define VIDIOC_S_EDID32		_IOWR('V', 41, struct v4l2_edid32)
-#define VIDIOC_TRY_FMT32      	_IOWR('V', 64, struct v4l2_format32)
+#define VIDIOC_TRY_FMT32	_IOWR('V', 64, struct v4l2_format32)
 #define VIDIOC_G_EXT_CTRLS32    _IOWR('V', 71, struct v4l2_ext_controls32)
 #define VIDIOC_S_EXT_CTRLS32    _IOWR('V', 72, struct v4l2_ext_controls32)
 #define VIDIOC_TRY_EXT_CTRLS32  _IOWR('V', 73, struct v4l2_ext_controls32)
@@ -873,22 +1002,23 @@ static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
 #define VIDIOC_G_OUTPUT32	_IOR ('V', 46, s32)
 #define VIDIOC_S_OUTPUT32	_IOWR('V', 47, s32)
 
+static int alloc_userspace(unsigned int size, u32 aux_space,
+			   void __user **up_native)
+{
+	*up_native = compat_alloc_user_space(size + aux_space);
+	if (!*up_native)
+		return -ENOMEM;
+	if (clear_user(*up_native, size))
+		return -EFAULT;
+	return 0;
+}
+
 static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	union {
-		struct v4l2_format v2f;
-		struct v4l2_buffer v2b;
-		struct v4l2_framebuffer v2fb;
-		struct v4l2_input v2i;
-		struct v4l2_standard v2s;
-		struct v4l2_ext_controls v2ecs;
-		struct v4l2_event v2ev;
-		struct v4l2_create_buffers v2crt;
-		struct v4l2_edid v2edid;
-		unsigned long vx;
-		int vi;
-	} karg;
 	void __user *up = compat_ptr(arg);
+	void __user *up_native = NULL;
+	void __user *aux_buf;
+	u32 aux_space;
 	int compatible_arg = 1;
 	long err = 0;
 
@@ -927,30 +1057,52 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 	case VIDIOC_STREAMOFF:
 	case VIDIOC_S_INPUT:
 	case VIDIOC_S_OUTPUT:
-		err = get_user(karg.vi, (s32 __user *)up);
+		err = alloc_userspace(sizeof(unsigned int), 0, &up_native);
+		if (!err && assign_in_user((unsigned int __user *)up_native,
+					   (compat_uint_t __user *)up))
+			err = -EFAULT;
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_G_INPUT:
 	case VIDIOC_G_OUTPUT:
+		err = alloc_userspace(sizeof(unsigned int), 0, &up_native);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_G_EDID:
 	case VIDIOC_S_EDID:
-		err = get_v4l2_edid32(&karg.v2edid, up);
+		err = alloc_userspace(sizeof(struct v4l2_edid), 0, &up_native);
+		if (!err)
+			err = get_v4l2_edid32(up_native, up);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_G_FMT:
 	case VIDIOC_S_FMT:
 	case VIDIOC_TRY_FMT:
-		err = get_v4l2_format32(&karg.v2f, up);
+		err = bufsize_v4l2_format(up, &aux_space);
+		if (!err)
+			err = alloc_userspace(sizeof(struct v4l2_format),
+					      aux_space, &up_native);
+		if (!err) {
+			aux_buf = up_native + sizeof(struct v4l2_format);
+			err = get_v4l2_format32(up_native, up,
+						aux_buf, aux_space);
+		}
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_CREATE_BUFS:
-		err = get_v4l2_create32(&karg.v2crt, up);
+		err = bufsize_v4l2_create(up, &aux_space);
+		if (!err)
+			err = alloc_userspace(sizeof(struct v4l2_create_buffers),
+					      aux_space, &up_native);
+		if (!err) {
+			aux_buf = up_native + sizeof(struct v4l2_create_buffers);
+			err = get_v4l2_create32(up_native, up,
+						aux_buf, aux_space);
+		}
 		compatible_arg = 0;
 		break;
 
@@ -958,36 +1110,63 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
-		err = get_v4l2_buffer32(&karg.v2b, up);
+		err = bufsize_v4l2_buffer(up, &aux_space);
+		if (!err)
+			err = alloc_userspace(sizeof(struct v4l2_buffer),
+					      aux_space, &up_native);
+		if (!err) {
+			aux_buf = up_native + sizeof(struct v4l2_buffer);
+			err = get_v4l2_buffer32(up_native, up,
+						aux_buf, aux_space);
+		}
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_S_FBUF:
-		err = get_v4l2_framebuffer32(&karg.v2fb, up);
+		err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
+				      &up_native);
+		if (!err)
+			err = get_v4l2_framebuffer32(up_native, up);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_G_FBUF:
+		err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
+				      &up_native);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_ENUMSTD:
-		err = get_v4l2_standard32(&karg.v2s, up);
+		err = alloc_userspace(sizeof(struct v4l2_standard), 0,
+				      &up_native);
+		if (!err)
+			err = get_v4l2_standard32(up_native, up);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_ENUMINPUT:
-		err = get_v4l2_input32(&karg.v2i, up);
+		err = alloc_userspace(sizeof(struct v4l2_input), 0, &up_native);
+		if (!err)
+			err = get_v4l2_input32(up_native, up);
 		compatible_arg = 0;
 		break;
 
 	case VIDIOC_G_EXT_CTRLS:
 	case VIDIOC_S_EXT_CTRLS:
 	case VIDIOC_TRY_EXT_CTRLS:
-		err = get_v4l2_ext_controls32(&karg.v2ecs, up);
+		err = bufsize_v4l2_ext_controls(up, &aux_space);
+		if (!err)
+			err = alloc_userspace(sizeof(struct v4l2_ext_controls),
+					      aux_space, &up_native);
+		if (!err) {
+			aux_buf = up_native + sizeof(struct v4l2_ext_controls);
+			err = get_v4l2_ext_controls32(file, up_native, up,
+						      aux_buf, aux_space);
+		}
 		compatible_arg = 0;
 		break;
 	case VIDIOC_DQEVENT:
+		err = alloc_userspace(sizeof(struct v4l2_event), 0, &up_native);
 		compatible_arg = 0;
 		break;
 	}
@@ -996,26 +1175,26 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 
 	if (compatible_arg)
 		err = native_ioctl(file, cmd, (unsigned long)up);
-	else {
-		mm_segment_t old_fs = get_fs();
+	else
+		err = native_ioctl(file, cmd, (unsigned long)up_native);
 
-		set_fs(KERNEL_DS);
-		err = native_ioctl(file, cmd, (unsigned long)&karg);
-		set_fs(old_fs);
-	}
+	if (err == -ENOTTY)
+		return err;
 
-	/* Special case: even after an error we need to put the
-	   results back for these ioctls since the error_idx will
-	   contain information on which control failed. */
+	/*
+	 * Special case: even after an error we need to put the
+	 * results back for these ioctls since the error_idx will
+	 * contain information on which control failed.
+	 */
 	switch (cmd) {
 	case VIDIOC_G_EXT_CTRLS:
 	case VIDIOC_S_EXT_CTRLS:
 	case VIDIOC_TRY_EXT_CTRLS:
-		if (put_v4l2_ext_controls32(&karg.v2ecs, up))
+		if (put_v4l2_ext_controls32(file, up_native, up))
 			err = -EFAULT;
 		break;
 	case VIDIOC_S_EDID:
-		if (put_v4l2_edid32(&karg.v2edid, up))
+		if (put_v4l2_edid32(up_native, up))
 			err = -EFAULT;
 		break;
 	}
@@ -1027,43 +1206,46 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
 	case VIDIOC_S_OUTPUT:
 	case VIDIOC_G_INPUT:
 	case VIDIOC_G_OUTPUT:
-		err = put_user(((s32)karg.vi), (s32 __user *)up);
+		if (assign_in_user((compat_uint_t __user *)up,
+				   ((unsigned int __user *)up_native)))
+			err = -EFAULT;
 		break;
 
 	case VIDIOC_G_FBUF:
-		err = put_v4l2_framebuffer32(&karg.v2fb, up);
+		err = put_v4l2_framebuffer32(up_native, up);
 		break;
 
 	case VIDIOC_DQEVENT:
-		err = put_v4l2_event32(&karg.v2ev, up);
+		err = put_v4l2_event32(up_native, up);
 		break;
 
 	case VIDIOC_G_EDID:
-		err = put_v4l2_edid32(&karg.v2edid, up);
+		err = put_v4l2_edid32(up_native, up);
 		break;
 
 	case VIDIOC_G_FMT:
 	case VIDIOC_S_FMT:
 	case VIDIOC_TRY_FMT:
-		err = put_v4l2_format32(&karg.v2f, up);
+		err = put_v4l2_format32(up_native, up);
 		break;
 
 	case VIDIOC_CREATE_BUFS:
-		err = put_v4l2_create32(&karg.v2crt, up);
+		err = put_v4l2_create32(up_native, up);
 		break;
 
+	case VIDIOC_PREPARE_BUF:
 	case VIDIOC_QUERYBUF:
 	case VIDIOC_QBUF:
 	case VIDIOC_DQBUF:
-		err = put_v4l2_buffer32(&karg.v2b, up);
+		err = put_v4l2_buffer32(up_native, up);
 		break;
 
 	case VIDIOC_ENUMSTD:
-		err = put_v4l2_standard32(&karg.v2s, up);
+		err = put_v4l2_standard32(up_native, up);
 		break;
 
 	case VIDIOC_ENUMINPUT:
-		err = put_v4l2_input32(&karg.v2i, up);
+		err = put_v4l2_input32(up_native, up);
 		break;
 	}
 	return err;
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 8ad8c16..cd8127d 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -102,7 +102,7 @@ static DECLARE_BITMAP(devnode_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES);
 
 #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
 /* Return the bitmap corresponding to vfl_type. */
-static inline unsigned long *devnode_bits(int vfl_type)
+static inline unsigned long *devnode_bits(enum vfl_devnode_type vfl_type)
 {
 	/* Any types not assigned to fixed minor ranges must be mapped to
 	   one single bitmap for the purposes of finding a free node number
@@ -113,7 +113,7 @@ static inline unsigned long *devnode_bits(int vfl_type)
 }
 #else
 /* Return the bitmap corresponding to vfl_type. */
-static inline unsigned long *devnode_bits(int vfl_type)
+static inline unsigned long *devnode_bits(enum vfl_devnode_type vfl_type)
 {
 	return devnode_nums[vfl_type];
 }
@@ -821,8 +821,10 @@ static int video_register_media_controller(struct video_device *vdev, int type)
 	return 0;
 }
 
-int __video_register_device(struct video_device *vdev, int type, int nr,
-		int warn_if_nr_in_use, struct module *owner)
+int __video_register_device(struct video_device *vdev,
+			    enum vfl_devnode_type type,
+			    int nr, int warn_if_nr_in_use,
+			    struct module *owner)
 {
 	int i = 0;
 	int ret;
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 930f9c5..e2ee5f0 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -249,7 +249,7 @@ EXPORT_SYMBOL_GPL(v4l2_find_dv_timings_cea861_vic);
  * @t2: with this struct.
  * @pclock_delta: the allowed pixelclock deviation.
  * @match_reduced_fps: if true, then fail if V4L2_DV_FL_REDUCED_FPS does not
- * 	match.
+ *	match.
  *
  * Compare t1 with t2 with a given margin of error for the pixelclock.
  */
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index fb72c7a..d630640 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -359,9 +359,9 @@ static int v4l2_async_notifier_fwnode_parse_endpoint(
 		return -ENOMEM;
 
 	asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-	asd->match.fwnode.fwnode =
+	asd->match.fwnode =
 		fwnode_graph_get_remote_port_parent(endpoint);
-	if (!asd->match.fwnode.fwnode) {
+	if (!asd->match.fwnode) {
 		dev_warn(dev, "bad remote port parent\n");
 		ret = -EINVAL;
 		goto out_err;
@@ -393,7 +393,7 @@ static int v4l2_async_notifier_fwnode_parse_endpoint(
 	return 0;
 
 out_err:
-	fwnode_handle_put(asd->match.fwnode.fwnode);
+	fwnode_handle_put(asd->match.fwnode);
 	kfree(asd);
 
 	return ret == -ENOTCONN ? 0 : ret;
@@ -566,7 +566,7 @@ static int v4l2_fwnode_reference_parse(
 		}
 
 		notifier->subdevs[notifier->num_subdevs] = asd;
-		asd->match.fwnode.fwnode = args.fwnode;
+		asd->match.fwnode = args.fwnode;
 		asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
 		notifier->num_subdevs++;
 	}
@@ -853,7 +853,7 @@ static int v4l2_fwnode_reference_parse_int_props(
 		}
 
 		notifier->subdevs[notifier->num_subdevs] = asd;
-		asd->match.fwnode.fwnode = fwnode;
+		asd->match.fwnode = fwnode;
 		asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
 		notifier->num_subdevs++;
 	}
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 7961499..260288c 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -46,37 +46,37 @@ struct std_descr {
 };
 
 static const struct std_descr standards[] = {
-	{ V4L2_STD_NTSC, 	"NTSC"      },
-	{ V4L2_STD_NTSC_M, 	"NTSC-M"    },
-	{ V4L2_STD_NTSC_M_JP, 	"NTSC-M-JP" },
+	{ V4L2_STD_NTSC,	"NTSC"      },
+	{ V4L2_STD_NTSC_M,	"NTSC-M"    },
+	{ V4L2_STD_NTSC_M_JP,	"NTSC-M-JP" },
 	{ V4L2_STD_NTSC_M_KR,	"NTSC-M-KR" },
-	{ V4L2_STD_NTSC_443, 	"NTSC-443"  },
-	{ V4L2_STD_PAL, 	"PAL"       },
-	{ V4L2_STD_PAL_BG, 	"PAL-BG"    },
-	{ V4L2_STD_PAL_B, 	"PAL-B"     },
-	{ V4L2_STD_PAL_B1, 	"PAL-B1"    },
-	{ V4L2_STD_PAL_G, 	"PAL-G"     },
-	{ V4L2_STD_PAL_H, 	"PAL-H"     },
-	{ V4L2_STD_PAL_I, 	"PAL-I"     },
-	{ V4L2_STD_PAL_DK, 	"PAL-DK"    },
-	{ V4L2_STD_PAL_D, 	"PAL-D"     },
-	{ V4L2_STD_PAL_D1, 	"PAL-D1"    },
-	{ V4L2_STD_PAL_K, 	"PAL-K"     },
-	{ V4L2_STD_PAL_M, 	"PAL-M"     },
-	{ V4L2_STD_PAL_N, 	"PAL-N"     },
-	{ V4L2_STD_PAL_Nc, 	"PAL-Nc"    },
-	{ V4L2_STD_PAL_60, 	"PAL-60"    },
-	{ V4L2_STD_SECAM, 	"SECAM"     },
-	{ V4L2_STD_SECAM_B, 	"SECAM-B"   },
-	{ V4L2_STD_SECAM_G, 	"SECAM-G"   },
-	{ V4L2_STD_SECAM_H, 	"SECAM-H"   },
-	{ V4L2_STD_SECAM_DK, 	"SECAM-DK"  },
-	{ V4L2_STD_SECAM_D, 	"SECAM-D"   },
-	{ V4L2_STD_SECAM_K, 	"SECAM-K"   },
-	{ V4L2_STD_SECAM_K1, 	"SECAM-K1"  },
-	{ V4L2_STD_SECAM_L, 	"SECAM-L"   },
-	{ V4L2_STD_SECAM_LC, 	"SECAM-Lc"  },
-	{ 0, 			"Unknown"   }
+	{ V4L2_STD_NTSC_443,	"NTSC-443"  },
+	{ V4L2_STD_PAL,		"PAL"       },
+	{ V4L2_STD_PAL_BG,	"PAL-BG"    },
+	{ V4L2_STD_PAL_B,	"PAL-B"     },
+	{ V4L2_STD_PAL_B1,	"PAL-B1"    },
+	{ V4L2_STD_PAL_G,	"PAL-G"     },
+	{ V4L2_STD_PAL_H,	"PAL-H"     },
+	{ V4L2_STD_PAL_I,	"PAL-I"     },
+	{ V4L2_STD_PAL_DK,	"PAL-DK"    },
+	{ V4L2_STD_PAL_D,	"PAL-D"     },
+	{ V4L2_STD_PAL_D1,	"PAL-D1"    },
+	{ V4L2_STD_PAL_K,	"PAL-K"     },
+	{ V4L2_STD_PAL_M,	"PAL-M"     },
+	{ V4L2_STD_PAL_N,	"PAL-N"     },
+	{ V4L2_STD_PAL_Nc,	"PAL-Nc"    },
+	{ V4L2_STD_PAL_60,	"PAL-60"    },
+	{ V4L2_STD_SECAM,	"SECAM"     },
+	{ V4L2_STD_SECAM_B,	"SECAM-B"   },
+	{ V4L2_STD_SECAM_G,	"SECAM-G"   },
+	{ V4L2_STD_SECAM_H,	"SECAM-H"   },
+	{ V4L2_STD_SECAM_DK,	"SECAM-DK"  },
+	{ V4L2_STD_SECAM_D,	"SECAM-D"   },
+	{ V4L2_STD_SECAM_K,	"SECAM-K"   },
+	{ V4L2_STD_SECAM_K1,	"SECAM-K1"  },
+	{ V4L2_STD_SECAM_L,	"SECAM-L"   },
+	{ V4L2_STD_SECAM_LC,	"SECAM-Lc"  },
+	{ 0,			"Unknown"   }
 };
 
 /* video4linux standard ID conversion to standard name
@@ -1202,6 +1202,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
 	case V4L2_PIX_FMT_SGBRG10P:	descr = "10-bit Bayer GBGB/RGRG Packed"; break;
 	case V4L2_PIX_FMT_SGRBG10P:	descr = "10-bit Bayer GRGR/BGBG Packed"; break;
 	case V4L2_PIX_FMT_SRGGB10P:	descr = "10-bit Bayer RGRG/GBGB Packed"; break;
+	case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break;
+	case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break;
+	case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break;
+	case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break;
 	case V4L2_PIX_FMT_SBGGR10ALAW8:	descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
 	case V4L2_PIX_FMT_SGBRG10ALAW8:	descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
 	case V4L2_PIX_FMT_SGRBG10ALAW8:	descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
@@ -1246,6 +1250,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
 	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;
 
 	default:
 		/* Compressed formats */
@@ -1311,52 +1316,50 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
 	struct v4l2_fmtdesc *p = arg;
-	struct video_device *vfd = video_devdata(file);
-	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
-	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
-	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
-	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
-	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
-	int ret = -EINVAL;
+	int ret = check_fmt(file, p->type);
+
+	if (ret)
+		return ret;
+	ret = -EINVAL;
 
 	switch (p->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_enum_fmt_vid_cap))
+		if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
 			break;
 		ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
 		break;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap_mplane))
+		if (unlikely(!ops->vidioc_enum_fmt_vid_cap_mplane))
 			break;
 		ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
 		break;
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_overlay))
+		if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
 			break;
 		ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
 		break;
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out))
+		if (unlikely(!ops->vidioc_enum_fmt_vid_out))
 			break;
 		ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
 		break;
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out_mplane))
+		if (unlikely(!ops->vidioc_enum_fmt_vid_out_mplane))
 			break;
 		ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
 		break;
 	case V4L2_BUF_TYPE_SDR_CAPTURE:
-		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_enum_fmt_sdr_cap))
+		if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
 			break;
 		ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
 		break;
 	case V4L2_BUF_TYPE_SDR_OUTPUT:
-		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_enum_fmt_sdr_out))
+		if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
 			break;
 		ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
 		break;
 	case V4L2_BUF_TYPE_META_CAPTURE:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_meta_cap))
+		if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
 			break;
 		ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
 		break;
@@ -1370,13 +1373,10 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
 	struct v4l2_format *p = arg;
-	struct video_device *vfd = video_devdata(file);
-	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
-	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
-	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
-	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
-	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
-	int ret;
+	int ret = check_fmt(file, p->type);
+
+	if (ret)
+		return ret;
 
 	/*
 	 * fmt can't be cleared for these overlay types due to the 'clips'
@@ -1404,7 +1404,7 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
 
 	switch (p->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_g_fmt_vid_cap))
+		if (unlikely(!ops->vidioc_g_fmt_vid_cap))
 			break;
 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
 		ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
@@ -1412,23 +1412,15 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
 		return ret;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane))
-			break;
 		return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg);
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_overlay))
-			break;
 		return ops->vidioc_g_fmt_vid_overlay(file, fh, arg);
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
-		if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_vbi_cap))
-			break;
 		return ops->vidioc_g_fmt_vbi_cap(file, fh, arg);
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-		if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_cap))
-			break;
 		return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg);
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out))
+		if (unlikely(!ops->vidioc_g_fmt_vid_out))
 			break;
 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
 		ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
@@ -1436,32 +1428,18 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
 		return ret;
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane))
-			break;
 		return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg);
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_overlay))
-			break;
 		return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg);
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
-		if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_vbi_out))
-			break;
 		return ops->vidioc_g_fmt_vbi_out(file, fh, arg);
 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-		if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out))
-			break;
 		return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
 	case V4L2_BUF_TYPE_SDR_CAPTURE:
-		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap))
-			break;
 		return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
 	case V4L2_BUF_TYPE_SDR_OUTPUT:
-		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_g_fmt_sdr_out))
-			break;
 		return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
 	case V4L2_BUF_TYPE_META_CAPTURE:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_meta_cap))
-			break;
 		return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
 	}
 	return -EINVAL;
@@ -1487,12 +1465,10 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
 {
 	struct v4l2_format *p = arg;
 	struct video_device *vfd = video_devdata(file);
-	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
-	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
-	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
-	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
-	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
-	int ret;
+	int ret = check_fmt(file, p->type);
+
+	if (ret)
+		return ret;
 
 	ret = v4l_enable_media_source(vfd);
 	if (ret)
@@ -1501,37 +1477,37 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
 
 	switch (p->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_s_fmt_vid_cap))
+		if (unlikely(!ops->vidioc_s_fmt_vid_cap))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.pix);
 		ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
 		/* just in case the driver zeroed it again */
 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
-		if (is_tch)
+		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(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane))
+		if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
 		return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_overlay))
+		if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.win);
 		return ops->vidioc_s_fmt_vid_overlay(file, fh, arg);
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
-		if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_vbi_cap))
+		if (unlikely(!ops->vidioc_s_fmt_vbi_cap))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.vbi);
 		return ops->vidioc_s_fmt_vbi_cap(file, fh, arg);
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-		if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_cap))
+		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.sliced);
 		return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg);
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out))
+		if (unlikely(!ops->vidioc_s_fmt_vid_out))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.pix);
 		ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
@@ -1539,37 +1515,37 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
 		return ret;
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane))
+		if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
 		return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_overlay))
+		if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.win);
 		return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg);
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
-		if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_vbi_out))
+		if (unlikely(!ops->vidioc_s_fmt_vbi_out))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.vbi);
 		return ops->vidioc_s_fmt_vbi_out(file, fh, arg);
 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-		if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_out))
+		if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.sliced);
 		return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg);
 	case V4L2_BUF_TYPE_SDR_CAPTURE:
-		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_s_fmt_sdr_cap))
+		if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.sdr);
 		return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
 	case V4L2_BUF_TYPE_SDR_OUTPUT:
-		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_s_fmt_sdr_out))
+		if (unlikely(!ops->vidioc_s_fmt_sdr_out))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.sdr);
 		return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
 	case V4L2_BUF_TYPE_META_CAPTURE:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_meta_cap))
+		if (unlikely(!ops->vidioc_s_fmt_meta_cap))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.meta);
 		return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
@@ -1581,19 +1557,16 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
 				struct file *file, void *fh, void *arg)
 {
 	struct v4l2_format *p = arg;
-	struct video_device *vfd = video_devdata(file);
-	bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
-	bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
-	bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
-	bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
-	bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
-	int ret;
+	int ret = check_fmt(file, p->type);
+
+	if (ret)
+		return ret;
 
 	v4l_sanitize_format(p);
 
 	switch (p->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-		if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_try_fmt_vid_cap))
+		if (unlikely(!ops->vidioc_try_fmt_vid_cap))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.pix);
 		ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
@@ -1601,27 +1574,27 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
 		return ret;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane))
+		if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
 		return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_overlay))
+		if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.win);
 		return ops->vidioc_try_fmt_vid_overlay(file, fh, arg);
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
-		if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_vbi_cap))
+		if (unlikely(!ops->vidioc_try_fmt_vbi_cap))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.vbi);
 		return ops->vidioc_try_fmt_vbi_cap(file, fh, arg);
 	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-		if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_cap))
+		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.sliced);
 		return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg);
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out))
+		if (unlikely(!ops->vidioc_try_fmt_vid_out))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.pix);
 		ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
@@ -1629,37 +1602,37 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
 		p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
 		return ret;
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane))
+		if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
 		return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-		if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_overlay))
+		if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.win);
 		return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg);
 	case V4L2_BUF_TYPE_VBI_OUTPUT:
-		if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_vbi_out))
+		if (unlikely(!ops->vidioc_try_fmt_vbi_out))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.vbi);
 		return ops->vidioc_try_fmt_vbi_out(file, fh, arg);
 	case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-		if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_out))
+		if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.sliced);
 		return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg);
 	case V4L2_BUF_TYPE_SDR_CAPTURE:
-		if (unlikely(!is_rx || !is_sdr || !ops->vidioc_try_fmt_sdr_cap))
+		if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.sdr);
 		return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
 	case V4L2_BUF_TYPE_SDR_OUTPUT:
-		if (unlikely(!is_tx || !is_sdr || !ops->vidioc_try_fmt_sdr_out))
+		if (unlikely(!ops->vidioc_try_fmt_sdr_out))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.sdr);
 		return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
 	case V4L2_BUF_TYPE_META_CAPTURE:
-		if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_meta_cap))
+		if (unlikely(!ops->vidioc_try_fmt_meta_cap))
 			break;
 		CLEAR_AFTER_FIELD(p, fmt.meta);
 		return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
@@ -2539,7 +2512,7 @@ struct v4l2_ioctl_info {
 #define INFO_FL_CLEAR(v4l2_struct, field)			\
 	((offsetof(struct v4l2_struct, field) +			\
 	  sizeof(((struct v4l2_struct *)0)->field)) << 16)
-#define INFO_FL_CLEAR_MASK 	(_IOC_SIZEMASK << 16)
+#define INFO_FL_CLEAR_MASK	(_IOC_SIZEMASK << 16)
 
 #define IOCTL_INFO_STD(_ioctl, _vidioc, _debug, _flags)			\
 	[_IOC_NR(_ioctl)] = {						\
@@ -2927,8 +2900,11 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
 
 	/* Handles IOCTL */
 	err = func(file, cmd, parg);
-	if (err == -ENOIOCTLCMD)
+	if (err == -ENOTTY || err == -ENOIOCTLCMD) {
 		err = -ENOTTY;
+		goto out;
+	}
+
 	if (err == 0) {
 		if (cmd == VIDIOC_DQBUF)
 			trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c
index 303980b..1d550af 100644
--- a/drivers/media/v4l2-core/v4l2-mc.c
+++ b/drivers/media/v4l2-core/v4l2-mc.c
@@ -25,8 +25,6 @@
 #include <media/v4l2-fh.h>
 #include <media/v4l2-mc.h>
 #include <media/v4l2-subdev.h>
-#include <media/media-device.h>
-#include <media/v4l2-mc.h>
 #include <media/videobuf2-core.h>
 
 int v4l2_mc_create_media_graph(struct media_device *mdev)
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index 1afa27d..fcb3a92 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -1258,20 +1258,6 @@ static struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = {
 	},
 };
 
-#define DEFINE_SHOW_ATTRIBUTE(__name)					      \
-static int __name ## _open(struct inode *inode, struct file *file)	      \
-{									      \
-	return single_open(file, __name ## _show, inode->i_private);	      \
-}									      \
-									      \
-static const struct file_operations __name ## _fops = {			      \
-	.owner		= THIS_MODULE,					      \
-	.open		= __name ## _open,				      \
-	.read		= seq_read,					      \
-	.llseek		= seq_lseek,					      \
-	.release	= single_release,				      \
-}									      \
-
 static irqreturn_t ab8500_debug_handler(int irq, void *data)
 {
 	char buf[16];
diff --git a/drivers/misc/mic/vop/vop_main.c b/drivers/misc/mic/vop/vop_main.c
index a341938..3633202 100644
--- a/drivers/misc/mic/vop/vop_main.c
+++ b/drivers/misc/mic/vop/vop_main.c
@@ -452,10 +452,12 @@ static irqreturn_t vop_virtio_intr_handler(int irq, void *data)
 
 static void vop_virtio_release_dev(struct device *_d)
 {
-	/*
-	 * No need for a release method similar to virtio PCI.
-	 * Provide an empty one to avoid getting a warning from core.
-	 */
+	struct virtio_device *vdev =
+			container_of(_d, struct virtio_device, dev);
+	struct _vop_vdev *vop_vdev =
+			container_of(vdev, struct _vop_vdev, vdev);
+
+	kfree(vop_vdev);
 }
 
 /*
@@ -466,7 +468,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
 			   unsigned int offset, struct vop_device *vpdev,
 			   int dnode)
 {
-	struct _vop_vdev *vdev;
+	struct _vop_vdev *vdev, *reg_dev = NULL;
 	int ret;
 	u8 type = ioread8(&d->type);
 
@@ -497,6 +499,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
 	vdev->c2h_vdev_db = ioread8(&vdev->dc->c2h_vdev_db);
 
 	ret = register_virtio_device(&vdev->vdev);
+	reg_dev = vdev;
 	if (ret) {
 		dev_err(_vop_dev(vdev),
 			"Failed to register vop device %u type %u\n",
@@ -512,7 +515,10 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
 free_irq:
 	vpdev->hw_ops->free_irq(vpdev, vdev->virtio_cookie, vdev);
 kfree:
-	kfree(vdev);
+	if (reg_dev)
+		put_device(&vdev->vdev.dev);
+	else
+		kfree(vdev);
 	return ret;
 }
 
@@ -568,7 +574,7 @@ static int _vop_remove_device(struct mic_device_desc __iomem *d,
 		iowrite8(-1, &dc->h2c_vdev_db);
 		if (status & VIRTIO_CONFIG_S_DRIVER_OK)
 			wait_for_completion(&vdev->reset_done);
-		kfree(vdev);
+		put_device(&vdev->vdev.dev);
 		iowrite8(1, &dc->guest_ack);
 		dev_dbg(&vpdev->dev, "%s %d guest_ack %d\n",
 			__func__, __LINE__, ioread8(&dc->guest_ack));
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 7a3ebfd..100adee 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -595,7 +595,7 @@ static void xgbe_isr_task(unsigned long data)
 
 		reissue_mask = 1 << 0;
 		if (!pdata->per_channel_irq)
-			reissue_mask |= 0xffff < 4;
+			reissue_mask |= 0xffff << 4;
 
 		XP_IOWRITE(pdata, XP_INT_REISSUE_EN, reissue_mask);
 	}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 3591077..ffa7959 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -812,7 +812,7 @@ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid)
 	if (!vf)
 		return false;
 
-	dev = pci_get_bus_and_slot(vf->bus, vf->devfn);
+	dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn);
 	if (dev)
 		return bnx2x_is_pcie_pending(dev);
 	return false;
@@ -1041,6 +1041,13 @@ void bnx2x_iov_init_dmae(struct bnx2x *bp)
 		REG_WR(bp, DMAE_REG_BACKWARD_COMP_EN, 0);
 }
 
+static int bnx2x_vf_domain(struct bnx2x *bp, int vfid)
+{
+	struct pci_dev *dev = bp->pdev;
+
+	return pci_domain_nr(dev->bus);
+}
+
 static int bnx2x_vf_bus(struct bnx2x *bp, int vfid)
 {
 	struct pci_dev *dev = bp->pdev;
@@ -1606,6 +1613,7 @@ int bnx2x_iov_nic_init(struct bnx2x *bp)
 		struct bnx2x_virtf *vf = BP_VF(bp, vfid);
 
 		/* fill in the BDF and bars */
+		vf->domain = bnx2x_vf_domain(bp, vfid);
 		vf->bus = bnx2x_vf_bus(bp, vfid);
 		vf->devfn = bnx2x_vf_devfn(bp, vfid);
 		bnx2x_vf_set_bars(bp, vf);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index 53466f6..eb814c6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -182,6 +182,7 @@ struct bnx2x_virtf {
 	u32 error;	/* 0 means all's-well */
 
 	/* BDF */
+	unsigned int domain;
 	unsigned int bus;
 	unsigned int devfn;
 
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 8984c49..382891f 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -248,6 +248,7 @@ struct be_tx_stats {
 	u32 tx_spoof_check_err;
 	u32 tx_qinq_err;
 	u32 tx_internal_parity_err;
+	u32 tx_sge_err;
 	struct u64_stats_sync sync;
 	struct u64_stats_sync sync_compl;
 };
@@ -944,8 +945,10 @@ static inline bool is_ipv6_ext_hdr(struct sk_buff *skb)
 #define BE_ERROR_EEH		1
 #define BE_ERROR_UE		BIT(1)
 #define BE_ERROR_FW		BIT(2)
-#define BE_ERROR_HW		(BE_ERROR_EEH | BE_ERROR_UE)
-#define BE_ERROR_ANY		(BE_ERROR_EEH | BE_ERROR_UE | BE_ERROR_FW)
+#define BE_ERROR_TX		BIT(3)
+#define BE_ERROR_HW		(BE_ERROR_EEH | BE_ERROR_UE | BE_ERROR_TX)
+#define BE_ERROR_ANY		(BE_ERROR_EEH | BE_ERROR_UE | BE_ERROR_FW | \
+				 BE_ERROR_TX)
 #define BE_CLEAR_ALL		0xFF
 
 static inline u8 be_check_error(struct be_adapter *adapter, u32 err_type)
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 7d1819c..7f7e206 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -189,6 +189,7 @@ static const struct be_ethtool_stat et_tx_stats[] = {
 	 * packet data. This counter is applicable only for Lancer adapters.
 	 */
 	{DRVSTAT_TX_INFO(tx_internal_parity_err)},
+	{DRVSTAT_TX_INFO(tx_sge_err)},
 	{DRVSTAT_TX_INFO(tx_bytes)},
 	{DRVSTAT_TX_INFO(tx_pkts)},
 	{DRVSTAT_TX_INFO(tx_vxlan_offload_pkts)},
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
index c967f45..db5f92f 100644
--- a/drivers/net/ethernet/emulex/benet/be_hw.h
+++ b/drivers/net/ethernet/emulex/benet/be_hw.h
@@ -261,6 +261,7 @@ struct be_eth_hdr_wrb {
 #define LANCER_TX_COMP_HSW_DROP_MAC_ERR		0x3
 #define LANCER_TX_COMP_HSW_DROP_VLAN_ERR	0x5
 #define LANCER_TX_COMP_QINQ_ERR			0x7
+#define LANCER_TX_COMP_SGE_ERR			0x9
 #define LANCER_TX_COMP_PARITY_ERR		0xb
 #define LANCER_TX_COMP_DMA_ERR			0xd
 
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index d81e2d3..5774fb6 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2583,7 +2583,48 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp, u32 frags_needed)
 	}
 }
 
-static struct be_tx_compl_info *be_tx_compl_get(struct be_tx_obj *txo)
+static inline void be_update_tx_err(struct be_tx_obj *txo, u8 status)
+{
+	switch (status) {
+	case BE_TX_COMP_HDR_PARSE_ERR:
+		tx_stats(txo)->tx_hdr_parse_err++;
+		break;
+	case BE_TX_COMP_NDMA_ERR:
+		tx_stats(txo)->tx_dma_err++;
+		break;
+	case BE_TX_COMP_ACL_ERR:
+		tx_stats(txo)->tx_spoof_check_err++;
+		break;
+	}
+}
+
+static inline void lancer_update_tx_err(struct be_tx_obj *txo, u8 status)
+{
+	switch (status) {
+	case LANCER_TX_COMP_LSO_ERR:
+		tx_stats(txo)->tx_tso_err++;
+		break;
+	case LANCER_TX_COMP_HSW_DROP_MAC_ERR:
+	case LANCER_TX_COMP_HSW_DROP_VLAN_ERR:
+		tx_stats(txo)->tx_spoof_check_err++;
+		break;
+	case LANCER_TX_COMP_QINQ_ERR:
+		tx_stats(txo)->tx_qinq_err++;
+		break;
+	case LANCER_TX_COMP_PARITY_ERR:
+		tx_stats(txo)->tx_internal_parity_err++;
+		break;
+	case LANCER_TX_COMP_DMA_ERR:
+		tx_stats(txo)->tx_dma_err++;
+		break;
+	case LANCER_TX_COMP_SGE_ERR:
+		tx_stats(txo)->tx_sge_err++;
+		break;
+	}
+}
+
+static struct be_tx_compl_info *be_tx_compl_get(struct be_adapter *adapter,
+						struct be_tx_obj *txo)
 {
 	struct be_queue_info *tx_cq = &txo->cq;
 	struct be_tx_compl_info *txcp = &txo->txcp;
@@ -2599,6 +2640,24 @@ static struct be_tx_compl_info *be_tx_compl_get(struct be_tx_obj *txo)
 	txcp->status = GET_TX_COMPL_BITS(status, compl);
 	txcp->end_index = GET_TX_COMPL_BITS(wrb_index, compl);
 
+	if (txcp->status) {
+		if (lancer_chip(adapter)) {
+			lancer_update_tx_err(txo, txcp->status);
+			/* Reset the adapter incase of TSO,
+			 * SGE or Parity error
+			 */
+			if (txcp->status == LANCER_TX_COMP_LSO_ERR ||
+			    txcp->status == LANCER_TX_COMP_PARITY_ERR ||
+			    txcp->status == LANCER_TX_COMP_SGE_ERR)
+				be_set_error(adapter, BE_ERROR_TX);
+		} else {
+			be_update_tx_err(txo, txcp->status);
+		}
+	}
+
+	if (be_check_error(adapter, BE_ERROR_TX))
+		return NULL;
+
 	compl->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0;
 	queue_tail_inc(tx_cq);
 	return txcp;
@@ -2741,7 +2800,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
 			cmpl = 0;
 			num_wrbs = 0;
 			txq = &txo->q;
-			while ((txcp = be_tx_compl_get(txo))) {
+			while ((txcp = be_tx_compl_get(adapter, txo))) {
 				num_wrbs +=
 					be_tx_compl_process(adapter, txo,
 							    txcp->end_index);
@@ -3120,42 +3179,6 @@ static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
 	return work_done;
 }
 
-static inline void be_update_tx_err(struct be_tx_obj *txo, u8 status)
-{
-	switch (status) {
-	case BE_TX_COMP_HDR_PARSE_ERR:
-		tx_stats(txo)->tx_hdr_parse_err++;
-		break;
-	case BE_TX_COMP_NDMA_ERR:
-		tx_stats(txo)->tx_dma_err++;
-		break;
-	case BE_TX_COMP_ACL_ERR:
-		tx_stats(txo)->tx_spoof_check_err++;
-		break;
-	}
-}
-
-static inline void lancer_update_tx_err(struct be_tx_obj *txo, u8 status)
-{
-	switch (status) {
-	case LANCER_TX_COMP_LSO_ERR:
-		tx_stats(txo)->tx_tso_err++;
-		break;
-	case LANCER_TX_COMP_HSW_DROP_MAC_ERR:
-	case LANCER_TX_COMP_HSW_DROP_VLAN_ERR:
-		tx_stats(txo)->tx_spoof_check_err++;
-		break;
-	case LANCER_TX_COMP_QINQ_ERR:
-		tx_stats(txo)->tx_qinq_err++;
-		break;
-	case LANCER_TX_COMP_PARITY_ERR:
-		tx_stats(txo)->tx_internal_parity_err++;
-		break;
-	case LANCER_TX_COMP_DMA_ERR:
-		tx_stats(txo)->tx_dma_err++;
-		break;
-	}
-}
 
 static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
 			  int idx)
@@ -3163,16 +3186,9 @@ static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
 	int num_wrbs = 0, work_done = 0;
 	struct be_tx_compl_info *txcp;
 
-	while ((txcp = be_tx_compl_get(txo))) {
+	while ((txcp = be_tx_compl_get(adapter, txo))) {
 		num_wrbs += be_tx_compl_process(adapter, txo, txcp->end_index);
 		work_done++;
-
-		if (txcp->status) {
-			if (lancer_chip(adapter))
-				lancer_update_tx_err(txo, txcp->status);
-			else
-				be_update_tx_err(txo, txcp->status);
-		}
 	}
 
 	if (work_done) {
@@ -5104,9 +5120,12 @@ static netdev_features_t be_features_check(struct sk_buff *skb,
 			features &= ~NETIF_F_TSO6;
 
 		/* Lancer cannot handle the packet with MSS less than 256.
+		 * Also it can't handle a TSO packet with a single segment
 		 * Disable the GSO support in such cases
 		 */
-		if (lancer_chip(adapter) && skb_shinfo(skb)->gso_size < 256)
+		if (lancer_chip(adapter) &&
+		    (skb_shinfo(skb)->gso_size < 256 ||
+		     skb_shinfo(skb)->gso_segs == 1))
 			features &= ~NETIF_F_GSO_MASK;
 	}
 
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
index 7d95f08..28a81ac 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
@@ -143,7 +143,7 @@ int hinic_alloc_cmdq_buf(struct hinic_cmdqs *cmdqs,
 	struct hinic_hwif *hwif = cmdqs->hwif;
 	struct pci_dev *pdev = hwif->pdev;
 
-	cmdq_buf->buf = pci_pool_alloc(cmdqs->cmdq_buf_pool, GFP_KERNEL,
+	cmdq_buf->buf = dma_pool_alloc(cmdqs->cmdq_buf_pool, GFP_KERNEL,
 				       &cmdq_buf->dma_addr);
 	if (!cmdq_buf->buf) {
 		dev_err(&pdev->dev, "Failed to allocate cmd from the pool\n");
@@ -161,7 +161,7 @@ int hinic_alloc_cmdq_buf(struct hinic_cmdqs *cmdqs,
 void hinic_free_cmdq_buf(struct hinic_cmdqs *cmdqs,
 			 struct hinic_cmdq_buf *cmdq_buf)
 {
-	pci_pool_free(cmdqs->cmdq_buf_pool, cmdq_buf->buf, cmdq_buf->dma_addr);
+	dma_pool_free(cmdqs->cmdq_buf_pool, cmdq_buf->buf, cmdq_buf->dma_addr);
 }
 
 static unsigned int cmdq_wqe_size_from_bdlen(enum bufdesc_len len)
@@ -875,7 +875,7 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
 	int err;
 
 	cmdqs->hwif = hwif;
-	cmdqs->cmdq_buf_pool = pci_pool_create("hinic_cmdq", pdev,
+	cmdqs->cmdq_buf_pool = dma_pool_create("hinic_cmdq", &pdev->dev,
 					       HINIC_CMDQ_BUF_SIZE,
 					       HINIC_CMDQ_BUF_SIZE, 0);
 	if (!cmdqs->cmdq_buf_pool)
@@ -916,7 +916,7 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
 	devm_kfree(&pdev->dev, cmdqs->saved_wqs);
 
 err_saved_wqs:
-	pci_pool_destroy(cmdqs->cmdq_buf_pool);
+	dma_pool_destroy(cmdqs->cmdq_buf_pool);
 	return err;
 }
 
@@ -942,5 +942,5 @@ void hinic_free_cmdqs(struct hinic_cmdqs *cmdqs)
 
 	devm_kfree(&pdev->dev, cmdqs->saved_wqs);
 
-	pci_pool_destroy(cmdqs->cmdq_buf_pool);
+	dma_pool_destroy(cmdqs->cmdq_buf_pool);
 }
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
index b355834..23f8d39e 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
@@ -157,7 +157,7 @@ struct hinic_cmdq {
 struct hinic_cmdqs {
 	struct hinic_hwif       *hwif;
 
-	struct pci_pool         *cmdq_buf_pool;
+	struct dma_pool         *cmdq_buf_pool;
 
 	struct hinic_wq         *saved_wqs;
 
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 5caaa90..afaf29b 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -3286,7 +3286,7 @@ static void handle_vpd_rsp(union ibmvnic_crq *crq,
 			   struct ibmvnic_adapter *adapter)
 {
 	struct device *dev = &adapter->vdev->dev;
-	unsigned char *substr = NULL, *ptr = NULL;
+	unsigned char *substr = NULL;
 	u8 fw_level_len = 0;
 
 	memset(adapter->fw_version, 0, 32);
@@ -3306,10 +3306,6 @@ static void handle_vpd_rsp(union ibmvnic_crq *crq,
 	substr = strnstr(adapter->vpd->buff, "RM", adapter->vpd->len);
 	if (!substr) {
 		dev_info(dev, "Warning - No FW level has been provided in the VPD buffer by the VIOS Server\n");
-		ptr = strncpy((char *)adapter->fw_version, "N/A",
-			      3 * sizeof(char));
-		if (!ptr)
-			dev_err(dev, "Failed to inform that firmware version is unavailable to the adapter\n");
 		goto complete;
 	}
 
@@ -3324,16 +3320,14 @@ static void handle_vpd_rsp(union ibmvnic_crq *crq,
 	/* copy firmware version string from vpd into adapter */
 	if ((substr + 3 + fw_level_len) <
 	    (adapter->vpd->buff + adapter->vpd->len)) {
-		ptr = strncpy((char *)adapter->fw_version,
-			      substr + 3, fw_level_len);
-
-		if (!ptr)
-			dev_err(dev, "Failed to isolate FW level string\n");
+		strncpy((char *)adapter->fw_version, substr + 3, fw_level_len);
 	} else {
 		dev_info(dev, "FW substr extrapolated VPD buff\n");
 	}
 
 complete:
+	if (adapter->fw_version[0] == '\0')
+		strncpy((char *)adapter->fw_version, "N/A", 3 * sizeof(char));
 	complete(&adapter->fw_done);
 }
 
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
index 44b3937..2948647 100644
--- a/drivers/net/ethernet/intel/e100.c
+++ b/drivers/net/ethernet/intel/e100.c
@@ -607,7 +607,7 @@ struct nic {
 	struct mem *mem;
 	dma_addr_t dma_addr;
 
-	struct pci_pool *cbs_pool;
+	struct dma_pool *cbs_pool;
 	dma_addr_t cbs_dma_addr;
 	u8 adaptive_ifs;
 	u8 tx_threshold;
@@ -1892,7 +1892,7 @@ static void e100_clean_cbs(struct nic *nic)
 			nic->cb_to_clean = nic->cb_to_clean->next;
 			nic->cbs_avail++;
 		}
-		pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr);
+		dma_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr);
 		nic->cbs = NULL;
 		nic->cbs_avail = 0;
 	}
@@ -1910,7 +1910,7 @@ static int e100_alloc_cbs(struct nic *nic)
 	nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL;
 	nic->cbs_avail = 0;
 
-	nic->cbs = pci_pool_zalloc(nic->cbs_pool, GFP_KERNEL,
+	nic->cbs = dma_pool_zalloc(nic->cbs_pool, GFP_KERNEL,
 				   &nic->cbs_dma_addr);
 	if (!nic->cbs)
 		return -ENOMEM;
@@ -2960,8 +2960,8 @@ static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		netif_err(nic, probe, nic->netdev, "Cannot register net device, aborting\n");
 		goto err_out_free;
 	}
-	nic->cbs_pool = pci_pool_create(netdev->name,
-			   nic->pdev,
+	nic->cbs_pool = dma_pool_create(netdev->name,
+			   &nic->pdev->dev,
 			   nic->params.cbs.max * sizeof(struct cb),
 			   sizeof(u32),
 			   0);
@@ -3001,7 +3001,7 @@ static void e100_remove(struct pci_dev *pdev)
 		unregister_netdev(netdev);
 		e100_free(nic);
 		pci_iounmap(pdev, nic->csr);
-		pci_pool_destroy(nic->cbs_pool);
+		dma_pool_destroy(nic->cbs_pool);
 		free_netdev(netdev);
 		pci_release_regions(pdev);
 		pci_disable_device(pdev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index 05c1157..25106e9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -51,7 +51,7 @@ enum {
 
 enum {
 	MLX5_NUM_SPARE_EQE	= 0x80,
-	MLX5_NUM_ASYNC_EQE	= 0x100,
+	MLX5_NUM_ASYNC_EQE	= 0x1000,
 	MLX5_NUM_CMD_EQE	= 32,
 	MLX5_NUM_PF_DRAIN	= 64,
 };
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h
index 424fe83..054df3d 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.h
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h
@@ -112,22 +112,22 @@ enum pkt_vec {
  * @map_elems_in_use:	number of elements allocated to offloaded maps
  *
  * @adjust_head:	adjust head capability
- * @flags:		extra flags for adjust head
- * @off_min:		minimal packet offset within buffer required
- * @off_max:		maximum packet offset within buffer required
- * @guaranteed_sub:	amount of negative adjustment guaranteed possible
- * @guaranteed_add:	amount of positive adjustment guaranteed possible
+ * @adjust_head.flags:		extra flags for adjust head
+ * @adjust_head.off_min:	minimal packet offset within buffer required
+ * @adjust_head.off_max:	maximum packet offset within buffer required
+ * @adjust_head.guaranteed_sub:	negative adjustment guaranteed possible
+ * @adjust_head.guaranteed_add:	positive adjustment guaranteed possible
  *
  * @maps:		map capability
- * @types:		supported map types
- * @max_maps:		max number of maps supported
- * @max_elems:		max number of entries in each map
- * @max_key_sz:		max size of map key
- * @max_val_sz:		max size of map value
- * @max_elem_sz:	max size of map entry (key + value)
+ * @maps.types:			supported map types
+ * @maps.max_maps:		max number of maps supported
+ * @maps.max_elems:		max number of entries in each map
+ * @maps.max_key_sz:		max size of map key
+ * @maps.max_val_sz:		max size of map value
+ * @maps.max_elem_sz:		max size of map entry (key + value)
  *
  * @helpers:		helper addressess for various calls
- * @map_lookup:		map lookup helper address
+ * @helpers.map_lookup:		map lookup helper address
  */
 struct nfp_app_bpf {
 	struct nfp_app *app;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
index b03f22f..ec524d9 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
@@ -50,9 +50,9 @@
  * @seq:		sequence number of the message
  * @count:		number of tunnels report in message
  * @flags:		options part of the request
- * @ipv4:		dest IPv4 address of active route
- * @egress_port:	port the encapsulated packet egressed
- * @extra:		reserved for future use
+ * @tun_info.ipv4:		dest IPv4 address of active route
+ * @tun_info.egress_port:	port the encapsulated packet egressed
+ * @tun_info.extra:		reserved for future use
  * @tun_info:		tunnels that have sent traffic in reported period
  */
 struct nfp_tun_active_tuns {
@@ -132,8 +132,8 @@ struct nfp_ipv4_addr_entry {
  * struct nfp_tun_mac_addr - configure MAC address of tunnel EP on NFP
  * @reserved:	reserved for future use
  * @count:	number of MAC addresses in the message
- * @index:	index of MAC address in the lookup table
- * @addr:	interface MAC address
+ * @addresses.index:	index of MAC address in the lookup table
+ * @addresses.addr:	interface MAC address
  * @addresses:	series of MACs to offload
  */
 struct nfp_tun_mac_addr {
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index d88eda9..787df47 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -193,7 +193,8 @@ struct nfp_net_tx_desc {
 
 /**
  * struct nfp_net_tx_buf - software TX buffer descriptor
- * @skb:	sk_buff associated with this buffer
+ * @skb:	normal ring, sk_buff associated with this buffer
+ * @frag:	XDP ring, page frag associated with this buffer
  * @dma_addr:	DMA mapping address of the buffer
  * @fidx:	Fragment index (-1 for the head and [0..nr_frags-1] for frags)
  * @pkt_cnt:	Number of packets to be produced out of the skb associated
@@ -377,6 +378,9 @@ struct nfp_net_rx_ring {
  * struct nfp_net_r_vector - Per ring interrupt vector configuration
  * @nfp_net:        Backpointer to nfp_net structure
  * @napi:           NAPI structure for this ring vec
+ * @tasklet:        ctrl vNIC, tasklet for servicing the r_vec
+ * @queue:          ctrl vNIC, send queue
+ * @lock:           ctrl vNIC, r_vec lock protects @queue
  * @tx_ring:        Pointer to TX ring
  * @rx_ring:        Pointer to RX ring
  * @xdp_ring:	    Pointer to an extra TX ring for XDP
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
index e983c9d..f23d9e0 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
@@ -98,28 +98,29 @@ enum nfp_eth_fec {
  * @max_index:	max of @index fields of all @ports
  * @ports:	table of ports
  *
- * @eth_index:	port index according to legacy ethX numbering
- * @index:	chip-wide first channel index
- * @nbi:	NBI index
- * @base:	first channel index (within NBI)
- * @lanes:	number of channels
- * @speed:	interface speed (in Mbps)
- * @interface:	interface (module) plugged in
- * @media:	media type of the @interface
- * @fec:	forward error correction mode
- * @aneg:	auto negotiation mode
- * @mac_addr:	interface MAC address
- * @label_port:	port id
- * @label_subport:  id of interface within port (for split ports)
- * @enabled:	is enabled?
- * @tx_enabled:	is TX enabled?
- * @rx_enabled:	is RX enabled?
- * @override_changed: is media reconfig pending?
+ * @ports.eth_index:	port index according to legacy ethX numbering
+ * @ports.index:	chip-wide first channel index
+ * @ports.nbi:		NBI index
+ * @ports.base:		first channel index (within NBI)
+ * @ports.lanes:	number of channels
+ * @ports.speed:	interface speed (in Mbps)
+ * @ports.interface:	interface (module) plugged in
+ * @ports.media:	media type of the @interface
+ * @ports.fec:		forward error correction mode
+ * @ports.aneg:		auto negotiation mode
+ * @ports.mac_addr:	interface MAC address
+ * @ports.label_port:	port id
+ * @ports.label_subport:  id of interface within port (for split ports)
+ * @ports.enabled:	is enabled?
+ * @ports.tx_enabled:	is TX enabled?
+ * @ports.rx_enabled:	is RX enabled?
+ * @ports.override_changed: is media reconfig pending?
  *
- * @port_type:	one of %PORT_* defines for ethtool
- * @port_lanes:	total number of lanes on the port (sum of lanes of all subports)
- * @is_split:	is interface part of a split port
- * @fec_modes_supported:	bitmap of FEC modes supported
+ * @ports.port_type:	one of %PORT_* defines for ethtool
+ * @ports.port_lanes:	total number of lanes on the port (sum of lanes of all
+ *			subports)
+ * @ports.is_split:	is interface part of a split port
+ * @ports.fec_modes_supported:	bitmap of FEC modes supported
  */
 struct nfp_eth_table {
 	unsigned int count;
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
index b1dd13f..7e14725 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
@@ -56,16 +56,17 @@
 
 /**
  * struct nfp_resource_entry - Resource table entry
- * @owner:		NFP CPP Lock, interface owner
- * @key:		NFP CPP Lock, posix_crc32(name, 8)
- * @region:		Memory region descriptor
- * @name:		ASCII, zero padded name
- * @reserved
- * @cpp_action:		CPP Action
- * @cpp_token:		CPP Token
- * @cpp_target:		CPP Target ID
- * @page_offset:	256-byte page offset into target's CPP address
- * @page_size:		size, in 256-byte pages
+ * @mutex:	NFP CPP Lock
+ * @mutex.owner:	NFP CPP Lock, interface owner
+ * @mutex.key:		NFP CPP Lock, posix_crc32(name, 8)
+ * @region:	Memory region descriptor
+ * @region.name:	ASCII, zero padded name
+ * @region.reserved:	padding
+ * @region.cpp_action:	CPP Action
+ * @region.cpp_token:	CPP Token
+ * @region.cpp_target:	CPP Target ID
+ * @region.page_offset:	256-byte page offset into target's CPP address
+ * @region.page_size:	size, in 256-byte pages
  */
 struct nfp_resource_entry {
 	struct nfp_resource_entry_mutex {
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 40e52ff..7cd4946 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -2594,8 +2594,10 @@ static int pch_gbe_probe(struct pci_dev *pdev,
 	if (adapter->pdata && adapter->pdata->platform_init)
 		adapter->pdata->platform_init(pdev);
 
-	adapter->ptp_pdev = pci_get_bus_and_slot(adapter->pdev->bus->number,
-					       PCI_DEVFN(12, 4));
+	adapter->ptp_pdev =
+		pci_get_domain_bus_and_slot(pci_domain_nr(adapter->pdev->bus),
+					    adapter->pdev->bus->number,
+					    PCI_DEVFN(12, 4));
 
 	netdev->netdev_ops = &pch_gbe_netdev_ops;
 	netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD;
diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c
index 0624b71..edcd1e6 100644
--- a/drivers/net/ethernet/tundra/tsi108_eth.c
+++ b/drivers/net/ethernet/tundra/tsi108_eth.c
@@ -152,6 +152,8 @@ struct tsi108_prv_data {
 	u32 msg_enable;			/* debug message level */
 	struct mii_if_info mii_if;
 	unsigned int init_media;
+
+	struct platform_device *pdev;
 };
 
 /* Structure for a device driver */
@@ -703,17 +705,18 @@ static int tsi108_send_packet(struct sk_buff * skb, struct net_device *dev)
 		data->txskbs[tx] = skb;
 
 		if (i == 0) {
-			data->txring[tx].buf0 = dma_map_single(NULL, skb->data,
-					skb_headlen(skb), DMA_TO_DEVICE);
+			data->txring[tx].buf0 = dma_map_single(&data->pdev->dev,
+					skb->data, skb_headlen(skb),
+					DMA_TO_DEVICE);
 			data->txring[tx].len = skb_headlen(skb);
 			misc |= TSI108_TX_SOF;
 		} else {
 			const skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
 
-			data->txring[tx].buf0 = skb_frag_dma_map(NULL, frag,
-								 0,
-								 skb_frag_size(frag),
-								 DMA_TO_DEVICE);
+			data->txring[tx].buf0 =
+				skb_frag_dma_map(&data->pdev->dev, frag,
+						0, skb_frag_size(frag),
+						DMA_TO_DEVICE);
 			data->txring[tx].len = skb_frag_size(frag);
 		}
 
@@ -808,9 +811,9 @@ static int tsi108_refill_rx(struct net_device *dev, int budget)
 		if (!skb)
 			break;
 
-		data->rxring[rx].buf0 = dma_map_single(NULL, skb->data,
-							TSI108_RX_SKB_SIZE,
-							DMA_FROM_DEVICE);
+		data->rxring[rx].buf0 = dma_map_single(&data->pdev->dev,
+				skb->data, TSI108_RX_SKB_SIZE,
+				DMA_FROM_DEVICE);
 
 		/* Sometimes the hardware sets blen to zero after packet
 		 * reception, even though the manual says that it's only ever
@@ -1308,15 +1311,15 @@ static int tsi108_open(struct net_device *dev)
 		       data->id, dev->irq, dev->name);
 	}
 
-	data->rxring = dma_zalloc_coherent(NULL, rxring_size, &data->rxdma,
-					   GFP_KERNEL);
+	data->rxring = dma_zalloc_coherent(&data->pdev->dev, rxring_size,
+			&data->rxdma, GFP_KERNEL);
 	if (!data->rxring)
 		return -ENOMEM;
 
-	data->txring = dma_zalloc_coherent(NULL, txring_size, &data->txdma,
-					   GFP_KERNEL);
+	data->txring = dma_zalloc_coherent(&data->pdev->dev, txring_size,
+			&data->txdma, GFP_KERNEL);
 	if (!data->txring) {
-		pci_free_consistent(NULL, rxring_size, data->rxring,
+		dma_free_coherent(&data->pdev->dev, rxring_size, data->rxring,
 				    data->rxdma);
 		return -ENOMEM;
 	}
@@ -1428,10 +1431,10 @@ static int tsi108_close(struct net_device *dev)
 		dev_kfree_skb(skb);
 	}
 
-	dma_free_coherent(0,
+	dma_free_coherent(&data->pdev->dev,
 			    TSI108_RXRING_LEN * sizeof(rx_desc),
 			    data->rxring, data->rxdma);
-	dma_free_coherent(0,
+	dma_free_coherent(&data->pdev->dev,
 			    TSI108_TXRING_LEN * sizeof(tx_desc),
 			    data->txring, data->txdma);
 
@@ -1576,6 +1579,7 @@ tsi108_init_one(struct platform_device *pdev)
 	printk("tsi108_eth%d: probe...\n", pdev->id);
 	data = netdev_priv(dev);
 	data->dev = dev;
+	data->pdev = pdev;
 
 	pr_debug("tsi108_eth%d:regs:phyresgs:phy:irq_num=0x%x:0x%x:0x%x:0x%x\n",
 			pdev->id, einfo->regs, einfo->phyregs,
diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c
index de73c1f..75c2530 100644
--- a/drivers/net/netdevsim/bpf.c
+++ b/drivers/net/netdevsim/bpf.c
@@ -480,8 +480,7 @@ static int
 nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)
 {
 	struct nsim_bpf_bound_map *nmap;
-	unsigned int i;
-	int err;
+	int i, err;
 
 	if (WARN_ON(offmap->map.map_type != BPF_MAP_TYPE_ARRAY &&
 		    offmap->map.map_type != BPF_MAP_TYPE_HASH))
@@ -518,7 +517,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)
 	return 0;
 
 err_free:
-	while (--i) {
+	while (--i >= 0) {
 		kfree(nmap->entry[i].key);
 		kfree(nmap->entry[i].value);
 	}
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 88272b3..24b5511 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -56,7 +56,8 @@ static int mdiobus_register_gpiod(struct mdio_device *mdiodev)
 		gpiod = fwnode_get_named_gpiod(&mdiodev->dev.of_node->fwnode,
 					       "reset-gpios", 0, GPIOD_OUT_LOW,
 					       "PHY reset");
-	if (PTR_ERR(gpiod) == -ENOENT)
+	if (PTR_ERR(gpiod) == -ENOENT ||
+	    PTR_ERR(gpiod) == -ENOSYS)
 		gpiod = NULL;
 	else if (IS_ERR(gpiod))
 		return PTR_ERR(gpiod);
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index c586bcd..2ef544f1 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -753,6 +753,7 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size,
 		return NULL;
 	arena->nd_btt = btt->nd_btt;
 	arena->sector_size = btt->sector_size;
+	mutex_init(&arena->err_lock);
 
 	if (!size)
 		return arena;
@@ -891,7 +892,6 @@ static int discover_arenas(struct btt *btt)
 			goto out;
 		}
 
-		mutex_init(&arena->err_lock);
 		ret = btt_freelist_init(arena);
 		if (ret)
 			goto out;
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index 0a5e6cd..78eabc3 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -1142,9 +1142,6 @@ int __init nvdimm_bus_init(void)
 {
 	int rc;
 
-	BUILD_BUG_ON(sizeof(struct nd_smart_payload) != 128);
-	BUILD_BUG_ON(sizeof(struct nd_smart_threshold_payload) != 8);
-
 	rc = bus_register(&nvdimm_bus_type);
 	if (rc)
 		return rc;
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index bb3ba8c..658ada4 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -2408,7 +2408,7 @@ static struct device **scan_labels(struct nd_region *nd_region)
 
 static struct device **create_namespaces(struct nd_region *nd_region)
 {
-	struct nd_mapping *nd_mapping = &nd_region->mapping[0];
+	struct nd_mapping *nd_mapping;
 	struct device **devs;
 	int i;
 
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index e958f37..8d6375e 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -368,15 +368,14 @@ unsigned int pmem_sector_size(struct nd_namespace_common *ndns);
 void nvdimm_badblocks_populate(struct nd_region *nd_region,
 		struct badblocks *bb, const struct resource *res);
 #if IS_ENABLED(CONFIG_ND_CLAIM)
-struct vmem_altmap *nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
-		struct resource *res, struct vmem_altmap *altmap);
+int nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap);
 int devm_nsio_enable(struct device *dev, struct nd_namespace_io *nsio);
 void devm_nsio_disable(struct device *dev, struct nd_namespace_io *nsio);
 #else
-static inline struct vmem_altmap *nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
-		struct resource *res, struct vmem_altmap *altmap)
+static inline int nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
+				   struct dev_pagemap *pgmap)
 {
-	return ERR_PTR(-ENXIO);
+	return -ENXIO;
 }
 static inline int devm_nsio_enable(struct device *dev,
 		struct nd_namespace_io *nsio)
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index 2adada1..f5c4e8c 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -542,9 +542,10 @@ static unsigned long init_altmap_reserve(resource_size_t base)
 	return reserve;
 }
 
-static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
-		struct resource *res, struct vmem_altmap *altmap)
+static int __nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap)
 {
+	struct resource *res = &pgmap->res;
+	struct vmem_altmap *altmap = &pgmap->altmap;
 	struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
 	u64 offset = le64_to_cpu(pfn_sb->dataoff);
 	u32 start_pad = __le32_to_cpu(pfn_sb->start_pad);
@@ -561,11 +562,13 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
 	res->start += start_pad;
 	res->end -= end_trunc;
 
+	pgmap->type = MEMORY_DEVICE_HOST;
+
 	if (nd_pfn->mode == PFN_MODE_RAM) {
 		if (offset < SZ_8K)
-			return ERR_PTR(-EINVAL);
+			return -EINVAL;
 		nd_pfn->npfns = le64_to_cpu(pfn_sb->npfns);
-		altmap = NULL;
+		pgmap->altmap_valid = false;
 	} else if (nd_pfn->mode == PFN_MODE_PMEM) {
 		nd_pfn->npfns = PFN_SECTION_ALIGN_UP((resource_size(res)
 					- offset) / PAGE_SIZE);
@@ -577,10 +580,11 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
 		memcpy(altmap, &__altmap, sizeof(*altmap));
 		altmap->free = PHYS_PFN(offset - SZ_8K);
 		altmap->alloc = 0;
+		pgmap->altmap_valid = true;
 	} else
-		return ERR_PTR(-ENXIO);
+		return -ENXIO;
 
-	return altmap;
+	return 0;
 }
 
 static u64 phys_pmem_align_down(struct nd_pfn *nd_pfn, u64 phys)
@@ -708,19 +712,18 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
  * Determine the effective resource range and vmem_altmap from an nd_pfn
  * instance.
  */
-struct vmem_altmap *nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
-		struct resource *res, struct vmem_altmap *altmap)
+int nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap)
 {
 	int rc;
 
 	if (!nd_pfn->uuid || !nd_pfn->ndns)
-		return ERR_PTR(-ENODEV);
+		return -ENODEV;
 
 	rc = nd_pfn_init(nd_pfn);
 	if (rc)
-		return ERR_PTR(rc);
+		return rc;
 
-	/* we need a valid pfn_sb before we can init a vmem_altmap */
-	return __nvdimm_setup_pfn(nd_pfn, res, altmap);
+	/* we need a valid pfn_sb before we can init a dev_pagemap */
+	return __nvdimm_setup_pfn(nd_pfn, pgmap);
 }
 EXPORT_SYMBOL_GPL(nvdimm_setup_pfn);
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 7fbc5c5..10041ac 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -35,6 +35,7 @@
 #include "pmem.h"
 #include "pfn.h"
 #include "nd.h"
+#include "nd-core.h"
 
 static struct device *to_dev(struct pmem_device *pmem)
 {
@@ -298,34 +299,34 @@ static int pmem_attach_disk(struct device *dev,
 {
 	struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
 	struct nd_region *nd_region = to_nd_region(dev->parent);
-	struct vmem_altmap __altmap, *altmap = NULL;
 	int nid = dev_to_node(dev), fua, wbc;
 	struct resource *res = &nsio->res;
+	struct resource bb_res;
 	struct nd_pfn *nd_pfn = NULL;
 	struct dax_device *dax_dev;
 	struct nd_pfn_sb *pfn_sb;
 	struct pmem_device *pmem;
-	struct resource pfn_res;
 	struct request_queue *q;
 	struct device *gendev;
 	struct gendisk *disk;
 	void *addr;
-
-	/* while nsio_rw_bytes is active, parse a pfn info block if present */
-	if (is_nd_pfn(dev)) {
-		nd_pfn = to_nd_pfn(dev);
-		altmap = nvdimm_setup_pfn(nd_pfn, &pfn_res, &__altmap);
-		if (IS_ERR(altmap))
-			return PTR_ERR(altmap);
-	}
-
-	/* we're attaching a block device, disable raw namespace access */
-	devm_nsio_disable(dev, nsio);
+	int rc;
 
 	pmem = devm_kzalloc(dev, sizeof(*pmem), GFP_KERNEL);
 	if (!pmem)
 		return -ENOMEM;
 
+	/* while nsio_rw_bytes is active, parse a pfn info block if present */
+	if (is_nd_pfn(dev)) {
+		nd_pfn = to_nd_pfn(dev);
+		rc = nvdimm_setup_pfn(nd_pfn, &pmem->pgmap);
+		if (rc)
+			return rc;
+	}
+
+	/* we're attaching a block device, disable raw namespace access */
+	devm_nsio_disable(dev, nsio);
+
 	dev_set_drvdata(dev, pmem);
 	pmem->phys_addr = res->start;
 	pmem->size = resource_size(res);
@@ -334,7 +335,8 @@ static int pmem_attach_disk(struct device *dev,
 		dev_warn(dev, "unable to guarantee persistence of writes\n");
 		fua = 0;
 	}
-	wbc = nvdimm_has_cache(nd_region);
+	wbc = nvdimm_has_cache(nd_region) &&
+		!test_bit(ND_REGION_PERSIST_CACHE, &nd_region->flags);
 
 	if (!devm_request_mem_region(dev, res->start, resource_size(res),
 				dev_name(&ndns->dev))) {
@@ -350,19 +352,22 @@ static int pmem_attach_disk(struct device *dev,
 		return -ENOMEM;
 
 	pmem->pfn_flags = PFN_DEV;
+	pmem->pgmap.ref = &q->q_usage_counter;
 	if (is_nd_pfn(dev)) {
-		addr = devm_memremap_pages(dev, &pfn_res, &q->q_usage_counter,
-				altmap);
+		addr = devm_memremap_pages(dev, &pmem->pgmap);
 		pfn_sb = nd_pfn->pfn_sb;
 		pmem->data_offset = le64_to_cpu(pfn_sb->dataoff);
-		pmem->pfn_pad = resource_size(res) - resource_size(&pfn_res);
+		pmem->pfn_pad = resource_size(res) -
+			resource_size(&pmem->pgmap.res);
 		pmem->pfn_flags |= PFN_MAP;
-		res = &pfn_res; /* for badblocks populate */
-		res->start += pmem->data_offset;
+		memcpy(&bb_res, &pmem->pgmap.res, sizeof(bb_res));
+		bb_res.start += pmem->data_offset;
 	} else if (pmem_should_map_pages(dev)) {
-		addr = devm_memremap_pages(dev, &nsio->res,
-				&q->q_usage_counter, NULL);
+		memcpy(&pmem->pgmap.res, &nsio->res, sizeof(pmem->pgmap.res));
+		pmem->pgmap.altmap_valid = false;
+		addr = devm_memremap_pages(dev, &pmem->pgmap);
 		pmem->pfn_flags |= PFN_MAP;
+		memcpy(&bb_res, &pmem->pgmap.res, sizeof(bb_res));
 	} else
 		addr = devm_memremap(dev, pmem->phys_addr,
 				pmem->size, ARCH_MEMREMAP_PMEM);
@@ -401,7 +406,7 @@ static int pmem_attach_disk(struct device *dev,
 			/ 512);
 	if (devm_init_badblocks(dev, &pmem->bb))
 		return -ENOMEM;
-	nvdimm_badblocks_populate(nd_region, &pmem->bb, res);
+	nvdimm_badblocks_populate(nd_region, &pmem->bb, &bb_res);
 	disk->bb = &pmem->bb;
 
 	dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops);
diff --git a/drivers/nvdimm/pmem.h b/drivers/nvdimm/pmem.h
index 6a3cd2a1..a64ebc7 100644
--- a/drivers/nvdimm/pmem.h
+++ b/drivers/nvdimm/pmem.h
@@ -22,6 +22,7 @@ struct pmem_device {
 	struct badblocks	bb;
 	struct dax_device	*dax_dev;
 	struct gendisk		*disk;
+	struct dev_pagemap	pgmap;
 };
 
 long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff,
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index abaf38c..e6d0191 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -528,6 +528,18 @@ static ssize_t resource_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(resource);
 
+static ssize_t persistence_domain_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct nd_region *nd_region = to_nd_region(dev);
+	unsigned long flags = nd_region->flags;
+
+	return sprintf(buf, "%s%s\n",
+			flags & BIT(ND_REGION_PERSIST_CACHE) ? "cpu_cache " : "",
+			flags & BIT(ND_REGION_PERSIST_MEMCTRL) ? "memory_controller " : "");
+}
+static DEVICE_ATTR_RO(persistence_domain);
+
 static struct attribute *nd_region_attributes[] = {
 	&dev_attr_size.attr,
 	&dev_attr_nstype.attr,
@@ -543,6 +555,7 @@ static struct attribute *nd_region_attributes[] = {
 	&dev_attr_init_namespaces.attr,
 	&dev_attr_badblocks.attr,
 	&dev_attr_resource.attr,
+	&dev_attr_persistence_domain.attr,
 	NULL,
 };
 
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 0689803..783e087 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -64,10 +64,6 @@
 config OF_ADDRESS
 	def_bool y
 	depends on !SPARC && (HAS_IOMEM || UML)
-	select OF_ADDRESS_PCI if PCI
-
-config OF_ADDRESS_PCI
-	bool
 
 config OF_IRQ
 	def_bool y
@@ -84,18 +80,6 @@
 	help
 	  OpenFirmware MDIO bus (Ethernet PHY) accessors
 
-config OF_PCI
-	def_tristate PCI
-	depends on PCI
-	help
-	  OpenFirmware PCI bus accessors
-
-config OF_PCI_IRQ
-	def_tristate PCI
-	depends on OF_PCI && OF_IRQ
-	help
-	  OpenFirmware PCI IRQ routing helpers
-
 config OF_RESERVED_MEM
 	depends on OF_EARLY_FLATTREE
 	bool
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 63a4be6..663a4af 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,8 +10,6 @@
 obj-$(CONFIG_OF_NET)	+= of_net.o
 obj-$(CONFIG_OF_UNITTEST) += unittest.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
-obj-$(CONFIG_OF_PCI)	+= of_pci.o
-obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
 obj-$(CONFIG_OF_RESOLVE)  += resolver.o
 obj-$(CONFIG_OF_OVERLAY) += overlay.o
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 6391604..ce4d3d8 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -96,7 +96,7 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr)
 	return IORESOURCE_MEM;
 }
 
-#ifdef CONFIG_OF_ADDRESS_PCI
+#ifdef CONFIG_PCI
 /*
  * PCI bus specific translator
  */
@@ -171,9 +171,7 @@ static int of_bus_pci_translate(__be32 *addr, u64 offset, int na)
 {
 	return of_bus_default_translate(addr + 1, offset, na - 1);
 }
-#endif /* CONFIG_OF_ADDRESS_PCI */
 
-#ifdef CONFIG_PCI
 const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
 			unsigned int *flags)
 {
@@ -361,6 +359,7 @@ int of_pci_range_to_resource(struct of_pci_range *range,
 	res->end = (resource_size_t)OF_BAD_ADDR;
 	return err;
 }
+EXPORT_SYMBOL(of_pci_range_to_resource);
 #endif /* CONFIG_PCI */
 
 /*
@@ -426,7 +425,7 @@ static unsigned int of_bus_isa_get_flags(const __be32 *addr)
  */
 
 static struct of_bus of_busses[] = {
-#ifdef CONFIG_OF_ADDRESS_PCI
+#ifdef CONFIG_PCI
 	/* PCI */
 	{
 		.name = "pci",
@@ -437,7 +436,7 @@ static struct of_bus of_busses[] = {
 		.translate = of_bus_pci_translate,
 		.get_flags = of_bus_pci_get_flags,
 	},
-#endif /* CONFIG_OF_ADDRESS_PCI */
+#endif /* CONFIG_PCI */
 	/* ISA */
 	{
 		.name = "isa",
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
deleted file mode 100644
index a7b1cb6..0000000
--- a/drivers/of/of_pci.c
+++ /dev/null
@@ -1,384 +0,0 @@
-#define pr_fmt(fmt)	"OF: PCI: " fmt
-
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/of_pci.h>
-#include <linux/slab.h>
-
-static inline int __of_pci_pci_compare(struct device_node *node,
-				       unsigned int data)
-{
-	int devfn;
-
-	devfn = of_pci_get_devfn(node);
-	if (devfn < 0)
-		return 0;
-
-	return devfn == data;
-}
-
-struct device_node *of_pci_find_child_device(struct device_node *parent,
-					     unsigned int devfn)
-{
-	struct device_node *node, *node2;
-
-	for_each_child_of_node(parent, node) {
-		if (__of_pci_pci_compare(node, devfn))
-			return node;
-		/*
-		 * Some OFs create a parent node "multifunc-device" as
-		 * a fake root for all functions of a multi-function
-		 * device we go down them as well.
-		 */
-		if (!strcmp(node->name, "multifunc-device")) {
-			for_each_child_of_node(node, node2) {
-				if (__of_pci_pci_compare(node2, devfn)) {
-					of_node_put(node);
-					return node2;
-				}
-			}
-		}
-	}
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(of_pci_find_child_device);
-
-/**
- * of_pci_get_devfn() - Get device and function numbers for a device node
- * @np: device node
- *
- * Parses a standard 5-cell PCI resource and returns an 8-bit value that can
- * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device
- * and function numbers respectively. On error a negative error code is
- * returned.
- */
-int of_pci_get_devfn(struct device_node *np)
-{
-	u32 reg[5];
-	int error;
-
-	error = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
-	if (error)
-		return error;
-
-	return (reg[0] >> 8) & 0xff;
-}
-EXPORT_SYMBOL_GPL(of_pci_get_devfn);
-
-/**
- * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
- * @node: device node
- * @res: address to a struct resource to return the bus-range
- *
- * Returns 0 on success or a negative error-code on failure.
- */
-int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
-{
-	u32 bus_range[2];
-	int error;
-
-	error = of_property_read_u32_array(node, "bus-range", bus_range,
-					   ARRAY_SIZE(bus_range));
-	if (error)
-		return error;
-
-	res->name = node->name;
-	res->start = bus_range[0];
-	res->end = bus_range[1];
-	res->flags = IORESOURCE_BUS;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
-
-/**
- * This function will try to obtain the host bridge domain number by
- * finding a property called "linux,pci-domain" of the given device node.
- *
- * @node: device tree node with the domain information
- *
- * Returns the associated domain number from DT in the range [0-0xffff], or
- * a negative value if the required property is not found.
- */
-int of_get_pci_domain_nr(struct device_node *node)
-{
-	u32 domain;
-	int error;
-
-	error = of_property_read_u32(node, "linux,pci-domain", &domain);
-	if (error)
-		return error;
-
-	return (u16)domain;
-}
-EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
-
-/**
- * This function will try to find the limitation of link speed by finding
- * a property called "max-link-speed" of the given device node.
- *
- * @node: device tree node with the max link speed information
- *
- * Returns the associated max link speed from DT, or a negative value if the
- * required property is not found or is invalid.
- */
-int of_pci_get_max_link_speed(struct device_node *node)
-{
-	u32 max_link_speed;
-
-	if (of_property_read_u32(node, "max-link-speed", &max_link_speed) ||
-	    max_link_speed > 4)
-		return -EINVAL;
-
-	return max_link_speed;
-}
-EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
-
-/**
- * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
- *                           is present and valid
- */
-void of_pci_check_probe_only(void)
-{
-	u32 val;
-	int ret;
-
-	ret = of_property_read_u32(of_chosen, "linux,pci-probe-only", &val);
-	if (ret) {
-		if (ret == -ENODATA || ret == -EOVERFLOW)
-			pr_warn("linux,pci-probe-only without valid value, ignoring\n");
-		return;
-	}
-
-	if (val)
-		pci_add_flags(PCI_PROBE_ONLY);
-	else
-		pci_clear_flags(PCI_PROBE_ONLY);
-
-	pr_info("PROBE_ONLY %sabled\n", val ? "en" : "dis");
-}
-EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
-
-#if defined(CONFIG_OF_ADDRESS)
-/**
- * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
- * @dev: device node of the host bridge having the range property
- * @busno: bus number associated with the bridge root bus
- * @bus_max: maximum number of buses for this bridge
- * @resources: list where the range of resources will be added after DT parsing
- * @io_base: pointer to a variable that will contain on return the physical
- * address for the start of the I/O range. Can be NULL if the caller doesn't
- * expect IO ranges to be present in the device tree.
- *
- * It is the caller's job to free the @resources list.
- *
- * This function will parse the "ranges" property of a PCI host bridge device
- * node and setup the resource mapping based on its content. It is expected
- * that the property conforms with the Power ePAPR document.
- *
- * It returns zero if the range parsing has been successful or a standard error
- * value if it failed.
- */
-int of_pci_get_host_bridge_resources(struct device_node *dev,
-			unsigned char busno, unsigned char bus_max,
-			struct list_head *resources, resource_size_t *io_base)
-{
-	struct resource_entry *window;
-	struct resource *res;
-	struct resource *bus_range;
-	struct of_pci_range range;
-	struct of_pci_range_parser parser;
-	char range_type[4];
-	int err;
-
-	if (io_base)
-		*io_base = (resource_size_t)OF_BAD_ADDR;
-
-	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
-	if (!bus_range)
-		return -ENOMEM;
-
-	pr_info("host bridge %pOF ranges:\n", dev);
-
-	err = of_pci_parse_bus_range(dev, bus_range);
-	if (err) {
-		bus_range->start = busno;
-		bus_range->end = bus_max;
-		bus_range->flags = IORESOURCE_BUS;
-		pr_info("  No bus range found for %pOF, using %pR\n",
-			dev, bus_range);
-	} else {
-		if (bus_range->end > bus_range->start + bus_max)
-			bus_range->end = bus_range->start + bus_max;
-	}
-	pci_add_resource(resources, bus_range);
-
-	/* Check for ranges property */
-	err = of_pci_range_parser_init(&parser, dev);
-	if (err)
-		goto parse_failed;
-
-	pr_debug("Parsing ranges property...\n");
-	for_each_of_pci_range(&parser, &range) {
-		/* Read next ranges element */
-		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
-			snprintf(range_type, 4, " IO");
-		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
-			snprintf(range_type, 4, "MEM");
-		else
-			snprintf(range_type, 4, "err");
-		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
-			range.cpu_addr, range.cpu_addr + range.size - 1,
-			range.pci_addr);
-
-		/*
-		 * If we failed translation or got a zero-sized region
-		 * then skip this range
-		 */
-		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
-			continue;
-
-		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
-		if (!res) {
-			err = -ENOMEM;
-			goto parse_failed;
-		}
-
-		err = of_pci_range_to_resource(&range, dev, res);
-		if (err) {
-			kfree(res);
-			continue;
-		}
-
-		if (resource_type(res) == IORESOURCE_IO) {
-			if (!io_base) {
-				pr_err("I/O range found for %pOF. Please provide an io_base pointer to save CPU base address\n",
-					dev);
-				err = -EINVAL;
-				goto conversion_failed;
-			}
-			if (*io_base != (resource_size_t)OF_BAD_ADDR)
-				pr_warn("More than one I/O resource converted for %pOF. CPU base address for old range lost!\n",
-					dev);
-			*io_base = range.cpu_addr;
-		}
-
-		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
-	}
-
-	return 0;
-
-conversion_failed:
-	kfree(res);
-parse_failed:
-	resource_list_for_each_entry(window, resources)
-		kfree(window->res);
-	pci_free_resource_list(resources);
-	return err;
-}
-EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
-#endif /* CONFIG_OF_ADDRESS */
-
-/**
- * of_pci_map_rid - Translate a requester ID through a downstream mapping.
- * @np: root complex device node.
- * @rid: PCI requester ID to map.
- * @map_name: property name of the map to use.
- * @map_mask_name: optional property name of the mask to use.
- * @target: optional pointer to a target device node.
- * @id_out: optional pointer to receive the translated ID.
- *
- * Given a PCI requester ID, look up the appropriate implementation-defined
- * platform ID and/or the target device which receives transactions on that
- * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
- * @id_out may be NULL if only the other is required. If @target points to
- * a non-NULL device node pointer, only entries targeting that node will be
- * matched; if it points to a NULL value, it will receive the device node of
- * the first matching target phandle, with a reference held.
- *
- * Return: 0 on success or a standard error code on failure.
- */
-int of_pci_map_rid(struct device_node *np, u32 rid,
-		   const char *map_name, const char *map_mask_name,
-		   struct device_node **target, u32 *id_out)
-{
-	u32 map_mask, masked_rid;
-	int map_len;
-	const __be32 *map = NULL;
-
-	if (!np || !map_name || (!target && !id_out))
-		return -EINVAL;
-
-	map = of_get_property(np, map_name, &map_len);
-	if (!map) {
-		if (target)
-			return -ENODEV;
-		/* Otherwise, no map implies no translation */
-		*id_out = rid;
-		return 0;
-	}
-
-	if (!map_len || map_len % (4 * sizeof(*map))) {
-		pr_err("%pOF: Error: Bad %s length: %d\n", np,
-			map_name, map_len);
-		return -EINVAL;
-	}
-
-	/* The default is to select all bits. */
-	map_mask = 0xffffffff;
-
-	/*
-	 * Can be overridden by "{iommu,msi}-map-mask" property.
-	 * If of_property_read_u32() fails, the default is used.
-	 */
-	if (map_mask_name)
-		of_property_read_u32(np, map_mask_name, &map_mask);
-
-	masked_rid = map_mask & rid;
-	for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
-		struct device_node *phandle_node;
-		u32 rid_base = be32_to_cpup(map + 0);
-		u32 phandle = be32_to_cpup(map + 1);
-		u32 out_base = be32_to_cpup(map + 2);
-		u32 rid_len = be32_to_cpup(map + 3);
-
-		if (rid_base & ~map_mask) {
-			pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n",
-				np, map_name, map_name,
-				map_mask, rid_base);
-			return -EFAULT;
-		}
-
-		if (masked_rid < rid_base || masked_rid >= rid_base + rid_len)
-			continue;
-
-		phandle_node = of_find_node_by_phandle(phandle);
-		if (!phandle_node)
-			return -ENODEV;
-
-		if (target) {
-			if (*target)
-				of_node_put(phandle_node);
-			else
-				*target = phandle_node;
-
-			if (*target != phandle_node)
-				continue;
-		}
-
-		if (id_out)
-			*id_out = masked_rid - rid_base + out_base;
-
-		pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n",
-			np, map_name, map_mask, rid_base, out_base,
-			rid_len, rid, masked_rid - rid_base + out_base);
-		return 0;
-	}
-
-	pr_err("%pOF: Invalid %s translation - no match for rid 0x%x on %pOF\n",
-		np, map_name, rid, target && *target ? *target : NULL);
-	return -EFAULT;
-}
diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c
deleted file mode 100644
index 3a05568..0000000
--- a/drivers/of/of_pci_irq.c
+++ /dev/null
@@ -1,131 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/of_pci.h>
-#include <linux/of_irq.h>
-#include <linux/export.h>
-
-/**
- * of_irq_parse_pci - Resolve the interrupt for a PCI device
- * @pdev:       the device whose interrupt is to be resolved
- * @out_irq:    structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
-{
-	struct device_node *dn, *ppnode;
-	struct pci_dev *ppdev;
-	__be32 laddr[3];
-	u8 pin;
-	int rc;
-
-	/* Check if we have a device node, if yes, fallback to standard
-	 * device tree parsing
-	 */
-	dn = pci_device_to_OF_node(pdev);
-	if (dn) {
-		rc = of_irq_parse_one(dn, 0, out_irq);
-		if (!rc)
-			return rc;
-	}
-
-	/* Ok, we don't, time to have fun. Let's start by building up an
-	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
-	 * for PCI. If you do different, then don't use that routine.
-	 */
-	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
-	if (rc != 0)
-		goto err;
-	/* No pin, exit with no error message. */
-	if (pin == 0)
-		return -ENODEV;
-
-	/* Now we walk up the PCI tree */
-	for (;;) {
-		/* Get the pci_dev of our parent */
-		ppdev = pdev->bus->self;
-
-		/* Ouch, it's a host bridge... */
-		if (ppdev == NULL) {
-			ppnode = pci_bus_to_OF_node(pdev->bus);
-
-			/* No node for host bridge ? give up */
-			if (ppnode == NULL) {
-				rc = -EINVAL;
-				goto err;
-			}
-		} else {
-			/* We found a P2P bridge, check if it has a node */
-			ppnode = pci_device_to_OF_node(ppdev);
-		}
-
-		/* Ok, we have found a parent with a device-node, hand over to
-		 * the OF parsing code.
-		 * We build a unit address from the linux device to be used for
-		 * resolution. Note that we use the linux bus number which may
-		 * not match your firmware bus numbering.
-		 * Fortunately, in most cases, interrupt-map-mask doesn't
-		 * include the bus number as part of the matching.
-		 * You should still be careful about that though if you intend
-		 * to rely on this function (you ship  a firmware that doesn't
-		 * create device nodes for all PCI devices).
-		 */
-		if (ppnode)
-			break;
-
-		/* We can only get here if we hit a P2P bridge with no node,
-		 * let's do standard swizzling and try again
-		 */
-		pin = pci_swizzle_interrupt_pin(pdev, pin);
-		pdev = ppdev;
-	}
-
-	out_irq->np = ppnode;
-	out_irq->args_count = 1;
-	out_irq->args[0] = pin;
-	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
-	laddr[1] = laddr[2] = cpu_to_be32(0);
-	rc = of_irq_parse_raw(laddr, out_irq);
-	if (rc)
-		goto err;
-	return 0;
-err:
-	if (rc == -ENOENT) {
-		dev_warn(&pdev->dev,
-			"%s: no interrupt-map found, INTx interrupts not available\n",
-			__func__);
-		pr_warn_once("%s: possibly some PCI slots don't have level triggered interrupts capability\n",
-			__func__);
-	} else {
-		dev_err(&pdev->dev, "%s: failed with rc=%d\n", __func__, rc);
-	}
-	return rc;
-}
-EXPORT_SYMBOL_GPL(of_irq_parse_pci);
-
-/**
- * of_irq_parse_and_map_pci() - Decode a PCI irq from the device tree and map to a virq
- * @dev: The pci device needing an irq
- * @slot: PCI slot number; passed when used as map_irq callback. Unused
- * @pin: PCI irq pin number; passed when used as map_irq callback. Unused
- *
- * @slot and @pin are unused, but included in the function so that this
- * function can be used directly as the map_irq callback to
- * pci_assign_irq() and struct pci_host_bridge.map_irq pointer
- */
-int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	struct of_phandle_args oirq;
-	int ret;
-
-	ret = of_irq_parse_pci(dev, &oirq);
-	if (ret)
-		return 0; /* Proper return code 0 == NO_IRQ */
-
-	return irq_create_of_mapping(&oirq);
-}
-EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
-
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index bda1517..34b56a8 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # PCI configuration
 #
@@ -125,6 +126,7 @@
 
 config PCI_LABEL
 	def_bool y if (DMI || ACPI)
+	depends on PCI
 	select NLS
 
 config PCI_HYPERV
@@ -135,6 +137,7 @@
           PCI devices from a PCI backend to support PCI driver domains.
 
 source "drivers/pci/hotplug/Kconfig"
+source "drivers/pci/cadence/Kconfig"
 source "drivers/pci/dwc/Kconfig"
 source "drivers/pci/host/Kconfig"
 source "drivers/pci/endpoint/Kconfig"
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index c7819b9..9419709 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -3,12 +3,15 @@
 # Makefile for the PCI bus specific drivers.
 #
 
-obj-y		+= access.o bus.o probe.o host-bridge.o remove.o pci.o \
+obj-$(CONFIG_PCI)	+= access.o bus.o probe.o host-bridge.o remove.o pci.o \
 			pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
 			irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o
 
+ifdef CONFIG_PCI
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_SYSFS) += slot.o
+obj-$(CONFIG_OF) += of.o
+endif
 
 obj-$(CONFIG_PCI_QUIRKS) += quirks.o
 
@@ -44,10 +47,15 @@
 
 obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o
 
-obj-$(CONFIG_OF) += of.o
-
 ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
 
 # PCI host controller drivers
 obj-y += host/
 obj-y += switch/
+
+obj-$(CONFIG_PCI_ENDPOINT)	+= endpoint/
+
+# Endpoint library must be initialized before its users
+obj-$(CONFIG_PCIE_CADENCE)	+= cadence/
+# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
+obj-y				+= dwc/
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 913d672..5e9a982 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/module.h>
@@ -333,8 +334,7 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size)
 			    (tag == PCI_VPD_LTIN_RW_DATA)) {
 				if (pci_read_vpd(dev, off+1, 2,
 						 &header[1]) != 2) {
-					dev_warn(&dev->dev,
-						 "invalid large VPD tag %02x size at offset %zu",
+					pci_warn(dev, "invalid large VPD tag %02x size at offset %zu",
 						 tag, off + 1);
 					return 0;
 				}
@@ -354,8 +354,7 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size)
 		if ((tag != PCI_VPD_LTIN_ID_STRING) &&
 		    (tag != PCI_VPD_LTIN_RO_DATA) &&
 		    (tag != PCI_VPD_LTIN_RW_DATA)) {
-			dev_warn(&dev->dev,
-				 "invalid %s VPD tag %02x at offset %zu",
+			pci_warn(dev, "invalid %s VPD tag %02x at offset %zu",
 				 (header[0] & PCI_VPD_LRDT) ? "large" : "short",
 				 tag, off);
 			return 0;
@@ -402,7 +401,7 @@ static int pci_vpd_wait(struct pci_dev *dev)
 			max_sleep *= 2;
 	}
 
-	dev_warn(&dev->dev, "VPD access failed.  This is likely a firmware bug on this device.  Contact the card vendor for a firmware update\n");
+	pci_warn(dev, "VPD access failed.  This is likely a firmware bug on this device.  Contact the card vendor for a firmware update\n");
 	return -ETIMEDOUT;
 }
 
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index ad8ddbb..6ad80a1 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * drivers/pci/ats.c
  *
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index bc56cf1..737d1c5 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *	drivers/pci/bus.c
  *
@@ -289,7 +290,7 @@ bool pci_bus_clip_resource(struct pci_dev *dev, int idx)
 		res->end = end;
 		res->flags &= ~IORESOURCE_UNSET;
 		orig_res.flags &= ~IORESOURCE_UNSET;
-		dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n",
+		pci_printk(KERN_DEBUG, dev, "%pR clipped to %pR\n",
 				 &orig_res, res);
 
 		return true;
@@ -325,7 +326,7 @@ void pci_bus_add_device(struct pci_dev *dev)
 	dev->match_driver = true;
 	retval = device_attach(&dev->dev);
 	if (retval < 0 && retval != -EPROBE_DEFER) {
-		dev_warn(&dev->dev, "device attach failed (%d)\n", retval);
+		pci_warn(dev, "device attach failed (%d)\n", retval);
 		pci_proc_detach_device(dev);
 		pci_remove_sysfs_dev_files(dev);
 		return;
diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig
new file mode 100644
index 0000000..e6824cb
--- /dev/null
+++ b/drivers/pci/cadence/Kconfig
@@ -0,0 +1,27 @@
+menu "Cadence PCIe controllers support"
+
+config PCIE_CADENCE
+	bool
+
+config PCIE_CADENCE_HOST
+	bool "Cadence PCIe host controller"
+	depends on OF
+	depends on PCI
+	select IRQ_DOMAIN
+	select PCIE_CADENCE
+	help
+	  Say Y here if you want to support the Cadence PCIe controller in host
+	  mode. This PCIe controller may be embedded into many different vendors
+	  SoCs.
+
+config PCIE_CADENCE_EP
+	bool "Cadence PCIe endpoint controller"
+	depends on OF
+	depends on PCI_ENDPOINT
+	select PCIE_CADENCE
+	help
+	  Say Y here if you want to support the Cadence PCIe  controller in
+	  endpoint mode. This PCIe controller may be embedded into many
+	  different vendors SoCs.
+
+endmenu
diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile
new file mode 100644
index 0000000..719392b
--- /dev/null
+++ b/drivers/pci/cadence/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
+obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
+obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
diff --git a/drivers/pci/cadence/pcie-cadence-ep.c b/drivers/pci/cadence/pcie-cadence-ep.c
new file mode 100644
index 0000000..3c3a977
--- /dev/null
+++ b/drivers/pci/cadence/pcie-cadence-ep.c
@@ -0,0 +1,542 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe endpoint controller driver.
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pci-epc.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/sizes.h>
+
+#include "pcie-cadence.h"
+
+#define CDNS_PCIE_EP_MIN_APERTURE		128	/* 128 bytes */
+#define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE		0x1
+#define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY	0x3
+
+/**
+ * struct cdns_pcie_ep - private data for this PCIe endpoint controller driver
+ * @pcie: Cadence PCIe controller
+ * @max_regions: maximum number of regions supported by hardware
+ * @ob_region_map: bitmask of mapped outbound regions
+ * @ob_addr: base addresses in the AXI bus where the outbound regions start
+ * @irq_phys_addr: base address on the AXI bus where the MSI/legacy IRQ
+ *		   dedicated outbound regions is mapped.
+ * @irq_cpu_addr: base address in the CPU space where a write access triggers
+ *		  the sending of a memory write (MSI) / normal message (legacy
+ *		  IRQ) TLP through the PCIe bus.
+ * @irq_pci_addr: used to save the current mapping of the MSI/legacy IRQ
+ *		  dedicated outbound region.
+ * @irq_pci_fn: the latest PCI function that has updated the mapping of
+ *		the MSI/legacy IRQ dedicated outbound region.
+ * @irq_pending: bitmask of asserted legacy IRQs.
+ */
+struct cdns_pcie_ep {
+	struct cdns_pcie		pcie;
+	u32				max_regions;
+	unsigned long			ob_region_map;
+	phys_addr_t			*ob_addr;
+	phys_addr_t			irq_phys_addr;
+	void __iomem			*irq_cpu_addr;
+	u64				irq_pci_addr;
+	u8				irq_pci_fn;
+	u8				irq_pending;
+};
+
+static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+				     struct pci_epf_header *hdr)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+
+	cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
+	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
+	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CLASS_PROG, hdr->progif_code);
+	cdns_pcie_ep_fn_writew(pcie, fn, PCI_CLASS_DEVICE,
+			       hdr->subclass_code | hdr->baseclass_code << 8);
+	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CACHE_LINE_SIZE,
+			       hdr->cache_line_size);
+	cdns_pcie_ep_fn_writew(pcie, fn, PCI_SUBSYSTEM_ID, hdr->subsys_id);
+	cdns_pcie_ep_fn_writeb(pcie, fn, PCI_INTERRUPT_PIN, hdr->interrupt_pin);
+
+	/*
+	 * Vendor ID can only be modified from function 0, all other functions
+	 * use the same vendor ID as function 0.
+	 */
+	if (fn == 0) {
+		/* Update the vendor IDs. */
+		u32 id = CDNS_PCIE_LM_ID_VENDOR(hdr->vendorid) |
+			 CDNS_PCIE_LM_ID_SUBSYS(hdr->subsys_vendor_id);
+
+		cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, id);
+	}
+
+	return 0;
+}
+
+static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, enum pci_barno bar,
+				dma_addr_t bar_phys, size_t size, int flags)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 addr0, addr1, reg, cfg, b, aperture, ctrl;
+	u64 sz;
+
+	/* BAR size is 2^(aperture + 7) */
+	sz = max_t(size_t, size, CDNS_PCIE_EP_MIN_APERTURE);
+	/*
+	 * roundup_pow_of_two() returns an unsigned long, which is not suited
+	 * for 64bit values.
+	 */
+	sz = 1ULL << fls64(sz - 1);
+	aperture = ilog2(sz) - 7; /* 128B -> 0, 256B -> 1, 512B -> 2, ... */
+
+	if ((flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+		ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS;
+	} else {
+		bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH);
+		bool is_64bits = sz > SZ_2G;
+
+		if (is_64bits && (bar & 1))
+			return -EINVAL;
+
+		if (is_64bits && is_prefetch)
+			ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS;
+		else if (is_prefetch)
+			ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS;
+		else if (is_64bits)
+			ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS;
+		else
+			ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS;
+	}
+
+	addr0 = lower_32_bits(bar_phys);
+	addr1 = upper_32_bits(bar_phys);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
+			 addr0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
+			 addr1);
+
+	if (bar < BAR_4) {
+		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
+		b = bar;
+	} else {
+		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
+		b = bar - BAR_4;
+	}
+
+	cfg = cdns_pcie_readl(pcie, reg);
+	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+	cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
+		CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
+	cdns_pcie_writel(pcie, reg, cfg);
+
+	return 0;
+}
+
+static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+				   enum pci_barno bar)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 reg, cfg, b, ctrl;
+
+	if (bar < BAR_4) {
+		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
+		b = bar;
+	} else {
+		reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
+		b = bar - BAR_4;
+	}
+
+	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
+	cfg = cdns_pcie_readl(pcie, reg);
+	cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+		 CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+	cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
+	cdns_pcie_writel(pcie, reg, cfg);
+
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), 0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), 0);
+}
+
+static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr,
+				 u64 pci_addr, size_t size)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 r;
+
+	r = find_first_zero_bit(&ep->ob_region_map,
+				sizeof(ep->ob_region_map) * BITS_PER_LONG);
+	if (r >= ep->max_regions - 1) {
+		dev_err(&epc->dev, "no free outbound region\n");
+		return -EINVAL;
+	}
+
+	cdns_pcie_set_outbound_region(pcie, fn, r, false, addr, pci_addr, size);
+
+	set_bit(r, &ep->ob_region_map);
+	ep->ob_addr[r] = addr;
+
+	return 0;
+}
+
+static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+				    phys_addr_t addr)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 r;
+
+	for (r = 0; r < ep->max_regions - 1; r++)
+		if (ep->ob_addr[r] == addr)
+			break;
+
+	if (r == ep->max_regions - 1)
+		return;
+
+	cdns_pcie_reset_outbound_region(pcie, r);
+
+	ep->ob_addr[r] = 0;
+	clear_bit(r, &ep->ob_region_map);
+}
+
+static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 mmc)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+	u16 flags;
+
+	/*
+	 * Set the Multiple Message Capable bitfield into the Message Control
+	 * register.
+	 */
+	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+	flags = (flags & ~PCI_MSI_FLAGS_QMASK) | (mmc << 1);
+	flags |= PCI_MSI_FLAGS_64BIT;
+	flags &= ~PCI_MSI_FLAGS_MASKBIT;
+	cdns_pcie_ep_fn_writew(pcie, fn, cap + PCI_MSI_FLAGS, flags);
+
+	return 0;
+}
+
+static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+	u16 flags, mmc, mme;
+
+	/* Validate that the MSI feature is actually enabled. */
+	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+	if (!(flags & PCI_MSI_FLAGS_ENABLE))
+		return -EINVAL;
+
+	/*
+	 * Get the Multiple Message Enable bitfield from the Message Control
+	 * register.
+	 */
+	mmc = (flags & PCI_MSI_FLAGS_QMASK) >> 1;
+	mme = (flags & PCI_MSI_FLAGS_QSIZE) >> 4;
+
+	return mme;
+}
+
+static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
+				     u8 intx, bool is_asserted)
+{
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 r = ep->max_regions - 1;
+	u32 offset;
+	u16 status;
+	u8 msg_code;
+
+	intx &= 3;
+
+	/* Set the outbound region if needed. */
+	if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY ||
+		     ep->irq_pci_fn != fn)) {
+		/* Last region was reserved for IRQ writes. */
+		cdns_pcie_set_outbound_region_for_normal_msg(pcie, fn, r,
+							     ep->irq_phys_addr);
+		ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY;
+		ep->irq_pci_fn = fn;
+	}
+
+	if (is_asserted) {
+		ep->irq_pending |= BIT(intx);
+		msg_code = MSG_CODE_ASSERT_INTA + intx;
+	} else {
+		ep->irq_pending &= ~BIT(intx);
+		msg_code = MSG_CODE_DEASSERT_INTA + intx;
+	}
+
+	status = cdns_pcie_ep_fn_readw(pcie, fn, PCI_STATUS);
+	if (((status & PCI_STATUS_INTERRUPT) != 0) ^ (ep->irq_pending != 0)) {
+		status ^= PCI_STATUS_INTERRUPT;
+		cdns_pcie_ep_fn_writew(pcie, fn, PCI_STATUS, status);
+	}
+
+	offset = CDNS_PCIE_NORMAL_MSG_ROUTING(MSG_ROUTING_LOCAL) |
+		 CDNS_PCIE_NORMAL_MSG_CODE(msg_code) |
+		 CDNS_PCIE_MSG_NO_DATA;
+	writel(0, ep->irq_cpu_addr + offset);
+}
+
+static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 intx)
+{
+	u16 cmd;
+
+	cmd = cdns_pcie_ep_fn_readw(&ep->pcie, fn, PCI_COMMAND);
+	if (cmd & PCI_COMMAND_INTX_DISABLE)
+		return -EINVAL;
+
+	cdns_pcie_ep_assert_intx(ep, fn, intx, true);
+	/*
+	 * The mdelay() value was taken from dra7xx_pcie_raise_legacy_irq()
+	 * from drivers/pci/dwc/pci-dra7xx.c
+	 */
+	mdelay(1);
+	cdns_pcie_ep_assert_intx(ep, fn, intx, false);
+	return 0;
+}
+
+static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
+				     u8 interrupt_num)
+{
+	struct cdns_pcie *pcie = &ep->pcie;
+	u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+	u16 flags, mme, data, data_mask;
+	u8 msi_count;
+	u64 pci_addr, pci_addr_mask = 0xff;
+
+	/* Check whether the MSI feature has been enabled by the PCI host. */
+	flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+	if (!(flags & PCI_MSI_FLAGS_ENABLE))
+		return -EINVAL;
+
+	/* Get the number of enabled MSIs */
+	mme = (flags & PCI_MSI_FLAGS_QSIZE) >> 4;
+	msi_count = 1 << mme;
+	if (!interrupt_num || interrupt_num > msi_count)
+		return -EINVAL;
+
+	/* Compute the data value to be written. */
+	data_mask = msi_count - 1;
+	data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64);
+	data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask);
+
+	/* Get the PCI address where to write the data into. */
+	pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI);
+	pci_addr <<= 32;
+	pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO);
+	pci_addr &= GENMASK_ULL(63, 2);
+
+	/* Set the outbound region if needed. */
+	if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
+		     ep->irq_pci_fn != fn)) {
+		/* Last region was reserved for IRQ writes. */
+		cdns_pcie_set_outbound_region(pcie, fn, ep->max_regions - 1,
+					      false,
+					      ep->irq_phys_addr,
+					      pci_addr & ~pci_addr_mask,
+					      pci_addr_mask + 1);
+		ep->irq_pci_addr = (pci_addr & ~pci_addr_mask);
+		ep->irq_pci_fn = fn;
+	}
+	writew(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask));
+
+	return 0;
+}
+
+static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+				  enum pci_epc_irq_type type, u8 interrupt_num)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+
+	switch (type) {
+	case PCI_EPC_IRQ_LEGACY:
+		return cdns_pcie_ep_send_legacy_irq(ep, fn, 0);
+
+	case PCI_EPC_IRQ_MSI:
+		return cdns_pcie_ep_send_msi_irq(ep, fn, interrupt_num);
+
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int cdns_pcie_ep_start(struct pci_epc *epc)
+{
+	struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+	struct cdns_pcie *pcie = &ep->pcie;
+	struct pci_epf *epf;
+	u32 cfg;
+
+	/*
+	 * BIT(0) is hardwired to 1, hence function 0 is always enabled
+	 * and can't be disabled anyway.
+	 */
+	cfg = BIT(0);
+	list_for_each_entry(epf, &epc->pci_epf, list)
+		cfg |= BIT(epf->func_no);
+	cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, cfg);
+
+	/*
+	 * The PCIe links are automatically established by the controller
+	 * once for all at powerup: the software can neither start nor stop
+	 * those links later at runtime.
+	 *
+	 * Then we only have to notify the EP core that our links are already
+	 * established. However we don't call directly pci_epc_linkup() because
+	 * we've already locked the epc->lock.
+	 */
+	list_for_each_entry(epf, &epc->pci_epf, list)
+		pci_epf_linkup(epf);
+
+	return 0;
+}
+
+static const struct pci_epc_ops cdns_pcie_epc_ops = {
+	.write_header	= cdns_pcie_ep_write_header,
+	.set_bar	= cdns_pcie_ep_set_bar,
+	.clear_bar	= cdns_pcie_ep_clear_bar,
+	.map_addr	= cdns_pcie_ep_map_addr,
+	.unmap_addr	= cdns_pcie_ep_unmap_addr,
+	.set_msi	= cdns_pcie_ep_set_msi,
+	.get_msi	= cdns_pcie_ep_get_msi,
+	.raise_irq	= cdns_pcie_ep_raise_irq,
+	.start		= cdns_pcie_ep_start,
+};
+
+static const struct of_device_id cdns_pcie_ep_of_match[] = {
+	{ .compatible = "cdns,cdns-pcie-ep" },
+
+	{ },
+};
+
+static int cdns_pcie_ep_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct cdns_pcie_ep *ep;
+	struct cdns_pcie *pcie;
+	struct pci_epc *epc;
+	struct resource *res;
+	int ret;
+
+	ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
+	if (!ep)
+		return -ENOMEM;
+
+	pcie = &ep->pcie;
+	pcie->is_rc = false;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg");
+	pcie->reg_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(pcie->reg_base)) {
+		dev_err(dev, "missing \"reg\"\n");
+		return PTR_ERR(pcie->reg_base);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem");
+	if (!res) {
+		dev_err(dev, "missing \"mem\"\n");
+		return -EINVAL;
+	}
+	pcie->mem_res = res;
+
+	ret = of_property_read_u32(np, "cdns,max-outbound-regions",
+				   &ep->max_regions);
+	if (ret < 0) {
+		dev_err(dev, "missing \"cdns,max-outbound-regions\"\n");
+		return ret;
+	}
+	ep->ob_addr = devm_kzalloc(dev, ep->max_regions * sizeof(*ep->ob_addr),
+				   GFP_KERNEL);
+	if (!ep->ob_addr)
+		return -ENOMEM;
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync() failed\n");
+		goto err_get_sync;
+	}
+
+	/* Disable all but function 0 (anyway BIT(0) is hardwired to 1). */
+	cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, BIT(0));
+
+	epc = devm_pci_epc_create(dev, &cdns_pcie_epc_ops);
+	if (IS_ERR(epc)) {
+		dev_err(dev, "failed to create epc device\n");
+		ret = PTR_ERR(epc);
+		goto err_init;
+	}
+
+	epc_set_drvdata(epc, ep);
+
+	if (of_property_read_u8(np, "max-functions", &epc->max_functions) < 0)
+		epc->max_functions = 1;
+
+	ret = pci_epc_mem_init(epc, pcie->mem_res->start,
+			       resource_size(pcie->mem_res));
+	if (ret < 0) {
+		dev_err(dev, "failed to initialize the memory space\n");
+		goto err_init;
+	}
+
+	ep->irq_cpu_addr = pci_epc_mem_alloc_addr(epc, &ep->irq_phys_addr,
+						  SZ_128K);
+	if (!ep->irq_cpu_addr) {
+		dev_err(dev, "failed to reserve memory space for MSI\n");
+		ret = -ENOMEM;
+		goto free_epc_mem;
+	}
+	ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE;
+
+	return 0;
+
+ free_epc_mem:
+	pci_epc_mem_exit(epc);
+
+ err_init:
+	pm_runtime_put_sync(dev);
+
+ err_get_sync:
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static void cdns_pcie_ep_shutdown(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	ret = pm_runtime_put_sync(dev);
+	if (ret < 0)
+		dev_dbg(dev, "pm_runtime_put_sync failed\n");
+
+	pm_runtime_disable(dev);
+
+	/* The PCIe controller can't be disabled. */
+}
+
+static struct platform_driver cdns_pcie_ep_driver = {
+	.driver = {
+		.name = "cdns-pcie-ep",
+		.of_match_table = cdns_pcie_ep_of_match,
+	},
+	.probe = cdns_pcie_ep_probe,
+	.shutdown = cdns_pcie_ep_shutdown,
+};
+builtin_platform_driver(cdns_pcie_ep_driver);
diff --git a/drivers/pci/cadence/pcie-cadence-host.c b/drivers/pci/cadence/pcie-cadence-host.c
new file mode 100644
index 0000000..a4ebbd3
--- /dev/null
+++ b/drivers/pci/cadence/pcie-cadence-host.c
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe host controller driver.
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "pcie-cadence.h"
+
+/**
+ * struct cdns_pcie_rc - private data for this PCIe Root Complex driver
+ * @pcie: Cadence PCIe controller
+ * @dev: pointer to PCIe device
+ * @cfg_res: start/end offsets in the physical system memory to map PCI
+ *           configuration space accesses
+ * @bus_range: first/last buses behind the PCIe host controller
+ * @cfg_base: IO mapped window to access the PCI configuration space of a
+ *            single function at a time
+ * @max_regions: maximum number of regions supported by the hardware
+ * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address
+ *                translation (nbits sets into the "no BAR match" register)
+ * @vendor_id: PCI vendor ID
+ * @device_id: PCI device ID
+ */
+struct cdns_pcie_rc {
+	struct cdns_pcie	pcie;
+	struct device		*dev;
+	struct resource		*cfg_res;
+	struct resource		*bus_range;
+	void __iomem		*cfg_base;
+	u32			max_regions;
+	u32			no_bar_nbits;
+	u16			vendor_id;
+	u16			device_id;
+};
+
+static void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
+				      int where)
+{
+	struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
+	struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge);
+	struct cdns_pcie *pcie = &rc->pcie;
+	unsigned int busn = bus->number;
+	u32 addr0, desc0;
+
+	if (busn == rc->bus_range->start) {
+		/*
+		 * Only the root port (devfn == 0) is connected to this bus.
+		 * All other PCI devices are behind some bridge hence on another
+		 * bus.
+		 */
+		if (devfn)
+			return NULL;
+
+		return pcie->reg_base + (where & 0xfff);
+	}
+
+	/* Update Output registers for AXI region 0. */
+	addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(12) |
+		CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) |
+		CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(busn);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(0), addr0);
+
+	/* Configuration Type 0 or Type 1 access. */
+	desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
+		CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
+	/*
+	 * The bus number was already set once for all in desc1 by
+	 * cdns_pcie_host_init_address_translation().
+	 */
+	if (busn == rc->bus_range->start + 1)
+		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0;
+	else
+		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1;
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(0), desc0);
+
+	return rc->cfg_base + (where & 0xfff);
+}
+
+static struct pci_ops cdns_pcie_host_ops = {
+	.map_bus	= cdns_pci_map_bus,
+	.read		= pci_generic_config_read,
+	.write		= pci_generic_config_write,
+};
+
+static const struct of_device_id cdns_pcie_host_of_match[] = {
+	{ .compatible = "cdns,cdns-pcie-host" },
+
+	{ },
+};
+
+static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	u32 value, ctrl;
+
+	/*
+	 * Set the root complex BAR configuration register:
+	 * - disable both BAR0 and BAR1.
+	 * - enable Prefetchable Memory Base and Limit registers in type 1
+	 *   config space (64 bits).
+	 * - enable IO Base and Limit registers in type 1 config
+	 *   space (32 bits).
+	 */
+	ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
+	value = CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(ctrl) |
+		CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(ctrl) |
+		CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE |
+		CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS |
+		CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE |
+		CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS;
+	cdns_pcie_writel(pcie, CDNS_PCIE_LM_RC_BAR_CFG, value);
+
+	/* Set root port configuration space */
+	if (rc->vendor_id != 0xffff)
+		cdns_pcie_rp_writew(pcie, PCI_VENDOR_ID, rc->vendor_id);
+	if (rc->device_id != 0xffff)
+		cdns_pcie_rp_writew(pcie, PCI_DEVICE_ID, rc->device_id);
+
+	cdns_pcie_rp_writeb(pcie, PCI_CLASS_REVISION, 0);
+	cdns_pcie_rp_writeb(pcie, PCI_CLASS_PROG, 0);
+	cdns_pcie_rp_writew(pcie, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_PCI);
+
+	return 0;
+}
+
+static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
+{
+	struct cdns_pcie *pcie = &rc->pcie;
+	struct resource *cfg_res = rc->cfg_res;
+	struct resource *mem_res = pcie->mem_res;
+	struct resource *bus_range = rc->bus_range;
+	struct device *dev = rc->dev;
+	struct device_node *np = dev->of_node;
+	struct of_pci_range_parser parser;
+	struct of_pci_range range;
+	u32 addr0, addr1, desc1;
+	u64 cpu_addr;
+	int r, err;
+
+	/*
+	 * Reserve region 0 for PCI configure space accesses:
+	 * OB_REGION_PCI_ADDR0 and OB_REGION_DESC0 are updated dynamically by
+	 * cdns_pci_map_bus(), other region registers are set here once for all.
+	 */
+	addr1 = 0; /* Should be programmed to zero. */
+	desc1 = CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus_range->start);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1);
+
+	cpu_addr = cfg_res->start - mem_res->start;
+	addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(12) |
+		(lower_32_bits(cpu_addr) & GENMASK(31, 8));
+	addr1 = upper_32_bits(cpu_addr);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(0), addr0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(0), addr1);
+
+	err = of_pci_range_parser_init(&parser, np);
+	if (err)
+		return err;
+
+	r = 1;
+	for_each_of_pci_range(&parser, &range) {
+		bool is_io;
+
+		if (r >= rc->max_regions)
+			break;
+
+		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
+			is_io = false;
+		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
+			is_io = true;
+		else
+			continue;
+
+		cdns_pcie_set_outbound_region(pcie, 0, r, is_io,
+					      range.cpu_addr,
+					      range.pci_addr,
+					      range.size);
+		r++;
+	}
+
+	/*
+	 * Set Root Port no BAR match Inbound Translation registers:
+	 * needed for MSI and DMA.
+	 * Root Port BAR0 and BAR1 are disabled, hence no need to set their
+	 * inbound translation registers.
+	 */
+	addr0 = CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(rc->no_bar_nbits);
+	addr1 = 0;
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_RP_BAR_ADDR0(RP_NO_BAR), addr0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_RP_BAR_ADDR1(RP_NO_BAR), addr1);
+
+	return 0;
+}
+
+static int cdns_pcie_host_init(struct device *dev,
+			       struct list_head *resources,
+			       struct cdns_pcie_rc *rc)
+{
+	struct resource *bus_range = NULL;
+	int err;
+
+	/* Parse our PCI ranges and request their resources */
+	err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
+	if (err)
+		return err;
+
+	rc->bus_range = bus_range;
+	rc->pcie.bus = bus_range->start;
+
+	err = cdns_pcie_host_init_root_port(rc);
+	if (err)
+		goto err_out;
+
+	err = cdns_pcie_host_init_address_translation(rc);
+	if (err)
+		goto err_out;
+
+	return 0;
+
+ err_out:
+	pci_free_resource_list(resources);
+	return err;
+}
+
+static int cdns_pcie_host_probe(struct platform_device *pdev)
+{
+	const char *type;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct pci_host_bridge *bridge;
+	struct list_head resources;
+	struct cdns_pcie_rc *rc;
+	struct cdns_pcie *pcie;
+	struct resource *res;
+	int ret;
+
+	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+	if (!bridge)
+		return -ENOMEM;
+
+	rc = pci_host_bridge_priv(bridge);
+	rc->dev = dev;
+
+	pcie = &rc->pcie;
+	pcie->is_rc = true;
+
+	rc->max_regions = 32;
+	of_property_read_u32(np, "cdns,max-outbound-regions", &rc->max_regions);
+
+	rc->no_bar_nbits = 32;
+	of_property_read_u32(np, "cdns,no-bar-match-nbits", &rc->no_bar_nbits);
+
+	rc->vendor_id = 0xffff;
+	of_property_read_u16(np, "vendor-id", &rc->vendor_id);
+
+	rc->device_id = 0xffff;
+	of_property_read_u16(np, "device-id", &rc->device_id);
+
+	type = of_get_property(np, "device_type", NULL);
+	if (!type || strcmp(type, "pci")) {
+		dev_err(dev, "invalid \"device_type\" %s\n", type);
+		return -EINVAL;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg");
+	pcie->reg_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(pcie->reg_base)) {
+		dev_err(dev, "missing \"reg\"\n");
+		return PTR_ERR(pcie->reg_base);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
+	rc->cfg_base = devm_pci_remap_cfg_resource(dev, res);
+	if (IS_ERR(rc->cfg_base)) {
+		dev_err(dev, "missing \"cfg\"\n");
+		return PTR_ERR(rc->cfg_base);
+	}
+	rc->cfg_res = res;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem");
+	if (!res) {
+		dev_err(dev, "missing \"mem\"\n");
+		return -EINVAL;
+	}
+	pcie->mem_res = res;
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync() failed\n");
+		goto err_get_sync;
+	}
+
+	ret = cdns_pcie_host_init(dev, &resources, rc);
+	if (ret)
+		goto err_init;
+
+	list_splice_init(&resources, &bridge->windows);
+	bridge->dev.parent = dev;
+	bridge->busnr = pcie->bus;
+	bridge->ops = &cdns_pcie_host_ops;
+	bridge->map_irq = of_irq_parse_and_map_pci;
+	bridge->swizzle_irq = pci_common_swizzle;
+
+	ret = pci_host_probe(bridge);
+	if (ret < 0)
+		goto err_host_probe;
+
+	return 0;
+
+ err_host_probe:
+	pci_free_resource_list(&resources);
+
+ err_init:
+	pm_runtime_put_sync(dev);
+
+ err_get_sync:
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static struct platform_driver cdns_pcie_host_driver = {
+	.driver = {
+		.name = "cdns-pcie-host",
+		.of_match_table = cdns_pcie_host_of_match,
+	},
+	.probe = cdns_pcie_host_probe,
+};
+builtin_platform_driver(cdns_pcie_host_driver);
diff --git a/drivers/pci/cadence/pcie-cadence.c b/drivers/pci/cadence/pcie-cadence.c
new file mode 100644
index 0000000..138d113
--- /dev/null
+++ b/drivers/pci/cadence/pcie-cadence.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe controller driver.
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#include <linux/kernel.h>
+
+#include "pcie-cadence.h"
+
+void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn,
+				   u32 r, bool is_io,
+				   u64 cpu_addr, u64 pci_addr, size_t size)
+{
+	/*
+	 * roundup_pow_of_two() returns an unsigned long, which is not suited
+	 * for 64bit values.
+	 */
+	u64 sz = 1ULL << fls64(size - 1);
+	int nbits = ilog2(sz);
+	u32 addr0, addr1, desc0, desc1;
+
+	if (nbits < 8)
+		nbits = 8;
+
+	/* Set the PCI address */
+	addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) |
+		(lower_32_bits(pci_addr) & GENMASK(31, 8));
+	addr1 = upper_32_bits(pci_addr);
+
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r), addr0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r), addr1);
+
+	/* Set the PCIe header descriptor */
+	if (is_io)
+		desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_IO;
+	else
+		desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MEM;
+	desc1 = 0;
+
+	/*
+	 * Whatever Bit [23] is set or not inside DESC0 register of the outbound
+	 * PCIe descriptor, the PCI function number must be set into
+	 * Bits [26:24] of DESC0 anyway.
+	 *
+	 * In Root Complex mode, the function number is always 0 but in Endpoint
+	 * mode, the PCIe controller may support more than one function. This
+	 * function number needs to be set properly into the outbound PCIe
+	 * descriptor.
+	 *
+	 * Besides, setting Bit [23] is mandatory when in Root Complex mode:
+	 * then the driver must provide the bus, resp. device, number in
+	 * Bits [7:0] of DESC1, resp. Bits[31:27] of DESC0. Like the function
+	 * number, the device number is always 0 in Root Complex mode.
+	 *
+	 * However when in Endpoint mode, we can clear Bit [23] of DESC0, hence
+	 * the PCIe controller will use the captured values for the bus and
+	 * device numbers.
+	 */
+	if (pcie->is_rc) {
+		/* The device and function numbers are always 0. */
+		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
+			 CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
+		desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(pcie->bus);
+	} else {
+		/*
+		 * Use captured values for bus and device numbers but still
+		 * need to set the function number.
+		 */
+		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(fn);
+	}
+
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(r), desc0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), desc1);
+
+	/* Set the CPU address */
+	cpu_addr -= pcie->mem_res->start;
+	addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) |
+		(lower_32_bits(cpu_addr) & GENMASK(31, 8));
+	addr1 = upper_32_bits(cpu_addr);
+
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), addr0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), addr1);
+}
+
+void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn,
+						  u32 r, u64 cpu_addr)
+{
+	u32 addr0, addr1, desc0, desc1;
+
+	desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG;
+	desc1 = 0;
+
+	/* See cdns_pcie_set_outbound_region() comments above. */
+	if (pcie->is_rc) {
+		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
+			 CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
+		desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(pcie->bus);
+	} else {
+		desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(fn);
+	}
+
+	/* Set the CPU address */
+	cpu_addr -= pcie->mem_res->start;
+	addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(17) |
+		(lower_32_bits(cpu_addr) & GENMASK(31, 8));
+	addr1 = upper_32_bits(cpu_addr);
+
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r), 0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r), 0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(r), desc0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), desc1);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), addr0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), addr1);
+}
+
+void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r)
+{
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r), 0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r), 0);
+
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(r), 0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), 0);
+
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), 0);
+	cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), 0);
+}
diff --git a/drivers/pci/cadence/pcie-cadence.h b/drivers/pci/cadence/pcie-cadence.h
new file mode 100644
index 0000000..4bb2733
--- /dev/null
+++ b/drivers/pci/cadence/pcie-cadence.h
@@ -0,0 +1,311 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe controller driver.
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#ifndef _PCIE_CADENCE_H
+#define _PCIE_CADENCE_H
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+/*
+ * Local Management Registers
+ */
+#define CDNS_PCIE_LM_BASE	0x00100000
+
+/* Vendor ID Register */
+#define CDNS_PCIE_LM_ID		(CDNS_PCIE_LM_BASE + 0x0044)
+#define  CDNS_PCIE_LM_ID_VENDOR_MASK	GENMASK(15, 0)
+#define  CDNS_PCIE_LM_ID_VENDOR_SHIFT	0
+#define  CDNS_PCIE_LM_ID_VENDOR(vid) \
+	(((vid) << CDNS_PCIE_LM_ID_VENDOR_SHIFT) & CDNS_PCIE_LM_ID_VENDOR_MASK)
+#define  CDNS_PCIE_LM_ID_SUBSYS_MASK	GENMASK(31, 16)
+#define  CDNS_PCIE_LM_ID_SUBSYS_SHIFT	16
+#define  CDNS_PCIE_LM_ID_SUBSYS(sub) \
+	(((sub) << CDNS_PCIE_LM_ID_SUBSYS_SHIFT) & CDNS_PCIE_LM_ID_SUBSYS_MASK)
+
+/* Root Port Requestor ID Register */
+#define CDNS_PCIE_LM_RP_RID	(CDNS_PCIE_LM_BASE + 0x0228)
+#define  CDNS_PCIE_LM_RP_RID_MASK	GENMASK(15, 0)
+#define  CDNS_PCIE_LM_RP_RID_SHIFT	0
+#define  CDNS_PCIE_LM_RP_RID_(rid) \
+	(((rid) << CDNS_PCIE_LM_RP_RID_SHIFT) & CDNS_PCIE_LM_RP_RID_MASK)
+
+/* Endpoint Bus and Device Number Register */
+#define CDNS_PCIE_LM_EP_ID	(CDNS_PCIE_LM_BASE + 0x022c)
+#define  CDNS_PCIE_LM_EP_ID_DEV_MASK	GENMASK(4, 0)
+#define  CDNS_PCIE_LM_EP_ID_DEV_SHIFT	0
+#define  CDNS_PCIE_LM_EP_ID_BUS_MASK	GENMASK(15, 8)
+#define  CDNS_PCIE_LM_EP_ID_BUS_SHIFT	8
+
+/* Endpoint Function f BAR b Configuration Registers */
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
+	(CDNS_PCIE_LM_BASE + 0x0244 + (fn) * 0x0008)
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \
+	(GENMASK(4, 0) << ((b) * 8))
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
+	(((a) << ((b) * 8)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b))
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b) \
+	(GENMASK(7, 5) << ((b) * 8))
+#define  CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, c) \
+	(((c) << ((b) * 8 + 5)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b))
+
+/* Endpoint Function Configuration Register */
+#define CDNS_PCIE_LM_EP_FUNC_CFG	(CDNS_PCIE_LM_BASE + 0x02c0)
+
+/* Root Complex BAR Configuration Register */
+#define CDNS_PCIE_LM_RC_BAR_CFG	(CDNS_PCIE_LM_BASE + 0x0300)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK	GENMASK(5, 0)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE(a) \
+	(((a) << 0) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK		GENMASK(8, 6)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(c) \
+	(((c) << 6) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK	GENMASK(13, 9)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE(a) \
+	(((a) << 9) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK		GENMASK(16, 14)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(c) \
+	(((c) << 14) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE	BIT(17)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_32BITS	0
+#define  CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS	BIT(18)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE		BIT(19)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_16BITS		0
+#define  CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS		BIT(20)
+#define  CDNS_PCIE_LM_RC_BAR_CFG_CHECK_ENABLE		BIT(31)
+
+/* BAR control values applicable to both Endpoint Function and Root Complex */
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED		0x0
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS		0x1
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS		0x4
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS	0x5
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS		0x6
+#define  CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS	0x7
+
+
+/*
+ * Endpoint Function Registers (PCI configuration space for endpoint functions)
+ */
+#define CDNS_PCIE_EP_FUNC_BASE(fn)	(((fn) << 12) & GENMASK(19, 12))
+
+#define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET	0x90
+
+/*
+ * Root Port Registers (PCI configuration space for the root port function)
+ */
+#define CDNS_PCIE_RP_BASE	0x00200000
+
+
+/*
+ * Address Translation Registers
+ */
+#define CDNS_PCIE_AT_BASE	0x00400000
+
+/* Region r Outbound AXI to PCIe Address Translation Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
+	(CDNS_PCIE_AT_BASE + 0x0000 + ((r) & 0x1f) * 0x0020)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK	GENMASK(5, 0)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) \
+	(((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK	GENMASK(19, 12)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \
+	(((devfn) << 12) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK	GENMASK(27, 20)
+#define  CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(bus) \
+	(((bus) << 20) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK)
+
+/* Region r Outbound AXI to PCIe Address Translation Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r) \
+	(CDNS_PCIE_AT_BASE + 0x0004 + ((r) & 0x1f) * 0x0020)
+
+/* Region r Outbound PCIe Descriptor Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_DESC0(r) \
+	(CDNS_PCIE_AT_BASE + 0x0008 + ((r) & 0x1f) * 0x0020)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK		GENMASK(3, 0)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MEM		0x2
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_IO		0x6
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0	0xa
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1	0xb
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG	0xc
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_VENDOR_MSG	0xd
+/* Bit 23 MUST be set in RC mode. */
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID	BIT(23)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK	GENMASK(31, 24)
+#define  CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(devfn) \
+	(((devfn) << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK)
+
+/* Region r Outbound PCIe Descriptor Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_DESC1(r)	\
+	(CDNS_PCIE_AT_BASE + 0x000c + ((r) & 0x1f) * 0x0020)
+#define  CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK	GENMASK(7, 0)
+#define  CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus) \
+	((bus) & CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK)
+
+/* Region r AXI Region Base Address Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r) \
+	(CDNS_PCIE_AT_BASE + 0x0018 + ((r) & 0x1f) * 0x0020)
+#define  CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK	GENMASK(5, 0)
+#define  CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) \
+	(((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK)
+
+/* Region r AXI Region Base Address Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r) \
+	(CDNS_PCIE_AT_BASE + 0x001c + ((r) & 0x1f) * 0x0020)
+
+/* Root Port BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR0(bar) \
+	(CDNS_PCIE_AT_BASE + 0x0800 + (bar) * 0x0008)
+#define  CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK	GENMASK(5, 0)
+#define  CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(nbits) \
+	(((nbits) - 1) & CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK)
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR1(bar) \
+	(CDNS_PCIE_AT_BASE + 0x0804 + (bar) * 0x0008)
+
+enum cdns_pcie_rp_bar {
+	RP_BAR0,
+	RP_BAR1,
+	RP_NO_BAR
+};
+
+/* Endpoint Function BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
+	(CDNS_PCIE_AT_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008)
+#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \
+	(CDNS_PCIE_AT_BASE + 0x0844 + (fn) * 0x0040 + (bar) * 0x0008)
+
+/* Normal/Vendor specific message access: offset inside some outbound region */
+#define CDNS_PCIE_NORMAL_MSG_ROUTING_MASK	GENMASK(7, 5)
+#define CDNS_PCIE_NORMAL_MSG_ROUTING(route) \
+	(((route) << 5) & CDNS_PCIE_NORMAL_MSG_ROUTING_MASK)
+#define CDNS_PCIE_NORMAL_MSG_CODE_MASK		GENMASK(15, 8)
+#define CDNS_PCIE_NORMAL_MSG_CODE(code) \
+	(((code) << 8) & CDNS_PCIE_NORMAL_MSG_CODE_MASK)
+#define CDNS_PCIE_MSG_NO_DATA			BIT(16)
+
+enum cdns_pcie_msg_code {
+	MSG_CODE_ASSERT_INTA	= 0x20,
+	MSG_CODE_ASSERT_INTB	= 0x21,
+	MSG_CODE_ASSERT_INTC	= 0x22,
+	MSG_CODE_ASSERT_INTD	= 0x23,
+	MSG_CODE_DEASSERT_INTA	= 0x24,
+	MSG_CODE_DEASSERT_INTB	= 0x25,
+	MSG_CODE_DEASSERT_INTC	= 0x26,
+	MSG_CODE_DEASSERT_INTD	= 0x27,
+};
+
+enum cdns_pcie_msg_routing {
+	/* Route to Root Complex */
+	MSG_ROUTING_TO_RC,
+
+	/* Use Address Routing */
+	MSG_ROUTING_BY_ADDR,
+
+	/* Use ID Routing */
+	MSG_ROUTING_BY_ID,
+
+	/* Route as Broadcast Message from Root Complex */
+	MSG_ROUTING_BCAST,
+
+	/* Local message; terminate at receiver (INTx messages) */
+	MSG_ROUTING_LOCAL,
+
+	/* Gather & route to Root Complex (PME_TO_Ack message) */
+	MSG_ROUTING_GATHER,
+};
+
+/**
+ * struct cdns_pcie - private data for Cadence PCIe controller drivers
+ * @reg_base: IO mapped register base
+ * @mem_res: start/end offsets in the physical system memory to map PCI accesses
+ * @is_rc: tell whether the PCIe controller mode is Root Complex or Endpoint.
+ * @bus: In Root Complex mode, the bus number
+ */
+struct cdns_pcie {
+	void __iomem		*reg_base;
+	struct resource		*mem_res;
+	bool			is_rc;
+	u8			bus;
+};
+
+/* Register access */
+static inline void cdns_pcie_writeb(struct cdns_pcie *pcie, u32 reg, u8 value)
+{
+	writeb(value, pcie->reg_base + reg);
+}
+
+static inline void cdns_pcie_writew(struct cdns_pcie *pcie, u32 reg, u16 value)
+{
+	writew(value, pcie->reg_base + reg);
+}
+
+static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value)
+{
+	writel(value, pcie->reg_base + reg);
+}
+
+static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
+{
+	return readl(pcie->reg_base + reg);
+}
+
+/* Root Port register access */
+static inline void cdns_pcie_rp_writeb(struct cdns_pcie *pcie,
+				       u32 reg, u8 value)
+{
+	writeb(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+}
+
+static inline void cdns_pcie_rp_writew(struct cdns_pcie *pcie,
+				       u32 reg, u16 value)
+{
+	writew(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+}
+
+/* Endpoint Function register access */
+static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn,
+					  u32 reg, u8 value)
+{
+	writeb(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline void cdns_pcie_ep_fn_writew(struct cdns_pcie *pcie, u8 fn,
+					  u32 reg, u16 value)
+{
+	writew(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline void cdns_pcie_ep_fn_writel(struct cdns_pcie *pcie, u8 fn,
+					  u32 reg, u16 value)
+{
+	writel(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline u8 cdns_pcie_ep_fn_readb(struct cdns_pcie *pcie, u8 fn, u32 reg)
+{
+	return readb(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline u16 cdns_pcie_ep_fn_readw(struct cdns_pcie *pcie, u8 fn, u32 reg)
+{
+	return readw(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg)
+{
+	return readl(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn,
+				   u32 r, bool is_io,
+				   u64 cpu_addr, u64 pci_addr, size_t size);
+
+void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn,
+						  u32 r, u64 cpu_addr);
+
+void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r);
+
+#endif /* _PCIE_CADENCE_H */
diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
index 113e094..0f666b1 100644
--- a/drivers/pci/dwc/Kconfig
+++ b/drivers/pci/dwc/Kconfig
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
 menu "DesignWare PCI Core Support"
 
 config PCIE_DW
@@ -15,39 +17,38 @@
 	select PCIE_DW
 
 config PCI_DRA7XX
-	bool "TI DRA7xx PCIe controller"
-	depends on SOC_DRA7XX || COMPILE_TEST
-	depends on (PCI && PCI_MSI_IRQ_DOMAIN) || PCI_ENDPOINT
-	depends on OF && HAS_IOMEM && TI_PIPE3
-	help
-	 Enables support for the PCIe controller in the DRA7xx SoC. There
-	 are two instances of PCIe controller in DRA7xx. This controller can
-	 work either as EP or RC. In order to enable host-specific features
-	 PCI_DRA7XX_HOST must be selected and in order to enable device-
-	 specific features PCI_DRA7XX_EP must be selected. This uses
-	 the DesignWare core.
-
-if PCI_DRA7XX
+	bool
 
 config PCI_DRA7XX_HOST
-	bool "PCI DRA7xx Host Mode"
-	depends on PCI
-	depends on PCI_MSI_IRQ_DOMAIN
+	bool "TI DRA7xx PCIe controller Host Mode"
+	depends on SOC_DRA7XX || COMPILE_TEST
+	depends on PCI && PCI_MSI_IRQ_DOMAIN
+	depends on OF && HAS_IOMEM && TI_PIPE3
 	select PCIE_DW_HOST
+	select PCI_DRA7XX
 	default y
 	help
-	 Enables support for the PCIe controller in the DRA7xx SoC to work in
-	 host mode.
+	  Enables support for the PCIe controller in the DRA7xx SoC to work in
+	  host mode. There are two instances of PCIe controller in DRA7xx.
+	  This controller can work either as EP or RC. In order to enable
+	  host-specific features PCI_DRA7XX_HOST must be selected and in order
+	  to enable device-specific features PCI_DRA7XX_EP must be selected.
+	  This uses the DesignWare core.
 
 config PCI_DRA7XX_EP
-	bool "PCI DRA7xx Endpoint Mode"
+	bool "TI DRA7xx PCIe controller Endpoint Mode"
+	depends on SOC_DRA7XX || COMPILE_TEST
 	depends on PCI_ENDPOINT
+	depends on OF && HAS_IOMEM && TI_PIPE3
 	select PCIE_DW_EP
+	select PCI_DRA7XX
 	help
-	 Enables support for the PCIe controller in the DRA7xx SoC to work in
-	 endpoint mode.
-
-endif
+	  Enables support for the PCIe controller in the DRA7xx SoC to work in
+	  endpoint mode. There are two instances of PCIe controller in DRA7xx.
+	  This controller can work either as EP or RC. In order to enable
+	  host-specific features PCI_DRA7XX_HOST must be selected and in order
+	  to enable device-specific features PCI_DRA7XX_EP must be selected.
+	  This uses the DesignWare core.
 
 config PCIE_DW_PLAT
 	bool "Platform bus based DesignWare PCIe Controller"
@@ -149,15 +150,28 @@
 	  DesignWare core functions to implement the driver.
 
 config PCIE_ARTPEC6
-	bool "Axis ARTPEC-6 PCIe controller"
-	depends on PCI
+	bool
+
+config PCIE_ARTPEC6_HOST
+	bool "Axis ARTPEC-6 PCIe controller Host Mode"
 	depends on MACH_ARTPEC6
-	depends on PCI_MSI_IRQ_DOMAIN
+	depends on PCI && PCI_MSI_IRQ_DOMAIN
 	select PCIEPORTBUS
 	select PCIE_DW_HOST
+	select PCIE_ARTPEC6
 	help
-	  Say Y here to enable PCIe controller support on Axis ARTPEC-6
-	  SoCs.  This PCIe controller uses the DesignWare core.
+	  Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
+	  host mode. This uses the DesignWare core.
+
+config PCIE_ARTPEC6_EP
+	bool "Axis ARTPEC-6 PCIe controller Endpoint Mode"
+	depends on MACH_ARTPEC6
+	depends on PCI_ENDPOINT
+	select PCIE_DW_EP
+	select PCIE_ARTPEC6
+	help
+	  Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
+	  endpoint mode. This uses the DesignWare core.
 
 config PCIE_KIRIN
 	depends on OF && ARM64
diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
index 41ba499..5d2ce72 100644
--- a/drivers/pci/dwc/Makefile
+++ b/drivers/pci/dwc/Makefile
@@ -3,9 +3,7 @@
 obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
 obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
 obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
-ifneq ($(filter y,$(CONFIG_PCI_DRA7XX_HOST) $(CONFIG_PCI_DRA7XX_EP)),)
-        obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
-endif
+obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
@@ -27,4 +25,6 @@
 # ARM64 and use internal ifdefs to only build the pieces we need
 # depending on whether ACPI, the DT driver, or both are enabled.
 
+ifdef CONFIG_PCI
 obj-$(CONFIG_ARM64) += pcie-hisi.o
+endif
diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index e77a4cee..ed8558d 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * pcie-dra7xx - PCIe controller driver for TI DRA7xx SoCs
  *
  * Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com
  *
  * Authors: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/delay.h>
@@ -110,7 +107,7 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
 	writel(value, pcie->base + offset);
 }
 
-static u64 dra7xx_pcie_cpu_addr_fixup(u64 pci_addr)
+static u64 dra7xx_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
 {
 	return pci_addr & DRA7XX_CPU_TO_BUS_ADDR;
 }
@@ -226,6 +223,7 @@ static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
 
 static const struct irq_domain_ops intx_domain_ops = {
 	.map = dra7xx_pcie_intx_map,
+	.xlate = pci_irqd_intx_xlate,
 };
 
 static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
@@ -256,7 +254,8 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
 	struct dra7xx_pcie *dra7xx = arg;
 	struct dw_pcie *pci = dra7xx->pci;
 	struct pcie_port *pp = &pci->pp;
-	u32 reg;
+	unsigned long reg;
+	u32 virq, bit;
 
 	reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
 
@@ -268,8 +267,11 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
 	case INTB:
 	case INTC:
 	case INTD:
-		generic_handle_irq(irq_find_mapping(dra7xx->irq_domain,
-						    ffs(reg)));
+		for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
+			virq = irq_find_mapping(dra7xx->irq_domain, bit);
+			if (virq)
+				generic_handle_irq(virq);
+		}
 		break;
 	}
 
@@ -337,15 +339,6 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
-{
-	u32 reg;
-
-	reg = PCI_BASE_ADDRESS_0 + (4 * bar);
-	dw_pcie_writel_dbi2(pci, reg, 0x0);
-	dw_pcie_writel_dbi(pci, reg, 0x0);
-}
-
 static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -375,7 +368,7 @@ static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie *dra7xx,
 	dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_MSI_XMT, reg);
 }
 
-static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep,
+static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
 				 enum pci_epc_irq_type type, u8 interrupt_num)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -470,6 +463,8 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
 	if (!pci->dbi_base)
 		return -ENOMEM;
 
+	pp->ops = &dra7xx_pcie_host_ops;
+
 	ret = dw_pcie_host_init(pp);
 	if (ret) {
 		dev_err(dev, "failed to initialize host\n");
@@ -599,7 +594,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
 	void __iomem *base;
 	struct resource *res;
 	struct dw_pcie *pci;
-	struct pcie_port *pp;
 	struct dra7xx_pcie *dra7xx;
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
@@ -627,9 +621,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
 	pci->dev = dev;
 	pci->ops = &dw_pcie_ops;
 
-	pp = &pci->pp;
-	pp->ops = &dra7xx_pcie_host_ops;
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		dev_err(dev, "missing IRQ resource: %d\n", irq);
@@ -705,6 +696,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
 
 	switch (mode) {
 	case DW_PCIE_RC_TYPE:
+		if (!IS_ENABLED(CONFIG_PCI_DRA7XX_HOST)) {
+			ret = -ENODEV;
+			goto err_gpio;
+		}
+
 		dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
 				   DEVICE_TYPE_RC);
 		ret = dra7xx_add_pcie_port(dra7xx, pdev);
@@ -712,6 +708,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
 			goto err_gpio;
 		break;
 	case DW_PCIE_EP_TYPE:
+		if (!IS_ENABLED(CONFIG_PCI_DRA7XX_EP)) {
+			ret = -ENODEV;
+			goto err_gpio;
+		}
+
 		dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
 				   DEVICE_TYPE_EP);
 
@@ -810,7 +811,7 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
 }
 #endif
 
-void dra7xx_pcie_shutdown(struct platform_device *pdev)
+static void dra7xx_pcie_shutdown(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
diff --git a/drivers/pci/dwc/pci-exynos.c b/drivers/pci/dwc/pci-exynos.c
index 5596fde..ca62781 100644
--- a/drivers/pci/dwc/pci-exynos.c
+++ b/drivers/pci/dwc/pci-exynos.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe host controller driver for Samsung EXYNOS SoCs
  *
@@ -5,10 +6,6 @@
  *		http://www.samsung.com
  *
  * Author: Jingoo Han <jg1.han@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/clk.h>
@@ -55,49 +52,8 @@
 #define PCIE_ELBI_SLV_ARMISC		0x120
 #define PCIE_ELBI_SLV_DBI_ENABLE	BIT(21)
 
-/* PCIe Purple registers */
-#define PCIE_PHY_GLOBAL_RESET		0x000
-#define PCIE_PHY_COMMON_RESET		0x004
-#define PCIE_PHY_CMN_REG		0x008
-#define PCIE_PHY_MAC_RESET		0x00c
-#define PCIE_PHY_PLL_LOCKED		0x010
-#define PCIE_PHY_TRSVREG_RESET		0x020
-#define PCIE_PHY_TRSV_RESET		0x024
-
-/* PCIe PHY registers */
-#define PCIE_PHY_IMPEDANCE		0x004
-#define PCIE_PHY_PLL_DIV_0		0x008
-#define PCIE_PHY_PLL_BIAS		0x00c
-#define PCIE_PHY_DCC_FEEDBACK		0x014
-#define PCIE_PHY_PLL_DIV_1		0x05c
-#define PCIE_PHY_COMMON_POWER		0x064
-#define PCIE_PHY_COMMON_PD_CMN		BIT(3)
-#define PCIE_PHY_TRSV0_EMP_LVL		0x084
-#define PCIE_PHY_TRSV0_DRV_LVL		0x088
-#define PCIE_PHY_TRSV0_RXCDR		0x0ac
-#define PCIE_PHY_TRSV0_POWER		0x0c4
-#define PCIE_PHY_TRSV0_PD_TSV		BIT(7)
-#define PCIE_PHY_TRSV0_LVCC		0x0dc
-#define PCIE_PHY_TRSV1_EMP_LVL		0x144
-#define PCIE_PHY_TRSV1_RXCDR		0x16c
-#define PCIE_PHY_TRSV1_POWER		0x184
-#define PCIE_PHY_TRSV1_PD_TSV		BIT(7)
-#define PCIE_PHY_TRSV1_LVCC		0x19c
-#define PCIE_PHY_TRSV2_EMP_LVL		0x204
-#define PCIE_PHY_TRSV2_RXCDR		0x22c
-#define PCIE_PHY_TRSV2_POWER		0x244
-#define PCIE_PHY_TRSV2_PD_TSV		BIT(7)
-#define PCIE_PHY_TRSV2_LVCC		0x25c
-#define PCIE_PHY_TRSV3_EMP_LVL		0x2c4
-#define PCIE_PHY_TRSV3_RXCDR		0x2ec
-#define PCIE_PHY_TRSV3_POWER		0x304
-#define PCIE_PHY_TRSV3_PD_TSV		BIT(7)
-#define PCIE_PHY_TRSV3_LVCC		0x31c
-
 struct exynos_pcie_mem_res {
 	void __iomem *elbi_base;   /* DT 0th resource: PCIe CTRL */
-	void __iomem *phy_base;    /* DT 1st resource: PHY CTRL */
-	void __iomem *block_base;  /* DT 2nd resource: PHY ADDITIONAL CTRL */
 };
 
 struct exynos_pcie_clk_res {
@@ -112,8 +68,6 @@ struct exynos_pcie {
 	const struct exynos_pcie_ops	*ops;
 	int				reset_gpio;
 
-	/* For Generic PHY Framework */
-	bool				using_phy;
 	struct phy			*phy;
 };
 
@@ -141,20 +95,6 @@ static int exynos5440_pcie_get_mem_resources(struct platform_device *pdev,
 	if (IS_ERR(ep->mem_res->elbi_base))
 		return PTR_ERR(ep->mem_res->elbi_base);
 
-	/* If using the PHY framework, doesn't need to get other resource */
-	if (ep->using_phy)
-		return 0;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	ep->mem_res->phy_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(ep->mem_res->phy_base))
-		return PTR_ERR(ep->mem_res->phy_base);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
-	ep->mem_res->block_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(ep->mem_res->block_base))
-		return PTR_ERR(ep->mem_res->block_base);
-
 	return 0;
 }
 
@@ -279,111 +219,6 @@ static void exynos_pcie_deassert_core_reset(struct exynos_pcie *ep)
 	exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_NONSTICKY_RESET);
 	exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_APP_INIT_RESET);
 	exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_APP_INIT_RESET);
-	exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_MAC_RESET);
-}
-
-static void exynos_pcie_assert_phy_reset(struct exynos_pcie *ep)
-{
-	exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_MAC_RESET);
-	exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_GLOBAL_RESET);
-}
-
-static void exynos_pcie_deassert_phy_reset(struct exynos_pcie *ep)
-{
-	exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_GLOBAL_RESET);
-	exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_PWR_RESET);
-	exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_COMMON_RESET);
-	exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_CMN_REG);
-	exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_TRSVREG_RESET);
-	exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_TRSV_RESET);
-}
-
-static void exynos_pcie_power_on_phy(struct exynos_pcie *ep)
-{
-	u32 val;
-
-	val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_COMMON_POWER);
-	val &= ~PCIE_PHY_COMMON_PD_CMN;
-	exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_COMMON_POWER);
-
-	val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV0_POWER);
-	val &= ~PCIE_PHY_TRSV0_PD_TSV;
-	exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV0_POWER);
-
-	val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV1_POWER);
-	val &= ~PCIE_PHY_TRSV1_PD_TSV;
-	exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV1_POWER);
-
-	val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV2_POWER);
-	val &= ~PCIE_PHY_TRSV2_PD_TSV;
-	exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV2_POWER);
-
-	val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV3_POWER);
-	val &= ~PCIE_PHY_TRSV3_PD_TSV;
-	exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV3_POWER);
-}
-
-static void exynos_pcie_power_off_phy(struct exynos_pcie *ep)
-{
-	u32 val;
-
-	val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_COMMON_POWER);
-	val |= PCIE_PHY_COMMON_PD_CMN;
-	exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_COMMON_POWER);
-
-	val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV0_POWER);
-	val |= PCIE_PHY_TRSV0_PD_TSV;
-	exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV0_POWER);
-
-	val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV1_POWER);
-	val |= PCIE_PHY_TRSV1_PD_TSV;
-	exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV1_POWER);
-
-	val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV2_POWER);
-	val |= PCIE_PHY_TRSV2_PD_TSV;
-	exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV2_POWER);
-
-	val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV3_POWER);
-	val |= PCIE_PHY_TRSV3_PD_TSV;
-	exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV3_POWER);
-}
-
-static void exynos_pcie_init_phy(struct exynos_pcie *ep)
-{
-	/* DCC feedback control off */
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x29, PCIE_PHY_DCC_FEEDBACK);
-
-	/* set TX/RX impedance */
-	exynos_pcie_writel(ep->mem_res->phy_base, 0xd5, PCIE_PHY_IMPEDANCE);
-
-	/* set 50Mhz PHY clock */
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x14, PCIE_PHY_PLL_DIV_0);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x12, PCIE_PHY_PLL_DIV_1);
-
-	/* set TX Differential output for lane 0 */
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x7f, PCIE_PHY_TRSV0_DRV_LVL);
-
-	/* set TX Pre-emphasis Level Control for lane 0 to minimum */
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x0, PCIE_PHY_TRSV0_EMP_LVL);
-
-	/* set RX clock and data recovery bandwidth */
-	exynos_pcie_writel(ep->mem_res->phy_base, 0xe7, PCIE_PHY_PLL_BIAS);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV0_RXCDR);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV1_RXCDR);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV2_RXCDR);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV3_RXCDR);
-
-	/* change TX Pre-emphasis Level Control for lanes */
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV0_EMP_LVL);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV1_EMP_LVL);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV2_EMP_LVL);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV3_EMP_LVL);
-
-	/* set LVCC */
-	exynos_pcie_writel(ep->mem_res->phy_base, 0x20, PCIE_PHY_TRSV0_LVCC);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV1_LVCC);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV2_LVCC);
-	exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV3_LVCC);
 }
 
 static void exynos_pcie_assert_reset(struct exynos_pcie *ep)
@@ -401,7 +236,6 @@ static int exynos_pcie_establish_link(struct exynos_pcie *ep)
 	struct dw_pcie *pci = ep->pci;
 	struct pcie_port *pp = &pci->pp;
 	struct device *dev = pci->dev;
-	u32 val;
 
 	if (dw_pcie_link_up(pci)) {
 		dev_err(dev, "Link already up\n");
@@ -410,32 +244,13 @@ static int exynos_pcie_establish_link(struct exynos_pcie *ep)
 
 	exynos_pcie_assert_core_reset(ep);
 
-	if (ep->using_phy) {
-		phy_reset(ep->phy);
+	phy_reset(ep->phy);
 
-		exynos_pcie_writel(ep->mem_res->elbi_base, 1,
-				PCIE_PWR_RESET);
+	exynos_pcie_writel(ep->mem_res->elbi_base, 1,
+			PCIE_PWR_RESET);
 
-		phy_power_on(ep->phy);
-		phy_init(ep->phy);
-	} else {
-		exynos_pcie_assert_phy_reset(ep);
-		exynos_pcie_deassert_phy_reset(ep);
-		exynos_pcie_power_on_phy(ep);
-		exynos_pcie_init_phy(ep);
-
-		/* pulse for common reset */
-		exynos_pcie_writel(ep->mem_res->block_base, 1,
-					PCIE_PHY_COMMON_RESET);
-		udelay(500);
-		exynos_pcie_writel(ep->mem_res->block_base, 0,
-					PCIE_PHY_COMMON_RESET);
-	}
-
-	/* pulse for common reset */
-	exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_COMMON_RESET);
-	udelay(500);
-	exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_COMMON_RESET);
+	phy_power_on(ep->phy);
+	phy_init(ep->phy);
 
 	exynos_pcie_deassert_core_reset(ep);
 	dw_pcie_setup_rc(pp);
@@ -449,18 +264,7 @@ static int exynos_pcie_establish_link(struct exynos_pcie *ep)
 	if (!dw_pcie_wait_for_link(pci))
 		return 0;
 
-	if (ep->using_phy) {
-		phy_power_off(ep->phy);
-		return -ETIMEDOUT;
-	}
-
-	while (exynos_pcie_readl(ep->mem_res->phy_base,
-				PCIE_PHY_PLL_LOCKED) == 0) {
-		val = exynos_pcie_readl(ep->mem_res->block_base,
-				PCIE_PHY_PLL_LOCKED);
-		dev_info(dev, "PLL Locked: 0x%x\n", val);
-	}
-	exynos_pcie_power_off_phy(ep);
+	phy_power_off(ep->phy);
 	return -ETIMEDOUT;
 }
 
@@ -678,16 +482,13 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
 
 	ep->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
 
-	/* Assume that controller doesn't use the PHY framework */
-	ep->using_phy = false;
-
 	ep->phy = devm_of_phy_get(dev, np, NULL);
 	if (IS_ERR(ep->phy)) {
 		if (PTR_ERR(ep->phy) == -EPROBE_DEFER)
 			return PTR_ERR(ep->phy);
-		dev_warn(dev, "Use the 'phy' property. Current DT of pci-exynos was deprecated!!\n");
-	} else
-		ep->using_phy = true;
+
+		ep->phy = NULL;
+	}
 
 	if (ep->ops && ep->ops->get_mem_resources) {
 		ret = ep->ops->get_mem_resources(pdev, ep);
@@ -695,7 +496,8 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
 			return ret;
 	}
 
-	if (ep->ops && ep->ops->get_clk_resources) {
+	if (ep->ops && ep->ops->get_clk_resources &&
+			ep->ops->init_clk_resources) {
 		ret = ep->ops->get_clk_resources(ep);
 		if (ret)
 			return ret;
@@ -713,8 +515,7 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
 	return 0;
 
 fail_probe:
-	if (ep->using_phy)
-		phy_exit(ep->phy);
+	phy_exit(ep->phy);
 
 	if (ep->ops && ep->ops->deinit_clk_resources)
 		ep->ops->deinit_clk_resources(ep);
diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c
index b734835..4fddbd0 100644
--- a/drivers/pci/dwc/pci-imx6.c
+++ b/drivers/pci/dwc/pci-imx6.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe host controller driver for Freescale i.MX6 SoCs
  *
@@ -5,10 +6,6 @@
  *		http://www.kosagi.com
  *
  * Author: Sean Cross <xobs@kosagi.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/clk.h>
diff --git a/drivers/pci/dwc/pci-keystone-dw.c b/drivers/pci/dwc/pci-keystone-dw.c
index 2fb20b8..99a0e70 100644
--- a/drivers/pci/dwc/pci-keystone-dw.c
+++ b/drivers/pci/dwc/pci-keystone-dw.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * DesignWare application register space functions for Keystone PCI controller
  *
@@ -5,11 +6,6 @@
  *		http://www.ti.com
  *
  * Author: Murali Karicheri <m-karicheri2@ti.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/irq.h>
diff --git a/drivers/pci/dwc/pci-keystone.c b/drivers/pci/dwc/pci-keystone.c
index 5bee3af..d4f8ab9 100644
--- a/drivers/pci/dwc/pci-keystone.c
+++ b/drivers/pci/dwc/pci-keystone.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe host controller driver for Texas Instruments Keystone SoCs
  *
@@ -6,10 +7,6 @@
  *
  * Author: Murali Karicheri <m-karicheri2@ti.com>
  * Implementation based on pci-exynos.c and pcie-designware.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/irqchip/chained_irq.h>
@@ -178,7 +175,7 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
 	}
 
 	/* interrupt controller is in a child node */
-	*np_temp = of_find_node_by_name(np_pcie, controller);
+	*np_temp = of_get_child_by_name(np_pcie, controller);
 	if (!(*np_temp)) {
 		dev_err(dev, "Node for %s is absent\n", controller);
 		return -EINVAL;
@@ -187,6 +184,7 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
 	temp = of_irq_count(*np_temp);
 	if (!temp) {
 		dev_err(dev, "No IRQ entries in %s\n", controller);
+		of_node_put(*np_temp);
 		return -EINVAL;
 	}
 
@@ -204,6 +202,8 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
 			break;
 	}
 
+	of_node_put(*np_temp);
+
 	if (temp) {
 		*num_irqs = temp;
 		return 0;
diff --git a/drivers/pci/dwc/pci-keystone.h b/drivers/pci/dwc/pci-keystone.h
index 30b7bc2..1dd1f3e 100644
--- a/drivers/pci/dwc/pci-keystone.h
+++ b/drivers/pci/dwc/pci-keystone.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Keystone PCI Controller's common includes
  *
@@ -5,11 +6,6 @@
  *		http://www.ti.com
  *
  * Author: Murali Karicheri <m-karicheri2@ti.com>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #define MAX_MSI_HOST_IRQS		8
diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c
index 8f34c2f..a7b4159 100644
--- a/drivers/pci/dwc/pci-layerscape.c
+++ b/drivers/pci/dwc/pci-layerscape.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe host controller driver for Freescale Layerscape SoCs
  *
  * Copyright (C) 2014 Freescale Semiconductor.
  *
  * Author: Minghuan Lian <Minghuan.Lian@freescale.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/pci/dwc/pcie-armada8k.c b/drivers/pci/dwc/pcie-armada8k.c
index 370d057..b587352 100644
--- a/drivers/pci/dwc/pcie-armada8k.c
+++ b/drivers/pci/dwc/pcie-armada8k.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe host controller driver for Marvell Armada-8K SoCs
  *
@@ -7,10 +8,6 @@
  *
  * Author: Yehuda Yitshak <yehuday@marvell.com>
  * Author: Shadi Ammouri <shadi@marvell.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/clk.h>
diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c
index 6653619..93b3df9 100644
--- a/drivers/pci/dwc/pcie-artpec6.c
+++ b/drivers/pci/dwc/pcie-artpec6.c
@@ -1,18 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe host controller driver for Axis ARTPEC-6 SoC
  *
  * Author: Niklas Cassel <niklas.cassel@axis.com>
  *
  * Based on work done by Phil Edworthy <phil@edworthys.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/of_device.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/resource.h>
@@ -26,44 +24,72 @@
 
 #define to_artpec6_pcie(x)	dev_get_drvdata((x)->dev)
 
+enum artpec_pcie_variants {
+	ARTPEC6,
+	ARTPEC7,
+};
+
 struct artpec6_pcie {
 	struct dw_pcie		*pci;
 	struct regmap		*regmap;	/* DT axis,syscon-pcie */
 	void __iomem		*phy_base;	/* DT phy */
+	enum artpec_pcie_variants variant;
+	enum dw_pcie_device_mode mode;
 };
 
+struct artpec_pcie_of_data {
+	enum artpec_pcie_variants variant;
+	enum dw_pcie_device_mode mode;
+};
+
+static const struct of_device_id artpec6_pcie_of_match[];
+
 /* PCIe Port Logic registers (memory-mapped) */
 #define PL_OFFSET			0x700
-#define PCIE_PHY_DEBUG_R0		(PL_OFFSET + 0x28)
-#define PCIE_PHY_DEBUG_R1		(PL_OFFSET + 0x2c)
 
-#define MISC_CONTROL_1_OFF		(PL_OFFSET + 0x1bc)
-#define  DBI_RO_WR_EN			1
+#define ACK_F_ASPM_CTRL_OFF		(PL_OFFSET + 0xc)
+#define ACK_N_FTS_MASK			GENMASK(15, 8)
+#define ACK_N_FTS(x)			(((x) << 8) & ACK_N_FTS_MASK)
+
+#define FAST_TRAINING_SEQ_MASK		GENMASK(7, 0)
+#define FAST_TRAINING_SEQ(x)		(((x) << 0) & FAST_TRAINING_SEQ_MASK)
 
 /* ARTPEC-6 specific registers */
 #define PCIECFG				0x18
-#define  PCIECFG_DBG_OEN		(1 << 24)
-#define  PCIECFG_CORE_RESET_REQ		(1 << 21)
-#define  PCIECFG_LTSSM_ENABLE		(1 << 20)
-#define  PCIECFG_CLKREQ_B		(1 << 11)
-#define  PCIECFG_REFCLK_ENABLE		(1 << 10)
-#define  PCIECFG_PLL_ENABLE		(1 << 9)
-#define  PCIECFG_PCLK_ENABLE		(1 << 8)
-#define  PCIECFG_RISRCREN		(1 << 4)
-#define  PCIECFG_MODE_TX_DRV_EN		(1 << 3)
-#define  PCIECFG_CISRREN		(1 << 2)
-#define  PCIECFG_MACRO_ENABLE		(1 << 0)
+#define  PCIECFG_DBG_OEN		BIT(24)
+#define  PCIECFG_CORE_RESET_REQ		BIT(21)
+#define  PCIECFG_LTSSM_ENABLE		BIT(20)
+#define  PCIECFG_DEVICE_TYPE_MASK	GENMASK(19, 16)
+#define  PCIECFG_CLKREQ_B		BIT(11)
+#define  PCIECFG_REFCLK_ENABLE		BIT(10)
+#define  PCIECFG_PLL_ENABLE		BIT(9)
+#define  PCIECFG_PCLK_ENABLE		BIT(8)
+#define  PCIECFG_RISRCREN		BIT(4)
+#define  PCIECFG_MODE_TX_DRV_EN		BIT(3)
+#define  PCIECFG_CISRREN		BIT(2)
+#define  PCIECFG_MACRO_ENABLE		BIT(0)
+/* ARTPEC-7 specific fields */
+#define  PCIECFG_REFCLKSEL		BIT(23)
+#define  PCIECFG_NOC_RESET		BIT(3)
+
+#define PCIESTAT			0x1c
+/* ARTPEC-7 specific fields */
+#define  PCIESTAT_EXTREFCLK		BIT(3)
 
 #define NOCCFG				0x40
-#define NOCCFG_ENABLE_CLK_PCIE		(1 << 4)
-#define NOCCFG_POWER_PCIE_IDLEACK	(1 << 3)
-#define NOCCFG_POWER_PCIE_IDLE		(1 << 2)
-#define NOCCFG_POWER_PCIE_IDLEREQ	(1 << 1)
+#define  NOCCFG_ENABLE_CLK_PCIE		BIT(4)
+#define  NOCCFG_POWER_PCIE_IDLEACK	BIT(3)
+#define  NOCCFG_POWER_PCIE_IDLE		BIT(2)
+#define  NOCCFG_POWER_PCIE_IDLEREQ	BIT(1)
 
 #define PHY_STATUS			0x118
-#define PHY_COSPLLLOCK			(1 << 0)
+#define  PHY_COSPLLLOCK			BIT(0)
 
-#define ARTPEC6_CPU_TO_BUS_ADDR		0x0fffffff
+#define PHY_TX_ASIC_OUT			0x4040
+#define  PHY_TX_ASIC_OUT_TX_ACK		BIT(0)
+
+#define PHY_RX_ASIC_OUT			0x405c
+#define  PHY_RX_ASIC_OUT_ACK		BIT(0)
 
 static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset)
 {
@@ -78,22 +104,123 @@ static void artpec6_pcie_writel(struct artpec6_pcie *artpec6_pcie, u32 offset, u
 	regmap_write(artpec6_pcie->regmap, offset, val);
 }
 
-static u64 artpec6_pcie_cpu_addr_fixup(u64 pci_addr)
+static u64 artpec6_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
 {
-	return pci_addr & ARTPEC6_CPU_TO_BUS_ADDR;
+	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
+	struct pcie_port *pp = &pci->pp;
+	struct dw_pcie_ep *ep = &pci->ep;
+
+	switch (artpec6_pcie->mode) {
+	case DW_PCIE_RC_TYPE:
+		return pci_addr - pp->cfg0_base;
+	case DW_PCIE_EP_TYPE:
+		return pci_addr - ep->phys_base;
+	default:
+		dev_err(pci->dev, "UNKNOWN device type\n");
+	}
+	return pci_addr;
 }
 
-static int artpec6_pcie_establish_link(struct artpec6_pcie *artpec6_pcie)
+static int artpec6_pcie_establish_link(struct dw_pcie *pci)
+{
+	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
+	u32 val;
+
+	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
+	val |= PCIECFG_LTSSM_ENABLE;
+	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+
+	return 0;
+}
+
+static void artpec6_pcie_stop_link(struct dw_pcie *pci)
+{
+	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
+	u32 val;
+
+	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
+	val &= ~PCIECFG_LTSSM_ENABLE;
+	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+}
+
+static const struct dw_pcie_ops dw_pcie_ops = {
+	.cpu_addr_fixup = artpec6_pcie_cpu_addr_fixup,
+	.start_link = artpec6_pcie_establish_link,
+	.stop_link = artpec6_pcie_stop_link,
+};
+
+static void artpec6_pcie_wait_for_phy_a6(struct artpec6_pcie *artpec6_pcie)
 {
 	struct dw_pcie *pci = artpec6_pcie->pci;
-	struct pcie_port *pp = &pci->pp;
+	struct device *dev = pci->dev;
 	u32 val;
 	unsigned int retries;
 
-	/* Hold DW core in reset */
-	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
-	val |= PCIECFG_CORE_RESET_REQ;
-	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+	retries = 50;
+	do {
+		usleep_range(1000, 2000);
+		val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
+		retries--;
+	} while (retries &&
+		(val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
+	if (!retries)
+		dev_err(dev, "PCIe clock manager did not leave idle state\n");
+
+	retries = 50;
+	do {
+		usleep_range(1000, 2000);
+		val = readl(artpec6_pcie->phy_base + PHY_STATUS);
+		retries--;
+	} while (retries && !(val & PHY_COSPLLLOCK));
+	if (!retries)
+		dev_err(dev, "PHY PLL did not lock\n");
+}
+
+static void artpec6_pcie_wait_for_phy_a7(struct artpec6_pcie *artpec6_pcie)
+{
+	struct dw_pcie *pci = artpec6_pcie->pci;
+	struct device *dev = pci->dev;
+	u32 val;
+	u16 phy_status_tx, phy_status_rx;
+	unsigned int retries;
+
+	retries = 50;
+	do {
+		usleep_range(1000, 2000);
+		val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
+		retries--;
+	} while (retries &&
+		(val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
+	if (!retries)
+		dev_err(dev, "PCIe clock manager did not leave idle state\n");
+
+	retries = 50;
+	do {
+		usleep_range(1000, 2000);
+		phy_status_tx = readw(artpec6_pcie->phy_base + PHY_TX_ASIC_OUT);
+		phy_status_rx = readw(artpec6_pcie->phy_base + PHY_RX_ASIC_OUT);
+		retries--;
+	} while (retries && ((phy_status_tx & PHY_TX_ASIC_OUT_TX_ACK) ||
+				(phy_status_rx & PHY_RX_ASIC_OUT_ACK)));
+	if (!retries)
+		dev_err(dev, "PHY did not enter Pn state\n");
+}
+
+static void artpec6_pcie_wait_for_phy(struct artpec6_pcie *artpec6_pcie)
+{
+	switch (artpec6_pcie->variant) {
+	case ARTPEC6:
+		artpec6_pcie_wait_for_phy_a6(artpec6_pcie);
+		break;
+	case ARTPEC7:
+		artpec6_pcie_wait_for_phy_a7(artpec6_pcie);
+		break;
+	}
+}
+
+static void artpec6_pcie_init_phy_a6(struct artpec6_pcie *artpec6_pcie)
+{
+	u32 val;
 
 	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
 	val |=  PCIECFG_RISRCREN |	/* Receiver term. 50 Ohm */
@@ -119,45 +246,110 @@ static int artpec6_pcie_establish_link(struct artpec6_pcie *artpec6_pcie)
 	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
 	val &= ~NOCCFG_POWER_PCIE_IDLEREQ;
 	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
+}
 
-	retries = 50;
-	do {
-		usleep_range(1000, 2000);
-		val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
-		retries--;
-	} while (retries &&
-		(val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
+static void artpec6_pcie_init_phy_a7(struct artpec6_pcie *artpec6_pcie)
+{
+	struct dw_pcie *pci = artpec6_pcie->pci;
+	u32 val;
+	bool extrefclk;
 
-	retries = 50;
-	do {
-		usleep_range(1000, 2000);
-		val = readl(artpec6_pcie->phy_base + PHY_STATUS);
-		retries--;
-	} while (retries && !(val & PHY_COSPLLLOCK));
+	/* Check if external reference clock is connected */
+	val = artpec6_pcie_readl(artpec6_pcie, PCIESTAT);
+	extrefclk = !!(val & PCIESTAT_EXTREFCLK);
+	dev_dbg(pci->dev, "Using reference clock: %s\n",
+		extrefclk ? "external" : "internal");
 
-	/* Take DW core out of reset */
 	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
-	val &= ~PCIECFG_CORE_RESET_REQ;
+	val |=  PCIECFG_RISRCREN |	/* Receiver term. 50 Ohm */
+		PCIECFG_PCLK_ENABLE;
+	if (extrefclk)
+		val |= PCIECFG_REFCLKSEL;
+	else
+		val &= ~PCIECFG_REFCLKSEL;
+	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+	usleep_range(10, 20);
+
+	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
+	val |= NOCCFG_ENABLE_CLK_PCIE;
+	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
+	usleep_range(20, 30);
+
+	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
+	val &= ~NOCCFG_POWER_PCIE_IDLEREQ;
+	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
+}
+
+static void artpec6_pcie_init_phy(struct artpec6_pcie *artpec6_pcie)
+{
+	switch (artpec6_pcie->variant) {
+	case ARTPEC6:
+		artpec6_pcie_init_phy_a6(artpec6_pcie);
+		break;
+	case ARTPEC7:
+		artpec6_pcie_init_phy_a7(artpec6_pcie);
+		break;
+	}
+}
+
+static void artpec6_pcie_set_nfts(struct artpec6_pcie *artpec6_pcie)
+{
+	struct dw_pcie *pci = artpec6_pcie->pci;
+	u32 val;
+
+	if (artpec6_pcie->variant != ARTPEC7)
+		return;
+
+	/*
+	 * Increase the N_FTS (Number of Fast Training Sequences)
+	 * to be transmitted when transitioning from L0s to L0.
+	 */
+	val = dw_pcie_readl_dbi(pci, ACK_F_ASPM_CTRL_OFF);
+	val &= ~ACK_N_FTS_MASK;
+	val |= ACK_N_FTS(180);
+	dw_pcie_writel_dbi(pci, ACK_F_ASPM_CTRL_OFF, val);
+
+	/*
+	 * Set the Number of Fast Training Sequences that the core
+	 * advertises as its N_FTS during Gen2 or Gen3 link training.
+	 */
+	val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
+	val &= ~FAST_TRAINING_SEQ_MASK;
+	val |= FAST_TRAINING_SEQ(180);
+	dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+}
+
+static void artpec6_pcie_assert_core_reset(struct artpec6_pcie *artpec6_pcie)
+{
+	u32 val;
+
+	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
+	switch (artpec6_pcie->variant) {
+	case ARTPEC6:
+		val |= PCIECFG_CORE_RESET_REQ;
+		break;
+	case ARTPEC7:
+		val &= ~PCIECFG_NOC_RESET;
+		break;
+	}
+	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+}
+
+static void artpec6_pcie_deassert_core_reset(struct artpec6_pcie *artpec6_pcie)
+{
+	u32 val;
+
+	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
+	switch (artpec6_pcie->variant) {
+	case ARTPEC6:
+		val &= ~PCIECFG_CORE_RESET_REQ;
+		break;
+	case ARTPEC7:
+		val |= PCIECFG_NOC_RESET;
+		break;
+	}
 	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
 	usleep_range(100, 200);
-
-	/* setup root complex */
-	dw_pcie_setup_rc(pp);
-
-	/* assert LTSSM enable */
-	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
-	val |= PCIECFG_LTSSM_ENABLE;
-	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
-
-	/* check if the link is up or not */
-	if (!dw_pcie_wait_for_link(pci))
-		return 0;
-
-	dev_dbg(pci->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
-		dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
-		dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
-
-	return -ETIMEDOUT;
 }
 
 static void artpec6_pcie_enable_interrupts(struct artpec6_pcie *artpec6_pcie)
@@ -174,7 +366,14 @@ static int artpec6_pcie_host_init(struct pcie_port *pp)
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
 
-	artpec6_pcie_establish_link(artpec6_pcie);
+	artpec6_pcie_assert_core_reset(artpec6_pcie);
+	artpec6_pcie_init_phy(artpec6_pcie);
+	artpec6_pcie_deassert_core_reset(artpec6_pcie);
+	artpec6_pcie_wait_for_phy(artpec6_pcie);
+	artpec6_pcie_set_nfts(artpec6_pcie);
+	dw_pcie_setup_rc(pp);
+	artpec6_pcie_establish_link(pci);
+	dw_pcie_wait_for_link(pci);
 	artpec6_pcie_enable_interrupts(artpec6_pcie);
 
 	return 0;
@@ -230,10 +429,78 @@ static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
 	return 0;
 }
 
-static const struct dw_pcie_ops dw_pcie_ops = {
-	.cpu_addr_fixup = artpec6_pcie_cpu_addr_fixup,
+static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
+	enum pci_barno bar;
+
+	artpec6_pcie_assert_core_reset(artpec6_pcie);
+	artpec6_pcie_init_phy(artpec6_pcie);
+	artpec6_pcie_deassert_core_reset(artpec6_pcie);
+	artpec6_pcie_wait_for_phy(artpec6_pcie);
+	artpec6_pcie_set_nfts(artpec6_pcie);
+
+	for (bar = BAR_0; bar <= BAR_5; bar++)
+		dw_pcie_ep_reset_bar(pci, bar);
+}
+
+static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
+				  enum pci_epc_irq_type type, u8 interrupt_num)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+
+	switch (type) {
+	case PCI_EPC_IRQ_LEGACY:
+		dev_err(pci->dev, "EP cannot trigger legacy IRQs\n");
+		return -EINVAL;
+	case PCI_EPC_IRQ_MSI:
+		return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
+	default:
+		dev_err(pci->dev, "UNKNOWN IRQ type\n");
+	}
+
+	return 0;
+}
+
+static struct dw_pcie_ep_ops pcie_ep_ops = {
+	.ep_init = artpec6_pcie_ep_init,
+	.raise_irq = artpec6_pcie_raise_irq,
 };
 
+static int artpec6_add_pcie_ep(struct artpec6_pcie *artpec6_pcie,
+			       struct platform_device *pdev)
+{
+	int ret;
+	struct dw_pcie_ep *ep;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+	struct dw_pcie *pci = artpec6_pcie->pci;
+
+	ep = &pci->ep;
+	ep->ops = &pcie_ep_ops;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
+	pci->dbi_base2 = devm_ioremap(dev, res->start, resource_size(res));
+	if (!pci->dbi_base2)
+		return -ENOMEM;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+	if (!res)
+		return -EINVAL;
+
+	ep->phys_base = res->start;
+	ep->addr_size = resource_size(res);
+
+	ret = dw_pcie_ep_init(ep);
+	if (ret) {
+		dev_err(dev, "failed to initialize endpoint\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int artpec6_pcie_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -242,6 +509,18 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
 	struct resource *dbi_base;
 	struct resource *phy_base;
 	int ret;
+	const struct of_device_id *match;
+	const struct artpec_pcie_of_data *data;
+	enum artpec_pcie_variants variant;
+	enum dw_pcie_device_mode mode;
+
+	match = of_match_device(artpec6_pcie_of_match, dev);
+	if (!match)
+		return -EINVAL;
+
+	data = (struct artpec_pcie_of_data *)match->data;
+	variant = (enum artpec_pcie_variants)data->variant;
+	mode = (enum dw_pcie_device_mode)data->mode;
 
 	artpec6_pcie = devm_kzalloc(dev, sizeof(*artpec6_pcie), GFP_KERNEL);
 	if (!artpec6_pcie)
@@ -255,6 +534,8 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
 	pci->ops = &dw_pcie_ops;
 
 	artpec6_pcie->pci = pci;
+	artpec6_pcie->variant = variant;
+	artpec6_pcie->mode = mode;
 
 	dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
 	pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
@@ -274,15 +555,73 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, artpec6_pcie);
 
-	ret = artpec6_add_pcie_port(artpec6_pcie, pdev);
-	if (ret < 0)
-		return ret;
+	switch (artpec6_pcie->mode) {
+	case DW_PCIE_RC_TYPE:
+		if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST))
+			return -ENODEV;
+
+		ret = artpec6_add_pcie_port(artpec6_pcie, pdev);
+		if (ret < 0)
+			return ret;
+		break;
+	case DW_PCIE_EP_TYPE: {
+		u32 val;
+
+		if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP))
+			return -ENODEV;
+
+		val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
+		val &= ~PCIECFG_DEVICE_TYPE_MASK;
+		artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+		ret = artpec6_add_pcie_ep(artpec6_pcie, pdev);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	default:
+		dev_err(dev, "INVALID device type %d\n", artpec6_pcie->mode);
+	}
 
 	return 0;
 }
 
+static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data = {
+	.variant = ARTPEC6,
+	.mode = DW_PCIE_RC_TYPE,
+};
+
+static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data = {
+	.variant = ARTPEC6,
+	.mode = DW_PCIE_EP_TYPE,
+};
+
+static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data = {
+	.variant = ARTPEC7,
+	.mode = DW_PCIE_RC_TYPE,
+};
+
+static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data = {
+	.variant = ARTPEC7,
+	.mode = DW_PCIE_EP_TYPE,
+};
+
 static const struct of_device_id artpec6_pcie_of_match[] = {
-	{ .compatible = "axis,artpec6-pcie", },
+	{
+		.compatible = "axis,artpec6-pcie",
+		.data = &artpec6_pcie_rc_of_data,
+	},
+	{
+		.compatible = "axis,artpec6-pcie-ep",
+		.data = &artpec6_pcie_ep_of_data,
+	},
+	{
+		.compatible = "axis,artpec7-pcie",
+		.data = &artpec7_pcie_rc_of_data,
+	},
+	{
+		.compatible = "axis,artpec7-pcie-ep",
+		.data = &artpec7_pcie_ep_of_data,
+	},
 	{},
 };
 
diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c
index d53d5f1..3a6feef 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /**
  * Synopsys DesignWare PCIe Endpoint controller driver
  *
  * Copyright (C) 2017 Texas Instruments
  * Author: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 of
- * the License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/of.h>
@@ -30,21 +19,24 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
 	pci_epc_linkup(epc);
 }
 
-static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
+void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
 {
 	u32 reg;
 
 	reg = PCI_BASE_ADDRESS_0 + (4 * bar);
+	dw_pcie_dbi_ro_wr_en(pci);
 	dw_pcie_writel_dbi2(pci, reg, 0x0);
 	dw_pcie_writel_dbi(pci, reg, 0x0);
+	dw_pcie_dbi_ro_wr_dis(pci);
 }
 
-static int dw_pcie_ep_write_header(struct pci_epc *epc,
+static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
 				   struct pci_epf_header *hdr)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 
+	dw_pcie_dbi_ro_wr_en(pci);
 	dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, hdr->vendorid);
 	dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, hdr->deviceid);
 	dw_pcie_writeb_dbi(pci, PCI_REVISION_ID, hdr->revid);
@@ -58,6 +50,7 @@ static int dw_pcie_ep_write_header(struct pci_epc *epc,
 	dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_ID, hdr->subsys_id);
 	dw_pcie_writeb_dbi(pci, PCI_INTERRUPT_PIN,
 			   hdr->interrupt_pin);
+	dw_pcie_dbi_ro_wr_dis(pci);
 
 	return 0;
 }
@@ -70,8 +63,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
 	u32 free_win;
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 
-	free_win = find_first_zero_bit(&ep->ib_window_map,
-				       sizeof(ep->ib_window_map));
+	free_win = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows);
 	if (free_win >= ep->num_ib_windows) {
 		dev_err(pci->dev, "no free inbound window\n");
 		return -EINVAL;
@@ -85,7 +77,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
 	}
 
 	ep->bar_to_atu[bar] = free_win;
-	set_bit(free_win, &ep->ib_window_map);
+	set_bit(free_win, ep->ib_window_map);
 
 	return 0;
 }
@@ -96,8 +88,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
 	u32 free_win;
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 
-	free_win = find_first_zero_bit(&ep->ob_window_map,
-				       sizeof(ep->ob_window_map));
+	free_win = find_first_zero_bit(ep->ob_window_map, ep->num_ob_windows);
 	if (free_win >= ep->num_ob_windows) {
 		dev_err(pci->dev, "no free outbound window\n");
 		return -EINVAL;
@@ -106,13 +97,14 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
 	dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
 				  phys_addr, pci_addr, size);
 
-	set_bit(free_win, &ep->ob_window_map);
+	set_bit(free_win, ep->ob_window_map);
 	ep->outbound_addr[free_win] = phys_addr;
 
 	return 0;
 }
 
-static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar)
+static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
+				 enum pci_barno bar)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -121,10 +113,11 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar)
 	dw_pcie_ep_reset_bar(pci, bar);
 
 	dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
-	clear_bit(atu_index, &ep->ib_window_map);
+	clear_bit(atu_index, ep->ib_window_map);
 }
 
-static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar,
+static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
+			      enum pci_barno bar,
 			      dma_addr_t bar_phys, size_t size, int flags)
 {
 	int ret;
@@ -142,8 +135,10 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar,
 	if (ret)
 		return ret;
 
+	dw_pcie_dbi_ro_wr_en(pci);
 	dw_pcie_writel_dbi2(pci, reg, size - 1);
 	dw_pcie_writel_dbi(pci, reg, flags);
+	dw_pcie_dbi_ro_wr_dis(pci);
 
 	return 0;
 }
@@ -163,7 +158,8 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
 	return -EINVAL;
 }
 
-static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr)
+static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
+				  phys_addr_t addr)
 {
 	int ret;
 	u32 atu_index;
@@ -175,10 +171,11 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr)
 		return;
 
 	dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND);
-	clear_bit(atu_index, &ep->ob_window_map);
+	clear_bit(atu_index, ep->ob_window_map);
 }
 
-static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr,
+static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
+			       phys_addr_t addr,
 			       u64 pci_addr, size_t size)
 {
 	int ret;
@@ -194,39 +191,37 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr,
 	return 0;
 }
 
-static int dw_pcie_ep_get_msi(struct pci_epc *epc)
+static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
 {
 	int val;
-	u32 lower_addr;
-	u32 upper_addr;
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 
-	val = dw_pcie_readb_dbi(pci, MSI_MESSAGE_CONTROL);
-	val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
-
-	lower_addr = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
-	upper_addr = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
-
-	if (!(lower_addr || upper_addr))
+	val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
+	if (!(val & MSI_CAP_MSI_EN_MASK))
 		return -EINVAL;
 
+	val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
 	return val;
 }
 
-static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int)
+static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int)
 {
 	int val;
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 
-	val = (encode_int << MSI_CAP_MMC_SHIFT);
+	val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
+	val &= ~MSI_CAP_MMC_MASK;
+	val |= (encode_int << MSI_CAP_MMC_SHIFT) & MSI_CAP_MMC_MASK;
+	dw_pcie_dbi_ro_wr_en(pci);
 	dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val);
+	dw_pcie_dbi_ro_wr_dis(pci);
 
 	return 0;
 }
 
-static int dw_pcie_ep_raise_irq(struct pci_epc *epc,
+static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
 				enum pci_epc_irq_type type, u8 interrupt_num)
 {
 	struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -234,7 +229,7 @@ static int dw_pcie_ep_raise_irq(struct pci_epc *epc,
 	if (!ep->ops->raise_irq)
 		return -EINVAL;
 
-	return ep->ops->raise_irq(ep, type, interrupt_num);
+	return ep->ops->raise_irq(ep, func_no, type, interrupt_num);
 }
 
 static void dw_pcie_ep_stop(struct pci_epc *epc)
@@ -272,10 +267,48 @@ static const struct pci_epc_ops epc_ops = {
 	.stop			= dw_pcie_ep_stop,
 };
 
+int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
+			     u8 interrupt_num)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+	struct pci_epc *epc = ep->epc;
+	u16 msg_ctrl, msg_data;
+	u32 msg_addr_lower, msg_addr_upper;
+	u64 msg_addr;
+	bool has_upper;
+	int ret;
+
+	/* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
+	msg_ctrl = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
+	has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
+	msg_addr_lower = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
+	if (has_upper) {
+		msg_addr_upper = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
+		msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_64);
+	} else {
+		msg_addr_upper = 0;
+		msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_32);
+	}
+	msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
+	ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
+				  epc->mem->page_size);
+	if (ret)
+		return ret;
+
+	writel(msg_data | (interrupt_num - 1), ep->msi_mem);
+
+	dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
+
+	return 0;
+}
+
 void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
 {
 	struct pci_epc *epc = ep->epc;
 
+	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
+			      epc->mem->page_size);
+
 	pci_epc_mem_exit(epc);
 }
 
@@ -298,12 +331,32 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 		dev_err(dev, "unable to read *num-ib-windows* property\n");
 		return ret;
 	}
+	if (ep->num_ib_windows > MAX_IATU_IN) {
+		dev_err(dev, "invalid *num-ib-windows*\n");
+		return -EINVAL;
+	}
 
 	ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows);
 	if (ret < 0) {
 		dev_err(dev, "unable to read *num-ob-windows* property\n");
 		return ret;
 	}
+	if (ep->num_ob_windows > MAX_IATU_OUT) {
+		dev_err(dev, "invalid *num-ob-windows*\n");
+		return -EINVAL;
+	}
+
+	ep->ib_window_map = devm_kzalloc(dev, sizeof(long) *
+					 BITS_TO_LONGS(ep->num_ib_windows),
+					 GFP_KERNEL);
+	if (!ep->ib_window_map)
+		return -ENOMEM;
+
+	ep->ob_window_map = devm_kzalloc(dev, sizeof(long) *
+					 BITS_TO_LONGS(ep->num_ob_windows),
+					 GFP_KERNEL);
+	if (!ep->ob_window_map)
+		return -ENOMEM;
 
 	addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows,
 			    GFP_KERNEL);
@@ -331,6 +384,13 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 		return ret;
 	}
 
+	ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
+					     epc->mem->page_size);
+	if (!ep->msi_mem) {
+		dev_err(dev, "Failed to reserve memory for MSI\n");
+		return -ENOMEM;
+	}
+
 	ep->epc = epc;
 	epc_set_drvdata(epc, ep);
 	dw_pcie_setup(pci);
diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c
index 81e2157..8de2d5c 100644
--- a/drivers/pci/dwc/pcie-designware-host.c
+++ b/drivers/pci/dwc/pcie-designware-host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Synopsys DesignWare PCIe host controller driver
  *
@@ -5,10 +6,6 @@
  *		http://www.samsung.com
  *
  * Author: Jingoo Han <jg1.han@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/irqdomain.h>
@@ -83,10 +80,19 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
 
 void dw_pcie_msi_init(struct pcie_port *pp)
 {
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct device *dev = pci->dev;
+	struct page *page;
 	u64 msi_target;
 
-	pp->msi_data = __get_free_pages(GFP_KERNEL, 0);
-	msi_target = virt_to_phys((void *)pp->msi_data);
+	page = alloc_page(GFP_KERNEL);
+	pp->msi_data = dma_map_page(dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE);
+	if (dma_mapping_error(dev, pp->msi_data)) {
+		dev_err(dev, "failed to map MSI data\n");
+		__free_page(page);
+		return;
+	}
+	msi_target = (u64)pp->msi_data;
 
 	/* program the msi_data */
 	dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4,
@@ -187,7 +193,7 @@ static void dw_msi_setup_msg(struct pcie_port *pp, unsigned int irq, u32 pos)
 	if (pp->ops->get_msi_addr)
 		msi_target = pp->ops->get_msi_addr(pp);
 	else
-		msi_target = virt_to_phys((void *)pp->msi_data);
+		msi_target = (u64)pp->msi_data;
 
 	msg.address_lo = (u32)(msi_target & 0xffffffff);
 	msg.address_hi = (u32)(msi_target >> 32 & 0xffffffff);
diff --git a/drivers/pci/dwc/pcie-designware-plat.c b/drivers/pci/dwc/pcie-designware-plat.c
index 168e238..ebdf28b 100644
--- a/drivers/pci/dwc/pcie-designware-plat.c
+++ b/drivers/pci/dwc/pcie-designware-plat.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe RC driver for Synopsys DesignWare Core
  *
  * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
  *
  * Authors: Joao Pinto <Joao.Pinto@synopsys.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 #include <linux/clk.h>
 #include <linux/delay.h>
diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c
index 88abddd..1b7282e 100644
--- a/drivers/pci/dwc/pcie-designware.c
+++ b/drivers/pci/dwc/pcie-designware.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Synopsys DesignWare PCIe host controller driver
  *
@@ -5,10 +6,6 @@
  *		http://www.samsung.com
  *
  * Author: Jingoo Han <jg1.han@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/delay.h>
@@ -149,7 +146,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
 	u32 retries, val;
 
 	if (pci->ops->cpu_addr_fixup)
-		cpu_addr = pci->ops->cpu_addr_fixup(cpu_addr);
+		cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
 
 	if (pci->iatu_unroll_enabled) {
 		dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr,
diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h
index e5d9d77..11b1386 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Synopsys DesignWare PCIe host controller driver
  *
@@ -5,15 +6,12 @@
  *		http://www.samsung.com
  *
  * Author: Jingoo Han <jg1.han@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #ifndef _PCIE_DESIGNWARE_H
 #define _PCIE_DESIGNWARE_H
 
+#include <linux/dma-mapping.h>
 #include <linux/irq.h>
 #include <linux/msi.h>
 #include <linux/pci.h>
@@ -100,10 +98,14 @@
 
 #define MSI_MESSAGE_CONTROL		0x52
 #define MSI_CAP_MMC_SHIFT		1
+#define MSI_CAP_MMC_MASK		(7 << MSI_CAP_MMC_SHIFT)
 #define MSI_CAP_MME_SHIFT		4
+#define MSI_CAP_MSI_EN_MASK		0x1
 #define MSI_CAP_MME_MASK		(7 << MSI_CAP_MME_SHIFT)
 #define MSI_MESSAGE_ADDR_L32		0x54
 #define MSI_MESSAGE_ADDR_U32		0x58
+#define MSI_MESSAGE_DATA_32		0x58
+#define MSI_MESSAGE_DATA_64		0x5C
 
 /*
  * Maximum number of MSI IRQs can be 256 per controller. But keep
@@ -113,6 +115,10 @@
 #define MAX_MSI_IRQS			32
 #define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)
 
+/* Maximum number of inbound/outbound iATUs */
+#define MAX_IATU_IN			256
+#define MAX_IATU_OUT			256
+
 struct pcie_port;
 struct dw_pcie;
 struct dw_pcie_ep;
@@ -168,7 +174,7 @@ struct pcie_port {
 	const struct dw_pcie_host_ops *ops;
 	int			msi_irq;
 	struct irq_domain	*irq_domain;
-	unsigned long		msi_data;
+	dma_addr_t		msi_data;
 	DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
 };
 
@@ -180,8 +186,8 @@ enum dw_pcie_as_type {
 
 struct dw_pcie_ep_ops {
 	void	(*ep_init)(struct dw_pcie_ep *ep);
-	int	(*raise_irq)(struct dw_pcie_ep *ep, enum pci_epc_irq_type type,
-			     u8 interrupt_num);
+	int	(*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,
+			     enum pci_epc_irq_type type, u8 interrupt_num);
 };
 
 struct dw_pcie_ep {
@@ -192,14 +198,16 @@ struct dw_pcie_ep {
 	size_t			page_size;
 	u8			bar_to_atu[6];
 	phys_addr_t		*outbound_addr;
-	unsigned long		ib_window_map;
-	unsigned long		ob_window_map;
+	unsigned long		*ib_window_map;
+	unsigned long		*ob_window_map;
 	u32			num_ib_windows;
 	u32			num_ob_windows;
+	void __iomem		*msi_mem;
+	phys_addr_t		msi_mem_phys;
 };
 
 struct dw_pcie_ops {
-	u64	(*cpu_addr_fixup)(u64 cpu_addr);
+	u64	(*cpu_addr_fixup)(struct dw_pcie *pcie, u64 cpu_addr);
 	u32	(*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
 			    size_t size);
 	void	(*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
@@ -334,6 +342,9 @@ static inline int dw_pcie_host_init(struct pcie_port *pp)
 void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
 int dw_pcie_ep_init(struct dw_pcie_ep *ep);
 void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
+int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
+			     u8 interrupt_num);
+void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar);
 #else
 static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
 {
@@ -347,5 +358,15 @@ static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
 {
 }
+
+static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
+					   u8 interrupt_num)
+{
+	return 0;
+}
+
+static inline void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
+{
+}
 #endif
 #endif /* _PCIE_DESIGNWARE_H */
diff --git a/drivers/pci/dwc/pcie-hisi.c b/drivers/pci/dwc/pcie-hisi.c
index a201791..2658aae 100644
--- a/drivers/pci/dwc/pcie-hisi.c
+++ b/drivers/pci/dwc/pcie-hisi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe host controller driver for HiSilicon SoCs
  *
@@ -6,10 +7,6 @@
  * Authors: Zhou Wang <wangzhou1@hisilicon.com>
  *          Dacai Zhu <zhudacai@hisilicon.com>
  *          Gabriele Paoloni <gabriele.paoloni@huawei.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 #include <linux/interrupt.h>
 #include <linux/init.h>
diff --git a/drivers/pci/dwc/pcie-histb.c b/drivers/pci/dwc/pcie-histb.c
index 33b01b73..70b5c0b 100644
--- a/drivers/pci/dwc/pcie-histb.c
+++ b/drivers/pci/dwc/pcie-histb.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe host controller driver for HiSilicon STB SoCs
  *
@@ -5,10 +6,6 @@
  *
  * Authors: Ruqiang Ju <juruqiang@hisilicon.com>
  *          Jianguo Sun <sunjianguo1@huawei.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/clk.h>
diff --git a/drivers/pci/dwc/pcie-kirin.c b/drivers/pci/dwc/pcie-kirin.c
index dc3033c..13d839b 100644
--- a/drivers/pci/dwc/pcie-kirin.c
+++ b/drivers/pci/dwc/pcie-kirin.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe host controller driver for Kirin Phone SoCs
  *
@@ -5,10 +6,6 @@
  *		http://www.huawei.com
  *
  * Author: Xiaowei Song <songxiaowei@huawei.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <asm/compiler.h>
diff --git a/drivers/pci/dwc/pcie-qcom.c b/drivers/pci/dwc/pcie-qcom.c
index ce7ba5b7..6310c66 100644
--- a/drivers/pci/dwc/pcie-qcom.c
+++ b/drivers/pci/dwc/pcie-qcom.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Qualcomm PCIe root complex driver
  *
@@ -5,15 +6,6 @@
  * Copyright 2015 Linaro Limited.
  *
  * Author: Stanimir Varbanov <svarbanov@mm-sol.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 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/clk.h>
@@ -171,7 +163,7 @@ struct qcom_pcie {
 	union qcom_pcie_resources res;
 	struct phy *phy;
 	struct gpio_desc *reset;
-	struct qcom_pcie_ops *ops;
+	const struct qcom_pcie_ops *ops;
 };
 
 #define to_qcom_pcie(x)		dev_get_drvdata((x)->dev)
@@ -1234,7 +1226,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
 
 	pcie->pci = pci;
 
-	pcie->ops = (struct qcom_pcie_ops *)of_device_get_match_data(dev);
+	pcie->ops = of_device_get_match_data(dev);
 
 	pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW);
 	if (IS_ERR(pcie->reset))
diff --git a/drivers/pci/dwc/pcie-spear13xx.c b/drivers/pci/dwc/pcie-spear13xx.c
index 709189d..ecb58f7 100644
--- a/drivers/pci/dwc/pcie-spear13xx.c
+++ b/drivers/pci/dwc/pcie-spear13xx.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe host controller driver for ST Microelectronics SPEAr13xx SoCs
  *
@@ -6,10 +7,6 @@
  * Copyright (C) 2010-2014 ST Microelectronics
  * Pratyush Anand <pratyush.anand@gmail.com>
  * Mohit Kumar <mohit.kumar.dhaka@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/clk.h>
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
index c228a2e..1a81af0 100644
--- a/drivers/pci/ecam.c
+++ b/drivers/pci/ecam.c
@@ -1,17 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright 2016 Broadcom
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation (the "GPL").
- *
- * 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 version 2 (GPLv2) for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 (GPLv2) along with this source code.
  */
 
 #include <linux/device.h>
diff --git a/drivers/pci/endpoint/Kconfig b/drivers/pci/endpoint/Kconfig
index c09623c..d1e7e41 100644
--- a/drivers/pci/endpoint/Kconfig
+++ b/drivers/pci/endpoint/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # PCI Endpoint Support
 #
diff --git a/drivers/pci/endpoint/Makefile b/drivers/pci/endpoint/Makefile
index 1041f80..95b2fe4 100644
--- a/drivers/pci/endpoint/Makefile
+++ b/drivers/pci/endpoint/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # Makefile for PCI Endpoint Support
 #
diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig
index 2942066..8820d0f 100644
--- a/drivers/pci/endpoint/functions/Kconfig
+++ b/drivers/pci/endpoint/functions/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # PCI Endpoint Functions
 #
diff --git a/drivers/pci/endpoint/functions/Makefile b/drivers/pci/endpoint/functions/Makefile
index 6d94a48..d6fafff 100644
--- a/drivers/pci/endpoint/functions/Makefile
+++ b/drivers/pci/endpoint/functions/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # Makefile for PCI Endpoint Functions
 #
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index f9308c2..64d8a17 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /**
  * Test driver to test endpoint functionality
  *
  * Copyright (C) 2017 Texas Instruments
  * Author: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 of
- * the License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/crc32.h>
@@ -104,7 +93,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, src_phys_addr, reg->src_addr, reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr,
+			       reg->size);
 	if (ret) {
 		dev_err(dev, "failed to map source address\n");
 		reg->status = STATUS_SRC_ADDR_INVALID;
@@ -119,7 +109,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 		goto err_src_map_addr;
 	}
 
-	ret = pci_epc_map_addr(epc, dst_phys_addr, reg->dst_addr, reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr,
+			       reg->size);
 	if (ret) {
 		dev_err(dev, "failed to map destination address\n");
 		reg->status = STATUS_DST_ADDR_INVALID;
@@ -128,13 +119,13 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
 
 	memcpy(dst_addr, src_addr, reg->size);
 
-	pci_epc_unmap_addr(epc, dst_phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr);
 
 err_dst_addr:
 	pci_epc_mem_free_addr(epc, dst_phys_addr, dst_addr, reg->size);
 
 err_src_map_addr:
-	pci_epc_unmap_addr(epc, src_phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, src_phys_addr);
 
 err_src_addr:
 	pci_epc_mem_free_addr(epc, src_phys_addr, src_addr, reg->size);
@@ -164,7 +155,8 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, phys_addr, reg->src_addr, reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->src_addr,
+			       reg->size);
 	if (ret) {
 		dev_err(dev, "failed to map address\n");
 		reg->status = STATUS_SRC_ADDR_INVALID;
@@ -186,7 +178,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
 	kfree(buf);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
 
 err_addr:
 	pci_epc_mem_free_addr(epc, phys_addr, src_addr, reg->size);
@@ -215,7 +207,8 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
 		goto err;
 	}
 
-	ret = pci_epc_map_addr(epc, phys_addr, reg->dst_addr, reg->size);
+	ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->dst_addr,
+			       reg->size);
 	if (ret) {
 		dev_err(dev, "failed to map address\n");
 		reg->status = STATUS_DST_ADDR_INVALID;
@@ -242,7 +235,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
 	kfree(buf);
 
 err_map_addr:
-	pci_epc_unmap_addr(epc, phys_addr);
+	pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
 
 err_addr:
 	pci_epc_mem_free_addr(epc, phys_addr, dst_addr, reg->size);
@@ -260,11 +253,11 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq)
 	struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
 
 	reg->status |= STATUS_IRQ_RAISED;
-	msi_count = pci_epc_get_msi(epc);
+	msi_count = pci_epc_get_msi(epc, epf->func_no);
 	if (irq > msi_count || msi_count <= 0)
-		pci_epc_raise_irq(epc, PCI_EPC_IRQ_LEGACY, 0);
+		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
 	else
-		pci_epc_raise_irq(epc, PCI_EPC_IRQ_MSI, irq);
+		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
 }
 
 static void pci_epf_test_cmd_handler(struct work_struct *work)
@@ -291,7 +284,7 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 
 	if (command & COMMAND_RAISE_LEGACY_IRQ) {
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, PCI_EPC_IRQ_LEGACY, 0);
+		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
 		goto reset_handler;
 	}
 
@@ -326,11 +319,11 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
 	}
 
 	if (command & COMMAND_RAISE_MSI_IRQ) {
-		msi_count = pci_epc_get_msi(epc);
+		msi_count = pci_epc_get_msi(epc, epf->func_no);
 		if (irq > msi_count || msi_count <= 0)
 			goto reset_handler;
 		reg->status = STATUS_IRQ_RAISED;
-		pci_epc_raise_irq(epc, PCI_EPC_IRQ_MSI, irq);
+		pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
 		goto reset_handler;
 	}
 
@@ -358,7 +351,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
 	for (bar = BAR_0; bar <= BAR_5; bar++) {
 		if (epf_test->reg[bar]) {
 			pci_epf_free_space(epf, epf_test->reg[bar], bar);
-			pci_epc_clear_bar(epc, bar);
+			pci_epc_clear_bar(epc, epf->func_no, bar);
 		}
 	}
 }
@@ -380,7 +373,8 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
 
 	for (bar = BAR_0; bar <= BAR_5; bar++) {
 		epf_bar = &epf->bar[bar];
-		ret = pci_epc_set_bar(epc, bar, epf_bar->phys_addr,
+		ret = pci_epc_set_bar(epc, epf->func_no, bar,
+				      epf_bar->phys_addr,
 				      epf_bar->size, flags);
 		if (ret) {
 			pci_epf_free_space(epf, epf_test->reg[bar], bar);
@@ -433,7 +427,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
 	if (WARN_ON_ONCE(!epc))
 		return -EINVAL;
 
-	ret = pci_epc_write_header(epc, header);
+	ret = pci_epc_write_header(epc, epf->func_no, header);
 	if (ret) {
 		dev_err(dev, "configuration header write failed\n");
 		return ret;
@@ -447,7 +441,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
 	if (ret)
 		return ret;
 
-	ret = pci_epc_set_msi(epc, epf->msi_interrupts);
+	ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
 	if (ret)
 		return ret;
 
diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c
index 4f74386..018ea34 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -1,35 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
 /**
  * configfs to configure the PCI endpoint
  *
  * Copyright (C) 2017 Texas Instruments
  * Author: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 of
- * the License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/module.h>
+#include <linux/idr.h>
 #include <linux/slab.h>
 
 #include <linux/pci-epc.h>
 #include <linux/pci-epf.h>
 #include <linux/pci-ep-cfs.h>
 
+static DEFINE_IDR(functions_idr);
+static DEFINE_MUTEX(functions_mutex);
 static struct config_group *functions_group;
 static struct config_group *controllers_group;
 
 struct pci_epf_group {
 	struct config_group group;
 	struct pci_epf *epf;
+	int index;
 };
 
 struct pci_epc_group {
@@ -97,22 +90,23 @@ static int pci_epc_epf_link(struct config_item *epc_item,
 {
 	int ret;
 	u32 func_no = 0;
-	struct pci_epc *epc;
-	struct pci_epf *epf;
 	struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
 	struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
+	struct pci_epc *epc = epc_group->epc;
+	struct pci_epf *epf = epf_group->epf;
 
-	epc = epc_group->epc;
-	epf = epf_group->epf;
+	func_no = find_first_zero_bit(&epc_group->function_num_map,
+				      BITS_PER_LONG);
+	if (func_no >= BITS_PER_LONG)
+		return -EINVAL;
+
+	set_bit(func_no, &epc_group->function_num_map);
+	epf->func_no = func_no;
+
 	ret = pci_epc_add_epf(epc, epf);
 	if (ret)
 		goto err_add_epf;
 
-	func_no = find_first_zero_bit(&epc_group->function_num_map,
-				      sizeof(epc_group->function_num_map));
-	set_bit(func_no, &epc_group->function_num_map);
-	epf->func_no = func_no;
-
 	ret = pci_epf_bind(epf);
 	if (ret)
 		goto err_epf_bind;
@@ -353,6 +347,9 @@ static void pci_epf_release(struct config_item *item)
 {
 	struct pci_epf_group *epf_group = to_pci_epf_group(item);
 
+	mutex_lock(&functions_mutex);
+	idr_remove(&functions_idr, epf_group->index);
+	mutex_unlock(&functions_mutex);
 	pci_epf_destroy(epf_group->epf);
 	kfree(epf_group);
 }
@@ -372,22 +369,57 @@ static struct config_group *pci_epf_make(struct config_group *group,
 {
 	struct pci_epf_group *epf_group;
 	struct pci_epf *epf;
+	char *epf_name;
+	int index, err;
 
 	epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
 	if (!epf_group)
 		return ERR_PTR(-ENOMEM);
 
+	mutex_lock(&functions_mutex);
+	index = idr_alloc(&functions_idr, epf_group, 0, 0, GFP_KERNEL);
+	mutex_unlock(&functions_mutex);
+	if (index < 0) {
+		err = index;
+		goto free_group;
+	}
+
+	epf_group->index = index;
+
 	config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
 
-	epf = pci_epf_create(group->cg_item.ci_name);
+	epf_name = kasprintf(GFP_KERNEL, "%s.%d",
+			     group->cg_item.ci_name, epf_group->index);
+	if (!epf_name) {
+		err = -ENOMEM;
+		goto remove_idr;
+	}
+
+	epf = pci_epf_create(epf_name);
 	if (IS_ERR(epf)) {
 		pr_err("failed to create endpoint function device\n");
-		return ERR_PTR(-EINVAL);
+		err = -EINVAL;
+		goto free_name;
 	}
 
 	epf_group->epf = epf;
 
+	kfree(epf_name);
+
 	return &epf_group->group;
+
+free_name:
+	kfree(epf_name);
+
+remove_idr:
+	mutex_lock(&functions_mutex);
+	idr_remove(&functions_idr, epf_group->index);
+	mutex_unlock(&functions_mutex);
+
+free_group:
+	kfree(epf_group);
+
+	return ERR_PTR(err);
 }
 
 static void pci_epf_drop(struct config_group *group, struct config_item *item)
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 42c2a11..e245bba 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -1,24 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
 /**
  * PCI Endpoint *Controller* (EPC) library
  *
  * Copyright (C) 2017 Texas Instruments
  * Author: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 of
- * the License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/device.h>
-#include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
@@ -142,25 +130,26 @@ EXPORT_SYMBOL_GPL(pci_epc_start);
 /**
  * pci_epc_raise_irq() - interrupt the host system
  * @epc: the EPC device which has to interrupt the host
+ * @func_no: the endpoint function number in the EPC device
  * @type: specify the type of interrupt; legacy or MSI
  * @interrupt_num: the MSI interrupt number
  *
  * Invoke to raise an MSI or legacy interrupt
  */
-int pci_epc_raise_irq(struct pci_epc *epc, enum pci_epc_irq_type type,
-		      u8 interrupt_num)
+int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+		      enum pci_epc_irq_type type, u8 interrupt_num)
 {
 	int ret;
 	unsigned long flags;
 
-	if (IS_ERR(epc))
+	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
 	if (!epc->ops->raise_irq)
 		return 0;
 
 	spin_lock_irqsave(&epc->lock, flags);
-	ret = epc->ops->raise_irq(epc, type, interrupt_num);
+	ret = epc->ops->raise_irq(epc, func_no, type, interrupt_num);
 	spin_unlock_irqrestore(&epc->lock, flags);
 
 	return ret;
@@ -170,22 +159,23 @@ EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
 /**
  * pci_epc_get_msi() - get the number of MSI interrupt numbers allocated
  * @epc: the EPC device to which MSI interrupts was requested
+ * @func_no: the endpoint function number in the EPC device
  *
  * Invoke to get the number of MSI interrupts allocated by the RC
  */
-int pci_epc_get_msi(struct pci_epc *epc)
+int pci_epc_get_msi(struct pci_epc *epc, u8 func_no)
 {
 	int interrupt;
 	unsigned long flags;
 
-	if (IS_ERR(epc))
+	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return 0;
 
 	if (!epc->ops->get_msi)
 		return 0;
 
 	spin_lock_irqsave(&epc->lock, flags);
-	interrupt = epc->ops->get_msi(epc);
+	interrupt = epc->ops->get_msi(epc, func_no);
 	spin_unlock_irqrestore(&epc->lock, flags);
 
 	if (interrupt < 0)
@@ -200,17 +190,18 @@ EXPORT_SYMBOL_GPL(pci_epc_get_msi);
 /**
  * pci_epc_set_msi() - set the number of MSI interrupt numbers required
  * @epc: the EPC device on which MSI has to be configured
+ * @func_no: the endpoint function number in the EPC device
  * @interrupts: number of MSI interrupts required by the EPF
  *
  * Invoke to set the required number of MSI interrupts.
  */
-int pci_epc_set_msi(struct pci_epc *epc, u8 interrupts)
+int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
 {
 	int ret;
 	u8 encode_int;
 	unsigned long flags;
 
-	if (IS_ERR(epc))
+	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
 	if (!epc->ops->set_msi)
@@ -219,7 +210,7 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 interrupts)
 	encode_int = order_base_2(interrupts);
 
 	spin_lock_irqsave(&epc->lock, flags);
-	ret = epc->ops->set_msi(epc, encode_int);
+	ret = epc->ops->set_msi(epc, func_no, encode_int);
 	spin_unlock_irqrestore(&epc->lock, flags);
 
 	return ret;
@@ -229,22 +220,24 @@ EXPORT_SYMBOL_GPL(pci_epc_set_msi);
 /**
  * pci_epc_unmap_addr() - unmap CPU address from PCI address
  * @epc: the EPC device on which address is allocated
+ * @func_no: the endpoint function number in the EPC device
  * @phys_addr: physical address of the local system
  *
  * Invoke to unmap the CPU address from PCI address.
  */
-void pci_epc_unmap_addr(struct pci_epc *epc, phys_addr_t phys_addr)
+void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
+			phys_addr_t phys_addr)
 {
 	unsigned long flags;
 
-	if (IS_ERR(epc))
+	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return;
 
 	if (!epc->ops->unmap_addr)
 		return;
 
 	spin_lock_irqsave(&epc->lock, flags);
-	epc->ops->unmap_addr(epc, phys_addr);
+	epc->ops->unmap_addr(epc, func_no, phys_addr);
 	spin_unlock_irqrestore(&epc->lock, flags);
 }
 EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
@@ -252,26 +245,27 @@ EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
 /**
  * pci_epc_map_addr() - map CPU address to PCI address
  * @epc: the EPC device on which address is allocated
+ * @func_no: the endpoint function number in the EPC device
  * @phys_addr: physical address of the local system
  * @pci_addr: PCI address to which the physical address should be mapped
  * @size: the size of the allocation
  *
  * Invoke to map CPU address with PCI address.
  */
-int pci_epc_map_addr(struct pci_epc *epc, phys_addr_t phys_addr,
-		     u64 pci_addr, size_t size)
+int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
+		     phys_addr_t phys_addr, u64 pci_addr, size_t size)
 {
 	int ret;
 	unsigned long flags;
 
-	if (IS_ERR(epc))
+	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
 	if (!epc->ops->map_addr)
 		return 0;
 
 	spin_lock_irqsave(&epc->lock, flags);
-	ret = epc->ops->map_addr(epc, phys_addr, pci_addr, size);
+	ret = epc->ops->map_addr(epc, func_no, phys_addr, pci_addr, size);
 	spin_unlock_irqrestore(&epc->lock, flags);
 
 	return ret;
@@ -281,22 +275,23 @@ EXPORT_SYMBOL_GPL(pci_epc_map_addr);
 /**
  * pci_epc_clear_bar() - reset the BAR
  * @epc: the EPC device for which the BAR has to be cleared
+ * @func_no: the endpoint function number in the EPC device
  * @bar: the BAR number that has to be reset
  *
  * Invoke to reset the BAR of the endpoint device.
  */
-void pci_epc_clear_bar(struct pci_epc *epc, int bar)
+void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, int bar)
 {
 	unsigned long flags;
 
-	if (IS_ERR(epc))
+	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return;
 
 	if (!epc->ops->clear_bar)
 		return;
 
 	spin_lock_irqsave(&epc->lock, flags);
-	epc->ops->clear_bar(epc, bar);
+	epc->ops->clear_bar(epc, func_no, bar);
 	spin_unlock_irqrestore(&epc->lock, flags);
 }
 EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
@@ -304,26 +299,27 @@ EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
 /**
  * pci_epc_set_bar() - configure BAR in order for host to assign PCI addr space
  * @epc: the EPC device on which BAR has to be configured
+ * @func_no: the endpoint function number in the EPC device
  * @bar: the BAR number that has to be configured
  * @size: the size of the addr space
  * @flags: specify memory allocation/io allocation/32bit address/64 bit address
  *
  * Invoke to configure the BAR of the endpoint device.
  */
-int pci_epc_set_bar(struct pci_epc *epc, enum pci_barno bar,
+int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, enum pci_barno bar,
 		    dma_addr_t bar_phys, size_t size, int flags)
 {
 	int ret;
 	unsigned long irq_flags;
 
-	if (IS_ERR(epc))
+	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
 	if (!epc->ops->set_bar)
 		return 0;
 
 	spin_lock_irqsave(&epc->lock, irq_flags);
-	ret = epc->ops->set_bar(epc, bar, bar_phys, size, flags);
+	ret = epc->ops->set_bar(epc, func_no, bar, bar_phys, size, flags);
 	spin_unlock_irqrestore(&epc->lock, irq_flags);
 
 	return ret;
@@ -333,6 +329,7 @@ EXPORT_SYMBOL_GPL(pci_epc_set_bar);
 /**
  * pci_epc_write_header() - write standard configuration header
  * @epc: the EPC device to which the configuration header should be written
+ * @func_no: the endpoint function number in the EPC device
  * @header: standard configuration header fields
  *
  * Invoke to write the configuration header to the endpoint controller. Every
@@ -340,19 +337,20 @@ EXPORT_SYMBOL_GPL(pci_epc_set_bar);
  * configuration header would be written. The callback function should write
  * the header fields to this dedicated location.
  */
-int pci_epc_write_header(struct pci_epc *epc, struct pci_epf_header *header)
+int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
+			 struct pci_epf_header *header)
 {
 	int ret;
 	unsigned long flags;
 
-	if (IS_ERR(epc))
+	if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
 		return -EINVAL;
 
 	if (!epc->ops->write_header)
 		return 0;
 
 	spin_lock_irqsave(&epc->lock, flags);
-	ret = epc->ops->write_header(epc, header);
+	ret = epc->ops->write_header(epc, func_no, header);
 	spin_unlock_irqrestore(&epc->lock, flags);
 
 	return ret;
@@ -371,7 +369,6 @@ EXPORT_SYMBOL_GPL(pci_epc_write_header);
 int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
 {
 	unsigned long flags;
-	struct device *dev = epc->dev.parent;
 
 	if (epf->epc)
 		return -EBUSY;
@@ -383,12 +380,6 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
 		return -EINVAL;
 
 	epf->epc = epc;
-	if (dev->of_node) {
-		of_dma_configure(&epf->dev, dev->of_node);
-	} else {
-		dma_set_coherent_mask(&epf->dev, epc->dev.coherent_dma_mask);
-		epf->dev.dma_mask = epc->dev.dma_mask;
-	}
 
 	spin_lock_irqsave(&epc->lock, flags);
 	list_add_tail(&epf->list, &epc->pci_epf);
@@ -503,9 +494,7 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
 	INIT_LIST_HEAD(&epc->pci_epf);
 
 	device_initialize(&epc->dev);
-	dma_set_coherent_mask(&epc->dev, dev->coherent_dma_mask);
 	epc->dev.class = pci_epc_class;
-	epc->dev.dma_mask = dev->dma_mask;
 	epc->dev.parent = dev;
 	epc->ops = ops;
 
diff --git a/drivers/pci/endpoint/pci-epc-mem.c b/drivers/pci/endpoint/pci-epc-mem.c
index 83b7d5d..2bf8bd1 100644
--- a/drivers/pci/endpoint/pci-epc-mem.c
+++ b/drivers/pci/endpoint/pci-epc-mem.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /**
  * PCI Endpoint *Controller* Address Space Management
  *
  * Copyright (C) 2017 Texas Instruments
  * Author: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 of
- * the License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/io.h>
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index ae1611a..766ce1d 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /**
  * PCI Endpoint *Function* (EPF) library
  *
  * Copyright (C) 2017 Texas Instruments
  * Author: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 of
- * the License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/device.h>
@@ -99,7 +88,7 @@ EXPORT_SYMBOL_GPL(pci_epf_bind);
  */
 void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar)
 {
-	struct device *dev = &epf->dev;
+	struct device *dev = epf->epc->dev.parent;
 
 	if (!addr)
 		return;
@@ -122,7 +111,7 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space);
 void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar)
 {
 	void *space;
-	struct device *dev = &epf->dev;
+	struct device *dev = epf->epc->dev.parent;
 	dma_addr_t phys_addr;
 
 	if (size < 128)
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index add6623..ac8d812 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * host bridge related code
  */
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 38d1298..a4ed748 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
 menu "PCI host controller drivers"
 	depends on PCI
 
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 34ec1d8..3b10591 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -34,6 +34,8 @@
 # ARM64 and use internal ifdefs to only build the pieces we need
 # depending on whether ACPI, the DT driver, or both are enabled.
 
+ifdef CONFIG_PCI
 obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
 obj-$(CONFIG_ARM64) += pci-thunder-pem.o
 obj-$(CONFIG_ARM64) += pci-xgene.o
+endif
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c
index 26ed0c0..b04d37b 100644
--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Driver for the Aardvark PCIe controller, used on Marvell Armada
  * 3700.
@@ -5,10 +6,6 @@
  * Copyright (C) 2016 Marvell
  *
  * Author: Hezi Shahmoon <hezi.shahmoon@marvell.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/delay.h>
diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c
index 44a47d4..5d028f5 100644
--- a/drivers/pci/host/pci-host-common.c
+++ b/drivers/pci/host/pci-host-common.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Generic PCI host driver common code
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
  * Copyright (C) 2014 ARM Limited
  *
  * Author: Will Deacon <will.deacon@arm.com>
@@ -24,50 +13,6 @@
 #include <linux/pci-ecam.h>
 #include <linux/platform_device.h>
 
-static int gen_pci_parse_request_of_pci_ranges(struct device *dev,
-		       struct list_head *resources, struct resource **bus_range)
-{
-	int err, res_valid = 0;
-	struct device_node *np = dev->of_node;
-	resource_size_t iobase;
-	struct resource_entry *win, *tmp;
-
-	err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase);
-	if (err)
-		return err;
-
-	err = devm_request_pci_bus_resources(dev, resources);
-	if (err)
-		return err;
-
-	resource_list_for_each_entry_safe(win, tmp, resources) {
-		struct resource *res = win->res;
-
-		switch (resource_type(res)) {
-		case IORESOURCE_IO:
-			err = pci_remap_iospace(res, iobase);
-			if (err) {
-				dev_warn(dev, "error %d: failed to map resource %pR\n",
-					 err, res);
-				resource_list_destroy_entry(win);
-			}
-			break;
-		case IORESOURCE_MEM:
-			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
-			break;
-		case IORESOURCE_BUS:
-			*bus_range = res;
-			break;
-		}
-	}
-
-	if (res_valid)
-		return 0;
-
-	dev_err(dev, "non-prefetchable memory resource required\n");
-	return -EINVAL;
-}
-
 static void gen_pci_unmap_cfg(void *ptr)
 {
 	pci_ecam_free((struct pci_config_window *)ptr);
@@ -82,9 +27,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev,
 	struct pci_config_window *cfg;
 
 	/* Parse our PCI ranges and request their resources */
-	err = gen_pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
+	err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
 	if (err)
-		goto err_out;
+		return ERR_PTR(err);
 
 	err = of_address_to_resource(dev->of_node, 0, &cfgres);
 	if (err) {
@@ -116,7 +61,6 @@ int pci_host_common_probe(struct platform_device *pdev,
 	const char *type;
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
-	struct pci_bus *bus, *child;
 	struct pci_host_bridge *bridge;
 	struct pci_config_window *cfg;
 	struct list_head resources;
@@ -135,14 +79,13 @@ int pci_host_common_probe(struct platform_device *pdev,
 	of_pci_check_probe_only();
 
 	/* Parse and map our Configuration Space windows */
-	INIT_LIST_HEAD(&resources);
 	cfg = gen_pci_init(dev, &resources, ops);
 	if (IS_ERR(cfg))
 		return PTR_ERR(cfg);
 
 	/* Do not reassign resources if probe only */
 	if (!pci_has_flag(PCI_PROBE_ONLY))
-		pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
+		pci_add_flags(PCI_REASSIGN_ALL_BUS);
 
 	list_splice_init(&resources, &bridge->windows);
 	bridge->dev.parent = dev;
@@ -152,29 +95,11 @@ int pci_host_common_probe(struct platform_device *pdev,
 	bridge->map_irq = of_irq_parse_and_map_pci;
 	bridge->swizzle_irq = pci_common_swizzle;
 
-	ret = pci_scan_root_bus_bridge(bridge);
+	ret = pci_host_probe(bridge);
 	if (ret < 0) {
-		dev_err(dev, "Scanning root bridge failed");
+		pci_free_resource_list(&resources);
 		return ret;
 	}
 
-	bus = bridge->bus;
-
-	/*
-	 * We insert PCI resources into the iomem_resource and
-	 * ioport_resource trees in either pci_bus_claim_resources()
-	 * or pci_bus_assign_resources().
-	 */
-	if (pci_has_flag(PCI_PROBE_ONLY)) {
-		pci_bus_claim_resources(bus);
-	} else {
-		pci_bus_size_bridges(bus);
-		pci_bus_assign_resources(bus);
-
-		list_for_each_entry(child, &bus->children, node)
-			pcie_bus_configure_settings(child);
-	}
-
-	pci_bus_add_devices(bus);
 	return 0;
 }
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index 2f05511..45319ee 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Simple, generic PCI host controller driver targetting firmware-initialised
  * systems and virtual machines (e.g. the PCI emulation provided by kvmtool).
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
  * Copyright (C) 2014 ARM Limited
  *
  * Author: Will Deacon <will.deacon@arm.com>
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index 6b8d060..2faf38e 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) Microsoft Corporation.
  *
@@ -34,17 +35,6 @@
  * read and write handlers for config space must be aware of this mechanism.
  * Similarly, device setup and teardown involves messages sent to and from
  * the PCI back-end driver in Hyper-V.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 8d88f19..5d4dccf 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe driver for Marvell Armada 370 and Armada XP SoCs
  *
  * Author: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c
index e46de69..a28370b 100644
--- a/drivers/pci/host/pci-rcar-gen2.c
+++ b/drivers/pci/host/pci-rcar-gen2.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *  pci-rcar-gen2: internal PCI bus support
  *
@@ -5,10 +6,6 @@
  * Copyright (C) 2013 Cogent Embedded, Inc.
  *
  * Author: Valentine Barshak <valentine.barshak@cogentembedded.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/delay.h>
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index f9d3960..dd9b3bc 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCIe host controller driver for Tegra SoCs
  *
@@ -10,20 +11,6 @@
  * Bits taken from arch/arm/mach-dove/pcie.c
  *
  * Author: Thierry Reding <treding@nvidia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
 #include <linux/clk.h>
@@ -269,11 +256,10 @@ struct tegra_pcie {
 
 	void __iomem *pads;
 	void __iomem *afi;
+	void __iomem *cfg;
 	int irq;
 
-	struct list_head buses;
-	struct resource *cs;
-
+	struct resource cs;
 	struct resource io;
 	struct resource pio;
 	struct resource mem;
@@ -322,7 +308,6 @@ struct tegra_pcie_port {
 };
 
 struct tegra_pcie_bus {
-	struct vm_struct *area;
 	struct list_head list;
 	unsigned int nr;
 };
@@ -362,109 +347,26 @@ static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset)
  *
  * Mapping the whole extended configuration space would require 256 MiB of
  * virtual address space, only a small part of which will actually be used.
- * To work around this, a 1 MiB of virtual addresses are allocated per bus
- * when the bus is first accessed. When the physical range is mapped, the
- * the bus number bits are hidden so that the extended register number bits
- * appear as bits [19:16]. Therefore the virtual mapping looks like this:
  *
- *    [19:16] extended register number
- *    [15:11] device number
- *    [10: 8] function number
- *    [ 7: 0] register number
- *
- * This is achieved by stitching together 16 chunks of 64 KiB of physical
- * address space via the MMU.
+ * To work around this, a 4 KiB region is used to generate the required
+ * configuration transaction with relevant B:D:F and register offset values.
+ * This is achieved by dynamically programming base address and size of
+ * AFI_AXI_BAR used for end point config space mapping to make sure that the
+ * address (access to which generates correct config transaction) falls in
+ * this 4 KiB region.
  */
-static unsigned long tegra_pcie_conf_offset(unsigned int devfn, int where)
+static unsigned int tegra_pcie_conf_offset(u8 bus, unsigned int devfn,
+					   unsigned int where)
 {
-	return ((where & 0xf00) << 8) | (PCI_SLOT(devfn) << 11) |
-	       (PCI_FUNC(devfn) << 8) | (where & 0xfc);
-}
-
-static struct tegra_pcie_bus *tegra_pcie_bus_alloc(struct tegra_pcie *pcie,
-						   unsigned int busnr)
-{
-	struct device *dev = pcie->dev;
-	pgprot_t prot = pgprot_noncached(PAGE_KERNEL);
-	phys_addr_t cs = pcie->cs->start;
-	struct tegra_pcie_bus *bus;
-	unsigned int i;
-	int err;
-
-	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
-	if (!bus)
-		return ERR_PTR(-ENOMEM);
-
-	INIT_LIST_HEAD(&bus->list);
-	bus->nr = busnr;
-
-	/* allocate 1 MiB of virtual addresses */
-	bus->area = get_vm_area(SZ_1M, VM_IOREMAP);
-	if (!bus->area) {
-		err = -ENOMEM;
-		goto free;
-	}
-
-	/* map each of the 16 chunks of 64 KiB each */
-	for (i = 0; i < 16; i++) {
-		unsigned long virt = (unsigned long)bus->area->addr +
-				     i * SZ_64K;
-		phys_addr_t phys = cs + i * SZ_16M + busnr * SZ_64K;
-
-		err = ioremap_page_range(virt, virt + SZ_64K, phys, prot);
-		if (err < 0) {
-			dev_err(dev, "ioremap_page_range() failed: %d\n", err);
-			goto unmap;
-		}
-	}
-
-	return bus;
-
-unmap:
-	vunmap(bus->area->addr);
-free:
-	kfree(bus);
-	return ERR_PTR(err);
-}
-
-static int tegra_pcie_add_bus(struct pci_bus *bus)
-{
-	struct pci_host_bridge *host = pci_find_host_bridge(bus);
-	struct tegra_pcie *pcie = pci_host_bridge_priv(host);
-	struct tegra_pcie_bus *b;
-
-	b = tegra_pcie_bus_alloc(pcie, bus->number);
-	if (IS_ERR(b))
-		return PTR_ERR(b);
-
-	list_add_tail(&b->list, &pcie->buses);
-
-	return 0;
-}
-
-static void tegra_pcie_remove_bus(struct pci_bus *child)
-{
-	struct pci_host_bridge *host = pci_find_host_bridge(child);
-	struct tegra_pcie *pcie = pci_host_bridge_priv(host);
-	struct tegra_pcie_bus *bus, *tmp;
-
-	list_for_each_entry_safe(bus, tmp, &pcie->buses, list) {
-		if (bus->nr == child->number) {
-			vunmap(bus->area->addr);
-			list_del(&bus->list);
-			kfree(bus);
-			break;
-		}
-	}
+	return ((where & 0xf00) << 16) | (bus << 16) | (PCI_SLOT(devfn) << 11) |
+	       (PCI_FUNC(devfn) << 8) | (where & 0xff);
 }
 
 static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
 					unsigned int devfn,
 					int where)
 {
-	struct pci_host_bridge *host = pci_find_host_bridge(bus);
-	struct tegra_pcie *pcie = pci_host_bridge_priv(host);
-	struct device *dev = pcie->dev;
+	struct tegra_pcie *pcie = bus->sysdata;
 	void __iomem *addr = NULL;
 
 	if (bus->number == 0) {
@@ -478,19 +380,17 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
 			}
 		}
 	} else {
-		struct tegra_pcie_bus *b;
+		unsigned int offset;
+		u32 base;
 
-		list_for_each_entry(b, &pcie->buses, list)
-			if (b->nr == bus->number)
-				addr = (void __iomem *)b->area->addr;
+		offset = tegra_pcie_conf_offset(bus->number, devfn, where);
 
-		if (!addr) {
-			dev_err(dev, "failed to map cfg. space for bus %u\n",
-				bus->number);
-			return NULL;
-		}
+		/* move 4 KiB window to offset within the FPCI region */
+		base = 0xfe100000 + ((offset & ~(SZ_4K - 1)) >> 8);
+		afi_writel(pcie, base, AFI_FPCI_BAR0);
 
-		addr += tegra_pcie_conf_offset(devfn, where);
+		/* move to correct offset within the 4 KiB page */
+		addr = pcie->cfg + (offset & (SZ_4K - 1));
 	}
 
 	return addr;
@@ -517,8 +417,6 @@ static int tegra_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
 }
 
 static struct pci_ops tegra_pcie_ops = {
-	.add_bus = tegra_pcie_add_bus,
-	.remove_bus = tegra_pcie_remove_bus,
 	.map_bus = tegra_pcie_map_bus,
 	.read = tegra_pcie_config_read,
 	.write = tegra_pcie_config_write,
@@ -661,8 +559,7 @@ static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
 
 static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
-	struct pci_host_bridge *host = pci_find_host_bridge(pdev->bus);
-	struct tegra_pcie *pcie = pci_host_bridge_priv(host);
+	struct tegra_pcie *pcie = pdev->bus->sysdata;
 	int irq;
 
 	tegra_cpuidle_pcie_irqs_in_use();
@@ -743,12 +640,9 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 	u32 fpci_bar, size, axi_address;
 
 	/* Bar 0: type 1 extended configuration space */
-	fpci_bar = 0xfe100000;
-	size = resource_size(pcie->cs);
-	axi_address = pcie->cs->start;
-	afi_writel(pcie, axi_address, AFI_AXI_BAR0_START);
+	size = resource_size(&pcie->cs);
+	afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
 	afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
-	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR0);
 
 	/* Bar 1: downstream IO bar */
 	fpci_bar = 0xfdfc0000;
@@ -1353,10 +1247,14 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
 		goto poweroff;
 	}
 
-	pcie->cs = devm_request_mem_region(dev, res->start,
-					   resource_size(res), res->name);
-	if (!pcie->cs) {
-		err = -EADDRNOTAVAIL;
+	pcie->cs = *res;
+
+	/* constrain configuration space to 4 KiB */
+	pcie->cs.end = pcie->cs.start + SZ_4K - 1;
+
+	pcie->cfg = devm_ioremap_resource(dev, &pcie->cs);
+	if (IS_ERR(pcie->cfg)) {
+		err = PTR_ERR(pcie->cfg);
 		goto poweroff;
 	}
 
@@ -2345,9 +2243,9 @@ static int tegra_pcie_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	pcie = pci_host_bridge_priv(host);
+	host->sysdata = pcie;
 
 	pcie->soc = of_device_get_match_data(dev);
-	INIT_LIST_HEAD(&pcie->buses);
 	INIT_LIST_HEAD(&pcie->ports);
 	pcie->dev = dev;
 
@@ -2382,7 +2280,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
 
 	tegra_pcie_enable_ports(pcie);
 
-	pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
 	host->busnr = pcie->busn.start;
 	host->dev.parent = &pdev->dev;
 	host->ops = &tegra_pcie_ops;
diff --git a/drivers/pci/host/pci-thunder-ecam.c b/drivers/pci/host/pci-thunder-ecam.c
index fc0ca03..32d1d7b 100644
--- a/drivers/pci/host/pci-thunder-ecam.c
+++ b/drivers/pci/host/pci-thunder-ecam.c
@@ -1,8 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
  * Copyright (C) 2015, 2016 Cavium, Inc.
  */
 
diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c
index 6e066f8..f127ce8 100644
--- a/drivers/pci/host/pci-thunder-pem.c
+++ b/drivers/pci/host/pci-thunder-pem.c
@@ -1,16 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
  * Copyright (C) 2015 - 2016 Cavium, Inc.
  */
 
diff --git a/drivers/pci/host/pci-v3-semi.c b/drivers/pci/host/pci-v3-semi.c
index 02f6e1e..7fef648 100644
--- a/drivers/pci/host/pci-v3-semi.c
+++ b/drivers/pci/host/pci-v3-semi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Support for V3 Semiconductor PCI Local Bus to PCI Bridge
  * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c
index d417aca..5b3876f 100644
--- a/drivers/pci/host/pci-versatile.c
+++ b/drivers/pci/host/pci-versatile.c
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright 2004 Koninklijke Philips Electronics NV
  *
  * Conversion to platform driver and DT:
  * Copyright 2014 Linaro Ltd.
  *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  * 14/04/2005 Initial version, colin.king@philips.com
  */
 #include <linux/kernel.h>
@@ -202,7 +194,7 @@ static int versatile_pci_probe(struct platform_device *pdev)
 	writel(0, versatile_cfg_base[0] + PCI_INTERRUPT_LINE);
 
 	pci_add_flags(PCI_ENABLE_PROC_DOMAINS);
-	pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);
+	pci_add_flags(PCI_REASSIGN_ALL_BUS);
 
 	list_splice_init(&pci_res, &bridge->windows);
 	bridge->dev.parent = dev;
diff --git a/drivers/pci/host/pci-xgene-msi.c b/drivers/pci/host/pci-xgene-msi.c
index 1f42a20..df8e4bd 100644
--- a/drivers/pci/host/pci-xgene-msi.c
+++ b/drivers/pci/host/pci-xgene-msi.c
@@ -1,19 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * APM X-Gene MSI Driver
  *
  * Copyright (c) 2014, Applied Micro Circuits Corporation
  * Author: Tanmay Inamdar <tinamdar@apm.com>
  *	   Duc Dang <dhdang@apm.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index 465aa2a..0a0d7ee 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -1,20 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /**
  * APM X-Gene PCIe Driver
  *
  * Copyright (c) 2014 Applied Micro Circuits Corporation.
  *
  * Author: Tanmay Inamdar <tinamdar@apm.com>.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  */
 #include <linux/clk.h>
 #include <linux/delay.h>
@@ -668,7 +658,6 @@ static int xgene_pcie_probe(struct platform_device *pdev)
 
 	bus = bridge->bus;
 
-	pci_scan_child_bus(bus);
 	pci_assign_unassigned_bus_resources(bus);
 	list_for_each_entry(child, &bus->children, node)
 		pcie_bus_configure_settings(child);
diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c
index d8141f4..025ef7d 100644
--- a/drivers/pci/host/pcie-altera-msi.c
+++ b/drivers/pci/host/pcie-altera-msi.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Altera PCIe MSI support
  *
  * Author: Ley Foon Tan <lftan@altera.com>
  *
  * Copyright Altera Corporation (C) 2013-2015. All rights reserved
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/interrupt.h>
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index 5cc4f59..2235f47 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright Altera Corporation (C) 2013-2015. All rights reserved
  *
  * Author: Ley Foon Tan <lftan@altera.com>
  * Description: Altera PCIe host controller driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <linux/delay.h>
diff --git a/drivers/pci/host/pcie-iproc-bcma.c b/drivers/pci/host/pcie-iproc-bcma.c
index f03d5e3..603c834 100644
--- a/drivers/pci/host/pcie-iproc-bcma.c
+++ b/drivers/pci/host/pcie-iproc-bcma.c
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2015 Broadcom Corporation
  * Copyright (C) 2015 Hauke Mehrtens <hauke@hauke-m.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/pci/host/pcie-iproc-msi.c b/drivers/pci/host/pcie-iproc-msi.c
index 990fc90..9deb56989 100644
--- a/drivers/pci/host/pcie-iproc-msi.c
+++ b/drivers/pci/host/pcie-iproc-msi.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2015 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/interrupt.h>
diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c
index a5073a9..e764a2a 100644
--- a/drivers/pci/host/pcie-iproc-platform.c
+++ b/drivers/pci/host/pcie-iproc-platform.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2015 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/kernel.h>
@@ -92,6 +84,13 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
 		pcie->need_ob_cfg = true;
 	}
 
+	/*
+	 * DT nodes are not used by all platforms that use the iProc PCIe
+	 * core driver. For platforms that require explict inbound mapping
+	 * configuration, "dma-ranges" would have been present in DT
+	 */
+	pcie->need_ib_cfg = of_property_read_bool(np, "dma-ranges");
+
 	/* PHY use is optional */
 	pcie->phy = devm_phy_get(dev, "pcie-phy");
 	if (IS_ERR(pcie->phy)) {
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
index 935909b..cbb0954 100644
--- a/drivers/pci/host/pcie-iproc.c
+++ b/drivers/pci/host/pcie-iproc.c
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2014 Hauke Mehrtens <hauke@hauke-m.de>
  * Copyright (C) 2015 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/kernel.h>
@@ -1378,9 +1370,11 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
 		}
 	}
 
-	ret = iproc_pcie_map_dma_ranges(pcie);
-	if (ret && ret != -ENOENT)
-		goto err_power_off_phy;
+	if (pcie->need_ib_cfg) {
+		ret = iproc_pcie_map_dma_ranges(pcie);
+		if (ret && ret != -ENOENT)
+			goto err_power_off_phy;
+	}
 
 #ifdef CONFIG_ARM
 	pcie->sysdata.private_data = pcie;
diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h
index a6b55ce..d55f56a 100644
--- a/drivers/pci/host/pcie-iproc.h
+++ b/drivers/pci/host/pcie-iproc.h
@@ -1,14 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) 2014-2015 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #ifndef _PCIE_IPROC_H
@@ -74,6 +66,7 @@ struct iproc_msi;
  * @ob: outbound mapping related parameters
  * @ob_map: outbound mapping related parameters specific to the controller
  *
+ * @need_ib_cfg: indicates SW needs to configure the inbound mapping window
  * @ib: inbound mapping related parameters
  * @ib_map: outbound mapping region related parameters
  *
@@ -101,6 +94,7 @@ struct iproc_pcie {
 	struct iproc_pcie_ob ob;
 	const struct iproc_pcie_ob_map *ob_map;
 
+	bool need_ib_cfg;
 	struct iproc_pcie_ib ib;
 	const struct iproc_pcie_ib_map *ib_map;
 
diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
index db93efd..a8b20c5 100644
--- a/drivers/pci/host/pcie-mediatek.c
+++ b/drivers/pci/host/pcie-mediatek.c
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * MediaTek PCIe host controller driver.
  *
  * Copyright (c) 2017 MediaTek Inc.
  * Author: Ryder Lee <ryder.lee@mediatek.com>
  *	   Honghui Zhang <honghui.zhang@mediatek.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/clk.h>
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 52ab3cb..b4c4aad2 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe driver for Renesas R-Car SoCs
  *  Copyright (C) 2014 Renesas Electronics Europe Ltd
@@ -8,10 +9,6 @@
  *  Copyright (C) 2009 - 2011  Paul Mundt
  *
  * Author: Phil Edworthy <phil.edworthy@renesas.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/clk.h>
@@ -459,7 +456,7 @@ static int rcar_pcie_enable(struct rcar_pcie *pcie)
 
 	rcar_pcie_setup(&bridge->windows, pcie);
 
-	pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
+	pci_add_flags(PCI_REASSIGN_ALL_BUS);
 
 	bridge->dev.parent = dev;
 	bridge->sysdata = pcie;
@@ -1123,7 +1120,9 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 
 	INIT_LIST_HEAD(&pcie->resources);
 
-	rcar_pcie_parse_request_of_pci_ranges(pcie);
+	err = rcar_pcie_parse_request_of_pci_ranges(pcie);
+	if (err)
+		goto err_free_bridge;
 
 	err = rcar_pcie_get_resources(pcie);
 	if (err < 0) {
@@ -1178,6 +1177,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
 
 err_free_resource_list:
 	pci_free_resource_list(&pcie->resources);
+err_free_bridge:
 	pci_free_host_bridge(bridge);
 
 	return err;
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
index 9051c6c..f1e8f97 100644
--- a/drivers/pci/host/pcie-rockchip.c
+++ b/drivers/pci/host/pcie-rockchip.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Rockchip AXI PCIe host controller driver
  *
@@ -8,11 +9,6 @@
  *
  * Bits taken from Synopsys DesignWare Host controller driver and
  * ARM PCI Host generic driver.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/bitrev.h>
diff --git a/drivers/pci/host/pcie-xilinx-nwl.c b/drivers/pci/host/pcie-xilinx-nwl.c
index 65dea98..0acaf48 100644
--- a/drivers/pci/host/pcie-xilinx-nwl.c
+++ b/drivers/pci/host/pcie-xilinx-nwl.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCIe host controller driver for NWL PCIe Bridge
  * Based on pcie-xilinx.c, pci-tegra.c
  *
  * (C) Copyright 2014 - 2015, Xilinx, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/delay.h>
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
index 7b53259..0ad188e 100644
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCIe host controller driver for Xilinx AXI PCIe Bridge
  *
@@ -7,11 +8,6 @@
  *
  * Bits taken from Synopsys DesignWare Host controller driver and
  * ARM PCI Host generic driver.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/interrupt.h>
diff --git a/drivers/pci/host/vmd.c b/drivers/pci/host/vmd.c
index 509893b..930a8fa 100644
--- a/drivers/pci/host/vmd.c
+++ b/drivers/pci/host/vmd.c
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Volume Management Device driver
  * Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
  */
 
 #include <linux/device.h>
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index aadce45..a8f21d05 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # PCI Hotplug support
 #
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index a5e66df..c981616 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Common ACPI functions for hot plug platforms
  *
@@ -5,21 +6,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <kristen.c.accardi@intel.com>
  *
  */
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index f0ebc8b..e438a2d 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * ACPI PCI Hot Plug Controller Driver
  *
@@ -12,21 +13,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <gregkh@us.ibm.com>,
  *		    <t-kochi@bq.jp.nec.com>
  *
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 3c81fc8..12b5655 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * ACPI PCI Hot Plug Controller Driver
  *
@@ -12,21 +13,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <kristen.c.accardi@intel.com>
  *
  */
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 5db6f18..e2198a2f 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * ACPI PCI HotPlug glue functions to ACPI CA subsystem
  *
@@ -11,21 +12,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <kristen.c.accardi@intel.com>
  *
  */
@@ -811,10 +797,8 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
 
 	handle = adev->handle;
 	bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
-	if (!bridge) {
-		acpi_handle_err(handle, "No memory for bridge object\n");
+	if (!bridge)
 		return;
-	}
 
 	INIT_LIST_HEAD(&bridge->slots);
 	kref_init(&bridge->ref);
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index 984c7e8..3903d90 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * ACPI PCI Hot Plug IBM Extension
  *
@@ -6,21 +7,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <vernux@us.ibm.com>
  *
  */
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
index 60e66e0..4658557 100644
--- a/drivers/pci/hotplug/cpci_hotplug.h
+++ b/drivers/pci/hotplug/cpci_hotplug.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * CompactPCI Hot Plug Core Functions
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <scottm@somanetworks.com>
  */
 
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index 95f689f..07b533a 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * CompactPCI Hot Plug Driver
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <scottm@somanetworks.com>
  */
 
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index f616358..389b8fb5 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * CompactPCI Hot Plug Driver PCI functions
  *
@@ -5,21 +6,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <scottm@somanetworks.com>
  */
 
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
index bbf9cf8..17d71ed 100644
--- a/drivers/pci/hotplug/cpcihp_generic.c
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * cpcihp_generic.c
  *
@@ -7,26 +8,6 @@
  * Copyright 2001 Intel San Luis Obispo
  * Copyright 2000,2001 MontaVista Software Inc.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * This generic CompactPCI hotplug driver should allow using the PCI hotplug
  * mechanism on any CompactPCI board that exposes the #ENUM signal as a bit
  * in a system register that can be read through standard port I/O.
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
index 2f8659a..ae63e5a 100644
--- a/drivers/pci/hotplug/cpcihp_zt5550.c
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * cpcihp_zt5550.c
  *
@@ -7,26 +8,6 @@
  * Copyright 2001 Intel San Luis Obispo
  * Copyright 2000,2001 MontaVista Software Inc.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <scottm@somanetworks.com>
  */
 
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.h b/drivers/pci/hotplug/cpcihp_zt5550.h
index 9a57fda..5ea10df 100644
--- a/drivers/pci/hotplug/cpcihp_zt5550.h
+++ b/drivers/pci/hotplug/cpcihp_zt5550.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * cpcihp_zt5550.h
  *
@@ -7,26 +8,6 @@
  * Copyright 2001 Intel San Luis Obispo
  * Copyright 2000,2001 MontaVista Software Inc.
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <scottm@somanetworks.com>
  */
 
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
index c2bbe6b..db78b39 100644
--- a/drivers/pci/hotplug/cpqphp.h
+++ b/drivers/pci/hotplug/cpqphp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Compaq Hot Plug Controller Driver
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>
  *
  */
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 70967ac..1797e36 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Compaq Hot Plug Controller Driver
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>
  *
  * Jan 12, 2003 -	Added 66/100/133MHz PCI-X support,
@@ -835,7 +821,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	bus = pdev->subordinate;
 	if (!bus) {
-		dev_notice(&pdev->dev, "the device is not a bridge, skipping\n");
+		pci_notice(pdev, "the device is not a bridge, skipping\n");
 		rc = -ENODEV;
 		goto err_disable_device;
 	}
@@ -883,7 +869,6 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL);
 	if (!ctrl) {
-		err("%s : out of memory\n", __func__);
 		rc = -ENOMEM;
 		goto err_disable_device;
 	}
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index a93069e..b1b6e45 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Compaq Hot Plug Controller Driver
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>
  *
  */
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
index daae807..00cd2b4 100644
--- a/drivers/pci/hotplug/cpqphp_nvram.c
+++ b/drivers/pci/hotplug/cpqphp_nvram.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Compaq Hot Plug Controller Driver
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>
  *
  */
diff --git a/drivers/pci/hotplug/cpqphp_nvram.h b/drivers/pci/hotplug/cpqphp_nvram.h
index 34e4e54..918ff8d 100644
--- a/drivers/pci/hotplug/cpqphp_nvram.h
+++ b/drivers/pci/hotplug/cpqphp_nvram.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Compaq Hot Plug Controller Driver
  *
@@ -6,21 +7,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>
  *
  */
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index e220d49..1b2b3f3 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Compaq Hot Plug Controller Driver
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>
  *
  */
@@ -89,7 +75,9 @@ int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func)
 	pci_lock_rescan_remove();
 
 	if (func->pci_dev == NULL)
-		func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function));
+		func->pci_dev = pci_get_domain_bus_and_slot(0, func->bus,
+							PCI_DEVFN(func->device,
+							func->function));
 
 	/* No pci device, we need to create it then */
 	if (func->pci_dev == NULL) {
@@ -99,7 +87,9 @@ int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func)
 		if (num)
 			pci_bus_add_devices(ctrl->pci_dev->bus);
 
-		func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function));
+		func->pci_dev = pci_get_domain_bus_and_slot(0, func->bus,
+							PCI_DEVFN(func->device,
+							func->function));
 		if (func->pci_dev == NULL) {
 			dbg("ERROR: pci_dev still null\n");
 			goto out;
@@ -129,7 +119,10 @@ int cpqhp_unconfigure_device(struct pci_func *func)
 
 	pci_lock_rescan_remove();
 	for (j = 0; j < 8 ; j++) {
-		struct pci_dev *temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j));
+		struct pci_dev *temp = pci_get_domain_bus_and_slot(0,
+							func->bus,
+							PCI_DEVFN(func->device,
+							j));
 		if (temp) {
 			pci_dev_put(temp);
 			pci_stop_and_remove_bus_device(temp);
@@ -319,6 +312,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
 	int cloop = 0;
 	int stop_it;
 	int index;
+	u16 devfn;
 
 	/* Decide which slots are supported */
 
@@ -416,7 +410,9 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
 			new_slot->switch_save = 0x10;
 			/* In case of unsupported board */
 			new_slot->status = DevError;
-			new_slot->pci_dev = pci_get_bus_and_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
+			devfn = (new_slot->device << 3) | new_slot->function;
+			new_slot->pci_dev = pci_get_domain_bus_and_slot(0,
+							new_slot->bus, devfn);
 
 			for (cloop = 0; cloop < 0x20; cloop++) {
 				rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) &(new_slot->config_space[cloop]));
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index 775974d..fed1360 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Compaq Hot Plug Controller Driver
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>
  *
  */
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
index d325683..fddb786 100644
--- a/drivers/pci/hotplug/ibmphp.h
+++ b/drivers/pci/hotplug/ibmphp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 #ifndef __IBMPHP_H
 #define __IBMPHP_H
 
@@ -11,21 +12,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <gregkh@us.ibm.com>
  *
  */
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 73cf846..b81ca3f 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * IBM Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <gregkh@us.ibm.com>
  *
  */
@@ -603,10 +589,8 @@ int ibmphp_update_slot_info(struct slot *slot_cur)
 	u8 mode;
 
 	info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
-	if (!info) {
-		err("out of system memory\n");
+	if (!info)
 		return -ENOMEM;
-	}
 
 	info->power_status = SLOT_PWRGD(slot_cur->status);
 	info->attention_status = SLOT_ATTN(slot_cur->status,
@@ -707,7 +691,8 @@ static void ibm_unconfigure_device(struct pci_func *func)
 	pci_lock_rescan_remove();
 
 	for (j = 0; j < 0x08; j++) {
-		temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);
+		temp = pci_get_domain_bus_and_slot(0, func->busno,
+						   (func->device << 3) | j);
 		if (temp) {
 			pci_stop_and_remove_bus_device(temp);
 			pci_dev_put(temp);
@@ -734,14 +719,12 @@ static u8 bus_structure_fixup(u8 busno)
 		return 1;
 
 	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
-	if (!bus) {
-		err("%s - out of memory\n", __func__);
+	if (!bus)
 		return 1;
-	}
+
 	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
 		kfree(bus);
-		err("%s - out of memory\n", __func__);
 		return 1;
 	}
 
@@ -780,7 +763,7 @@ static int ibm_configure_device(struct pci_func *func)
 	if (!(bus_structure_fixup(func->busno)))
 		flag = 1;
 	if (func->dev == NULL)
-		func->dev = pci_get_bus_and_slot(func->busno,
+		func->dev = pci_get_domain_bus_and_slot(0, func->busno,
 				PCI_DEVFN(func->device, func->function));
 
 	if (func->dev == NULL) {
@@ -793,7 +776,7 @@ static int ibm_configure_device(struct pci_func *func)
 		if (num)
 			pci_bus_add_devices(bus);
 
-		func->dev = pci_get_bus_and_slot(func->busno,
+		func->dev = pci_get_domain_bus_and_slot(0, func->busno,
 				PCI_DEVFN(func->device, func->function));
 		if (func->dev == NULL) {
 			err("ERROR... : pci_dev still NULL\n");
@@ -1101,7 +1084,6 @@ static int enable_slot(struct hotplug_slot *hs)
 	if (!slot_cur->func) {
 		/* We cannot do update_slot_info here, since no memory for
 		 * kmalloc n.e.ways, and update_slot_info allocates some */
-		err("out of system memory\n");
 		rc = -ENOMEM;
 		goto error_power;
 	}
@@ -1208,7 +1190,6 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)
 		/* We need this for functions that were there on bootup */
 		slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
 		if (!slot_cur->func) {
-			err("out of system memory\n");
 			rc = -ENOMEM;
 			goto error;
 		}
@@ -1306,7 +1287,6 @@ static int __init ibmphp_init(void)
 
 	ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
 	if (!ibmphp_pci_bus) {
-		err("out of memory\n");
 		rc = -ENOMEM;
 		goto exit;
 	}
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
index a6a4dac7..64549aa 100644
--- a/drivers/pci/hotplug/ibmphp_ebda.c
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * IBM Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <gregkh@us.ibm.com>
  *
  */
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
index a6b458e..752c384 100644
--- a/drivers/pci/hotplug/ibmphp_hpc.c
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * IBM Hot Plug Controller Driver
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <gregkh@us.ibm.com>
  *                  <jshah@us.ibm.com>
  *
diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
index 25edd0b1..e22d023 100644
--- a/drivers/pci/hotplug/ibmphp_pci.c
+++ b/drivers/pci/hotplug/ibmphp_pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * IBM Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <gregkh@us.ibm.com>
  *
  */
@@ -167,10 +153,9 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno)
 						goto error;
 					}
 					newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
-					if (!newfunc) {
-						err("out of system memory\n");
+					if (!newfunc)
 						return -ENOMEM;
-					}
+
 					newfunc->busno = cur_func->busno;
 					newfunc->device = device;
 					cur_func->next = newfunc;
@@ -205,10 +190,9 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno)
 					for (i = 0; i < 32; i++) {
 						if (func->devices[i]) {
 							newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
-							if (!newfunc) {
-								err("out of system memory\n");
+							if (!newfunc)
 								return -ENOMEM;
-							}
+
 							newfunc->busno = sec_number;
 							newfunc->device = (u8) i;
 							for (j = 0; j < 4; j++)
@@ -233,10 +217,9 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno)
 					}
 
 					newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
-					if (!newfunc) {
-						err("out of system memory\n");
+					if (!newfunc)
 						return -ENOMEM;
-					}
+
 					newfunc->busno = cur_func->busno;
 					newfunc->device = device;
 					for (j = 0; j < 4; j++)
@@ -279,10 +262,9 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno)
 						if (func->devices[i]) {
 							debug("inside for loop, device is %x\n", i);
 							newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
-							if (!newfunc) {
-								err(" out of system memory\n");
+							if (!newfunc)
 								return -ENOMEM;
-							}
+
 							newfunc->busno = sec_number;
 							newfunc->device = (u8) i;
 							for (j = 0; j < 4; j++)
@@ -405,10 +387,9 @@ static int configure_device(struct pci_func *func)
 
 			io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
 
-			if (!io[count]) {
-				err("out of system memory\n");
+			if (!io[count])
 				return -ENOMEM;
-			}
+
 			io[count]->type = IO;
 			io[count]->busno = func->busno;
 			io[count]->devfunc = PCI_DEVFN(func->device, func->function);
@@ -442,10 +423,9 @@ static int configure_device(struct pci_func *func)
 				debug("len[count] in PFMEM %x, count %d\n", len[count], count);
 
 				pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
-				if (!pfmem[count]) {
-					err("out of system memory\n");
+				if (!pfmem[count])
 					return -ENOMEM;
-				}
+
 				pfmem[count]->type = PFMEM;
 				pfmem[count]->busno = func->busno;
 				pfmem[count]->devfunc = PCI_DEVFN(func->device,
@@ -458,7 +438,6 @@ static int configure_device(struct pci_func *func)
 				} else {
 					mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
 					if (!mem_tmp) {
-						err("out of system memory\n");
 						kfree(pfmem[count]);
 						return -ENOMEM;
 					}
@@ -508,10 +487,9 @@ static int configure_device(struct pci_func *func)
 				debug("len[count] in Mem %x, count %d\n", len[count], count);
 
 				mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
-				if (!mem[count]) {
-					err("out of system memory\n");
+				if (!mem[count])
 					return -ENOMEM;
-				}
+
 				mem[count]->type = MEM;
 				mem[count]->busno = func->busno;
 				mem[count]->devfunc = PCI_DEVFN(func->device,
@@ -674,7 +652,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
 			bus_io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
 
 			if (!bus_io[count]) {
-				err("out of system memory\n");
 				retval = -ENOMEM;
 				goto error;
 			}
@@ -706,7 +683,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
 
 				bus_pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
 				if (!bus_pfmem[count]) {
-					err("out of system memory\n");
 					retval = -ENOMEM;
 					goto error;
 				}
@@ -722,7 +698,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
 				} else {
 					mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
 					if (!mem_tmp) {
-						err("out of system memory\n");
 						retval = -ENOMEM;
 						goto error;
 					}
@@ -763,7 +738,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
 
 				bus_mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
 				if (!bus_mem[count]) {
-					err("out of system memory\n");
 					retval = -ENOMEM;
 					goto error;
 				}
@@ -834,7 +808,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
 		io = kzalloc(sizeof(*io), GFP_KERNEL);
 
 		if (!io) {
-			err("out of system memory\n");
 			retval = -ENOMEM;
 			goto error;
 		}
@@ -856,7 +829,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
 		debug("it wants %x memory behind the bridge\n", amount_needed->mem);
 		mem = kzalloc(sizeof(*mem), GFP_KERNEL);
 		if (!mem) {
-			err("out of system memory\n");
 			retval = -ENOMEM;
 			goto error;
 		}
@@ -878,7 +850,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
 		debug("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
 		pfmem = kzalloc(sizeof(*pfmem), GFP_KERNEL);
 		if (!pfmem) {
-			err("out of system memory\n");
 			retval = -ENOMEM;
 			goto error;
 		}
@@ -893,7 +864,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
 		} else {
 			mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
 			if (!mem_tmp) {
-				err("out of system memory\n");
 				retval = -ENOMEM;
 				goto error;
 			}
@@ -924,7 +894,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
 		if (!bus) {
 			bus = kzalloc(sizeof(*bus), GFP_KERNEL);
 			if (!bus) {
-				err("out of system memory\n");
 				retval = -ENOMEM;
 				goto error;
 			}
@@ -1652,10 +1621,9 @@ static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct re
 	}
 	if (io) {
 		io_range = kzalloc(sizeof(*io_range), GFP_KERNEL);
-		if (!io_range) {
-			err("out of system memory\n");
+		if (!io_range)
 			return -ENOMEM;
-		}
+
 		io_range->start = io->start;
 		io_range->end = io->end;
 		io_range->rangeno = 1;
@@ -1664,10 +1632,9 @@ static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct re
 	}
 	if (mem) {
 		mem_range = kzalloc(sizeof(*mem_range), GFP_KERNEL);
-		if (!mem_range) {
-			err("out of system memory\n");
+		if (!mem_range)
 			return -ENOMEM;
-		}
+
 		mem_range->start = mem->start;
 		mem_range->end = mem->end;
 		mem_range->rangeno = 1;
@@ -1676,10 +1643,9 @@ static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct re
 	}
 	if (pfmem) {
 		pfmem_range = kzalloc(sizeof(*pfmem_range), GFP_KERNEL);
-		if (!pfmem_range) {
-			err("out of system memory\n");
+		if (!pfmem_range)
 			return -ENOMEM;
-		}
+
 		pfmem_range->start = pfmem->start;
 		pfmem_range->end = pfmem->end;
 		pfmem_range->rangeno = 1;
diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c
index aee6e41..5e8caf7 100644
--- a/drivers/pci/hotplug/ibmphp_res.c
+++ b/drivers/pci/hotplug/ibmphp_res.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * IBM Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <gregkh@us.ibm.com>
  *
  */
@@ -56,10 +42,8 @@ static struct bus_node * __init alloc_error_bus(struct ebda_pci_rsrc *curr, u8 b
 	}
 
 	newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL);
-	if (!newbus) {
-		err("out of system memory\n");
+	if (!newbus)
 		return NULL;
-	}
 
 	if (flag)
 		newbus->busno = busno;
@@ -79,10 +63,9 @@ static struct resource_node * __init alloc_resources(struct ebda_pci_rsrc *curr)
 	}
 
 	rs = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
-	if (!rs) {
-		err("out of system memory\n");
+	if (!rs)
 		return NULL;
-	}
+
 	rs->busno = curr->bus_num;
 	rs->devfunc = curr->dev_fun;
 	rs->start = curr->start_addr;
@@ -99,10 +82,9 @@ static int __init alloc_bus_range(struct bus_node **new_bus, struct range_node *
 
 	if (first_bus) {
 		newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL);
-		if (!newbus) {
-			err("out of system memory.\n");
+		if (!newbus)
 			return -ENOMEM;
-		}
+
 		newbus->busno = curr->bus_num;
 	} else {
 		newbus = *new_bus;
@@ -123,7 +105,6 @@ static int __init alloc_bus_range(struct bus_node **new_bus, struct range_node *
 	if (!newrange) {
 		if (first_bus)
 			kfree(newbus);
-		err("out of system memory\n");
 		return -ENOMEM;
 	}
 	newrange->start = curr->start_addr;
@@ -1707,10 +1688,9 @@ static int __init once_over(void)
 				bus_cur->firstPFMemFromMem = pfmem_cur;
 
 				mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
-				if (!mem) {
-					err("out of system memory\n");
+				if (!mem)
 					return -ENOMEM;
-				}
+
 				mem->type = MEM;
 				mem->busno = pfmem_cur->busno;
 				mem->devfunc = pfmem_cur->devfunc;
@@ -1989,10 +1969,9 @@ static int __init update_bridge_ranges(struct bus_node **bus)
 
 						if ((start_address) && (start_address <= end_address)) {
 							range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
-							if (!range) {
-								err("out of system memory\n");
+							if (!range)
 								return -ENOMEM;
-							}
+
 							range->start = start_address;
 							range->end = end_address + 0xfff;
 
@@ -2016,7 +1995,6 @@ static int __init update_bridge_ranges(struct bus_node **bus)
 								io = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
 								if (!io) {
 									kfree(range);
-									err("out of system memory\n");
 									return -ENOMEM;
 								}
 								io->type = IO;
@@ -2038,10 +2016,9 @@ static int __init update_bridge_ranges(struct bus_node **bus)
 						if ((start_address) && (start_address <= end_address)) {
 
 							range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
-							if (!range) {
-								err("out of system memory\n");
+							if (!range)
 								return -ENOMEM;
-							}
+
 							range->start = start_address;
 							range->end = end_address + 0xfffff;
 
@@ -2066,7 +2043,6 @@ static int __init update_bridge_ranges(struct bus_node **bus)
 								mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
 								if (!mem) {
 									kfree(range);
-									err("out of system memory\n");
 									return -ENOMEM;
 								}
 								mem->type = MEM;
@@ -2092,10 +2068,9 @@ static int __init update_bridge_ranges(struct bus_node **bus)
 						if ((start_address) && (start_address <= end_address)) {
 
 							range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
-							if (!range) {
-								err("out of system memory\n");
+							if (!range)
 								return -ENOMEM;
-							}
+
 							range->start = start_address;
 							range->end = end_address + 0xfffff;
 
@@ -2119,7 +2094,6 @@ static int __init update_bridge_ranges(struct bus_node **bus)
 								pfmem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
 								if (!pfmem) {
 									kfree(range);
-									err("out of system memory\n");
 									return -ENOMEM;
 								}
 								pfmem->type = PFMEM;
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 7b0e97b..af92fed 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI HotPlug Controller Core
  *
@@ -6,21 +7,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <kristen.c.accardi@intel.com>
  *
  * Authors:
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 06109d4..636ed8f 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * PCI Express Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 35d8484..332b723 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI Express Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  * Authors:
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 83f3d4a..c684faa 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI Express Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7bab060..18a42f8 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI Express PCI Hot Plug Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
  *
  */
@@ -838,16 +824,22 @@ struct controller *pcie_init(struct pcie_device *dev)
 	struct pci_dev *pdev = dev->port;
 
 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
-	if (!ctrl) {
-		dev_err(&dev->device, "%s: Out of memory\n", __func__);
+	if (!ctrl)
 		goto abort;
-	}
+
 	ctrl->pcie = dev;
 	pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);
 
 	if (pdev->hotplug_user_indicators)
 		slot_cap &= ~(PCI_EXP_SLTCAP_AIP | PCI_EXP_SLTCAP_PIP);
 
+	/*
+	 * We assume no Thunderbolt controllers support Command Complete events,
+	 * but some controllers falsely claim they do.
+	 */
+	if (pdev->is_thunderbolt)
+		slot_cap |= PCI_EXP_SLTCAP_NCCS;
+
 	ctrl->slot_cap = slot_cap;
 	mutex_init(&ctrl->ctrl_lock);
 	init_waitqueue_head(&ctrl->queue);
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 2a1ca02..3f518de 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI Express Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
@@ -79,7 +65,6 @@ int pciehp_configure_device(struct slot *p_slot)
 int pciehp_unconfigure_device(struct slot *p_slot)
 {
 	int rc = 0;
-	u8 bctl = 0;
 	u8 presence = 0;
 	struct pci_dev *dev, *temp;
 	struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate;
@@ -101,17 +86,6 @@ int pciehp_unconfigure_device(struct slot *p_slot)
 	list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
 					 bus_list) {
 		pci_dev_get(dev);
-		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
-			pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
-			if (bctl & PCI_BRIDGE_CTL_VGA) {
-				ctrl_err(ctrl,
-					 "Cannot remove display device %s\n",
-					 pci_name(dev));
-				pci_dev_put(dev);
-				rc = -EINVAL;
-				break;
-			}
-		}
 		if (!presence) {
 			pci_dev_set_disconnected(dev, NULL);
 			if (pci_has_subordinate(dev))
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c
index 172ed89..c19694a 100644
--- a/drivers/pci/hotplug/pcihp_skeleton.c
+++ b/drivers/pci/hotplug/pcihp_skeleton.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI Hot Plug Controller Skeleton Driver - 0.3
  *
@@ -6,21 +7,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * This driver is to be used as a skeleton driver to show how to interface
  * with the pci hotplug core easily.
  *
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
index 74f6a17..23da304 100644
--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI Hotplug Driver for PowerPC PowerNV platform.
  *
  * Copyright Gavin Shan, IBM Corporation 2016.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
  */
 
 #include <linux/libfdt.h>
@@ -266,22 +262,18 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
 	fdt1 = kzalloc(0x10000, GFP_KERNEL);
 	if (!fdt1) {
 		ret = -ENOMEM;
-		dev_warn(&php_slot->pdev->dev, "Cannot alloc FDT blob\n");
 		goto out;
 	}
 
 	ret = pnv_pci_get_device_tree(php_slot->dn->phandle, fdt1, 0x10000);
 	if (ret) {
-		dev_warn(&php_slot->pdev->dev, "Error %d getting FDT blob\n",
-			 ret);
+		pci_warn(php_slot->pdev, "Error %d getting FDT blob\n", ret);
 		goto free_fdt1;
 	}
 
 	fdt = kzalloc(fdt_totalsize(fdt1), GFP_KERNEL);
 	if (!fdt) {
 		ret = -ENOMEM;
-		dev_warn(&php_slot->pdev->dev, "Cannot %d bytes memory\n",
-			 fdt_totalsize(fdt1));
 		goto free_fdt1;
 	}
 
@@ -290,7 +282,7 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
 	dt = of_fdt_unflatten_tree(fdt, php_slot->dn, NULL);
 	if (!dt) {
 		ret = -EINVAL;
-		dev_warn(&php_slot->pdev->dev, "Cannot unflatten FDT\n");
+		pci_warn(php_slot->pdev, "Cannot unflatten FDT\n");
 		goto free_fdt;
 	}
 
@@ -300,7 +292,7 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
 	ret = pnv_php_populate_changeset(&php_slot->ocs, php_slot->dn);
 	if (ret) {
 		pnv_php_reverse_nodes(php_slot->dn);
-		dev_warn(&php_slot->pdev->dev, "Error %d populating changeset\n",
+		pci_warn(php_slot->pdev, "Error %d populating changeset\n",
 			 ret);
 		goto free_dt;
 	}
@@ -308,8 +300,7 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
 	php_slot->dn->child = NULL;
 	ret = of_changeset_apply(&php_slot->ocs);
 	if (ret) {
-		dev_warn(&php_slot->pdev->dev, "Error %d applying changeset\n",
-			 ret);
+		pci_warn(php_slot->pdev, "Error %d applying changeset\n", ret);
 		goto destroy_changeset;
 	}
 
@@ -345,14 +336,14 @@ int pnv_php_set_slot_power_state(struct hotplug_slot *slot,
 		if (be64_to_cpu(msg.params[1]) != php_slot->dn->phandle	||
 		    be64_to_cpu(msg.params[2]) != state			||
 		    be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) {
-			dev_warn(&php_slot->pdev->dev, "Wrong msg (%lld, %lld, %lld)\n",
+			pci_warn(php_slot->pdev, "Wrong msg (%lld, %lld, %lld)\n",
 				 be64_to_cpu(msg.params[1]),
 				 be64_to_cpu(msg.params[2]),
 				 be64_to_cpu(msg.params[3]));
 			return -ENOMSG;
 		}
 	} else if (ret < 0) {
-		dev_warn(&php_slot->pdev->dev, "Error %d powering %s\n",
+		pci_warn(php_slot->pdev, "Error %d powering %s\n",
 			 ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off");
 		return ret;
 	}
@@ -379,7 +370,7 @@ static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state)
 	 */
 	ret = pnv_pci_get_power_state(php_slot->id, &power_state);
 	if (ret) {
-		dev_warn(&php_slot->pdev->dev, "Error %d getting power status\n",
+		pci_warn(php_slot->pdev, "Error %d getting power status\n",
 			 ret);
 	} else {
 		*state = power_state;
@@ -405,8 +396,7 @@ static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
 		slot->info->adapter_status = presence;
 		ret = 0;
 	} else {
-		dev_warn(&php_slot->pdev->dev, "Error %d getting presence\n",
-			 ret);
+		pci_warn(php_slot->pdev, "Error %d getting presence\n", ret);
 	}
 
 	return ret;
@@ -629,8 +619,7 @@ static int pnv_php_register_slot(struct pnv_php_slot *php_slot)
 	ret = pci_hp_register(&php_slot->slot, php_slot->bus,
 			      php_slot->slot_no, php_slot->name);
 	if (ret) {
-		dev_warn(&php_slot->pdev->dev, "Error %d registering slot\n",
-			 ret);
+		pci_warn(php_slot->pdev, "Error %d registering slot\n", ret);
 		return ret;
 	}
 
@@ -683,7 +672,7 @@ static int pnv_php_enable_msix(struct pnv_php_slot *php_slot)
 	/* Enable MSIx */
 	ret = pci_enable_msix_exact(pdev, &entry, 1);
 	if (ret) {
-		dev_warn(&pdev->dev, "Error %d enabling MSIx\n", ret);
+		pci_warn(pdev, "Error %d enabling MSIx\n", ret);
 		return ret;
 	}
 
@@ -727,7 +716,7 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
 		   (sts & PCI_EXP_SLTSTA_PDC)) {
 		ret = pnv_pci_get_presence_state(php_slot->id, &presence);
 		if (ret) {
-			dev_warn(&pdev->dev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
+			pci_warn(pdev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
 				 php_slot->name, ret, sts);
 			return IRQ_HANDLED;
 		}
@@ -757,12 +746,12 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
 	 */
 	event = kzalloc(sizeof(*event), GFP_ATOMIC);
 	if (!event) {
-		dev_warn(&pdev->dev, "PCI slot [%s] missed hotplug event 0x%04x\n",
+		pci_warn(pdev, "PCI slot [%s] missed hotplug event 0x%04x\n",
 			 php_slot->name, sts);
 		return IRQ_HANDLED;
 	}
 
-	dev_info(&pdev->dev, "PCI slot [%s] %s (IRQ: %d)\n",
+	pci_info(pdev, "PCI slot [%s] %s (IRQ: %d)\n",
 		 php_slot->name, added ? "added" : "removed", irq);
 	INIT_WORK(&event->work, pnv_php_event_handler);
 	event->added = added;
@@ -782,7 +771,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
 	/* Allocate workqueue */
 	php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name);
 	if (!php_slot->wq) {
-		dev_warn(&pdev->dev, "Cannot alloc workqueue\n");
+		pci_warn(pdev, "Cannot alloc workqueue\n");
 		pnv_php_disable_irq(php_slot, true);
 		return;
 	}
@@ -806,7 +795,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
 			  php_slot->name, php_slot);
 	if (ret) {
 		pnv_php_disable_irq(php_slot, true);
-		dev_warn(&pdev->dev, "Error %d enabling IRQ %d\n", ret, irq);
+		pci_warn(pdev, "Error %d enabling IRQ %d\n", ret, irq);
 		return;
 	}
 
@@ -842,7 +831,7 @@ static void pnv_php_enable_irq(struct pnv_php_slot *php_slot)
 
 	ret = pci_enable_device(pdev);
 	if (ret) {
-		dev_warn(&pdev->dev, "Error %d enabling device\n", ret);
+		pci_warn(pdev, "Error %d enabling device\n", ret);
 		return;
 	}
 
diff --git a/drivers/pci/hotplug/rpadlpar.h b/drivers/pci/hotplug/rpadlpar.h
index 81df939..1eeb55d 100644
--- a/drivers/pci/hotplug/rpadlpar.h
+++ b/drivers/pci/hotplug/rpadlpar.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Interface for Dynamic Logical Partitioning of I/O Slots on
  * RPA-compliant PPC64 platform.
@@ -6,11 +7,6 @@
  * October 2003
  *
  * Copyright (C) 2003 IBM.
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
  */
 #ifndef _RPADLPAR_IO_H_
 #define _RPADLPAR_IO_H_
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index fc01d7d..e2356a9 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Interface for Dynamic Logical Partitioning of I/O Slots on
  * RPA-compliant PPC64 platform.
@@ -8,11 +9,6 @@
  * October 2003
  *
  * Copyright (C) 2003 IBM.
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
  */
 
 #undef DEBUG
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c
index b806314..cdbfa5d 100644
--- a/drivers/pci/hotplug/rpadlpar_sysfs.c
+++ b/drivers/pci/hotplug/rpadlpar_sysfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Interface for Dynamic Logical Partitioning of I/O Slots on
  * RPA-compliant PPC64 platform.
@@ -6,11 +7,6 @@
  * October 2003
  *
  * Copyright (C) 2003 IBM.
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
  */
 #include <linux/kobject.h>
 #include <linux/string.h>
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index bdb844b..c831172 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
  *
@@ -5,21 +6,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <lxie@us.ibm.com>,
  *
  */
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 53902c7..fb5e084 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -1,24 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
  * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <lxie@us.ibm.com>
  *
  */
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index 32aabc5..0aac33e 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -1,24 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
  * Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <lxie@us.ibm.com>
  *
  */
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index 4898623..3840a20 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -1,24 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * RPA Virtual I/O device functions
  * Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <lxie@us.ibm.com>
  *
  */
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index 530d0e4..ffdc297 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI Hot Plug Controller Driver for System z
  *
@@ -5,8 +6,6 @@
  *
  * Author(s):
  *   Jan Glauber <jang@linux.vnet.ibm.com>
- *
- * License: GPL
  */
 
 #define KMSG_COMPONENT "zpci"
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index 339bce0..78b6bdb 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -1,8 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
  * Copyright (C) 2005-2006 Silicon Graphics, Inc. All rights reserved.
  *
  * This work was based on the 2.4/2.6 kernel development by Dick Reigner.
@@ -245,18 +242,18 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
 
 
 	if (rc == PCI_SLOT_ALREADY_UP) {
-		dev_dbg(&slot->pci_bus->self->dev, "is already active\n");
+		pci_dbg(slot->pci_bus->self, "is already active\n");
 		return 1; /* return 1 to user */
 	}
 
 	if (rc == PCI_L1_ERR) {
-		dev_dbg(&slot->pci_bus->self->dev, "L1 failure %d with message: %s",
+		pci_dbg(slot->pci_bus->self, "L1 failure %d with message: %s",
 			resp.resp_sub_errno, resp.resp_l1_msg);
 		return -EPERM;
 	}
 
 	if (rc) {
-		dev_dbg(&slot->pci_bus->self->dev, "insert failed with error %d sub-error %d\n",
+		pci_dbg(slot->pci_bus->self, "insert failed with error %d sub-error %d\n",
 			rc, resp.resp_sub_errno);
 		return -EIO;
 	}
@@ -281,23 +278,23 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
 
 	if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
 	    (rc == PCI_SLOT_ALREADY_DOWN)) {
-		dev_dbg(&slot->pci_bus->self->dev, "Slot %s already inactive\n", slot->physical_path);
+		pci_dbg(slot->pci_bus->self, "Slot %s already inactive\n", slot->physical_path);
 		return 1; /* return 1 to user */
 	}
 
 	if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
-		dev_dbg(&slot->pci_bus->self->dev, "Cannot remove last 33MHz card\n");
+		pci_dbg(slot->pci_bus->self, "Cannot remove last 33MHz card\n");
 		return -EPERM;
 	}
 
 	if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
-		dev_dbg(&slot->pci_bus->self->dev, "L1 failure %d with message \n%s\n",
+		pci_dbg(slot->pci_bus->self, "L1 failure %d with message \n%s\n",
 			resp.resp_sub_errno, resp.resp_l1_msg);
 		return -EPERM;
 	}
 
 	if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
-		dev_dbg(&slot->pci_bus->self->dev, "remove failed with error %d sub-error %d\n",
+		pci_dbg(slot->pci_bus->self, "remove failed with error %d sub-error %d\n",
 			rc, resp.resp_sub_errno);
 		return -EIO;
 	}
@@ -308,12 +305,12 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
 	if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
 		pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
 		pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
-		dev_dbg(&slot->pci_bus->self->dev, "remove successful\n");
+		pci_dbg(slot->pci_bus->self, "remove successful\n");
 		return 0;
 	}
 
 	if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
-		dev_dbg(&slot->pci_bus->self->dev, "remove failed rc = %d\n", rc);
+		pci_dbg(slot->pci_bus->self, "remove failed rc = %d\n", rc);
 	}
 
 	return rc;
@@ -366,7 +363,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
 	num_funcs = pci_scan_slot(slot->pci_bus,
 				  PCI_DEVFN(slot->device_num + 1, 0));
 	if (!num_funcs) {
-		dev_dbg(&slot->pci_bus->self->dev, "no device in slot\n");
+		pci_dbg(slot->pci_bus->self, "no device in slot\n");
 		mutex_unlock(&sn_hotplug_mutex);
 		return -ENODEV;
 	}
@@ -412,7 +409,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
 		phandle = acpi_device_handle(PCI_CONTROLLER(slot->pci_bus)->companion);
 
 		if (acpi_bus_get_device(phandle, &pdevice)) {
-			dev_dbg(&slot->pci_bus->self->dev, "no parent device, assuming NULL\n");
+			pci_dbg(slot->pci_bus->self, "no parent device, assuming NULL\n");
 			pdevice = NULL;
 		}
 
@@ -463,9 +460,9 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
 	mutex_unlock(&sn_hotplug_mutex);
 
 	if (rc == 0)
-		dev_dbg(&slot->pci_bus->self->dev, "insert operation successful\n");
+		pci_dbg(slot->pci_bus->self, "insert operation successful\n");
 	else
-		dev_dbg(&slot->pci_bus->self->dev, "insert operation failed rc = %d\n", rc);
+		pci_dbg(slot->pci_bus->self, "insert operation failed rc = %d\n", rc);
 
 	return rc;
 }
@@ -643,16 +640,16 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
 		if (rc)
 			goto register_err;
 	}
-	dev_dbg(&pci_bus->self->dev, "Registered bus with hotplug\n");
+	pci_dbg(pci_bus->self, "Registered bus with hotplug\n");
 	return rc;
 
 register_err:
-	dev_dbg(&pci_bus->self->dev, "bus failed to register with err = %d\n",
+	pci_dbg(pci_bus->self, "bus failed to register with err = %d\n",
 		rc);
 
 alloc_err:
 	if (rc == -ENOMEM)
-		dev_dbg(&pci_bus->self->dev, "Memory allocation error\n");
+		pci_dbg(pci_bus->self, "Memory allocation error\n");
 
 	/* destroy THIS element */
 	if (bss_hotplug_slot)
@@ -685,10 +682,10 @@ static int __init sn_pci_hotplug_init(void)
 
 		rc = sn_pci_bus_valid(pci_bus);
 		if (rc != 1) {
-			dev_dbg(&pci_bus->self->dev, "not a valid hotplug bus\n");
+			pci_dbg(pci_bus->self, "not a valid hotplug bus\n");
 			continue;
 		}
-		dev_dbg(&pci_bus->self->dev, "valid hotplug bus\n");
+		pci_dbg(pci_bus->self, "valid hotplug bus\n");
 
 		rc = sn_hotplug_slot_register(pci_bus);
 		if (!rc) {
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 70c7ea6..c55730b 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Standard Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
  *
  */
@@ -62,15 +48,15 @@ do {									\
 #define ctrl_dbg(ctrl, format, arg...)					\
 	do {								\
 		if (shpchp_debug)					\
-			dev_printk(KERN_DEBUG, &ctrl->pci_dev->dev,	\
+			pci_printk(KERN_DEBUG, ctrl->pci_dev,		\
 					format, ## arg);		\
 	} while (0)
 #define ctrl_err(ctrl, format, arg...)					\
-	dev_err(&ctrl->pci_dev->dev, format, ## arg)
+	pci_err(ctrl->pci_dev, format, ## arg)
 #define ctrl_info(ctrl, format, arg...)					\
-	dev_info(&ctrl->pci_dev->dev, format, ## arg)
+	pci_info(ctrl->pci_dev, format, ## arg)
 #define ctrl_warn(ctrl, format, arg...)					\
-	dev_warn(&ctrl->pci_dev->dev, format, ## arg)
+	pci_warn(ctrl->pci_dev, format, ## arg)
 
 
 #define SLOT_NAME_SIZE 10
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 7bfb87b..1f0f969 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Standard Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
@@ -305,10 +291,9 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		return -ENODEV;
 
 	ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
-	if (!ctrl) {
-		dev_err(&pdev->dev, "%s: Out of memory\n", __func__);
+	if (!ctrl)
 		goto err_out_none;
-	}
+
 	INIT_LIST_HEAD(&ctrl->slot_list);
 
 	rc = shpc_init(ctrl, pdev);
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 10c7927..bedda5b 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Standard Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 4810e96..db04728 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Standard PCI Hot Plug Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
  *
  */
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index ea63db5..1157013 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Standard Hot Plug Controller Driver
  *
@@ -8,21 +9,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
@@ -78,7 +64,6 @@ int shpchp_configure_device(struct slot *p_slot)
 int shpchp_unconfigure_device(struct slot *p_slot)
 {
 	int rc = 0;
-	u8 bctl = 0;
 	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
 	struct pci_dev *dev, *temp;
 	struct controller *ctrl = p_slot->ctrl;
@@ -93,17 +78,6 @@ int shpchp_unconfigure_device(struct slot *p_slot)
 			continue;
 
 		pci_dev_get(dev);
-		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-			pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
-			if (bctl & PCI_BRIDGE_CTL_VGA) {
-				ctrl_err(ctrl,
-					 "Cannot remove display device %s\n",
-					 pci_name(dev));
-				pci_dev_put(dev);
-				rc = -EINVAL;
-				break;
-			}
-		}
 		pci_stop_and_remove_bus_device(dev);
 		pci_dev_put(dev);
 	}
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
index 7efb56a..45658bb 100644
--- a/drivers/pci/hotplug/shpchp_sysfs.c
+++ b/drivers/pci/hotplug/shpchp_sysfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Compaq Hot Plug Controller Driver
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <greg@kroah.com>
  *
  */
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 0b7b5da..677924a 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * drivers/pci/iov.c
  *
@@ -259,19 +260,19 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
 			nres++;
 	}
 	if (nres != iov->nres) {
-		dev_err(&dev->dev, "not enough MMIO resources for SR-IOV\n");
+		pci_err(dev, "not enough MMIO resources for SR-IOV\n");
 		return -ENOMEM;
 	}
 
 	bus = pci_iov_virtfn_bus(dev, nr_virtfn - 1);
 	if (bus > dev->bus->busn_res.end) {
-		dev_err(&dev->dev, "can't enable %d VFs (bus %02x out of range of %pR)\n",
+		pci_err(dev, "can't enable %d VFs (bus %02x out of range of %pR)\n",
 			nr_virtfn, bus, &dev->bus->busn_res);
 		return -ENOMEM;
 	}
 
 	if (pci_enable_resources(dev, bars)) {
-		dev_err(&dev->dev, "SR-IOV: IOV BARS not allocated\n");
+		pci_err(dev, "SR-IOV: IOV BARS not allocated\n");
 		return -ENOMEM;
 	}
 
@@ -298,7 +299,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
 
 	rc = pcibios_sriov_enable(dev, initial);
 	if (rc) {
-		dev_err(&dev->dev, "failure %d from pcibios_sriov_enable()\n", rc);
+		pci_err(dev, "failure %d from pcibios_sriov_enable()\n", rc);
 		goto err_pcibios;
 	}
 
@@ -432,7 +433,7 @@ static int sriov_init(struct pci_dev *dev, int pos)
 		}
 		iov->barsz[i] = resource_size(res);
 		res->end = res->start + resource_size(res) * total - 1;
-		dev_info(&dev->dev, "VF(n) BAR%d space: %pR (contains BAR%d for %d VFs)\n",
+		pci_info(dev, "VF(n) BAR%d space: %pR (contains BAR%d for %d VFs)\n",
 			 i, res, i, total);
 		i += bar64;
 		nres++;
diff --git a/drivers/pci/irq.c b/drivers/pci/irq.c
index 10929cd..2a808e1 100644
--- a/drivers/pci/irq.c
+++ b/drivers/pci/irq.c
@@ -16,11 +16,10 @@ static void pci_note_irq_problem(struct pci_dev *pdev, const char *reason)
 {
 	struct pci_dev *parent = to_pci_dev(pdev->dev.parent);
 
-	dev_err(&pdev->dev,
-		"Potentially misrouted IRQ (Bridge %s %04x:%04x)\n",
+	pci_err(pdev, "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n",
 		dev_name(&parent->dev), parent->vendor, parent->device);
-	dev_err(&pdev->dev, "%s\n", reason);
-	dev_err(&pdev->dev, "Please report to linux-kernel@vger.kernel.org\n");
+	pci_err(pdev, "%s\n", reason);
+	pci_err(pdev, "Please report to linux-kernel@vger.kernel.org\n");
 	WARN_ON(1);
 }
 
diff --git a/drivers/pci/mmap.c b/drivers/pci/mmap.c
index 9a5e5a9..814a3ce 100644
--- a/drivers/pci/mmap.c
+++ b/drivers/pci/mmap.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * mmap.c — generic PCI resource mmap helper
  *
  * Copyright © 2017 Amazon.com, Inc. or its affiliates.
  *
  * Author: David Woodhouse <dwmw2@infradead.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index e066071..8b0729c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * File:	msi.c
  * Purpose:	PCI Message Signaled Interrupt (MSI)
@@ -578,7 +579,7 @@ static int msi_verify_entries(struct pci_dev *dev)
 	for_each_pci_msi_entry(entry, dev) {
 		if (!dev->no_64bit_msi || !entry->msg.address_hi)
 			continue;
-		dev_err(&dev->dev, "Device has broken 64-bit MSI but arch"
+		pci_err(dev, "Device has broken 64-bit MSI but arch"
 			" tried to assign one above 4G\n");
 		return -EIO;
 	}
@@ -962,7 +963,7 @@ static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries,
 
 	/* Check whether driver already requested for MSI irq */
 	if (dev->msi_enabled) {
-		dev_info(&dev->dev, "can't enable MSI-X (MSI IRQ already assigned)\n");
+		pci_info(dev, "can't enable MSI-X (MSI IRQ already assigned)\n");
 		return -EINVAL;
 	}
 	return msix_capability_init(dev, entries, nvec, affd);
@@ -1032,8 +1033,7 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
 
 	/* Check whether driver already requested MSI-X irqs */
 	if (dev->msix_enabled) {
-		dev_info(&dev->dev,
-			 "can't enable MSI (MSI-X already enabled)\n");
+		pci_info(dev, "can't enable MSI (MSI-X already enabled)\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index e112da1..a28355c 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -1,19 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * PCI <-> OF mapping helpers
  *
  * Copyright 2011 IBM Corp.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
  */
+#define pr_fmt(fmt)	"PCI: OF: " fmt
 
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
+#include <linux/of_address.h>
 #include <linux/of_pci.h>
 #include "pci.h"
 
@@ -51,8 +49,9 @@ struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus)
 	if (WARN_ON(bus->self || bus->parent))
 		return NULL;
 
-	/* Look for a node pointer in either the intermediary device we
-	 * create above the root bus or it's own parent. Normally only
+	/*
+	 * Look for a node pointer in either the intermediary device we
+	 * create above the root bus or its own parent. Normally only
 	 * the later is populated.
 	 */
 	if (bus->bridge->of_node)
@@ -88,3 +87,561 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus)
 	return NULL;
 #endif
 }
+
+static inline int __of_pci_pci_compare(struct device_node *node,
+				       unsigned int data)
+{
+	int devfn;
+
+	devfn = of_pci_get_devfn(node);
+	if (devfn < 0)
+		return 0;
+
+	return devfn == data;
+}
+
+struct device_node *of_pci_find_child_device(struct device_node *parent,
+					     unsigned int devfn)
+{
+	struct device_node *node, *node2;
+
+	for_each_child_of_node(parent, node) {
+		if (__of_pci_pci_compare(node, devfn))
+			return node;
+		/*
+		 * Some OFs create a parent node "multifunc-device" as
+		 * a fake root for all functions of a multi-function
+		 * device we go down them as well.
+		 */
+		if (!strcmp(node->name, "multifunc-device")) {
+			for_each_child_of_node(node, node2) {
+				if (__of_pci_pci_compare(node2, devfn)) {
+					of_node_put(node);
+					return node2;
+				}
+			}
+		}
+	}
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(of_pci_find_child_device);
+
+/**
+ * of_pci_get_devfn() - Get device and function numbers for a device node
+ * @np: device node
+ *
+ * Parses a standard 5-cell PCI resource and returns an 8-bit value that can
+ * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device
+ * and function numbers respectively. On error a negative error code is
+ * returned.
+ */
+int of_pci_get_devfn(struct device_node *np)
+{
+	u32 reg[5];
+	int error;
+
+	error = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
+	if (error)
+		return error;
+
+	return (reg[0] >> 8) & 0xff;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_devfn);
+
+/**
+ * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
+ * @node: device node
+ * @res: address to a struct resource to return the bus-range
+ *
+ * Returns 0 on success or a negative error-code on failure.
+ */
+int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
+{
+	u32 bus_range[2];
+	int error;
+
+	error = of_property_read_u32_array(node, "bus-range", bus_range,
+					   ARRAY_SIZE(bus_range));
+	if (error)
+		return error;
+
+	res->name = node->name;
+	res->start = bus_range[0];
+	res->end = bus_range[1];
+	res->flags = IORESOURCE_BUS;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
+
+/**
+ * This function will try to obtain the host bridge domain number by
+ * finding a property called "linux,pci-domain" of the given device node.
+ *
+ * @node: device tree node with the domain information
+ *
+ * Returns the associated domain number from DT in the range [0-0xffff], or
+ * a negative value if the required property is not found.
+ */
+int of_get_pci_domain_nr(struct device_node *node)
+{
+	u32 domain;
+	int error;
+
+	error = of_property_read_u32(node, "linux,pci-domain", &domain);
+	if (error)
+		return error;
+
+	return (u16)domain;
+}
+EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
+
+/**
+ * This function will try to find the limitation of link speed by finding
+ * a property called "max-link-speed" of the given device node.
+ *
+ * @node: device tree node with the max link speed information
+ *
+ * Returns the associated max link speed from DT, or a negative value if the
+ * required property is not found or is invalid.
+ */
+int of_pci_get_max_link_speed(struct device_node *node)
+{
+	u32 max_link_speed;
+
+	if (of_property_read_u32(node, "max-link-speed", &max_link_speed) ||
+	    max_link_speed > 4)
+		return -EINVAL;
+
+	return max_link_speed;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
+
+/**
+ * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
+ *                           is present and valid
+ */
+void of_pci_check_probe_only(void)
+{
+	u32 val;
+	int ret;
+
+	ret = of_property_read_u32(of_chosen, "linux,pci-probe-only", &val);
+	if (ret) {
+		if (ret == -ENODATA || ret == -EOVERFLOW)
+			pr_warn("linux,pci-probe-only without valid value, ignoring\n");
+		return;
+	}
+
+	if (val)
+		pci_add_flags(PCI_PROBE_ONLY);
+	else
+		pci_clear_flags(PCI_PROBE_ONLY);
+
+	pr_info("PROBE_ONLY %sabled\n", val ? "en" : "dis");
+}
+EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
+
+#if defined(CONFIG_OF_ADDRESS)
+/**
+ * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
+ * @dev: device node of the host bridge having the range property
+ * @busno: bus number associated with the bridge root bus
+ * @bus_max: maximum number of buses for this bridge
+ * @resources: list where the range of resources will be added after DT parsing
+ * @io_base: pointer to a variable that will contain on return the physical
+ * address for the start of the I/O range. Can be NULL if the caller doesn't
+ * expect I/O ranges to be present in the device tree.
+ *
+ * It is the caller's job to free the @resources list.
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping based on its content. It is expected
+ * that the property conforms with the Power ePAPR document.
+ *
+ * It returns zero if the range parsing has been successful or a standard error
+ * value if it failed.
+ */
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+			unsigned char busno, unsigned char bus_max,
+			struct list_head *resources, resource_size_t *io_base)
+{
+	struct resource_entry *window;
+	struct resource *res;
+	struct resource *bus_range;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	char range_type[4];
+	int err;
+
+	if (io_base)
+		*io_base = (resource_size_t)OF_BAD_ADDR;
+
+	bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
+	if (!bus_range)
+		return -ENOMEM;
+
+	pr_info("host bridge %pOF ranges:\n", dev);
+
+	err = of_pci_parse_bus_range(dev, bus_range);
+	if (err) {
+		bus_range->start = busno;
+		bus_range->end = bus_max;
+		bus_range->flags = IORESOURCE_BUS;
+		pr_info("  No bus range found for %pOF, using %pR\n",
+			dev, bus_range);
+	} else {
+		if (bus_range->end > bus_range->start + bus_max)
+			bus_range->end = bus_range->start + bus_max;
+	}
+	pci_add_resource(resources, bus_range);
+
+	/* Check for ranges property */
+	err = of_pci_range_parser_init(&parser, dev);
+	if (err)
+		goto parse_failed;
+
+	pr_debug("Parsing ranges property...\n");
+	for_each_of_pci_range(&parser, &range) {
+		/* Read next ranges element */
+		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
+			snprintf(range_type, 4, " IO");
+		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
+			snprintf(range_type, 4, "MEM");
+		else
+			snprintf(range_type, 4, "err");
+		pr_info("  %s %#010llx..%#010llx -> %#010llx\n", range_type,
+			range.cpu_addr, range.cpu_addr + range.size - 1,
+			range.pci_addr);
+
+		/*
+		 * If we failed translation or got a zero-sized region
+		 * then skip this range
+		 */
+		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
+			continue;
+
+		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+		if (!res) {
+			err = -ENOMEM;
+			goto parse_failed;
+		}
+
+		err = of_pci_range_to_resource(&range, dev, res);
+		if (err) {
+			kfree(res);
+			continue;
+		}
+
+		if (resource_type(res) == IORESOURCE_IO) {
+			if (!io_base) {
+				pr_err("I/O range found for %pOF. Please provide an io_base pointer to save CPU base address\n",
+					dev);
+				err = -EINVAL;
+				goto conversion_failed;
+			}
+			if (*io_base != (resource_size_t)OF_BAD_ADDR)
+				pr_warn("More than one I/O resource converted for %pOF. CPU base address for old range lost!\n",
+					dev);
+			*io_base = range.cpu_addr;
+		}
+
+		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
+	}
+
+	return 0;
+
+conversion_failed:
+	kfree(res);
+parse_failed:
+	resource_list_for_each_entry(window, resources)
+		kfree(window->res);
+	pci_free_resource_list(resources);
+	return err;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
+#endif /* CONFIG_OF_ADDRESS */
+
+/**
+ * of_pci_map_rid - Translate a requester ID through a downstream mapping.
+ * @np: root complex device node.
+ * @rid: PCI requester ID to map.
+ * @map_name: property name of the map to use.
+ * @map_mask_name: optional property name of the mask to use.
+ * @target: optional pointer to a target device node.
+ * @id_out: optional pointer to receive the translated ID.
+ *
+ * Given a PCI requester ID, look up the appropriate implementation-defined
+ * platform ID and/or the target device which receives transactions on that
+ * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
+ * @id_out may be NULL if only the other is required. If @target points to
+ * a non-NULL device node pointer, only entries targeting that node will be
+ * matched; if it points to a NULL value, it will receive the device node of
+ * the first matching target phandle, with a reference held.
+ *
+ * Return: 0 on success or a standard error code on failure.
+ */
+int of_pci_map_rid(struct device_node *np, u32 rid,
+		   const char *map_name, const char *map_mask_name,
+		   struct device_node **target, u32 *id_out)
+{
+	u32 map_mask, masked_rid;
+	int map_len;
+	const __be32 *map = NULL;
+
+	if (!np || !map_name || (!target && !id_out))
+		return -EINVAL;
+
+	map = of_get_property(np, map_name, &map_len);
+	if (!map) {
+		if (target)
+			return -ENODEV;
+		/* Otherwise, no map implies no translation */
+		*id_out = rid;
+		return 0;
+	}
+
+	if (!map_len || map_len % (4 * sizeof(*map))) {
+		pr_err("%pOF: Error: Bad %s length: %d\n", np,
+			map_name, map_len);
+		return -EINVAL;
+	}
+
+	/* The default is to select all bits. */
+	map_mask = 0xffffffff;
+
+	/*
+	 * Can be overridden by "{iommu,msi}-map-mask" property.
+	 * If of_property_read_u32() fails, the default is used.
+	 */
+	if (map_mask_name)
+		of_property_read_u32(np, map_mask_name, &map_mask);
+
+	masked_rid = map_mask & rid;
+	for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
+		struct device_node *phandle_node;
+		u32 rid_base = be32_to_cpup(map + 0);
+		u32 phandle = be32_to_cpup(map + 1);
+		u32 out_base = be32_to_cpup(map + 2);
+		u32 rid_len = be32_to_cpup(map + 3);
+
+		if (rid_base & ~map_mask) {
+			pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n",
+				np, map_name, map_name,
+				map_mask, rid_base);
+			return -EFAULT;
+		}
+
+		if (masked_rid < rid_base || masked_rid >= rid_base + rid_len)
+			continue;
+
+		phandle_node = of_find_node_by_phandle(phandle);
+		if (!phandle_node)
+			return -ENODEV;
+
+		if (target) {
+			if (*target)
+				of_node_put(phandle_node);
+			else
+				*target = phandle_node;
+
+			if (*target != phandle_node)
+				continue;
+		}
+
+		if (id_out)
+			*id_out = masked_rid - rid_base + out_base;
+
+		pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n",
+			np, map_name, map_mask, rid_base, out_base,
+			rid_len, rid, masked_rid - rid_base + out_base);
+		return 0;
+	}
+
+	pr_err("%pOF: Invalid %s translation - no match for rid 0x%x on %pOF\n",
+		np, map_name, rid, target && *target ? *target : NULL);
+	return -EFAULT;
+}
+
+#if IS_ENABLED(CONFIG_OF_IRQ)
+/**
+ * of_irq_parse_pci - Resolve the interrupt for a PCI device
+ * @pdev:       the device whose interrupt is to be resolved
+ * @out_irq:    structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+static int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
+{
+	struct device_node *dn, *ppnode;
+	struct pci_dev *ppdev;
+	__be32 laddr[3];
+	u8 pin;
+	int rc;
+
+	/*
+	 * Check if we have a device node, if yes, fallback to standard
+	 * device tree parsing
+	 */
+	dn = pci_device_to_OF_node(pdev);
+	if (dn) {
+		rc = of_irq_parse_one(dn, 0, out_irq);
+		if (!rc)
+			return rc;
+	}
+
+	/*
+	 * Ok, we don't, time to have fun. Let's start by building up an
+	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
+	 * for PCI. If you do different, then don't use that routine.
+	 */
+	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+	if (rc != 0)
+		goto err;
+	/* No pin, exit with no error message. */
+	if (pin == 0)
+		return -ENODEV;
+
+	/* Now we walk up the PCI tree */
+	for (;;) {
+		/* Get the pci_dev of our parent */
+		ppdev = pdev->bus->self;
+
+		/* Ouch, it's a host bridge... */
+		if (ppdev == NULL) {
+			ppnode = pci_bus_to_OF_node(pdev->bus);
+
+			/* No node for host bridge ? give up */
+			if (ppnode == NULL) {
+				rc = -EINVAL;
+				goto err;
+			}
+		} else {
+			/* We found a P2P bridge, check if it has a node */
+			ppnode = pci_device_to_OF_node(ppdev);
+		}
+
+		/*
+		 * Ok, we have found a parent with a device-node, hand over to
+		 * the OF parsing code.
+		 * We build a unit address from the linux device to be used for
+		 * resolution. Note that we use the linux bus number which may
+		 * not match your firmware bus numbering.
+		 * Fortunately, in most cases, interrupt-map-mask doesn't
+		 * include the bus number as part of the matching.
+		 * You should still be careful about that though if you intend
+		 * to rely on this function (you ship a firmware that doesn't
+		 * create device nodes for all PCI devices).
+		 */
+		if (ppnode)
+			break;
+
+		/*
+		 * We can only get here if we hit a P2P bridge with no node;
+		 * let's do standard swizzling and try again
+		 */
+		pin = pci_swizzle_interrupt_pin(pdev, pin);
+		pdev = ppdev;
+	}
+
+	out_irq->np = ppnode;
+	out_irq->args_count = 1;
+	out_irq->args[0] = pin;
+	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+	laddr[1] = laddr[2] = cpu_to_be32(0);
+	rc = of_irq_parse_raw(laddr, out_irq);
+	if (rc)
+		goto err;
+	return 0;
+err:
+	if (rc == -ENOENT) {
+		dev_warn(&pdev->dev,
+			"%s: no interrupt-map found, INTx interrupts not available\n",
+			__func__);
+		pr_warn_once("%s: possibly some PCI slots don't have level triggered interrupts capability\n",
+			__func__);
+	} else {
+		dev_err(&pdev->dev, "%s: failed with rc=%d\n", __func__, rc);
+	}
+	return rc;
+}
+
+/**
+ * of_irq_parse_and_map_pci() - Decode a PCI IRQ from the device tree and map to a VIRQ
+ * @dev: The PCI device needing an IRQ
+ * @slot: PCI slot number; passed when used as map_irq callback. Unused
+ * @pin: PCI IRQ pin number; passed when used as map_irq callback. Unused
+ *
+ * @slot and @pin are unused, but included in the function so that this
+ * function can be used directly as the map_irq callback to
+ * pci_assign_irq() and struct pci_host_bridge.map_irq pointer
+ */
+int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct of_phandle_args oirq;
+	int ret;
+
+	ret = of_irq_parse_pci(dev, &oirq);
+	if (ret)
+		return 0; /* Proper return code 0 == NO_IRQ */
+
+	return irq_create_of_mapping(&oirq);
+}
+EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
+#endif	/* CONFIG_OF_IRQ */
+
+int pci_parse_request_of_pci_ranges(struct device *dev,
+				    struct list_head *resources,
+				    struct resource **bus_range)
+{
+	int err, res_valid = 0;
+	struct device_node *np = dev->of_node;
+	resource_size_t iobase;
+	struct resource_entry *win, *tmp;
+
+	INIT_LIST_HEAD(resources);
+	err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase);
+	if (err)
+		return err;
+
+	err = devm_request_pci_bus_resources(dev, resources);
+	if (err)
+		goto out_release_res;
+
+	resource_list_for_each_entry_safe(win, tmp, resources) {
+		struct resource *res = win->res;
+
+		switch (resource_type(res)) {
+		case IORESOURCE_IO:
+			err = pci_remap_iospace(res, iobase);
+			if (err) {
+				dev_warn(dev, "error %d: failed to map resource %pR\n",
+					 err, res);
+				resource_list_destroy_entry(win);
+			}
+			break;
+		case IORESOURCE_MEM:
+			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
+			break;
+		case IORESOURCE_BUS:
+			if (bus_range)
+				*bus_range = res;
+			break;
+		}
+	}
+
+	if (res_valid)
+		return 0;
+
+	dev_err(dev, "non-prefetchable memory resource required\n");
+	err = -EINVAL;
+
+ out_release_res:
+	pci_free_resource_list(resources);
+	return err;
+}
+
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 4708eb9..7815768 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * File:	pci-acpi.c
  * Purpose:	Provide PCI support in ACPI
@@ -542,7 +543,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 	}
 
 	if (!error)
-		dev_dbg(&dev->dev, "power state changed by ACPI to %s\n",
+		pci_dbg(dev, "power state changed by ACPI to %s\n",
 			 acpi_power_state_string(state_conv[state]));
 
 	return error;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 5958c8d..3bed6be 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1,11 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * drivers/pci/pci-driver.c
  *
  * (C) Copyright 2002-2004, 2007 Greg Kroah-Hartman <greg@kroah.com>
  * (C) Copyright 2007 Novell Inc.
- *
- * Released under the GPL v2 only.
- *
  */
 
 #include <linux/pci.h>
diff --git a/drivers/pci/pci-mid.c b/drivers/pci/pci-mid.c
index a4ac940..314e135 100644
--- a/drivers/pci/pci-mid.c
+++ b/drivers/pci/pci-mid.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Intel MID platform PM support
  *
  * Copyright (C) 2016, Intel Corporation
  *
  * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
  */
 
 #include <linux/init.h>
diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c
index 886fb35..10d54f9 100644
--- a/drivers/pci/pci-stub.c
+++ b/drivers/pci/pci-stub.c
@@ -1,11 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /* pci-stub - simple stub driver to reserve a pci device
  *
  * Copyright (C) 2008 Red Hat, Inc.
  * Author:
  *	Chris Wright
  *
- * This work is licensed under the terms of the GNU GPL, version 2.
- *
  * Usage is simple, allocate a new id to the stub driver and bind the
  * device to it.  For example:
  *
@@ -28,7 +27,7 @@ MODULE_PARM_DESC(ids, "Initial PCI IDs to add to the stub driver, format is "
 
 static int pci_stub_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-	dev_info(&dev->dev, "claimed by stub\n");
+	pci_info(dev, "claimed by stub\n");
 	return 0;
 }
 
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 06c7f0b..eb6bee8 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -278,6 +278,16 @@ static ssize_t subordinate_bus_number_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(subordinate_bus_number);
 
+static ssize_t ari_enabled_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+
+	return sprintf(buf, "%u\n", pci_ari_enabled(pci_dev->bus));
+}
+static DEVICE_ATTR_RO(ari_enabled);
+
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 {
@@ -348,7 +358,7 @@ static ssize_t numa_node_store(struct device *dev,
 		return -EINVAL;
 
 	add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
-	dev_alert(&pdev->dev, FW_BUG "Overriding NUMA node to %d.  Contact your vendor for updates.",
+	pci_alert(pdev, FW_BUG "Overriding NUMA node to %d.  Contact your vendor for updates.",
 		  node);
 
 	dev->numa_node = node;
@@ -411,7 +421,7 @@ static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr,
 	 */
 	if (!subordinate) {
 		pdev->no_msi = !val;
-		dev_info(&pdev->dev, "MSI/MSI-X %s for future drivers\n",
+		pci_info(pdev, "MSI/MSI-X %s for future drivers\n",
 			 val ? "allowed" : "disallowed");
 		return count;
 	}
@@ -613,7 +623,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
 
 	/* is PF driver loaded w/callback */
 	if (!pdev->driver || !pdev->driver->sriov_configure) {
-		dev_info(&pdev->dev, "Driver doesn't support SRIOV configuration via sysfs\n");
+		pci_info(pdev, "Driver doesn't support SRIOV configuration via sysfs\n");
 		ret = -ENOENT;
 		goto exit;
 	}
@@ -626,7 +636,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
 
 	/* enable VFs */
 	if (pdev->sriov->num_VFs) {
-		dev_warn(&pdev->dev, "%d VFs already enabled. Disable before enabling %d VFs\n",
+		pci_warn(pdev, "%d VFs already enabled. Disable before enabling %d VFs\n",
 			 pdev->sriov->num_VFs, num_vfs);
 		ret = -EBUSY;
 		goto exit;
@@ -637,7 +647,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
 		goto exit;
 
 	if (ret != num_vfs)
-		dev_warn(&pdev->dev, "%d VFs requested; only %d enabled\n",
+		pci_warn(pdev, "%d VFs requested; only %d enabled\n",
 			 num_vfs, ret);
 
 exit:
@@ -786,6 +796,7 @@ static struct attribute *pci_dev_attrs[] = {
 	&dev_attr_devspec.attr,
 #endif
 	&dev_attr_driver_override.attr,
+	&dev_attr_ari_enabled.attr,
 	NULL,
 };
 
@@ -1216,14 +1227,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
 	if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
 		return -EINVAL;
 
-	if (!pci_mmap_fits(pdev, bar, vma, PCI_MMAP_SYSFS)) {
-		WARN(1, "process \"%s\" tried to map 0x%08lx bytes at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
-			current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
-			pci_name(pdev), bar,
-			(u64)pci_resource_start(pdev, bar),
-			(u64)pci_resource_len(pdev, bar));
+	if (!pci_mmap_fits(pdev, bar, vma, PCI_MMAP_SYSFS))
 		return -EINVAL;
-	}
+
 	mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
 
 	return pci_mmap_resource_range(pdev, bar, vma, mmap_type, write_combine);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 764ca7b..f6a4dd10 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *	PCI Bus Services, see include/linux/pci.h for further explanation.
  *
@@ -156,7 +157,7 @@ void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
 	 * Make sure the BAR is actually a memory resource, not an IO resource
 	 */
 	if (res->flags & IORESOURCE_UNSET || !(res->flags & IORESOURCE_MEM)) {
-		dev_warn(&pdev->dev, "can't ioremap BAR %d: %pR\n", bar, res);
+		pci_warn(pdev, "can't ioremap BAR %d: %pR\n", bar, res);
 		return NULL;
 	}
 	return ioremap_nocache(res->start, resource_size(res));
@@ -648,7 +649,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
 	 */
 	if (state != PCI_D0 && dev->current_state <= PCI_D3cold
 	    && dev->current_state > state) {
-		dev_err(&dev->dev, "invalid power transition (from state %d to %d)\n",
+		pci_err(dev, "invalid power transition (from state %d to %d)\n",
 			dev->current_state, state);
 		return -EINVAL;
 	}
@@ -696,7 +697,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
 	pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
 	dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
 	if (dev->current_state != state && printk_ratelimit())
-		dev_info(&dev->dev, "Refused to change power state, currently in D%d\n",
+		pci_info(dev, "Refused to change power state, currently in D%d\n",
 			 dev->current_state);
 
 	/*
@@ -970,7 +971,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
 	case PM_EVENT_HIBERNATE:
 		return PCI_D3hot;
 	default:
-		dev_info(&dev->dev, "unrecognized suspend event %d\n",
+		pci_info(dev, "unrecognized suspend event %d\n",
 			 state.event);
 		BUG();
 	}
@@ -1013,7 +1014,7 @@ static int pci_save_pcie_state(struct pci_dev *dev)
 
 	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
 	if (!save_state) {
-		dev_err(&dev->dev, "buffer not found in %s\n", __func__);
+		pci_err(dev, "buffer not found in %s\n", __func__);
 		return -ENOMEM;
 	}
 
@@ -1061,7 +1062,7 @@ static int pci_save_pcix_state(struct pci_dev *dev)
 
 	save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
 	if (!save_state) {
-		dev_err(&dev->dev, "buffer not found in %s\n", __func__);
+		pci_err(dev, "buffer not found in %s\n", __func__);
 		return -ENOMEM;
 	}
 
@@ -1121,7 +1122,7 @@ static void pci_restore_config_dword(struct pci_dev *pdev, int offset,
 		return;
 
 	for (;;) {
-		dev_dbg(&pdev->dev, "restoring config space at offset %#x (was %#x, writing %#x)\n",
+		pci_dbg(pdev, "restoring config space at offset %#x (was %#x, writing %#x)\n",
 			offset, val, saved_val);
 		pci_write_config_dword(pdev, offset, saved_val);
 		if (retry-- <= 0)
@@ -1358,7 +1359,7 @@ static void pci_enable_bridge(struct pci_dev *dev)
 
 	retval = pci_enable_device(dev);
 	if (retval)
-		dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n",
+		pci_err(dev, "Error enabling bridge (%d), continuing\n",
 			retval);
 	pci_set_master(dev);
 }
@@ -1867,7 +1868,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
 			pme_dev = kmalloc(sizeof(struct pci_pme_device),
 					  GFP_KERNEL);
 			if (!pme_dev) {
-				dev_warn(&dev->dev, "can't enable PME#\n");
+				pci_warn(dev, "can't enable PME#\n");
 				return;
 			}
 			pme_dev->dev = dev;
@@ -1891,7 +1892,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
 		}
 	}
 
-	dev_dbg(&dev->dev, "PME# %s\n", enable ? "enabled" : "disabled");
+	pci_dbg(dev, "PME# %s\n", enable ? "enabled" : "disabled");
 }
 EXPORT_SYMBOL(pci_pme_active);
 
@@ -2428,7 +2429,7 @@ void pci_pm_init(struct pci_dev *dev)
 	pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc);
 
 	if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
-		dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n",
+		pci_err(dev, "unsupported PM cap regs version (%u)\n",
 			pmc & PCI_PM_CAP_VER_MASK);
 		return;
 	}
@@ -2448,15 +2449,14 @@ void pci_pm_init(struct pci_dev *dev)
 			dev->d2_support = true;
 
 		if (dev->d1_support || dev->d2_support)
-			dev_printk(KERN_DEBUG, &dev->dev, "supports%s%s\n",
+			pci_printk(KERN_DEBUG, dev, "supports%s%s\n",
 				   dev->d1_support ? " D1" : "",
 				   dev->d2_support ? " D2" : "");
 	}
 
 	pmc &= PCI_PM_CAP_PME_MASK;
 	if (pmc) {
-		dev_printk(KERN_DEBUG, &dev->dev,
-			 "PME# supported from%s%s%s%s%s\n",
+		pci_printk(KERN_DEBUG, dev, "PME# supported from%s%s%s%s%s\n",
 			 (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
 			 (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
 			 (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
@@ -2548,13 +2548,13 @@ static int pci_ea_read(struct pci_dev *dev, int offset)
 
 	res = pci_ea_get_resource(dev, bei, prop);
 	if (!res) {
-		dev_err(&dev->dev, "Unsupported EA entry BEI: %u\n", bei);
+		pci_err(dev, "Unsupported EA entry BEI: %u\n", bei);
 		goto out;
 	}
 
 	flags = pci_ea_flags(dev, prop);
 	if (!flags) {
-		dev_err(&dev->dev, "Unsupported EA properties: %#x\n", prop);
+		pci_err(dev, "Unsupported EA properties: %#x\n", prop);
 		goto out;
 	}
 
@@ -2604,13 +2604,12 @@ static int pci_ea_read(struct pci_dev *dev, int offset)
 	}
 
 	if (end < start) {
-		dev_err(&dev->dev, "EA Entry crosses address boundary\n");
+		pci_err(dev, "EA Entry crosses address boundary\n");
 		goto out;
 	}
 
 	if (ent_size != ent_offset - offset) {
-		dev_err(&dev->dev,
-			"EA Entry Size (%d) does not match length read (%d)\n",
+		pci_err(dev, "EA Entry Size (%d) does not match length read (%d)\n",
 			ent_size, ent_offset - offset);
 		goto out;
 	}
@@ -2621,16 +2620,16 @@ static int pci_ea_read(struct pci_dev *dev, int offset)
 	res->flags = flags;
 
 	if (bei <= PCI_EA_BEI_BAR5)
-		dev_printk(KERN_DEBUG, &dev->dev, "BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
+		pci_printk(KERN_DEBUG, dev, "BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
 			   bei, res, prop);
 	else if (bei == PCI_EA_BEI_ROM)
-		dev_printk(KERN_DEBUG, &dev->dev, "ROM: %pR (from Enhanced Allocation, properties %#02x)\n",
+		pci_printk(KERN_DEBUG, dev, "ROM: %pR (from Enhanced Allocation, properties %#02x)\n",
 			   res, prop);
 	else if (bei >= PCI_EA_BEI_VF_BAR0 && bei <= PCI_EA_BEI_VF_BAR5)
-		dev_printk(KERN_DEBUG, &dev->dev, "VF BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
+		pci_printk(KERN_DEBUG, dev, "VF BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
 			   bei - PCI_EA_BEI_VF_BAR0, res, prop);
 	else
-		dev_printk(KERN_DEBUG, &dev->dev, "BEI %d res: %pR (from Enhanced Allocation, properties %#02x)\n",
+		pci_printk(KERN_DEBUG, dev, "BEI %d res: %pR (from Enhanced Allocation, properties %#02x)\n",
 			   bei, res, prop);
 
 out:
@@ -2727,13 +2726,11 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
 	error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP,
 					PCI_EXP_SAVE_REGS * sizeof(u16));
 	if (error)
-		dev_err(&dev->dev,
-			"unable to preallocate PCI Express save buffer\n");
+		pci_err(dev, "unable to preallocate PCI Express save buffer\n");
 
 	error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_PCIX, sizeof(u16));
 	if (error)
-		dev_err(&dev->dev,
-			"unable to preallocate PCI-X save buffer\n");
+		pci_err(dev, "unable to preallocate PCI-X save buffer\n");
 
 	pci_allocate_vc_save_buffers(dev);
 }
@@ -3070,6 +3067,81 @@ int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size)
 }
 
 /**
+ * pci_enable_atomic_ops_to_root - enable AtomicOp requests to root port
+ * @dev: the PCI device
+ * @cap_mask: mask of desired AtomicOp sizes, including one or more of:
+ *	PCI_EXP_DEVCAP2_ATOMIC_COMP32
+ *	PCI_EXP_DEVCAP2_ATOMIC_COMP64
+ *	PCI_EXP_DEVCAP2_ATOMIC_COMP128
+ *
+ * Return 0 if all upstream bridges support AtomicOp routing, egress
+ * blocking is disabled on all upstream ports, and the root port supports
+ * the requested completion capabilities (32-bit, 64-bit and/or 128-bit
+ * AtomicOp completion), or negative otherwise.
+ */
+int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask)
+{
+	struct pci_bus *bus = dev->bus;
+	struct pci_dev *bridge;
+	u32 cap, ctl2;
+
+	if (!pci_is_pcie(dev))
+		return -EINVAL;
+
+	/*
+	 * Per PCIe r4.0, sec 6.15, endpoints and root ports may be
+	 * AtomicOp requesters.  For now, we only support endpoints as
+	 * requesters and root ports as completers.  No endpoints as
+	 * completers, and no peer-to-peer.
+	 */
+
+	switch (pci_pcie_type(dev)) {
+	case PCI_EXP_TYPE_ENDPOINT:
+	case PCI_EXP_TYPE_LEG_END:
+	case PCI_EXP_TYPE_RC_END:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	while (bus->parent) {
+		bridge = bus->self;
+
+		pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap);
+
+		switch (pci_pcie_type(bridge)) {
+		/* Ensure switch ports support AtomicOp routing */
+		case PCI_EXP_TYPE_UPSTREAM:
+		case PCI_EXP_TYPE_DOWNSTREAM:
+			if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE))
+				return -EINVAL;
+			break;
+
+		/* Ensure root port supports all the sizes we care about */
+		case PCI_EXP_TYPE_ROOT_PORT:
+			if ((cap & cap_mask) != cap_mask)
+				return -EINVAL;
+			break;
+		}
+
+		/* Ensure upstream ports don't block AtomicOps on egress */
+		if (!bridge->has_secondary_link) {
+			pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2,
+						   &ctl2);
+			if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK)
+				return -EINVAL;
+		}
+
+		bus = bus->parent;
+	}
+
+	pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
+				 PCI_EXP_DEVCTL2_ATOMIC_REQ);
+	return 0;
+}
+EXPORT_SYMBOL(pci_enable_atomic_ops_to_root);
+
+/**
  * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
  * @dev: the PCI device
  * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTC, 4=INTD)
@@ -3202,7 +3274,7 @@ static int __pci_request_region(struct pci_dev *pdev, int bar,
 	return 0;
 
 err_out:
-	dev_warn(&pdev->dev, "BAR %d: can't reserve %pR\n", bar,
+	pci_warn(pdev, "BAR %d: can't reserve %pR\n", bar,
 		 &pdev->resource[bar]);
 	return -EBUSY;
 }
@@ -3625,7 +3697,7 @@ static void __pci_set_master(struct pci_dev *dev, bool enable)
 	else
 		cmd = old_cmd & ~PCI_COMMAND_MASTER;
 	if (cmd != old_cmd) {
-		dev_dbg(&dev->dev, "%s bus mastering\n",
+		pci_dbg(dev, "%s bus mastering\n",
 			enable ? "enabling" : "disabling");
 		pci_write_config_word(dev, PCI_COMMAND, cmd);
 	}
@@ -3726,7 +3798,7 @@ int pci_set_cacheline_size(struct pci_dev *dev)
 	if (cacheline_size == pci_cache_line_size)
 		return 0;
 
-	dev_printk(KERN_DEBUG, &dev->dev, "cache line size of %d is not supported\n",
+	pci_printk(KERN_DEBUG, dev, "cache line size of %d is not supported\n",
 		   pci_cache_line_size << 2);
 
 	return -EINVAL;
@@ -3755,7 +3827,7 @@ int pci_set_mwi(struct pci_dev *dev)
 
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	if (!(cmd & PCI_COMMAND_INVALIDATE)) {
-		dev_dbg(&dev->dev, "enabling Mem-Wr-Inval\n");
+		pci_dbg(dev, "enabling Mem-Wr-Inval\n");
 		cmd |= PCI_COMMAND_INVALIDATE;
 		pci_write_config_word(dev, PCI_COMMAND, cmd);
 	}
@@ -3972,13 +4044,13 @@ static void pci_flr_wait(struct pci_dev *dev)
 	pci_read_config_dword(dev, PCI_COMMAND, &id);
 	while (id == ~0) {
 		if (delay > timeout) {
-			dev_warn(&dev->dev, "not ready %dms after FLR; giving up\n",
+			pci_warn(dev, "not ready %dms after FLR; giving up\n",
 				 100 + delay - 1);
 			return;
 		}
 
 		if (delay > 1000)
-			dev_info(&dev->dev, "not ready %dms after FLR; waiting\n",
+			pci_info(dev, "not ready %dms after FLR; waiting\n",
 				 100 + delay - 1);
 
 		msleep(delay);
@@ -3987,7 +4059,7 @@ static void pci_flr_wait(struct pci_dev *dev)
 	}
 
 	if (delay > 1000)
-		dev_info(&dev->dev, "ready %dms after FLR\n", 100 + delay - 1);
+		pci_info(dev, "ready %dms after FLR\n", 100 + delay - 1);
 }
 
 /**
@@ -4019,7 +4091,7 @@ static bool pcie_has_flr(struct pci_dev *dev)
 void pcie_flr(struct pci_dev *dev)
 {
 	if (!pci_wait_for_pending_transaction(dev))
-		dev_err(&dev->dev, "timed out waiting for pending transaction; performing function level reset anyway\n");
+		pci_err(dev, "timed out waiting for pending transaction; performing function level reset anyway\n");
 
 	pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
 	pci_flr_wait(dev);
@@ -4052,7 +4124,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe)
 	 */
 	if (!pci_wait_for_pending(dev, pos + PCI_AF_CTRL,
 				 PCI_AF_STATUS_TP << 8))
-		dev_err(&dev->dev, "timed out waiting for pending transaction; performing AF function level reset anyway\n");
+		pci_err(dev, "timed out waiting for pending transaction; performing AF function level reset anyway\n");
 
 	pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
 	pci_flr_wait(dev);
@@ -5175,12 +5247,12 @@ void pci_add_dma_alias(struct pci_dev *dev, u8 devfn)
 		dev->dma_alias_mask = kcalloc(BITS_TO_LONGS(U8_MAX),
 					      sizeof(long), GFP_KERNEL);
 	if (!dev->dma_alias_mask) {
-		dev_warn(&dev->dev, "Unable to allocate DMA alias mask\n");
+		pci_warn(dev, "Unable to allocate DMA alias mask\n");
 		return;
 	}
 
 	set_bit(devfn, dev->dma_alias_mask);
-	dev_info(&dev->dev, "Enabling fixed DMA alias to %02x.%d\n",
+	pci_info(dev, "Enabling fixed DMA alias to %02x.%d\n",
 		 PCI_SLOT(devfn), PCI_FUNC(devfn));
 }
 
@@ -5329,7 +5401,7 @@ static void pci_request_resource_alignment(struct pci_dev *dev, int bar,
 		return;
 
 	if (r->flags & IORESOURCE_PCI_FIXED) {
-		dev_info(&dev->dev, "BAR%d %pR: ignoring requested alignment %#llx\n",
+		pci_info(dev, "BAR%d %pR: ignoring requested alignment %#llx\n",
 			 bar, r, (unsigned long long)align);
 		return;
 	}
@@ -5366,7 +5438,7 @@ static void pci_request_resource_alignment(struct pci_dev *dev, int bar,
 	 * devices and we use the second.
 	 */
 
-	dev_info(&dev->dev, "BAR%d %pR: requesting alignment to %#llx\n",
+	pci_info(dev, "BAR%d %pR: requesting alignment to %#llx\n",
 		 bar, r, (unsigned long long)align);
 
 	if (resize) {
@@ -5412,13 +5484,11 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
 
 	if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
 	    (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
-		dev_warn(&dev->dev,
-			"Can't reassign resources to host bridge.\n");
+		pci_warn(dev, "Can't reassign resources to host bridge\n");
 		return;
 	}
 
-	dev_info(&dev->dev,
-		"Disabling memory decoding and releasing memory resources.\n");
+	pci_info(dev, "Disabling memory decoding and releasing memory resources\n");
 	pci_read_config_word(dev, PCI_COMMAND, &command);
 	command &= ~PCI_COMMAND_MEMORY;
 	pci_write_config_word(dev, PCI_COMMAND, command);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index f6b58b3..fcd8191 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -38,21 +38,21 @@ int pci_probe_reset_function(struct pci_dev *dev);
  * struct pci_platform_pm_ops - Firmware PM callbacks
  *
  * @is_manageable: returns 'true' if given device is power manageable by the
- *                 platform firmware
+ *		   platform firmware
  *
  * @set_state: invokes the platform firmware to set the device's power state
  *
  * @get_state: queries the platform firmware for a device's current power state
  *
  * @choose_state: returns PCI power state of given device preferred by the
- *                platform; to be used during system-wide transitions from a
- *                sleeping state to the working state and vice versa
+ *		  platform; to be used during system-wide transitions from a
+ *		  sleeping state to the working state and vice versa
  *
  * @set_wakeup: enables/disables wakeup capability for the device
  *
  * @need_resume: returns 'true' if the given device (which is currently
- *		suspended) needs to be resumed to be configured for system
- *		wakeup.
+ *		 suspended) needs to be resumed to be configured for system
+ *		 wakeup.
  *
  * If given platform is generally capable of power managing PCI devices, all of
  * these callbacks are mandatory.
@@ -112,7 +112,7 @@ struct pci_vpd_ops {
 
 struct pci_vpd {
 	const struct pci_vpd_ops *ops;
-	struct bin_attribute *attr; /* descriptor for sysfs VPD entry */
+	struct bin_attribute *attr;	/* Descriptor for sysfs VPD entry */
 	struct mutex	lock;
 	unsigned int	len;
 	u16		flag;
@@ -199,7 +199,7 @@ extern const struct attribute_group *pci_bus_groups[];
 
 /**
  * pci_match_one_device - Tell if a PCI device structure has a matching
- *                        PCI device id structure
+ *			  PCI device id structure
  * @id: single PCI device id structure to match
  * @dev: the PCI device structure to match against
  *
@@ -231,7 +231,7 @@ struct pci_slot_attribute {
 
 enum pci_bar_type {
 	pci_bar_unknown,	/* Standard PCI BAR probe */
-	pci_bar_io,		/* An io port BAR */
+	pci_bar_io,		/* An I/O port BAR */
 	pci_bar_mem32,		/* A 32-bit memory BAR */
 	pci_bar_mem64,		/* A 64-bit memory BAR */
 };
@@ -255,24 +255,24 @@ void pci_disable_bridge_window(struct pci_dev *dev);
 
 /* Single Root I/O Virtualization */
 struct pci_sriov {
-	int pos;		/* capability position */
-	int nres;		/* number of resources */
-	u32 cap;		/* SR-IOV Capabilities */
-	u16 ctrl;		/* SR-IOV Control */
-	u16 total_VFs;		/* total VFs associated with the PF */
-	u16 initial_VFs;	/* initial VFs associated with the PF */
-	u16 num_VFs;		/* number of VFs available */
-	u16 offset;		/* first VF Routing ID offset */
-	u16 stride;		/* following VF stride */
-	u16 vf_device;		/* VF device ID */
-	u32 pgsz;		/* page size for BAR alignment */
-	u8 link;		/* Function Dependency Link */
-	u8 max_VF_buses;	/* max buses consumed by VFs */
-	u16 driver_max_VFs;	/* max num VFs driver supports */
-	struct pci_dev *dev;	/* lowest numbered PF */
-	struct pci_dev *self;	/* this PF */
-	resource_size_t barsz[PCI_SRIOV_NUM_BARS];	/* VF BAR size */
-	bool drivers_autoprobe;	/* auto probing of VFs by driver */
+	int		pos;		/* Capability position */
+	int		nres;		/* Number of resources */
+	u32		cap;		/* SR-IOV Capabilities */
+	u16		ctrl;		/* SR-IOV Control */
+	u16		total_VFs;	/* Total VFs associated with the PF */
+	u16		initial_VFs;	/* Initial VFs associated with the PF */
+	u16		num_VFs;	/* Number of VFs available */
+	u16		offset;		/* First VF Routing ID offset */
+	u16		stride;		/* Following VF stride */
+	u16		vf_device;	/* VF device ID */
+	u32		pgsz;		/* Page size for BAR alignment */
+	u8		link;		/* Function Dependency Link */
+	u8		max_VF_buses;	/* Max buses consumed by VFs */
+	u16		driver_max_VFs;	/* Max num VFs driver supports */
+	struct pci_dev	*dev;		/* Lowest numbered PF */
+	struct pci_dev	*self;		/* This PF */
+	resource_size_t	barsz[PCI_SRIOV_NUM_BARS];	/* VF BAR size */
+	bool		drivers_autoprobe; /* Auto probing of VFs by driver */
 };
 
 /* pci_dev priv_flags */
@@ -335,13 +335,33 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
 	if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
 		return pci_sriov_resource_alignment(dev, resno);
 #endif
-	if (dev->class >> 8  == PCI_CLASS_BRIDGE_CARDBUS)
+	if (dev->class >> 8 == PCI_CLASS_BRIDGE_CARDBUS)
 		return pci_cardbus_resource_alignment(res);
 	return resource_alignment(res);
 }
 
 void pci_enable_acs(struct pci_dev *dev);
 
+#ifdef CONFIG_PCIEASPM
+void pcie_aspm_init_link_state(struct pci_dev *pdev);
+void pcie_aspm_exit_link_state(struct pci_dev *pdev);
+void pcie_aspm_pm_state_change(struct pci_dev *pdev);
+void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
+#else
+static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { }
+static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { }
+static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { }
+static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { }
+#endif
+
+#ifdef CONFIG_PCIEASPM_DEBUG
+void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev);
+void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev);
+#else
+static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) { }
+static inline void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) { }
+#endif
+
 #ifdef CONFIG_PCIE_PTM
 void pci_ptm_init(struct pci_dev *dev);
 #else
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index ac53edb..b12e28b 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # PCI Express Port Bus Configuration
 #
@@ -92,7 +93,7 @@
 
 config PCIE_DPC
 	bool "PCIe Downstream Port Containment support"
-	depends on PCIEPORTBUS
+	depends on PCIEPORTBUS && PCIEAER
 	default n
 	help
 	  This enables PCI Express Downstream Port Containment (DPC)
diff --git a/drivers/pci/pcie/aer/Kconfig b/drivers/pci/pcie/aer/Kconfig
index 7d1437b..5a64eb3 100644
--- a/drivers/pci/pcie/aer/Kconfig
+++ b/drivers/pci/pcie/aer/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # PCI Express Root Port Device AER Configuration
 #
diff --git a/drivers/pci/pcie/aer/Kconfig.debug b/drivers/pci/pcie/aer/Kconfig.debug
index 9142949..67e0217 100644
--- a/drivers/pci/pcie/aer/Kconfig.debug
+++ b/drivers/pci/pcie/aer/Kconfig.debug
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
 #
 # PCI Express Root Port Device AER Debug Configuration
 #
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 2b6a592..25e1feb 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe AER software error injection support.
  *
@@ -9,12 +10,6 @@
  *
  * Copyright 2009 Intel Corporation.
  *     Huang Ying <ying.huang@intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2
- * of the License.
- *
  */
 
 #include <linux/module.h>
@@ -344,14 +339,14 @@ static int aer_inject(struct aer_error_inj *einj)
 		return -ENODEV;
 	rpdev = pcie_find_root_port(dev);
 	if (!rpdev) {
-		dev_err(&dev->dev, "aer_inject: Root port not found\n");
+		pci_err(dev, "aer_inject: Root port not found\n");
 		ret = -ENODEV;
 		goto out_put;
 	}
 
 	pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 	if (!pos_cap_err) {
-		dev_err(&dev->dev, "aer_inject: Device doesn't support AER\n");
+		pci_err(dev, "aer_inject: Device doesn't support AER\n");
 		ret = -EPROTONOSUPPORT;
 		goto out_put;
 	}
@@ -362,8 +357,7 @@ static int aer_inject(struct aer_error_inj *einj)
 
 	rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR);
 	if (!rp_pos_cap_err) {
-		dev_err(&rpdev->dev,
-			"aer_inject: Root port doesn't support AER\n");
+		pci_err(rpdev, "aer_inject: Root port doesn't support AER\n");
 		ret = -EPROTONOSUPPORT;
 		goto out_put;
 	}
@@ -411,16 +405,14 @@ static int aer_inject(struct aer_error_inj *einj)
 	if (!aer_mask_override && einj->cor_status &&
 	    !(einj->cor_status & ~cor_mask)) {
 		ret = -EINVAL;
-		dev_warn(&dev->dev,
-			 "aer_inject: The correctable error(s) is masked by device\n");
+		pci_warn(dev, "aer_inject: The correctable error(s) is masked by device\n");
 		spin_unlock_irqrestore(&inject_lock, flags);
 		goto out_put;
 	}
 	if (!aer_mask_override && einj->uncor_status &&
 	    !(einj->uncor_status & ~uncor_mask)) {
 		ret = -EINVAL;
-		dev_warn(&dev->dev,
-			 "aer_inject: The uncorrectable error(s) is masked by device\n");
+		pci_warn(dev, "aer_inject: The uncorrectable error(s) is masked by device\n");
 		spin_unlock_irqrestore(&inject_lock, flags);
 		goto out_put;
 	}
@@ -483,7 +475,7 @@ static int aer_inject(struct aer_error_inj *einj)
 			 einj->cor_status, einj->uncor_status, pci_name(dev));
 		aer_irq(-1, edev);
 	} else {
-		dev_err(&rpdev->dev, "aer_inject: AER device not found\n");
+		pci_err(rpdev, "aer_inject: AER device not found\n");
 		ret = -ENODEV;
 	}
 out_put:
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 6ff5f5b..da8331f 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * drivers/pci/pcie/aer/aerdrv.c
  *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
  * This file implements the AER root port service driver. The driver will
  * register an irq handler. When root port triggers an AER interrupt, the irq
  * handler will collect root port status and schedule a work.
@@ -326,7 +323,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
 	pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32);
 
 	pci_reset_bridge_secondary_bus(dev);
-	dev_printk(KERN_DEBUG, &dev->dev, "Root Port link has been reset\n");
+	pci_printk(KERN_DEBUG, dev, "Root Port link has been reset\n");
 
 	/* Clear Root Error Status */
 	pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 8d74480..a4bfea5 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * drivers/pci/pcie/aer/aerdrv_core.c
  *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
  * This file implements the core part of PCIe AER. When a PCIe
  * error is delivered, an error message will be collected and printed to
  * console, then, an error recovery procedure will be executed by following
@@ -226,9 +223,8 @@ static bool find_source_device(struct pci_dev *parent,
 	pci_walk_bus(parent->subordinate, find_device_iter, e_info);
 
 	if (!e_info->error_dev_num) {
-		dev_printk(KERN_DEBUG, &parent->dev,
-				"can't find device of ID%04x\n",
-				e_info->id);
+		pci_printk(KERN_DEBUG, parent, "can't find device of ID%04x\n",
+			   e_info->id);
 		return false;
 	}
 	return true;
@@ -256,7 +252,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
 			 * of a driver for this device is unaware of
 			 * its hw state.
 			 */
-			dev_printk(KERN_DEBUG, &dev->dev, "device has %s\n",
+			pci_printk(KERN_DEBUG, dev, "device has %s\n",
 				   dev->driver ?
 				   "no AER-aware driver" : "no driver");
 		}
@@ -366,7 +362,7 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
 {
 	struct aer_broadcast_data result_data;
 
-	dev_printk(KERN_DEBUG, &dev->dev, "broadcast %s message\n", error_mesg);
+	pci_printk(KERN_DEBUG, dev, "broadcast %s message\n", error_mesg);
 	result_data.state = state;
 	if (cb == report_error_detected)
 		result_data.result = PCI_ERS_RESULT_CAN_RECOVER;
@@ -415,7 +411,7 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
 static pci_ers_result_t default_reset_link(struct pci_dev *dev)
 {
 	pci_reset_bridge_secondary_bus(dev);
-	dev_printk(KERN_DEBUG, &dev->dev, "downstream link has been reset\n");
+	pci_printk(KERN_DEBUG, dev, "downstream link has been reset\n");
 	return PCI_ERS_RESULT_RECOVERED;
 }
 
@@ -467,15 +463,13 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
 	} else if (udev->has_secondary_link) {
 		status = default_reset_link(udev);
 	} else {
-		dev_printk(KERN_DEBUG, &dev->dev,
-			"no link-reset support at upstream device %s\n",
+		pci_printk(KERN_DEBUG, dev, "no link-reset support at upstream device %s\n",
 			pci_name(udev));
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 
 	if (status != PCI_ERS_RESULT_RECOVERED) {
-		dev_printk(KERN_DEBUG, &dev->dev,
-			"link reset at upstream device %s failed\n",
+		pci_printk(KERN_DEBUG, dev, "link reset at upstream device %s failed\n",
 			pci_name(udev));
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
@@ -539,13 +533,13 @@ static void do_recovery(struct pci_dev *dev, int severity)
 				"resume",
 				report_resume);
 
-	dev_info(&dev->dev, "AER: Device recovery successful\n");
+	pci_info(dev, "AER: Device recovery successful\n");
 	return;
 
 failed:
 	pci_uevent_ers(dev, PCI_ERS_RESULT_DISCONNECT);
 	/* TODO: Should kernel panic here? */
-	dev_info(&dev->dev, "AER: Device recovery failed\n");
+	pci_info(dev, "AER: Device recovery failed\n");
 }
 
 /**
@@ -636,7 +630,8 @@ static void aer_recover_work_func(struct work_struct *work)
 			continue;
 		}
 		cper_print_aer(pdev, entry.severity, entry.regs);
-		do_recovery(pdev, entry.severity);
+		if (entry.severity != AER_CORRECTABLE)
+			do_recovery(pdev, entry.severity);
 		pci_dev_put(pdev);
 	}
 }
@@ -663,7 +658,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
 
 	/* The device might not support AER */
 	if (!pos)
-		return 1;
+		return 0;
 
 	if (info->severity == AER_CORRECTABLE) {
 		pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS,
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 54c4b69..6a352e6 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * drivers/pci/pcie/aer/aerdrv_errprint.c
  *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
  * Format error messages and print them to console.
  *
  * Copyright (C) 2006 Intel Corp.
@@ -132,7 +129,7 @@ static const char *aer_agent_string[] = {
 static void __print_tlp_header(struct pci_dev *dev,
 			       struct aer_header_log_regs *t)
 {
-	dev_err(&dev->dev, "  TLP Header: %08x %08x %08x %08x\n",
+	pci_err(dev, "  TLP Header: %08x %08x %08x %08x\n",
 		t->dw0, t->dw1, t->dw2, t->dw3);
 }
 
@@ -155,10 +152,10 @@ static void __aer_print_error(struct pci_dev *dev,
 				aer_uncorrectable_error_string[i] : NULL;
 
 		if (errmsg)
-			dev_err(&dev->dev, "   [%2d] %-22s%s\n", i, errmsg,
+			pci_err(dev, "   [%2d] %-22s%s\n", i, errmsg,
 				info->first_error == i ? " (First)" : "");
 		else
-			dev_err(&dev->dev, "   [%2d] Unknown Error Bit%s\n",
+			pci_err(dev, "   [%2d] Unknown Error Bit%s\n",
 				i, info->first_error == i ? " (First)" : "");
 	}
 }
@@ -169,7 +166,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
 	int id = ((dev->bus->number << 8) | dev->devfn);
 
 	if (!info->status) {
-		dev_err(&dev->dev, "PCIe Bus Error: severity=%s, type=Unaccessible, id=%04x(Unregistered Agent ID)\n",
+		pci_err(dev, "PCIe Bus Error: severity=%s, type=Unaccessible, id=%04x(Unregistered Agent ID)\n",
 			aer_error_severity_string[info->severity], id);
 		goto out;
 	}
@@ -177,11 +174,11 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
 	layer = AER_GET_LAYER_ERROR(info->severity, info->status);
 	agent = AER_GET_AGENT(info->severity, info->status);
 
-	dev_err(&dev->dev, "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n",
+	pci_err(dev, "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n",
 		aer_error_severity_string[info->severity],
 		aer_error_layer[layer], id, aer_agent_string[agent]);
 
-	dev_err(&dev->dev, "  device [%04x:%04x] error status/mask=%08x/%08x\n",
+	pci_err(dev, "  device [%04x:%04x] error status/mask=%08x/%08x\n",
 		dev->vendor, dev->device,
 		info->status, info->mask);
 
@@ -192,7 +189,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
 
 out:
 	if (info->id && info->error_dev_num > 1 && info->id == id)
-		dev_err(&dev->dev, "  Error of this Agent(%04x) is reported first\n", id);
+		pci_err(dev, "  Error of this Agent(%04x) is reported first\n", id);
 
 	trace_aer_event(dev_name(&dev->dev), (info->status & ~info->mask),
 			info->severity);
@@ -200,7 +197,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
 
 void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
 {
-	dev_info(&dev->dev, "AER: %s%s error received: id=%04x\n",
+	pci_info(dev, "AER: %s%s error received: id=%04x\n",
 		info->multi_error_valid ? "Multiple " : "",
 		aer_error_severity_string[info->severity], info->id);
 }
@@ -242,13 +239,13 @@ void cper_print_aer(struct pci_dev *dev, int aer_severity,
 	layer = AER_GET_LAYER_ERROR(aer_severity, status);
 	agent = AER_GET_AGENT(aer_severity, status);
 
-	dev_err(&dev->dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", status, mask);
+	pci_err(dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", status, mask);
 	cper_print_bits("", status, status_strs, status_strs_size);
-	dev_err(&dev->dev, "aer_layer=%s, aer_agent=%s\n",
+	pci_err(dev, "aer_layer=%s, aer_agent=%s\n",
 		aer_error_layer[layer], aer_agent_string[agent]);
 
 	if (aer_severity != AER_CORRECTABLE)
-		dev_err(&dev->dev, "aer_uncor_severity: 0x%08x\n",
+		pci_err(dev, "aer_uncor_severity: 0x%08x\n",
 			aer->uncor_severity);
 
 	if (tlp_header_valid)
diff --git a/drivers/pci/pcie/aer/ecrc.c b/drivers/pci/pcie/aer/ecrc.c
index a2747a6..26d3cac 100644
--- a/drivers/pci/pcie/aer/ecrc.c
+++ b/drivers/pci/pcie/aer/ecrc.c
@@ -1,23 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *    Enables/disables PCIe ECRC checking.
  *
  *    (C) Copyright 2009 Hewlett-Packard Development Company, L.P.
  *    Andrew Patterson <andrew.patterson@hp.com>
- *
- *    This program is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; version 2 of the License.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- *    General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- *    02111-1307, USA.
- *
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 9783e10..57feef2 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -43,18 +43,6 @@
 #define ASPM_STATE_ALL		(ASPM_STATE_L0S | ASPM_STATE_L1 |	\
 				 ASPM_STATE_L1SS)
 
-/*
- * When L1 substates are enabled, the LTR L1.2 threshold is a timing parameter
- * that decides whether L1.1 or L1.2 is entered (Refer PCIe spec for details).
- * Not sure is there is a way to "calculate" this on the fly, but maybe we
- * could turn it into a parameter in future.  This value has been taken from
- * the following files from Intel's coreboot (which is the only code I found
- * to have used this):
- * https://www.coreboot.org/pipermail/coreboot-gerrit/2015-March/021134.html
- * https://review.coreboot.org/#/c/8832/
- */
-#define LTR_L1_2_THRESHOLD_BITS	((1 << 21) | (1 << 23) | (1 << 30))
-
 struct aspm_latency {
 	u32 l0s;			/* L0s latency (nsec) */
 	u32 l1;				/* L1 latency (nsec) */
@@ -278,7 +266,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
 		return;
 
 	/* Training failed. Restore common clock configurations */
-	dev_err(&parent->dev, "ASPM: Could not configure common clock\n");
+	pci_err(parent, "ASPM: Could not configure common clock\n");
 	list_for_each_entry(child, &linkbus->devices, bus_list)
 		pcie_capability_write_word(child, PCI_EXP_LNKCTL,
 					   child_reg[PCI_FUNC(child->devfn)]);
@@ -328,11 +316,36 @@ static u32 calc_l1ss_pwron(struct pci_dev *pdev, u32 scale, u32 val)
 	case 2:
 		return val * 100;
 	}
-	dev_err(&pdev->dev, "%s: Invalid T_PwrOn scale: %u\n",
-		__func__, scale);
+	pci_err(pdev, "%s: Invalid T_PwrOn scale: %u\n", __func__, scale);
 	return 0;
 }
 
+static void encode_l12_threshold(u32 threshold_us, u32 *scale, u32 *value)
+{
+	u64 threshold_ns = threshold_us * 1000;
+
+	/* See PCIe r3.1, sec 7.33.3 and sec 6.18 */
+	if (threshold_ns < 32) {
+		*scale = 0;
+		*value = threshold_ns;
+	} else if (threshold_ns < 1024) {
+		*scale = 1;
+		*value = threshold_ns >> 5;
+	} else if (threshold_ns < 32768) {
+		*scale = 2;
+		*value = threshold_ns >> 10;
+	} else if (threshold_ns < 1048576) {
+		*scale = 3;
+		*value = threshold_ns >> 15;
+	} else if (threshold_ns < 33554432) {
+		*scale = 4;
+		*value = threshold_ns >> 20;
+	} else {
+		*scale = 5;
+		*value = threshold_ns >> 25;
+	}
+}
+
 struct aspm_register_info {
 	u32 support:2;
 	u32 enabled:2;
@@ -443,6 +456,7 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
 				struct aspm_register_info *dwreg)
 {
 	u32 val1, val2, scale1, scale2;
+	u32 t_common_mode, t_power_on, l1_2_threshold, scale, value;
 
 	link->l1ss.up_cap_ptr = upreg->l1ss_cap_ptr;
 	link->l1ss.dw_cap_ptr = dwreg->l1ss_cap_ptr;
@@ -454,16 +468,7 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
 	/* Choose the greater of the two Port Common_Mode_Restore_Times */
 	val1 = (upreg->l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
 	val2 = (dwreg->l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
-	if (val1 > val2)
-		link->l1ss.ctl1 |= val1 << 8;
-	else
-		link->l1ss.ctl1 |= val2 << 8;
-
-	/*
-	 * We currently use LTR L1.2 threshold to be fixed constant picked from
-	 * Intel's coreboot.
-	 */
-	link->l1ss.ctl1 |= LTR_L1_2_THRESHOLD_BITS;
+	t_common_mode = max(val1, val2);
 
 	/* Choose the greater of the two Port T_POWER_ON times */
 	val1   = (upreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
@@ -472,10 +477,27 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
 	scale2 = (dwreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
 
 	if (calc_l1ss_pwron(link->pdev, scale1, val1) >
-	    calc_l1ss_pwron(link->downstream, scale2, val2))
+	    calc_l1ss_pwron(link->downstream, scale2, val2)) {
 		link->l1ss.ctl2 |= scale1 | (val1 << 3);
-	else
+		t_power_on = calc_l1ss_pwron(link->pdev, scale1, val1);
+	} else {
 		link->l1ss.ctl2 |= scale2 | (val2 << 3);
+		t_power_on = calc_l1ss_pwron(link->downstream, scale2, val2);
+	}
+
+	/*
+	 * Set LTR_L1.2_THRESHOLD to the time required to transition the
+	 * Link from L0 to L1.2 and back to L0 so we enter L1.2 only if
+	 * downstream devices report (via LTR) that they can tolerate at
+	 * least that much latency.
+	 *
+	 * Based on PCIe r3.1, sec 5.5.3.3.1, Figures 5-16 and 5-17, and
+	 * Table 5-11.  T(POWER_OFF) is at most 2us and T(L1.2) is at
+	 * least 4us.
+	 */
+	l1_2_threshold = 2 + 4 + t_common_mode + t_power_on;
+	encode_l12_threshold(l1_2_threshold, &scale, &value);
+	link->l1ss.ctl1 |= t_common_mode << 8 | scale << 29 | value << 16;
 }
 
 static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
@@ -786,7 +808,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
 		 */
 		pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
 		if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
-			dev_info(&child->dev, "disabling ASPM on pre-1.1 PCIe device.  You can enable it with 'pcie_aspm=force'\n");
+			pci_info(child, "disabling ASPM on pre-1.1 PCIe device.  You can enable it with 'pcie_aspm=force'\n");
 			return -EINVAL;
 		}
 	}
@@ -1027,7 +1049,7 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
 	 * ignored in this situation.
 	 */
 	if (aspm_disabled) {
-		dev_warn(&pdev->dev, "can't disable ASPM; OS doesn't have ASPM control\n");
+		pci_warn(pdev, "can't disable ASPM; OS doesn't have ASPM control\n");
 		return;
 	}
 
diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c
index 2d976a6..38e40c6 100644
--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCI Express Downstream Port Containment services driver
  * Author: Keith Busch <keith.busch@intel.com>
  *
  * Copyright (C) 2016 Intel Corp.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
  */
 
 #include <linux/delay.h>
@@ -15,34 +12,15 @@
 #include <linux/pci.h>
 #include <linux/pcieport_if.h>
 #include "../pci.h"
-
-struct rp_pio_header_log_regs {
-	u32 dw0;
-	u32 dw1;
-	u32 dw2;
-	u32 dw3;
-};
-
-struct dpc_rp_pio_regs {
-	u32 status;
-	u32 mask;
-	u32 severity;
-	u32 syserror;
-	u32 exception;
-
-	struct rp_pio_header_log_regs header_log;
-	u32 impspec_log;
-	u32 tlp_prefix_log[4];
-	u32 log_size;
-	u16 first_error;
-};
+#include "aer/aerdrv.h"
 
 struct dpc_dev {
 	struct pcie_device	*dev;
 	struct work_struct	work;
-	int			cap_pos;
-	bool			rp;
+	u16			cap_pos;
+	bool			rp_extensions;
 	u32			rp_pio_status;
+	u8			rp_log_size;
 };
 
 static const char * const rp_pio_error_string[] = {
@@ -72,13 +50,13 @@ static int dpc_wait_rp_inactive(struct dpc_dev *dpc)
 	unsigned long timeout = jiffies + HZ;
 	struct pci_dev *pdev = dpc->dev->port;
 	struct device *dev = &dpc->dev->device;
-	u16 status;
+	u16 cap = dpc->cap_pos, status;
 
-	pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status);
+	pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
 	while (status & PCI_EXP_DPC_RP_BUSY &&
 					!time_after(jiffies, timeout)) {
 		msleep(10);
-		pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status);
+		pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
 	}
 	if (status & PCI_EXP_DPC_RP_BUSY) {
 		dev_warn(dev, "DPC root port still busy\n");
@@ -104,11 +82,12 @@ static void dpc_wait_link_inactive(struct dpc_dev *dpc)
 		dev_warn(dev, "Link state not disabled for DPC event\n");
 }
 
-static void interrupt_event_handler(struct work_struct *work)
+static void dpc_work(struct work_struct *work)
 {
 	struct dpc_dev *dpc = container_of(work, struct dpc_dev, work);
 	struct pci_dev *dev, *temp, *pdev = dpc->dev->port;
 	struct pci_bus *parent = pdev->subordinate;
+	u16 cap = dpc->cap_pos, ctl;
 
 	pci_lock_rescan_remove();
 	list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
@@ -124,124 +103,77 @@ static void interrupt_event_handler(struct work_struct *work)
 	pci_unlock_rescan_remove();
 
 	dpc_wait_link_inactive(dpc);
-	if (dpc->rp && dpc_wait_rp_inactive(dpc))
+	if (dpc->rp_extensions && dpc_wait_rp_inactive(dpc))
 		return;
-	if (dpc->rp && dpc->rp_pio_status) {
-		pci_write_config_dword(pdev,
-				      dpc->cap_pos + PCI_EXP_DPC_RP_PIO_STATUS,
-				      dpc->rp_pio_status);
+	if (dpc->rp_extensions && dpc->rp_pio_status) {
+		pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS,
+				       dpc->rp_pio_status);
 		dpc->rp_pio_status = 0;
 	}
 
-	pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS,
+	pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
 		PCI_EXP_DPC_STATUS_TRIGGER | PCI_EXP_DPC_STATUS_INTERRUPT);
-}
 
-static void dpc_rp_pio_print_tlp_header(struct device *dev,
-					struct rp_pio_header_log_regs *t)
-{
-	dev_err(dev, "TLP Header: %#010x %#010x %#010x %#010x\n",
-		t->dw0, t->dw1, t->dw2, t->dw3);
-}
-
-static void dpc_rp_pio_print_error(struct dpc_dev *dpc,
-				   struct dpc_rp_pio_regs *rp_pio)
-{
-	struct device *dev = &dpc->dev->device;
-	int i;
-	u32 status;
-
-	dev_err(dev, "rp_pio_status: %#010x, rp_pio_mask: %#010x\n",
-		rp_pio->status, rp_pio->mask);
-
-	dev_err(dev, "RP PIO severity=%#010x, syserror=%#010x, exception=%#010x\n",
-		rp_pio->severity, rp_pio->syserror, rp_pio->exception);
-
-	status = (rp_pio->status & ~rp_pio->mask);
-
-	for (i = 0; i < ARRAY_SIZE(rp_pio_error_string); i++) {
-		if (!(status & (1 << i)))
-			continue;
-
-		dev_err(dev, "[%2d] %s%s\n", i, rp_pio_error_string[i],
-			rp_pio->first_error == i ? " (First)" : "");
-	}
-
-	dpc_rp_pio_print_tlp_header(dev, &rp_pio->header_log);
-	if (rp_pio->log_size == 4)
-		return;
-	dev_err(dev, "RP PIO ImpSpec Log %#010x\n", rp_pio->impspec_log);
-
-	for (i = 0; i < rp_pio->log_size - 5; i++)
-		dev_err(dev, "TLP Prefix Header: dw%d, %#010x\n", i,
-			rp_pio->tlp_prefix_log[i]);
-}
-
-static void dpc_rp_pio_get_info(struct dpc_dev *dpc,
-				struct dpc_rp_pio_regs *rp_pio)
-{
-	struct pci_dev *pdev = dpc->dev->port;
-	struct device *dev = &dpc->dev->device;
-	int i;
-	u16 cap;
-	u16 status;
-
-	pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_STATUS,
-			      &rp_pio->status);
-	pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_MASK,
-			      &rp_pio->mask);
-
-	pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_SEVERITY,
-			      &rp_pio->severity);
-	pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_SYSERROR,
-			      &rp_pio->syserror);
-	pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_EXCEPTION,
-			      &rp_pio->exception);
-
-	/* Get First Error Pointer */
-	pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status);
-	rp_pio->first_error = (status & 0x1f00) >> 8;
-
-	pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap);
-	rp_pio->log_size = (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
-	if (rp_pio->log_size < 4 || rp_pio->log_size > 9) {
-		dev_err(dev, "RP PIO log size %u is invalid\n",
-			rp_pio->log_size);
-		return;
-	}
-
-	pci_read_config_dword(pdev,
-			      dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
-			      &rp_pio->header_log.dw0);
-	pci_read_config_dword(pdev,
-			      dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 4,
-			      &rp_pio->header_log.dw1);
-	pci_read_config_dword(pdev,
-			      dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 8,
-			      &rp_pio->header_log.dw2);
-	pci_read_config_dword(pdev,
-			      dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 12,
-			      &rp_pio->header_log.dw3);
-	if (rp_pio->log_size == 4)
-		return;
-
-	pci_read_config_dword(pdev,
-			      dpc->cap_pos + PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG,
-			      &rp_pio->impspec_log);
-	for (i = 0; i < rp_pio->log_size - 5; i++)
-		pci_read_config_dword(pdev,
-			dpc->cap_pos + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG,
-			&rp_pio->tlp_prefix_log[i]);
+	pci_read_config_word(pdev, cap + PCI_EXP_DPC_CTL, &ctl);
+	pci_write_config_word(pdev, cap + PCI_EXP_DPC_CTL,
+			      ctl | PCI_EXP_DPC_CTL_INT_EN);
 }
 
 static void dpc_process_rp_pio_error(struct dpc_dev *dpc)
 {
-	struct dpc_rp_pio_regs rp_pio_regs;
+	struct device *dev = &dpc->dev->device;
+	struct pci_dev *pdev = dpc->dev->port;
+	u16 cap = dpc->cap_pos, dpc_status, first_error;
+	u32 status, mask, sev, syserr, exc, dw0, dw1, dw2, dw3, log, prefix;
+	int i;
 
-	dpc_rp_pio_get_info(dpc, &rp_pio_regs);
-	dpc_rp_pio_print_error(dpc, &rp_pio_regs);
+	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, &status);
+	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_MASK, &mask);
+	dev_err(dev, "rp_pio_status: %#010x, rp_pio_mask: %#010x\n",
+		status, mask);
 
-	dpc->rp_pio_status = rp_pio_regs.status;
+	dpc->rp_pio_status = status;
+
+	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_SEVERITY, &sev);
+	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_SYSERROR, &syserr);
+	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_EXCEPTION, &exc);
+	dev_err(dev, "RP PIO severity=%#010x, syserror=%#010x, exception=%#010x\n",
+		sev, syserr, exc);
+
+	/* Get First Error Pointer */
+	pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &dpc_status);
+	first_error = (dpc_status & 0x1f00) >> 8;
+
+	status &= ~mask;
+	for (i = 0; i < ARRAY_SIZE(rp_pio_error_string); i++) {
+		if (status & (1 << i))
+			dev_err(dev, "[%2d] %s%s\n", i, rp_pio_error_string[i],
+				first_error == i ? " (First)" : "");
+	}
+
+	if (dpc->rp_log_size < 4)
+		return;
+	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
+			      &dw0);
+	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 4,
+			      &dw1);
+	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 8,
+			      &dw2);
+	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 12,
+			      &dw3);
+	dev_err(dev, "TLP Header: %#010x %#010x %#010x %#010x\n",
+		dw0, dw1, dw2, dw3);
+
+	if (dpc->rp_log_size < 5)
+		return;
+	pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG, &log);
+	dev_err(dev, "RP PIO ImpSpec Log %#010x\n", log);
+
+	for (i = 0; i < dpc->rp_log_size - 5; i++) {
+		pci_read_config_dword(pdev,
+			cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG, &prefix);
+		dev_err(dev, "TLP Prefix Header: dw%d, %#010x\n", i, prefix);
+	}
 }
 
 static irqreturn_t dpc_irq(int irq, void *context)
@@ -249,34 +181,49 @@ static irqreturn_t dpc_irq(int irq, void *context)
 	struct dpc_dev *dpc = (struct dpc_dev *)context;
 	struct pci_dev *pdev = dpc->dev->port;
 	struct device *dev = &dpc->dev->device;
-	u16 status, source;
+	u16 cap = dpc->cap_pos, ctl, status, source, reason, ext_reason;
 
-	pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status);
-	pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_SOURCE_ID,
-			     &source);
-	if (!status || status == (u16)(~0))
+	pci_read_config_word(pdev, cap + PCI_EXP_DPC_CTL, &ctl);
+
+	if (!(ctl & PCI_EXP_DPC_CTL_INT_EN) || ctl == (u16)(~0))
 		return IRQ_NONE;
 
+	pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
+
+	if (!(status & PCI_EXP_DPC_STATUS_INTERRUPT))
+		return IRQ_NONE;
+
+	if (!(status & PCI_EXP_DPC_STATUS_TRIGGER)) {
+		pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
+				      PCI_EXP_DPC_STATUS_INTERRUPT);
+		return IRQ_HANDLED;
+	}
+
+	pci_write_config_word(pdev, cap + PCI_EXP_DPC_CTL,
+			      ctl & ~PCI_EXP_DPC_CTL_INT_EN);
+
+	pci_read_config_word(pdev, cap + PCI_EXP_DPC_SOURCE_ID,
+			     &source);
+
 	dev_info(dev, "DPC containment event, status:%#06x source:%#06x\n",
 		status, source);
 
-	if (status & PCI_EXP_DPC_STATUS_TRIGGER) {
-		u16 reason = (status >> 1) & 0x3;
-		u16 ext_reason = (status >> 5) & 0x3;
+	reason = (status & PCI_EXP_DPC_STATUS_TRIGGER_RSN) >> 1;
+	ext_reason = (status & PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT) >> 5;
 
-		dev_warn(dev, "DPC %s detected, remove downstream devices\n",
-			 (reason == 0) ? "unmasked uncorrectable error" :
-			 (reason == 1) ? "ERR_NONFATAL" :
-			 (reason == 2) ? "ERR_FATAL" :
-			 (ext_reason == 0) ? "RP PIO error" :
-			 (ext_reason == 1) ? "software trigger" :
-					     "reserved error");
-		/* show RP PIO error detail information */
-		if (reason == 3 && ext_reason == 0)
-			dpc_process_rp_pio_error(dpc);
+	dev_warn(dev, "DPC %s detected, remove downstream devices\n",
+		 (reason == 0) ? "unmasked uncorrectable error" :
+		 (reason == 1) ? "ERR_NONFATAL" :
+		 (reason == 2) ? "ERR_FATAL" :
+		 (ext_reason == 0) ? "RP PIO error" :
+		 (ext_reason == 1) ? "software trigger" :
+				     "reserved error");
+	/* show RP PIO error detail information */
+	if (dpc->rp_extensions && reason == 3 && ext_reason == 0)
+		dpc_process_rp_pio_error(dpc);
 
-		schedule_work(&dpc->work);
-	}
+	schedule_work(&dpc->work);
+
 	return IRQ_HANDLED;
 }
 
@@ -289,13 +236,16 @@ static int dpc_probe(struct pcie_device *dev)
 	int status;
 	u16 ctl, cap;
 
+	if (pcie_aer_get_firmware_first(pdev))
+		return -ENOTSUPP;
+
 	dpc = devm_kzalloc(device, sizeof(*dpc), GFP_KERNEL);
 	if (!dpc)
 		return -ENOMEM;
 
 	dpc->cap_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DPC);
 	dpc->dev = dev;
-	INIT_WORK(&dpc->work, interrupt_event_handler);
+	INIT_WORK(&dpc->work, dpc_work);
 	set_service_data(dev, dpc);
 
 	status = devm_request_irq(device, dev->irq, dpc_irq, IRQF_SHARED,
@@ -309,15 +259,23 @@ static int dpc_probe(struct pcie_device *dev)
 	pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap);
 	pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, &ctl);
 
-	dpc->rp = (cap & PCI_EXP_DPC_CAP_RP_EXT);
+	dpc->rp_extensions = (cap & PCI_EXP_DPC_CAP_RP_EXT);
+	if (dpc->rp_extensions) {
+		dpc->rp_log_size = (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
+		if (dpc->rp_log_size < 4 || dpc->rp_log_size > 9) {
+			dev_err(device, "RP PIO log size %u is invalid\n",
+				dpc->rp_log_size);
+			dpc->rp_log_size = 0;
+		}
+	}
 
 	ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN;
 	pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl);
 
 	dev_info(device, "DPC error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n",
-		cap & 0xf, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT),
+		cap & PCI_EXP_DPC_IRQ, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT),
 		FLAG(cap, PCI_EXP_DPC_CAP_POISONED_TLP),
-		FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), (cap >> 8) & 0xf,
+		FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), dpc->rp_log_size,
 		FLAG(cap, PCI_EXP_DPC_CAP_DL_ACTIVE));
 	return status;
 }
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index df290aa..5480f54 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe Native PME support
  *
  * Copyright (C) 2007 - 2009 Intel Corp
  * Copyright (C) 2007 - 2009 Shaohua Li <shaohua.li@intel.com>
  * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License V2.  See the file "COPYING" in the main directory of this archive
- * for more details.
  */
 
 #include <linux/pci.h>
@@ -198,14 +195,14 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id)
 		 * assuming that the PME was reported by a PCIe-PCI bridge that
 		 * used devfn different from zero.
 		 */
-		dev_dbg(&port->dev, "PME interrupt generated for non-existent device %02x:%02x.%d\n",
+		pci_dbg(port, "PME interrupt generated for non-existent device %02x:%02x.%d\n",
 			busnr, PCI_SLOT(devfn), PCI_FUNC(devfn));
 		found = pcie_pme_from_pci_bridge(bus, 0);
 	}
 
  out:
 	if (!found)
-		dev_dbg(&port->dev, "Spurious native PME interrupt!\n");
+		pci_dbg(port, "Spurious native PME interrupt!\n");
 }
 
 /**
@@ -345,7 +342,7 @@ static int pcie_pme_probe(struct pcie_device *srv)
 		return ret;
 	}
 
-	dev_info(&port->dev, "Signaling PME with IRQ %d\n", srv->irq);
+	pci_info(port, "Signaling PME with IRQ %d\n", srv->irq);
 
 	pcie_pme_mark_devices(port);
 	pcie_pme_interrupt_enable(port, true);
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c
index 6b8c2f1..319c949 100644
--- a/drivers/pci/pcie/portdrv_acpi.c
+++ b/drivers/pci/pcie/portdrv_acpi.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCIe Port Native Services Support, ACPI-Related Part
  *
  * Copyright (C) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License V2.  See the file "COPYING" in the main directory of this archive
- * for more details.
  */
 
 #include <linux/pci.h>
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
index 87e79a6..f0fba55 100644
--- a/drivers/pci/pcie/portdrv_bus.c
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * File:	portdrv_bus.c
  * Purpose:	PCI Express Port Bus Driver's Bus Overloading Functions
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index a592103..ef3bad4 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -216,9 +216,9 @@ static int get_port_device_capability(struct pci_dev *dev)
 		return 0;
 
 	cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
-			| PCIE_PORT_SERVICE_VC | PCIE_PORT_SERVICE_DPC;
+			| PCIE_PORT_SERVICE_VC;
 	if (pci_aer_available())
-		cap_mask |= PCIE_PORT_SERVICE_AER;
+		cap_mask |= PCIE_PORT_SERVICE_AER | PCIE_PORT_SERVICE_DPC;
 
 	if (pcie_ports_auto)
 		pcie_port_platform_notify(dev, &cap_mask);
diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c
index bab8ac6..98cfa30 100644
--- a/drivers/pci/pcie/ptm.c
+++ b/drivers/pci/pcie/ptm.c
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCI Express Precision Time Measurement
  * Copyright (c) 2016, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
  */
 
 #include <linux/module.h>
@@ -33,7 +25,7 @@ static void pci_ptm_info(struct pci_dev *dev)
 			 dev->ptm_granularity);
 		break;
 	}
-	dev_info(&dev->dev, "PTM enabled%s, %s granularity\n",
+	pci_info(dev, "PTM enabled%s, %s granularity\n",
 		 dev->ptm_root ? " (root)" : "", clock_desc);
 }
 
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 14e0ea1..ef53774 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * probe.c - PCI detection and setup code
  */
@@ -69,8 +70,8 @@ static int find_anything(struct device *dev, void *data)
 }
 
 /*
- * Some device drivers need know if pci is initiated.
- * Basically, we think pci is not initiated when there
+ * Some device drivers need know if PCI is initiated.
+ * Basically, we think PCI is not initiated when there
  * is no device to be found on the pci_bus_type.
  */
 int no_pci_devices(void)
@@ -116,12 +117,16 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask)
 	if (!size)
 		return 0;
 
-	/* Get the lowest of them to find the decode size, and
-	   from that the extent.  */
+	/*
+	 * Get the lowest of them to find the decode size, and from that
+	 * the extent.
+	 */
 	size = (size & ~(size-1)) - 1;
 
-	/* base == maxbase can be valid only if the BAR has
-	   already been programmed with all 1s.  */
+	/*
+	 * base == maxbase can be valid only if the BAR has already been
+	 * programmed with all 1s.
+	 */
 	if (base == maxbase && ((base | size) & mask) != mask)
 		return 0;
 
@@ -164,7 +169,7 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)
 #define PCI_COMMAND_DECODE_ENABLE	(PCI_COMMAND_MEMORY | PCI_COMMAND_IO)
 
 /**
- * pci_read_base - read a PCI BAR
+ * pci_read_base - Read a PCI BAR
  * @dev: the PCI device
  * @type: type of the BAR
  * @res: resource buffer to be filled in
@@ -253,7 +258,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 
 	sz64 = pci_size(l64, sz64, mask64);
 	if (!sz64) {
-		dev_info(&dev->dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n",
+		pci_info(dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n",
 			 pos);
 		goto fail;
 	}
@@ -264,7 +269,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 			res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
 			res->start = 0;
 			res->end = 0;
-			dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
+			pci_err(dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
 				pos, (unsigned long long)sz64);
 			goto out;
 		}
@@ -274,7 +279,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 			res->flags |= IORESOURCE_UNSET;
 			res->start = 0;
 			res->end = sz64;
-			dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n",
+			pci_info(dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n",
 				 pos, (unsigned long long)l64);
 			goto out;
 		}
@@ -301,7 +306,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 		res->flags |= IORESOURCE_UNSET;
 		res->start = 0;
 		res->end = region.end - region.start;
-		dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
+		pci_info(dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
 			 pos, (unsigned long long)region.start);
 	}
 
@@ -312,7 +317,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 	res->flags = 0;
 out:
 	if (res->flags)
-		dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res);
+		pci_printk(KERN_DEBUG, dev, "reg 0x%x: %pR\n", pos, res);
 
 	return (res->flags & IORESOURCE_MEM_64) ? 1 : 0;
 }
@@ -375,7 +380,7 @@ static void pci_read_bridge_io(struct pci_bus *child)
 		region.start = base;
 		region.end = limit + io_granularity - 1;
 		pcibios_bus_to_resource(dev->bus, res, &region);
-		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
+		pci_printk(KERN_DEBUG, dev, "  bridge window %pR\n", res);
 	}
 }
 
@@ -397,7 +402,7 @@ static void pci_read_bridge_mmio(struct pci_bus *child)
 		region.start = base;
 		region.end = limit + 0xfffff;
 		pcibios_bus_to_resource(dev->bus, res, &region);
-		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
+		pci_printk(KERN_DEBUG, dev, "  bridge window %pR\n", res);
 	}
 }
 
@@ -437,7 +442,7 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
 	limit = (pci_bus_addr_t) limit64;
 
 	if (base != base64) {
-		dev_err(&dev->dev, "can't handle bridge window above 4GB (bus address %#010llx)\n",
+		pci_err(dev, "can't handle bridge window above 4GB (bus address %#010llx)\n",
 			(unsigned long long) base64);
 		return;
 	}
@@ -450,7 +455,7 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
 		region.start = base;
 		region.end = limit + 0xfffff;
 		pcibios_bus_to_resource(dev->bus, res, &region);
-		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
+		pci_printk(KERN_DEBUG, dev, "  bridge window %pR\n", res);
 	}
 }
 
@@ -463,7 +468,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
 	if (pci_is_root_bus(child))	/* It's a host bus, nothing to read */
 		return;
 
-	dev_info(&dev->dev, "PCI bridge to %pR%s\n",
+	pci_info(dev, "PCI bridge to %pR%s\n",
 		 &child->busn_res,
 		 dev->transparent ? " (subtractive decode)" : "");
 
@@ -480,7 +485,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
 			if (res && res->flags) {
 				pci_bus_add_resource(child, res,
 						     PCI_SUBTRACTIVE_DECODE);
-				dev_printk(KERN_DEBUG, &dev->dev,
+				pci_printk(KERN_DEBUG, dev,
 					   "  bridge window %pR (subtractive decode)\n",
 					   res);
 			}
@@ -764,7 +769,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
 
 	bridge->bus = bus;
 
-	/* temporarily move resources off the list */
+	/* Temporarily move resources off the list */
 	list_splice_init(&bridge->windows, &resources);
 	bus->sysdata = bridge->sysdata;
 	bus->msi = bridge->msi;
@@ -776,7 +781,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
 
 	b = pci_find_bus(pci_domain_nr(bus), bridge->busnr);
 	if (b) {
-		/* If we already got to this bus through a different bridge, ignore it */
+		/* Ignore it if we already got here via a different bridge */
 		dev_dbg(&b->dev, "bus already known\n");
 		err = -EEXIST;
 		goto free;
@@ -869,9 +874,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 	int i;
 	int ret;
 
-	/*
-	 * Allocate a new bus, and inherit stuff from the parent..
-	 */
+	/* Allocate a new bus and inherit stuff from the parent */
 	child = pci_alloc_bus(parent);
 	if (!child)
 		return NULL;
@@ -882,16 +885,14 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 	child->sysdata = parent->sysdata;
 	child->bus_flags = parent->bus_flags;
 
-	/* initialize some portions of the bus device, but don't register it
-	 * now as the parent is not properly set up yet.
+	/*
+	 * Initialize some portions of the bus device, but don't register
+	 * it now as the parent is not properly set up yet.
 	 */
 	child->dev.class = &pcibus_class;
 	dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
 
-	/*
-	 * Set up the primary, secondary and subordinate
-	 * bus numbers.
-	 */
+	/* Set up the primary, secondary and subordinate bus numbers */
 	child->number = child->busn_res.start = busnr;
 	child->primary = parent->busn_res.start;
 	child->busn_res.end = 0xff;
@@ -907,7 +908,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
 	pci_set_bus_of_node(child);
 	pci_set_bus_speed(child);
 
-	/* Set up default resource pointers and names.. */
+	/* Set up default resource pointers and names */
 	for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
 		child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i];
 		child->resource[i]->name = child->name;
@@ -1005,11 +1006,11 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 	secondary = (buses >> 8) & 0xFF;
 	subordinate = (buses >> 16) & 0xFF;
 
-	dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
+	pci_dbg(dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
 		secondary, subordinate, pass);
 
 	if (!primary && (primary != bus->number) && secondary && subordinate) {
-		dev_warn(&dev->dev, "Primary bus is hard wired to 0\n");
+		pci_warn(dev, "Primary bus is hard wired to 0\n");
 		primary = bus->number;
 	}
 
@@ -1017,13 +1018,15 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 	if (!pass &&
 	    (primary != bus->number || secondary <= bus->number ||
 	     secondary > subordinate)) {
-		dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n",
+		pci_info(dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n",
 			 secondary, subordinate);
 		broken = 1;
 	}
 
-	/* Disable MasterAbortMode during probing to avoid reporting
-	   of bus errors (in some architectures) */
+	/*
+	 * Disable Master-Abort Mode during probing to avoid reporting of
+	 * bus errors in some architectures.
+	 */
 	pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bctl);
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
 			      bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
@@ -1033,18 +1036,19 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 	if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
 	    !is_cardbus && !broken) {
 		unsigned int cmax;
+
 		/*
-		 * Bus already configured by firmware, process it in the first
-		 * pass and just note the configuration.
+		 * Bus already configured by firmware, process it in the
+		 * first pass and just note the configuration.
 		 */
 		if (pass)
 			goto out;
 
 		/*
-		 * The bus might already exist for two reasons: Either we are
-		 * rescanning the bus or the bus is reachable through more than
-		 * one bridge. The second case can happen with the i450NX
-		 * chipset.
+		 * The bus might already exist for two reasons: Either we
+		 * are rescanning the bus or the bus is reachable through
+		 * more than one bridge. The second case can happen with
+		 * the i450NX chipset.
 		 */
 		child = pci_find_bus(pci_domain_nr(bus), secondary);
 		if (!child) {
@@ -1058,24 +1062,29 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 
 		cmax = pci_scan_child_bus(child);
 		if (cmax > subordinate)
-			dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n",
+			pci_warn(dev, "bridge has subordinate %02x but max busn %02x\n",
 				 subordinate, cmax);
-		/* subordinate should equal child->busn_res.end */
+
+		/* Subordinate should equal child->busn_res.end */
 		if (subordinate > max)
 			max = subordinate;
 	} else {
+
 		/*
 		 * We need to assign a number to this bus which we always
 		 * do in the second pass.
 		 */
 		if (!pass) {
 			if (pcibios_assign_all_busses() || broken || is_cardbus)
-				/* Temporarily disable forwarding of the
-				   configuration cycles on all bridges in
-				   this bus segment to avoid possible
-				   conflicts in the second pass between two
-				   bridges programmed with overlapping
-				   bus ranges. */
+
+				/*
+				 * Temporarily disable forwarding of the
+				 * configuration cycles on all bridges in
+				 * this bus segment to avoid possible
+				 * conflicts in the second pass between two
+				 * bridges programmed with overlapping bus
+				 * ranges.
+				 */
 				pci_write_config_dword(dev, PCI_PRIMARY_BUS,
 						       buses & ~0xffffff);
 			goto out;
@@ -1084,9 +1093,11 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 		/* Clear errors */
 		pci_write_config_word(dev, PCI_STATUS, 0xffff);
 
-		/* Prevent assigning a bus number that already exists.
-		 * This can happen when a bridge is hot-plugged, so in
-		 * this case we only re-scan this bus. */
+		/*
+		 * Prevent assigning a bus number that already exists.
+		 * This can happen when a bridge is hot-plugged, so in this
+		 * case we only re-scan this bus.
+		 */
 		child = pci_find_bus(pci_domain_nr(bus), max+1);
 		if (!child) {
 			child = pci_add_new_bus(bus, dev, max+1);
@@ -1113,19 +1124,18 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 			buses |= CARDBUS_LATENCY_TIMER << 24;
 		}
 
-		/*
-		 * We need to blast all three values with a single write.
-		 */
+		/* We need to blast all three values with a single write */
 		pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
 
 		if (!is_cardbus) {
 			child->bridge_ctl = bctl;
 			max = pci_scan_child_bus_extend(child, available_buses);
 		} else {
+
 			/*
-			 * For CardBus bridges, we leave 4 bus numbers
-			 * as cards with a PCI-to-PCI bridge can be
-			 * inserted later.
+			 * For CardBus bridges, we leave 4 bus numbers as
+			 * cards with a PCI-to-PCI bridge can be inserted
+			 * later.
 			 */
 			for (i = 0; i < CARDBUS_RESERVE_BUSNR; i++) {
 				struct pci_bus *parent = bus;
@@ -1141,10 +1151,11 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 					parent = parent->parent;
 				}
 				if (j) {
+
 					/*
-					 * Often, there are two cardbus bridges
-					 * -- try to leave one valid bus number
-					 * for each one.
+					 * Often, there are two CardBus
+					 * bridges -- try to leave one
+					 * valid bus number for each one.
 					 */
 					i /= 2;
 					break;
@@ -1152,9 +1163,8 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 			}
 			max += i;
 		}
-		/*
-		 * Set the subordinate bus number to its real value.
-		 */
+
+		/* Set subordinate bus number to its real value */
 		pci_bus_update_busn_res_end(child, max);
 		pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
 	}
@@ -1295,7 +1305,7 @@ static void set_pcie_thunderbolt(struct pci_dev *dev)
 }
 
 /**
- * pci_ext_cfg_is_aliased - is ext config space just an alias of std config?
+ * pci_ext_cfg_is_aliased - Is ext config space just an alias of std config?
  * @dev: PCI device
  *
  * PCI Express to PCI/PCI-X Bridge Specification, rev 1.0, 4.1.4 says that
@@ -1332,7 +1342,7 @@ static bool pci_ext_cfg_is_aliased(struct pci_dev *dev)
 }
 
 /**
- * pci_cfg_space_size - get the configuration space size of the PCI device.
+ * pci_cfg_space_size - Get the configuration space size of the PCI device
  * @dev: PCI device
  *
  * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices
@@ -1398,7 +1408,7 @@ static void pci_msi_setup_pci_dev(struct pci_dev *dev)
 }
 
 /**
- * pci_intx_mask_broken - test PCI_COMMAND_INTX_DISABLE writability
+ * pci_intx_mask_broken - Test PCI_COMMAND_INTX_DISABLE writability
  * @dev: PCI device
  *
  * Test whether PCI_COMMAND_INTX_DISABLE is writable for @dev.  Check this
@@ -1426,11 +1436,11 @@ static int pci_intx_mask_broken(struct pci_dev *dev)
 }
 
 /**
- * pci_setup_device - fill in class and map information of a device
+ * pci_setup_device - Fill in class and map information of a device
  * @dev: the device structure to fill
  *
  * Initialize the device structure with information about the device's
- * vendor,class,memory and IO-space addresses,IRQ lines etc.
+ * vendor,class,memory and IO-space addresses, IRQ lines etc.
  * Called at initialisation of the PCI subsystem and by CardBus services.
  * Returns 0 on success and negative if unknown type of device (not normal,
  * bridge or CardBus).
@@ -1456,8 +1466,11 @@ int pci_setup_device(struct pci_dev *dev)
 	set_pcie_port_type(dev);
 
 	pci_dev_assign_slot(dev);
-	/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
-	   set this higher, assuming the system even supports it.  */
+
+	/*
+	 * Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
+	 * set this higher, assuming the system even supports it.
+	 */
 	dev->dma_mask = 0xffffffff;
 
 	dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
@@ -1468,13 +1481,13 @@ int pci_setup_device(struct pci_dev *dev)
 	dev->revision = class & 0xff;
 	dev->class = class >> 8;		    /* upper 3 bytes */
 
-	dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %02x class %#08x\n",
+	pci_printk(KERN_DEBUG, dev, "[%04x:%04x] type %02x class %#08x\n",
 		   dev->vendor, dev->device, dev->hdr_type, dev->class);
 
-	/* need to have dev->class ready */
+	/* Need to have dev->class ready */
 	dev->cfg_size = pci_cfg_space_size(dev);
 
-	/* need to have dev->cfg_size ready */
+	/* Need to have dev->cfg_size ready */
 	set_pcie_thunderbolt(dev);
 
 	/* "Unknown power state" */
@@ -1482,13 +1495,14 @@ int pci_setup_device(struct pci_dev *dev)
 
 	/* Early fixups, before probing the BARs */
 	pci_fixup_device(pci_fixup_early, dev);
-	/* device class may be changed after fixup */
+
+	/* Device class may be changed after fixup */
 	class = dev->class >> 8;
 
 	if (dev->non_compliant_bars) {
 		pci_read_config_word(dev, PCI_COMMAND, &cmd);
 		if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
-			dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
+			pci_info(dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
 			cmd &= ~PCI_COMMAND_IO;
 			cmd &= ~PCI_COMMAND_MEMORY;
 			pci_write_config_word(dev, PCI_COMMAND, cmd);
@@ -1521,14 +1535,14 @@ int pci_setup_device(struct pci_dev *dev)
 				res = &dev->resource[0];
 				res->flags = LEGACY_IO_RESOURCE;
 				pcibios_bus_to_resource(dev->bus, res, &region);
-				dev_info(&dev->dev, "legacy IDE quirk: reg 0x10: %pR\n",
+				pci_info(dev, "legacy IDE quirk: reg 0x10: %pR\n",
 					 res);
 				region.start = 0x3F6;
 				region.end = 0x3F6;
 				res = &dev->resource[1];
 				res->flags = LEGACY_IO_RESOURCE;
 				pcibios_bus_to_resource(dev->bus, res, &region);
-				dev_info(&dev->dev, "legacy IDE quirk: reg 0x14: %pR\n",
+				pci_info(dev, "legacy IDE quirk: reg 0x14: %pR\n",
 					 res);
 			}
 			if ((progif & 4) == 0) {
@@ -1537,14 +1551,14 @@ int pci_setup_device(struct pci_dev *dev)
 				res = &dev->resource[2];
 				res->flags = LEGACY_IO_RESOURCE;
 				pcibios_bus_to_resource(dev->bus, res, &region);
-				dev_info(&dev->dev, "legacy IDE quirk: reg 0x18: %pR\n",
+				pci_info(dev, "legacy IDE quirk: reg 0x18: %pR\n",
 					 res);
 				region.start = 0x376;
 				region.end = 0x376;
 				res = &dev->resource[3];
 				res->flags = LEGACY_IO_RESOURCE;
 				pcibios_bus_to_resource(dev->bus, res, &region);
-				dev_info(&dev->dev, "legacy IDE quirk: reg 0x1c: %pR\n",
+				pci_info(dev, "legacy IDE quirk: reg 0x1c: %pR\n",
 					 res);
 			}
 		}
@@ -1553,9 +1567,12 @@ int pci_setup_device(struct pci_dev *dev)
 	case PCI_HEADER_TYPE_BRIDGE:		    /* bridge header */
 		if (class != PCI_CLASS_BRIDGE_PCI)
 			goto bad;
-		/* The PCI-to-PCI bridge spec requires that subtractive
-		   decoding (i.e. transparent) bridge must have programming
-		   interface code of 0x01. */
+
+		/*
+		 * The PCI-to-PCI bridge spec requires that subtractive
+		 * decoding (i.e. transparent) bridge must have programming
+		 * interface code of 0x01.
+		 */
 		pci_read_irq(dev);
 		dev->transparent = ((dev->class & 0xff) == 1);
 		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
@@ -1577,12 +1594,12 @@ int pci_setup_device(struct pci_dev *dev)
 		break;
 
 	default:				    /* unknown header */
-		dev_err(&dev->dev, "unknown header type %02x, ignoring device\n",
+		pci_err(dev, "unknown header type %02x, ignoring device\n",
 			dev->hdr_type);
 		return -EIO;
 
 	bad:
-		dev_err(&dev->dev, "ignoring class %#08x (doesn't match header type %02x)\n",
+		pci_err(dev, "ignoring class %#08x (doesn't match header type %02x)\n",
 			dev->class, dev->hdr_type);
 		dev->class = PCI_CLASS_NOT_DEFINED << 8;
 	}
@@ -1606,7 +1623,7 @@ static void pci_configure_mps(struct pci_dev *dev)
 		return;
 
 	if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
-		dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
+		pci_warn(dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
 			 mps, pci_name(bridge), p_mps);
 		return;
 	}
@@ -1620,12 +1637,12 @@ static void pci_configure_mps(struct pci_dev *dev)
 
 	rc = pcie_set_mps(dev, p_mps);
 	if (rc) {
-		dev_warn(&dev->dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
+		pci_warn(dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
 			 p_mps);
 		return;
 	}
 
-	dev_info(&dev->dev, "Max Payload Size set to %d (was %d, max %d)\n",
+	pci_info(dev, "Max Payload Size set to %d (was %d, max %d)\n",
 		 p_mps, mps, 128 << dev->pcie_mpss);
 }
 
@@ -1645,8 +1662,7 @@ static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
 		hpp = &pci_default_type0;
 
 	if (hpp->revision > 1) {
-		dev_warn(&dev->dev,
-			 "PCI settings rev %d not supported; using defaults\n",
+		pci_warn(dev, "PCI settings rev %d not supported; using defaults\n",
 			 hpp->revision);
 		hpp = &pci_default_type0;
 	}
@@ -1684,7 +1700,7 @@ static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
 	if (!pos)
 		return;
 
-	dev_warn(&dev->dev, "PCI-X settings not supported\n");
+	pci_warn(dev, "PCI-X settings not supported\n");
 }
 
 static bool pcie_root_rcb_set(struct pci_dev *dev)
@@ -1714,7 +1730,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
 		return;
 
 	if (hpp->revision > 1) {
-		dev_warn(&dev->dev, "PCIe settings rev %d not supported\n",
+		pci_warn(dev, "PCIe settings rev %d not supported\n",
 			 hpp->revision);
 		return;
 	}
@@ -1772,6 +1788,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
 	/* Initialize Advanced Error Capabilities and Control Register */
 	pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
 	reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
+
 	/* Don't enable ECRC generation or checking if unsupported */
 	if (!(reg32 & PCI_ERR_CAP_ECRC_GENC))
 		reg32 &= ~PCI_ERR_CAP_ECRC_GENE;
@@ -1818,7 +1835,7 @@ int pci_configure_extended_tags(struct pci_dev *dev, void *ign)
 	 */
 	if (host->no_ext_tags) {
 		if (ctl & PCI_EXP_DEVCTL_EXT_TAG) {
-			dev_info(&dev->dev, "disabling Extended Tags\n");
+			pci_info(dev, "disabling Extended Tags\n");
 			pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
 						   PCI_EXP_DEVCTL_EXT_TAG);
 		}
@@ -1826,7 +1843,7 @@ int pci_configure_extended_tags(struct pci_dev *dev, void *ign)
 	}
 
 	if (!(ctl & PCI_EXP_DEVCTL_EXT_TAG)) {
-		dev_info(&dev->dev, "enabling Extended Tags\n");
+		pci_info(dev, "enabling Extended Tags\n");
 		pcie_capability_set_word(dev, PCI_EXP_DEVCTL,
 					 PCI_EXP_DEVCTL_EXT_TAG);
 	}
@@ -1871,10 +1888,42 @@ static void pci_configure_relaxed_ordering(struct pci_dev *dev)
 	if (root->dev_flags & PCI_DEV_FLAGS_NO_RELAXED_ORDERING) {
 		pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
 					   PCI_EXP_DEVCTL_RELAX_EN);
-		dev_info(&dev->dev, "Disable Relaxed Ordering because the Root Port didn't support it\n");
+		pci_info(dev, "Relaxed Ordering disabled because the Root Port didn't support it\n");
 	}
 }
 
+static void pci_configure_ltr(struct pci_dev *dev)
+{
+#ifdef CONFIG_PCIEASPM
+	u32 cap;
+	struct pci_dev *bridge;
+
+	if (!pci_is_pcie(dev))
+		return;
+
+	pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
+	if (!(cap & PCI_EXP_DEVCAP2_LTR))
+		return;
+
+	/*
+	 * Software must not enable LTR in an Endpoint unless the Root
+	 * Complex and all intermediate Switches indicate support for LTR.
+	 * PCIe r3.1, sec 6.18.
+	 */
+	if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+		dev->ltr_path = 1;
+	else {
+		bridge = pci_upstream_bridge(dev);
+		if (bridge && bridge->ltr_path)
+			dev->ltr_path = 1;
+	}
+
+	if (dev->ltr_path)
+		pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
+					 PCI_EXP_DEVCTL2_LTR_EN);
+#endif
+}
+
 static void pci_configure_device(struct pci_dev *dev)
 {
 	struct hotplug_params hpp;
@@ -1883,6 +1932,7 @@ static void pci_configure_device(struct pci_dev *dev)
 	pci_configure_mps(dev);
 	pci_configure_extended_tags(dev, NULL);
 	pci_configure_relaxed_ordering(dev);
+	pci_configure_ltr(dev);
 
 	memset(&hpp, 0, sizeof(hpp));
 	ret = pci_get_hp_params(dev, &hpp);
@@ -1902,10 +1952,11 @@ static void pci_release_capabilities(struct pci_dev *dev)
 }
 
 /**
- * pci_release_dev - free a pci device structure when all users of it are finished.
+ * pci_release_dev - Free a PCI device structure when all users of it are
+ *		     finished
  * @dev: device that's been disconnected
  *
- * Will be called only by the device core when all users of this pci device are
+ * Will be called only by the device core when all users of this PCI device are
  * done.
  */
 static void pci_release_dev(struct device *dev)
@@ -1993,7 +2044,7 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
 	if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l))
 		return false;
 
-	/* some broken boards return 0 or ~0 if a slot is empty: */
+	/* Some broken boards return 0 or ~0 if a slot is empty: */
 	if (*l == 0xffffffff || *l == 0x00000000 ||
 	    *l == 0x0000ffff || *l == 0xffff0000)
 		return false;
@@ -2006,8 +2057,8 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
 EXPORT_SYMBOL(pci_bus_read_dev_vendor_id);
 
 /*
- * Read the config data for a PCI device, sanity-check it
- * and fill in the dev structure...
+ * Read the config data for a PCI device, sanity-check it,
+ * and fill in the dev structure.
  */
 static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
 {
@@ -2073,7 +2124,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
 }
 
 /*
- * This is the equivalent of pci_host_bridge_msi_domain that acts on
+ * This is the equivalent of pci_host_bridge_msi_domain() that acts on
  * devices. Firmware interfaces that can select the MSI domain on a
  * per-device basis should be called from here.
  */
@@ -2082,7 +2133,7 @@ static struct irq_domain *pci_dev_msi_domain(struct pci_dev *dev)
 	struct irq_domain *d;
 
 	/*
-	 * If a domain has been set through the pcibios_add_device
+	 * If a domain has been set through the pcibios_add_device()
 	 * callback, then this is the one (platform code knows best).
 	 */
 	d = dev_get_msi_domain(&dev->dev);
@@ -2136,10 +2187,10 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	/* Fix up broken headers */
 	pci_fixup_device(pci_fixup_header, dev);
 
-	/* moved out from quirk header fixup code */
+	/* Moved out from quirk header fixup code */
 	pci_reassigndev_resource_alignment(dev);
 
-	/* Clear the state_saved flag. */
+	/* Clear the state_saved flag */
 	dev->state_saved = false;
 
 	/* Initialize various capabilities */
@@ -2156,7 +2207,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	ret = pcibios_add_device(dev);
 	WARN_ON(ret < 0);
 
-	/* Setup MSI irq domain */
+	/* Set up MSI IRQ domain */
 	pci_set_msi_domain(dev);
 
 	/* Notifier could use PCI capabilities */
@@ -2215,29 +2266,34 @@ static unsigned next_fn(struct pci_bus *bus, struct pci_dev *dev, unsigned fn)
 
 static int only_one_child(struct pci_bus *bus)
 {
-	struct pci_dev *parent = bus->self;
-
-	if (!parent || !pci_is_pcie(parent))
-		return 0;
-	if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT)
-		return 1;
+	struct pci_dev *bridge = bus->self;
 
 	/*
-	 * PCIe downstream ports are bridges that normally lead to only a
-	 * device 0, but if PCI_SCAN_ALL_PCIE_DEVS is set, scan all
-	 * possible devices, not just device 0.  See PCIe spec r3.0,
-	 * sec 7.3.1.
+	 * Systems with unusual topologies set PCI_SCAN_ALL_PCIE_DEVS so
+	 * we scan for all possible devices, not just Device 0.
 	 */
-	if (parent->has_secondary_link &&
-	    !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
+	if (pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
+		return 0;
+
+	/*
+	 * A PCIe Downstream Port normally leads to a Link with only Device
+	 * 0 on it (PCIe spec r3.1, sec 7.3.1).  As an optimization, scan
+	 * only for Device 0 in that situation.
+	 *
+	 * Checking has_secondary_link is a hack to identify Downstream
+	 * Ports because sometimes Switches are configured such that the
+	 * PCIe Port Type labels are backwards.
+	 */
+	if (bridge && pci_is_pcie(bridge) && bridge->has_secondary_link)
 		return 1;
+
 	return 0;
 }
 
 /**
- * pci_scan_slot - scan a PCI slot on a bus for devices.
+ * pci_scan_slot - Scan a PCI slot on a bus for devices
  * @bus: PCI bus to scan
- * @devfn: slot number to scan (must have zero function.)
+ * @devfn: slot number to scan (must have zero function)
  *
  * Scan a PCI slot on the specified PCI bus for devices, adding
  * discovered devices to the @bus->devices list.  New devices
@@ -2268,7 +2324,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn)
 		}
 	}
 
-	/* only one slot has pcie device */
+	/* Only one slot has PCIe device */
 	if (bus->self && nr)
 		pcie_aspm_init_link_state(bus->self);
 
@@ -2317,7 +2373,9 @@ static void pcie_write_mps(struct pci_dev *dev, int mps)
 
 		if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT &&
 		    dev->bus->self)
-			/* For "Performance", the assumption is made that
+
+			/*
+			 * For "Performance", the assumption is made that
 			 * downstream communication will never be larger than
 			 * the MRRS.  So, the MPS only needs to be configured
 			 * for the upstream communication.  This being the case,
@@ -2334,27 +2392,30 @@ static void pcie_write_mps(struct pci_dev *dev, int mps)
 
 	rc = pcie_set_mps(dev, mps);
 	if (rc)
-		dev_err(&dev->dev, "Failed attempting to set the MPS\n");
+		pci_err(dev, "Failed attempting to set the MPS\n");
 }
 
 static void pcie_write_mrrs(struct pci_dev *dev)
 {
 	int rc, mrrs;
 
-	/* In the "safe" case, do not configure the MRRS.  There appear to be
+	/*
+	 * In the "safe" case, do not configure the MRRS.  There appear to be
 	 * issues with setting MRRS to 0 on a number of devices.
 	 */
 	if (pcie_bus_config != PCIE_BUS_PERFORMANCE)
 		return;
 
-	/* For Max performance, the MRRS must be set to the largest supported
+	/*
+	 * For max performance, the MRRS must be set to the largest supported
 	 * value.  However, it cannot be configured larger than the MPS the
 	 * device or the bus can support.  This should already be properly
-	 * configured by a prior call to pcie_write_mps.
+	 * configured by a prior call to pcie_write_mps().
 	 */
 	mrrs = pcie_get_mps(dev);
 
-	/* MRRS is a R/W register.  Invalid values can be written, but a
+	/*
+	 * MRRS is a R/W register.  Invalid values can be written, but a
 	 * subsequent read will verify if the value is acceptable or not.
 	 * If the MRRS value provided is not acceptable (e.g., too large),
 	 * shrink the value until it is acceptable to the HW.
@@ -2364,12 +2425,12 @@ static void pcie_write_mrrs(struct pci_dev *dev)
 		if (!rc)
 			break;
 
-		dev_warn(&dev->dev, "Failed attempting to set the MRRS\n");
+		pci_warn(dev, "Failed attempting to set the MRRS\n");
 		mrrs /= 2;
 	}
 
 	if (mrrs < 128)
-		dev_err(&dev->dev, "MRRS was unable to be configured with a safe value.  If problems are experienced, try running with pci=pcie_bus_safe\n");
+		pci_err(dev, "MRRS was unable to be configured with a safe value.  If problems are experienced, try running with pci=pcie_bus_safe\n");
 }
 
 static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
@@ -2389,14 +2450,15 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
 	pcie_write_mps(dev, mps);
 	pcie_write_mrrs(dev);
 
-	dev_info(&dev->dev, "Max Payload Size set to %4d/%4d (was %4d), Max Read Rq %4d\n",
+	pci_info(dev, "Max Payload Size set to %4d/%4d (was %4d), Max Read Rq %4d\n",
 		 pcie_get_mps(dev), 128 << dev->pcie_mpss,
 		 orig_mps, pcie_get_readrq(dev));
 
 	return 0;
 }
 
-/* pcie_bus_configure_settings requires that pci_walk_bus work in a top-down,
+/*
+ * pcie_bus_configure_settings() requires that pci_walk_bus work in a top-down,
  * parents then children fashion.  If this changes, then this code will not
  * work as designed.
  */
@@ -2410,7 +2472,8 @@ void pcie_bus_configure_settings(struct pci_bus *bus)
 	if (!pci_is_pcie(bus->self))
 		return;
 
-	/* FIXME - Peer to peer DMA is possible, though the endpoint would need
+	/*
+	 * FIXME - Peer to peer DMA is possible, though the endpoint would need
 	 * to be aware of the MPS of the destination.  To work around this,
 	 * simply force the MPS of the entire system to the smallest possible.
 	 */
@@ -2464,7 +2527,7 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
 	for (devfn = 0; devfn < 0x100; devfn += 8)
 		pci_scan_slot(bus, devfn);
 
-	/* Reserve buses for SR-IOV capability. */
+	/* Reserve buses for SR-IOV capability */
 	used_buses = pci_iov_bus_range(bus);
 	max += used_buses;
 
@@ -2506,6 +2569,7 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
 		unsigned int buses = 0;
 
 		if (!hotplug_bridges && normal_bridges == 1) {
+
 			/*
 			 * There is only one bridge on the bus (upstream
 			 * port) so it gets all available buses which it
@@ -2514,6 +2578,7 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
 			 */
 			buses = available_buses;
 		} else if (dev->is_hotplug_bridge) {
+
 			/*
 			 * Distribute the extra buses between hotplug
 			 * bridges if any.
@@ -2572,8 +2637,8 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus)
 EXPORT_SYMBOL_GPL(pci_scan_child_bus);
 
 /**
- * pcibios_root_bridge_prepare - Platform-specific host bridge setup.
- * @bridge: Host bridge to set up.
+ * pcibios_root_bridge_prepare - Platform-specific host bridge setup
+ * @bridge: Host bridge to set up
  *
  * Default empty implementation.  Replace with an architecture-specific setup
  * routine, if necessary.
@@ -2620,6 +2685,39 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 }
 EXPORT_SYMBOL_GPL(pci_create_root_bus);
 
+int pci_host_probe(struct pci_host_bridge *bridge)
+{
+	struct pci_bus *bus, *child;
+	int ret;
+
+	ret = pci_scan_root_bus_bridge(bridge);
+	if (ret < 0) {
+		dev_err(bridge->dev.parent, "Scanning root bridge failed");
+		return ret;
+	}
+
+	bus = bridge->bus;
+
+	/*
+	 * We insert PCI resources into the iomem_resource and
+	 * ioport_resource trees in either pci_bus_claim_resources()
+	 * or pci_bus_assign_resources().
+	 */
+	if (pci_has_flag(PCI_PROBE_ONLY)) {
+		pci_bus_claim_resources(bus);
+	} else {
+		pci_bus_size_bridges(bus);
+		pci_bus_assign_resources(bus);
+
+		list_for_each_entry(child, &bus->children, node)
+			pcie_bus_configure_settings(child);
+	}
+
+	pci_bus_add_devices(bus);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_host_probe);
+
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
 {
 	struct resource *res = &b->busn_res;
@@ -2776,7 +2874,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
 EXPORT_SYMBOL(pci_scan_bus);
 
 /**
- * pci_rescan_bus_bridge_resize - scan a PCI bus for devices.
+ * pci_rescan_bus_bridge_resize - Scan a PCI bus for devices
  * @bridge: PCI bridge for the bus to scan
  *
  * Scan a PCI bus and child buses for new devices, add them,
@@ -2801,11 +2899,11 @@ unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge)
 }
 
 /**
- * pci_rescan_bus - scan a PCI bus for devices.
+ * pci_rescan_bus - Scan a PCI bus for devices
  * @bus: PCI bus to scan
  *
- * Scan a PCI bus and child buses for new devices, adds them,
- * and enables them.
+ * Scan a PCI bus and child buses for new devices, add them,
+ * and enable them.
  *
  * Returns the max number of subordinate bus discovered.
  */
@@ -2874,7 +2972,7 @@ int pci_hp_add_bridge(struct pci_dev *dev)
 			break;
 	}
 	if (busnr-- > end) {
-		dev_err(&dev->dev, "No bus number available for hot-added bridge\n");
+		pci_err(dev, "No bus number available for hot-added bridge\n");
 		return -1;
 	}
 
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 10684b1..fc73401 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -19,7 +19,6 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/acpi.h>
-#include <linux/kallsyms.h>
 #include <linux/dmi.h>
 #include <linux/pci-aspm.h>
 #include <linux/ioport.h>
@@ -66,7 +65,7 @@ static void quirk_passive_release(struct pci_dev *dev)
 	while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
 		pci_read_config_byte(d, 0x82, &dlc);
 		if (!(dlc & 1<<1)) {
-			dev_info(&d->dev, "PIIX3: Enabling Passive Release\n");
+			pci_info(d, "PIIX3: Enabling Passive Release\n");
 			dlc |= 1<<1;
 			pci_write_config_byte(d, 0x82, dlc);
 		}
@@ -86,7 +85,7 @@ static void quirk_isa_dma_hangs(struct pci_dev *dev)
 {
 	if (!isa_dma_bridge_buggy) {
 		isa_dma_bridge_buggy = 1;
-		dev_info(&dev->dev, "Activating ISA DMA hang workarounds\n");
+		pci_info(dev, "Activating ISA DMA hang workarounds\n");
 	}
 }
 	/*
@@ -115,7 +114,7 @@ static void quirk_tigerpoint_bm_sts(struct pci_dev *dev)
 	pm1a = inw(pmbase);
 
 	if (pm1a & 0x10) {
-		dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n");
+		pci_info(dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n");
 		outw(0x10, pmbase);
 	}
 }
@@ -127,7 +126,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk
 static void quirk_nopcipci(struct pci_dev *dev)
 {
 	if ((pci_pci_problems & PCIPCI_FAIL) == 0) {
-		dev_info(&dev->dev, "Disabling direct PCI/PCI transfers\n");
+		pci_info(dev, "Disabling direct PCI/PCI transfers\n");
 		pci_pci_problems |= PCIPCI_FAIL;
 	}
 }
@@ -140,7 +139,7 @@ static void quirk_nopciamd(struct pci_dev *dev)
 	pci_read_config_byte(dev, 0x08, &rev);
 	if (rev == 0x13) {
 		/* Erratum 24 */
-		dev_info(&dev->dev, "Chipset erratum: Disabling direct PCI/AGP transfers\n");
+		pci_info(dev, "Chipset erratum: Disabling direct PCI/AGP transfers\n");
 		pci_pci_problems |= PCIAGP_FAIL;
 	}
 }
@@ -152,7 +151,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8151_0,	quirk_nopci
 static void quirk_triton(struct pci_dev *dev)
 {
 	if ((pci_pci_problems&PCIPCI_TRITON) == 0) {
-		dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
+		pci_info(dev, "Limiting direct PCI/PCI transfers\n");
 		pci_pci_problems |= PCIPCI_TRITON;
 	}
 }
@@ -212,7 +211,7 @@ static void quirk_vialatency(struct pci_dev *dev)
 	busarb &= ~(1<<5);
 	busarb |= (1<<4);
 	pci_write_config_byte(dev, 0x76, busarb);
-	dev_info(&dev->dev, "Applying VIA southbridge workaround\n");
+	pci_info(dev, "Applying VIA southbridge workaround\n");
 exit:
 	pci_dev_put(p);
 }
@@ -230,7 +229,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8361,		quirk_viala
 static void quirk_viaetbf(struct pci_dev *dev)
 {
 	if ((pci_pci_problems&PCIPCI_VIAETBF) == 0) {
-		dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
+		pci_info(dev, "Limiting direct PCI/PCI transfers\n");
 		pci_pci_problems |= PCIPCI_VIAETBF;
 	}
 }
@@ -239,7 +238,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C597_0,	quirk_via
 static void quirk_vsfx(struct pci_dev *dev)
 {
 	if ((pci_pci_problems&PCIPCI_VSFX) == 0) {
-		dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
+		pci_info(dev, "Limiting direct PCI/PCI transfers\n");
 		pci_pci_problems |= PCIPCI_VSFX;
 	}
 }
@@ -254,7 +253,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C576,	quirk_vsfx)
 static void quirk_alimagik(struct pci_dev *dev)
 {
 	if ((pci_pci_problems&PCIPCI_ALIMAGIK) == 0) {
-		dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
+		pci_info(dev, "Limiting direct PCI/PCI transfers\n");
 		pci_pci_problems |= PCIPCI_ALIMAGIK|PCIPCI_TRITON;
 	}
 }
@@ -268,7 +267,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL,	PCI_DEVICE_ID_AL_M1651,		quirk_alimagi
 static void quirk_natoma(struct pci_dev *dev)
 {
 	if ((pci_pci_problems&PCIPCI_NATOMA) == 0) {
-		dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
+		pci_info(dev, "Limiting direct PCI/PCI transfers\n");
 		pci_pci_problems |= PCIPCI_NATOMA;
 	}
 }
@@ -313,7 +312,7 @@ static void quirk_extend_bar_to_page(struct pci_dev *dev)
 			r->end = PAGE_SIZE - 1;
 			r->start = 0;
 			r->flags |= IORESOURCE_UNSET;
-			dev_info(&dev->dev, "expanded BAR %d to page size: %pR\n",
+			pci_info(dev, "expanded BAR %d to page size: %pR\n",
 				 i, r);
 		}
 	}
@@ -360,7 +359,7 @@ static void quirk_io(struct pci_dev *dev, int pos, unsigned size,
 	bus_region.end = region + size - 1;
 	pcibios_bus_to_resource(dev->bus, res, &bus_region);
 
-	dev_info(&dev->dev, FW_BUG "%s quirk: reg 0x%x: %pR\n",
+	pci_info(dev, FW_BUG "%s quirk: reg 0x%x: %pR\n",
 		 name, PCI_BASE_ADDRESS_0 + (pos << 2), res);
 }
 
@@ -381,7 +380,7 @@ static void quirk_cs5536_vsa(struct pci_dev *dev)
 		quirk_io(dev, 0,   8, name);	/* SMB */
 		quirk_io(dev, 1, 256, name);	/* GPIO */
 		quirk_io(dev, 2,  64, name);	/* MFGPT */
-		dev_info(&dev->dev, "%s bug detected (incorrect header); workaround applied\n",
+		pci_info(dev, "%s bug detected (incorrect header); workaround applied\n",
 			 name);
 	}
 }
@@ -409,7 +408,7 @@ static void quirk_io_region(struct pci_dev *dev, int port,
 	pcibios_bus_to_resource(dev->bus, res, &bus_region);
 
 	if (!pci_claim_resource(dev, nr))
-		dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name);
+		pci_info(dev, "quirk: %pR claimed by %s\n", res, name);
 }
 
 /*
@@ -418,7 +417,7 @@ static void quirk_io_region(struct pci_dev *dev, int port,
  */
 static void quirk_ati_exploding_mce(struct pci_dev *dev)
 {
-	dev_info(&dev->dev, "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb\n");
+	pci_info(dev, "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb\n");
 	/* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */
 	request_region(0x3b0, 0x0C, "RadeonIGP");
 	request_region(0x3d3, 0x01, "RadeonIGP");
@@ -441,7 +440,7 @@ static void quirk_amd_nl_class(struct pci_dev *pdev)
 
 	/* Use "USB Device (not host controller)" class */
 	pdev->class = PCI_CLASS_SERIAL_USB_DEVICE;
-	dev_info(&pdev->dev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n",
+	pci_info(pdev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n",
 		 class, pdev->class);
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB,
@@ -488,8 +487,7 @@ static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int p
 	 * let's get enough confirmation reports first.
 	 */
 	base &= -size;
-	dev_info(&dev->dev, "%s PIO at %04x-%04x\n", name, base,
-		 base + size - 1);
+	pci_info(dev, "%s PIO at %04x-%04x\n", name, base, base + size - 1);
 }
 
 static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable)
@@ -514,8 +512,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int
 	 * reserve it, but let's get enough confirmation reports first.
 	 */
 	base &= -size;
-	dev_info(&dev->dev, "%s MMIO at %04x-%04x\n", name, base,
-		 base + size - 1);
+	pci_info(dev, "%s MMIO at %04x-%04x\n", name, base, base + size - 1);
 }
 
 /*
@@ -644,7 +641,7 @@ static void ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const cha
 	base &= ~(size-1);
 
 	/* Just print it out for now. We should reserve it after more debugging */
-	dev_info(&dev->dev, "%s PIO at %04x-%04x\n", name, base, base+size-1);
+	pci_info(dev, "%s PIO at %04x-%04x\n", name, base, base+size-1);
 }
 
 static void quirk_ich6_lpc(struct pci_dev *dev)
@@ -679,7 +676,7 @@ static void ich7_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const cha
 	mask |= 3;
 
 	/* Just print it out for now. We should reserve it after more debugging */
-	dev_info(&dev->dev, "%s PIO at %04x (mask %04x)\n", name, base, mask);
+	pci_info(dev, "%s PIO at %04x (mask %04x)\n", name, base, mask);
 }
 
 /* ICH7-10 has the same common LPC generic IO decode registers */
@@ -758,7 +755,7 @@ static void quirk_xio2000a(struct pci_dev *dev)
 	struct pci_dev *pdev;
 	u16 command;
 
-	dev_warn(&dev->dev, "TI XIO2000a quirk detected; secondary bus fast back-to-back transfers disabled\n");
+	pci_warn(dev, "TI XIO2000a quirk detected; secondary bus fast back-to-back transfers disabled\n");
 	list_for_each_entry(pdev, &dev->subordinate->devices, bus_list) {
 		pci_read_config_word(pdev, PCI_COMMAND, &command);
 		if (command & PCI_COMMAND_FAST_BACK)
@@ -788,7 +785,7 @@ static void quirk_via_ioapic(struct pci_dev *dev)
 	else
 		tmp = 0x1f; /* all known bits (4-0) routed to external APIC */
 
-	dev_info(&dev->dev, "%sbling VIA external APIC routing\n",
+	pci_info(dev, "%sbling VIA external APIC routing\n",
 	       tmp == 0 ? "Disa" : "Ena");
 
 	/* Offset 0x58: External APIC IRQ output control */
@@ -810,7 +807,7 @@ static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
 
 	pci_read_config_byte(dev, 0x5B, &misc_control2);
 	if (!(misc_control2 & BYPASS_APIC_DEASSERT)) {
-		dev_info(&dev->dev, "Bypassing VIA 8237 APIC De-Assert Message\n");
+		pci_info(dev, "Bypassing VIA 8237 APIC De-Assert Message\n");
 		pci_write_config_byte(dev, 0x5B, misc_control2|BYPASS_APIC_DEASSERT);
 	}
 }
@@ -829,8 +826,8 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237,		quirk
 static void quirk_amd_ioapic(struct pci_dev *dev)
 {
 	if (dev->revision >= 0x02) {
-		dev_warn(&dev->dev, "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n");
-		dev_warn(&dev->dev, "        : booting with the \"noapic\" option\n");
+		pci_warn(dev, "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n");
+		pci_warn(dev, "        : booting with the \"noapic\" option\n");
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_VIPER_7410,	quirk_amd_ioapic);
@@ -854,7 +851,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CAVIUM, 0xa018, quirk_cavium_sriov_rnm_lin
 static void quirk_amd_8131_mmrbc(struct pci_dev *dev)
 {
 	if (dev->subordinate && dev->revision <= 0x12) {
-		dev_info(&dev->dev, "AMD8131 rev %x detected; disabling PCI-X MMRBC\n",
+		pci_info(dev, "AMD8131 rev %x detected; disabling PCI-X MMRBC\n",
 			 dev->revision);
 		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC;
 	}
@@ -962,7 +959,7 @@ static void quirk_via_vlink(struct pci_dev *dev)
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
 	if (new_irq != irq) {
-		dev_info(&dev->dev, "VIA VLink IRQ fixup, from %d to %d\n",
+		pci_info(dev, "VIA VLink IRQ fixup, from %d to %d\n",
 			irq, new_irq);
 		udelay(15);	/* unknown if delay really needed */
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
@@ -1011,7 +1008,7 @@ static void quirk_amd_ordering(struct pci_dev *dev)
 	pci_read_config_dword(dev, 0x4C, &pcic);
 	if ((pcic & 6) != 6) {
 		pcic |= 6;
-		dev_warn(&dev->dev, "BIOS failed to enable PCI standards compliance; fixing this error\n");
+		pci_warn(dev, "BIOS failed to enable PCI standards compliance; fixing this error\n");
 		pci_write_config_dword(dev, 0x4C, pcic);
 		pci_read_config_dword(dev, 0x84, &pcic);
 		pcic |= (1 << 23);	/* Required in this mode */
@@ -1064,7 +1061,7 @@ static void quirk_mediagx_master(struct pci_dev *dev)
 	pci_read_config_byte(dev, 0x41, &reg);
 	if (reg & 2) {
 		reg &= ~2;
-		dev_info(&dev->dev, "Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n",
+		pci_info(dev, "Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n",
 			 reg);
 		pci_write_config_byte(dev, 0x41, reg);
 	}
@@ -1087,7 +1084,7 @@ static void quirk_disable_pxb(struct pci_dev *pdev)
 	if (config & (1<<6)) {
 		config &= ~(1<<6);
 		pci_write_config_word(pdev, 0x40, config);
-		dev_info(&pdev->dev, "C0 revision 450NX. Disabling PCI restreaming\n");
+		pci_info(pdev, "C0 revision 450NX. Disabling PCI restreaming\n");
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82454NX,	quirk_disable_pxb);
@@ -1107,7 +1104,7 @@ static void quirk_amd_ide_mode(struct pci_dev *pdev)
 		pci_write_config_byte(pdev, 0x40, tmp);
 
 		pdev->class = PCI_CLASS_STORAGE_SATA_AHCI;
-		dev_info(&pdev->dev, "set SATA to AHCI mode\n");
+		pci_info(pdev, "set SATA to AHCI mode\n");
 	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
@@ -1145,7 +1142,7 @@ static void quirk_ide_samemode(struct pci_dev *pdev)
 	pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
 
 	if (((prog & 1) && !(prog & 4)) || ((prog & 4) && !(prog & 1))) {
-		dev_info(&pdev->dev, "IDE mode mismatch; forcing legacy mode\n");
+		pci_info(pdev, "IDE mode mismatch; forcing legacy mode\n");
 		prog &= ~5;
 		pdev->class &= ~5;
 		pci_write_config_byte(pdev, PCI_CLASS_PROG, prog);
@@ -1356,10 +1353,10 @@ static void asus_hides_smbus_lpc(struct pci_dev *dev)
 		pci_write_config_word(dev, 0xF2, val & (~0x8));
 		pci_read_config_word(dev, 0xF2, &val);
 		if (val & 0x8)
-			dev_info(&dev->dev, "i801 SMBus device continues to play 'hide and seek'! 0x%x\n",
+			pci_info(dev, "i801 SMBus device continues to play 'hide and seek'! 0x%x\n",
 				 val);
 		else
-			dev_info(&dev->dev, "Enabled i801 SMBus device\n");
+			pci_info(dev, "Enabled i801 SMBus device\n");
 	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82801AA_0,	asus_hides_smbus_lpc);
@@ -1411,7 +1408,7 @@ static void asus_hides_smbus_lpc_ich6_resume(struct pci_dev *dev)
 		return;
 	iounmap(asus_rcba_base);
 	asus_rcba_base = NULL;
-	dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n");
+	pci_info(dev, "Enabled ICH6/i801 SMBus device\n");
 }
 
 static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
@@ -1433,7 +1430,7 @@ static void quirk_sis_96x_smbus(struct pci_dev *dev)
 	u8 val = 0;
 	pci_read_config_byte(dev, 0x77, &val);
 	if (val & 0x10) {
-		dev_info(&dev->dev, "Enabling SiS 96x SMBus\n");
+		pci_info(dev, "Enabling SiS 96x SMBus\n");
 		pci_write_config_byte(dev, 0x77, val & ~0x10);
 	}
 }
@@ -1505,10 +1502,10 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev)
 		pci_write_config_byte(dev, 0x50, val & (~0xc0));
 		pci_read_config_byte(dev, 0x50, &val);
 		if (val & 0xc0)
-			dev_info(&dev->dev, "Onboard AC97/MC97 devices continue to play 'hide and seek'! 0x%x\n",
+			pci_info(dev, "Onboard AC97/MC97 devices continue to play 'hide and seek'! 0x%x\n",
 				 val);
 		else
-			dev_info(&dev->dev, "Enabled onboard AC97/MC97 devices\n");
+			pci_info(dev, "Enabled onboard AC97/MC97 devices\n");
 	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
@@ -1599,7 +1596,7 @@ static void quirk_jmicron_async_suspend(struct pci_dev *dev)
 {
 	if (dev->multifunction) {
 		device_disable_async_suspend(&dev->dev);
-		dev_info(&dev->dev, "async suspend disabled to avoid multi-function power-on ordering issue\n");
+		pci_info(dev, "async suspend disabled to avoid multi-function power-on ordering issue\n");
 	}
 }
 DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, 8, quirk_jmicron_async_suspend);
@@ -1636,8 +1633,8 @@ static void quirk_pcie_mch(struct pci_dev *pdev)
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7520_MCH,	quirk_pcie_mch);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7320_MCH,	quirk_pcie_mch);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7525_MCH,	quirk_pcie_mch);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI,	0x1610,	quirk_pcie_mch);
 
+DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1610, PCI_CLASS_BRIDGE_PCI, 8, quirk_pcie_mch);
 
 /*
  * It's possible for the MSI to get corrupted if shpc and acpi
@@ -1646,7 +1643,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI,	0x1610,	quirk_pcie_mch);
 static void quirk_pcie_pxh(struct pci_dev *dev)
 {
 	dev->no_msi = 1;
-	dev_warn(&dev->dev, "PXH quirk detected; SHPC device MSI disabled\n");
+	pci_warn(dev, "PXH quirk detected; SHPC device MSI disabled\n");
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXHD_0,	quirk_pcie_pxh);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXHD_1,	quirk_pcie_pxh);
@@ -1692,7 +1689,7 @@ static void quirk_radeon_pm(struct pci_dev *dev)
 	    dev->subsystem_device == 0x00e2) {
 		if (dev->d3_delay < 20) {
 			dev->d3_delay = 20;
-			dev_info(&dev->dev, "extending delay after power-on from D3 to %d msec\n",
+			pci_info(dev, "extending delay after power-on from D3 to %d msec\n",
 				 dev->d3_delay);
 		}
 	}
@@ -1736,7 +1733,7 @@ static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev)
 		return;
 
 	dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT;
-	dev_info(&dev->dev, "rerouting interrupts for [%04x:%04x]\n",
+	pci_info(dev, "rerouting interrupts for [%04x:%04x]\n",
 		 dev->vendor, dev->device);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_80333_0,	quirk_reroute_to_boot_interrupts_intel);
@@ -1779,7 +1776,7 @@ static void quirk_disable_intel_boot_interrupt(struct pci_dev *dev)
 	pci_config_word |= INTEL_6300_DISABLE_BOOT_IRQ;
 	pci_write_config_word(dev, INTEL_6300_IOAPIC_ABAR, pci_config_word);
 
-	dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+	pci_info(dev, "disabled boot interrupts on device [%04x:%04x]\n",
 		 dev->vendor, dev->device);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_ESB_10,	quirk_disable_intel_boot_interrupt);
@@ -1812,7 +1809,7 @@ static void quirk_disable_broadcom_boot_interrupt(struct pci_dev *dev)
 
 	pci_write_config_dword(dev, BC_HT1000_FEATURE_REG, pci_config_dword);
 
-	dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+	pci_info(dev, "disabled boot interrupts on device [%04x:%04x]\n",
 		 dev->vendor, dev->device);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS,   PCI_DEVICE_ID_SERVERWORKS_HT1000SB,	quirk_disable_broadcom_boot_interrupt);
@@ -1845,7 +1842,7 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev)
 	pci_config_dword &= ~AMD_813X_NOIOAMODE;
 	pci_write_config_dword(dev, AMD_813X_MISC, pci_config_dword);
 
-	dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+	pci_info(dev, "disabled boot interrupts on device [%04x:%04x]\n",
 		 dev->vendor, dev->device);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,	PCI_DEVICE_ID_AMD_8131_BRIDGE,	quirk_disable_amd_813x_boot_interrupt);
@@ -1864,12 +1861,12 @@ static void quirk_disable_amd_8111_boot_interrupt(struct pci_dev *dev)
 
 	pci_read_config_word(dev, AMD_8111_PCI_IRQ_ROUTING, &pci_config_word);
 	if (!pci_config_word) {
-		dev_info(&dev->dev, "boot interrupts on device [%04x:%04x] already disabled\n",
+		pci_info(dev, "boot interrupts on device [%04x:%04x] already disabled\n",
 			 dev->vendor, dev->device);
 		return;
 	}
 	pci_write_config_word(dev, AMD_8111_PCI_IRQ_ROUTING, 0);
-	dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+	pci_info(dev, "disabled boot interrupts on device [%04x:%04x]\n",
 		 dev->vendor, dev->device);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8111_SMBUS,	quirk_disable_amd_8111_boot_interrupt);
@@ -1913,7 +1910,7 @@ static void quirk_plx_pci9050(struct pci_dev *dev)
 		if (pci_resource_len(dev, bar) == 0x80 &&
 		    (pci_resource_start(dev, bar) & 0x80)) {
 			struct resource *r = &dev->resource[bar];
-			dev_info(&dev->dev, "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n",
+			pci_info(dev, "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n",
 				 bar);
 			r->flags |= IORESOURCE_UNSET;
 			r->start = 0;
@@ -1960,7 +1957,7 @@ static void quirk_netmos(struct pci_dev *dev)
 	case PCI_DEVICE_ID_NETMOS_9845:
 	case PCI_DEVICE_ID_NETMOS_9855:
 		if (num_parallel) {
-			dev_info(&dev->dev, "Netmos %04x (%u parallel, %u serial); changing class SERIAL to OTHER (use parport_serial)\n",
+			pci_info(dev, "Netmos %04x (%u parallel, %u serial); changing class SERIAL to OTHER (use parport_serial)\n",
 				dev->device, num_parallel, num_serial);
 			dev->class = (PCI_CLASS_COMMUNICATION_OTHER << 8) |
 			    (dev->class & 0xff);
@@ -2046,13 +2043,13 @@ static void quirk_e100_interrupt(struct pci_dev *dev)
 	/* Convert from PCI bus to resource space.  */
 	csr = ioremap(pci_resource_start(dev, 0), 8);
 	if (!csr) {
-		dev_warn(&dev->dev, "Can't map e100 registers\n");
+		pci_warn(dev, "Can't map e100 registers\n");
 		return;
 	}
 
 	cmd_hi = readb(csr + 3);
 	if (cmd_hi == 0) {
-		dev_warn(&dev->dev, "Firmware left e100 interrupts enabled; disabling\n");
+		pci_warn(dev, "Firmware left e100 interrupts enabled; disabling\n");
 		writeb(1, csr + 3);
 	}
 
@@ -2067,7 +2064,7 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
  */
 static void quirk_disable_aspm_l0s(struct pci_dev *dev)
 {
-	dev_info(&dev->dev, "Disabling L0s\n");
+	pci_info(dev, "Disabling L0s\n");
 	pci_disable_link_state(dev, PCIE_LINK_STATE_L0S);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s);
@@ -2097,7 +2094,7 @@ static void fixup_rev1_53c810(struct pci_dev *dev)
 		return;
 
 	dev->class = PCI_CLASS_STORAGE_SCSI << 8;
-	dev_info(&dev->dev, "NCR 53c810 rev 1 PCI class overridden (%#08x -> %#08x)\n",
+	pci_info(dev, "NCR 53c810 rev 1 PCI class overridden (%#08x -> %#08x)\n",
 		 class, dev->class);
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
@@ -2110,7 +2107,7 @@ static void quirk_p64h2_1k_io(struct pci_dev *dev)
 	pci_read_config_word(dev, 0x40, &en1k);
 
 	if (en1k & 0x200) {
-		dev_info(&dev->dev, "Enable I/O Space to 1KB granularity\n");
+		pci_info(dev, "Enable I/O Space to 1KB granularity\n");
 		dev->io_window_1k = 1;
 	}
 }
@@ -2126,7 +2123,7 @@ static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
 	if (pci_read_config_byte(dev, 0xf41, &b) == 0) {
 		if (!(b & 0x20)) {
 			pci_write_config_byte(dev, 0xf41, b | 0x20);
-			dev_info(&dev->dev, "Linking AER extended capability\n");
+			pci_info(dev, "Linking AER extended capability\n");
 		}
 	}
 }
@@ -2164,7 +2161,7 @@ static void quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
 			/* Turn off PCI Bus Parking */
 			pci_write_config_byte(dev, 0x76, b ^ 0x40);
 
-			dev_info(&dev->dev, "Disabling VIA CX700 PCI parking\n");
+			pci_info(dev, "Disabling VIA CX700 PCI parking\n");
 		}
 	}
 
@@ -2179,7 +2176,7 @@ static void quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
 			/* Disable "Read FIFO Timer" */
 			pci_write_config_byte(dev, 0x77, 0x0);
 
-			dev_info(&dev->dev, "Disabling VIA CX700 PCI caching\n");
+			pci_info(dev, "Disabling VIA CX700 PCI caching\n");
 		}
 	}
 }
@@ -2196,7 +2193,7 @@ static void quirk_blacklist_vpd(struct pci_dev *dev)
 {
 	if (dev->vpd) {
 		dev->vpd->len = 0;
-		dev_warn(&dev->dev, FW_BUG "disabling VPD access (can't determine size of non-standard VPD format)\n");
+		pci_warn(dev, FW_BUG "disabling VPD access (can't determine size of non-standard VPD format)\n");
 	}
 }
 
@@ -2312,7 +2309,7 @@ static void quirk_unhide_mch_dev6(struct pci_dev *dev)
 	u8 reg;
 
 	if (pci_read_config_byte(dev, 0xF4, &reg) == 0 && !(reg & 0x02)) {
-		dev_info(&dev->dev, "Enabling MCH 'Overflow' Device\n");
+		pci_info(dev, "Enabling MCH 'Overflow' Device\n");
 		pci_write_config_byte(dev, 0xF4, reg | 0x02);
 	}
 }
@@ -2351,7 +2348,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1);
 static void quirk_disable_all_msi(struct pci_dev *dev)
 {
 	pci_no_msi();
-	dev_warn(&dev->dev, "MSI quirk detected; MSI disabled\n");
+	pci_warn(dev, "MSI quirk detected; MSI disabled\n");
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi);
@@ -2366,7 +2363,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, 0x0761, quirk_disable_all_msi);
 static void quirk_disable_msi(struct pci_dev *dev)
 {
 	if (dev->subordinate) {
-		dev_warn(&dev->dev, "MSI quirk detected; subordinate MSI disabled\n");
+		pci_warn(dev, "MSI quirk detected; subordinate MSI disabled\n");
 		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
 	}
 }
@@ -2406,7 +2403,7 @@ static int msi_ht_cap_enabled(struct pci_dev *dev)
 
 		if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
 					 &flags) == 0) {
-			dev_info(&dev->dev, "Found %s HT MSI Mapping\n",
+			pci_info(dev, "Found %s HT MSI Mapping\n",
 				flags & HT_MSI_FLAGS_ENABLE ?
 				"enabled" : "disabled");
 			return (flags & HT_MSI_FLAGS_ENABLE) != 0;
@@ -2422,7 +2419,7 @@ static int msi_ht_cap_enabled(struct pci_dev *dev)
 static void quirk_msi_ht_cap(struct pci_dev *dev)
 {
 	if (dev->subordinate && !msi_ht_cap_enabled(dev)) {
-		dev_warn(&dev->dev, "MSI quirk detected; subordinate MSI disabled\n");
+		pci_warn(dev, "MSI quirk detected; subordinate MSI disabled\n");
 		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
 	}
 }
@@ -2446,7 +2443,7 @@ static void quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
 	if (!pdev)
 		return;
 	if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
-		dev_warn(&dev->dev, "MSI quirk detected; subordinate MSI disabled\n");
+		pci_warn(dev, "MSI quirk detected; subordinate MSI disabled\n");
 		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
 	}
 	pci_dev_put(pdev);
@@ -2465,7 +2462,7 @@ static void ht_enable_msi_mapping(struct pci_dev *dev)
 
 		if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
 					 &flags) == 0) {
-			dev_info(&dev->dev, "Enabling HT MSI Mapping\n");
+			pci_info(dev, "Enabling HT MSI Mapping\n");
 
 			pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
 					      flags | HT_MSI_FLAGS_ENABLE);
@@ -2492,7 +2489,7 @@ static void nvenet_msi_disable(struct pci_dev *dev)
 	if (board_name &&
 	    (strstr(board_name, "P5N32-SLI PREMIUM") ||
 	     strstr(board_name, "P5N32-E SLI"))) {
-		dev_info(&dev->dev, "Disabling msi for MCP55 NIC on P5N32-SLI\n");
+		pci_info(dev, "Disabling MSI for MCP55 NIC on P5N32-SLI\n");
 		dev->no_msi = 1;
 	}
 }
@@ -2669,7 +2666,7 @@ static void ht_disable_msi_mapping(struct pci_dev *dev)
 
 		if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
 					 &flags) == 0) {
-			dev_info(&dev->dev, "Disabling HT MSI Mapping\n");
+			pci_info(dev, "Disabling HT MSI Mapping\n");
 
 			pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
 					      flags & ~HT_MSI_FLAGS_ENABLE);
@@ -2699,9 +2696,10 @@ static void __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all)
 	 * HT MSI mapping should be disabled on devices that are below
 	 * a non-Hypertransport host bridge. Locate the host bridge...
 	 */
-	host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+	host_bridge = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus), 0,
+						  PCI_DEVFN(0, 0));
 	if (host_bridge == NULL) {
-		dev_warn(&dev->dev, "nv_msi_ht_cap_quirk didn't locate host bridge\n");
+		pci_warn(dev, "nv_msi_ht_cap_quirk didn't locate host bridge\n");
 		return;
 	}
 
@@ -2770,7 +2768,7 @@ static void quirk_msi_intx_disable_qca_bug(struct pci_dev *dev)
 {
 	/* AR816X/AR817X/E210X MSI is fixed at HW level from revision 0x18 */
 	if (dev->revision < 0x18) {
-		dev_info(&dev->dev, "set MSI_INTX_DISABLE_BUG flag\n");
+		pci_info(dev, "set MSI_INTX_DISABLE_BUG flag\n");
 		dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;
 	}
 }
@@ -2899,8 +2897,8 @@ static void ricoh_mmc_fixup_rl5c476(struct pci_dev *dev)
 	pci_write_config_byte(dev, 0x8E, write_enable);
 	pci_write_config_byte(dev, 0x8D, write_target);
 
-	dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n");
-	dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+	pci_notice(dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n");
+	pci_notice(dev, "MMC cards are now supported by standard SDHCI controller\n");
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476);
 DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476);
@@ -2935,7 +2933,7 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev)
 		pci_write_config_byte(dev, 0xe1, 0x32);
 		pci_write_config_byte(dev, 0xfc, 0x00);
 
-		dev_notice(&dev->dev, "MMC controller base frequency changed to 50Mhz.\n");
+		pci_notice(dev, "MMC controller base frequency changed to 50Mhz.\n");
 	}
 
 	pci_read_config_byte(dev, 0xCB, &disable);
@@ -2948,8 +2946,8 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev)
 	pci_write_config_byte(dev, 0xCB, disable | 0x02);
 	pci_write_config_byte(dev, 0xCA, write_enable);
 
-	dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
-	dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+	pci_notice(dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
+	pci_notice(dev, "MMC cards are now supported by standard SDHCI controller\n");
 
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
@@ -2990,7 +2988,7 @@ static void fixup_ti816x_class(struct pci_dev *dev)
 
 	/* TI 816x devices do not have class code set when in PCIe boot mode */
 	dev->class = PCI_CLASS_MULTIMEDIA_VIDEO << 8;
-	dev_info(&dev->dev, "PCI class overridden (%#08x -> %#08x)\n",
+	pci_info(dev, "PCI class overridden (%#08x -> %#08x)\n",
 		 class, dev->class);
 }
 DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_TI, 0xb800,
@@ -3032,7 +3030,7 @@ static void quirk_intel_mc_errata(struct pci_dev *dev)
 	 */
 	err = pci_read_config_word(dev, 0x48, &rcc);
 	if (err) {
-		dev_err(&dev->dev, "Error attempting to read the read completion coalescing register\n");
+		pci_err(dev, "Error attempting to read the read completion coalescing register\n");
 		return;
 	}
 
@@ -3043,7 +3041,7 @@ static void quirk_intel_mc_errata(struct pci_dev *dev)
 
 	err = pci_write_config_word(dev, 0x48, rcc);
 	if (err) {
-		dev_err(&dev->dev, "Error attempting to write the read completion coalescing register\n");
+		pci_err(dev, "Error attempting to write the read completion coalescing register\n");
 		return;
 	}
 
@@ -3108,7 +3106,7 @@ static ktime_t fixup_debug_start(struct pci_dev *dev,
 {
 	ktime_t calltime = 0;
 
-	dev_dbg(&dev->dev, "calling %pF\n", fn);
+	pci_dbg(dev, "calling %pF\n", fn);
 	if (initcall_debug) {
 		pr_debug("calling  %pF @ %i for %s\n",
 			 fn, task_pid_nr(current), dev_name(&dev->dev));
@@ -3150,13 +3148,13 @@ static void disable_igfx_irq(struct pci_dev *dev)
 {
 	void __iomem *regs = pci_iomap(dev, 0, 0);
 	if (regs == NULL) {
-		dev_warn(&dev->dev, "igfx quirk: Can't iomap PCI device\n");
+		pci_warn(dev, "igfx quirk: Can't iomap PCI device\n");
 		return;
 	}
 
 	/* Check if any interrupt line is still enabled */
 	if (readl(regs + I915_DEIER_REG) != 0) {
-		dev_warn(&dev->dev, "BIOS left Intel GPU interrupts enabled; disabling\n");
+		pci_warn(dev, "BIOS left Intel GPU interrupts enabled; disabling\n");
 
 		writel(0, regs + I915_DEIER_REG);
 	}
@@ -3215,6 +3213,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x0030,
 			quirk_broken_intx_masking);
 DECLARE_PCI_FIXUP_FINAL(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */
 			quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(0x1b7c, 0x0004, /* Ceton InfiniTV4 */
+			quirk_broken_intx_masking);
 
 /*
  * Realtek RTL8169 PCI Gigabit Ethernet Controller (rev 10)
@@ -3317,13 +3317,13 @@ static void mellanox_check_broken_intx_masking(struct pci_dev *pdev)
 
 	/* For ConnectX-4 and ConnectX-4LX, need to check FW support */
 	if (pci_enable_device_mem(pdev)) {
-		dev_warn(&pdev->dev, "Can't enable device memory\n");
+		pci_warn(pdev, "Can't enable device memory\n");
 		return;
 	}
 
 	fw_ver = ioremap(pci_resource_start(pdev, 0), 4);
 	if (!fw_ver) {
-		dev_warn(&pdev->dev, "Can't map ConnectX-4 initialization segment\n");
+		pci_warn(pdev, "Can't map ConnectX-4 initialization segment\n");
 		goto out;
 	}
 
@@ -3335,7 +3335,7 @@ static void mellanox_check_broken_intx_masking(struct pci_dev *pdev)
 	fw_subminor = fw_sub_min & 0xffff;
 	if (fw_minor > CONNECTX_4_CURR_MAX_MINOR ||
 	    fw_minor < CONNECTX_4_INTX_SUPPORT_MINOR) {
-		dev_warn(&pdev->dev, "ConnectX-4: FW %u.%u.%u doesn't support INTx masking, disabling. Please upgrade FW to %d.14.1100 and up for INTx support\n",
+		pci_warn(pdev, "ConnectX-4: FW %u.%u.%u doesn't support INTx masking, disabling. Please upgrade FW to %d.14.1100 and up for INTx support\n",
 			 fw_major, fw_minor, fw_subminor, pdev->device ==
 			 PCI_DEVICE_ID_MELLANOX_CONNECTX4 ? 12 : 14);
 		pdev->broken_intx_masking = 1;
@@ -3473,7 +3473,7 @@ static void quirk_apple_poweroff_thunderbolt(struct pci_dev *dev)
 	    || ACPI_FAILURE(acpi_get_handle(bridge, "DSB0.NHI0.SXFP", &SXFP))
 	    || ACPI_FAILURE(acpi_get_handle(bridge, "DSB0.NHI0.SXLV", &SXLV)))
 		return;
-	dev_info(&dev->dev, "quirk: cutting power to thunderbolt controller...\n");
+	pci_info(dev, "quirk: cutting power to thunderbolt controller...\n");
 
 	/* magic sequence */
 	acpi_execute_simple_method(SXIO, NULL, 1);
@@ -3524,7 +3524,7 @@ static void quirk_apple_wait_for_thunderbolt(struct pci_dev *dev)
 			nhi->device != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI)
 		    || nhi->class != PCI_CLASS_SYSTEM_OTHER << 8)
 		goto out;
-	dev_info(&dev->dev, "quirk: waiting for thunderbolt to reestablish PCI tunnels...\n");
+	pci_info(dev, "quirk: waiting for thunderbolt to reestablish PCI tunnels...\n");
 	device_pm_wait_for_dev(&dev->dev, &nhi->dev);
 out:
 	pci_dev_put(nhi);
@@ -3740,7 +3740,7 @@ static int reset_ivb_igd(struct pci_dev *dev, int probe)
 			goto reset_complete;
 		msleep(10);
 	} while (time_before(jiffies, timeout));
-	dev_warn(&dev->dev, "timeout during reset\n");
+	pci_warn(dev, "timeout during reset\n");
 
 reset_complete:
 	iowrite32(0x00000002, mmio_base + NSDE_PWR_STATE);
@@ -3879,6 +3879,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9120,
 			 quirk_dma_func1_alias);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9123,
 			 quirk_dma_func1_alias);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9128,
+			 quirk_dma_func1_alias);
 /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9130,
 			 quirk_dma_func1_alias);
@@ -4012,7 +4014,7 @@ static void quirk_tw686x_class(struct pci_dev *pdev)
 
 	/* Use "Multimedia controller" class */
 	pdev->class = (PCI_CLASS_MULTIMEDIA_OTHER << 8) | 0x01;
-	dev_info(&pdev->dev, "TW686x PCI class overridden (%#08x -> %#08x)\n",
+	pci_info(pdev, "TW686x PCI class overridden (%#08x -> %#08x)\n",
 		 class, pdev->class);
 }
 DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6864, PCI_CLASS_NOT_DEFINED, 8,
@@ -4032,7 +4034,7 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6869, PCI_CLASS_NOT_DEFINED, 8,
 static void quirk_relaxedordering_disable(struct pci_dev *dev)
 {
 	dev->dev_flags |= PCI_DEV_FLAGS_NO_RELAXED_ORDERING;
-	dev_info(&dev->dev, "Disable Relaxed Ordering Attributes to avoid PCIe Completion erratum\n");
+	pci_info(dev, "Disable Relaxed Ordering Attributes to avoid PCIe Completion erratum\n");
 }
 
 /*
@@ -4141,11 +4143,11 @@ static void quirk_disable_root_port_attributes(struct pci_dev *pdev)
 	struct pci_dev *root_port = pci_find_pcie_root_port(pdev);
 
 	if (!root_port) {
-		dev_warn(&pdev->dev, "PCIe Completion erratum may cause device errors\n");
+		pci_warn(pdev, "PCIe Completion erratum may cause device errors\n");
 		return;
 	}
 
-	dev_info(&root_port->dev, "Disabling No Snoop/Relaxed Ordering Attributes to avoid PCIe Completion erratum in %s\n",
+	pci_info(root_port, "Disabling No Snoop/Relaxed Ordering Attributes to avoid PCIe Completion erratum in %s\n",
 		 dev_name(&pdev->dev));
 	pcie_capability_clear_and_set_word(root_port, PCI_EXP_DEVCTL,
 					   PCI_EXP_DEVCTL_RELAX_EN |
@@ -4339,7 +4341,7 @@ static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags)
 	u16 flags = (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV);
 	int ret = acs_flags & ~flags ? 0 : 1;
 
-	dev_info(&dev->dev, "Using QCOM ACS Quirk (%d)\n", ret);
+	pci_info(dev, "Using QCOM ACS Quirk (%d)\n", ret);
 
 	return ret;
 }
@@ -4591,7 +4593,7 @@ static int pci_quirk_enable_intel_lpc_acs(struct pci_dev *dev)
 	if (bspr != (INTEL_BSPR_REG_BPNPD | INTEL_BSPR_REG_BPPD)) {
 		updcr = readl(rcba_mem + INTEL_UPDCR_REG);
 		if (updcr & INTEL_UPDCR_REG_MASK) {
-			dev_info(&dev->dev, "Disabling UPDCR peer decodes\n");
+			pci_info(dev, "Disabling UPDCR peer decodes\n");
 			updcr &= ~INTEL_UPDCR_REG_MASK;
 			writel(updcr, rcba_mem + INTEL_UPDCR_REG);
 		}
@@ -4618,7 +4620,7 @@ static void pci_quirk_enable_intel_rp_mpc_acs(struct pci_dev *dev)
 	 */
 	pci_read_config_dword(dev, INTEL_MPC_REG, &mpc);
 	if (!(mpc & INTEL_MPC_REG_IRBNCE)) {
-		dev_info(&dev->dev, "Enabling MPC IRBNCE\n");
+		pci_info(dev, "Enabling MPC IRBNCE\n");
 		mpc |= INTEL_MPC_REG_IRBNCE;
 		pci_write_config_word(dev, INTEL_MPC_REG, mpc);
 	}
@@ -4630,7 +4632,7 @@ static int pci_quirk_enable_intel_pch_acs(struct pci_dev *dev)
 		return -ENOTTY;
 
 	if (pci_quirk_enable_intel_lpc_acs(dev)) {
-		dev_warn(&dev->dev, "Failed to enable Intel PCH ACS quirk\n");
+		pci_warn(dev, "Failed to enable Intel PCH ACS quirk\n");
 		return 0;
 	}
 
@@ -4638,7 +4640,7 @@ static int pci_quirk_enable_intel_pch_acs(struct pci_dev *dev)
 
 	dev->dev_flags |= PCI_DEV_FLAGS_ACS_ENABLED_QUIRK;
 
-	dev_info(&dev->dev, "Intel PCH root port ACS workaround enabled\n");
+	pci_info(dev, "Intel PCH root port ACS workaround enabled\n");
 
 	return 0;
 }
@@ -4665,7 +4667,7 @@ static int pci_quirk_enable_intel_spt_pch_acs(struct pci_dev *dev)
 
 	pci_write_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, ctrl);
 
-	dev_info(&dev->dev, "Intel SPT PCH root port ACS workaround enabled\n");
+	pci_info(dev, "Intel SPT PCH root port ACS workaround enabled\n");
 
 	return 0;
 }
@@ -4800,7 +4802,7 @@ static void quirk_no_ext_tags(struct pci_dev *pdev)
 		return;
 
 	bridge->no_ext_tags = 1;
-	dev_info(&pdev->dev, "disabling Extended Tags (this device can't handle them)\n");
+	pci_info(pdev, "disabling Extended Tags (this device can't handle them)\n");
 
 	pci_walk_bus(bridge->bus, pci_configure_extended_tags, NULL);
 }
@@ -4815,7 +4817,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0144, quirk_no_ext_tags);
  */
 static void quirk_no_ats(struct pci_dev *pdev)
 {
-	dev_info(&pdev->dev, "disabling ATS (broken on this device)\n");
+	pci_info(pdev, "disabling ATS (broken on this device)\n");
 	pdev->ats_cap = 0;
 }
 
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 2fa0dbd..6f072ea 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/pci-aspm.h>
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 1f5e6af..374a334 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * drivers/pci/rom.c
  *
@@ -92,15 +93,15 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
 		void __iomem *pds;
 		/* Standard PCI ROMs start out with these bytes 55 AA */
 		if (readw(image) != 0xAA55) {
-			dev_err(&pdev->dev, "Invalid PCI ROM header signature: expecting 0xaa55, got %#06x\n",
-				readw(image));
+			pci_info(pdev, "Invalid PCI ROM header signature: expecting 0xaa55, got %#06x\n",
+				 readw(image));
 			break;
 		}
 		/* get the PCI data structure and check its "PCIR" signature */
 		pds = image + readw(image + 24);
 		if (readl(pds) != 0x52494350) {
-			dev_err(&pdev->dev, "Invalid PCI ROM data signature: expecting 0x52494350, got %#010x\n",
-				readl(pds));
+			pci_info(pdev, "Invalid PCI ROM data signature: expecting 0x52494350, got %#010x\n",
+				 readl(pds));
 			break;
 		}
 		last_image = readb(pds + 21) & 0x80;
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 4c6044a..bc1e023 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *	PCI searching functions.
  *
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index b1ad466..3cce29a 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *	drivers/pci/setup-bus.c
  *
@@ -67,10 +68,8 @@ static int add_to_list(struct list_head *head,
 	struct pci_dev_resource *tmp;
 
 	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
-	if (!tmp) {
-		pr_warn("add_to_list: kmalloc() failed!\n");
+	if (!tmp)
 		return -ENOMEM;
-	}
 
 	tmp->res = res;
 	tmp->dev = dev;
@@ -152,7 +151,7 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
 
 		r_align = pci_resource_alignment(dev, r);
 		if (!r_align) {
-			dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n",
+			pci_warn(dev, "BAR %d: %pR has bogus alignment\n",
 				 i, r);
 			continue;
 		}
@@ -260,7 +259,7 @@ static void reassign_resources_sorted(struct list_head *realloc_head,
 				 (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN);
 			if (pci_reassign_resource(add_res->dev, idx,
 						  add_size, align))
-				dev_printk(KERN_DEBUG, &add_res->dev->dev,
+				pci_printk(KERN_DEBUG, add_res->dev,
 					   "failed to add %llx res[%d]=%pR\n",
 					   (unsigned long long)add_size,
 					   idx, res);
@@ -519,7 +518,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
 	struct resource *res;
 	struct pci_bus_region region;
 
-	dev_info(&bridge->dev, "CardBus bridge to %pR\n",
+	pci_info(bridge, "CardBus bridge to %pR\n",
 		 &bus->busn_res);
 
 	res = bus->resource[0];
@@ -529,7 +528,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
 		 * The IO resource is allocated a range twice as large as it
 		 * would normally need.  This allows us to set both IO regs.
 		 */
-		dev_info(&bridge->dev, "  bridge window %pR\n", res);
+		pci_info(bridge, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
@@ -539,7 +538,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
 	res = bus->resource[1];
 	pcibios_resource_to_bus(bridge->bus, &region, res);
 	if (res->flags & IORESOURCE_IO) {
-		dev_info(&bridge->dev, "  bridge window %pR\n", res);
+		pci_info(bridge, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
@@ -549,7 +548,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
 	res = bus->resource[2];
 	pcibios_resource_to_bus(bridge->bus, &region, res);
 	if (res->flags & IORESOURCE_MEM) {
-		dev_info(&bridge->dev, "  bridge window %pR\n", res);
+		pci_info(bridge, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
@@ -559,7 +558,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
 	res = bus->resource[3];
 	pcibios_resource_to_bus(bridge->bus, &region, res);
 	if (res->flags & IORESOURCE_MEM) {
-		dev_info(&bridge->dev, "  bridge window %pR\n", res);
+		pci_info(bridge, "  bridge window %pR\n", res);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
 					region.start);
 		pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
@@ -602,7 +601,7 @@ static void pci_setup_bridge_io(struct pci_dev *bridge)
 		l = ((u16) io_limit_lo << 8) | io_base_lo;
 		/* Set up upper 16 bits of I/O base/limit. */
 		io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
-		dev_info(&bridge->dev, "  bridge window %pR\n", res);
+		pci_info(bridge, "  bridge window %pR\n", res);
 	} else {
 		/* Clear upper 16 bits of I/O base/limit. */
 		io_upper16 = 0;
@@ -628,7 +627,7 @@ static void pci_setup_bridge_mmio(struct pci_dev *bridge)
 	if (res->flags & IORESOURCE_MEM) {
 		l = (region.start >> 16) & 0xfff0;
 		l |= region.end & 0xfff00000;
-		dev_info(&bridge->dev, "  bridge window %pR\n", res);
+		pci_info(bridge, "  bridge window %pR\n", res);
 	} else {
 		l = 0x0000fff0;
 	}
@@ -657,7 +656,7 @@ static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge)
 			bu = upper_32_bits(region.start);
 			lu = upper_32_bits(region.end);
 		}
-		dev_info(&bridge->dev, "  bridge window %pR\n", res);
+		pci_info(bridge, "  bridge window %pR\n", res);
 	} else {
 		l = 0x0000fff0;
 	}
@@ -672,7 +671,7 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type)
 {
 	struct pci_dev *bridge = bus->self;
 
-	dev_info(&bridge->dev, "PCI bridge to %pR\n",
+	pci_info(bridge, "PCI bridge to %pR\n",
 		 &bus->busn_res);
 
 	if (type & IORESOURCE_IO)
@@ -944,7 +943,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
 			resource_size(b_res), min_align);
 	if (!size0 && !size1) {
 		if (b_res->start || b_res->end)
-			dev_info(&bus->self->dev, "disabling bridge window %pR to %pR (unused)\n",
+			pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n",
 				 b_res, &bus->busn_res);
 		b_res->flags = 0;
 		return;
@@ -956,7 +955,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
 	if (size1 > size0 && realloc_head) {
 		add_to_list(realloc_head, bus->self, b_res, size1-size0,
 			    min_align);
-		dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window %pR to %pR add_size %llx\n",
+		pci_printk(KERN_DEBUG, bus->self, "bridge window %pR to %pR add_size %llx\n",
 			   b_res, &bus->busn_res,
 			   (unsigned long long)size1-size0);
 	}
@@ -1061,7 +1060,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 			if (order < 0)
 				order = 0;
 			if (order >= ARRAY_SIZE(aligns)) {
-				dev_warn(&dev->dev, "disabling BAR %d: %pR (bad alignment %#llx)\n",
+				pci_warn(dev, "disabling BAR %d: %pR (bad alignment %#llx)\n",
 					 i, r, (unsigned long long) align);
 				r->flags = 0;
 				continue;
@@ -1093,7 +1092,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 				resource_size(b_res), add_align);
 	if (!size0 && !size1) {
 		if (b_res->start || b_res->end)
-			dev_info(&bus->self->dev, "disabling bridge window %pR to %pR (unused)\n",
+			pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n",
 				 b_res, &bus->busn_res);
 		b_res->flags = 0;
 		return 0;
@@ -1103,7 +1102,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 	b_res->flags |= IORESOURCE_STARTALIGN;
 	if (size1 > size0 && realloc_head) {
 		add_to_list(realloc_head, bus->self, b_res, size1-size0, add_align);
-		dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window %pR to %pR add_size %llx add_align %llx\n",
+		pci_printk(KERN_DEBUG, bus->self, "bridge window %pR to %pR add_size %llx add_align %llx\n",
 			   b_res, &bus->busn_res,
 			   (unsigned long long) (size1 - size0),
 			   (unsigned long long) add_align);
@@ -1407,7 +1406,7 @@ void __pci_bus_assign_resources(const struct pci_bus *bus,
 			break;
 
 		default:
-			dev_info(&dev->dev, "not setting up bridge for bus %04x:%02x\n",
+			pci_info(dev, "not setting up bridge for bus %04x:%02x\n",
 				 pci_domain_nr(b), b->number);
 			break;
 		}
@@ -1513,7 +1512,7 @@ static void __pci_bridge_assign_resources(const struct pci_dev *bridge,
 		break;
 
 	default:
-		dev_info(&bridge->dev, "not setting up bridge for bus %04x:%02x\n",
+		pci_info(bridge, "not setting up bridge for bus %04x:%02x\n",
 			 pci_domain_nr(b), b->number);
 		break;
 	}
@@ -1571,7 +1570,7 @@ static void pci_bridge_release_resources(struct pci_bus *bus,
 	release_child_resources(r);
 	if (!release_resource(r)) {
 		type = old_flags = r->flags & PCI_RES_TYPE_MASK;
-		dev_printk(KERN_DEBUG, &dev->dev, "resource %d %pR released\n",
+		pci_printk(KERN_DEBUG, dev, "resource %d %pR released\n",
 					PCI_BRIDGE_RESOURCES + idx, r);
 		/* keep the old size */
 		r->end = resource_size(r) - 1;
@@ -1874,7 +1873,7 @@ static void extend_bridge_window(struct pci_dev *bridge, struct resource *res,
 		return;
 
 	dev_res->add_size = available - resource_size(res);
-	dev_dbg(&bridge->dev, "bridge window %pR extended by %pa\n", res,
+	pci_dbg(bridge, "bridge window %pR extended by %pa\n", res,
 		&dev_res->add_size);
 }
 
@@ -2085,7 +2084,7 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
 enable_all:
 	retval = pci_reenable_device(bridge);
 	if (retval)
-		dev_err(&bridge->dev, "Error reenabling bridge (%d)\n", retval);
+		pci_err(bridge, "Error reenabling bridge (%d)\n", retval);
 	pci_set_master(bridge);
 }
 EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
@@ -2119,7 +2118,7 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
 			if (ret)
 				goto cleanup;
 
-			dev_info(&bridge->dev, "BAR %d: releasing %pR\n",
+			pci_info(bridge, "BAR %d: releasing %pR\n",
 				 i, res);
 
 			if (res->parent)
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index 86106c4..5ad4ee7 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  *	drivers/pci/setup-irq.c
  *
@@ -25,7 +26,7 @@ void pci_assign_irq(struct pci_dev *dev)
 	struct pci_host_bridge *hbrg = pci_find_host_bridge(dev->bus);
 
 	if (!(hbrg->map_irq)) {
-		dev_dbg(&dev->dev, "runtime IRQ mapping not provided by arch\n");
+		pci_dbg(dev, "runtime IRQ mapping not provided by arch\n");
 		return;
 	}
 
@@ -55,7 +56,7 @@ void pci_assign_irq(struct pci_dev *dev)
 	}
 	dev->irq = irq;
 
-	dev_dbg(&dev->dev, "assign IRQ: got %d\n", dev->irq);
+	pci_dbg(dev, "assign IRQ: got %d\n", dev->irq);
 
 	/* Always tell the device, so the driver knows what is
 	   the real IRQ to use; the device does not use it. */
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index e815111..369d48d 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -103,7 +103,7 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno)
 	pci_read_config_dword(dev, reg, &check);
 
 	if ((new ^ check) & mask) {
-		dev_err(&dev->dev, "BAR %d: error updating (%#08x != %#08x)\n",
+		pci_err(dev, "BAR %d: error updating (%#08x != %#08x)\n",
 			resno, new, check);
 	}
 
@@ -112,7 +112,7 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno)
 		pci_write_config_dword(dev, reg + 4, new);
 		pci_read_config_dword(dev, reg + 4, &check);
 		if (check != new) {
-			dev_err(&dev->dev, "BAR %d: error updating (high %#08x != %#08x)\n",
+			pci_err(dev, "BAR %d: error updating (high %#08x != %#08x)\n",
 				resno, new, check);
 		}
 	}
@@ -137,7 +137,7 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
 	struct resource *root, *conflict;
 
 	if (res->flags & IORESOURCE_UNSET) {
-		dev_info(&dev->dev, "can't claim BAR %d %pR: no address assigned\n",
+		pci_info(dev, "can't claim BAR %d %pR: no address assigned\n",
 			 resource, res);
 		return -EINVAL;
 	}
@@ -152,7 +152,7 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
 
 	root = pci_find_parent_resource(dev, res);
 	if (!root) {
-		dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n",
+		pci_info(dev, "can't claim BAR %d %pR: no compatible bridge window\n",
 			 resource, res);
 		res->flags |= IORESOURCE_UNSET;
 		return -EINVAL;
@@ -160,7 +160,7 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
 
 	conflict = request_resource_conflict(root, res);
 	if (conflict) {
-		dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
+		pci_info(dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
 			 resource, res, conflict->name, conflict);
 		res->flags |= IORESOURCE_UNSET;
 		return -EBUSY;
@@ -172,7 +172,7 @@ EXPORT_SYMBOL(pci_claim_resource);
 
 void pci_disable_bridge_window(struct pci_dev *dev)
 {
-	dev_info(&dev->dev, "disabling bridge mem windows\n");
+	pci_info(dev, "disabling bridge mem windows\n");
 
 	/* MMIO Base/Limit */
 	pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
@@ -221,11 +221,11 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
 			root = &iomem_resource;
 	}
 
-	dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n",
+	pci_info(dev, "BAR %d: trying firmware assignment %pR\n",
 		 resno, res);
 	conflict = request_resource_conflict(root, res);
 	if (conflict) {
-		dev_info(&dev->dev, "BAR %d: %pR conflicts with %s %pR\n",
+		pci_info(dev, "BAR %d: %pR conflicts with %s %pR\n",
 			 resno, res, conflict->name, conflict);
 		res->start = start;
 		res->end = end;
@@ -324,7 +324,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
 	res->flags |= IORESOURCE_UNSET;
 	align = pci_resource_alignment(dev, res);
 	if (!align) {
-		dev_info(&dev->dev, "BAR %d: can't assign %pR (bogus alignment)\n",
+		pci_info(dev, "BAR %d: can't assign %pR (bogus alignment)\n",
 			 resno, res);
 		return -EINVAL;
 	}
@@ -338,19 +338,18 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
 	 * working, which is better than just leaving it disabled.
 	 */
 	if (ret < 0) {
-		dev_info(&dev->dev, "BAR %d: no space for %pR\n", resno, res);
+		pci_info(dev, "BAR %d: no space for %pR\n", resno, res);
 		ret = pci_revert_fw_address(res, dev, resno, size);
 	}
 
 	if (ret < 0) {
-		dev_info(&dev->dev, "BAR %d: failed to assign %pR\n", resno,
-			 res);
+		pci_info(dev, "BAR %d: failed to assign %pR\n", resno, res);
 		return ret;
 	}
 
 	res->flags &= ~IORESOURCE_UNSET;
 	res->flags &= ~IORESOURCE_STARTALIGN;
-	dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
+	pci_info(dev, "BAR %d: assigned %pR\n", resno, res);
 	if (resno < PCI_BRIDGE_RESOURCES)
 		pci_update_resource(dev, resno);
 
@@ -372,7 +371,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
 	flags = res->flags;
 	res->flags |= IORESOURCE_UNSET;
 	if (!res->parent) {
-		dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR\n",
+		pci_info(dev, "BAR %d: can't reassign an unassigned resource %pR\n",
 			 resno, res);
 		return -EINVAL;
 	}
@@ -382,14 +381,14 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
 	ret = _pci_assign_resource(dev, resno, new_size, min_align);
 	if (ret) {
 		res->flags = flags;
-		dev_info(&dev->dev, "BAR %d: %pR (failed to expand by %#llx)\n",
+		pci_info(dev, "BAR %d: %pR (failed to expand by %#llx)\n",
 			 resno, res, (unsigned long long) addsize);
 		return ret;
 	}
 
 	res->flags &= ~IORESOURCE_UNSET;
 	res->flags &= ~IORESOURCE_STARTALIGN;
-	dev_info(&dev->dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
+	pci_info(dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
 		 resno, res, (unsigned long long) addsize);
 	if (resno < PCI_BRIDGE_RESOURCES)
 		pci_update_resource(dev, resno);
@@ -401,7 +400,7 @@ void pci_release_resource(struct pci_dev *dev, int resno)
 {
 	struct resource *res = dev->resource + resno;
 
-	dev_info(&dev->dev, "BAR %d: releasing %pR\n", resno, res);
+	pci_info(dev, "BAR %d: releasing %pR\n", resno, res);
 	release_resource(res);
 	res->end = resource_size(res) - 1;
 	res->start = 0;
@@ -477,13 +476,13 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
 			continue;
 
 		if (r->flags & IORESOURCE_UNSET) {
-			dev_err(&dev->dev, "can't enable device: BAR %d %pR not assigned\n",
+			pci_err(dev, "can't enable device: BAR %d %pR not assigned\n",
 				i, r);
 			return -EINVAL;
 		}
 
 		if (!r->parent) {
-			dev_err(&dev->dev, "can't enable device: BAR %d %pR not claimed\n",
+			pci_err(dev, "can't enable device: BAR %d %pR not claimed\n",
 				i, r);
 			return -EINVAL;
 		}
@@ -495,8 +494,7 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
 	}
 
 	if (cmd != old_cmd) {
-		dev_info(&dev->dev, "enabling device (%04x -> %04x)\n",
-			 old_cmd, cmd);
+		pci_info(dev, "enabling device (%04x -> %04x)\n", old_cmd, cmd);
 		pci_write_config_word(dev, PCI_COMMAND, cmd);
 	}
 	return 0;
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index e429095..d10f556 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * drivers/pci/slot.c
  * Copyright (C) 2006 Matthew Wilcox <matthew@wil.cx>
diff --git a/drivers/pci/switch/Kconfig b/drivers/pci/switch/Kconfig
index 4c49648..aee28a5 100644
--- a/drivers/pci/switch/Kconfig
+++ b/drivers/pci/switch/Kconfig
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
 menu "PCI switch controller drivers"
 	depends on PCI
 
diff --git a/drivers/pci/switch/Makefile b/drivers/pci/switch/Makefile
index 37d8cfb..acd56d3 100644
--- a/drivers/pci/switch/Makefile
+++ b/drivers/pci/switch/Makefile
@@ -1 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_PCI_SW_SWITCHTEC) += switchtec.o
diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index fab143a..a60c0ab 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -1,16 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Microsemi Switchtec(tm) PCIe Management Driver
  * Copyright (c) 2017, Microsemi Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
  */
 
 #include <linux/switchtec.h>
@@ -707,6 +698,7 @@ static const struct event_reg {
 	EV_GLB(SWITCHTEC_IOCTL_EVENT_CLI_MRPC_COMP_ASYNC,
 	       cli_mrpc_comp_async_hdr),
 	EV_GLB(SWITCHTEC_IOCTL_EVENT_GPIO_INT, gpio_interrupt_hdr),
+	EV_GLB(SWITCHTEC_IOCTL_EVENT_GFMS, gfms_event_hdr),
 	EV_PAR(SWITCHTEC_IOCTL_EVENT_PART_RESET, part_reset_hdr),
 	EV_PAR(SWITCHTEC_IOCTL_EVENT_MRPC_COMP, mrpc_comp_hdr),
 	EV_PAR(SWITCHTEC_IOCTL_EVENT_MRPC_COMP_ASYNC, mrpc_comp_async_hdr),
@@ -1352,6 +1344,8 @@ static const struct pci_device_id switchtec_pci_tbl[] = {
 	SWITCHTEC_PCI_DEVICE(0x8534),  //PFX 64xG3
 	SWITCHTEC_PCI_DEVICE(0x8535),  //PFX 80xG3
 	SWITCHTEC_PCI_DEVICE(0x8536),  //PFX 96xG3
+	SWITCHTEC_PCI_DEVICE(0x8541),  //PSX 24xG3
+	SWITCHTEC_PCI_DEVICE(0x8542),  //PSX 32xG3
 	SWITCHTEC_PCI_DEVICE(0x8543),  //PSX 48xG3
 	SWITCHTEC_PCI_DEVICE(0x8544),  //PSX 64xG3
 	SWITCHTEC_PCI_DEVICE(0x8545),  //PSX 80xG3
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
index 83efa00..e725f99 100644
--- a/drivers/pci/syscall.c
+++ b/drivers/pci/syscall.c
@@ -28,7 +28,7 @@ SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn,
 		return -EPERM;
 
 	err = -ENODEV;
-	dev = pci_get_bus_and_slot(bus, dfn);
+	dev = pci_get_domain_bus_and_slot(0, bus, dfn);
 	if (!dev)
 		goto error;
 
@@ -96,7 +96,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
-	dev = pci_get_bus_and_slot(bus, dfn);
+	dev = pci_get_domain_bus_and_slot(0, bus, dfn);
 	if (!dev)
 		return -ENODEV;
 
diff --git a/drivers/pci/vc.c b/drivers/pci/vc.c
index 1fa3a32..5acd9c0 100644
--- a/drivers/pci/vc.c
+++ b/drivers/pci/vc.c
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * PCI Virtual Channel support
  *
  * Copyright (C) 2013 Red Hat, Inc.  All rights reserved.
  *     Author: Alex Williamson <alex.williamson@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 
 #include <linux/device.h>
@@ -57,7 +54,7 @@ static void pci_vc_load_arb_table(struct pci_dev *dev, int pos)
 				 PCI_VC_PORT_STATUS_TABLE))
 		return;
 
-	dev_err(&dev->dev, "VC arbitration table failed to load\n");
+	pci_err(dev, "VC arbitration table failed to load\n");
 }
 
 /**
@@ -85,7 +82,7 @@ static void pci_vc_load_port_arb_table(struct pci_dev *dev, int pos, int res)
 	if (pci_wait_for_pending(dev, status_pos, PCI_VC_RES_STATUS_TABLE))
 		return;
 
-	dev_err(&dev->dev, "VC%d port arbitration table failed to load\n", res);
+	pci_err(dev, "VC%d port arbitration table failed to load\n", res);
 }
 
 /**
@@ -161,11 +158,11 @@ static void pci_vc_enable(struct pci_dev *dev, int pos, int res)
 	pci_write_config_dword(dev, ctrl_pos, ctrl);
 
 	if (!pci_wait_for_pending(dev, status_pos, PCI_VC_RES_STATUS_NEGO))
-		dev_err(&dev->dev, "VC%d negotiation stuck pending\n", id);
+		pci_err(dev, "VC%d negotiation stuck pending\n", id);
 
 	if (link && !pci_wait_for_pending(link, status_pos2,
 					  PCI_VC_RES_STATUS_NEGO))
-		dev_err(&link->dev, "VC%d negotiation stuck pending\n", id);
+		pci_err(link, "VC%d negotiation stuck pending\n", id);
 }
 
 /**
@@ -195,8 +192,7 @@ static int pci_vc_do_save_buffer(struct pci_dev *dev, int pos,
 	/* Sanity check buffer size for save/restore */
 	if (buf && save_state->cap.size !=
 	    pci_vc_do_save_buffer(dev, pos, NULL, save)) {
-		dev_err(&dev->dev,
-			"VC save buffer size does not match @0x%x\n", pos);
+		pci_err(dev, "VC save buffer size does not match @0x%x\n", pos);
 		return -ENOMEM;
 	}
 
@@ -366,14 +362,14 @@ int pci_save_vc_state(struct pci_dev *dev)
 
 		save_state = pci_find_saved_ext_cap(dev, vc_caps[i].id);
 		if (!save_state) {
-			dev_err(&dev->dev, "%s buffer not found in %s\n",
+			pci_err(dev, "%s buffer not found in %s\n",
 				vc_caps[i].name, __func__);
 			return -ENOMEM;
 		}
 
 		ret = pci_vc_do_save_buffer(dev, pos, save_state, true);
 		if (ret) {
-			dev_err(&dev->dev, "%s save unsuccessful %s\n",
+			pci_err(dev, "%s save unsuccessful %s\n",
 				vc_caps[i].name, __func__);
 			return ret;
 		}
@@ -426,8 +422,7 @@ void pci_allocate_vc_save_buffers(struct pci_dev *dev)
 
 		len = pci_vc_do_save_buffer(dev, pos, NULL, false);
 		if (pci_add_ext_cap_save_buffer(dev, vc_caps[i].id, len))
-			dev_err(&dev->dev,
-				"unable to preallocate %s save buffer\n",
+			pci_err(dev, "unable to preallocate %s save buffer\n",
 				vc_caps[i].name);
 	}
 }
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
index 39b7907..70fba57 100644
--- a/drivers/pci/vpd.c
+++ b/drivers/pci/vpd.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * File:	vpd.c
  * Purpose:	Provide PCI VPD support
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 8fc2e95..8785014 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Xen PCI Frontend.
  *
@@ -261,8 +262,8 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
 	struct msi_desc *entry;
 
 	if (nvec > SH_INFO_MAX_VEC) {
-		dev_err(&dev->dev, "too much vector for pci frontend: %x."
-				   " Increase SH_INFO_MAX_VEC.\n", nvec);
+		pci_err(dev, "too many vectors (0x%x) for PCI frontend:"
+				   " Increase SH_INFO_MAX_VEC\n", nvec);
 		return -EINVAL;
 	}
 
@@ -281,7 +282,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
 			/* we get the result */
 			for (i = 0; i < nvec; i++) {
 				if (op.msix_entries[i].vector <= 0) {
-					dev_warn(&dev->dev, "MSI-X entry %d is invalid: %d!\n",
+					pci_warn(dev, "MSI-X entry %d is invalid: %d!\n",
 						i, op.msix_entries[i].vector);
 					err = -EINVAL;
 					vector[i] = -1;
@@ -295,7 +296,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
 			err = op.value;
 		}
 	} else {
-		dev_err(&dev->dev, "enable msix get err %x\n", err);
+		pci_err(dev, "enable msix get err %x\n", err);
 	}
 	return err;
 }
@@ -316,7 +317,7 @@ static void pci_frontend_disable_msix(struct pci_dev *dev)
 
 	/* What should do for error ? */
 	if (err)
-		dev_err(&dev->dev, "pci_disable_msix get err %x\n", err);
+		pci_err(dev, "pci_disable_msix get err %x\n", err);
 }
 
 static int pci_frontend_enable_msi(struct pci_dev *dev, int vector[])
@@ -335,13 +336,13 @@ static int pci_frontend_enable_msi(struct pci_dev *dev, int vector[])
 	if (likely(!err)) {
 		vector[0] = op.value;
 		if (op.value <= 0) {
-			dev_warn(&dev->dev, "MSI entry is invalid: %d!\n",
+			pci_warn(dev, "MSI entry is invalid: %d!\n",
 				op.value);
 			err = -EINVAL;
 			vector[0] = -1;
 		}
 	} else {
-		dev_err(&dev->dev, "pci frontend enable msi failed for dev "
+		pci_err(dev, "pci frontend enable msi failed for dev "
 				    "%x:%x\n", op.bus, op.devfn);
 		err = -EINVAL;
 	}
@@ -560,7 +561,7 @@ static void free_root_bus_devs(struct pci_bus *bus)
 	while (!list_empty(&bus->devices)) {
 		dev = container_of(bus->devices.next, struct pci_dev,
 				   bus_list);
-		dev_dbg(&dev->dev, "removing device\n");
+		pci_dbg(dev, "removing device\n");
 		pci_stop_and_remove_bus_device(dev);
 	}
 }
@@ -595,6 +596,7 @@ static pci_ers_result_t pcifront_common_process(int cmd,
 	struct pci_driver *pdrv;
 	int bus = pdev->sh_info->aer_op.bus;
 	int devfn = pdev->sh_info->aer_op.devfn;
+	int domain = pdev->sh_info->aer_op.domain;
 	struct pci_dev *pcidev;
 	int flag = 0;
 
@@ -603,7 +605,7 @@ static pci_ers_result_t pcifront_common_process(int cmd,
 		cmd, bus, devfn);
 	result = PCI_ERS_RESULT_NONE;
 
-	pcidev = pci_get_bus_and_slot(bus, devfn);
+	pcidev = pci_get_domain_bus_and_slot(domain, bus, devfn);
 	if (!pcidev || !pcidev->driver) {
 		dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n");
 		pci_dev_put(pcidev);
@@ -613,8 +615,7 @@ static pci_ers_result_t pcifront_common_process(int cmd,
 
 	if (pdrv) {
 		if (pdrv->err_handler && pdrv->err_handler->error_detected) {
-			dev_dbg(&pcidev->dev,
-				"trying to call AER service\n");
+			pci_dbg(pcidev, "trying to call AER service\n");
 			if (pcidev) {
 				flag = 1;
 				switch (cmd) {
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 5ef7b46..49377d5 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -367,7 +367,7 @@ static int do_validate_mem(struct pcmcia_socket *s,
 		}
 	}
 
-	dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %p %p %u %u %u",
+	dev_dbg(&s->dev, "cs: memory probe 0x%06lx-0x%06lx: %pr %pr %u %u %u",
 		base, base+size-1, res1, res2, ret, info1, info2);
 
 	free_region(res2);
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 764650e..c5f2344 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -191,12 +191,16 @@ static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	int ret = 0, i;
 
-	clk_prepare_enable(skt->clk);
+	ret = clk_prepare_enable(skt->clk);
+	if (ret)
+		return ret;
 
 	if (skt->ops->hw_init) {
 		ret = skt->ops->hw_init(skt);
-		if (ret)
+		if (ret) {
+			clk_disable_unprepare(skt->clk);
 			return ret;
+		}
 	}
 
 	for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
index 93c50e3..38f2cc2 100644
--- a/drivers/perf/arm_dsu_pmu.c
+++ b/drivers/perf/arm_dsu_pmu.c
@@ -658,10 +658,8 @@ static void dsu_pmu_probe_pmu(struct dsu_pmu *dsu_pmu)
 		return;
 	cpmceid[0] = __dsu_pmu_read_pmceid(0);
 	cpmceid[1] = __dsu_pmu_read_pmceid(1);
-	bitmap_from_u32array(dsu_pmu->cpmceid_bitmap,
-				DSU_PMU_MAX_COMMON_EVENTS,
-				cpmceid,
-				ARRAY_SIZE(cpmceid));
+	bitmap_from_arr32(dsu_pmu->cpmceid_bitmap, cpmceid,
+			  DSU_PMU_MAX_COMMON_EVENTS);
 }
 
 static void dsu_pmu_set_active_cpu(int cpu, struct dsu_pmu *dsu_pmu)
diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index c11db8b..d4c2e42 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -8,3 +8,5 @@
 source "drivers/platform/goldfish/Kconfig"
 
 source "drivers/platform/chrome/Kconfig"
+
+source "drivers/platform/mellanox/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index d3a6630..4b2ce58 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -4,6 +4,7 @@
 #
 
 obj-$(CONFIG_X86)		+= x86/
+obj-$(CONFIG_MELLANOX_PLATFORM)	+= mellanox/
 obj-$(CONFIG_MIPS)		+= mips/
 obj-$(CONFIG_OLPC)		+= olpc/
 obj-$(CONFIG_GOLDFISH)		+= goldfish/
diff --git a/drivers/platform/mellanox/Kconfig b/drivers/platform/mellanox/Kconfig
new file mode 100644
index 0000000..591bccd
--- /dev/null
+++ b/drivers/platform/mellanox/Kconfig
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Platform support for Mellanox hardware
+#
+
+menuconfig MELLANOX_PLATFORM
+	bool "Platform support for Mellanox hardware"
+	depends on X86 || ARM || COMPILE_TEST
+	---help---
+	  Say Y here to get to see options for platform support for
+	  Mellanox systems. This option alone does not add any kernel code.
+
+	  If you say N, all options in this submenu will be skipped and disabled.
+
+if MELLANOX_PLATFORM
+
+config MLXREG_HOTPLUG
+	tristate "Mellanox platform hotplug driver support"
+	depends on REGMAP
+	depends on HWMON
+	depends on I2C
+	---help---
+	  This driver handles hot-plug events for the power suppliers, power
+	  cables and fans on the wide range Mellanox IB and Ethernet systems.
+
+endif # MELLANOX_PLATFORM
diff --git a/drivers/platform/mellanox/Makefile b/drivers/platform/mellanox/Makefile
new file mode 100644
index 0000000..7c8385e4
--- /dev/null
+++ b/drivers/platform/mellanox/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for linux/drivers/platform/mellanox
+# Mellanox Platform-Specific Drivers
+#
+obj-$(CONFIG_MLXREG_HOTPLUG)	+= mlxreg-hotplug.o
diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c
new file mode 100644
index 0000000..0dfa1ca
--- /dev/null
+++ b/drivers/platform/mellanox/mlxreg-hotplug.c
@@ -0,0 +1,638 @@
+/*
+ * Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016-2018 Vadim Pasternak <vadimp@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_data/mlxreg.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/regmap.h>
+#include <linux/workqueue.h>
+
+/* Offset of event and mask registers from status register. */
+#define MLXREG_HOTPLUG_EVENT_OFF	1
+#define MLXREG_HOTPLUG_MASK_OFF		2
+#define MLXREG_HOTPLUG_AGGR_MASK_OFF	1
+
+/* ASIC health parameters. */
+#define MLXREG_HOTPLUG_HEALTH_MASK	0x02
+#define MLXREG_HOTPLUG_RST_CNTR		3
+
+#define MLXREG_HOTPLUG_ATTRS_MAX	24
+
+/**
+ * struct mlxreg_hotplug_priv_data - platform private data:
+ * @irq: platform device interrupt number;
+ * @pdev: platform device;
+ * @plat: platform data;
+ * @dwork: delayed work template;
+ * @lock: spin lock;
+ * @hwmon: hwmon device;
+ * @mlxreg_hotplug_attr: sysfs attributes array;
+ * @mlxreg_hotplug_dev_attr: sysfs sensor device attribute array;
+ * @group: sysfs attribute group;
+ * @groups: list of sysfs attribute group for hwmon registration;
+ * @cell: location of top aggregation interrupt register;
+ * @mask: top aggregation interrupt common mask;
+ * @aggr_cache: last value of aggregation register status;
+ */
+struct mlxreg_hotplug_priv_data {
+	int irq;
+	struct device *dev;
+	struct platform_device *pdev;
+	struct mlxreg_hotplug_platform_data *plat;
+	struct regmap *regmap;
+	struct delayed_work dwork_irq;
+	struct delayed_work dwork;
+	spinlock_t lock; /* sync with interrupt */
+	struct device *hwmon;
+	struct attribute *mlxreg_hotplug_attr[MLXREG_HOTPLUG_ATTRS_MAX + 1];
+	struct sensor_device_attribute_2
+			mlxreg_hotplug_dev_attr[MLXREG_HOTPLUG_ATTRS_MAX];
+	struct attribute_group group;
+	const struct attribute_group *groups[2];
+	u32 cell;
+	u32 mask;
+	u32 aggr_cache;
+	bool after_probe;
+};
+
+static int mlxreg_hotplug_device_create(struct device *dev,
+					struct mlxreg_core_data *data)
+{
+	/*
+	 * Return if adapter number is negative. It could be in case hotplug
+	 * event is not associated with hotplug device.
+	 */
+	if (data->hpdev.nr < 0)
+		return 0;
+
+	data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr);
+	if (!data->hpdev.adapter) {
+		dev_err(dev, "Failed to get adapter for bus %d\n",
+			data->hpdev.nr);
+		return -EFAULT;
+	}
+
+	data->hpdev.client = i2c_new_device(data->hpdev.adapter,
+					    data->hpdev.brdinfo);
+	if (!data->hpdev.client) {
+		dev_err(dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
+			data->hpdev.brdinfo->type, data->hpdev.nr,
+			data->hpdev.brdinfo->addr);
+
+		i2c_put_adapter(data->hpdev.adapter);
+		data->hpdev.adapter = NULL;
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static void mlxreg_hotplug_device_destroy(struct mlxreg_core_data *data)
+{
+	if (data->hpdev.client) {
+		i2c_unregister_device(data->hpdev.client);
+		data->hpdev.client = NULL;
+	}
+
+	if (data->hpdev.adapter) {
+		i2c_put_adapter(data->hpdev.adapter);
+		data->hpdev.adapter = NULL;
+	}
+}
+
+static ssize_t mlxreg_hotplug_attr_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct mlxreg_hotplug_priv_data *priv = dev_get_drvdata(dev);
+	struct mlxreg_core_hotplug_platform_data *pdata;
+	int index = to_sensor_dev_attr_2(attr)->index;
+	int nr = to_sensor_dev_attr_2(attr)->nr;
+	struct mlxreg_core_item *item;
+	struct mlxreg_core_data *data;
+	u32 regval;
+	int ret;
+
+	pdata = dev_get_platdata(&priv->pdev->dev);
+	item = pdata->items + nr;
+	data = item->data + index;
+
+	ret = regmap_read(priv->regmap, data->reg, &regval);
+	if (ret)
+		return ret;
+
+	if (item->health) {
+		regval &= data->mask;
+	} else {
+		/* Bit = 0 : functional if item->inversed is true. */
+		if (item->inversed)
+			regval = !(regval & data->mask);
+		else
+			regval = !!(regval & data->mask);
+	}
+
+	return sprintf(buf, "%u\n", regval);
+}
+
+#define PRIV_ATTR(i) priv->mlxreg_hotplug_attr[i]
+#define PRIV_DEV_ATTR(i) priv->mlxreg_hotplug_dev_attr[i]
+
+static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv)
+{
+	struct mlxreg_core_hotplug_platform_data *pdata;
+	struct mlxreg_core_item *item;
+	struct mlxreg_core_data *data;
+	int num_attrs = 0, id = 0, i, j;
+
+	pdata = dev_get_platdata(&priv->pdev->dev);
+	item = pdata->items;
+
+	/* Go over all kinds of items - psu, pwr, fan. */
+	for (i = 0; i < pdata->counter; i++, item++) {
+		num_attrs += item->count;
+		data = item->data;
+		/* Go over all units within the item. */
+		for (j = 0; j < item->count; j++, data++, id++) {
+			PRIV_ATTR(id) = &PRIV_DEV_ATTR(id).dev_attr.attr;
+			PRIV_ATTR(id)->name = devm_kasprintf(&priv->pdev->dev,
+							     GFP_KERNEL,
+							     data->label);
+
+			if (!PRIV_ATTR(id)->name) {
+				dev_err(priv->dev, "Memory allocation failed for attr %d.\n",
+					id);
+				return -ENOMEM;
+			}
+
+			PRIV_DEV_ATTR(id).dev_attr.attr.name =
+							PRIV_ATTR(id)->name;
+			PRIV_DEV_ATTR(id).dev_attr.attr.mode = 0444;
+			PRIV_DEV_ATTR(id).dev_attr.show =
+						mlxreg_hotplug_attr_show;
+			PRIV_DEV_ATTR(id).nr = i;
+			PRIV_DEV_ATTR(id).index = j;
+			sysfs_attr_init(&PRIV_DEV_ATTR(id).dev_attr.attr);
+		}
+	}
+
+	priv->group.attrs = devm_kzalloc(&priv->pdev->dev, num_attrs *
+					 sizeof(struct attribute *),
+					 GFP_KERNEL);
+	if (!priv->group.attrs)
+		return -ENOMEM;
+
+	priv->group.attrs = priv->mlxreg_hotplug_attr;
+	priv->groups[0] = &priv->group;
+	priv->groups[1] = NULL;
+
+	return 0;
+}
+
+static void
+mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
+			   struct mlxreg_core_item *item)
+{
+	struct mlxreg_core_data *data;
+	u32 asserted, regval, bit;
+	int ret;
+
+	/*
+	 * Validate if item related to received signal type is valid.
+	 * It should never happen, excepted the situation when some
+	 * piece of hardware is broken. In such situation just produce
+	 * error message and return. Caller must continue to handle the
+	 * signals from other devices if any.
+	 */
+	if (unlikely(!item)) {
+		dev_err(priv->dev, "False signal: at offset:mask 0x%02x:0x%02x.\n",
+			item->reg, item->mask);
+
+		return;
+	}
+
+	/* Mask event. */
+	ret = regmap_write(priv->regmap, item->reg + MLXREG_HOTPLUG_MASK_OFF,
+			   0);
+	if (ret)
+		goto out;
+
+	/* Read status. */
+	ret = regmap_read(priv->regmap, item->reg, &regval);
+	if (ret)
+		goto out;
+
+	/* Set asserted bits and save last status. */
+	regval &= item->mask;
+	asserted = item->cache ^ regval;
+	item->cache = regval;
+
+	for_each_set_bit(bit, (unsigned long *)&asserted, 8) {
+		data = item->data + bit;
+		if (regval & BIT(bit)) {
+			if (item->inversed)
+				mlxreg_hotplug_device_destroy(data);
+			else
+				mlxreg_hotplug_device_create(priv->dev, data);
+		} else {
+			if (item->inversed)
+				mlxreg_hotplug_device_create(priv->dev, data);
+			else
+				mlxreg_hotplug_device_destroy(data);
+		}
+	}
+
+	/* Acknowledge event. */
+	ret = regmap_write(priv->regmap, item->reg + MLXREG_HOTPLUG_EVENT_OFF,
+			   0);
+	if (ret)
+		goto out;
+
+	/* Unmask event. */
+	ret = regmap_write(priv->regmap, item->reg + MLXREG_HOTPLUG_MASK_OFF,
+			   item->mask);
+
+ out:
+	if (ret)
+		dev_err(priv->dev, "Failed to complete workqueue.\n");
+}
+
+static void
+mlxreg_hotplug_health_work_helper(struct mlxreg_hotplug_priv_data *priv,
+				  struct mlxreg_core_item *item)
+{
+	struct mlxreg_core_data *data = item->data;
+	u32 regval;
+	int i, ret;
+
+	for (i = 0; i < item->count; i++, data++) {
+		/* Mask event. */
+		ret = regmap_write(priv->regmap, data->reg +
+				   MLXREG_HOTPLUG_MASK_OFF, 0);
+		if (ret)
+			goto out;
+
+		/* Read status. */
+		ret = regmap_read(priv->regmap, data->reg, &regval);
+		if (ret)
+			goto out;
+
+		regval &= data->mask;
+		item->cache = regval;
+		if (regval == MLXREG_HOTPLUG_HEALTH_MASK) {
+			if ((data->health_cntr++ == MLXREG_HOTPLUG_RST_CNTR) ||
+			    !priv->after_probe) {
+				mlxreg_hotplug_device_create(priv->dev, data);
+				data->attached = true;
+			}
+		} else {
+			if (data->attached) {
+				mlxreg_hotplug_device_destroy(data);
+				data->attached = false;
+				data->health_cntr = 0;
+			}
+		}
+
+		/* Acknowledge event. */
+		ret = regmap_write(priv->regmap, data->reg +
+				   MLXREG_HOTPLUG_EVENT_OFF, 0);
+		if (ret)
+			goto out;
+
+		/* Unmask event. */
+		ret = regmap_write(priv->regmap, data->reg +
+				   MLXREG_HOTPLUG_MASK_OFF, data->mask);
+		if (ret)
+			goto out;
+	}
+
+ out:
+	if (ret)
+		dev_err(priv->dev, "Failed to complete workqueue.\n");
+}
+
+/*
+ * mlxreg_hotplug_work_handler - performs traversing of device interrupt
+ * registers according to the below hierarchy schema:
+ *
+ *				Aggregation registers (status/mask)
+ * PSU registers:		*---*
+ * *-----------------*		|   |
+ * |status/event/mask|----->    | * |
+ * *-----------------*		|   |
+ * Power registers:		|   |
+ * *-----------------*		|   |
+ * |status/event/mask|----->    | * |
+ * *-----------------*		|   |
+ * FAN registers:		|   |--> CPU
+ * *-----------------*		|   |
+ * |status/event/mask|----->    | * |
+ * *-----------------*		|   |
+ * ASIC registers:		|   |
+ * *-----------------*		|   |
+ * |status/event/mask|----->    | * |
+ * *-----------------*		|   |
+ *				*---*
+ *
+ * In case some system changed are detected: FAN in/out, PSU in/out, power
+ * cable attached/detached, ASIC health good/bad, relevant device is created
+ * or destroyed.
+ */
+static void mlxreg_hotplug_work_handler(struct work_struct *work)
+{
+	struct mlxreg_core_hotplug_platform_data *pdata;
+	struct mlxreg_hotplug_priv_data *priv;
+	struct mlxreg_core_item *item;
+	u32 regval, aggr_asserted;
+	unsigned long flags;
+	int i, ret;
+
+	priv = container_of(work, struct mlxreg_hotplug_priv_data,
+			    dwork_irq.work);
+	pdata = dev_get_platdata(&priv->pdev->dev);
+	item = pdata->items;
+
+	/* Mask aggregation event. */
+	ret = regmap_write(priv->regmap, pdata->cell +
+			   MLXREG_HOTPLUG_AGGR_MASK_OFF, 0);
+	if (ret < 0)
+		goto out;
+
+	/* Read aggregation status. */
+	ret = regmap_read(priv->regmap, pdata->cell, &regval);
+	if (ret)
+		goto out;
+
+	regval &= pdata->mask;
+	aggr_asserted = priv->aggr_cache ^ regval;
+	priv->aggr_cache = regval;
+
+	/* Handle topology and health configuration changes. */
+	for (i = 0; i < pdata->counter; i++, item++) {
+		if (aggr_asserted & item->aggr_mask) {
+			if (item->health)
+				mlxreg_hotplug_health_work_helper(priv, item);
+			else
+				mlxreg_hotplug_work_helper(priv, item);
+		}
+	}
+
+	if (aggr_asserted) {
+		spin_lock_irqsave(&priv->lock, flags);
+
+		/*
+		 * It is possible, that some signals have been inserted, while
+		 * interrupt has been masked by mlxreg_hotplug_work_handler.
+		 * In this case such signals will be missed. In order to handle
+		 * these signals delayed work is canceled and work task
+		 * re-scheduled for immediate execution. It allows to handle
+		 * missed signals, if any. In other case work handler just
+		 * validates that no new signals have been received during
+		 * masking.
+		 */
+		cancel_delayed_work(&priv->dwork_irq);
+		schedule_delayed_work(&priv->dwork_irq, 0);
+
+		spin_unlock_irqrestore(&priv->lock, flags);
+
+		return;
+	}
+
+	/* Unmask aggregation event (no need acknowledge). */
+	ret = regmap_write(priv->regmap, pdata->cell +
+			   MLXREG_HOTPLUG_AGGR_MASK_OFF, pdata->mask);
+
+ out:
+	if (ret)
+		dev_err(priv->dev, "Failed to complete workqueue.\n");
+}
+
+static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv)
+{
+	struct mlxreg_core_hotplug_platform_data *pdata;
+	struct mlxreg_core_item *item;
+	int i, ret;
+
+	pdata = dev_get_platdata(&priv->pdev->dev);
+	item = pdata->items;
+
+	for (i = 0; i < pdata->counter; i++, item++) {
+		/* Clear group presense event. */
+		ret = regmap_write(priv->regmap, item->reg +
+				   MLXREG_HOTPLUG_EVENT_OFF, 0);
+		if (ret)
+			goto out;
+
+		/* Set group initial status as mask and unmask group event. */
+		if (item->inversed) {
+			item->cache = item->mask;
+			ret = regmap_write(priv->regmap, item->reg +
+					   MLXREG_HOTPLUG_MASK_OFF,
+					   item->mask);
+			if (ret)
+				goto out;
+		}
+	}
+
+	/* Keep aggregation initial status as zero and unmask events. */
+	ret = regmap_write(priv->regmap, pdata->cell +
+			   MLXREG_HOTPLUG_AGGR_MASK_OFF, pdata->mask);
+	if (ret)
+		goto out;
+
+	/* Keep low aggregation initial status as zero and unmask events. */
+	if (pdata->cell_low) {
+		ret = regmap_write(priv->regmap, pdata->cell_low +
+				   MLXREG_HOTPLUG_AGGR_MASK_OFF,
+				   pdata->mask_low);
+		if (ret)
+			goto out;
+	}
+
+	/* Invoke work handler for initializing hot plug devices setting. */
+	mlxreg_hotplug_work_handler(&priv->dwork_irq.work);
+
+ out:
+	if (ret)
+		dev_err(priv->dev, "Failed to set interrupts.\n");
+	enable_irq(priv->irq);
+	return ret;
+}
+
+static void mlxreg_hotplug_unset_irq(struct mlxreg_hotplug_priv_data *priv)
+{
+	struct mlxreg_core_hotplug_platform_data *pdata;
+	struct mlxreg_core_item *item;
+	struct mlxreg_core_data *data;
+	int count, i, j;
+
+	pdata = dev_get_platdata(&priv->pdev->dev);
+	item = pdata->items;
+	disable_irq(priv->irq);
+	cancel_delayed_work_sync(&priv->dwork_irq);
+
+	/* Mask low aggregation event, if defined. */
+	if (pdata->cell_low)
+		regmap_write(priv->regmap, pdata->cell_low +
+			     MLXREG_HOTPLUG_AGGR_MASK_OFF, 0);
+
+	/* Mask aggregation event. */
+	regmap_write(priv->regmap, pdata->cell + MLXREG_HOTPLUG_AGGR_MASK_OFF,
+		     0);
+
+	/* Clear topology configurations. */
+	for (i = 0; i < pdata->counter; i++, item++) {
+		data = item->data;
+		/* Mask group presense event. */
+		regmap_write(priv->regmap, data->reg + MLXREG_HOTPLUG_MASK_OFF,
+			     0);
+		/* Clear group presense event. */
+		regmap_write(priv->regmap, data->reg +
+			     MLXREG_HOTPLUG_EVENT_OFF, 0);
+
+		/* Remove all the attached devices in group. */
+		count = item->count;
+		for (j = 0; j < count; j++, data++)
+			mlxreg_hotplug_device_destroy(data);
+	}
+}
+
+static irqreturn_t mlxreg_hotplug_irq_handler(int irq, void *dev)
+{
+	struct mlxreg_hotplug_priv_data *priv;
+
+	priv = (struct mlxreg_hotplug_priv_data *)dev;
+
+	/* Schedule work task for immediate execution.*/
+	schedule_delayed_work(&priv->dwork_irq, 0);
+
+	return IRQ_HANDLED;
+}
+
+static int mlxreg_hotplug_probe(struct platform_device *pdev)
+{
+	struct mlxreg_core_hotplug_platform_data *pdata;
+	struct mlxreg_hotplug_priv_data *priv;
+	int err;
+
+	pdata = dev_get_platdata(&pdev->dev);
+	if (!pdata) {
+		dev_err(&pdev->dev, "Failed to get platform data.\n");
+		return -EINVAL;
+	}
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	if (pdata->irq) {
+		priv->irq = pdata->irq;
+	} else {
+		priv->irq = platform_get_irq(pdev, 0);
+		if (priv->irq < 0) {
+			dev_err(&pdev->dev, "Failed to get platform irq: %d\n",
+				priv->irq);
+			return priv->irq;
+		}
+	}
+
+	priv->regmap = pdata->regmap;
+	priv->dev = pdev->dev.parent;
+	priv->pdev = pdev;
+
+	err = devm_request_irq(&pdev->dev, priv->irq,
+			       mlxreg_hotplug_irq_handler, IRQF_TRIGGER_FALLING
+			       | IRQF_SHARED, "mlxreg-hotplug", priv);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to request irq: %d\n", err);
+		return err;
+	}
+
+	disable_irq(priv->irq);
+	spin_lock_init(&priv->lock);
+	INIT_DELAYED_WORK(&priv->dwork_irq, mlxreg_hotplug_work_handler);
+	/* Perform initial interrupts setup. */
+	mlxreg_hotplug_set_irq(priv);
+
+	priv->after_probe = true;
+	dev_set_drvdata(&pdev->dev, priv);
+
+	err = mlxreg_hotplug_attr_init(priv);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to allocate attributes: %d\n",
+			err);
+		return err;
+	}
+
+	priv->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
+					"mlxreg_hotplug", priv, priv->groups);
+	if (IS_ERR(priv->hwmon)) {
+		dev_err(&pdev->dev, "Failed to register hwmon device %ld\n",
+			PTR_ERR(priv->hwmon));
+		return PTR_ERR(priv->hwmon);
+	}
+
+	return 0;
+}
+
+static int mlxreg_hotplug_remove(struct platform_device *pdev)
+{
+	struct mlxreg_hotplug_priv_data *priv = dev_get_drvdata(&pdev->dev);
+
+	/* Clean interrupts setup. */
+	mlxreg_hotplug_unset_irq(priv);
+
+	return 0;
+}
+
+static struct platform_driver mlxreg_hotplug_driver = {
+	.driver = {
+		.name = "mlxreg-hotplug",
+	},
+	.probe = mlxreg_hotplug_probe,
+	.remove = mlxreg_hotplug_remove,
+};
+
+module_platform_driver(mlxreg_hotplug_driver);
+
+MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
+MODULE_DESCRIPTION("Mellanox regmap hotplug platform driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("platform:mlxreg-hotplug");
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 2c745e8..9a8f964 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -36,6 +36,20 @@
 	  If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M
 	  here.
 
+config ACER_WIRELESS
+        tristate "Acer Wireless Radio Control Driver"
+        depends on ACPI
+        depends on INPUT
+        ---help---
+          The Acer Wireless Radio Control handles the airplane mode hotkey
+          present on new Acer laptops.
+
+          Say Y or M here if you have an Acer notebook with an airplane mode
+          hotkey.
+
+          If you choose to compile this driver as a module the module will be
+          called acer-wireless.
+
 config ACERHDF
 	tristate "Acer Aspire One temperature and fan driver"
 	depends on ACPI && THERMAL
@@ -244,6 +258,18 @@
 	  This is a driver for enabling wifi on some Fujitsu-Siemens Amilo
 	  laptops.
 
+config GPD_POCKET_FAN
+	tristate "GPD Pocket Fan Controller support"
+	depends on ACPI
+	depends on THERMAL
+	---help---
+	  Driver for the GPD Pocket vendor specific FAN02501 ACPI device
+	  which controls the fan speed on the GPD Pocket.
+
+	  Without this driver the fan on the Pocket will stay off independent
+	  of the CPU temperature. Say Y or M if the kernel may be used on a
+	  GPD pocket.
+
 config TC1100_WMI
 	tristate "HP Compaq TC1100 Tablet WMI Extras"
 	depends on !X86_64
@@ -812,9 +838,8 @@
 
 config ACPI_CMPC
 	tristate "CMPC Laptop Extras"
-	depends on ACPI
+	depends on ACPI && INPUT
 	depends on RFKILL || RFKILL=n
-	select INPUT
 	select BACKLIGHT_CLASS_DEVICE
 	help
 	  Support for Intel Classmate PC ACPI devices, including some
@@ -949,7 +974,7 @@
 	  If you are running on a Galileo/Quark say Y here.
 
 config INTEL_PMC_CORE
-	bool "Intel PMC Core driver"
+	tristate "Intel PMC Core driver"
 	depends on PCI
 	---help---
 	  The Intel Platform Controller Hub for Intel Core SoCs provides access
@@ -958,7 +983,10 @@
 	  exposed by the Power Management Controller.
 
 	  Supported features:
-		- SLP_S0_RESIDENCY counter.
+		- SLP_S0_RESIDENCY counter
+		- PCH IP Power Gating status
+		- LTR Ignore
+		- MPHY/PLL gating status (Sunrisepoint PCH only)
 
 config IBM_RTL
 	tristate "Device driver to enable PRTL support"
@@ -1131,7 +1159,6 @@
 
 config MLX_PLATFORM
 	tristate "Mellanox Technologies platform support"
-	depends on X86_64
 	---help---
 	  This option enables system support for the Mellanox Technologies
 	  platform. The Mellanox systems provide data center networking
@@ -1141,14 +1168,6 @@
 
 	  If you have a Mellanox system, say Y or M here.
 
-config MLX_CPLD_PLATFORM
-	tristate "Mellanox platform hotplug driver support"
-	select HWMON
-	select I2C
-	---help---
-	  This driver handles hot-plug events for the power suppliers, power
-	  cables and fans on the wide range Mellanox IB and Ethernet systems.
-
 config INTEL_TURBO_MAX_3
 	bool "Intel Turbo Boost Max Technology 3.0 enumeration driver"
 	depends on X86_64 && SCHED_MC_PRIO
@@ -1170,6 +1189,17 @@
 	  with the OS-image for the device. This option supplies the missing
 	  information. Enable this for x86 tablets with Silead touchscreens.
 
+config INTEL_CHTDC_TI_PWRBTN
+	tristate "Intel Cherry Trail Dollar Cove TI power button driver"
+	depends on INTEL_SOC_PMIC_CHTDC_TI
+	depends on INPUT
+	---help---
+	  This option adds a power button driver driver for Dollar Cove TI
+	  PMIC on Intel Cherry Trail devices.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called intel_chtdc_ti_pwrbtn.
+
 endif # X86_PLATFORM_DEVICES
 
 config PMC_ATOM
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index c32b34a..c388608 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -23,11 +23,13 @@
 obj-$(CONFIG_DELL_SMO8800)	+= dell-smo8800.o
 obj-$(CONFIG_DELL_RBTN)		+= dell-rbtn.o
 obj-$(CONFIG_ACER_WMI)		+= acer-wmi.o
+obj-$(CONFIG_ACER_WIRELESS)	+= acer-wireless.o
 obj-$(CONFIG_ACERHDF)		+= acerhdf.o
 obj-$(CONFIG_HP_ACCEL)		+= hp_accel.o
 obj-$(CONFIG_HP_WIRELESS)	+= hp-wireless.o
 obj-$(CONFIG_HP_WMI)		+= hp-wmi.o
 obj-$(CONFIG_AMILO_RFKILL)	+= amilo-rfkill.o
+obj-$(CONFIG_GPD_POCKET_FAN)	+= gpd-pocket-fan.o
 obj-$(CONFIG_TC1100_WMI)	+= tc1100-wmi.o
 obj-$(CONFIG_SONY_LAPTOP)	+= sony-laptop.o
 obj-$(CONFIG_IDEAPAD_LAPTOP)	+= ideapad-laptop.o
@@ -86,5 +88,5 @@
 obj-$(CONFIG_INTEL_PMC_CORE)    += intel_pmc_core.o
 obj-$(CONFIG_PMC_ATOM)		+= pmc_atom.o
 obj-$(CONFIG_MLX_PLATFORM)	+= mlx-platform.o
-obj-$(CONFIG_MLX_CPLD_PLATFORM)	+= mlxcpld-hotplug.o
 obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
+obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN)	+= intel_chtdc_ti_pwrbtn.o
diff --git a/drivers/platform/x86/acer-wireless.c b/drivers/platform/x86/acer-wireless.c
new file mode 100644
index 0000000..8580379
--- /dev/null
+++ b/drivers/platform/x86/acer-wireless.c
@@ -0,0 +1,71 @@
+/*
+ * Acer Wireless Radio Control Driver
+ *
+ * Copyright (C) 2017 Endless Mobile, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci_ids.h>
+#include <linux/types.h>
+
+static const struct acpi_device_id acer_wireless_acpi_ids[] = {
+	{"10251229", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, acer_wireless_acpi_ids);
+
+static void acer_wireless_notify(struct acpi_device *adev, u32 event)
+{
+	struct input_dev *idev = acpi_driver_data(adev);
+
+	dev_dbg(&adev->dev, "event=%#x\n", event);
+	if (event != 0x80) {
+		dev_notice(&adev->dev, "Unknown SMKB event: %#x\n", event);
+		return;
+	}
+	input_report_key(idev, KEY_RFKILL, 1);
+	input_report_key(idev, KEY_RFKILL, 0);
+	input_sync(idev);
+}
+
+static int acer_wireless_add(struct acpi_device *adev)
+{
+	struct input_dev *idev;
+
+	idev = devm_input_allocate_device(&adev->dev);
+	if (!idev)
+		return -ENOMEM;
+
+	adev->driver_data = idev;
+	idev->name = "Acer Wireless Radio Control";
+	idev->phys = "acer-wireless/input0";
+	idev->id.bustype = BUS_HOST;
+	idev->id.vendor = PCI_VENDOR_ID_AI;
+	idev->id.product = 0x1229;
+	set_bit(EV_KEY, idev->evbit);
+	set_bit(KEY_RFKILL, idev->keybit);
+
+	return input_register_device(idev);
+}
+
+static struct acpi_driver acer_wireless_driver = {
+	.name = "Acer Wireless Radio Control Driver",
+	.class = "hotkey",
+	.ids = acer_wireless_acpi_ids,
+	.ops = {
+		.add = acer_wireless_add,
+		.notify = acer_wireless_notify,
+	},
+};
+module_acpi_driver(acer_wireless_driver);
+
+MODULE_DESCRIPTION("Acer Wireless Radio Control Driver");
+MODULE_AUTHOR("Chris Chiu <chiu@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c
index 4eb8e1a..9d7dbd9 100644
--- a/drivers/platform/x86/alienware-wmi.c
+++ b/drivers/platform/x86/alienware-wmi.c
@@ -68,6 +68,14 @@ struct quirk_entry {
 
 static struct quirk_entry *quirks;
 
+
+static struct quirk_entry quirk_inspiron5675 = {
+	.num_zones = 2,
+	.hdmi_mux = 0,
+	.amplifier = 0,
+	.deepslp = 0,
+};
+
 static struct quirk_entry quirk_unknown = {
 	.num_zones = 2,
 	.hdmi_mux = 0,
@@ -171,6 +179,15 @@ static const struct dmi_system_id alienware_quirks[] __initconst = {
 		     },
 	 .driver_data = &quirk_asm201,
 	 },
+	 {
+	 .callback = dmi_matched,
+	 .ident = "Dell Inc. Inspiron 5675",
+	 .matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+		     DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
+		     },
+	 .driver_data = &quirk_inspiron5675,
+	 },
 	{}
 };
 
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c
index 623d322..7c4eb86 100644
--- a/drivers/platform/x86/apple-gmux.c
+++ b/drivers/platform/x86/apple-gmux.c
@@ -24,7 +24,6 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/vga_switcheroo.h>
-#include <linux/vgaarb.h>
 #include <acpi/video.h>
 #include <asm/io.h>
 
@@ -54,7 +53,6 @@ struct apple_gmux_data {
 	bool indexed;
 	struct mutex index_lock;
 
-	struct pci_dev *pdev;
 	struct backlight_device *bdev;
 
 	/* switcheroo data */
@@ -599,23 +597,6 @@ static int gmux_resume(struct device *dev)
 	return 0;
 }
 
-static struct pci_dev *gmux_get_io_pdev(void)
-{
-	struct pci_dev *pdev = NULL;
-
-	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev))) {
-		u16 cmd;
-
-		pci_read_config_word(pdev, PCI_COMMAND, &cmd);
-		if (!(cmd & PCI_COMMAND_IO))
-			continue;
-
-		return pdev;
-	}
-
-	return NULL;
-}
-
 static int is_thunderbolt(struct device *dev, void *data)
 {
 	return to_pci_dev(dev)->is_thunderbolt;
@@ -631,7 +612,6 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
 	int ret = -ENXIO;
 	acpi_status status;
 	unsigned long long gpe;
-	struct pci_dev *pdev = NULL;
 
 	if (apple_gmux_data)
 		return -EBUSY;
@@ -682,7 +662,7 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
 			ver_minor = (version >> 16) & 0xff;
 			ver_release = (version >> 8) & 0xff;
 		} else {
-			pr_info("gmux device not present or IO disabled\n");
+			pr_info("gmux device not present\n");
 			ret = -ENODEV;
 			goto err_release;
 		}
@@ -690,23 +670,6 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
 	pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor,
 		ver_release, (gmux_data->indexed ? "indexed" : "classic"));
 
-	/*
-	 * Apple systems with gmux are EFI based and normally don't use
-	 * VGA. In addition changing IO+MEM ownership between IGP and dGPU
-	 * disables IO/MEM used for backlight control on some systems.
-	 * Lock IO+MEM to GPU with active IO to prevent switch.
-	 */
-	pdev = gmux_get_io_pdev();
-	if (pdev && vga_tryget(pdev,
-			       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM)) {
-		pr_err("IO+MEM vgaarb-locking for PCI:%s failed\n",
-			pci_name(pdev));
-		ret = -EBUSY;
-		goto err_release;
-	} else if (pdev)
-		pr_info("locked IO for PCI:%s\n", pci_name(pdev));
-	gmux_data->pdev = pdev;
-
 	memset(&props, 0, sizeof(props));
 	props.type = BACKLIGHT_PLATFORM;
 	props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS);
@@ -822,10 +785,6 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
 err_notify:
 	backlight_device_unregister(bdev);
 err_release:
-	if (gmux_data->pdev)
-		vga_put(gmux_data->pdev,
-			VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM);
-	pci_dev_put(pdev);
 	release_region(gmux_data->iostart, gmux_data->iolen);
 err_free:
 	kfree(gmux_data);
@@ -845,11 +804,6 @@ static void gmux_remove(struct pnp_dev *pnp)
 					   &gmux_notify_handler);
 	}
 
-	if (gmux_data->pdev) {
-		vga_put(gmux_data->pdev,
-			VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM);
-		pci_dev_put(gmux_data->pdev);
-	}
 	backlight_device_unregister(gmux_data->bdev);
 
 	release_region(gmux_data->iostart, gmux_data->iolen);
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 5269a01..136ff2b 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -111,7 +111,7 @@ static struct quirk_entry quirk_asus_x550lb = {
 	.xusb2pr = 0x01D9,
 };
 
-static struct quirk_entry quirk_asus_ux330uak = {
+static struct quirk_entry quirk_asus_forceals = {
 	.wmi_force_als_set = true,
 };
 
@@ -387,7 +387,7 @@ static const struct dmi_system_id asus_quirks[] = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 			DMI_MATCH(DMI_PRODUCT_NAME, "UX330UAK"),
 		},
-		.driver_data = &quirk_asus_ux330uak,
+		.driver_data = &quirk_asus_forceals,
 	},
 	{
 		.callback = dmi_matched,
@@ -398,6 +398,15 @@ static const struct dmi_system_id asus_quirks[] = {
 		},
 		.driver_data = &quirk_asus_x550lb,
 	},
+	{
+		.callback = dmi_matched,
+		.ident = "ASUSTeK COMPUTER INC. UX430UQ",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "UX430UQ"),
+		},
+		.driver_data = &quirk_asus_forceals,
+	},
 	{},
 };
 
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index cd4725e..2a68f59 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -36,10 +36,10 @@
 #include "dell-smbios.h"
 
 struct quirk_entry {
-	u8 touchpad_led;
-	u8 kbd_led_levels_off_1;
+	bool touchpad_led;
+	bool kbd_led_levels_off_1;
 
-	int needs_kbd_timeouts;
+	bool needs_kbd_timeouts;
 	/*
 	 * Ordered list of timeouts expressed in seconds.
 	 * The list must end with -1
@@ -50,7 +50,7 @@ struct quirk_entry {
 static struct quirk_entry *quirks;
 
 static struct quirk_entry quirk_dell_vostro_v130 = {
-	.touchpad_led = 1,
+	.touchpad_led = true,
 };
 
 static int __init dmi_matched(const struct dmi_system_id *dmi)
@@ -64,12 +64,12 @@ static int __init dmi_matched(const struct dmi_system_id *dmi)
  * is used then BIOS silently set timeout to 0 without any error message.
  */
 static struct quirk_entry quirk_dell_xps13_9333 = {
-	.needs_kbd_timeouts = 1,
+	.needs_kbd_timeouts = true,
 	.kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 },
 };
 
 static struct quirk_entry quirk_dell_latitude_e6410 = {
-	.kbd_led_levels_off_1 = 1,
+	.kbd_led_levels_off_1 = true,
 };
 
 static struct platform_driver platform_driver = {
@@ -78,7 +78,6 @@ static struct platform_driver platform_driver = {
 	}
 };
 
-static struct calling_interface_buffer *buffer;
 static struct platform_device *platform_device;
 static struct backlight_device *dell_backlight_device;
 static struct rfkill *wifi_rfkill;
@@ -110,6 +109,42 @@ static const struct dmi_system_id dell_device_table[] __initconst = {
 		},
 	},
 	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "30"), /*Tablet*/
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /*Convertible*/
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "32"), /*Detachable*/
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "30"), /*Tablet*/
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /*Convertible*/
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_CHASSIS_TYPE, "32"), /*Detachable*/
+		},
+	},
+	{
 		.ident = "Dell Computer Corporation",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
@@ -286,7 +321,8 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
 	{ }
 };
 
-void dell_set_arguments(u32 arg0, u32 arg1, u32 arg2, u32 arg3)
+static void dell_fill_request(struct calling_interface_buffer *buffer,
+			       u32 arg0, u32 arg1, u32 arg2, u32 arg3)
 {
 	memset(buffer, 0, sizeof(struct calling_interface_buffer));
 	buffer->input[0] = arg0;
@@ -295,7 +331,8 @@ void dell_set_arguments(u32 arg0, u32 arg1, u32 arg2, u32 arg3)
 	buffer->input[3] = arg3;
 }
 
-int dell_send_request(u16 class, u16 select)
+static int dell_send_request(struct calling_interface_buffer *buffer,
+			     u16 class, u16 select)
 {
 	int ret;
 
@@ -432,21 +469,22 @@ static int dell_rfkill_set(void *data, bool blocked)
 	int disable = blocked ? 1 : 0;
 	unsigned long radio = (unsigned long)data;
 	int hwswitch_bit = (unsigned long)data - 1;
+	struct calling_interface_buffer buffer;
 	int hwswitch;
 	int status;
 	int ret;
 
-	dell_set_arguments(0, 0, 0, 0);
-	ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+	dell_fill_request(&buffer, 0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
 	if (ret)
 		return ret;
-	status = buffer->output[1];
+	status = buffer.output[1];
 
-	dell_set_arguments(0x2, 0, 0, 0);
-	ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+	dell_fill_request(&buffer, 0x2, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
 	if (ret)
 		return ret;
-	hwswitch = buffer->output[1];
+	hwswitch = buffer.output[1];
 
 	/* If the hardware switch controls this radio, and the hardware
 	   switch is disabled, always disable the radio */
@@ -454,8 +492,8 @@ static int dell_rfkill_set(void *data, bool blocked)
 	    (status & BIT(0)) && !(status & BIT(16)))
 		disable = 1;
 
-	dell_set_arguments(1 | (radio<<8) | (disable << 16), 0, 0, 0);
-	ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+	dell_fill_request(&buffer, 1 | (radio<<8) | (disable << 16), 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
 	return ret;
 }
 
@@ -464,9 +502,11 @@ static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,
 {
 	if (status & BIT(0)) {
 		/* Has hw-switch, sync sw_state to BIOS */
+		struct calling_interface_buffer buffer;
 		int block = rfkill_blocked(rfkill);
-		dell_set_arguments(1 | (radio << 8) | (block << 16), 0, 0, 0);
-		dell_send_request(CLASS_INFO, SELECT_RFKILL);
+		dell_fill_request(&buffer,
+				   1 | (radio << 8) | (block << 16), 0, 0, 0);
+		dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
 	} else {
 		/* No hw-switch, sync BIOS state to sw_state */
 		rfkill_set_sw_state(rfkill, !!(status & BIT(radio + 16)));
@@ -483,21 +523,22 @@ static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio,
 static void dell_rfkill_query(struct rfkill *rfkill, void *data)
 {
 	int radio = ((unsigned long)data & 0xF);
+	struct calling_interface_buffer buffer;
 	int hwswitch;
 	int status;
 	int ret;
 
-	dell_set_arguments(0, 0, 0, 0);
-	ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
-	status = buffer->output[1];
+	dell_fill_request(&buffer, 0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
+	status = buffer.output[1];
 
 	if (ret != 0 || !(status & BIT(0))) {
 		return;
 	}
 
-	dell_set_arguments(0, 0x2, 0, 0);
-	ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
-	hwswitch = buffer->output[1];
+	dell_fill_request(&buffer, 0, 0x2, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
+	hwswitch = buffer.output[1];
 
 	if (ret != 0)
 		return;
@@ -514,22 +555,23 @@ static struct dentry *dell_laptop_dir;
 
 static int dell_debugfs_show(struct seq_file *s, void *data)
 {
+	struct calling_interface_buffer buffer;
 	int hwswitch_state;
 	int hwswitch_ret;
 	int status;
 	int ret;
 
-	dell_set_arguments(0, 0, 0, 0);
-	ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+	dell_fill_request(&buffer, 0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
 	if (ret)
 		return ret;
-	status = buffer->output[1];
+	status = buffer.output[1];
 
-	dell_set_arguments(0, 0x2, 0, 0);
-	hwswitch_ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+	dell_fill_request(&buffer, 0, 0x2, 0, 0);
+	hwswitch_ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
 	if (hwswitch_ret)
 		return hwswitch_ret;
-	hwswitch_state = buffer->output[1];
+	hwswitch_state = buffer.output[1];
 
 	seq_printf(s, "return:\t%d\n", ret);
 	seq_printf(s, "status:\t0x%X\n", status);
@@ -594,38 +636,27 @@ static int dell_debugfs_show(struct seq_file *s, void *data)
 
 	return 0;
 }
-
-static int dell_debugfs_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, dell_debugfs_show, inode->i_private);
-}
-
-static const struct file_operations dell_debugfs_fops = {
-	.owner = THIS_MODULE,
-	.open = dell_debugfs_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(dell_debugfs);
 
 static void dell_update_rfkill(struct work_struct *ignored)
 {
+	struct calling_interface_buffer buffer;
 	int hwswitch = 0;
 	int status;
 	int ret;
 
-	dell_set_arguments(0, 0, 0, 0);
-	ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
-	status = buffer->output[1];
+	dell_fill_request(&buffer, 0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
+	status = buffer.output[1];
 
 	if (ret != 0)
 		return;
 
-	dell_set_arguments(0, 0x2, 0, 0);
-	ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+	dell_fill_request(&buffer, 0, 0x2, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
 
 	if (ret == 0 && (status & BIT(0)))
-		hwswitch = buffer->output[1];
+		hwswitch = buffer.output[1];
 
 	if (wifi_rfkill) {
 		dell_rfkill_update_hw_state(wifi_rfkill, 1, status, hwswitch);
@@ -683,6 +714,7 @@ static struct notifier_block dell_laptop_rbtn_notifier = {
 
 static int __init dell_setup_rfkill(void)
 {
+	struct calling_interface_buffer buffer;
 	int status, ret, whitelisted;
 	const char *product;
 
@@ -698,9 +730,9 @@ static int __init dell_setup_rfkill(void)
 	if (!force_rfkill && !whitelisted)
 		return 0;
 
-	dell_set_arguments(0, 0, 0, 0);
-	ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
-	status = buffer->output[1];
+	dell_fill_request(&buffer, 0, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
+	status = buffer.output[1];
 
 	/* dell wireless info smbios call is not supported */
 	if (ret != 0)
@@ -853,6 +885,7 @@ static void dell_cleanup_rfkill(void)
 
 static int dell_send_intensity(struct backlight_device *bd)
 {
+	struct calling_interface_buffer buffer;
 	struct calling_interface_token *token;
 	int ret;
 
@@ -860,17 +893,21 @@ static int dell_send_intensity(struct backlight_device *bd)
 	if (!token)
 		return -ENODEV;
 
-	dell_set_arguments(token->location, bd->props.brightness, 0, 0);
+	dell_fill_request(&buffer,
+			   token->location, bd->props.brightness, 0, 0);
 	if (power_supply_is_system_supplied() > 0)
-		ret = dell_send_request(CLASS_TOKEN_WRITE, SELECT_TOKEN_AC);
+		ret = dell_send_request(&buffer,
+					CLASS_TOKEN_WRITE, SELECT_TOKEN_AC);
 	else
-		ret = dell_send_request(CLASS_TOKEN_WRITE, SELECT_TOKEN_BAT);
+		ret = dell_send_request(&buffer,
+					CLASS_TOKEN_WRITE, SELECT_TOKEN_BAT);
 
 	return ret;
 }
 
 static int dell_get_intensity(struct backlight_device *bd)
 {
+	struct calling_interface_buffer buffer;
 	struct calling_interface_token *token;
 	int ret;
 
@@ -878,14 +915,17 @@ static int dell_get_intensity(struct backlight_device *bd)
 	if (!token)
 		return -ENODEV;
 
-	dell_set_arguments(token->location, 0, 0, 0);
+	dell_fill_request(&buffer, token->location, 0, 0, 0);
 	if (power_supply_is_system_supplied() > 0)
-		ret = dell_send_request(CLASS_TOKEN_READ, SELECT_TOKEN_AC);
+		ret = dell_send_request(&buffer,
+					CLASS_TOKEN_READ, SELECT_TOKEN_AC);
 	else
-		ret = dell_send_request(CLASS_TOKEN_READ, SELECT_TOKEN_BAT);
+		ret = dell_send_request(&buffer,
+					CLASS_TOKEN_READ, SELECT_TOKEN_BAT);
 
 	if (ret == 0)
-		ret = buffer->output[1];
+		ret = buffer.output[1];
+
 	return ret;
 }
 
@@ -1133,6 +1173,7 @@ static u8 kbd_previous_mode_bit;
 
 static bool kbd_led_present;
 static DEFINE_MUTEX(kbd_led_mutex);
+static enum led_brightness kbd_led_level;
 
 /*
  * NOTE: there are three ways to set the keyboard backlight level.
@@ -1149,31 +1190,33 @@ static DEFINE_MUTEX(kbd_led_mutex);
 
 static int kbd_get_info(struct kbd_info *info)
 {
+	struct calling_interface_buffer buffer;
 	u8 units;
 	int ret;
 
-	dell_set_arguments(0, 0, 0, 0);
-	ret = dell_send_request(CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
+	dell_fill_request(&buffer, 0, 0, 0, 0);
+	ret = dell_send_request(&buffer,
+				CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
 	if (ret)
 		return ret;
 
-	info->modes = buffer->output[1] & 0xFFFF;
-	info->type = (buffer->output[1] >> 24) & 0xFF;
-	info->triggers = buffer->output[2] & 0xFF;
-	units = (buffer->output[2] >> 8) & 0xFF;
-	info->levels = (buffer->output[2] >> 16) & 0xFF;
+	info->modes = buffer.output[1] & 0xFFFF;
+	info->type = (buffer.output[1] >> 24) & 0xFF;
+	info->triggers = buffer.output[2] & 0xFF;
+	units = (buffer.output[2] >> 8) & 0xFF;
+	info->levels = (buffer.output[2] >> 16) & 0xFF;
 
 	if (quirks && quirks->kbd_led_levels_off_1 && info->levels)
 		info->levels--;
 
 	if (units & BIT(0))
-		info->seconds = (buffer->output[3] >> 0) & 0xFF;
+		info->seconds = (buffer.output[3] >> 0) & 0xFF;
 	if (units & BIT(1))
-		info->minutes = (buffer->output[3] >> 8) & 0xFF;
+		info->minutes = (buffer.output[3] >> 8) & 0xFF;
 	if (units & BIT(2))
-		info->hours = (buffer->output[3] >> 16) & 0xFF;
+		info->hours = (buffer.output[3] >> 16) & 0xFF;
 	if (units & BIT(3))
-		info->days = (buffer->output[3] >> 24) & 0xFF;
+		info->days = (buffer.output[3] >> 24) & 0xFF;
 
 	return ret;
 }
@@ -1233,31 +1276,34 @@ static int kbd_set_level(struct kbd_state *state, u8 level)
 
 static int kbd_get_state(struct kbd_state *state)
 {
+	struct calling_interface_buffer buffer;
 	int ret;
 
-	dell_set_arguments(0x1, 0, 0, 0);
-	ret = dell_send_request(CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
+	dell_fill_request(&buffer, 0, 0, 0, 0);
+	ret = dell_send_request(&buffer,
+				CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
 	if (ret)
 		return ret;
 
-	state->mode_bit = ffs(buffer->output[1] & 0xFFFF);
+	state->mode_bit = ffs(buffer.output[1] & 0xFFFF);
 	if (state->mode_bit != 0)
 		state->mode_bit--;
 
-	state->triggers = (buffer->output[1] >> 16) & 0xFF;
-	state->timeout_value = (buffer->output[1] >> 24) & 0x3F;
-	state->timeout_unit = (buffer->output[1] >> 30) & 0x3;
-	state->als_setting = buffer->output[2] & 0xFF;
-	state->als_value = (buffer->output[2] >> 8) & 0xFF;
-	state->level = (buffer->output[2] >> 16) & 0xFF;
-	state->timeout_value_ac = (buffer->output[2] >> 24) & 0x3F;
-	state->timeout_unit_ac = (buffer->output[2] >> 30) & 0x3;
+	state->triggers = (buffer.output[1] >> 16) & 0xFF;
+	state->timeout_value = (buffer.output[1] >> 24) & 0x3F;
+	state->timeout_unit = (buffer.output[1] >> 30) & 0x3;
+	state->als_setting = buffer.output[2] & 0xFF;
+	state->als_value = (buffer.output[2] >> 8) & 0xFF;
+	state->level = (buffer.output[2] >> 16) & 0xFF;
+	state->timeout_value_ac = (buffer.output[2] >> 24) & 0x3F;
+	state->timeout_unit_ac = (buffer.output[2] >> 30) & 0x3;
 
 	return ret;
 }
 
 static int kbd_set_state(struct kbd_state *state)
 {
+	struct calling_interface_buffer buffer;
 	int ret;
 	u32 input1;
 	u32 input2;
@@ -1270,8 +1316,9 @@ static int kbd_set_state(struct kbd_state *state)
 	input2 |= (state->level & 0xFF) << 16;
 	input2 |= (state->timeout_value_ac & 0x3F) << 24;
 	input2 |= (state->timeout_unit_ac & 0x3) << 30;
-	dell_set_arguments(0x2, input1, input2, 0);
-	ret = dell_send_request(CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
+	dell_fill_request(&buffer, 0x2, input1, input2, 0);
+	ret = dell_send_request(&buffer,
+				CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
 
 	return ret;
 }
@@ -1298,6 +1345,7 @@ static int kbd_set_state_safe(struct kbd_state *state, struct kbd_state *old)
 
 static int kbd_set_token_bit(u8 bit)
 {
+	struct calling_interface_buffer buffer;
 	struct calling_interface_token *token;
 	int ret;
 
@@ -1308,14 +1356,15 @@ static int kbd_set_token_bit(u8 bit)
 	if (!token)
 		return -EINVAL;
 
-	dell_set_arguments(token->location, token->value, 0, 0);
-	ret = dell_send_request(CLASS_TOKEN_WRITE, SELECT_TOKEN_STD);
+	dell_fill_request(&buffer, token->location, token->value, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_TOKEN_WRITE, SELECT_TOKEN_STD);
 
 	return ret;
 }
 
 static int kbd_get_token_bit(u8 bit)
 {
+	struct calling_interface_buffer buffer;
 	struct calling_interface_token *token;
 	int ret;
 	int val;
@@ -1327,9 +1376,9 @@ static int kbd_get_token_bit(u8 bit)
 	if (!token)
 		return -EINVAL;
 
-	dell_set_arguments(token->location, 0, 0, 0);
-	ret = dell_send_request(CLASS_TOKEN_READ, SELECT_TOKEN_STD);
-	val = buffer->output[1];
+	dell_fill_request(&buffer, token->location, 0, 0, 0);
+	ret = dell_send_request(&buffer, CLASS_TOKEN_READ, SELECT_TOKEN_STD);
+	val = buffer.output[1];
 
 	if (ret)
 		return ret;
@@ -1947,6 +1996,7 @@ static enum led_brightness kbd_led_level_get(struct led_classdev *led_cdev)
 static int kbd_led_level_set(struct led_classdev *led_cdev,
 			     enum led_brightness value)
 {
+	enum led_brightness new_value = value;
 	struct kbd_state state;
 	struct kbd_state new_state;
 	u16 num;
@@ -1976,6 +2026,9 @@ static int kbd_led_level_set(struct led_classdev *led_cdev,
 	}
 
 out:
+	if (ret == 0)
+		kbd_led_level = new_value;
+
 	mutex_unlock(&kbd_led_mutex);
 	return ret;
 }
@@ -2003,6 +2056,9 @@ static int __init kbd_led_init(struct device *dev)
 		if (kbd_led.max_brightness)
 			kbd_led.max_brightness--;
 	}
+
+	kbd_led_level = kbd_led_level_get(NULL);
+
 	ret = led_classdev_register(dev, &kbd_led);
 	if (ret)
 		kbd_led_present = false;
@@ -2027,13 +2083,25 @@ static void kbd_led_exit(void)
 static int dell_laptop_notifier_call(struct notifier_block *nb,
 				     unsigned long action, void *data)
 {
+	bool changed = false;
+	enum led_brightness new_kbd_led_level;
+
 	switch (action) {
 	case DELL_LAPTOP_KBD_BACKLIGHT_BRIGHTNESS_CHANGED:
 		if (!kbd_led_present)
 			break;
 
-		led_classdev_notify_brightness_hw_changed(&kbd_led,
-						kbd_led_level_get(&kbd_led));
+		mutex_lock(&kbd_led_mutex);
+		new_kbd_led_level = kbd_led_level_get(&kbd_led);
+		if (kbd_led_level != new_kbd_led_level) {
+			kbd_led_level = new_kbd_led_level;
+			changed = true;
+		}
+		mutex_unlock(&kbd_led_mutex);
+
+		if (changed)
+			led_classdev_notify_brightness_hw_changed(&kbd_led,
+								kbd_led_level);
 		break;
 	}
 
@@ -2046,6 +2114,7 @@ static struct notifier_block dell_laptop_notifier = {
 
 int dell_micmute_led_set(int state)
 {
+	struct calling_interface_buffer buffer;
 	struct calling_interface_token *token;
 
 	if (state == 0)
@@ -2058,8 +2127,8 @@ int dell_micmute_led_set(int state)
 	if (!token)
 		return -ENODEV;
 
-	dell_set_arguments(token->location, token->value, 0, 0);
-	dell_send_request(CLASS_TOKEN_WRITE, SELECT_TOKEN_STD);
+	dell_fill_request(&buffer, token->location, token->value, 0, 0);
+	dell_send_request(&buffer, CLASS_TOKEN_WRITE, SELECT_TOKEN_STD);
 
 	return state;
 }
@@ -2090,13 +2159,6 @@ static int __init dell_init(void)
 	if (ret)
 		goto fail_platform_device2;
 
-	buffer = kzalloc(sizeof(struct calling_interface_buffer), GFP_KERNEL);
-	if (!buffer) {
-		ret = -ENOMEM;
-		goto fail_buffer;
-	}
-
-
 	ret = dell_setup_rfkill();
 
 	if (ret) {
@@ -2121,10 +2183,13 @@ static int __init dell_init(void)
 
 	token = dell_smbios_find_token(BRIGHTNESS_TOKEN);
 	if (token) {
-		dell_set_arguments(token->location, 0, 0, 0);
-		ret = dell_send_request(CLASS_TOKEN_READ, SELECT_TOKEN_AC);
+		struct calling_interface_buffer buffer;
+
+		dell_fill_request(&buffer, token->location, 0, 0, 0);
+		ret = dell_send_request(&buffer,
+					CLASS_TOKEN_READ, SELECT_TOKEN_AC);
 		if (ret)
-			max_intensity = buffer->output[3];
+			max_intensity = buffer.output[3];
 	}
 
 	if (max_intensity) {
@@ -2158,8 +2223,6 @@ static int __init dell_init(void)
 fail_get_brightness:
 	backlight_device_unregister(dell_backlight_device);
 fail_backlight:
-	kfree(buffer);
-fail_buffer:
 	dell_cleanup_rfkill();
 fail_rfkill:
 	platform_device_del(platform_device);
@@ -2179,7 +2242,6 @@ static void __exit dell_exit(void)
 		touchpad_led_exit();
 	kbd_led_exit();
 	backlight_device_unregister(dell_backlight_device);
-	kfree(buffer);
 	dell_cleanup_rfkill();
 	if (platform_device) {
 		platform_device_unregister(platform_device);
diff --git a/drivers/platform/x86/dell-smbios.c b/drivers/platform/x86/dell-smbios.c
index 6a60db5..8541cde 100644
--- a/drivers/platform/x86/dell-smbios.c
+++ b/drivers/platform/x86/dell-smbios.c
@@ -65,10 +65,10 @@ static struct smbios_call call_whitelist[] = {
 
 /* calls that are explicitly blacklisted */
 static struct smbios_call call_blacklist[] = {
-	{0x0000, 01, 07}, /* manufacturing use */
-	{0x0000, 06, 05}, /* manufacturing use */
-	{0x0000, 11, 03}, /* write once */
-	{0x0000, 11, 07}, /* write once */
+	{0x0000,  1,  7}, /* manufacturing use */
+	{0x0000,  6,  5}, /* manufacturing use */
+	{0x0000, 11,  3}, /* write once */
+	{0x0000, 11,  7}, /* write once */
 	{0x0000, 11, 11}, /* write once */
 	{0x0000, 19, -1}, /* diagnostics */
 	/* handled by kernel: dell-laptop */
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
index fb25b20..2c99274 100644
--- a/drivers/platform/x86/dell-wmi.c
+++ b/drivers/platform/x86/dell-wmi.c
@@ -261,6 +261,9 @@ static const u16 bios_to_linux_keycode[256] = {
  * override them.
  */
 static const struct key_entry dell_wmi_keymap_type_0010[] = {
+	/* Mic mute */
+	{ KE_KEY, 0x150, { KEY_MICMUTE } },
+
 	/* Fn-lock */
 	{ KE_IGNORE, 0x151, { KEY_RESERVED } },
 
diff --git a/drivers/platform/x86/gpd-pocket-fan.c b/drivers/platform/x86/gpd-pocket-fan.c
new file mode 100644
index 0000000..2d645c5
--- /dev/null
+++ b/drivers/platform/x86/gpd-pocket-fan.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * GPD Pocket fan controller driver
+ *
+ * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/thermal.h>
+#include <linux/workqueue.h>
+
+#define MAX_SPEED 3
+
+static int temp_limits[3] = { 55000, 60000, 65000 };
+module_param_array(temp_limits, int, NULL, 0444);
+MODULE_PARM_DESC(temp_limits,
+		 "Milli-celcius values above which the fan speed increases");
+
+static int hysteresis = 3000;
+module_param(hysteresis, int, 0444);
+MODULE_PARM_DESC(hysteresis,
+		 "Hysteresis in milli-celcius before lowering the fan speed");
+
+static int speed_on_ac = 2;
+module_param(speed_on_ac, int, 0444);
+MODULE_PARM_DESC(speed_on_ac,
+		 "minimum fan speed to allow when system is powered by AC");
+
+struct gpd_pocket_fan_data {
+	struct device *dev;
+	struct thermal_zone_device *dts0;
+	struct thermal_zone_device *dts1;
+	struct gpio_desc *gpio0;
+	struct gpio_desc *gpio1;
+	struct delayed_work work;
+	int last_speed;
+};
+
+static void gpd_pocket_fan_set_speed(struct gpd_pocket_fan_data *fan, int speed)
+{
+	if (speed == fan->last_speed)
+		return;
+
+	gpiod_direction_output(fan->gpio0, !!(speed & 1));
+	gpiod_direction_output(fan->gpio1, !!(speed & 2));
+
+	fan->last_speed = speed;
+}
+
+static int gpd_pocket_fan_min_speed(void)
+{
+	if (power_supply_is_system_supplied())
+		return speed_on_ac;
+	else
+		return 0;
+}
+
+static void gpd_pocket_fan_worker(struct work_struct *work)
+{
+	struct gpd_pocket_fan_data *fan =
+		container_of(work, struct gpd_pocket_fan_data, work.work);
+	int t0, t1, temp, speed, min_speed, i;
+
+	if (thermal_zone_get_temp(fan->dts0, &t0) ||
+	    thermal_zone_get_temp(fan->dts1, &t1)) {
+		dev_warn(fan->dev, "Error getting temperature\n");
+		speed = MAX_SPEED;
+		goto set_speed;
+	}
+
+	temp = max(t0, t1);
+
+	speed = fan->last_speed;
+	min_speed = gpd_pocket_fan_min_speed();
+
+	/* Determine minimum speed */
+	for (i = min_speed; i < ARRAY_SIZE(temp_limits); i++) {
+		if (temp < temp_limits[i])
+			break;
+	}
+	if (speed < i)
+		speed = i;
+
+	/* Use hysteresis before lowering speed again */
+	for (i = min_speed; i < ARRAY_SIZE(temp_limits); i++) {
+		if (temp <= (temp_limits[i] - hysteresis))
+			break;
+	}
+	if (speed > i)
+		speed = i;
+
+	if (fan->last_speed <= 0 && speed)
+		speed = MAX_SPEED; /* kick start motor */
+
+set_speed:
+	gpd_pocket_fan_set_speed(fan, speed);
+
+	/* When mostly idle (low temp/speed), slow down the poll interval. */
+	queue_delayed_work(system_wq, &fan->work,
+			   msecs_to_jiffies(4000 / (speed + 1)));
+}
+
+static void gpd_pocket_fan_force_update(struct gpd_pocket_fan_data *fan)
+{
+	fan->last_speed = -1;
+	mod_delayed_work(system_wq, &fan->work, 0);
+}
+
+static int gpd_pocket_fan_probe(struct platform_device *pdev)
+{
+	struct gpd_pocket_fan_data *fan;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(temp_limits); i++) {
+		if (temp_limits[i] < 40000 || temp_limits[i] > 70000) {
+			dev_err(&pdev->dev, "Invalid temp-limit %d (must be between 40000 and 70000)\n",
+				temp_limits[i]);
+			return -EINVAL;
+		}
+	}
+	if (hysteresis < 1000 || hysteresis > 10000) {
+		dev_err(&pdev->dev, "Invalid hysteresis %d (must be between 1000 and 10000)\n",
+			hysteresis);
+		return -EINVAL;
+	}
+	if (speed_on_ac < 0 || speed_on_ac > MAX_SPEED) {
+		dev_err(&pdev->dev, "Invalid speed_on_ac %d (must be between 0 and 3)\n",
+			speed_on_ac);
+		return -EINVAL;
+	}
+
+	fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL);
+	if (!fan)
+		return -ENOMEM;
+
+	fan->dev = &pdev->dev;
+	INIT_DELAYED_WORK(&fan->work, gpd_pocket_fan_worker);
+
+	/* Note this returns a "weak" reference which we don't need to free */
+	fan->dts0 = thermal_zone_get_zone_by_name("soc_dts0");
+	if (IS_ERR(fan->dts0))
+		return -EPROBE_DEFER;
+
+	fan->dts1 = thermal_zone_get_zone_by_name("soc_dts1");
+	if (IS_ERR(fan->dts1))
+		return -EPROBE_DEFER;
+
+	fan->gpio0 = devm_gpiod_get_index(fan->dev, NULL, 0, GPIOD_ASIS);
+	if (IS_ERR(fan->gpio0))
+		return PTR_ERR(fan->gpio0);
+
+	fan->gpio1 = devm_gpiod_get_index(fan->dev, NULL, 1, GPIOD_ASIS);
+	if (IS_ERR(fan->gpio1))
+		return PTR_ERR(fan->gpio1);
+
+	gpd_pocket_fan_force_update(fan);
+
+	platform_set_drvdata(pdev, fan);
+	return 0;
+}
+
+static int gpd_pocket_fan_remove(struct platform_device *pdev)
+{
+	struct gpd_pocket_fan_data *fan = platform_get_drvdata(pdev);
+
+	cancel_delayed_work_sync(&fan->work);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int gpd_pocket_fan_suspend(struct device *dev)
+{
+	struct gpd_pocket_fan_data *fan = dev_get_drvdata(dev);
+
+	cancel_delayed_work_sync(&fan->work);
+	gpd_pocket_fan_set_speed(fan, gpd_pocket_fan_min_speed());
+	return 0;
+}
+
+static int gpd_pocket_fan_resume(struct device *dev)
+{
+	struct gpd_pocket_fan_data *fan = dev_get_drvdata(dev);
+
+	gpd_pocket_fan_force_update(fan);
+	return 0;
+}
+#endif
+static SIMPLE_DEV_PM_OPS(gpd_pocket_fan_pm_ops,
+			 gpd_pocket_fan_suspend,
+			 gpd_pocket_fan_resume);
+
+static struct acpi_device_id gpd_pocket_fan_acpi_match[] = {
+	{ "FAN02501" },
+	{},
+};
+MODULE_DEVICE_TABLE(acpi, gpd_pocket_fan_acpi_match);
+
+static struct platform_driver gpd_pocket_fan_driver = {
+	.probe	= gpd_pocket_fan_probe,
+	.remove	= gpd_pocket_fan_remove,
+	.driver	= {
+		.name			= "gpd_pocket_fan",
+		.acpi_match_table	= gpd_pocket_fan_acpi_match,
+		.pm			= &gpd_pocket_fan_pm_ops,
+	 },
+};
+
+module_platform_driver(gpd_pocket_fan_driver);
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com");
+MODULE_DESCRIPTION("GPD pocket fan driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 53ab4e0..5b6f18b18 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -124,10 +124,10 @@ static int read_method_int(acpi_handle handle, const char *method, int *val)
 	if (ACPI_FAILURE(status)) {
 		*val = -1;
 		return -1;
-	} else {
-		*val = result;
-		return 0;
 	}
+	*val = result;
+	return 0;
+
 }
 
 static int method_gbmd(acpi_handle handle, unsigned long *ret)
@@ -164,10 +164,10 @@ static int method_vpcr(acpi_handle handle, int cmd, int *ret)
 	if (ACPI_FAILURE(status)) {
 		*ret = -1;
 		return -1;
-	} else {
-		*ret = result;
-		return 0;
 	}
+	*ret = result;
+	return 0;
+
 }
 
 static int method_vpcw(acpi_handle handle, int cmd, int data)
@@ -231,7 +231,7 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data)
 		if (val == 0)
 			return 0;
 	}
-	pr_err("timeout in write_ec_cmd\n");
+	pr_err("timeout in %s\n", __func__);
 	return -1;
 }
 
@@ -284,19 +284,7 @@ static int debugfs_status_show(struct seq_file *s, void *data)
 
 	return 0;
 }
-
-static int debugfs_status_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, debugfs_status_show, inode->i_private);
-}
-
-static const struct file_operations debugfs_status_fops = {
-	.owner = THIS_MODULE,
-	.open = debugfs_status_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(debugfs_status);
 
 static int debugfs_cfg_show(struct seq_file *s, void *data)
 {
@@ -337,19 +325,7 @@ static int debugfs_cfg_show(struct seq_file *s, void *data)
 	}
 	return 0;
 }
-
-static int debugfs_cfg_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, debugfs_cfg_show, inode->i_private);
-}
-
-static const struct file_operations debugfs_cfg_fops = {
-	.owner = THIS_MODULE,
-	.open = debugfs_cfg_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(debugfs_cfg);
 
 static int ideapad_debugfs_init(struct ideapad_private *priv)
 {
@@ -964,6 +940,13 @@ static void ideapad_wmi_notify(u32 value, void *context)
  */
 static const struct dmi_system_id no_hw_rfkill_list[] = {
 	{
+		.ident = "Lenovo RESCUER R720-15IKBN",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_BOARD_NAME, "80WW"),
+		},
+	},
+	{
 		.ident = "Lenovo G40-30",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
@@ -1104,6 +1087,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
 		},
 	},
 	{
+		.ident = "Lenovo Legion Y720-15IKB",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y720-15IKB"),
+		},
+	},
+	{
 		.ident = "Lenovo Legion Y720-15IKBN",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c
index f470279..d1a0131 100644
--- a/drivers/platform/x86/intel-hid.c
+++ b/drivers/platform/x86/intel-hid.c
@@ -25,6 +25,7 @@
 #include <linux/acpi.h>
 #include <linux/suspend.h>
 #include <acpi/acpi_bus.h>
+#include <linux/dmi.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Alex Hung");
@@ -73,6 +74,24 @@ static const struct key_entry intel_array_keymap[] = {
 	{ KE_END },
 };
 
+static const struct dmi_system_id button_array_table[] = {
+	{
+		.ident = "Wacom MobileStudio Pro 13",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Wacom Co.,Ltd"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Wacom MobileStudio Pro 13"),
+		},
+	},
+	{
+		.ident = "Wacom MobileStudio Pro 16",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Wacom Co.,Ltd"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Wacom MobileStudio Pro 16"),
+		},
+	},
+	{ }
+};
+
 struct intel_hid_priv {
 	struct input_dev *input_dev;
 	struct input_dev *array;
@@ -263,10 +282,27 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
 			 ev_index);
 }
 
+static bool button_array_present(struct platform_device *device)
+{
+	acpi_handle handle = ACPI_HANDLE(&device->dev);
+	unsigned long long event_cap;
+	acpi_status status;
+	bool supported = false;
+
+	status = acpi_evaluate_integer(handle, "HEBC", NULL, &event_cap);
+	if (ACPI_SUCCESS(status) && (event_cap & 0x20000))
+		supported = true;
+
+	if (dmi_check_system(button_array_table))
+		supported = true;
+
+	return supported;
+}
+
 static int intel_hid_probe(struct platform_device *device)
 {
 	acpi_handle handle = ACPI_HANDLE(&device->dev);
-	unsigned long long event_cap, mode;
+	unsigned long long mode;
 	struct intel_hid_priv *priv;
 	acpi_status status;
 	int err;
@@ -299,8 +335,7 @@ static int intel_hid_probe(struct platform_device *device)
 	}
 
 	/* Setup 5 button array */
-	status = acpi_evaluate_integer(handle, "HEBC", NULL, &event_cap);
-	if (ACPI_SUCCESS(status) && (event_cap & 0x20000)) {
+	if (button_array_present(device)) {
 		dev_info(&device->dev, "platform supports 5 button array\n");
 		err = intel_button_array_input_setup(device);
 		if (err)
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
index 58c5ff3..b703d6f 100644
--- a/drivers/platform/x86/intel-vbtn.c
+++ b/drivers/platform/x86/intel-vbtn.c
@@ -1,30 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  Intel Virtual Button driver for Windows 8.1+
  *
  *  Copyright (C) 2016 AceLan Kao <acelan.kao@canonical.com>
  *  Copyright (C) 2016 Alex Hung <alex.hung@canonical.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
  */
 
+#include <linux/acpi.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/init.h>
-#include <linux/input.h>
 #include <linux/platform_device.h>
-#include <linux/input/sparse-keymap.h>
-#include <linux/acpi.h>
 #include <linux/suspend.h>
-#include <acpi/acpi_bus.h>
+
+/* When NOT in tablet mode, VGBS returns with the flag 0x40 */
+#define TABLET_MODE_FLAG 0x40
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("AceLan Kao");
@@ -38,10 +29,16 @@ static const struct acpi_device_id intel_vbtn_ids[] = {
 static const struct key_entry intel_vbtn_keymap[] = {
 	{ KE_KEY, 0xC0, { KEY_POWER } },	/* power key press */
 	{ KE_IGNORE, 0xC1, { KEY_POWER } },	/* power key release */
+	{ KE_KEY, 0xC2, { KEY_LEFTMETA } },		/* 'Windows' key press */
+	{ KE_KEY, 0xC3, { KEY_LEFTMETA } },		/* 'Windows' key release */
 	{ KE_KEY, 0xC4, { KEY_VOLUMEUP } },		/* volume-up key press */
 	{ KE_IGNORE, 0xC5, { KEY_VOLUMEUP } },		/* volume-up key release */
 	{ KE_KEY, 0xC6, { KEY_VOLUMEDOWN } },		/* volume-down key press */
 	{ KE_IGNORE, 0xC7, { KEY_VOLUMEDOWN } },	/* volume-down key release */
+	{ KE_KEY,    0xC8, { KEY_ROTATE_LOCK_TOGGLE } },	/* rotate-lock key press */
+	{ KE_KEY,    0xC9, { KEY_ROTATE_LOCK_TOGGLE } },	/* rotate-lock key release */
+	{ KE_SW,     0xCC, { .sw = { SW_TABLET_MODE, 1 } } },	/* Tablet */
+	{ KE_SW,     0xCD, { .sw = { SW_TABLET_MODE, 0 } } },	/* Laptop */
 	{ KE_END },
 };
 
@@ -74,20 +71,35 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
 {
 	struct platform_device *device = context;
 	struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
+	unsigned int val = !(event & 1); /* Even=press, Odd=release */
+	const struct key_entry *ke_rel;
+	bool autorelease;
 
 	if (priv->wakeup_mode) {
 		if (sparse_keymap_entry_from_scancode(priv->input_dev, event)) {
 			pm_wakeup_hard_event(&device->dev);
 			return;
 		}
-	} else if (sparse_keymap_report_event(priv->input_dev, event, 1, true)) {
-		return;
+		goto out_unknown;
 	}
+
+	/*
+	 * Even press events are autorelease if there is no corresponding odd
+	 * release event, or if the odd event is KE_IGNORE.
+	 */
+	ke_rel = sparse_keymap_entry_from_scancode(priv->input_dev, event | 1);
+	autorelease = val && (!ke_rel || ke_rel->type == KE_IGNORE);
+
+	if (sparse_keymap_report_event(priv->input_dev, event, val, autorelease))
+		return;
+
+out_unknown:
 	dev_dbg(&device->dev, "unknown event index 0x%x\n", event);
 }
 
 static int intel_vbtn_probe(struct platform_device *device)
 {
+	struct acpi_buffer vgbs_output = { ACPI_ALLOCATE_BUFFER, NULL };
 	acpi_handle handle = ACPI_HANDLE(&device->dev);
 	struct intel_vbtn_priv *priv;
 	acpi_status status;
@@ -110,6 +122,23 @@ static int intel_vbtn_probe(struct platform_device *device)
 		return err;
 	}
 
+	/*
+	 * VGBS being present and returning something means we have
+	 * a tablet mode switch.
+	 */
+	status = acpi_evaluate_object(handle, "VGBS", NULL, &vgbs_output);
+	if (ACPI_SUCCESS(status)) {
+		union acpi_object *obj = vgbs_output.pointer;
+
+		if (obj && obj->type == ACPI_TYPE_INTEGER) {
+			int m = !(obj->integer.value & TABLET_MODE_FLAG);
+
+			input_report_switch(priv->input_dev, SW_TABLET_MODE, m);
+		}
+	}
+
+	kfree(vgbs_output.pointer);
+
 	status = acpi_install_notify_handler(handle,
 					     ACPI_DEVICE_NOTIFY,
 					     notify_handler,
diff --git a/drivers/platform/x86/intel_chtdc_ti_pwrbtn.c b/drivers/platform/x86/intel_chtdc_ti_pwrbtn.c
new file mode 100644
index 0000000..38b8e7c
--- /dev/null
+++ b/drivers/platform/x86/intel_chtdc_ti_pwrbtn.c
@@ -0,0 +1,93 @@
+/*
+ * Power-button driver for Dollar Cove TI PMIC
+ * Copyright (C) 2014 Intel Corp
+ * Copyright (c) 2017 Takashi Iwai <tiwai@suse.de>
+ */
+
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/mfd/intel_soc_pmic.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
+#include <linux/slab.h>
+
+#define CHTDC_TI_SIRQ_REG	0x3
+#define SIRQ_PWRBTN_REL		BIT(0)
+
+static irqreturn_t chtdc_ti_pwrbtn_interrupt(int irq, void *dev_id)
+{
+	struct input_dev *input = dev_id;
+	struct device *dev = input->dev.parent;
+	struct regmap *regmap = dev_get_drvdata(dev);
+	int state;
+
+	if (!regmap_read(regmap, CHTDC_TI_SIRQ_REG, &state)) {
+		dev_dbg(dev, "SIRQ_REG=0x%x\n", state);
+		input_report_key(input, KEY_POWER, !(state & SIRQ_PWRBTN_REL));
+		input_sync(input);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int chtdc_ti_pwrbtn_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct intel_soc_pmic *pmic = dev_get_drvdata(dev->parent);
+	struct input_dev *input;
+	int irq, err;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+	input = devm_input_allocate_device(dev);
+	if (!input)
+		return -ENOMEM;
+	input->name = pdev->name;
+	input->phys = "power-button/input0";
+	input->id.bustype = BUS_HOST;
+	input_set_capability(input, EV_KEY, KEY_POWER);
+	err = input_register_device(input);
+	if (err)
+		return err;
+
+	dev_set_drvdata(dev, pmic->regmap);
+
+	err = devm_request_threaded_irq(dev, irq, NULL,
+					chtdc_ti_pwrbtn_interrupt,
+					0, KBUILD_MODNAME, input);
+	if (err)
+		return err;
+
+	device_init_wakeup(dev, true);
+	dev_pm_set_wake_irq(dev, irq);
+	return 0;
+}
+
+static int chtdc_ti_pwrbtn_remove(struct platform_device *pdev)
+{
+	dev_pm_clear_wake_irq(&pdev->dev);
+	device_init_wakeup(&pdev->dev, false);
+	return 0;
+}
+
+static const struct platform_device_id chtdc_ti_pwrbtn_id_table[] = {
+	{ .name = "chtdc_ti_pwrbtn" },
+	{},
+};
+MODULE_DEVICE_TABLE(platform, chtdc_ti_pwrbtn_id_table);
+
+static struct platform_driver chtdc_ti_pwrbtn_driver = {
+	.driver = {
+		.name	= KBUILD_MODNAME,
+	},
+	.probe		= chtdc_ti_pwrbtn_probe,
+	.remove		= chtdc_ti_pwrbtn_remove,
+	.id_table	= chtdc_ti_pwrbtn_id_table,
+};
+module_platform_driver(chtdc_ti_pwrbtn_driver);
+
+MODULE_DESCRIPTION("Power-button driver for Dollar Cove TI PMIC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c
index f7b67e8..a473dc5 100644
--- a/drivers/platform/x86/intel_int0002_vgpio.c
+++ b/drivers/platform/x86/intel_int0002_vgpio.c
@@ -180,7 +180,7 @@ static int int0002_probe(struct platform_device *pdev)
 	 * to gpiochip_set_chained_irqchip, because the irq is shared.
 	 */
 	ret = devm_request_irq(dev, irq, int0002_irq,
-			       IRQF_SHARED | IRQF_NO_THREAD, "INT0002", chip);
+			       IRQF_SHARED, "INT0002", chip);
 	if (ret) {
 		dev_err(dev, "Error requesting IRQ %d: %d\n", irq, ret);
 		return ret;
diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index 17e08b4..43bbe747 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -18,20 +18,24 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/acpi.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/init.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/uaccess.h>
 
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
-#include <asm/pmc_core.h>
 
 #include "intel_pmc_core.h"
 
+#define ICPU(model, data) \
+	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (kernel_ulong_t)data }
+
 static struct pmc_dev pmc;
 
 static const struct pmc_bit_map spt_pll_map[] = {
@@ -119,10 +123,88 @@ static const struct pmc_reg_map spt_reg_map = {
 	.pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT,
 };
 
-static const struct pci_device_id pmc_pci_ids[] = {
-	{ PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID),
-					(kernel_ulong_t)&spt_reg_map },
-	{ 0, },
+/* Cannonlake: PGD PFET Enable Ack Status Register(s) bitmap */
+static const struct pmc_bit_map cnp_pfear_map[] = {
+	{"PMC",                 BIT(0)},
+	{"OPI-DMI",             BIT(1)},
+	{"SPI/eSPI",            BIT(2)},
+	{"XHCI",                BIT(3)},
+	{"SPA",                 BIT(4)},
+	{"SPB",                 BIT(5)},
+	{"SPC",                 BIT(6)},
+	{"GBE",                 BIT(7)},
+
+	{"SATA",                BIT(0)},
+	{"HDA_PGD0",            BIT(1)},
+	{"HDA_PGD1",            BIT(2)},
+	{"HDA_PGD2",            BIT(3)},
+	{"HDA_PGD3",            BIT(4)},
+	{"SPD",                 BIT(5)},
+	{"LPSS",                BIT(6)},
+	{"LPC",                 BIT(7)},
+
+	{"SMB",                 BIT(0)},
+	{"ISH",                 BIT(1)},
+	{"P2SB",                BIT(2)},
+	{"NPK_VNN",             BIT(3)},
+	{"SDX",                 BIT(4)},
+	{"SPE",                 BIT(5)},
+	{"Fuse",                BIT(6)},
+	{"Res_23",              BIT(7)},
+
+	{"CSME_FSC",            BIT(0)},
+	{"USB3_OTG",            BIT(1)},
+	{"EXI",                 BIT(2)},
+	{"CSE",                 BIT(3)},
+	{"csme_kvm",            BIT(4)},
+	{"csme_pmt",            BIT(5)},
+	{"csme_clink",          BIT(6)},
+	{"csme_ptio",           BIT(7)},
+
+	{"csme_usbr",           BIT(0)},
+	{"csme_susram",         BIT(1)},
+	{"csme_smt1",           BIT(2)},
+	{"CSME_SMT4",           BIT(3)},
+	{"csme_sms2",           BIT(4)},
+	{"csme_sms1",           BIT(5)},
+	{"csme_rtc",            BIT(6)},
+	{"csme_psf",            BIT(7)},
+
+	{"SBR0",                BIT(0)},
+	{"SBR1",                BIT(1)},
+	{"SBR2",                BIT(2)},
+	{"SBR3",                BIT(3)},
+	{"SBR4",                BIT(4)},
+	{"SBR5",                BIT(5)},
+	{"CSME_PECI",           BIT(6)},
+	{"PSF1",                BIT(7)},
+
+	{"PSF2",                BIT(0)},
+	{"PSF3",                BIT(1)},
+	{"PSF4",                BIT(2)},
+	{"CNVI",                BIT(3)},
+	{"UFS0",                BIT(4)},
+	{"EMMC",                BIT(5)},
+	{"Res_6",               BIT(6)},
+	{"SBR6",                BIT(7)},
+
+	{"SBR7",                BIT(0)},
+	{"NPK_AON",             BIT(1)},
+	{"HDA_PGD4",            BIT(2)},
+	{"HDA_PGD5",            BIT(3)},
+	{"HDA_PGD6",            BIT(4)},
+	{}
+};
+
+static const struct pmc_reg_map cnp_reg_map = {
+	.pfear_sts = cnp_pfear_map,
+	.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
+	.ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
+	.regmap_length = CNP_PMC_MMIO_REG_LEN,
+	.ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
+	.ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES,
+	.pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
+	.pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
 };
 
 static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset)
@@ -146,37 +228,6 @@ static inline u32 pmc_core_adjust_slp_s0_step(u32 value)
 	return value * SPT_PMC_SLP_S0_RES_COUNTER_STEP;
 }
 
-/**
- * intel_pmc_slp_s0_counter_read() - Read SLP_S0 residency.
- * @data: Out param that contains current SLP_S0 count.
- *
- * This API currently supports Intel Skylake SoC and Sunrise
- * Point Platform Controller Hub. Future platform support
- * should be added for platforms that support low power modes
- * beyond Package C10 state.
- *
- * SLP_S0_RESIDENCY counter counts in 100 us granularity per
- * step hence function populates the multiplied value in out
- * parameter @data.
- *
- * Return: an error code or 0 on success.
- */
-int intel_pmc_slp_s0_counter_read(u32 *data)
-{
-	struct pmc_dev *pmcdev = &pmc;
-	const struct pmc_reg_map *map = pmcdev->map;
-	u32 value;
-
-	if (!pmcdev->has_slp_s0_res)
-		return -EACCES;
-
-	value = pmc_core_reg_read(pmcdev, map->slp_s0_offset);
-	*data = pmc_core_adjust_slp_s0_step(value);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(intel_pmc_slp_s0_counter_read);
-
 static int pmc_core_dev_state_get(void *data, u64 *val)
 {
 	struct pmc_dev *pmcdev = data;
@@ -437,47 +488,33 @@ static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev)
 
 static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
 {
-	struct dentry *dir, *file;
+	struct dentry *dir;
 
 	dir = debugfs_create_dir("pmc_core", NULL);
 	if (!dir)
 		return -ENOMEM;
 
 	pmcdev->dbgfs_dir = dir;
-	file = debugfs_create_file("slp_s0_residency_usec", S_IFREG | S_IRUGO,
-				   dir, pmcdev, &pmc_core_dev_state);
-	if (!file)
-		goto err;
 
-	file = debugfs_create_file("pch_ip_power_gating_status",
-				   S_IFREG | S_IRUGO, dir, pmcdev,
-				   &pmc_core_ppfear_ops);
-	if (!file)
-		goto err;
+	debugfs_create_file("slp_s0_residency_usec", 0444, dir, pmcdev,
+			    &pmc_core_dev_state);
 
-	file = debugfs_create_file("mphy_core_lanes_power_gating_status",
-				   S_IFREG | S_IRUGO, dir, pmcdev,
-				   &pmc_core_mphy_pg_ops);
-	if (!file)
-		goto err;
+	debugfs_create_file("pch_ip_power_gating_status", 0444, dir, pmcdev,
+			    &pmc_core_ppfear_ops);
 
-	file = debugfs_create_file("pll_status",
-				   S_IFREG | S_IRUGO, dir, pmcdev,
-				   &pmc_core_pll_ops);
-	if (!file)
-		goto err;
+	debugfs_create_file("ltr_ignore", 0644, dir, pmcdev,
+			    &pmc_core_ltr_ignore_ops);
 
-	file = debugfs_create_file("ltr_ignore",
-				   S_IFREG | S_IRUGO, dir, pmcdev,
-				   &pmc_core_ltr_ignore_ops);
+	if (pmcdev->map->pll_sts)
+		debugfs_create_file("pll_status", 0444, dir, pmcdev,
+				    &pmc_core_pll_ops);
 
-	if (!file)
-		goto err;
+	if (pmcdev->map->mphy_sts)
+		debugfs_create_file("mphy_core_lanes_power_gating_status",
+				    0444, dir, pmcdev,
+				    &pmc_core_mphy_pg_ops);
 
 	return 0;
-err:
-	pmc_core_dbgfs_unregister(pmcdev);
-	return -ENODEV;
 }
 #else
 static inline int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
@@ -491,71 +528,76 @@ static inline void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev)
 #endif /* CONFIG_DEBUG_FS */
 
 static const struct x86_cpu_id intel_pmc_core_ids[] = {
-	{ X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_MOBILE, X86_FEATURE_MWAIT,
-		(kernel_ulong_t)NULL},
-	{ X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_DESKTOP, X86_FEATURE_MWAIT,
-		(kernel_ulong_t)NULL},
-	{ X86_VENDOR_INTEL, 6, INTEL_FAM6_KABYLAKE_MOBILE, X86_FEATURE_MWAIT,
-		(kernel_ulong_t)NULL},
-	{ X86_VENDOR_INTEL, 6, INTEL_FAM6_KABYLAKE_DESKTOP, X86_FEATURE_MWAIT,
-		(kernel_ulong_t)NULL},
+	ICPU(INTEL_FAM6_SKYLAKE_MOBILE, &spt_reg_map),
+	ICPU(INTEL_FAM6_SKYLAKE_DESKTOP, &spt_reg_map),
+	ICPU(INTEL_FAM6_KABYLAKE_MOBILE, &spt_reg_map),
+	ICPU(INTEL_FAM6_KABYLAKE_DESKTOP, &spt_reg_map),
+	ICPU(INTEL_FAM6_CANNONLAKE_MOBILE, &cnp_reg_map),
 	{}
 };
 
-static int pmc_core_probe(struct pci_dev *dev, const struct pci_device_id *id)
+MODULE_DEVICE_TABLE(x86cpu, intel_pmc_core_ids);
+
+static const struct pci_device_id pmc_pci_ids[] = {
+	{ PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID), 0},
+	{ 0, },
+};
+
+static int __init pmc_core_probe(void)
 {
-	struct device *ptr_dev = &dev->dev;
 	struct pmc_dev *pmcdev = &pmc;
 	const struct x86_cpu_id *cpu_id;
-	const struct pmc_reg_map *map = (struct pmc_reg_map *)id->driver_data;
+	u64 slp_s0_addr;
 	int err;
 
 	cpu_id = x86_match_cpu(intel_pmc_core_ids);
-	if (!cpu_id) {
-		dev_dbg(&dev->dev, "PMC Core: cpuid mismatch.\n");
-		return -EINVAL;
-	}
+	if (!cpu_id)
+		return -ENODEV;
 
-	err = pcim_enable_device(dev);
-	if (err < 0) {
-		dev_dbg(&dev->dev, "PMC Core: failed to enable Power Management Controller.\n");
-		return err;
-	}
+	pmcdev->map = (struct pmc_reg_map *)cpu_id->driver_data;
 
-	err = pci_read_config_dword(dev,
-				    SPT_PMC_BASE_ADDR_OFFSET,
-				    &pmcdev->base_addr);
-	if (err < 0) {
-		dev_dbg(&dev->dev, "PMC Core: failed to read PCI config space.\n");
-		return err;
-	}
-	pmcdev->base_addr &= PMC_BASE_ADDR_MASK;
-	dev_dbg(&dev->dev, "PMC Core: PWRMBASE is %#x\n", pmcdev->base_addr);
+	/*
+	 * Coffeelake has CPU ID of Kabylake and Cannonlake PCH. So here
+	 * Sunrisepoint PCH regmap can't be used. Use Cannonlake PCH regmap
+	 * in this case.
+	 */
+	if (!pci_dev_present(pmc_pci_ids))
+		pmcdev->map = &cnp_reg_map;
 
-	pmcdev->regbase = devm_ioremap_nocache(ptr_dev,
-					      pmcdev->base_addr,
-					      SPT_PMC_MMIO_REG_LEN);
-	if (!pmcdev->regbase) {
-		dev_dbg(&dev->dev, "PMC Core: ioremap failed.\n");
+	if (lpit_read_residency_count_address(&slp_s0_addr))
+		pmcdev->base_addr = PMC_BASE_ADDR_DEFAULT;
+	else
+		pmcdev->base_addr = slp_s0_addr - pmcdev->map->slp_s0_offset;
+
+	pmcdev->regbase = ioremap(pmcdev->base_addr,
+				  pmcdev->map->regmap_length);
+	if (!pmcdev->regbase)
 		return -ENOMEM;
-	}
 
 	mutex_init(&pmcdev->lock);
-	pmcdev->map = map;
 	pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
 
 	err = pmc_core_dbgfs_register(pmcdev);
-	if (err < 0)
-		dev_warn(&dev->dev, "PMC Core: debugfs register failed.\n");
+	if (err < 0) {
+		pr_warn(" debugfs register failed.\n");
+		iounmap(pmcdev->regbase);
+		return err;
+	}
 
-	pmc.has_slp_s0_res = true;
+	pr_info(" initialized\n");
 	return 0;
 }
+module_init(pmc_core_probe)
 
-static struct pci_driver intel_pmc_core_driver = {
-	.name = "intel_pmc_core",
-	.id_table = pmc_pci_ids,
-	.probe = pmc_core_probe,
-};
+static void __exit pmc_core_remove(void)
+{
+	struct pmc_dev *pmcdev = &pmc;
 
-builtin_pci_driver(intel_pmc_core_driver);
+	pmc_core_dbgfs_unregister(pmcdev);
+	mutex_destroy(&pmcdev->lock);
+	iounmap(pmcdev->regbase);
+}
+module_exit(pmc_core_remove)
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel PMC Core Driver");
diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h
index 3d225a9..5fa5f97 100644
--- a/drivers/platform/x86/intel_pmc_core.h
+++ b/drivers/platform/x86/intel_pmc_core.h
@@ -21,9 +21,10 @@
 #ifndef PMC_CORE_H
 #define PMC_CORE_H
 
+#define PMC_BASE_ADDR_DEFAULT			0xFE000000
+
 /* Sunrise Point Power Management Controller PCI Device ID */
 #define SPT_PMC_PCI_DEVICE_ID			0x9d21
-
 #define SPT_PMC_BASE_ADDR_OFFSET		0x48
 #define SPT_PMC_SLP_S0_RES_COUNTER_OFFSET	0x13c
 #define SPT_PMC_PM_CFG_OFFSET			0x18
@@ -122,6 +123,17 @@ enum ppfear_regs {
 #define SPT_PMC_BIT_MPHY_CMN_LANE2		BIT(2)
 #define SPT_PMC_BIT_MPHY_CMN_LANE3		BIT(3)
 
+/* Cannonlake Power Management Controller register offsets */
+#define CNP_PMC_SLP_S0_RES_COUNTER_OFFSET      0x193C
+#define CNP_PMC_LTR_IGNORE_OFFSET              0x1B0C
+#define CNP_PMC_PM_CFG_OFFSET                  0x1818
+/* Cannonlake: PGD PFET Enable Ack Status Register(s) start */
+#define CNP_PMC_HOST_PPFEAR0A                  0x1D90
+
+#define CNP_PMC_MMIO_REG_LEN                   0x2000
+#define CNP_PPFEAR_NUM_ENTRIES                 8
+#define CNP_PMC_READ_DISABLE_BIT               22
+
 struct pmc_bit_map {
 	const char *name;
 	u32 bit_mask;
@@ -135,7 +147,6 @@ struct pmc_bit_map {
  * @pll_sts:		Maps name of PLL to corresponding bit status
  * @slp_s0_offset:	PWRMBASE offset to read SLP_S0 residency
  * @ltr_ignore_offset:	PWRMBASE offset to read/write LTR ignore bit
- * @base_address:	Base address of PWRMBASE defined in BIOS writer guide
  * @regmap_length:	Length of memory to map from PWRMBASE address to access
  * @ppfear0_offset:	PWRMBASE offset to to read PPFEAR*
  * @ppfear_buckets:	Number of 8 bits blocks to read all IP blocks from
@@ -152,7 +163,6 @@ struct pmc_reg_map {
 	const struct pmc_bit_map *pll_sts;
 	const u32 slp_s0_offset;
 	const u32 ltr_ignore_offset;
-	const u32 base_address;
 	const int regmap_length;
 	const u32 ppfear0_offset;
 	const int ppfear_buckets;
@@ -162,12 +172,14 @@ struct pmc_reg_map {
 
 /**
  * struct pmc_dev - pmc device structure
- * @base_addr:		comtains pmc base address
+ * @base_addr:		contains pmc base address
  * @regbase:		pointer to io-remapped memory location
- * @dbgfs_dir:		path to debug fs interface
- * @feature_available:	flag to indicate whether
- *			the feature is available
- *			on a particular platform or not.
+ * @map:		pointer to pmc_reg_map struct that contains platform
+ *			specific attributes
+ * @dbgfs_dir:		path to debugfs interface
+ * @pmc_xram_read_bit:	flag to indicate whether PMC XRAM shadow registers
+ *			used to read MPHY PG and PLL status are available
+ * @mutex_lock:		mutex to complete one transcation
  *
  * pmc_dev contains info about power management controller device.
  */
@@ -178,7 +190,6 @@ struct pmc_dev {
 #if IS_ENABLED(CONFIG_DEBUG_FS)
 	struct dentry *dbgfs_dir;
 #endif /* CONFIG_DEBUG_FS */
-	bool has_slp_s0_res;
 	int pmc_xram_read_bit;
 	struct mutex lock; /* generic mutex lock for PMC Core */
 };
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index e03fa314..e7edc8c 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -215,11 +215,11 @@ static inline int is_gcr_valid(u32 offset)
 }
 
 /**
- * intel_pmc_gcr_read() - Read PMC GCR register
+ * intel_pmc_gcr_read() - Read a 32-bit PMC GCR register
  * @offset:	offset of GCR register from GCR address base
  * @data:	data pointer for storing the register output
  *
- * Reads the PMC GCR register of given offset.
+ * Reads the 32-bit PMC GCR register at given offset.
  *
  * Return:	negative value on error or 0 on success.
  */
@@ -244,6 +244,35 @@ int intel_pmc_gcr_read(u32 offset, u32 *data)
 EXPORT_SYMBOL_GPL(intel_pmc_gcr_read);
 
 /**
+ * intel_pmc_gcr_read64() - Read a 64-bit PMC GCR register
+ * @offset:	offset of GCR register from GCR address base
+ * @data:	data pointer for storing the register output
+ *
+ * Reads the 64-bit PMC GCR register at given offset.
+ *
+ * Return:	negative value on error or 0 on success.
+ */
+int intel_pmc_gcr_read64(u32 offset, u64 *data)
+{
+	int ret;
+
+	spin_lock(&ipcdev.gcr_lock);
+
+	ret = is_gcr_valid(offset);
+	if (ret < 0) {
+		spin_unlock(&ipcdev.gcr_lock);
+		return ret;
+	}
+
+	*data = readq(ipcdev.gcr_mem_base + offset);
+
+	spin_unlock(&ipcdev.gcr_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(intel_pmc_gcr_read64);
+
+/**
  * intel_pmc_gcr_write() - Write PMC GCR register
  * @offset:	offset of GCR register from GCR address base
  * @data:	register update value
diff --git a/drivers/platform/x86/intel_telemetry_debugfs.c b/drivers/platform/x86/intel_telemetry_debugfs.c
index 4249e826..ffd0474 100644
--- a/drivers/platform/x86/intel_telemetry_debugfs.c
+++ b/drivers/platform/x86/intel_telemetry_debugfs.c
@@ -23,7 +23,6 @@
  */
 #include <linux/debugfs.h>
 #include <linux/device.h>
-#include <linux/io.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/seq_file.h>
@@ -32,11 +31,10 @@
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
 #include <asm/intel_pmc_ipc.h>
-#include <asm/intel_punit_ipc.h>
 #include <asm/intel_telemetry.h>
 
-#define DRIVER_NAME	"telemetry_soc_debugfs"
-#define DRIVER_VERSION	"1.0.0"
+#define DRIVER_NAME			"telemetry_soc_debugfs"
+#define DRIVER_VERSION			"1.0.0"
 
 /* ApolloLake SoC Event-IDs */
 #define TELEM_APL_PSS_PSTATES_ID	0x2802
@@ -98,10 +96,6 @@ static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
 static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
 
 struct telemetry_susp_stats {
-	u32 shlw_swake_ctr;
-	u32 deep_swake_ctr;
-	u64 shlw_swake_res;
-	u64 deep_swake_res;
 	u32 shlw_ctr;
 	u32 deep_ctr;
 	u64 shlw_res;
@@ -250,7 +244,6 @@ static struct telem_ioss_pg_info telem_apl_ioss_pg_data[] = {
 	{"PRTC",	25},
 };
 
-
 struct telemetry_debugfs_conf {
 	struct telemetry_susp_stats suspend_stats;
 	struct dentry *telemetry_dbg_dir;
@@ -385,7 +378,6 @@ static int telem_pss_states_show(struct seq_file *s, void *unused)
 			TELEM_APL_MASK_PCS_STATE;
 		}
 
-
 		TELEM_CHECK_AND_PARSE_EVTS(conf->pss_idle_id,
 					   conf->pss_idle_evts - 1,
 					   pss_idle, evtlog[index].telem_evtlog,
@@ -405,7 +397,6 @@ static int telem_pss_states_show(struct seq_file *s, void *unused)
 					   conf->pcs_s0ix_blkd_data,
 					   TELEM_MASK_BYTE);
 
-
 		TELEM_CHECK_AND_PARSE_EVTS(conf->pss_wakeup_id,
 					   conf->pss_wakeup_evts,
 					   pss_s0ix_wakeup,
@@ -498,7 +489,6 @@ static const struct file_operations telem_pss_ops = {
 	.release	= single_release,
 };
 
-
 static int telem_ioss_states_show(struct seq_file *s, void *unused)
 {
 	struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
@@ -598,19 +588,15 @@ static int telem_soc_states_show(struct seq_file *s, void *unused)
 
 	seq_printf(s, "S0IX Shallow\t\t\t %10u\t %10llu\n",
 		   s0ix_shlw_ctr -
-		   conf->suspend_stats.shlw_ctr -
-		   conf->suspend_stats.shlw_swake_ctr,
+		   conf->suspend_stats.shlw_ctr,
 		   (u64)((s0ix_shlw_res -
-		   conf->suspend_stats.shlw_res -
-		   conf->suspend_stats.shlw_swake_res)*10/192));
+		   conf->suspend_stats.shlw_res)*10/192));
 
 	seq_printf(s, "S0IX Deep\t\t\t %10u\t %10llu\n",
 		   s0ix_deep_ctr -
-		   conf->suspend_stats.deep_ctr -
-		   conf->suspend_stats.deep_swake_ctr,
+		   conf->suspend_stats.deep_ctr,
 		   (u64)((s0ix_deep_res -
-		   conf->suspend_stats.deep_res -
-		   conf->suspend_stats.deep_swake_res)*10/192));
+		   conf->suspend_stats.deep_res)*10/192));
 
 	seq_printf(s, "Suspend(With S0ixShallow)\t %10u\t %10llu\n",
 		   conf->suspend_stats.shlw_ctr,
@@ -620,14 +606,8 @@ static int telem_soc_states_show(struct seq_file *s, void *unused)
 		   conf->suspend_stats.deep_ctr,
 		   (u64)(conf->suspend_stats.deep_res*10)/192);
 
-	seq_printf(s, "Suspend(With Shallow-Wakes)\t %10u\t %10llu\n",
-		   conf->suspend_stats.shlw_swake_ctr +
-		   conf->suspend_stats.deep_swake_ctr,
-		   (u64)((conf->suspend_stats.shlw_swake_res +
-		   conf->suspend_stats.deep_swake_res)*10/192));
-
-	seq_printf(s, "S0IX+Suspend Total\t\t %10u\t %10llu\n", s0ix_total_ctr,
-				(u64)(s0ix_total_res*10/192));
+	seq_printf(s, "TOTAL S0IX\t\t\t %10u\t %10llu\n", s0ix_total_ctr,
+		   (u64)(s0ix_total_res*10/192));
 	seq_puts(s, "\n-------------------------------------------------\n");
 	seq_puts(s, "\t\tDEVICE STATES\n");
 	seq_puts(s, "-------------------------------------------------\n");
@@ -772,7 +752,6 @@ static const struct file_operations telem_pss_trc_verb_ops = {
 	.release	= single_release,
 };
 
-
 static int telem_ioss_trc_verb_show(struct seq_file *s, void *unused)
 {
 	u32 verbosity;
@@ -890,28 +869,45 @@ static int pm_suspend_exit_cb(void)
 		goto out;
 	}
 
+	/*
+	 * Due to some design limitations in the firmware, sometimes the
+	 * counters do not get updated by the time we reach here. As a
+	 * workaround, we try to see if this was a genuine case of sleep
+	 * failure or not by cross-checking from PMC GCR registers directly.
+	 */
+	if (suspend_shlw_ctr_exit == suspend_shlw_ctr_temp &&
+	    suspend_deep_ctr_exit == suspend_deep_ctr_temp) {
+		ret = intel_pmc_gcr_read64(PMC_GCR_TELEM_SHLW_S0IX_REG,
+					  &suspend_shlw_res_exit);
+		if (ret < 0)
+			goto out;
+
+		ret = intel_pmc_gcr_read64(PMC_GCR_TELEM_DEEP_S0IX_REG,
+					  &suspend_deep_res_exit);
+		if (ret < 0)
+			goto out;
+
+		if (suspend_shlw_res_exit > suspend_shlw_res_temp)
+			suspend_shlw_ctr_exit++;
+
+		if (suspend_deep_res_exit > suspend_deep_res_temp)
+			suspend_deep_ctr_exit++;
+	}
+
 	suspend_shlw_ctr_exit -= suspend_shlw_ctr_temp;
 	suspend_deep_ctr_exit -= suspend_deep_ctr_temp;
 	suspend_shlw_res_exit -= suspend_shlw_res_temp;
 	suspend_deep_res_exit -= suspend_deep_res_temp;
 
-	if (suspend_shlw_ctr_exit == 1) {
+	if (suspend_shlw_ctr_exit != 0) {
 		conf->suspend_stats.shlw_ctr +=
 		suspend_shlw_ctr_exit;
 
 		conf->suspend_stats.shlw_res +=
 		suspend_shlw_res_exit;
 	}
-	/* Shallow Wakes Case */
-	else if (suspend_shlw_ctr_exit > 1) {
-		conf->suspend_stats.shlw_swake_ctr +=
-		suspend_shlw_ctr_exit;
 
-		conf->suspend_stats.shlw_swake_res +=
-		suspend_shlw_res_exit;
-	}
-
-	if (suspend_deep_ctr_exit == 1) {
+	if (suspend_deep_ctr_exit != 0) {
 		conf->suspend_stats.deep_ctr +=
 		suspend_deep_ctr_exit;
 
@@ -919,15 +915,6 @@ static int pm_suspend_exit_cb(void)
 		suspend_deep_res_exit;
 	}
 
-	/* Shallow Wakes Case */
-	else if (suspend_deep_ctr_exit > 1) {
-		conf->suspend_stats.deep_swake_ctr +=
-		suspend_deep_ctr_exit;
-
-		conf->suspend_stats.deep_swake_res +=
-		suspend_deep_res_exit;
-	}
-
 out:
 	suspend_prep_ok = 0;
 	return NOTIFY_OK;
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
index 504256c..27de299 100644
--- a/drivers/platform/x86/mlx-platform.c
+++ b/drivers/platform/x86/mlx-platform.c
@@ -35,20 +35,31 @@
 #include <linux/dmi.h>
 #include <linux/i2c.h>
 #include <linux/i2c-mux.h>
+#include <linux/io.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_data/i2c-mux-reg.h>
-#include <linux/platform_data/mlxcpld-hotplug.h>
+#include <linux/platform_data/mlxreg.h>
+#include <linux/regmap.h>
 
 #define MLX_PLAT_DEVICE_NAME		"mlxplat"
 
 /* LPC bus IO offsets */
 #define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR		0x2000
 #define MLXPLAT_CPLD_LPC_REG_BASE_ADRR		0x2500
-#define MLXPLAT_CPLD_LPC_REG_AGGR_ADRR		0x253a
-#define MLXPLAT_CPLD_LPC_REG_PSU_ADRR		0x2558
-#define MLXPLAT_CPLD_LPC_REG_PWR_ADRR		0x2564
-#define MLXPLAT_CPLD_LPC_REG_FAN_ADRR		0x2588
+#define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET	0x3a
+#define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET	0x3b
+#define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET	0x40
+#define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET	0x41
+#define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET		0x58
+#define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET	0x59
+#define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET	0x5a
+#define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET		0x64
+#define MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET	0x65
+#define MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET	0x66
+#define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET		0x88
+#define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET	0x89
+#define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET	0x8a
 #define MLXPLAT_CPLD_LPC_IO_RANGE		0x100
 #define MLXPLAT_CPLD_LPC_I2C_CH1_OFF		0xdb
 #define MLXPLAT_CPLD_LPC_I2C_CH2_OFF		0xda
@@ -81,6 +92,7 @@
 /* mlxplat_priv - platform private data
  * @pdev_i2c - i2c controller platform device
  * @pdev_mux - array of mux platform devices
+ * @pdev_hotplug - hotplug platform devices
  */
 struct mlxplat_priv {
 	struct platform_device *pdev_i2c;
@@ -138,86 +150,264 @@ static struct i2c_mux_reg_platform_data mlxplat_mux_data[] = {
 };
 
 /* Platform hotplug devices */
-static struct mlxcpld_hotplug_device mlxplat_mlxcpld_psu[] = {
+static struct i2c_board_info mlxplat_mlxcpld_psu[] = {
 	{
-		.brdinfo = { I2C_BOARD_INFO("24c02", 0x51) },
-		.bus = 10,
+		I2C_BOARD_INFO("24c02", 0x51),
 	},
 	{
-		.brdinfo = { I2C_BOARD_INFO("24c02", 0x50) },
-		.bus = 10,
+		I2C_BOARD_INFO("24c02", 0x50),
 	},
 };
 
-static struct mlxcpld_hotplug_device mlxplat_mlxcpld_pwr[] = {
+static struct i2c_board_info mlxplat_mlxcpld_pwr[] = {
 	{
-		.brdinfo = { I2C_BOARD_INFO("dps460", 0x59) },
-		.bus = 10,
+		I2C_BOARD_INFO("dps460", 0x59),
 	},
 	{
-		.brdinfo = { I2C_BOARD_INFO("dps460", 0x58) },
-		.bus = 10,
+		I2C_BOARD_INFO("dps460", 0x58),
 	},
 };
 
-static struct mlxcpld_hotplug_device mlxplat_mlxcpld_fan[] = {
+static struct i2c_board_info mlxplat_mlxcpld_fan[] = {
 	{
-		.brdinfo = { I2C_BOARD_INFO("24c32", 0x50) },
-		.bus = 11,
+		I2C_BOARD_INFO("24c32", 0x50),
 	},
 	{
-		.brdinfo = { I2C_BOARD_INFO("24c32", 0x50) },
-		.bus = 12,
+		I2C_BOARD_INFO("24c32", 0x50),
 	},
 	{
-		.brdinfo = { I2C_BOARD_INFO("24c32", 0x50) },
-		.bus = 13,
+		I2C_BOARD_INFO("24c32", 0x50),
 	},
 	{
-		.brdinfo = { I2C_BOARD_INFO("24c32", 0x50) },
-		.bus = 14,
+		I2C_BOARD_INFO("24c32", 0x50),
 	},
 };
 
 /* Platform hotplug default data */
+static struct mlxreg_core_data mlxplat_mlxcpld_default_psu_items_data[] = {
+	{
+		.label = "psu1",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = BIT(0),
+		.hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
+		.hpdev.nr = 10,
+	},
+	{
+		.label = "psu2",
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = BIT(1),
+		.hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
+		.hpdev.nr = 10,
+	},
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data[] = {
+	{
+		.label = "pwr1",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = BIT(0),
+		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
+		.hpdev.nr = 10,
+	},
+	{
+		.label = "pwr2",
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = BIT(1),
+		.hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
+		.hpdev.nr = 10,
+	},
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = {
+	{
+		.label = "fan1",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(0),
+		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[0],
+		.hpdev.nr = 11,
+	},
+	{
+		.label = "fan2",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(1),
+		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[1],
+		.hpdev.nr = 12,
+	},
+	{
+		.label = "fan3",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(2),
+		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[2],
+		.hpdev.nr = 13,
+	},
+	{
+		.label = "fan4",
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = BIT(3),
+		.hpdev.brdinfo = &mlxplat_mlxcpld_fan[3],
+		.hpdev.nr = 14,
+	},
+};
+
+static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = {
+	{
+		.data = mlxplat_mlxcpld_default_psu_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+		.mask = MLXPLAT_CPLD_PSU_MASK,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_psu),
+		.inversed = 1,
+		.health = false,
+	},
+	{
+		.data = mlxplat_mlxcpld_default_pwr_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = MLXPLAT_CPLD_PWR_MASK,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
+		.inversed = 0,
+		.health = false,
+	},
+	{
+		.data = mlxplat_mlxcpld_default_fan_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+		.mask = MLXPLAT_CPLD_FAN_MASK,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
+		.inversed = 1,
+		.health = false,
+	},
+};
+
 static
-struct mlxcpld_hotplug_platform_data mlxplat_mlxcpld_default_data = {
-	.top_aggr_offset = MLXPLAT_CPLD_LPC_REG_AGGR_ADRR,
-	.top_aggr_mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
-	.top_aggr_psu_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF,
-	.psu_reg_offset = MLXPLAT_CPLD_LPC_REG_PSU_ADRR,
-	.psu_mask = MLXPLAT_CPLD_PSU_MASK,
-	.psu_count = ARRAY_SIZE(mlxplat_mlxcpld_psu),
-	.psu = mlxplat_mlxcpld_psu,
-	.top_aggr_pwr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
-	.pwr_reg_offset = MLXPLAT_CPLD_LPC_REG_PWR_ADRR,
-	.pwr_mask = MLXPLAT_CPLD_PWR_MASK,
-	.pwr_count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
-	.pwr = mlxplat_mlxcpld_pwr,
-	.top_aggr_fan_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
-	.fan_reg_offset = MLXPLAT_CPLD_LPC_REG_FAN_ADRR,
-	.fan_mask = MLXPLAT_CPLD_FAN_MASK,
-	.fan_count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
-	.fan = mlxplat_mlxcpld_fan,
+struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = {
+	.items = mlxplat_mlxcpld_default_items,
+	.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
+	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
+	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
 };
 
 /* Platform hotplug MSN21xx system family data */
+static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items[] = {
+	{
+		.data = mlxplat_mlxcpld_default_pwr_items_data,
+		.aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
+		.reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+		.mask = MLXPLAT_CPLD_PWR_MASK,
+		.count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
+		.inversed = 0,
+		.health = false,
+	},
+};
+
 static
-struct mlxcpld_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
-	.top_aggr_offset = MLXPLAT_CPLD_LPC_REG_AGGR_ADRR,
-	.top_aggr_mask = MLXPLAT_CPLD_AGGR_MASK_MSN21XX,
-	.top_aggr_pwr_mask = MLXPLAT_CPLD_AGGR_MASK_MSN21XX,
-	.pwr_reg_offset = MLXPLAT_CPLD_LPC_REG_PWR_ADRR,
-	.pwr_mask = MLXPLAT_CPLD_PWR_MASK,
-	.pwr_count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
+struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
+	.items = mlxplat_mlxcpld_msn21xx_items,
+	.counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items),
+	.cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
+	.mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
+};
+
+static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+		return true;
+	}
+	return false;
+}
+
+static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+		return true;
+	}
+	return false;
+}
+
+static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
+	case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+		return true;
+	}
+	return false;
+}
+
+struct mlxplat_mlxcpld_regmap_context {
+	void __iomem *base;
+};
+
+static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx;
+
+static int
+mlxplat_mlxcpld_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+	struct mlxplat_mlxcpld_regmap_context *ctx = context;
+
+	*val = ioread8(ctx->base + reg);
+	return 0;
+}
+
+static int
+mlxplat_mlxcpld_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+	struct mlxplat_mlxcpld_regmap_context *ctx = context;
+
+	iowrite8(val, ctx->base + reg);
+	return 0;
+}
+
+static const struct regmap_config mlxplat_mlxcpld_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 255,
+	.cache_type = REGCACHE_FLAT,
+	.writeable_reg = mlxplat_mlxcpld_writeable_reg,
+	.readable_reg = mlxplat_mlxcpld_readable_reg,
+	.volatile_reg = mlxplat_mlxcpld_volatile_reg,
+	.reg_read = mlxplat_mlxcpld_reg_read,
+	.reg_write = mlxplat_mlxcpld_reg_write,
 };
 
 static struct resource mlxplat_mlxcpld_resources[] = {
-	[0] = DEFINE_RES_IRQ_NAMED(17, "mlxcpld-hotplug"),
+	[0] = DEFINE_RES_IRQ_NAMED(17, "mlxreg-hotplug"),
 };
 
 static struct platform_device *mlxplat_dev;
-static struct mlxcpld_hotplug_platform_data *mlxplat_hotplug;
+static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
 
 static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
 {
@@ -286,6 +476,8 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
 	{ }
 };
 
+MODULE_DEVICE_TABLE(dmi, mlxplat_dmi_table);
+
 static int __init mlxplat_init(void)
 {
 	struct mlxplat_priv *priv;
@@ -328,8 +520,23 @@ static int __init mlxplat_init(void)
 		}
 	}
 
+	mlxplat_mlxcpld_regmap_ctx.base = devm_ioport_map(&mlxplat_dev->dev,
+			       mlxplat_lpc_resources[1].start, 1);
+	if (!mlxplat_mlxcpld_regmap_ctx.base) {
+		err = -ENOMEM;
+		goto fail_platform_mux_register;
+	}
+
+	mlxplat_hotplug->regmap = devm_regmap_init(&mlxplat_dev->dev, NULL,
+					&mlxplat_mlxcpld_regmap_ctx,
+					&mlxplat_mlxcpld_regmap_config);
+	if (IS_ERR(mlxplat_hotplug->regmap)) {
+		err = PTR_ERR(mlxplat_hotplug->regmap);
+		goto fail_platform_mux_register;
+	}
+
 	priv->pdev_hotplug = platform_device_register_resndata(
-				&mlxplat_dev->dev, "mlxcpld-hotplug",
+				&mlxplat_dev->dev, "mlxreg-hotplug",
 				PLATFORM_DEVID_NONE,
 				mlxplat_mlxcpld_resources,
 				ARRAY_SIZE(mlxplat_mlxcpld_resources),
@@ -339,8 +546,16 @@ static int __init mlxplat_init(void)
 		goto fail_platform_mux_register;
 	}
 
+	/* Sync registers with hardware. */
+	regcache_mark_dirty(mlxplat_hotplug->regmap);
+	err = regcache_sync(mlxplat_hotplug->regmap);
+	if (err)
+		goto fail_platform_hotplug_register;
+
 	return 0;
 
+fail_platform_hotplug_register:
+	platform_device_unregister(priv->pdev_hotplug);
 fail_platform_mux_register:
 	while (--i >= 0)
 		platform_device_unregister(priv->pdev_mux[i]);
@@ -370,8 +585,3 @@ module_exit(mlxplat_exit);
 MODULE_AUTHOR("Vadim Pasternak (vadimp@mellanox.com)");
 MODULE_DESCRIPTION("Mellanox platform driver");
 MODULE_LICENSE("Dual BSD/GPL");
-MODULE_ALIAS("dmi:*:*Mellanox*:MSN24*:");
-MODULE_ALIAS("dmi:*:*Mellanox*:MSN27*:");
-MODULE_ALIAS("dmi:*:*Mellanox*:MSB*:");
-MODULE_ALIAS("dmi:*:*Mellanox*:MSX*:");
-MODULE_ALIAS("dmi:*:*Mellanox*:MSN21*:");
diff --git a/drivers/platform/x86/mlxcpld-hotplug.c b/drivers/platform/x86/mlxcpld-hotplug.c
deleted file mode 100644
index aff3686..0000000
--- a/drivers/platform/x86/mlxcpld-hotplug.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * drivers/platform/x86/mlxcpld-hotplug.c
- * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
- * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/bitops.h>
-#include <linux/device.h>
-#include <linux/hwmon.h>
-#include <linux/hwmon-sysfs.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_data/mlxcpld-hotplug.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-
-/* Offset of event and mask registers from status register */
-#define MLXCPLD_HOTPLUG_EVENT_OFF	1
-#define MLXCPLD_HOTPLUG_MASK_OFF	2
-#define MLXCPLD_HOTPLUG_AGGR_MASK_OFF	1
-
-#define MLXCPLD_HOTPLUG_ATTRS_NUM	8
-
-/**
- * enum mlxcpld_hotplug_attr_type - sysfs attributes for hotplug events:
- * @MLXCPLD_HOTPLUG_ATTR_TYPE_PSU: power supply unit attribute;
- * @MLXCPLD_HOTPLUG_ATTR_TYPE_PWR: power cable attribute;
- * @MLXCPLD_HOTPLUG_ATTR_TYPE_FAN: FAN drawer attribute;
- */
-enum mlxcpld_hotplug_attr_type {
-	MLXCPLD_HOTPLUG_ATTR_TYPE_PSU,
-	MLXCPLD_HOTPLUG_ATTR_TYPE_PWR,
-	MLXCPLD_HOTPLUG_ATTR_TYPE_FAN,
-};
-
-/**
- * struct mlxcpld_hotplug_priv_data - platform private data:
- * @irq: platform interrupt number;
- * @pdev: platform device;
- * @plat: platform data;
- * @hwmon: hwmon device;
- * @mlxcpld_hotplug_attr: sysfs attributes array;
- * @mlxcpld_hotplug_dev_attr: sysfs sensor device attribute array;
- * @group: sysfs attribute group;
- * @groups: list of sysfs attribute group for hwmon registration;
- * @dwork: delayed work template;
- * @lock: spin lock;
- * @aggr_cache: last value of aggregation register status;
- * @psu_cache: last value of PSU register status;
- * @pwr_cache: last value of power register status;
- * @fan_cache: last value of FAN register status;
- */
-struct mlxcpld_hotplug_priv_data {
-	int irq;
-	struct platform_device *pdev;
-	struct mlxcpld_hotplug_platform_data *plat;
-	struct device *hwmon;
-	struct attribute *mlxcpld_hotplug_attr[MLXCPLD_HOTPLUG_ATTRS_NUM + 1];
-	struct sensor_device_attribute_2
-			mlxcpld_hotplug_dev_attr[MLXCPLD_HOTPLUG_ATTRS_NUM];
-	struct attribute_group group;
-	const struct attribute_group *groups[2];
-	struct delayed_work dwork;
-	spinlock_t lock;
-	u8 aggr_cache;
-	u8 psu_cache;
-	u8 pwr_cache;
-	u8 fan_cache;
-};
-
-static ssize_t mlxcpld_hotplug_attr_show(struct device *dev,
-					 struct device_attribute *attr,
-					 char *buf)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct mlxcpld_hotplug_priv_data *priv = platform_get_drvdata(pdev);
-	int index = to_sensor_dev_attr_2(attr)->index;
-	int nr = to_sensor_dev_attr_2(attr)->nr;
-	u8 reg_val = 0;
-
-	switch (nr) {
-	case MLXCPLD_HOTPLUG_ATTR_TYPE_PSU:
-		/* Bit = 0 : PSU is present. */
-		reg_val = !!!(inb(priv->plat->psu_reg_offset) & BIT(index));
-		break;
-
-	case MLXCPLD_HOTPLUG_ATTR_TYPE_PWR:
-		/* Bit = 1 : power cable is attached. */
-		reg_val = !!(inb(priv->plat->pwr_reg_offset) & BIT(index %
-						priv->plat->pwr_count));
-		break;
-
-	case MLXCPLD_HOTPLUG_ATTR_TYPE_FAN:
-		/* Bit = 0 : FAN is present. */
-		reg_val = !!!(inb(priv->plat->fan_reg_offset) & BIT(index %
-						priv->plat->fan_count));
-		break;
-	}
-
-	return sprintf(buf, "%u\n", reg_val);
-}
-
-#define PRIV_ATTR(i) priv->mlxcpld_hotplug_attr[i]
-#define PRIV_DEV_ATTR(i) priv->mlxcpld_hotplug_dev_attr[i]
-static int mlxcpld_hotplug_attr_init(struct mlxcpld_hotplug_priv_data *priv)
-{
-	int num_attrs = priv->plat->psu_count + priv->plat->pwr_count +
-			priv->plat->fan_count;
-	int i;
-
-	priv->group.attrs = devm_kzalloc(&priv->pdev->dev, num_attrs *
-					 sizeof(struct attribute *),
-					 GFP_KERNEL);
-	if (!priv->group.attrs)
-		return -ENOMEM;
-
-	for (i = 0; i < num_attrs; i++) {
-		PRIV_ATTR(i) = &PRIV_DEV_ATTR(i).dev_attr.attr;
-
-		if (i < priv->plat->psu_count) {
-			PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
-						GFP_KERNEL, "psu%u", i + 1);
-			PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_PSU;
-		} else if (i < priv->plat->psu_count + priv->plat->pwr_count) {
-			PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
-						GFP_KERNEL, "pwr%u", i %
-						priv->plat->pwr_count + 1);
-			PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_PWR;
-		} else {
-			PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
-						GFP_KERNEL, "fan%u", i %
-						priv->plat->fan_count + 1);
-			PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_FAN;
-		}
-
-		if (!PRIV_ATTR(i)->name) {
-			dev_err(&priv->pdev->dev, "Memory allocation failed for sysfs attribute %d.\n",
-				i + 1);
-			return -ENOMEM;
-		}
-
-		PRIV_DEV_ATTR(i).dev_attr.attr.name = PRIV_ATTR(i)->name;
-		PRIV_DEV_ATTR(i).dev_attr.attr.mode = S_IRUGO;
-		PRIV_DEV_ATTR(i).dev_attr.show = mlxcpld_hotplug_attr_show;
-		PRIV_DEV_ATTR(i).index = i;
-		sysfs_attr_init(&PRIV_DEV_ATTR(i).dev_attr.attr);
-	}
-
-	priv->group.attrs = priv->mlxcpld_hotplug_attr;
-	priv->groups[0] = &priv->group;
-	priv->groups[1] = NULL;
-
-	return 0;
-}
-
-static int mlxcpld_hotplug_device_create(struct device *dev,
-					 struct mlxcpld_hotplug_device *item)
-{
-	item->adapter = i2c_get_adapter(item->bus);
-	if (!item->adapter) {
-		dev_err(dev, "Failed to get adapter for bus %d\n",
-			item->bus);
-		return -EFAULT;
-	}
-
-	item->client = i2c_new_device(item->adapter, &item->brdinfo);
-	if (!item->client) {
-		dev_err(dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
-			item->brdinfo.type, item->bus, item->brdinfo.addr);
-		i2c_put_adapter(item->adapter);
-		item->adapter = NULL;
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-static void mlxcpld_hotplug_device_destroy(struct mlxcpld_hotplug_device *item)
-{
-	if (item->client) {
-		i2c_unregister_device(item->client);
-		item->client = NULL;
-	}
-
-	if (item->adapter) {
-		i2c_put_adapter(item->adapter);
-		item->adapter = NULL;
-	}
-}
-
-static inline void
-mlxcpld_hotplug_work_helper(struct device *dev,
-			    struct mlxcpld_hotplug_device *item, u8 is_inverse,
-			    u16 offset, u8 mask, u8 *cache)
-{
-	u8 val, asserted;
-	int bit;
-
-	/* Mask event. */
-	outb(0, offset + MLXCPLD_HOTPLUG_MASK_OFF);
-	/* Read status. */
-	val = inb(offset) & mask;
-	asserted = *cache ^ val;
-	*cache = val;
-
-	/*
-	 * Validate if item related to received signal type is valid.
-	 * It should never happen, excepted the situation when some
-	 * piece of hardware is broken. In such situation just produce
-	 * error message and return. Caller must continue to handle the
-	 * signals from other devices if any.
-	 */
-	if (unlikely(!item)) {
-		dev_err(dev, "False signal is received: register at offset 0x%02x, mask 0x%02x.\n",
-			offset, mask);
-		return;
-	}
-
-	for_each_set_bit(bit, (unsigned long *)&asserted, 8) {
-		if (val & BIT(bit)) {
-			if (is_inverse)
-				mlxcpld_hotplug_device_destroy(item + bit);
-			else
-				mlxcpld_hotplug_device_create(dev, item + bit);
-		} else {
-			if (is_inverse)
-				mlxcpld_hotplug_device_create(dev, item + bit);
-			else
-				mlxcpld_hotplug_device_destroy(item + bit);
-		}
-	}
-
-	/* Acknowledge event. */
-	outb(0, offset + MLXCPLD_HOTPLUG_EVENT_OFF);
-	/* Unmask event. */
-	outb(mask, offset + MLXCPLD_HOTPLUG_MASK_OFF);
-}
-
-/*
- * mlxcpld_hotplug_work_handler - performs traversing of CPLD interrupt
- * registers according to the below hierarchy schema:
- *
- *                   Aggregation registers (status/mask)
- * PSU registers:           *---*
- * *-----------------*      |   |
- * |status/event/mask|----->| * |
- * *-----------------*      |   |
- * Power registers:         |   |
- * *-----------------*      |   |
- * |status/event/mask|----->| * |---> CPU
- * *-----------------*      |   |
- * FAN registers:
- * *-----------------*      |   |
- * |status/event/mask|----->| * |
- * *-----------------*      |   |
- *                          *---*
- * In case some system changed are detected: FAN in/out, PSU in/out, power
- * cable attached/detached, relevant device is created or destroyed.
- */
-static void mlxcpld_hotplug_work_handler(struct work_struct *work)
-{
-	struct mlxcpld_hotplug_priv_data *priv = container_of(work,
-				struct mlxcpld_hotplug_priv_data, dwork.work);
-	u8 val, aggr_asserted;
-	unsigned long flags;
-
-	/* Mask aggregation event. */
-	outb(0, priv->plat->top_aggr_offset + MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
-	/* Read aggregation status. */
-	val = inb(priv->plat->top_aggr_offset) & priv->plat->top_aggr_mask;
-	aggr_asserted = priv->aggr_cache ^ val;
-	priv->aggr_cache = val;
-
-	/* Handle PSU configuration changes. */
-	if (aggr_asserted & priv->plat->top_aggr_psu_mask)
-		mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->psu,
-					    1, priv->plat->psu_reg_offset,
-					    priv->plat->psu_mask,
-					    &priv->psu_cache);
-
-	/* Handle power cable configuration changes. */
-	if (aggr_asserted & priv->plat->top_aggr_pwr_mask)
-		mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->pwr,
-					    0, priv->plat->pwr_reg_offset,
-					    priv->plat->pwr_mask,
-					    &priv->pwr_cache);
-
-	/* Handle FAN configuration changes. */
-	if (aggr_asserted & priv->plat->top_aggr_fan_mask)
-		mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->fan,
-					    1, priv->plat->fan_reg_offset,
-					    priv->plat->fan_mask,
-					    &priv->fan_cache);
-
-	if (aggr_asserted) {
-		spin_lock_irqsave(&priv->lock, flags);
-
-		/*
-		 * It is possible, that some signals have been inserted, while
-		 * interrupt has been masked by mlxcpld_hotplug_work_handler.
-		 * In this case such signals will be missed. In order to handle
-		 * these signals delayed work is canceled and work task
-		 * re-scheduled for immediate execution. It allows to handle
-		 * missed signals, if any. In other case work handler just
-		 * validates that no new signals have been received during
-		 * masking.
-		 */
-		cancel_delayed_work(&priv->dwork);
-		schedule_delayed_work(&priv->dwork, 0);
-
-		spin_unlock_irqrestore(&priv->lock, flags);
-
-		return;
-	}
-
-	/* Unmask aggregation event (no need acknowledge). */
-	outb(priv->plat->top_aggr_mask, priv->plat->top_aggr_offset +
-						MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
-}
-
-static void mlxcpld_hotplug_set_irq(struct mlxcpld_hotplug_priv_data *priv)
-{
-	/* Clear psu presense event. */
-	outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
-	/* Set psu initial status as mask and unmask psu event. */
-	priv->psu_cache = priv->plat->psu_mask;
-	outb(priv->plat->psu_mask, priv->plat->psu_reg_offset +
-						MLXCPLD_HOTPLUG_MASK_OFF);
-
-	/* Clear power cable event. */
-	outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
-	/* Keep power initial status as zero and unmask power event. */
-	outb(priv->plat->pwr_mask, priv->plat->pwr_reg_offset +
-						MLXCPLD_HOTPLUG_MASK_OFF);
-
-	/* Clear fan presense event. */
-	outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
-	/* Set fan initial status as mask and unmask fan event. */
-	priv->fan_cache = priv->plat->fan_mask;
-	outb(priv->plat->fan_mask, priv->plat->fan_reg_offset +
-						MLXCPLD_HOTPLUG_MASK_OFF);
-
-	/* Keep aggregation initial status as zero and unmask events. */
-	outb(priv->plat->top_aggr_mask, priv->plat->top_aggr_offset +
-						MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
-
-	/* Invoke work handler for initializing hot plug devices setting. */
-	mlxcpld_hotplug_work_handler(&priv->dwork.work);
-
-	enable_irq(priv->irq);
-}
-
-static void mlxcpld_hotplug_unset_irq(struct mlxcpld_hotplug_priv_data *priv)
-{
-	int i;
-
-	disable_irq(priv->irq);
-	cancel_delayed_work_sync(&priv->dwork);
-
-	/* Mask aggregation event. */
-	outb(0, priv->plat->top_aggr_offset + MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
-
-	/* Mask psu presense event. */
-	outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF);
-	/* Clear psu presense event. */
-	outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
-
-	/* Mask power cable event. */
-	outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF);
-	/* Clear power cable event. */
-	outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
-
-	/* Mask fan presense event. */
-	outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF);
-	/* Clear fan presense event. */
-	outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
-
-	/* Remove all the attached devices. */
-	for (i = 0; i < priv->plat->psu_count; i++)
-		mlxcpld_hotplug_device_destroy(priv->plat->psu + i);
-
-	for (i = 0; i < priv->plat->pwr_count; i++)
-		mlxcpld_hotplug_device_destroy(priv->plat->pwr + i);
-
-	for (i = 0; i < priv->plat->fan_count; i++)
-		mlxcpld_hotplug_device_destroy(priv->plat->fan + i);
-}
-
-static irqreturn_t mlxcpld_hotplug_irq_handler(int irq, void *dev)
-{
-	struct mlxcpld_hotplug_priv_data *priv =
-				(struct mlxcpld_hotplug_priv_data *)dev;
-
-	/* Schedule work task for immediate execution.*/
-	schedule_delayed_work(&priv->dwork, 0);
-
-	return IRQ_HANDLED;
-}
-
-static int mlxcpld_hotplug_probe(struct platform_device *pdev)
-{
-	struct mlxcpld_hotplug_platform_data *pdata;
-	struct mlxcpld_hotplug_priv_data *priv;
-	int err;
-
-	pdata = dev_get_platdata(&pdev->dev);
-	if (!pdata) {
-		dev_err(&pdev->dev, "Failed to get platform data.\n");
-		return -EINVAL;
-	}
-
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	priv->pdev = pdev;
-	priv->plat = pdata;
-
-	priv->irq = platform_get_irq(pdev, 0);
-	if (priv->irq < 0) {
-		dev_err(&pdev->dev, "Failed to get platform irq: %d\n",
-			priv->irq);
-		return priv->irq;
-	}
-
-	err = devm_request_irq(&pdev->dev, priv->irq,
-				mlxcpld_hotplug_irq_handler, 0, pdev->name,
-				priv);
-	if (err) {
-		dev_err(&pdev->dev, "Failed to request irq: %d\n", err);
-		return err;
-	}
-	disable_irq(priv->irq);
-
-	INIT_DELAYED_WORK(&priv->dwork, mlxcpld_hotplug_work_handler);
-	spin_lock_init(&priv->lock);
-
-	err = mlxcpld_hotplug_attr_init(priv);
-	if (err) {
-		dev_err(&pdev->dev, "Failed to allocate attributes: %d\n", err);
-		return err;
-	}
-
-	priv->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
-					"mlxcpld_hotplug", priv, priv->groups);
-	if (IS_ERR(priv->hwmon)) {
-		dev_err(&pdev->dev, "Failed to register hwmon device %ld\n",
-			PTR_ERR(priv->hwmon));
-		return PTR_ERR(priv->hwmon);
-	}
-
-	platform_set_drvdata(pdev, priv);
-
-	/* Perform initial interrupts setup. */
-	mlxcpld_hotplug_set_irq(priv);
-
-	return 0;
-}
-
-static int mlxcpld_hotplug_remove(struct platform_device *pdev)
-{
-	struct mlxcpld_hotplug_priv_data *priv = platform_get_drvdata(pdev);
-
-	/* Clean interrupts setup. */
-	mlxcpld_hotplug_unset_irq(priv);
-
-	return 0;
-}
-
-static struct platform_driver mlxcpld_hotplug_driver = {
-	.driver = {
-		.name = "mlxcpld-hotplug",
-	},
-	.probe = mlxcpld_hotplug_probe,
-	.remove = mlxcpld_hotplug_remove,
-};
-
-module_platform_driver(mlxcpld_hotplug_driver);
-
-MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
-MODULE_DESCRIPTION("Mellanox CPLD hotplug platform driver");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_ALIAS("platform:mlxcpld-hotplug");
diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
index 77bac85..8f018b3 100644
--- a/drivers/platform/x86/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -309,17 +309,7 @@ static int pmc_dev_state_show(struct seq_file *s, void *unused)
 	return 0;
 }
 
-static int pmc_dev_state_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, pmc_dev_state_show, inode->i_private);
-}
-
-static const struct file_operations pmc_dev_state_ops = {
-	.open		= pmc_dev_state_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pmc_dev_state);
 
 static int pmc_pss_state_show(struct seq_file *s, void *unused)
 {
@@ -336,17 +326,7 @@ static int pmc_pss_state_show(struct seq_file *s, void *unused)
 	return 0;
 }
 
-static int pmc_pss_state_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, pmc_pss_state_show, inode->i_private);
-}
-
-static const struct file_operations pmc_pss_state_ops = {
-	.open		= pmc_pss_state_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pmc_pss_state);
 
 static int pmc_sleep_tmr_show(struct seq_file *s, void *unused)
 {
@@ -367,17 +347,7 @@ static int pmc_sleep_tmr_show(struct seq_file *s, void *unused)
 	return 0;
 }
 
-static int pmc_sleep_tmr_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, pmc_sleep_tmr_show, inode->i_private);
-}
-
-static const struct file_operations pmc_sleep_tmr_ops = {
-	.open		= pmc_sleep_tmr_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pmc_sleep_tmr);
 
 static void pmc_dbgfs_unregister(struct pmc_dev *pmc)
 {
@@ -395,17 +365,17 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc)
 	pmc->dbgfs_dir = dir;
 
 	f = debugfs_create_file("dev_state", S_IFREG | S_IRUGO,
-				dir, pmc, &pmc_dev_state_ops);
+				dir, pmc, &pmc_dev_state_fops);
 	if (!f)
 		goto err;
 
 	f = debugfs_create_file("pss_state", S_IFREG | S_IRUGO,
-				dir, pmc, &pmc_pss_state_ops);
+				dir, pmc, &pmc_pss_state_fops);
 	if (!f)
 		goto err;
 
 	f = debugfs_create_file("sleep_state", S_IFREG | S_IRUGO,
-				dir, pmc, &pmc_sleep_tmr_ops);
+				dir, pmc, &pmc_sleep_tmr_fops);
 	if (!f)
 		goto err;
 
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
index d3cb26f..03305e0 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -1252,7 +1252,7 @@ static int __init samsung_sysfs_init(struct samsung_laptop *samsung)
 
 }
 
-static int show_call(struct seq_file *m, void *data)
+static int samsung_laptop_call_show(struct seq_file *m, void *data)
 {
 	struct samsung_laptop *samsung = m->private;
 	struct sabi_data *sdata = &samsung->debug.data;
@@ -1274,19 +1274,7 @@ static int show_call(struct seq_file *m, void *data)
 		   sdata->d0, sdata->d1, sdata->d2, sdata->d3);
 	return 0;
 }
-
-static int samsung_debugfs_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, show_call, inode->i_private);
-}
-
-static const struct file_operations samsung_laptop_call_io_ops = {
-	.owner = THIS_MODULE,
-	.open = samsung_debugfs_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(samsung_laptop_call);
 
 static void samsung_debugfs_exit(struct samsung_laptop *samsung)
 {
@@ -1351,7 +1339,7 @@ static int samsung_debugfs_init(struct samsung_laptop *samsung)
 
 	dent = debugfs_create_file("call", S_IFREG | S_IRUGO,
 				   samsung->debug.root, samsung,
-				   &samsung_laptop_call_io_ops);
+				   &samsung_laptop_call_fops);
 	if (!dent)
 		goto error_debugfs;
 
diff --git a/drivers/platform/x86/silead_dmi.c b/drivers/platform/x86/silead_dmi.c
index 266535c..3a62409 100644
--- a/drivers/platform/x86/silead_dmi.c
+++ b/drivers/platform/x86/silead_dmi.c
@@ -67,6 +67,21 @@ static const struct silead_ts_dmi_data dexp_ursus_7w_data = {
 	.properties	= dexp_ursus_7w_props,
 };
 
+static const struct property_entry surftab_twin_10_1_st10432_8_props[] = {
+	PROPERTY_ENTRY_U32("touchscreen-size-x", 1900),
+	PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
+	PROPERTY_ENTRY_U32("touchscreen-inverted-y", 1),
+	PROPERTY_ENTRY_STRING("firmware-name",
+			      "gsl3670-surftab-twin-10-1-st10432-8.fw"),
+	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+	{ }
+};
+
+static const struct silead_ts_dmi_data surftab_twin_10_1_st10432_8_data = {
+	.acpi_name	= "MSSL1680:00",
+	.properties	= surftab_twin_10_1_st10432_8_props,
+};
+
 static const struct property_entry surftab_wintron70_st70416_6_props[] = {
 	PROPERTY_ENTRY_U32("touchscreen-size-x", 884),
 	PROPERTY_ENTRY_U32("touchscreen-size-y", 632),
@@ -171,6 +186,97 @@ static const struct silead_ts_dmi_data digma_citi_e200_data = {
 	.properties	= digma_citi_e200_props,
 };
 
+static const struct property_entry onda_obook_20_plus_props[] = {
+	PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
+	PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
+	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
+	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+	PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-obook-20-plus.fw"),
+	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+	PROPERTY_ENTRY_BOOL("silead,home-button"),
+	{ }
+};
+
+static const struct silead_ts_dmi_data onda_obook_20_plus_data = {
+	.acpi_name	= "MSSL1680:00",
+	.properties	= onda_obook_20_plus_props,
+};
+
+static const struct property_entry chuwi_hi8_props[] = {
+	PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
+	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
+	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+	PROPERTY_ENTRY_BOOL("silead,home-button"),
+	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"),
+	{ }
+};
+
+static const struct silead_ts_dmi_data chuwi_hi8_data = {
+	.acpi_name      = "MSSL0001:00",
+	.properties     = chuwi_hi8_props,
+};
+
+static const struct property_entry chuwi_vi8_props[] = {
+	PROPERTY_ENTRY_U32("touchscreen-size-x", 1724),
+	PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
+	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+	PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-vi8.fw"),
+	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+	PROPERTY_ENTRY_BOOL("silead,home-button"),
+	{ }
+};
+
+static const struct silead_ts_dmi_data chuwi_vi8_data = {
+	.acpi_name      = "MSSL1680:00",
+	.properties     = chuwi_vi8_props,
+};
+
+static const struct property_entry trekstor_primebook_c13_props[] = {
+	PROPERTY_ENTRY_U32("touchscreen-size-x", 2624),
+	PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
+	PROPERTY_ENTRY_STRING("firmware-name",
+			      "gsl1680-trekstor-primebook-c13.fw"),
+	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+	PROPERTY_ENTRY_BOOL("silead,home-button"),
+	{ }
+};
+
+static const struct silead_ts_dmi_data trekstor_primebook_c13_data = {
+	.acpi_name	= "MSSL1680:00",
+	.properties	= trekstor_primebook_c13_props,
+};
+
+static const struct property_entry teclast_x98plus2_props[] = {
+	PROPERTY_ENTRY_U32("touchscreen-size-x", 2048),
+	PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
+	PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
+	PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+	PROPERTY_ENTRY_STRING("firmware-name",
+			      "gsl1686-teclast_x98plus2.fw"),
+	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+	{ }
+};
+
+static const struct silead_ts_dmi_data teclast_x98plus2_data = {
+	.acpi_name	= "MSSL1680:00",
+	.properties	= teclast_x98plus2_props,
+};
+
+static const struct property_entry teclast_x3_plus_props[] = {
+	PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
+	PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
+	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-teclast-x3-plus.fw"),
+	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+	PROPERTY_ENTRY_BOOL("silead,home-button"),
+	{ }
+};
+
+static const struct silead_ts_dmi_data teclast_x3_plus_data = {
+	.acpi_name	= "MSSL1680:00",
+	.properties	= teclast_x3_plus_props,
+};
+
 static const struct dmi_system_id silead_ts_dmi_table[] = {
 	{
 		/* CUBE iwork8 Air */
@@ -199,6 +305,14 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
 		},
 	},
 	{
+		/* TrekStor SurfTab twin 10.1 ST10432-8 */
+		.driver_data = (void *)&surftab_twin_10_1_st10432_8_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "SurfTab twin 10.1"),
+		},
+	},
+	{
 		/* Trekstor Surftab Wintron 7.0 ST70416-6 */
 		.driver_data = (void *)&surftab_wintron70_st70416_6_data,
 		.matches = {
@@ -209,6 +323,17 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
 		},
 	},
 	{
+		/* Trekstor Surftab Wintron 7.0 ST70416-6, newer BIOS */
+		.driver_data = (void *)&surftab_wintron70_st70416_6_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
+			DMI_MATCH(DMI_PRODUCT_NAME,
+					     "SurfTab wintron 7.0 ST70416-6"),
+			/* Exact match, different versions need different fw */
+			DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA05"),
+		},
+	},
+	{
 		/* Ployer Momo7w (same hardware as the Trekstor ST70416-6) */
 		.driver_data = (void *)&surftab_wintron70_st70416_6_data,
 		.matches = {
@@ -271,6 +396,56 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
 			DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
 		},
 	},
+	{
+		/* Onda oBook 20 Plus */
+		.driver_data = (void *)&onda_obook_20_plus_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ONDA"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OBOOK 20 PLUS"),
+		},
+	},
+	{
+		/* Chuwi Hi8 */
+		.driver_data = (void *)&chuwi_hi8_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
+		},
+	},
+	{
+		/* Chuwi Vi8 (CWI506) */
+		.driver_data = (void *)&chuwi_vi8_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "i86"),
+			DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
+		},
+	},
+	{
+		/* Trekstor Primebook C13 */
+		.driver_data = (void *)&trekstor_primebook_c13_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
+		},
+	},
+	{
+		/* Teclast X98 Plus II */
+		.driver_data = (void *)&teclast_x98plus2_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
+		},
+	},
+	{
+		/* Teclast X3 Plus */
+		.driver_data = (void *)&teclast_x3_plus_data,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X3 Plus"),
+			DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"),
+		},
+	},
 	{ },
 };
 
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 117be48..d5eaf3b1 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -214,6 +214,10 @@ enum tpacpi_hkey_event_t {
 	/* AC-related events */
 	TP_HKEY_EV_AC_CHANGED		= 0x6040, /* AC status changed */
 
+	/* Further user-interface events */
+	TP_HKEY_EV_PALM_DETECTED	= 0x60b0, /* palm hoveres keyboard */
+	TP_HKEY_EV_PALM_UNDETECTED	= 0x60b1, /* palm removed */
+
 	/* Misc */
 	TP_HKEY_EV_RFKILL_CHANGED	= 0x7000, /* rfkill switch changed */
 };
@@ -2113,12 +2117,10 @@ static int hotkey_gmms_get_tablet_mode(int s, int *has_tablet_mode)
 			      TP_ACPI_MULTI_MODE_FLAT;
 		break;
 	case 4:
-		valid_modes = TP_ACPI_MULTI_MODE_LAPTOP |
-			      TP_ACPI_MULTI_MODE_TABLET |
-			      TP_ACPI_MULTI_MODE_STAND |
-			      TP_ACPI_MULTI_MODE_TENT;
-		break;
 	case 5:
+		/* In mode 4, FLAT is not specified as a valid mode. However,
+		 * it can be seen at least on the X1 Yoga 2nd Generation.
+		 */
 		valid_modes = TP_ACPI_MULTI_MODE_LAPTOP |
 			      TP_ACPI_MULTI_MODE_FLAT |
 			      TP_ACPI_MULTI_MODE_TABLET |
@@ -4079,6 +4081,12 @@ static bool hotkey_notify_6xxx(const u32 hkey,
 		*send_acpi_ev = false;
 		break;
 
+	case TP_HKEY_EV_PALM_DETECTED:
+	case TP_HKEY_EV_PALM_UNDETECTED:
+		/* palm detected hovering the keyboard, forward to user-space
+		 * via netlink for consumption */
+		return true;
+
 	default:
 		pr_warn("unknown possible thermal alarm or keyboard event received\n");
 		known = false;
diff --git a/drivers/pps/generators/pps_gen_parport.c b/drivers/pps/generators/pps_gen_parport.c
index dcd39fb..51cfde6 100644
--- a/drivers/pps/generators/pps_gen_parport.c
+++ b/drivers/pps/generators/pps_gen_parport.c
@@ -70,7 +70,7 @@ static long hrtimer_error = SAFETY_INTERVAL;
 /* the kernel hrtimer event */
 static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
 {
-	struct timespec expire_time, ts1, ts2, ts3, dts;
+	struct timespec64 expire_time, ts1, ts2, ts3, dts;
 	struct pps_generator_pp *dev;
 	struct parport *port;
 	long lim, delta;
@@ -78,7 +78,7 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
 
 	/* We have to disable interrupts here. The idea is to prevent
 	 * other interrupts on the same processor to introduce random
-	 * lags while polling the clock. getnstimeofday() takes <1us on
+	 * lags while polling the clock. ktime_get_real_ts64() takes <1us on
 	 * most machines while other interrupt handlers can take much
 	 * more potentially.
 	 *
@@ -88,22 +88,22 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
 	local_irq_save(flags);
 
 	/* first of all we get the time stamp... */
-	getnstimeofday(&ts1);
-	expire_time = ktime_to_timespec(hrtimer_get_softexpires(timer));
+	ktime_get_real_ts64(&ts1);
+	expire_time = ktime_to_timespec64(hrtimer_get_softexpires(timer));
 	dev = container_of(timer, struct pps_generator_pp, timer);
 	lim = NSEC_PER_SEC - send_delay - dev->port_write_time;
 
 	/* check if we are late */
 	if (expire_time.tv_sec != ts1.tv_sec || ts1.tv_nsec > lim) {
 		local_irq_restore(flags);
-		pr_err("we are late this time %ld.%09ld\n",
-				ts1.tv_sec, ts1.tv_nsec);
+		pr_err("we are late this time %lld.%09ld\n",
+				(s64)ts1.tv_sec, ts1.tv_nsec);
 		goto done;
 	}
 
 	/* busy loop until the time is right for an assert edge */
 	do {
-		getnstimeofday(&ts2);
+		ktime_get_real_ts64(&ts2);
 	} while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim);
 
 	/* set the signal */
@@ -113,25 +113,25 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
 	/* busy loop until the time is right for a clear edge */
 	lim = NSEC_PER_SEC - dev->port_write_time;
 	do {
-		getnstimeofday(&ts2);
+		ktime_get_real_ts64(&ts2);
 	} while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim);
 
 	/* unset the signal */
 	port->ops->write_control(port, NO_SIGNAL);
 
-	getnstimeofday(&ts3);
+	ktime_get_real_ts64(&ts3);
 
 	local_irq_restore(flags);
 
 	/* update calibrated port write time */
-	dts = timespec_sub(ts3, ts2);
+	dts = timespec64_sub(ts3, ts2);
 	dev->port_write_time =
-		(dev->port_write_time + timespec_to_ns(&dts)) >> 1;
+		(dev->port_write_time + timespec64_to_ns(&dts)) >> 1;
 
 done:
 	/* update calibrated hrtimer error */
-	dts = timespec_sub(ts1, expire_time);
-	delta = timespec_to_ns(&dts);
+	dts = timespec64_sub(ts1, expire_time);
+	delta = timespec64_to_ns(&dts);
 	/* If the new error value is bigger then the old, use the new
 	 * value, if not then slowly move towards the new value. This
 	 * way it should be safe in bad conditions and efficient in
@@ -161,17 +161,17 @@ static void calibrate_port(struct pps_generator_pp *dev)
 	long acc = 0;
 
 	for (i = 0; i < (1 << PORT_NTESTS_SHIFT); i++) {
-		struct timespec a, b;
+		struct timespec64 a, b;
 		unsigned long irq_flags;
 
 		local_irq_save(irq_flags);
-		getnstimeofday(&a);
+		ktime_get_real_ts64(&a);
 		port->ops->write_control(port, NO_SIGNAL);
-		getnstimeofday(&b);
+		ktime_get_real_ts64(&b);
 		local_irq_restore(irq_flags);
 
-		b = timespec_sub(b, a);
-		acc += timespec_to_ns(&b);
+		b = timespec64_sub(b, a);
+		acc += timespec64_to_ns(&b);
 	}
 
 	dev->port_write_time = acc >> PORT_NTESTS_SHIFT;
@@ -180,9 +180,9 @@ static void calibrate_port(struct pps_generator_pp *dev)
 
 static inline ktime_t next_intr_time(struct pps_generator_pp *dev)
 {
-	struct timespec ts;
+	struct timespec64 ts;
 
-	getnstimeofday(&ts);
+	ktime_get_real_ts64(&ts);
 
 	return ktime_set(ts.tv_sec +
 			((ts.tv_nsec > 990 * NSEC_PER_MSEC) ? 1 : 0),
diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c
index e2a4185..006ea5a 100644
--- a/drivers/rapidio/devices/tsi721_dma.c
+++ b/drivers/rapidio/devices/tsi721_dma.c
@@ -222,7 +222,7 @@ static int tsi721_bdma_ch_free(struct tsi721_bdma_chan *bdma_chan)
 	struct tsi721_device *priv = to_tsi721(bdma_chan->dchan.device);
 #endif
 
-	if (bdma_chan->bd_base == NULL)
+	if (!bdma_chan->bd_base)
 		return 0;
 
 	/* Check if DMA channel still running */
@@ -346,7 +346,7 @@ tsi721_desc_fill_init(struct tsi721_tx_desc *desc,
 {
 	u64 rio_addr;
 
-	if (bd_ptr == NULL)
+	if (!bd_ptr)
 		return -EINVAL;
 
 	/* Initialize DMA descriptor */
@@ -370,7 +370,7 @@ tsi721_desc_fill_init(struct tsi721_tx_desc *desc,
 static int
 tsi721_desc_fill_end(struct tsi721_dma_desc *bd_ptr, u32 bcount, bool interrupt)
 {
-	if (bd_ptr == NULL)
+	if (!bd_ptr)
 		return -EINVAL;
 
 	/* Update DMA descriptor */
@@ -555,9 +555,7 @@ static void tsi721_advance_work(struct tsi721_bdma_chan *bdma_chan,
 	 * If there is no data transfer in progress, fetch new descriptor from
 	 * the pending queue.
 	*/
-
-	if (desc == NULL && bdma_chan->active_tx == NULL &&
-					!list_empty(&bdma_chan->queue)) {
+	if (!desc && !bdma_chan->active_tx && !list_empty(&bdma_chan->queue)) {
 		desc = list_first_entry(&bdma_chan->queue,
 					struct tsi721_tx_desc, desc_node);
 		list_del_init((&desc->desc_node));
@@ -735,7 +733,7 @@ static dma_cookie_t tsi721_tx_submit(struct dma_async_tx_descriptor *txd)
 static int tsi721_alloc_chan_resources(struct dma_chan *dchan)
 {
 	struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan);
-	struct tsi721_tx_desc *desc = NULL;
+	struct tsi721_tx_desc *desc;
 	int i;
 
 	tsi_debug(DMA, &dchan->dev->device, "DMAC%d", bdma_chan->id);
@@ -754,9 +752,6 @@ static int tsi721_alloc_chan_resources(struct dma_chan *dchan)
 	desc = kcalloc(dma_txqueue_sz, sizeof(struct tsi721_tx_desc),
 			GFP_ATOMIC);
 	if (!desc) {
-		tsi_err(&dchan->dev->device,
-			"DMAC%d Failed to allocate logical descriptors",
-			bdma_chan->id);
 		tsi721_bdma_ch_free(bdma_chan);
 		return -ENOMEM;
 	}
@@ -799,7 +794,7 @@ static void tsi721_free_chan_resources(struct dma_chan *dchan)
 
 	tsi_debug(DMA, &dchan->dev->device, "DMAC%d", bdma_chan->id);
 
-	if (bdma_chan->bd_base == NULL)
+	if (!bdma_chan->bd_base)
 		return;
 
 	tsi721_bdma_interrupt_enable(bdma_chan, 0);
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 38d9494..83406696 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -81,6 +81,7 @@ u16 rio_local_get_device_id(struct rio_mport *port)
 
 	return (RIO_GET_DID(port->sys_size, result));
 }
+EXPORT_SYMBOL_GPL(rio_local_get_device_id);
 
 /**
  * rio_query_mport - Query mport device attributes
@@ -110,9 +111,8 @@ EXPORT_SYMBOL(rio_query_mport);
  */
 struct rio_net *rio_alloc_net(struct rio_mport *mport)
 {
-	struct rio_net *net;
+	struct rio_net *net = kzalloc(sizeof(*net), GFP_KERNEL);
 
-	net = kzalloc(sizeof(struct rio_net), GFP_KERNEL);
 	if (net) {
 		INIT_LIST_HEAD(&net->node);
 		INIT_LIST_HEAD(&net->devices);
@@ -243,18 +243,17 @@ int rio_request_inb_mbox(struct rio_mport *mport,
 	int rc = -ENOSYS;
 	struct resource *res;
 
-	if (mport->ops->open_inb_mbox == NULL)
+	if (!mport->ops->open_inb_mbox)
 		goto out;
 
-	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
-
+	res = kzalloc(sizeof(*res), GFP_KERNEL);
 	if (res) {
 		rio_init_mbox_res(res, mbox, mbox);
 
 		/* Make sure this mailbox isn't in use */
-		if ((rc =
-		     request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE],
-				      res)) < 0) {
+		rc = request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE],
+				      res);
+		if (rc < 0) {
 			kfree(res);
 			goto out;
 		}
@@ -277,6 +276,7 @@ int rio_request_inb_mbox(struct rio_mport *mport,
       out:
 	return rc;
 }
+EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
 
 /**
  * rio_release_inb_mbox - release inbound mailbox message service
@@ -305,6 +305,7 @@ int rio_release_inb_mbox(struct rio_mport *mport, int mbox)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
 
 /**
  * rio_request_outb_mbox - request outbound mailbox service
@@ -326,18 +327,17 @@ int rio_request_outb_mbox(struct rio_mport *mport,
 	int rc = -ENOSYS;
 	struct resource *res;
 
-	if (mport->ops->open_outb_mbox == NULL)
+	if (!mport->ops->open_outb_mbox)
 		goto out;
 
-	res = kzalloc(sizeof(struct resource), GFP_KERNEL);
-
+	res = kzalloc(sizeof(*res), GFP_KERNEL);
 	if (res) {
 		rio_init_mbox_res(res, mbox, mbox);
 
 		/* Make sure this outbound mailbox isn't in use */
-		if ((rc =
-		     request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE],
-				      res)) < 0) {
+		rc = request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE],
+				      res);
+		if (rc < 0) {
 			kfree(res);
 			goto out;
 		}
@@ -360,6 +360,7 @@ int rio_request_outb_mbox(struct rio_mport *mport,
       out:
 	return rc;
 }
+EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
 
 /**
  * rio_release_outb_mbox - release outbound mailbox message service
@@ -388,6 +389,7 @@ int rio_release_outb_mbox(struct rio_mport *mport, int mbox)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
 
 /**
  * rio_setup_inb_dbell - bind inbound doorbell callback
@@ -405,13 +407,10 @@ rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res,
 		    void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst,
 				  u16 info))
 {
-	int rc = 0;
-	struct rio_dbell *dbell;
+	struct rio_dbell *dbell = kmalloc(sizeof(*dbell), GFP_KERNEL);
 
-	if (!(dbell = kmalloc(sizeof(struct rio_dbell), GFP_KERNEL))) {
-		rc = -ENOMEM;
-		goto out;
-	}
+	if (!dbell)
+		return -ENOMEM;
 
 	dbell->res = res;
 	dbell->dinb = dinb;
@@ -420,9 +419,7 @@ rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res,
 	mutex_lock(&mport->lock);
 	list_add_tail(&dbell->node, &mport->dbells);
 	mutex_unlock(&mport->lock);
-
-      out:
-	return rc;
+	return 0;
 }
 
 /**
@@ -444,17 +441,16 @@ int rio_request_inb_dbell(struct rio_mport *mport,
 			  void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src,
 					u16 dst, u16 info))
 {
-	int rc = 0;
-
-	struct resource *res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+	int rc;
+	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
 	if (res) {
 		rio_init_dbell_res(res, start, end);
 
 		/* Make sure these doorbells aren't in use */
-		if ((rc =
-		     request_resource(&mport->riores[RIO_DOORBELL_RESOURCE],
-				      res)) < 0) {
+		rc = request_resource(&mport->riores[RIO_DOORBELL_RESOURCE],
+				      res);
+		if (rc < 0) {
 			kfree(res);
 			goto out;
 		}
@@ -467,6 +463,7 @@ int rio_request_inb_dbell(struct rio_mport *mport,
       out:
 	return rc;
 }
+EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
 
 /**
  * rio_release_inb_dbell - release inbound doorbell message service
@@ -508,6 +505,7 @@ int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end)
       out:
 	return rc;
 }
+EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
 
 /**
  * rio_request_outb_dbell - request outbound doorbell message range
@@ -536,6 +534,7 @@ struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start,
 
 	return res;
 }
+EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
 
 /**
  * rio_release_outb_dbell - release outbound doorbell message range
@@ -553,6 +552,7 @@ int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res)
 
 	return rc;
 }
+EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
 
 /**
  * rio_add_mport_pw_handler - add port-write message handler into the list
@@ -567,22 +567,17 @@ int rio_add_mport_pw_handler(struct rio_mport *mport, void *context,
 			     int (*pwcback)(struct rio_mport *mport,
 			     void *context, union rio_pw_msg *msg, int step))
 {
-	int rc = 0;
-	struct rio_pwrite *pwrite;
+	struct rio_pwrite *pwrite = kzalloc(sizeof(*pwrite), GFP_KERNEL);
 
-	pwrite = kzalloc(sizeof(struct rio_pwrite), GFP_KERNEL);
-	if (!pwrite) {
-		rc = -ENOMEM;
-		goto out;
-	}
+	if (!pwrite)
+		return -ENOMEM;
 
 	pwrite->pwcback = pwcback;
 	pwrite->context = context;
 	mutex_lock(&mport->lock);
 	list_add_tail(&pwrite->node, &mport->pwrites);
 	mutex_unlock(&mport->lock);
-out:
-	return rc;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(rio_add_mport_pw_handler);
 
@@ -632,7 +627,7 @@ int rio_request_inb_pwrite(struct rio_dev *rdev,
 	int rc = 0;
 
 	spin_lock(&rio_global_list_lock);
-	if (rdev->pwcback != NULL)
+	if (rdev->pwcback)
 		rc = -ENOMEM;
 	else
 		rdev->pwcback = pwcback;
@@ -698,7 +693,7 @@ EXPORT_SYMBOL_GPL(rio_pw_enable);
 int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local,
 			u64 rbase, u32 size, u32 rflags)
 {
-	int rc = 0;
+	int rc;
 	unsigned long flags;
 
 	if (!mport->ops->map_inb)
@@ -742,7 +737,7 @@ EXPORT_SYMBOL_GPL(rio_unmap_inb_region);
 int rio_map_outb_region(struct rio_mport *mport, u16 destid, u64 rbase,
 			u32 size, u32 rflags, dma_addr_t *local)
 {
-	int rc = 0;
+	int rc;
 	unsigned long flags;
 
 	if (!mport->ops->map_outb)
@@ -975,7 +970,7 @@ rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum)
 		rdev = rdev->prev;
 	}
 
-	if (prev == NULL)
+	if (!prev)
 		goto err_out;
 
 	p_port = prev->rswitch->route_table[rdev->destid];
@@ -1054,7 +1049,7 @@ rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp)
 		RIO_MNT_REQ_CMD_IS);
 
 	/* Exit if the response is not expected */
-	if (lnkresp == NULL)
+	if (!lnkresp)
 		return 0;
 
 	checkcount = 3;
@@ -1411,7 +1406,9 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
 						 ext_ftr_ptr, &ftr_header);
 		if (RIO_GET_BLOCK_ID(ftr_header) == ftr)
 			return ext_ftr_ptr;
-		if (!(ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header)))
+
+		ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header);
+		if (!ext_ftr_ptr)
 			break;
 	}
 
@@ -1462,6 +1459,7 @@ struct rio_dev *rio_get_asm(u16 vid, u16 did,
 	spin_unlock(&rio_global_list_lock);
 	return rdev;
 }
+EXPORT_SYMBOL_GPL(rio_get_asm);
 
 /**
  * rio_get_device - Begin or continue searching for a RIO device by vid/did
@@ -1481,6 +1479,7 @@ struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from)
 {
 	return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from);
 }
+EXPORT_SYMBOL_GPL(rio_get_device);
 
 /**
  * rio_std_route_add_entry - Add switch route table entry using standard
@@ -1696,7 +1695,7 @@ int rio_route_add_entry(struct rio_dev *rdev,
 
 	spin_lock(&rdev->rswitch->lock);
 
-	if (ops == NULL || ops->add_entry == NULL) {
+	if (!ops || !ops->add_entry) {
 		rc = rio_std_route_add_entry(rdev->net->hport, rdev->destid,
 					     rdev->hopcount, table,
 					     route_destid, route_port);
@@ -1749,7 +1748,7 @@ int rio_route_get_entry(struct rio_dev *rdev, u16 table,
 
 	spin_lock(&rdev->rswitch->lock);
 
-	if (ops == NULL || ops->get_entry == NULL) {
+	if (!ops || !ops->get_entry) {
 		rc = rio_std_route_get_entry(rdev->net->hport, rdev->destid,
 					     rdev->hopcount, table,
 					     route_destid, route_port);
@@ -1797,7 +1796,7 @@ int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock)
 
 	spin_lock(&rdev->rswitch->lock);
 
-	if (ops == NULL || ops->clr_table == NULL) {
+	if (!ops || !ops->clr_table) {
 		rc = rio_std_route_clr_table(rdev->net->hport, rdev->destid,
 					     rdev->hopcount, table);
 	} else if (try_module_get(ops->owner)) {
@@ -1889,7 +1888,7 @@ struct dma_async_tx_descriptor *rio_dma_prep_xfer(struct dma_chan *dchan,
 {
 	struct rio_dma_ext rio_ext;
 
-	if (dchan->device->device_prep_slave_sg == NULL) {
+	if (!dchan->device->device_prep_slave_sg) {
 		pr_err("%s: prep_rio_sg == NULL\n", __func__);
 		return NULL;
 	}
@@ -2189,7 +2188,6 @@ int rio_init_mports(void)
 
 	work = kcalloc(n, sizeof *work, GFP_KERNEL);
 	if (!work) {
-		pr_err("RIO: no memory for work struct\n");
 		destroy_workqueue(rio_wq);
 		goto no_disc;
 	}
@@ -2216,6 +2214,7 @@ int rio_init_mports(void)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(rio_init_mports);
 
 static int rio_get_hdid(int index)
 {
@@ -2330,16 +2329,3 @@ int rio_unregister_mport(struct rio_mport *port)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(rio_unregister_mport);
-
-EXPORT_SYMBOL_GPL(rio_local_get_device_id);
-EXPORT_SYMBOL_GPL(rio_get_device);
-EXPORT_SYMBOL_GPL(rio_get_asm);
-EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
-EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
-EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
-EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
-EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
-EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
-EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
-EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
-EXPORT_SYMBOL_GPL(rio_init_mports);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 42681c1..dd4708c 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -758,7 +758,7 @@ static int suspend_set_state(struct regulator_dev *rdev,
 
 	rstate = regulator_get_suspend_state(rdev, state);
 	if (rstate == NULL)
-		return -EINVAL;
+		return 0;
 
 	/* If we have no suspend mode configration don't set anything;
 	 * only warn if the driver implements set_suspend_voltage or
diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig
index bc27d71..1444333 100644
--- a/drivers/s390/block/Kconfig
+++ b/drivers/s390/block/Kconfig
@@ -16,6 +16,7 @@
 config DCSSBLK
 	def_tristate m
 	select DAX
+	select FS_DAX_LIMITED
 	prompt "DCSSBLK support"
 	depends on S390 && BLOCK
 	help
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 6aaefb7..9cae08b 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -916,7 +916,8 @@ __dcssblk_direct_access(struct dcssblk_dev_info *dev_info, pgoff_t pgoff,
 
 	dev_sz = dev_info->end - dev_info->start + 1;
 	*kaddr = (void *) dev_info->start + offset;
-	*pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV);
+	*pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset),
+			PFN_DEV|PFN_SPECIAL);
 
 	return (dev_sz - offset) / PAGE_SIZE;
 }
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 2c2e6a3..7b31f19 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -251,8 +251,9 @@ static int oprompci2node(void __user *argp, struct device_node *dp, struct openp
 		struct pci_dev *pdev;
 		struct device_node *dp;
 
-		pdev = pci_get_bus_and_slot (((int *) op->oprom_array)[0],
-				      ((int *) op->oprom_array)[1]);
+		pdev = pci_get_domain_bus_and_slot(0,
+						((int *) op->oprom_array)[0],
+						((int *) op->oprom_array)[1]);
 
 		dp = pci_device_to_OF_node(pdev);
 		data->current_node = dp;
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index f8c25ee..e68e1d3 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -1,19 +1,19 @@
 menuconfig STAGING_MEDIA
-        bool "Media staging drivers"
-        default n
-        ---help---
-          This option allows you to select a number of media drivers that
+	bool "Media staging drivers"
+	default n
+	---help---
+	  This option allows you to select a number of media drivers that
 	  don't have the "normal" Linux kernel quality level.
 	  Most of them don't follow properly the V4L, DVB and/or RC API's,
 	  so, they won't likely work fine with the existing applications.
 	  That also means that, once fixed, their API's will change to match
 	  the existing ones.
 
-          If you wish to work on these drivers, to help improve them, or
-          to report problems you have with them, please use the
+	  If you wish to work on these drivers, to help improve them, or
+	  to report problems you have with them, please use the
 	  linux-media@vger.kernel.org mailing list.
 
-          If in doubt, say N here.
+	  If in doubt, say N here.
 
 
 if STAGING_MEDIA && MEDIA_SUPPORT
@@ -31,7 +31,6 @@
 
 source "drivers/staging/media/omap4iss/Kconfig"
 
-# Keep LIRC at the end, as it has sub-menus
-source "drivers/staging/media/lirc/Kconfig"
+source "drivers/staging/media/tegra-vde/Kconfig"
 
 endif
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index be732cf..59a47f6 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -2,7 +2,7 @@
 obj-$(CONFIG_I2C_BCM2048)	+= bcm2048/
 obj-$(CONFIG_DVB_CXD2099)	+= cxd2099/
 obj-$(CONFIG_VIDEO_IMX_MEDIA)	+= imx/
-obj-$(CONFIG_LIRC_STAGING)	+= lirc/
 obj-$(CONFIG_VIDEO_DM365_VPFE)	+= davinci_vpfe/
 obj-$(CONFIG_VIDEO_OMAP4)	+= omap4iss/
 obj-$(CONFIG_INTEL_ATOMISP)     += atomisp/
+obj-$(CONFIG_TEGRA_VDE)		+= tegra-vde/
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
index e70d8af..61b7598 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
@@ -1370,13 +1370,9 @@ static int gc0310_probe(struct i2c_client *client)
 	dev->fmt_idx = 0;
 	v4l2_i2c_subdev_init(&(dev->sd), client, &gc0310_ops);
 
-	if (ACPI_COMPANION(&client->dev))
-		pdata = gmin_camera_platform_data(&dev->sd,
-						  ATOMISP_INPUT_FORMAT_RAW_8,
-						  atomisp_bayer_order_grbg);
-	else
-		pdata = client->dev.platform_data;
-
+	pdata = gmin_camera_platform_data(&dev->sd,
+					  ATOMISP_INPUT_FORMAT_RAW_8,
+					  atomisp_bayer_order_grbg);
 	if (!pdata) {
 		ret = -EINVAL;
 		goto out_free;
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
index 85da5fe..d8de46d 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
@@ -1108,9 +1108,7 @@ static int gc2235_probe(struct i2c_client *client)
 	dev->fmt_idx = 0;
 	v4l2_i2c_subdev_init(&(dev->sd), client, &gc2235_ops);
 
-	gcpdev = client->dev.platform_data;
-	if (ACPI_COMPANION(&client->dev))
-		gcpdev = gmin_camera_platform_data(&dev->sd,
+	gcpdev = gmin_camera_platform_data(&dev->sd,
 				   ATOMISP_INPUT_FORMAT_RAW_10,
 				   atomisp_bayer_order_grbg);
 
@@ -1147,10 +1145,8 @@ static int gc2235_probe(struct i2c_client *client)
 	if (ret)
 		gc2235_remove(client);
 
-	if (ACPI_HANDLE(&client->dev))
-		ret = atomisp_register_i2c_module(&dev->sd, gcpdev, RAW_CAMERA);
+	return atomisp_register_i2c_module(&dev->sd, gcpdev, RAW_CAMERA);
 
-	return ret;
 out_free:
 	v4l2_device_unregister_subdev(&dev->sd);
 	kfree(dev);
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c
index 4fd9f53..7098bf3 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c
@@ -562,10 +562,10 @@ static const struct v4l2_ctrl_config lm3554_controls[] = {
 	{
 	 .ops = &ctrl_ops,
 	 .id = V4L2_CID_FLASH_STATUS,
-	 .type = V4L2_CTRL_TYPE_BOOLEAN,
+	 .type = V4L2_CTRL_TYPE_INTEGER,
 	 .name = "Flash Status",
-	 .min = 0,
-	 .max = 100,
+	 .min = ATOMISP_FLASH_STATUS_OK,
+	 .max = ATOMISP_FLASH_STATUS_TIMEOUT,
 	 .step = 1,
 	 .def = ATOMISP_FLASH_STATUS_OK,
 	 .flags = 0,
@@ -574,10 +574,10 @@ static const struct v4l2_ctrl_config lm3554_controls[] = {
 	{
 	 .ops = &ctrl_ops,
 	 .id = V4L2_CID_FLASH_STATUS_REGISTER,
-	 .type = V4L2_CTRL_TYPE_BOOLEAN,
+	 .type = V4L2_CTRL_TYPE_INTEGER,
 	 .name = "Flash Status Register",
 	 .min = 0,
-	 .max = 100,
+	 .max = 255,
 	 .step = 1,
 	 .def = 0,
 	 .flags = 0,
@@ -824,22 +824,15 @@ static void *lm3554_platform_data_func(struct i2c_client *client)
 {
 	static struct lm3554_platform_data platform_data;
 
-	if (ACPI_COMPANION(&client->dev)) {
-		platform_data.gpio_reset =
-		    desc_to_gpio(gpiod_get_index(&(client->dev),
+	platform_data.gpio_reset =
+		    desc_to_gpio(gpiod_get_index(&client->dev,
 						 NULL, 2, GPIOD_OUT_LOW));
-		platform_data.gpio_strobe =
-		    desc_to_gpio(gpiod_get_index(&(client->dev),
+	platform_data.gpio_strobe =
+		    desc_to_gpio(gpiod_get_index(&client->dev,
 						 NULL, 0, GPIOD_OUT_LOW));
-		platform_data.gpio_torch =
-		    desc_to_gpio(gpiod_get_index(&(client->dev),
+	platform_data.gpio_torch =
+		    desc_to_gpio(gpiod_get_index(&client->dev,
 						 NULL, 1, GPIOD_OUT_LOW));
-	} else {
-		platform_data.gpio_reset = -1;
-		platform_data.gpio_strobe = -1;
-		platform_data.gpio_torch = -1;
-	}
-
 	dev_info(&client->dev, "camera pdata: lm3554: reset: %d strobe %d torch %d\n",
 		platform_data.gpio_reset, platform_data.gpio_strobe,
 		platform_data.gpio_torch);
@@ -868,10 +861,7 @@ static int lm3554_probe(struct i2c_client *client)
 	if (!flash)
 		return -ENOMEM;
 
-	flash->pdata = client->dev.platform_data;
-
-	if (!flash->pdata || ACPI_COMPANION(&client->dev))
-		flash->pdata = lm3554_platform_data_func(client);
+	flash->pdata = lm3554_platform_data_func(client);
 
 	v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops);
 	flash->sd.internal_ops = &lm3554_internal_ops;
@@ -914,9 +904,7 @@ static int lm3554_probe(struct i2c_client *client)
 		dev_err(&client->dev, "gpio request/direction_output fail");
 		goto fail2;
 	}
-	if (ACPI_HANDLE(&client->dev))
-		err = atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH);
-	return 0;
+	return atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH);
 fail2:
 	media_entity_cleanup(&flash->sd.entity);
 	v4l2_ctrl_handler_free(&flash->ctrl_handler);
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
index 55882be..df253a5 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
@@ -1844,11 +1844,9 @@ static int mt9m114_probe(struct i2c_client *client)
 		return -ENOMEM;
 
 	v4l2_i2c_subdev_init(&dev->sd, client, &mt9m114_ops);
-	pdata = client->dev.platform_data;
-	if (ACPI_COMPANION(&client->dev))
-		pdata = gmin_camera_platform_data(&dev->sd,
-						  ATOMISP_INPUT_FORMAT_RAW_10,
-						  atomisp_bayer_order_grbg);
+	pdata = gmin_camera_platform_data(&dev->sd,
+					  ATOMISP_INPUT_FORMAT_RAW_10,
+					  atomisp_bayer_order_grbg);
 	if (pdata)
 		ret = mt9m114_s_config(&dev->sd, client->irq, pdata);
 	if (!pdata || ret) {
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index cd67d38..84f8d33 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -1447,13 +1447,9 @@ static int ov2680_probe(struct i2c_client *client)
 	dev->fmt_idx = 0;
 	v4l2_i2c_subdev_init(&(dev->sd), client, &ov2680_ops);
 
-	if (ACPI_COMPANION(&client->dev))
-		pdata = gmin_camera_platform_data(&dev->sd,
-						  ATOMISP_INPUT_FORMAT_RAW_10,
-						  atomisp_bayer_order_bggr);
-	else
-		pdata = client->dev.platform_data;
-
+	pdata = gmin_camera_platform_data(&dev->sd,
+					  ATOMISP_INPUT_FORMAT_RAW_10,
+					  atomisp_bayer_order_bggr);
 	if (!pdata) {
 		ret = -EINVAL;
 		goto out_free;
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index 4df7eba..2b6ae0f 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -1259,7 +1259,6 @@ static int ov2722_probe(struct i2c_client *client)
 	struct ov2722_device *dev;
 	void *ovpdev;
 	int ret;
-	struct acpi_device *adev;
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -1270,14 +1269,9 @@ static int ov2722_probe(struct i2c_client *client)
 	dev->fmt_idx = 0;
 	v4l2_i2c_subdev_init(&(dev->sd), client, &ov2722_ops);
 
-	ovpdev = client->dev.platform_data;
-	adev = ACPI_COMPANION(&client->dev);
-	if (adev) {
-		adev->power.flags.power_resources = 0;
-		ovpdev = gmin_camera_platform_data(&dev->sd,
-						   ATOMISP_INPUT_FORMAT_RAW_10,
-						   atomisp_bayer_order_grbg);
-	}
+	ovpdev = gmin_camera_platform_data(&dev->sd,
+					   ATOMISP_INPUT_FORMAT_RAW_10,
+					   atomisp_bayer_order_grbg);
 
 	ret = ov2722_s_config(&dev->sd, client->irq, ovpdev);
 	if (ret)
@@ -1296,10 +1290,7 @@ static int ov2722_probe(struct i2c_client *client)
 	if (ret)
 		ov2722_remove(client);
 
-	if (ACPI_HANDLE(&client->dev))
-		ret = atomisp_register_i2c_module(&dev->sd, ovpdev, RAW_CAMERA);
-
-	return ret;
+	return atomisp_register_i2c_module(&dev->sd, ovpdev, RAW_CAMERA);
 
 out_ctrl_handler_free:
 	v4l2_ctrl_handler_free(&dev->ctrl_handler);
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index bf48973..03f75dd 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -174,7 +174,6 @@ struct ov2680_format {
 		struct mutex input_lock;
 	struct v4l2_ctrl_handler ctrl_handler;
 		struct camera_sensor_platform_data *platform_data;
-		struct timespec timestamp_t_focus_abs;
 		int vt_pix_clk_freq_mhz;
 		int fmt_idx;
 		int run_mode;
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
index 3e7c3851..40d01bf 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
+++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
@@ -82,6 +82,7 @@ static int ad5823_i2c_write(struct i2c_client *client, u8 reg, u8 val)
 {
 	struct i2c_msg msg;
 	u8 buf[2];
+
 	buf[0] = reg;
 	buf[1] = val;
 	msg.addr = AD5823_VCM_ADDR;
@@ -98,6 +99,7 @@ static int ad5823_i2c_read(struct i2c_client *client, u8 reg, u8 *val)
 {
 	struct i2c_msg msg[2];
 	u8 buf[2];
+
 	buf[0] = reg;
 	buf[1] = 0;
 
@@ -211,7 +213,8 @@ static int vcm_dw_i2c_write(struct i2c_client *client, u16 data)
 	return ret == num_msg ? 0 : -EIO;
 }
 
-/* Theory: per datasheet, the two VCMs both allow for a 2-byte read.
+/*
+ * Theory: per datasheet, the two VCMs both allow for a 2-byte read.
  * The DW9714 doesn't actually specify what this does (it has a
  * two-byte write-only protocol, but specifies the read sequence as
  * legal), but it returns the same data (zeroes) always, after an
@@ -222,12 +225,14 @@ static int vcm_dw_i2c_write(struct i2c_client *client, u16 data)
  * these) in AD5823 are not pairwise repetitions of the same 16 bit
  * word.  So all we have to do is sequentially read two bytes at a
  * time and see if we detect a difference in any of the first four
- * pairs.  */
+ * pairs.
+ */
 static int vcm_detect(struct i2c_client *client)
 {
 	int i, ret;
 	struct i2c_msg msg;
 	u16 data0 = 0, data;
+
 	for (i = 0; i < 4; i++) {
 		msg.addr = VCM_ADDR;
 		msg.flags = I2C_M_RD;
@@ -235,8 +240,10 @@ static int vcm_detect(struct i2c_client *client)
 		msg.buf = (u8 *)&data;
 		ret = i2c_transfer(client->adapter, &msg, 1);
 
-		/* DW9714 always fails the first read and returns
-		 * zeroes for subsequent ones */
+		/*
+		 * DW9714 always fails the first read and returns
+		 * zeroes for subsequent ones
+		 */
 		if (i == 0 && ret == -EREMOTEIO) {
 			data0 = 0;
 			continue;
@@ -530,9 +537,11 @@ static long __ov5693_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 
 	hts = ov5693_res[dev->fmt_idx].pixels_per_line;
 	vts = ov5693_res[dev->fmt_idx].lines_per_frame;
-	/*If coarse_itg is larger than 1<<15, can not write to reg directly.
-	  The way is to write coarse_itg/2 to the reg, meanwhile write 2*hts
-	  to the reg. */
+	/*
+	 * If coarse_itg is larger than 1<<15, can not write to reg directly.
+	 * The way is to write coarse_itg/2 to the reg, meanwhile write 2*hts
+	 * to the reg.
+	 */
 	if (coarse_itg > (1 << 15)) {
 		hts = hts * 2;
 		coarse_itg = (int)coarse_itg / 2;
@@ -690,6 +699,7 @@ static long ov5693_s_exposure(struct v4l2_subdev *sd,
 	/* we should not accept the invalid value below */
 	if (analog_gain == 0) {
 		struct i2c_client *client = v4l2_get_subdevdata(sd);
+
 		v4l2_err(client, "%s: invalid value\n", __func__);
 		return -EINVAL;
 	}
@@ -722,6 +732,7 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
 	int ret;
 	int i;
 	u8 *b = buf;
+
 	dev->otp_size = 0;
 	for (i = 1; i < OV5693_OTP_BANK_MAX; i++) {
 		/*set bank NO and OTP read mode. */
@@ -753,7 +764,7 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
 		//pr_debug("BANK[%2d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i, *b, *(b+1), *(b+2), *(b+3), *(b+4), *(b+5), *(b+6), *(b+7), *(b+8), *(b+9), *(b+10), *(b+11), *(b+12), *(b+13), *(b+14), *(b+15));
 
 		//Intel OTP map, try to read 320byts first.
-		if (21 == i) {
+		if (i == 21) {
 			if ((*b) == 0) {
 				dev->otp_size = 320;
 				break;
@@ -761,15 +772,15 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
 				b = buf;
 				continue;
 			}
-		} else if (24 == i) {		//if the first 320bytes data doesn't not exist, try to read the next 32bytes data.
+		} else if (i == 24) {		//if the first 320bytes data doesn't not exist, try to read the next 32bytes data.
 			if ((*b) == 0) {
 				dev->otp_size = 32;
 				break;
-		} else {
+			} else {
 				b = buf;
 				continue;
 			}
-		} else if (27 == i) {		//if the prvious 32bytes data doesn't exist, try to read the next 32bytes data again.
+		} else if (i == 27) {		//if the prvious 32bytes data doesn't exist, try to read the next 32bytes data again.
 			if ((*b) == 0) {
 				dev->otp_size = 32;
 				break;
@@ -875,8 +886,10 @@ static long ov5693_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 	return 0;
 }
 
-/* This returns the exposure time being used. This should only be used
-   for filling in EXIF data, not for actual image processing. */
+/*
+ * This returns the exposure time being used. This should only be used
+ * for filling in EXIF data, not for actual image processing.
+ */
 static int ov5693_q_exposure(struct v4l2_subdev *sd, s32 *value)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -973,7 +986,7 @@ static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
 	if (ret == 0) {
 		dev->number_of_steps = value - dev->focus;
 		dev->focus = value;
-		getnstimeofday(&(dev->timestamp_t_focus_abs));
+		dev->timestamp_t_focus_abs = ktime_get();
 	} else
 		dev_err(&client->dev,
 			"%s: i2c failed. ret %d\n", __func__, ret);
@@ -984,6 +997,7 @@ static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
 static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
 {
 	struct ov5693_device *dev = to_ov5693_sensor(sd);
+
 	return ov5693_t_focus_abs(sd, dev->focus + value);
 }
 
@@ -993,16 +1007,13 @@ static int ov5693_q_focus_status(struct v4l2_subdev *sd, s32 *value)
 {
 	u32 status = 0;
 	struct ov5693_device *dev = to_ov5693_sensor(sd);
-	struct timespec temptime;
-	const struct timespec timedelay = {
-		0,
-		min((u32)abs(dev->number_of_steps) * DELAY_PER_STEP_NS,
-		(u32)DELAY_MAX_PER_STEP_NS),
-	};
+	ktime_t temptime;
+	ktime_t timedelay = ns_to_ktime(min_t(u32,
+			abs(dev->number_of_steps) * DELAY_PER_STEP_NS,
+			DELAY_MAX_PER_STEP_NS));
 
-	getnstimeofday(&temptime);
-	temptime = timespec_sub(temptime, (dev->timestamp_t_focus_abs));
-	if (timespec_compare(&temptime, &timedelay) <= 0) {
+	temptime = ktime_sub(ktime_get(), (dev->timestamp_t_focus_abs));
+	if (ktime_compare(temptime, timedelay) <= 0) {
 		status |= ATOMISP_FOCUS_STATUS_MOVING;
 		status |= ATOMISP_FOCUS_HP_IN_PROGRESS;
 	} else {
@@ -1033,6 +1044,7 @@ static int ov5693_q_focus_abs(struct v4l2_subdev *sd, s32 *value)
 static int ov5693_t_vcm_slew(struct v4l2_subdev *sd, s32 value)
 {
 	struct ov5693_device *dev = to_ov5693_sensor(sd);
+
 	dev->number_of_steps = value;
 	dev->vcm_update = true;
 	return 0;
@@ -1041,6 +1053,7 @@ static int ov5693_t_vcm_slew(struct v4l2_subdev *sd, s32 value)
 static int ov5693_t_vcm_timing(struct v4l2_subdev *sd, s32 value)
 {
 	struct ov5693_device *dev = to_ov5693_sensor(sd);
+
 	dev->number_of_steps = value;
 	dev->vcm_update = true;
 	return 0;
@@ -1293,11 +1306,13 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag)
 	if (!dev || !dev->platform_data)
 		return -ENODEV;
 
-	/* This driver assumes "internal DVDD, PWDNB tied to DOVDD".
+	/*
+	 * This driver assumes "internal DVDD, PWDNB tied to DOVDD".
 	 * In this set up only gpio0 (XSHUTDN) should be available
 	 * but in some products (for example ECS) gpio1 (PWDNB) is
 	 * also available. If gpio1 is available we emulate it being
-	 * tied to DOVDD here. */
+	 * tied to DOVDD here.
+	 */
 	if (flag) {
 		ret = dev->platform_data->v2p8_ctrl(sd, 1);
 		dev->platform_data->gpio1_ctrl(sd, 1);
@@ -1333,7 +1348,7 @@ static int __power_up(struct v4l2_subdev *sd)
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret;
 
-	if (NULL == dev->platform_data) {
+	if (!dev->platform_data) {
 		dev_err(&client->dev,
 			"no camera_sensor_platform_data");
 		return -ENODEV;
@@ -1381,7 +1396,7 @@ static int power_down(struct v4l2_subdev *sd)
 	int ret = 0;
 
 	dev->focus = OV5693_INVALID_CONFIG;
-	if (NULL == dev->platform_data) {
+	if (!dev->platform_data) {
 		dev_err(&client->dev,
 			"no camera_sensor_platform_data");
 		return -ENODEV;
@@ -1563,6 +1578,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
 	struct camera_mipi_info *ov5693_info = NULL;
 	int ret = 0;
 	int idx;
+
 	if (format->pad)
 		return -EINVAL;
 	if (!fmt)
@@ -1599,6 +1615,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
 	ret = startup(sd);
 	if (ret) {
 		int i = 0;
+
 		dev_err(&client->dev, "ov5693 startup err, retry to power up\n");
 		for (i = 0; i < OV5693_POWER_UP_RETRY_NUM; i++) {
 			dev_err(&client->dev,
@@ -1655,6 +1672,7 @@ static int ov5693_get_fmt(struct v4l2_subdev *sd,
 {
 	struct v4l2_mbus_framefmt *fmt = &format->format;
 	struct ov5693_device *dev = to_ov5693_sensor(sd);
+
 	if (format->pad)
 		return -EINVAL;
 
@@ -1818,6 +1836,7 @@ static int ov5693_s_parm(struct v4l2_subdev *sd,
 			struct v4l2_streamparm *param)
 {
 	struct ov5693_device *dev = to_ov5693_sensor(sd);
+
 	dev->run_mode = param->parm.capture.capturemode;
 
 	mutex_lock(&dev->input_lock);
@@ -1907,6 +1926,7 @@ static int ov5693_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct ov5693_device *dev = to_ov5693_sensor(sd);
+
 	dev_dbg(&client->dev, "ov5693_remove...\n");
 
 	dev->platform_data->csi_cfg(sd, 0);
@@ -1928,13 +1948,14 @@ static int ov5693_probe(struct i2c_client *client)
 	int i2c;
 	int ret = 0;
 	void *pdata = client->dev.platform_data;
-	struct acpi_device *adev;
 	unsigned int i;
 
-	/* Firmware workaround: Some modules use a "secondary default"
+	/*
+	 * Firmware workaround: Some modules use a "secondary default"
 	 * address of 0x10 which doesn't appear on schematics, and
 	 * some BIOS versions haven't gotten the memo.  Work around
-	 * via config. */
+	 * via config.
+	 */
 	i2c = gmin_get_var_int(&client->dev, "I2CAddr", -1);
 	if (i2c != -1) {
 		dev_info(&client->dev,
@@ -1952,14 +1973,9 @@ static int ov5693_probe(struct i2c_client *client)
 	dev->fmt_idx = 0;
 	v4l2_i2c_subdev_init(&(dev->sd), client, &ov5693_ops);
 
-	adev = ACPI_COMPANION(&client->dev);
-	if (adev) {
-		adev->power.flags.power_resources = 0;
-		pdata = gmin_camera_platform_data(&dev->sd,
-						  ATOMISP_INPUT_FORMAT_RAW_10,
-						  atomisp_bayer_order_bggr);
-	}
-
+	pdata = gmin_camera_platform_data(&dev->sd,
+					  ATOMISP_INPUT_FORMAT_RAW_10,
+					  atomisp_bayer_order_bggr);
 	if (!pdata)
 		goto out_free;
 
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
index 2ea6380..68cfcb4 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
+++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
@@ -221,7 +221,7 @@ struct ov5693_device {
 	struct v4l2_ctrl_handler ctrl_handler;
 
 	struct camera_sensor_platform_data *platform_data;
-	struct timespec timestamp_t_focus_abs;
+	ktime_t timestamp_t_focus_abs;
 	int vt_pix_clk_freq_mhz;
 	int fmt_idx;
 	int run_mode;
diff --git a/drivers/staging/media/atomisp/i2c/ov8858.c b/drivers/staging/media/atomisp/i2c/ov8858.c
index ba147ac..3cf8c71 100644
--- a/drivers/staging/media/atomisp/i2c/ov8858.c
+++ b/drivers/staging/media/atomisp/i2c/ov8858.c
@@ -2077,29 +2077,28 @@ static int ov8858_probe(struct i2c_client *client)
 
 	v4l2_i2c_subdev_init(&(dev->sd), client, &ov8858_ops);
 
-	if (ACPI_COMPANION(&client->dev)) {
-		pdata = gmin_camera_platform_data(&dev->sd,
-						  ATOMISP_INPUT_FORMAT_RAW_10,
-						  atomisp_bayer_order_bggr);
-		if (!pdata) {
-			dev_err(&client->dev,
-				"%s: failed to get acpi platform data\n",
-				__func__);
-			goto out_free;
-		}
-		ret = ov8858_s_config(&dev->sd, client->irq, pdata);
-		if (ret) {
-			dev_err(&client->dev,
-				"%s: failed to set config\n", __func__);
-			goto out_free;
-		}
-		ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA);
-		if (ret) {
-			dev_err(&client->dev,
-				"%s: failed to register subdev\n", __func__);
-			goto out_free;
-		}
+	pdata = gmin_camera_platform_data(&dev->sd,
+					  ATOMISP_INPUT_FORMAT_RAW_10,
+					  atomisp_bayer_order_bggr);
+	if (!pdata) {
+		dev_err(&client->dev,
+			"%s: failed to get acpi platform data\n",
+			__func__);
+		goto out_free;
 	}
+	ret = ov8858_s_config(&dev->sd, client->irq, pdata);
+	if (ret) {
+		dev_err(&client->dev,
+			"%s: failed to set config\n", __func__);
+		goto out_free;
+	}
+	ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA);
+	if (ret) {
+		dev_err(&client->dev,
+			"%s: failed to register subdev\n", __func__);
+		goto out_free;
+	}
+
 	/*
 	 * sd->name is updated with sensor driver name by the v4l2.
 	 * change it to sensor name in this case.
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
index 15fa567..ebe193b 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
@@ -68,7 +68,9 @@
 #define V4L2_MBUS_FMT_CUSTOM_RGB32	0x800a
 
 /* Custom media bus format for M10MO RAW capture */
+#if 0
 #define V4L2_MBUS_FMT_CUSTOM_M10MO_RAW	0x800b
+#endif
 
 /* Configuration used by Bayer noise reduction and YCC noise reduction */
 struct atomisp_nr_config {
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
index 7e3ca12..c52c56a 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
@@ -23,7 +23,6 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
 struct v4l2_subdev *atomisp_gmin_find_subdev(struct i2c_adapter *adapter,
 					     struct i2c_board_info *board_info);
 int atomisp_gmin_remove_subdev(struct v4l2_subdev *sd);
-int gmin_get_config_var(struct device *dev, const char *var, char *out, size_t *out_len);
 int gmin_get_var_int(struct device *dev, const char *var, int def);
 int camera_sensor_csi(struct v4l2_subdev *sd, u32 port,
                       u32 lanes, u32 format, u32 bayer_order, int flag);
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c
index 7129b88..ceedb82 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c
@@ -15,9 +15,9 @@
  *
  */
 
+#include <linux/device.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
-#include <linux/pci.h>
 
 #include "atomisp_compat.h"
 #include "atomisp_internal.h"
@@ -33,7 +33,7 @@
  *        bit 2: memory statistic
 */
 struct _iunit_debug {
-	struct pci_driver	*drv;
+	struct device_driver	*drv;
 	struct atomisp_device	*isp;
 	unsigned int		dbglvl;
 	unsigned int		dbgfun;
@@ -164,26 +164,25 @@ static const struct driver_attribute iunit_drvfs_attrs[] = {
 	__ATTR(dbgopt, 0644, iunit_dbgopt_show, iunit_dbgopt_store),
 };
 
-static int iunit_drvfs_create_files(struct pci_driver *drv)
+static int iunit_drvfs_create_files(struct device_driver *drv)
 {
 	int i, ret = 0;
 
 	for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++)
-		ret |= driver_create_file(&(drv->driver),
-					&iunit_drvfs_attrs[i]);
+		ret |= driver_create_file(drv, &iunit_drvfs_attrs[i]);
 
 	return ret;
 }
 
-static void iunit_drvfs_remove_files(struct pci_driver *drv)
+static void iunit_drvfs_remove_files(struct device_driver *drv)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++)
-		driver_remove_file(&(drv->driver), &iunit_drvfs_attrs[i]);
+		driver_remove_file(drv, &iunit_drvfs_attrs[i]);
 }
 
-int atomisp_drvfs_init(struct pci_driver *drv, struct atomisp_device *isp)
+int atomisp_drvfs_init(struct device_driver *drv, struct atomisp_device *isp)
 {
 	int ret;
 
@@ -193,7 +192,7 @@ int atomisp_drvfs_init(struct pci_driver *drv, struct atomisp_device *isp)
 	ret = iunit_drvfs_create_files(iunit_debug.drv);
 	if (ret) {
 		dev_err(atomisp_dev, "drvfs_create_files error: %d\n", ret);
-		iunit_drvfs_remove_files(drv);
+		iunit_drvfs_remove_files(iunit_debug.drv);
 	}
 
 	return ret;
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h
index b91bfef..7c99240 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h
@@ -18,8 +18,7 @@
 #ifndef	__ATOMISP_DRVFS_H__
 #define	__ATOMISP_DRVFS_H__
 
-extern int atomisp_drvfs_init(struct pci_driver *drv, struct atomisp_device
-				*isp);
-extern void atomisp_drvfs_exit(void);
+int atomisp_drvfs_init(struct device_driver *drv, struct atomisp_device *isp);
+void atomisp_drvfs_exit(void);
 
 #endif /* __ATOMISP_DRVFS_H__ */
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h
index 52a6f80..dc476a3 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h
@@ -227,7 +227,6 @@ struct atomisp_device {
 	struct media_device media_dev;
 	struct atomisp_platform_data *pdata;
 	void *mmu_l1_base;
-	struct pci_dev *pci_root;
 	const struct firmware *firmware;
 
 	struct pm_qos_request pm_qos;
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c
index 339b5d3..5c84dd6 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c
@@ -501,7 +501,9 @@ const struct atomisp_format_bridge atomisp_output_fmts[] = {
 		.mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
 		.sh_fmt = CSS_FRAME_FORMAT_BINARY_8,
 		.description = "JPEG"
-	}, {
+	},
+#if 0
+	{
 	/* This is a custom format being used by M10MO to send the RAW data */
 		.pixelformat = V4L2_PIX_FMT_CUSTOM_M10MO_RAW,
 		.depth = 8,
@@ -509,6 +511,7 @@ const struct atomisp_format_bridge atomisp_output_fmts[] = {
 		.sh_fmt = CSS_FRAME_FORMAT_BINARY_8,
 		.description = "Custom RAW for M10MO"
 	},
+#endif
 };
 
 const struct atomisp_format_bridge *atomisp_get_format_bridge(
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c
index 70b5398..f3e18d6 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c
@@ -48,7 +48,9 @@ const struct atomisp_in_fmt_conv atomisp_in_fmt_conv[] = {
 	{ V4L2_MBUS_FMT_CUSTOM_NV12, 12, 12, CSS_FRAME_FORMAT_NV12, 0, CSS_FRAME_FORMAT_NV12 },
 	{ V4L2_MBUS_FMT_CUSTOM_NV21, 12, 12, CSS_FRAME_FORMAT_NV21, 0, CSS_FRAME_FORMAT_NV21 },
 	{ V4L2_MBUS_FMT_CUSTOM_YUV420, 12, 12, ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY, 0, IA_CSS_STREAM_FORMAT_YUV420_8_LEGACY },
+#if 0
 	{ V4L2_MBUS_FMT_CUSTOM_M10MO_RAW, 8, 8, CSS_FRAME_FORMAT_BINARY_8, 0, IA_CSS_STREAM_FORMAT_BINARY_8 },
+#endif
 	/* no valid V4L2 MBUS code for metadata format, so leave it 0. */
 	{ 0, 0, 0, ATOMISP_INPUT_FORMAT_EMBEDDED, 0, IA_CSS_STREAM_FORMAT_EMBEDDED },
 	{}
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c
index 3c260f8..548e00e 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c
@@ -1152,8 +1152,6 @@ static int init_atomisp_wdts(struct atomisp_device *isp)
 	return err;
 }
 
-static struct pci_driver atomisp_pci_driver;
-
 #define ATOM_ISP_PCI_BAR	0
 
 static int atomisp_pci_probe(struct pci_dev *dev,
@@ -1212,11 +1210,6 @@ static int atomisp_pci_probe(struct pci_dev *dev,
 	isp->pdev = dev;
 	isp->dev = &dev->dev;
 	isp->sw_contex.power_state = ATOM_ISP_POWER_UP;
-	isp->pci_root = pci_get_bus_and_slot(0, 0);
-	if (!isp->pci_root) {
-		dev_err(&dev->dev, "Unable to find PCI host\n");
-		return -ENODEV;
-	}
 	isp->saved_regs.ispmmadr = start;
 
 	rt_mutex_init(&isp->mutex);
@@ -1451,7 +1444,7 @@ static int atomisp_pci_probe(struct pci_dev *dev,
 	isp->firmware = NULL;
 	isp->css_env.isp_css_fw.data = NULL;
 
-	atomisp_drvfs_init(&atomisp_pci_driver, isp);
+	atomisp_drvfs_init(&dev->driver->driver, isp);
 
 	return 0;
 
@@ -1496,7 +1489,6 @@ static int atomisp_pci_probe(struct pci_dev *dev,
 	/* Address later when we worry about the ...field chips */
 	if (IS_ENABLED(CONFIG_PM) && atomisp_mrfld_power_down(isp))
 		dev_err(&dev->dev, "Failed to switch off ISP\n");
-	pci_dev_put(isp->pci_root);
 	return err;
 }
 
@@ -1517,8 +1509,6 @@ static void atomisp_pci_remove(struct pci_dev *dev)
 	pm_qos_remove_request(&isp->pm_qos);
 
 	atomisp_msi_irq_uninit(isp, dev);
-	pci_dev_put(isp->pci_root);
-
 	atomisp_unregister_entities(isp);
 
 	destroy_workqueue(isp->wdt_work_queue);
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8.host.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8.host.c
index 682f8b7..47bb504 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8.host.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8.host.c
@@ -32,44 +32,44 @@
 #define NUMBER_OF_TCINV_POINTS 9
 #define NUMBER_OF_FCINV_POINTS 9
 
-const int16_t chgrinv_x[NUMBER_OF_CHGRINV_POINTS] = {
+static const int16_t chgrinv_x[NUMBER_OF_CHGRINV_POINTS] = {
 0, 16, 64, 144, 272, 448, 672, 976,
 1376, 1888, 2528, 3312, 4256, 5376, 6688};
 
-const int16_t chgrinv_a[NUMBER_OF_CHGRINV_POINTS] = {
+static const int16_t chgrinv_a[NUMBER_OF_CHGRINV_POINTS] = {
 -7171, -256, -29, -3456, -1071, -475, -189, -102,
 -48, -38, -10, -9, -7, -6, 0};
 
-const int16_t chgrinv_b[NUMBER_OF_CHGRINV_POINTS] = {
+static const int16_t chgrinv_b[NUMBER_OF_CHGRINV_POINTS] = {
 8191, 1021, 256, 114, 60, 37, 24, 17,
 12, 9, 6, 5, 4, 3, 2};
 
-const int16_t chgrinv_c[NUMBER_OF_CHGRINV_POINTS] = {
+static const int16_t chgrinv_c[NUMBER_OF_CHGRINV_POINTS] = {
 1, 1, 1, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0};
 
-const int16_t tcinv_x[NUMBER_OF_TCINV_POINTS] = {
+static const int16_t tcinv_x[NUMBER_OF_TCINV_POINTS] = {
 0, 4, 11, 23, 42, 68, 102, 148, 205};
 
-const int16_t tcinv_a[NUMBER_OF_TCINV_POINTS] = {
+static const int16_t tcinv_a[NUMBER_OF_TCINV_POINTS] = {
 -6364, -631, -126, -34, -13, -6, -4452, -2156, 0};
 
-const int16_t tcinv_b[NUMBER_OF_TCINV_POINTS] = {
+static const int16_t tcinv_b[NUMBER_OF_TCINV_POINTS] = {
 8191, 1828, 726, 352, 197, 121, 80, 55, 40};
 
-const int16_t tcinv_c[NUMBER_OF_TCINV_POINTS] = {
+static const int16_t tcinv_c[NUMBER_OF_TCINV_POINTS] = {
 1, 1, 1, 1, 1, 1, 0, 0, 0};
 
-const int16_t fcinv_x[NUMBER_OF_FCINV_POINTS] = {
+static const int16_t fcinv_x[NUMBER_OF_FCINV_POINTS] = {
 0, 80, 216, 456, 824, 1344, 2040, 2952, 4096};
 
-const int16_t fcinv_a[NUMBER_OF_FCINV_POINTS] = {
+static const int16_t fcinv_a[NUMBER_OF_FCINV_POINTS] = {
 -5244, -486, -86, -2849, -961, -400, -180, -86, 0};
 
-const int16_t fcinv_b[NUMBER_OF_FCINV_POINTS] = {
+static const int16_t fcinv_b[NUMBER_OF_FCINV_POINTS] = {
 8191, 1637, 607, 287, 159, 98, 64, 44, 32};
 
-const int16_t fcinv_c[NUMBER_OF_FCINV_POINTS] = {
+static const int16_t fcinv_c[NUMBER_OF_FCINV_POINTS] = {
 1, 1, 1, 0, 0, 0, 0, 0, 0};
 
 
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c
index dd1127a..f22d73b 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c
@@ -2567,6 +2567,7 @@ ia_css_debug_mode_enable_dma_channel(int dma_id,
 	return rc;
 }
 
+static
 void dtrace_dot(const char *fmt, ...)
 {
 	va_list ap;
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h
index 2283dd1..fa3f093 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h
+++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h
@@ -95,7 +95,7 @@ union ia_css_all_memory_offsets {
 };
 
 #define IA_CSS_DEFAULT_ISP_MEM_PARAMS \
-		{ { { { 0, 0 } } } }
+		{ { { { NULL, 0 } } } }
 
 #define IA_CSS_DEFAULT_ISP_CSS_PARAMS \
 		{ { { { 0, 0 } } } }
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c
index a1c81c1..4338b8a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c
@@ -158,10 +158,10 @@ static ssize_t dynamic_pool_show(struct device *dev,
 	return ret;
 };
 
-static DEVICE_ATTR(active_bo, 0444, active_bo_show, NULL);
-static DEVICE_ATTR(free_bo, 0444, free_bo_show, NULL);
-static DEVICE_ATTR(reserved_pool, 0444, reserved_pool_show, NULL);
-static DEVICE_ATTR(dynamic_pool, 0444, dynamic_pool_show, NULL);
+static DEVICE_ATTR_RO(active_bo);
+static DEVICE_ATTR_RO(free_bo);
+static DEVICE_ATTR_RO(reserved_pool);
+static DEVICE_ATTR_RO(dynamic_pool);
 
 static struct attribute *sysfs_attrs_ctrl[] = {
 	&dev_attr_active_bo.attr,
diff --git a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
index bf9f34b..d8b7183 100644
--- a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
+++ b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
@@ -114,7 +114,7 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
 	struct i2c_board_info *bi;
 	struct gmin_subdev *gs;
 	struct i2c_client *client = v4l2_get_subdevdata(subdev);
-	struct acpi_device *adev;
+	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
 
 	dev_info(&client->dev, "register atomisp i2c module type %d\n", type);
 
@@ -124,9 +124,7 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
 	 * tickled during suspend/resume.  This has caused power and
 	 * performance issues on multiple devices.
 	 */
-	adev = ACPI_COMPANION(&client->dev);
-	if (adev)
-		adev->power.flags.power_resources = 0;
+	adev->power.flags.power_resources = 0;
 
 	for (i = 0; i < MAX_SUBDEVS; i++)
 		if (!pdata.subdevs[i].type)
@@ -211,7 +209,7 @@ struct gmin_cfg_var {
 	const char *name, *val;
 };
 
-static const struct gmin_cfg_var ffrd8_vars[] = {
+static struct gmin_cfg_var ffrd8_vars[] = {
 	{ "INTCF1B:00_ImxId",    "0x134" },
 	{ "INTCF1B:00_CsiPort",  "1" },
 	{ "INTCF1B:00_CsiLanes", "4" },
@@ -222,14 +220,14 @@ static const struct gmin_cfg_var ffrd8_vars[] = {
 /* Cribbed from MCG defaults in the mt9m114 driver, not actually verified
  * vs. T100 hardware
  */
-static const struct gmin_cfg_var t100_vars[] = {
+static struct gmin_cfg_var t100_vars[] = {
 	{ "INT33F0:00_CsiPort",  "0" },
 	{ "INT33F0:00_CsiLanes", "1" },
 	{ "INT33F0:00_CamClk",   "1" },
 	{},
 };
 
-static const struct gmin_cfg_var mrd7_vars[] = {
+static struct gmin_cfg_var mrd7_vars[] = {
 	{"INT33F8:00_CamType", "1"},
 	{"INT33F8:00_CsiPort", "1"},
 	{"INT33F8:00_CsiLanes", "2"},
@@ -245,7 +243,7 @@ static const struct gmin_cfg_var mrd7_vars[] = {
 	{},
 };
 
-static const struct gmin_cfg_var ecs7_vars[] = {
+static struct gmin_cfg_var ecs7_vars[] = {
 	{"INT33BE:00_CsiPort", "1"},
 	{"INT33BE:00_CsiLanes", "2"},
 	{"INT33BE:00_CsiFmt", "13"},
@@ -260,8 +258,7 @@ static const struct gmin_cfg_var ecs7_vars[] = {
 	{},
 };
 
-
-static const struct gmin_cfg_var i8880_vars[] = {
+static struct gmin_cfg_var i8880_vars[] = {
 	{"XXOV2680:00_CsiPort", "1"},
 	{"XXOV2680:00_CsiLanes", "1"},
 	{"XXOV2680:00_CamClk", "0"},
@@ -271,18 +268,46 @@ static const struct gmin_cfg_var i8880_vars[] = {
 	{},
 };
 
-static const struct {
-	const char *dmi_board_name;
-	const struct gmin_cfg_var *vars;
-} hard_vars[] = {
-	{ "BYT-T FFD8", ffrd8_vars },
-	{ "T100TA", t100_vars },
-	{ "MRD7", mrd7_vars },
-	{ "ST70408", ecs7_vars },
-	{ "VTA0803", i8880_vars },
+static const struct dmi_system_id gmin_vars[] = {
+	{
+		.ident = "BYT-T FFD8",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
+		},
+		.driver_data = ffrd8_vars,
+	},
+	{
+		.ident = "T100TA",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "T100TA"),
+		},
+		.driver_data = t100_vars,
+	},
+	{
+		.ident = "MRD7",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "TABLET"),
+			DMI_MATCH(DMI_BOARD_VERSION, "MRD 7"),
+		},
+		.driver_data = mrd7_vars,
+	},
+	{
+		.ident = "ST70408",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "ST70408"),
+		},
+		.driver_data = ecs7_vars,
+	},
+	{
+		.ident = "VTA0803",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "VTA0803"),
+		},
+		.driver_data = i8880_vars,
+	},
+	{}
 };
 
-
 #define GMIN_CFG_VAR_EFI_GUID EFI_GUID(0xecb54cd9, 0xe5ae, 0x4fdc, \
 				       0xa9, 0x71, 0xe8, 0x77,	   \
 				       0x75, 0x60, 0x68, 0xf7)
@@ -322,8 +347,6 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
 							VLV2_CLK_PLL_19P2MHZ);
 	gmin_subdevs[i].csi_port = gmin_get_var_int(dev, "CsiPort", 0);
 	gmin_subdevs[i].csi_lanes = gmin_get_var_int(dev, "CsiLanes", 1);
-	gmin_subdevs[i].gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW);
-	gmin_subdevs[i].gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW);
 
 	/* get PMC clock with clock framework */
 	snprintf(gmin_pmc_clk_name,
@@ -356,9 +379,11 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
 	if (!ret)
 		clk_disable_unprepare(gmin_subdevs[i].pmc_clk);
 
+	gmin_subdevs[i].gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW);
 	if (IS_ERR(gmin_subdevs[i].gpio0))
 		gmin_subdevs[i].gpio0 = NULL;
 
+	gmin_subdevs[i].gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW);
 	if (IS_ERR(gmin_subdevs[i].gpio1))
 		gmin_subdevs[i].gpio1 = NULL;
 
@@ -394,7 +419,7 @@ static int gmin_gpio0_ctrl(struct v4l2_subdev *subdev, int on)
 {
 	struct gmin_subdev *gs = find_gmin_subdev(subdev);
 
-	if (gs && gs->gpio0) {
+	if (gs) {
 		gpiod_set_value(gs->gpio0, on);
 		return 0;
 	}
@@ -405,7 +430,7 @@ static int gmin_gpio1_ctrl(struct v4l2_subdev *subdev, int on)
 {
 	struct gmin_subdev *gs = find_gmin_subdev(subdev);
 
-	if (gs && gs->gpio1) {
+	if (gs) {
 		gpiod_set_value(gs->gpio1, on);
 		return 0;
 	}
@@ -606,17 +631,41 @@ int atomisp_gmin_register_vcm_control(struct camera_vcm_control *vcmCtrl)
 }
 EXPORT_SYMBOL_GPL(atomisp_gmin_register_vcm_control);
 
+static int gmin_get_hardcoded_var(struct gmin_cfg_var *varlist,
+				  const char *var8, char *out, size_t *out_len)
+{
+	struct gmin_cfg_var *gv;
+
+	for (gv = varlist; gv->name; gv++) {
+		size_t vl;
+
+		if (strcmp(var8, gv->name))
+			continue;
+
+		vl = strlen(gv->val);
+		if (vl > *out_len - 1)
+			return -ENOSPC;
+
+		strcpy(out, gv->val);
+		*out_len = vl;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 /* Retrieves a device-specific configuration variable.  The dev
  * argument should be a device with an ACPI companion, as all
  * configuration is based on firmware ID.
  */
-int gmin_get_config_var(struct device *dev, const char *var, char *out,
-			size_t *out_len)
+static int gmin_get_config_var(struct device *dev, const char *var,
+			       char *out, size_t *out_len)
 {
 	char var8[CFG_VAR_NAME_MAX];
 	efi_char16_t var16[CFG_VAR_NAME_MAX];
 	struct efivar_entry *ev;
-	int i, j, ret;
+	const struct dmi_system_id *id;
+	int i, ret;
 
 	if (dev && ACPI_COMPANION(dev))
 		dev = &ACPI_COMPANION(dev)->dev;
@@ -633,28 +682,9 @@ int gmin_get_config_var(struct device *dev, const char *var, char *out,
 	 * Some device firmwares lack the ability to set EFI variables at
 	 * runtime.
 	 */
-	for (i = 0; i < ARRAY_SIZE(hard_vars); i++) {
-		if (dmi_match(DMI_BOARD_NAME, hard_vars[i].dmi_board_name)) {
-			for (j = 0; hard_vars[i].vars[j].name; j++) {
-				size_t vl;
-				const struct gmin_cfg_var *gv;
-
-				gv = &hard_vars[i].vars[j];
-				vl = strlen(gv->val);
-
-				if (strcmp(var8, gv->name))
-					continue;
-				if (vl > *out_len - 1)
-					return -ENOSPC;
-
-				memcpy(out, gv->val, min(*out_len, vl+1));
-				out[*out_len-1] = 0;
-				*out_len = vl;
-
-				return 0;
-			}
-		}
-	}
+	id = dmi_first_match(gmin_vars);
+	if (id)
+		return gmin_get_hardcoded_var(id->driver_data, var8, out, out_len);
 
 	/* Our variable names are ASCII by construction, but EFI names
 	 * are wide chars.  Convert and zero-pad.
@@ -693,7 +723,6 @@ int gmin_get_config_var(struct device *dev, const char *var, char *out,
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(gmin_get_config_var);
 
 int gmin_get_var_int(struct device *dev, const char *var, int def)
 {
diff --git a/drivers/staging/media/cxd2099/Makefile b/drivers/staging/media/cxd2099/Makefile
index b2905e65..30432c9 100644
--- a/drivers/staging/media/cxd2099/Makefile
+++ b/drivers/staging/media/cxd2099/Makefile
@@ -1,5 +1,4 @@
 obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
 
-ccflags-y += -Idrivers/media/dvb-core/
 ccflags-y += -Idrivers/media/dvb-frontends/
 ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/staging/media/cxd2099/cxd2099.c b/drivers/staging/media/cxd2099/cxd2099.c
index 3e30f48..dc9cbd8 100644
--- a/drivers/staging/media/cxd2099/cxd2099.c
+++ b/drivers/staging/media/cxd2099/cxd2099.c
@@ -3,23 +3,14 @@
  *
  * Copyright (C) 2010-2013 Digital Devices GmbH
  *
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * version 2 only, as published by the Free Software Foundation.
  *
- *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  */
 
 #include <linux/slab.h>
@@ -35,7 +26,7 @@
 
 static int buffermode;
 module_param(buffermode, int, 0444);
-MODULE_PARM_DESC(buffermode, "Enable use of the CXD2099AR buffer mode (default: disabled)");
+MODULE_PARM_DESC(buffermode, "Enable CXD2099AR buffer mode (default: disabled)");
 
 static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount);
 
@@ -59,7 +50,7 @@ struct cxd {
 	int    amem_read;
 
 	int    cammode;
-	struct mutex lock;
+	struct mutex lock; /* device access lock */
 
 	u8     rbuf[1028];
 	u8     wbuf[1028];
@@ -101,7 +92,7 @@ static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr,
 				   .buf = val, .len = 1} };
 
 	if (i2c_transfer(adapter, msgs, 2) != 2) {
-		dev_err(&adapter->dev, "error in i2c_read_reg\n");
+		dev_err(&adapter->dev, "error in %s()\n", __func__);
 		return -1;
 	}
 	return 0;
@@ -116,7 +107,7 @@ static int i2c_read(struct i2c_adapter *adapter, u8 adr,
 				   .buf = data, .len = n} };
 
 	if (i2c_transfer(adapter, msgs, 2) != 2) {
-		dev_err(&adapter->dev, "error in i2c_read\n");
+		dev_err(&adapter->dev, "error in %s()\n", __func__);
 		return -1;
 	}
 	return 0;
@@ -134,7 +125,7 @@ static int read_block(struct cxd *ci, u8 adr, u8 *data, u16 n)
 		while (n) {
 			int len = n;
 
-			if (ci->cfg.max_i2c && (len > ci->cfg.max_i2c))
+			if (ci->cfg.max_i2c && len > ci->cfg.max_i2c)
 				len = ci->cfg.max_i2c;
 			status = i2c_read(ci->i2c, ci->cfg.adr, 1, data, len);
 			if (status)
@@ -527,7 +518,7 @@ static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
 {
 	struct cxd *ci = ca->data;
 
-	dev_info(&ci->i2c->dev, "%s\n", __func__);
+	dev_dbg(&ci->i2c->dev, "%s\n", __func__);
 	if (ci->cammode)
 		read_data(ca, slot, ci->rbuf, 0);
 	mutex_lock(&ci->lock);
@@ -591,7 +582,7 @@ static int campoll(struct cxd *ci)
 			}
 		}
 		if ((istat & 8) &&
-		    (ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT)) {
+		    ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT) {
 			ci->ready = 1;
 			ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY;
 		}
@@ -677,7 +668,8 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
 	u8 val;
 
 	if (i2c_read_reg(i2c, cfg->adr, 0, &val) < 0) {
-		dev_info(&i2c->dev, "No CXD2099 detected at %02x\n", cfg->adr);
+		dev_info(&i2c->dev, "No CXD2099AR detected at 0x%02x\n",
+			 cfg->adr);
 		return NULL;
 	}
 
@@ -695,7 +687,7 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
 	ci->en = en_templ;
 	ci->en.data = ci;
 	init(ci);
-	dev_info(&i2c->dev, "Attached CXD2099AR at %02x\n", ci->cfg.adr);
+	dev_info(&i2c->dev, "Attached CXD2099AR at 0x%02x\n", ci->cfg.adr);
 
 	if (!buffermode) {
 		ci->en.read_data = NULL;
@@ -708,6 +700,6 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
 }
 EXPORT_SYMBOL(cxd2099_attach);
 
-MODULE_DESCRIPTION("cxd2099");
+MODULE_DESCRIPTION("CXD2099AR Common Interface controller driver");
 MODULE_AUTHOR("Ralph Metzler");
 MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/cxd2099/cxd2099.h b/drivers/staging/media/cxd2099/cxd2099.h
index f4b29b1..253e3155 100644
--- a/drivers/staging/media/cxd2099/cxd2099.h
+++ b/drivers/staging/media/cxd2099/cxd2099.h
@@ -3,29 +3,20 @@
  *
  * Copyright (C) 2010-2011 Digital Devices GmbH
  *
- *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * version 2 only, as published by the Free Software Foundation.
  *
- *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  */
 
 #ifndef _CXD2099_H_
 #define _CXD2099_H_
 
-#include <dvb_ca_en50221.h>
+#include <media/dvb_ca_en50221.h>
 
 struct cxd2099_cfg {
 	u32 bitrate;
@@ -42,8 +33,9 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
 				      void *priv, struct i2c_adapter *i2c);
 #else
 
-static inline struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
-					void *priv, struct i2c_adapter *i2c)
+static inline struct
+dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg, void *priv,
+			       struct i2c_adapter *i2c)
 {
 	dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
diff --git a/drivers/staging/media/davinci_vpfe/TODO b/drivers/staging/media/davinci_vpfe/TODO
index 7015ab3..3e5477e 100644
--- a/drivers/staging/media/davinci_vpfe/TODO
+++ b/drivers/staging/media/davinci_vpfe/TODO
@@ -2,11 +2,11 @@
 ==================================
 
 - 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
+	- 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
diff --git a/drivers/staging/media/imx/TODO b/drivers/staging/media/imx/TODO
index 0bee313..9eb7326 100644
--- a/drivers/staging/media/imx/TODO
+++ b/drivers/staging/media/imx/TODO
@@ -1,19 +1,14 @@
 
-- Clean up and move the ov5642 subdev driver to drivers/media/i2c, or
-  merge support for OV5642 into drivers/media/i2c/ov5640.c, and create
-  the binding docs for it.
-
 - The Frame Interval Monitor could be exported to v4l2-core for
   general use.
 
-- At driver load time, the device-tree node that is the original source
-  (the "sensor"), is parsed to record its media bus configuration, and
-  this info is required in imx-media-csi.c to setup the CSI.
-  Laurent Pinchart argues that instead the CSI subdev should call its
-  neighbor's g_mbus_config op (which should be propagated if necessary)
-  to get this info. However Hans Verkuil is planning to remove the
-  g_mbus_config op. For now this driver uses the parsed DT mbus config
-  method until this issue is resolved.
+- The CSI subdevice parses its nearest upstream neighbor's device-tree
+  bus config in order to setup the CSI. Laurent Pinchart argues that
+  instead the CSI subdev should call its neighbor's g_mbus_config op
+  (which should be propagated if necessary) to get this info. However
+  Hans Verkuil is planning to remove the g_mbus_config op. For now this
+  driver uses the parsed DT bus config method until this issue is
+  resolved.
 
 - This media driver supports inheriting V4L2 controls to the
   video capture devices, from the subdevices in the capture device's
@@ -21,3 +16,47 @@
   link_notify callback when the pipeline is modified. It should be
   decided whether this feature is useful enough to make it generally
   available by exporting to v4l2-core.
+
+- The OF graph is walked at probe time to form the list of fwnodes to
+  be passed to v4l2_async_notifier_register(), starting from the IPU
+  CSI ports. And after all async subdevices have been bound,
+  v4l2_fwnode_parse_link() is used to form the media links between
+  the entities discovered by walking the OF graph.
+
+  While this approach allows support for arbitrary OF graphs, there
+  are some assumptions for this to work:
+
+  1. All port parent nodes reachable in the graph from the IPU CSI
+     ports bind to V4L2 async subdevice drivers.
+
+     If a device has mixed-use ports such as video plus audio, the
+     endpoints from the audio ports are followed to devices that must
+     bind to V4L2 subdevice drivers, and not for example, to an ALSA
+     driver or a non-V4L2 media driver. If the device were bound to
+     such a driver, imx-media would never get an async completion
+     notification because the device fwnode was added to the async
+     list, but the driver does not interface with the V4L2 async
+     framework.
+
+  2. Every port reachable in the graph is treated as a media pad,
+     owned by the V4L2 subdevice that is bound to the port's parent.
+
+     This presents problems for devices that don't make this port = pad
+     assumption. Examples are SMIAPP compatible cameras which define only
+     a single output port node, but which define multiple pads owned
+     by multiple subdevices (pixel-array, binner, scaler). Or video
+     decoders (entity function MEDIA_ENT_F_ATV_DECODER), which also define
+     only a single output port node, but define multiple pads for video,
+     VBI, and audio out.
+
+     A workaround at present is to set the port reg properties to
+     correspond to the media pad index that the port represents. A
+     possible long-term solution is to implement a subdev API that
+     maps a port id to a media pad index.
+
+  3. Every endpoint of a port reachable in the graph is treated as
+     a media link, between V4L2 subdevices that are bound to the
+     port parents of the local and remote endpoints.
+
+     Which means a port must not contain mixed-use endpoints, they
+     must all refer to media links between V4L2 subdevices.
diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c
index 9e41987..c6d7e80 100644
--- a/drivers/staging/media/imx/imx-ic-prp.c
+++ b/drivers/staging/media/imx/imx-ic-prp.c
@@ -300,7 +300,7 @@ static int prp_link_validate(struct v4l2_subdev *sd,
 {
 	struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd);
 	struct prp_priv *priv = ic_priv->prp_priv;
-	struct imx_media_subdev *csi;
+	struct v4l2_subdev *csi;
 	int ret;
 
 	ret = v4l2_subdev_link_validate_default(sd, link,
@@ -333,7 +333,7 @@ static int prp_link_validate(struct v4l2_subdev *sd,
 	}
 
 	if (csi) {
-		switch (csi->sd->grp_id) {
+		switch (csi->grp_id) {
 		case IMX_MEDIA_GRP_ID_CSI0:
 			priv->csi_id = 0;
 			break;
diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c
index ea145ba..576bdc7 100644
--- a/drivers/staging/media/imx/imx-media-capture.c
+++ b/drivers/staging/media/imx/imx-media-capture.c
@@ -449,9 +449,6 @@ static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
 	unsigned long flags;
 	int ret;
 
-	if (vb2_is_streaming(vq))
-		return 0;
-
 	ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
 					    true);
 	if (ret) {
@@ -480,9 +477,6 @@ static void capture_stop_streaming(struct vb2_queue *vq)
 	unsigned long flags;
 	int ret;
 
-	if (!vb2_is_streaming(vq))
-		return;
-
 	spin_lock_irqsave(&priv->q_lock, flags);
 	priv->stop = true;
 	spin_unlock_irqrestore(&priv->q_lock, flags);
@@ -754,6 +748,8 @@ imx_media_capture_device_init(struct v4l2_subdev *src_sd, int pad)
 	vfd->queue = &priv->q;
 	priv->vdev.vfd = vfd;
 
+	INIT_LIST_HEAD(&priv->vdev.list);
+
 	video_set_drvdata(vfd, priv);
 
 	v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0);
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 26994b4..eb7be50 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -13,6 +13,7 @@
 #include <linux/gcd.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/of_graph.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <media/v4l2-ctrls.h>
@@ -99,8 +100,8 @@ struct csi_priv {
 	/* the mipi virtual channel number at link validate */
 	int vc_num;
 
-	/* the attached sensor at stream on */
-	struct imx_media_subdev *sensor;
+	/* the upstream endpoint CSI is receiving from */
+	struct v4l2_fwnode_endpoint upstream_ep;
 
 	spinlock_t irqlock; /* protect eof_irq handler */
 	struct timer_list eof_timeout_timer;
@@ -120,6 +121,70 @@ static inline struct csi_priv *sd_to_dev(struct v4l2_subdev *sdev)
 	return container_of(sdev, struct csi_priv, sd);
 }
 
+static inline bool is_parallel_16bit_bus(struct v4l2_fwnode_endpoint *ep)
+{
+	return ep->bus_type != V4L2_MBUS_CSI2 &&
+		ep->bus.parallel.bus_width >= 16;
+}
+
+/*
+ * Parses the fwnode endpoint from the source pad of the entity
+ * connected to this CSI. This will either be the entity directly
+ * upstream from the CSI-2 receiver, or directly upstream from the
+ * video mux. The endpoint is needed to determine the bus type and
+ * bus config coming into the CSI.
+ */
+static int csi_get_upstream_endpoint(struct csi_priv *priv,
+				     struct v4l2_fwnode_endpoint *ep)
+{
+	struct device_node *endpoint, *port;
+	struct media_entity *src;
+	struct v4l2_subdev *sd;
+	struct media_pad *pad;
+
+	if (!priv->src_sd)
+		return -EPIPE;
+
+	src = &priv->src_sd->entity;
+
+	if (src->function == MEDIA_ENT_F_VID_MUX) {
+		/*
+		 * CSI is connected directly to video mux, skip up to
+		 * CSI-2 receiver if it is in the path, otherwise stay
+		 * with video mux.
+		 */
+		sd = imx_media_find_upstream_subdev(priv->md, src,
+						    IMX_MEDIA_GRP_ID_CSI2);
+		if (!IS_ERR(sd))
+			src = &sd->entity;
+	}
+
+	/* get source pad of entity directly upstream from src */
+	pad = imx_media_find_upstream_pad(priv->md, src, 0);
+	if (IS_ERR(pad))
+		return PTR_ERR(pad);
+
+	sd = media_entity_to_v4l2_subdev(pad->entity);
+
+	/*
+	 * NOTE: this assumes an OF-graph port id is the same as a
+	 * media pad index.
+	 */
+	port = of_graph_get_port_by_id(sd->dev->of_node, pad->index);
+	if (!port)
+		return -ENODEV;
+
+	endpoint = of_get_next_child(port, NULL);
+	of_node_put(port);
+	if (!endpoint)
+		return -ENODEV;
+
+	v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), ep);
+	of_node_put(endpoint);
+
+	return 0;
+}
+
 static void csi_idmac_put_ipu_resources(struct csi_priv *priv)
 {
 	if (priv->idmac_ch)
@@ -302,7 +367,6 @@ static void csi_idmac_unsetup_vb2_buf(struct csi_priv *priv,
 static int csi_idmac_setup_channel(struct csi_priv *priv)
 {
 	struct imx_media_video_dev *vdev = priv->vdev;
-	struct v4l2_fwnode_endpoint *sensor_ep;
 	struct v4l2_mbus_framefmt *infmt;
 	struct ipu_image image;
 	u32 passthrough_bits;
@@ -312,7 +376,6 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
 	int ret;
 
 	infmt = &priv->format_mbus[CSI_SINK_PAD];
-	sensor_ep = &priv->sensor->sensor_ep;
 
 	ipu_cpmem_zero(priv->idmac_ch);
 
@@ -330,14 +393,14 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
 	 * Check for conditions that require the IPU to handle the
 	 * data internally as generic data, aka passthrough mode:
 	 * - raw bayer formats
-	 * - the sensor bus is 16-bit parallel
+	 * - the CSI is receiving from a 16-bit parallel bus
 	 */
 	switch (image.pix.pixelformat) {
 	case V4L2_PIX_FMT_SBGGR8:
 	case V4L2_PIX_FMT_SGBRG8:
 	case V4L2_PIX_FMT_SGRBG8:
 	case V4L2_PIX_FMT_SRGGB8:
-		burst_size = 8;
+		burst_size = 16;
 		passthrough = true;
 		passthrough_bits = 8;
 		break;
@@ -354,8 +417,7 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
 		burst_size = (image.pix.width & 0x3f) ?
 			     ((image.pix.width & 0x1f) ?
 			      ((image.pix.width & 0xf) ? 8 : 16) : 32) : 64;
-		passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 &&
-			       sensor_ep->bus.parallel.bus_width >= 16);
+		passthrough = is_parallel_16bit_bus(&priv->upstream_ep);
 		passthrough_bits = 16;
 		/* Skip writing U and V components to odd rows */
 		ipu_cpmem_skip_odd_chroma_rows(priv->idmac_ch);
@@ -364,14 +426,12 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
 	case V4L2_PIX_FMT_UYVY:
 		burst_size = (image.pix.width & 0x1f) ?
 			     ((image.pix.width & 0xf) ? 8 : 16) : 32;
-		passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 &&
-			       sensor_ep->bus.parallel.bus_width >= 16);
+		passthrough = is_parallel_16bit_bus(&priv->upstream_ep);
 		passthrough_bits = 16;
 		break;
 	default:
 		burst_size = (image.pix.width & 0xf) ? 8 : 16;
-		passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 &&
-			       sensor_ep->bus.parallel.bus_width >= 16);
+		passthrough = is_parallel_16bit_bus(&priv->upstream_ep);
 		passthrough_bits = 16;
 		break;
 	}
@@ -568,22 +628,20 @@ static void csi_idmac_stop(struct csi_priv *priv)
 static int csi_setup(struct csi_priv *priv)
 {
 	struct v4l2_mbus_framefmt *infmt, *outfmt;
-	struct v4l2_mbus_config sensor_mbus_cfg;
-	struct v4l2_fwnode_endpoint *sensor_ep;
+	struct v4l2_mbus_config mbus_cfg;
 	struct v4l2_mbus_framefmt if_fmt;
 
 	infmt = &priv->format_mbus[CSI_SINK_PAD];
 	outfmt = &priv->format_mbus[priv->active_output_pad];
-	sensor_ep = &priv->sensor->sensor_ep;
 
-	/* compose mbus_config from sensor endpoint */
-	sensor_mbus_cfg.type = sensor_ep->bus_type;
-	sensor_mbus_cfg.flags = (sensor_ep->bus_type == V4L2_MBUS_CSI2) ?
-		sensor_ep->bus.mipi_csi2.flags :
-		sensor_ep->bus.parallel.flags;
+	/* compose mbus_config from the upstream endpoint */
+	mbus_cfg.type = priv->upstream_ep.bus_type;
+	mbus_cfg.flags = (priv->upstream_ep.bus_type == V4L2_MBUS_CSI2) ?
+		priv->upstream_ep.bus.mipi_csi2.flags :
+		priv->upstream_ep.bus.parallel.flags;
 
 	/*
-	 * we need to pass input sensor frame to CSI interface, but
+	 * we need to pass input frame to CSI interface, but
 	 * with translated field type from output format
 	 */
 	if_fmt = *infmt;
@@ -595,7 +653,7 @@ static int csi_setup(struct csi_priv *priv)
 			     priv->crop.width == 2 * priv->compose.width,
 			     priv->crop.height == 2 * priv->compose.height);
 
-	ipu_csi_init_interface(priv->csi, &sensor_mbus_cfg, &if_fmt);
+	ipu_csi_init_interface(priv->csi, &mbus_cfg, &if_fmt);
 
 	ipu_csi_set_dest(priv->csi, priv->dest);
 
@@ -611,35 +669,11 @@ static int csi_setup(struct csi_priv *priv)
 static int csi_start(struct csi_priv *priv)
 {
 	struct v4l2_fract *output_fi, *input_fi;
-	u32 bad_frames = 0;
 	int ret;
 
-	if (!priv->sensor) {
-		v4l2_err(&priv->sd, "no sensor attached\n");
-		return -EINVAL;
-	}
-
 	output_fi = &priv->frame_interval[priv->active_output_pad];
 	input_fi = &priv->frame_interval[CSI_SINK_PAD];
 
-	ret = v4l2_subdev_call(priv->sensor->sd, sensor,
-			       g_skip_frames, &bad_frames);
-	if (!ret && bad_frames) {
-		u32 delay_usec;
-
-		/*
-		 * This sensor has bad frames when it is turned on,
-		 * add a delay to avoid them before enabling the CSI
-		 * hardware. Especially for sensors with a bt.656 interface,
-		 * any shifts in the SAV/EAV sync codes will cause the CSI
-		 * to lose vert/horiz sync.
-		 */
-		delay_usec = DIV_ROUND_UP_ULL(
-			(u64)USEC_PER_SEC * input_fi->numerator * bad_frames,
-			input_fi->denominator);
-		usleep_range(delay_usec, delay_usec + 1000);
-	}
-
 	if (priv->dest == IPU_CSI_DEST_IDMAC) {
 		ret = csi_idmac_start(priv);
 		if (ret)
@@ -971,9 +1005,8 @@ static int csi_link_validate(struct v4l2_subdev *sd,
 			     struct v4l2_subdev_format *sink_fmt)
 {
 	struct csi_priv *priv = v4l2_get_subdevdata(sd);
-	struct v4l2_fwnode_endpoint *sensor_ep;
+	struct v4l2_fwnode_endpoint upstream_ep;
 	const struct imx_media_pixfmt *incc;
-	struct imx_media_subdev *sensor;
 	bool is_csi2;
 	int ret;
 
@@ -982,22 +1015,20 @@ static int csi_link_validate(struct v4l2_subdev *sd,
 	if (ret)
 		return ret;
 
-	sensor = __imx_media_find_sensor(priv->md, &priv->sd.entity);
-	if (IS_ERR(sensor)) {
-		v4l2_err(&priv->sd, "no sensor attached\n");
-		return PTR_ERR(priv->sensor);
+	ret = csi_get_upstream_endpoint(priv, &upstream_ep);
+	if (ret) {
+		v4l2_err(&priv->sd, "failed to find upstream endpoint\n");
+		return ret;
 	}
 
 	mutex_lock(&priv->lock);
 
-	priv->sensor = sensor;
-	sensor_ep = &priv->sensor->sensor_ep;
-	is_csi2 = (sensor_ep->bus_type == V4L2_MBUS_CSI2);
+	priv->upstream_ep = upstream_ep;
+	is_csi2 = (upstream_ep.bus_type == V4L2_MBUS_CSI2);
 	incc = priv->cc[CSI_SINK_PAD];
 
 	if (priv->dest != IPU_CSI_DEST_IDMAC &&
-	    (incc->bayer || (!is_csi2 &&
-			     sensor_ep->bus.parallel.bus_width >= 16))) {
+	    (incc->bayer || is_parallel_16bit_bus(&upstream_ep))) {
 		v4l2_err(&priv->sd,
 			 "bayer/16-bit parallel buses must go to IDMAC pad\n");
 		ret = -EINVAL;
@@ -1067,12 +1098,8 @@ static void csi_try_crop(struct csi_priv *priv,
 			 struct v4l2_rect *crop,
 			 struct v4l2_subdev_pad_config *cfg,
 			 struct v4l2_mbus_framefmt *infmt,
-			 struct imx_media_subdev *sensor)
+			 struct v4l2_fwnode_endpoint *upstream_ep)
 {
-	struct v4l2_fwnode_endpoint *sensor_ep;
-
-	sensor_ep = &sensor->sensor_ep;
-
 	crop->width = min_t(__u32, infmt->width, crop->width);
 	if (crop->left + crop->width > infmt->width)
 		crop->left = infmt->width - crop->width;
@@ -1086,7 +1113,7 @@ static void csi_try_crop(struct csi_priv *priv,
 	 * sync, so fix it to NTSC/PAL active lines. NTSC contains
 	 * 2 extra lines of active video that need to be cropped.
 	 */
-	if (sensor_ep->bus_type == V4L2_MBUS_BT656 &&
+	if (upstream_ep->bus_type == V4L2_MBUS_BT656 &&
 	    (V4L2_FIELD_HAS_BOTH(infmt->field) ||
 	     infmt->field == V4L2_FIELD_ALTERNATE)) {
 		crop->height = infmt->height;
@@ -1236,7 +1263,7 @@ static int csi_get_fmt(struct v4l2_subdev *sd,
 }
 
 static void csi_try_fmt(struct csi_priv *priv,
-			struct imx_media_subdev *sensor,
+			struct v4l2_fwnode_endpoint *upstream_ep,
 			struct v4l2_subdev_pad_config *cfg,
 			struct v4l2_subdev_format *sdformat,
 			struct v4l2_rect *crop,
@@ -1304,7 +1331,7 @@ static void csi_try_fmt(struct csi_priv *priv,
 		crop->top = 0;
 		crop->width = sdformat->format.width;
 		crop->height = sdformat->format.height;
-		csi_try_crop(priv, crop, cfg, &sdformat->format, sensor);
+		csi_try_crop(priv, crop, cfg, &sdformat->format, upstream_ep);
 		compose->left = 0;
 		compose->top = 0;
 		compose->width = crop->width;
@@ -1333,20 +1360,20 @@ static int csi_set_fmt(struct v4l2_subdev *sd,
 {
 	struct csi_priv *priv = v4l2_get_subdevdata(sd);
 	struct imx_media_video_dev *vdev = priv->vdev;
+	struct v4l2_fwnode_endpoint upstream_ep;
 	const struct imx_media_pixfmt *cc;
-	struct imx_media_subdev *sensor;
 	struct v4l2_pix_format vdev_fmt;
 	struct v4l2_mbus_framefmt *fmt;
 	struct v4l2_rect *crop, *compose;
-	int ret = 0;
+	int ret;
 
 	if (sdformat->pad >= CSI_NUM_PADS)
 		return -EINVAL;
 
-	sensor = imx_media_find_sensor(priv->md, &priv->sd.entity);
-	if (IS_ERR(sensor)) {
-		v4l2_err(&priv->sd, "no sensor attached\n");
-		return PTR_ERR(sensor);
+	ret = csi_get_upstream_endpoint(priv, &upstream_ep);
+	if (ret) {
+		v4l2_err(&priv->sd, "failed to find upstream endpoint\n");
+		return ret;
 	}
 
 	mutex_lock(&priv->lock);
@@ -1359,7 +1386,7 @@ static int csi_set_fmt(struct v4l2_subdev *sd,
 	crop = __csi_get_crop(priv, cfg, sdformat->which);
 	compose = __csi_get_compose(priv, cfg, sdformat->which);
 
-	csi_try_fmt(priv, sensor, cfg, sdformat, crop, compose, &cc);
+	csi_try_fmt(priv, &upstream_ep, cfg, sdformat, crop, compose, &cc);
 
 	fmt = __csi_get_fmt(priv, cfg, sdformat->pad, sdformat->which);
 	*fmt = sdformat->format;
@@ -1376,8 +1403,8 @@ static int csi_set_fmt(struct v4l2_subdev *sd,
 			format.pad = pad;
 			format.which = sdformat->which;
 			format.format = sdformat->format;
-			csi_try_fmt(priv, sensor, cfg, &format, NULL, compose,
-				    &outcc);
+			csi_try_fmt(priv, &upstream_ep, cfg, &format,
+				    NULL, compose, &outcc);
 
 			outfmt = __csi_get_fmt(priv, cfg, pad, sdformat->which);
 			*outfmt = format.format;
@@ -1472,18 +1499,18 @@ static int csi_set_selection(struct v4l2_subdev *sd,
 			     struct v4l2_subdev_selection *sel)
 {
 	struct csi_priv *priv = v4l2_get_subdevdata(sd);
+	struct v4l2_fwnode_endpoint upstream_ep;
 	struct v4l2_mbus_framefmt *infmt;
 	struct v4l2_rect *crop, *compose;
-	struct imx_media_subdev *sensor;
-	int pad, ret = 0;
+	int pad, ret;
 
 	if (sel->pad != CSI_SINK_PAD)
 		return -EINVAL;
 
-	sensor = imx_media_find_sensor(priv->md, &priv->sd.entity);
-	if (IS_ERR(sensor)) {
-		v4l2_err(&priv->sd, "no sensor attached\n");
-		return PTR_ERR(sensor);
+	ret = csi_get_upstream_endpoint(priv, &upstream_ep);
+	if (ret) {
+		v4l2_err(&priv->sd, "failed to find upstream endpoint\n");
+		return ret;
 	}
 
 	mutex_lock(&priv->lock);
@@ -1511,7 +1538,7 @@ static int csi_set_selection(struct v4l2_subdev *sd,
 			goto out;
 		}
 
-		csi_try_crop(priv, &sel->r, cfg, infmt, sensor);
+		csi_try_crop(priv, &sel->r, cfg, infmt, &upstream_ep);
 
 		*crop = sel->r;
 
diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
index 47c4c95..289d775 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -11,6 +11,7 @@
 #include <linux/delay.h>
 #include <linux/fs.h>
 #include <linux/module.h>
+#include <linux/of_graph.h>
 #include <linux/of_platform.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
@@ -32,29 +33,28 @@ static inline struct imx_media_dev *notifier2dev(struct v4l2_async_notifier *n)
 }
 
 /*
- * Find a subdev by device node or device name. This is called during
+ * Find an asd by fwnode or device name. This is called during
  * driver load to form the async subdev list and bind them.
  */
-struct imx_media_subdev *
-imx_media_find_async_subdev(struct imx_media_dev *imxmd,
-			    struct device_node *np,
-			    const char *devname)
+static struct v4l2_async_subdev *
+find_async_subdev(struct imx_media_dev *imxmd,
+		  struct fwnode_handle *fwnode,
+		  const char *devname)
 {
-	struct fwnode_handle *fwnode = np ? of_fwnode_handle(np) : NULL;
-	struct imx_media_subdev *imxsd;
-	int i;
+	struct imx_media_async_subdev *imxasd;
+	struct v4l2_async_subdev *asd;
 
-	for (i = 0; i < imxmd->subdev_notifier.num_subdevs; i++) {
-		imxsd = &imxmd->subdev[i];
-		switch (imxsd->asd.match_type) {
+	list_for_each_entry(imxasd, &imxmd->asd_list, list) {
+		asd = &imxasd->asd;
+		switch (asd->match_type) {
 		case V4L2_ASYNC_MATCH_FWNODE:
-			if (fwnode && imxsd->asd.match.fwnode.fwnode == fwnode)
-				return imxsd;
+			if (fwnode && asd->match.fwnode == fwnode)
+				return asd;
 			break;
 		case V4L2_ASYNC_MATCH_DEVNAME:
-			if (devname &&
-			    !strcmp(imxsd->asd.match.device_name.name, devname))
-				return imxsd;
+			if (devname && !strcmp(asd->match.device_name,
+					       devname))
+				return asd;
 			break;
 		default:
 			break;
@@ -66,57 +66,53 @@ imx_media_find_async_subdev(struct imx_media_dev *imxmd,
 
 
 /*
- * Adds a subdev to the async subdev list. If np is non-NULL, adds
+ * Adds a subdev to the async subdev list. If fwnode is non-NULL, adds
  * the async as a V4L2_ASYNC_MATCH_FWNODE match type, otherwise as
  * a V4L2_ASYNC_MATCH_DEVNAME match type using the dev_name of the
  * given platform_device. This is called during driver load when
  * forming the async subdev list.
  */
-struct imx_media_subdev *
-imx_media_add_async_subdev(struct imx_media_dev *imxmd,
-			   struct device_node *np,
-			   struct platform_device *pdev)
+int imx_media_add_async_subdev(struct imx_media_dev *imxmd,
+			       struct fwnode_handle *fwnode,
+			       struct platform_device *pdev)
 {
-	struct imx_media_subdev *imxsd;
+	struct device_node *np = to_of_node(fwnode);
+	struct imx_media_async_subdev *imxasd;
 	struct v4l2_async_subdev *asd;
 	const char *devname = NULL;
-	int sd_idx;
+	int ret = 0;
 
 	mutex_lock(&imxmd->mutex);
 
 	if (pdev)
 		devname = dev_name(&pdev->dev);
 
-	/* return -EEXIST if this subdev already added */
-	if (imx_media_find_async_subdev(imxmd, np, devname)) {
+	/* return -EEXIST if this asd already added */
+	if (find_async_subdev(imxmd, fwnode, devname)) {
 		dev_dbg(imxmd->md.dev, "%s: already added %s\n",
 			__func__, np ? np->name : devname);
-		imxsd = ERR_PTR(-EEXIST);
+		ret = -EEXIST;
 		goto out;
 	}
 
-	sd_idx = imxmd->subdev_notifier.num_subdevs;
-	if (sd_idx >= IMX_MEDIA_MAX_SUBDEVS) {
-		dev_err(imxmd->md.dev, "%s: too many subdevs! can't add %s\n",
-			__func__, np ? np->name : devname);
-		imxsd = ERR_PTR(-ENOSPC);
+	imxasd = devm_kzalloc(imxmd->md.dev, sizeof(*imxasd), GFP_KERNEL);
+	if (!imxasd) {
+		ret = -ENOMEM;
 		goto out;
 	}
+	asd = &imxasd->asd;
 
-	imxsd = &imxmd->subdev[sd_idx];
-
-	asd = &imxsd->asd;
-	if (np) {
+	if (fwnode) {
 		asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
-		asd->match.fwnode.fwnode = of_fwnode_handle(np);
+		asd->match.fwnode = fwnode;
 	} else {
 		asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
-		strncpy(imxsd->devname, devname, sizeof(imxsd->devname));
-		asd->match.device_name.name = imxsd->devname;
-		imxsd->pdev = pdev;
+		asd->match.device_name = devname;
+		imxasd->pdev = pdev;
 	}
 
-	imxmd->async_ptrs[sd_idx] = asd;
+	list_add_tail(&imxasd->list, &imxmd->asd_list);
+
 	imxmd->subdev_notifier.num_subdevs++;
 
 	dev_dbg(imxmd->md.dev, "%s: added %s, match type %s\n",
@@ -124,50 +120,6 @@ imx_media_add_async_subdev(struct imx_media_dev *imxmd,
 
 out:
 	mutex_unlock(&imxmd->mutex);
-	return imxsd;
-}
-
-/*
- * Adds an imx-media link to a subdev pad's link list. This is called
- * during driver load when forming the links between subdevs.
- *
- * @pad: the local pad
- * @remote_node: the device node of the remote subdev
- * @remote_devname: the device name of the remote subdev
- * @local_pad: local pad index
- * @remote_pad: remote pad index
- */
-int imx_media_add_pad_link(struct imx_media_dev *imxmd,
-			   struct imx_media_pad *pad,
-			   struct device_node *remote_node,
-			   const char *remote_devname,
-			   int local_pad, int remote_pad)
-{
-	struct imx_media_link *link;
-	int link_idx, ret = 0;
-
-	mutex_lock(&imxmd->mutex);
-
-	link_idx = pad->num_links;
-	if (link_idx >= IMX_MEDIA_MAX_LINKS) {
-		dev_err(imxmd->md.dev, "%s: too many links!\n", __func__);
-		ret = -ENOSPC;
-		goto out;
-	}
-
-	link = &pad->link[link_idx];
-
-	link->remote_sd_node = remote_node;
-	if (remote_devname)
-		strncpy(link->remote_devname, remote_devname,
-			sizeof(link->remote_devname));
-
-	link->local_pad = local_pad;
-	link->remote_pad = remote_pad;
-
-	pad->num_links++;
-out:
-	mutex_unlock(&imxmd->mutex);
 	return ret;
 }
 
@@ -206,122 +158,66 @@ static int imx_media_subdev_bound(struct v4l2_async_notifier *notifier,
 				  struct v4l2_async_subdev *asd)
 {
 	struct imx_media_dev *imxmd = notifier2dev(notifier);
-	struct device_node *np = to_of_node(sd->fwnode);
-	struct imx_media_subdev *imxsd;
 	int ret = 0;
 
 	mutex_lock(&imxmd->mutex);
 
-	imxsd = imx_media_find_async_subdev(imxmd, np, dev_name(sd->dev));
-	if (!imxsd) {
-		ret = -EINVAL;
-		goto out;
-	}
-
 	if (sd->grp_id & IMX_MEDIA_GRP_ID_CSI) {
 		ret = imx_media_get_ipu(imxmd, sd);
 		if (ret)
-			goto out_unlock;
-	} else if (sd->entity.function == MEDIA_ENT_F_VID_MUX) {
-		/* this is a video mux */
-		sd->grp_id = IMX_MEDIA_GRP_ID_VIDMUX;
-	} else if (imxsd->num_sink_pads == 0) {
-		/*
-		 * this is an original source of video frames, it
-		 * could be a camera sensor, an analog decoder, or
-		 * a bridge device (HDMI -> MIPI CSI-2 for example).
-		 * This group ID is used to locate the entity that
-		 * is the original source of video in a pipeline.
-		 */
-		sd->grp_id = IMX_MEDIA_GRP_ID_SENSOR;
+			goto out;
 	}
 
-	/* attach the subdev */
-	imxsd->sd = sd;
+	v4l2_info(&imxmd->v4l2_dev, "subdev %s bound\n", sd->name);
 out:
-	if (ret)
-		v4l2_warn(&imxmd->v4l2_dev,
-			  "Received unknown subdev %s\n", sd->name);
-	else
-		v4l2_info(&imxmd->v4l2_dev,
-			  "Registered subdev %s\n", sd->name);
-
-out_unlock:
 	mutex_unlock(&imxmd->mutex);
 	return ret;
 }
 
 /*
- * Create a single source->sink media link given a subdev and a single
- * link from one of its source pads. Called after all subdevs have
- * registered.
+ * create the media links for all subdevs that registered async.
+ * Called after all async subdevs have bound.
  */
-static int imx_media_create_link(struct imx_media_dev *imxmd,
-				 struct imx_media_subdev *src,
-				 struct imx_media_link *link)
+static int imx_media_create_links(struct v4l2_async_notifier *notifier)
 {
-	struct imx_media_subdev *sink;
-	u16 source_pad, sink_pad;
+	struct imx_media_dev *imxmd = notifier2dev(notifier);
+	struct v4l2_subdev *sd;
 	int ret;
 
-	sink = imx_media_find_async_subdev(imxmd, link->remote_sd_node,
-					   link->remote_devname);
-	if (!sink) {
-		v4l2_warn(&imxmd->v4l2_dev, "%s: no sink for %s:%d\n",
-			  __func__, src->sd->name, link->local_pad);
-		return 0;
-	}
-
-	source_pad = link->local_pad;
-	sink_pad = link->remote_pad;
-
-	v4l2_info(&imxmd->v4l2_dev, "%s: %s:%d -> %s:%d\n", __func__,
-		  src->sd->name, source_pad, sink->sd->name, sink_pad);
-
-	ret = media_create_pad_link(&src->sd->entity, source_pad,
-				    &sink->sd->entity, sink_pad, 0);
-	if (ret)
-		v4l2_err(&imxmd->v4l2_dev,
-			 "create_pad_link failed: %d\n", ret);
-
-	return ret;
-}
-
-/*
- * create the media links from all imx-media pads and their links.
- * Called after all subdevs have registered.
- */
-static int imx_media_create_links(struct imx_media_dev *imxmd)
-{
-	struct imx_media_subdev *imxsd;
-	struct imx_media_link *link;
-	struct imx_media_pad *pad;
-	int num_pads, i, j, k;
-	int ret = 0;
-
-	for (i = 0; i < imxmd->num_subdevs; i++) {
-		imxsd = &imxmd->subdev[i];
-		num_pads = imxsd->num_sink_pads + imxsd->num_src_pads;
-
-		for (j = 0; j < num_pads; j++) {
-			pad = &imxsd->pad[j];
-
-			/* only create the source->sink links */
-			if (!(pad->pad.flags & MEDIA_PAD_FL_SOURCE))
-				continue;
-
-			for (k = 0; k < pad->num_links; k++) {
-				link = &pad->link[k];
-
-				ret = imx_media_create_link(imxmd, imxsd, link);
-				if (ret)
-					goto out;
-			}
+	/*
+	 * Only links are created between subdevices that are known
+	 * to the async notifier. If there are other non-async subdevices,
+	 * they were created internally by some subdevice (smiapp is one
+	 * example). In those cases it is expected the subdevice is
+	 * responsible for creating those internal links.
+	 */
+	list_for_each_entry(sd, &notifier->done, async_list) {
+		switch (sd->grp_id) {
+		case IMX_MEDIA_GRP_ID_VDIC:
+		case IMX_MEDIA_GRP_ID_IC_PRP:
+		case IMX_MEDIA_GRP_ID_IC_PRPENC:
+		case IMX_MEDIA_GRP_ID_IC_PRPVF:
+		case IMX_MEDIA_GRP_ID_CSI0:
+		case IMX_MEDIA_GRP_ID_CSI1:
+			ret = imx_media_create_internal_links(imxmd, sd);
+			if (ret)
+				return ret;
+			/*
+			 * the CSIs straddle between the external and the IPU
+			 * internal entities, so create the external links
+			 * to the CSI sink pads.
+			 */
+			if (sd->grp_id & IMX_MEDIA_GRP_ID_CSI)
+				imx_media_create_csi_of_links(imxmd, sd);
+			break;
+		default:
+			/* this is an external fwnode subdev */
+			imx_media_create_of_links(imxmd, sd);
+			break;
 		}
 	}
 
-out:
-	return ret;
+	return 0;
 }
 
 /*
@@ -333,39 +229,45 @@ static int imx_media_add_vdev_to_pad(struct imx_media_dev *imxmd,
 				     struct media_pad *srcpad)
 {
 	struct media_entity *entity = srcpad->entity;
-	struct imx_media_subdev *imxsd;
-	struct imx_media_pad *imxpad;
+	struct imx_media_pad_vdev *pad_vdev;
+	struct list_head *pad_vdev_list;
 	struct media_link *link;
 	struct v4l2_subdev *sd;
-	int i, vdev_idx, ret;
+	int i, ret;
 
 	/* skip this entity if not a v4l2_subdev */
 	if (!is_media_entity_v4l2_subdev(entity))
 		return 0;
 
 	sd = media_entity_to_v4l2_subdev(entity);
-	imxsd = imx_media_find_subdev_by_sd(imxmd, sd);
-	if (IS_ERR(imxsd))
-		return PTR_ERR(imxsd);
 
-	imxpad = &imxsd->pad[srcpad->index];
-	vdev_idx = imxpad->num_vdevs;
+	pad_vdev_list = to_pad_vdev_list(sd, srcpad->index);
+	if (!pad_vdev_list) {
+		v4l2_warn(&imxmd->v4l2_dev, "%s:%u has no vdev list!\n",
+			  entity->name, srcpad->index);
+		/*
+		 * shouldn't happen, but no reason to fail driver load,
+		 * just skip this entity.
+		 */
+		return 0;
+	}
 
 	/* just return if we've been here before */
-	for (i = 0; i < vdev_idx; i++)
-		if (vdev == imxpad->vdev[i])
+	list_for_each_entry(pad_vdev, pad_vdev_list, list) {
+		if (pad_vdev->vdev == vdev)
 			return 0;
-
-	if (vdev_idx >= IMX_MEDIA_MAX_VDEVS) {
-		dev_err(imxmd->md.dev, "can't add %s to pad %s:%u\n",
-			vdev->vfd->entity.name, entity->name, srcpad->index);
-		return -ENOSPC;
 	}
 
 	dev_dbg(imxmd->md.dev, "adding %s to pad %s:%u\n",
 		vdev->vfd->entity.name, entity->name, srcpad->index);
-	imxpad->vdev[vdev_idx] = vdev;
-	imxpad->num_vdevs++;
+
+	pad_vdev = devm_kzalloc(imxmd->md.dev, sizeof(*pad_vdev), GFP_KERNEL);
+	if (!pad_vdev)
+		return -ENOMEM;
+
+	/* attach this vdev to this pad */
+	pad_vdev->vdev = vdev;
+	list_add_tail(&pad_vdev->list, pad_vdev_list);
 
 	/* move upstream from this entity's sink pads */
 	for (i = 0; i < entity->num_pads; i++) {
@@ -387,15 +289,49 @@ static int imx_media_add_vdev_to_pad(struct imx_media_dev *imxmd,
 	return 0;
 }
 
+/*
+ * For every subdevice, allocate an array of list_head's, one list_head
+ * for each pad, to hold the list of video devices reachable from that
+ * pad.
+ */
+static int imx_media_alloc_pad_vdev_lists(struct imx_media_dev *imxmd)
+{
+	struct list_head *vdev_lists;
+	struct media_entity *entity;
+	struct v4l2_subdev *sd;
+	int i;
+
+	list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
+		entity = &sd->entity;
+		vdev_lists = devm_kzalloc(
+			imxmd->md.dev,
+			entity->num_pads * sizeof(*vdev_lists),
+			GFP_KERNEL);
+		if (!vdev_lists)
+			return -ENOMEM;
+
+		/* attach to the subdev's host private pointer */
+		sd->host_priv = vdev_lists;
+
+		for (i = 0; i < entity->num_pads; i++)
+			INIT_LIST_HEAD(to_pad_vdev_list(sd, i));
+	}
+
+	return 0;
+}
+
 /* form the vdev lists in all imx-media source pads */
 static int imx_media_create_pad_vdev_lists(struct imx_media_dev *imxmd)
 {
 	struct imx_media_video_dev *vdev;
 	struct media_link *link;
-	int i, ret;
+	int ret;
 
-	for (i = 0; i < imxmd->num_vdevs; i++) {
-		vdev = imxmd->vdev[i];
+	ret = imx_media_alloc_pad_vdev_lists(imxmd);
+	if (ret)
+		return ret;
+
+	list_for_each_entry(vdev, &imxmd->vdev_list, list) {
 		link = list_first_entry(&vdev->vfd->entity.links,
 					struct media_link, list);
 		ret = imx_media_add_vdev_to_pad(imxmd, vdev, link->source);
@@ -410,20 +346,11 @@ static int imx_media_create_pad_vdev_lists(struct imx_media_dev *imxmd)
 static int imx_media_probe_complete(struct v4l2_async_notifier *notifier)
 {
 	struct imx_media_dev *imxmd = notifier2dev(notifier);
-	int i, ret;
+	int ret;
 
 	mutex_lock(&imxmd->mutex);
 
-	/* make sure all subdevs were bound */
-	for (i = 0; i < imxmd->num_subdevs; i++) {
-		if (!imxmd->subdev[i].sd) {
-			v4l2_err(&imxmd->v4l2_dev, "unbound subdev!\n");
-			ret = -ENODEV;
-			goto unlock;
-		}
-	}
-
-	ret = imx_media_create_links(imxmd);
+	ret = imx_media_create_links(notifier);
 	if (ret)
 		goto unlock;
 
@@ -492,12 +419,12 @@ static int imx_media_link_notify(struct media_link *link, u32 flags,
 				 unsigned int notification)
 {
 	struct media_entity *source = link->source->entity;
-	struct imx_media_subdev *imxsd;
-	struct imx_media_pad *imxpad;
+	struct imx_media_pad_vdev *pad_vdev;
+	struct list_head *pad_vdev_list;
 	struct imx_media_dev *imxmd;
 	struct video_device *vfd;
 	struct v4l2_subdev *sd;
-	int i, pad_idx, ret;
+	int pad_idx, ret;
 
 	ret = v4l2_pipeline_link_notify(link, flags, notification);
 	if (ret)
@@ -512,10 +439,11 @@ static int imx_media_link_notify(struct media_link *link, u32 flags,
 
 	imxmd = dev_get_drvdata(sd->v4l2_dev->dev);
 
-	imxsd = imx_media_find_subdev_by_sd(imxmd, sd);
-	if (IS_ERR(imxsd))
-		return PTR_ERR(imxsd);
-	imxpad = &imxsd->pad[pad_idx];
+	pad_vdev_list = to_pad_vdev_list(sd, pad_idx);
+	if (!pad_vdev_list) {
+		/* shouldn't happen, but no reason to fail link setup */
+		return 0;
+	}
 
 	/*
 	 * Before disabling a link, reset controls for all video
@@ -526,8 +454,8 @@ static int imx_media_link_notify(struct media_link *link, u32 flags,
 	 */
 	if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
 	    !(flags & MEDIA_LNK_FL_ENABLED)) {
-		for (i = 0; i < imxpad->num_vdevs; i++) {
-			vfd = imxpad->vdev[i]->vfd;
+		list_for_each_entry(pad_vdev, pad_vdev_list, list) {
+			vfd = pad_vdev->vdev->vfd;
 			dev_dbg(imxmd->md.dev,
 				"reset controls for %s\n",
 				vfd->entity.name);
@@ -536,8 +464,8 @@ static int imx_media_link_notify(struct media_link *link, u32 flags,
 		}
 	} else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
 		   (link->flags & MEDIA_LNK_FL_ENABLED)) {
-		for (i = 0; i < imxpad->num_vdevs; i++) {
-			vfd = imxpad->vdev[i]->vfd;
+		list_for_each_entry(pad_vdev, pad_vdev_list, list) {
+			vfd = pad_vdev->vdev->vfd;
 			dev_dbg(imxmd->md.dev,
 				"refresh controls for %s\n",
 				vfd->entity.name);
@@ -559,9 +487,10 @@ static int imx_media_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *node = dev->of_node;
-	struct imx_media_subdev *csi[4] = {0};
+	struct imx_media_async_subdev *imxasd;
+	struct v4l2_async_subdev **subdevs;
 	struct imx_media_dev *imxmd;
-	int ret;
+	int num_subdevs, i, ret;
 
 	imxmd = devm_kzalloc(dev, sizeof(*imxmd), GFP_KERNEL);
 	if (!imxmd)
@@ -590,29 +519,44 @@ static int imx_media_probe(struct platform_device *pdev)
 
 	dev_set_drvdata(imxmd->v4l2_dev.dev, imxmd);
 
-	ret = imx_media_of_parse(imxmd, &csi, node);
+	INIT_LIST_HEAD(&imxmd->asd_list);
+	INIT_LIST_HEAD(&imxmd->vdev_list);
+
+	ret = imx_media_add_of_subdevs(imxmd, node);
 	if (ret) {
 		v4l2_err(&imxmd->v4l2_dev,
-			 "imx_media_of_parse failed with %d\n", ret);
+			 "add_of_subdevs failed with %d\n", ret);
 		goto unreg_dev;
 	}
 
-	ret = imx_media_add_internal_subdevs(imxmd, csi);
+	ret = imx_media_add_internal_subdevs(imxmd);
 	if (ret) {
 		v4l2_err(&imxmd->v4l2_dev,
 			 "add_internal_subdevs failed with %d\n", ret);
 		goto unreg_dev;
 	}
 
+	num_subdevs = imxmd->subdev_notifier.num_subdevs;
+
 	/* no subdevs? just bail */
-	imxmd->num_subdevs = imxmd->subdev_notifier.num_subdevs;
-	if (imxmd->num_subdevs == 0) {
+	if (num_subdevs == 0) {
 		ret = -ENODEV;
 		goto unreg_dev;
 	}
 
+	subdevs = devm_kzalloc(imxmd->md.dev, sizeof(*subdevs) * num_subdevs,
+			       GFP_KERNEL);
+	if (!subdevs) {
+		ret = -ENOMEM;
+		goto unreg_dev;
+	}
+
+	i = 0;
+	list_for_each_entry(imxasd, &imxmd->asd_list, list)
+		subdevs[i++] = &imxasd->asd;
+
 	/* prepare the async subdev notifier and register it */
-	imxmd->subdev_notifier.subdevs = imxmd->async_ptrs;
+	imxmd->subdev_notifier.subdevs = subdevs;
 	imxmd->subdev_notifier.ops = &imx_media_subdev_ops;
 	ret = v4l2_async_notifier_register(&imxmd->v4l2_dev,
 					   &imxmd->subdev_notifier);
diff --git a/drivers/staging/media/imx/imx-media-internal-sd.c b/drivers/staging/media/imx/imx-media-internal-sd.c
index cdfbf40..70833fe 100644
--- a/drivers/staging/media/imx/imx-media-internal-sd.c
+++ b/drivers/staging/media/imx/imx-media-internal-sd.c
@@ -60,73 +60,68 @@ static const struct internal_subdev_id {
 	},
 };
 
+struct internal_subdev;
+
 struct internal_link {
-	const struct internal_subdev_id *remote_id;
+	const struct internal_subdev *remote;
+	int local_pad;
 	int remote_pad;
 };
 
+/* max pads per internal-sd */
+#define MAX_INTERNAL_PADS   8
+/* max links per internal-sd pad */
+#define MAX_INTERNAL_LINKS  8
+
 struct internal_pad {
-	bool devnode; /* does this pad link to a device node */
-	struct internal_link link[IMX_MEDIA_MAX_LINKS];
+	struct internal_link link[MAX_INTERNAL_LINKS];
 };
 
 static const struct internal_subdev {
 	const struct internal_subdev_id *id;
-	struct internal_pad pad[IMX_MEDIA_MAX_PADS];
-	int num_sink_pads;
-	int num_src_pads;
-} internal_subdev[num_isd] = {
+	struct internal_pad pad[MAX_INTERNAL_PADS];
+} int_subdev[num_isd] = {
 	[isd_csi0] = {
 		.id = &isd_id[isd_csi0],
-		.num_sink_pads = CSI_NUM_SINK_PADS,
-		.num_src_pads = CSI_NUM_SRC_PADS,
 		.pad[CSI_SRC_PAD_DIRECT] = {
 			.link = {
 				{
-					.remote_id = &isd_id[isd_ic_prp],
+					.local_pad = CSI_SRC_PAD_DIRECT,
+					.remote = &int_subdev[isd_ic_prp],
 					.remote_pad = PRP_SINK_PAD,
 				}, {
-					.remote_id =  &isd_id[isd_vdic],
+					.local_pad = CSI_SRC_PAD_DIRECT,
+					.remote = &int_subdev[isd_vdic],
 					.remote_pad = VDIC_SINK_PAD_DIRECT,
 				},
 			},
 		},
-		.pad[CSI_SRC_PAD_IDMAC] = {
-			.devnode = true,
-		},
 	},
 
 	[isd_csi1] = {
 		.id = &isd_id[isd_csi1],
-		.num_sink_pads = CSI_NUM_SINK_PADS,
-		.num_src_pads = CSI_NUM_SRC_PADS,
 		.pad[CSI_SRC_PAD_DIRECT] = {
 			.link = {
 				{
-					.remote_id = &isd_id[isd_ic_prp],
+					.local_pad = CSI_SRC_PAD_DIRECT,
+					.remote = &int_subdev[isd_ic_prp],
 					.remote_pad = PRP_SINK_PAD,
 				}, {
-					.remote_id =  &isd_id[isd_vdic],
+					.local_pad = CSI_SRC_PAD_DIRECT,
+					.remote = &int_subdev[isd_vdic],
 					.remote_pad = VDIC_SINK_PAD_DIRECT,
 				},
 			},
 		},
-		.pad[CSI_SRC_PAD_IDMAC] = {
-			.devnode = true,
-		},
 	},
 
 	[isd_vdic] = {
 		.id = &isd_id[isd_vdic],
-		.num_sink_pads = VDIC_NUM_SINK_PADS,
-		.num_src_pads = VDIC_NUM_SRC_PADS,
-		.pad[VDIC_SINK_PAD_IDMAC] = {
-			.devnode = true,
-		},
 		.pad[VDIC_SRC_PAD_DIRECT] = {
 			.link = {
 				{
-					.remote_id =  &isd_id[isd_ic_prp],
+					.local_pad = VDIC_SRC_PAD_DIRECT,
+					.remote = &int_subdev[isd_ic_prp],
 					.remote_pad = PRP_SINK_PAD,
 				},
 			},
@@ -135,12 +130,11 @@ static const struct internal_subdev {
 
 	[isd_ic_prp] = {
 		.id = &isd_id[isd_ic_prp],
-		.num_sink_pads = PRP_NUM_SINK_PADS,
-		.num_src_pads = PRP_NUM_SRC_PADS,
 		.pad[PRP_SRC_PAD_PRPENC] = {
 			.link = {
 				{
-					.remote_id = &isd_id[isd_ic_prpenc],
+					.local_pad = PRP_SRC_PAD_PRPENC,
+					.remote = &int_subdev[isd_ic_prpenc],
 					.remote_pad = 0,
 				},
 			},
@@ -148,7 +142,8 @@ static const struct internal_subdev {
 		.pad[PRP_SRC_PAD_PRPVF] = {
 			.link = {
 				{
-					.remote_id = &isd_id[isd_ic_prpvf],
+					.local_pad = PRP_SRC_PAD_PRPVF,
+					.remote = &int_subdev[isd_ic_prpvf],
 					.remote_pad = 0,
 				},
 			},
@@ -157,70 +152,111 @@ static const struct internal_subdev {
 
 	[isd_ic_prpenc] = {
 		.id = &isd_id[isd_ic_prpenc],
-		.num_sink_pads = PRPENCVF_NUM_SINK_PADS,
-		.num_src_pads = PRPENCVF_NUM_SRC_PADS,
-		.pad[PRPENCVF_SRC_PAD] = {
-			.devnode = true,
-		},
 	},
 
 	[isd_ic_prpvf] = {
 		.id = &isd_id[isd_ic_prpvf],
-		.num_sink_pads = PRPENCVF_NUM_SINK_PADS,
-		.num_src_pads = PRPENCVF_NUM_SRC_PADS,
-		.pad[PRPENCVF_SRC_PAD] = {
-			.devnode = true,
-		},
 	},
 };
 
-/* form a device name given a group id and ipu id */
-static inline void isd_id_to_devname(char *devname, int sz,
-				     const struct internal_subdev_id *id,
-				     int ipu_id)
+/* form a device name given an internal subdev and ipu id */
+static inline void isd_to_devname(char *devname, int sz,
+				  const struct internal_subdev *isd,
+				  int ipu_id)
 {
-	int pdev_id = ipu_id * num_isd + id->index;
+	int pdev_id = ipu_id * num_isd + isd->id->index;
 
-	snprintf(devname, sz, "%s.%d", id->name, pdev_id);
+	snprintf(devname, sz, "%s.%d", isd->id->name, pdev_id);
 }
 
-/* adds the links from given internal subdev */
-static int add_internal_links(struct imx_media_dev *imxmd,
-			      const struct internal_subdev *isd,
-			      struct imx_media_subdev *imxsd,
-			      int ipu_id)
+static const struct internal_subdev *find_intsd_by_grp_id(u32 grp_id)
 {
-	int i, num_pads, ret;
+	enum isd_enum i;
 
-	num_pads = isd->num_sink_pads + isd->num_src_pads;
+	for (i = 0; i < num_isd; i++) {
+		const struct internal_subdev *isd = &int_subdev[i];
 
-	for (i = 0; i < num_pads; i++) {
-		const struct internal_pad *intpad = &isd->pad[i];
-		struct imx_media_pad *pad = &imxsd->pad[i];
-		int j;
+		if (isd->id->grp_id == grp_id)
+			return isd;
+	}
 
-		/* init the pad flags for this internal subdev */
-		pad->pad.flags = (i < isd->num_sink_pads) ?
-			MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
-		/* export devnode pad flag to the subdevs */
-		pad->devnode = intpad->devnode;
+	return NULL;
+}
+
+static struct v4l2_subdev *find_sink(struct imx_media_dev *imxmd,
+				     struct v4l2_subdev *src,
+				     const struct internal_link *link)
+{
+	char sink_devname[32];
+	int ipu_id;
+
+	/*
+	 * retrieve IPU id from subdev name, note: can't get this from
+	 * struct imx_media_internal_sd_platformdata because if src is
+	 * a CSI, it has different struct ipu_client_platformdata which
+	 * does not contain IPU id.
+	 */
+	if (sscanf(src->name, "ipu%d", &ipu_id) != 1)
+		return NULL;
+
+	isd_to_devname(sink_devname, sizeof(sink_devname),
+		       link->remote, ipu_id - 1);
+
+	return imx_media_find_subdev_by_devname(imxmd, sink_devname);
+}
+
+static int create_ipu_internal_link(struct imx_media_dev *imxmd,
+				    struct v4l2_subdev *src,
+				    const struct internal_link *link)
+{
+	struct v4l2_subdev *sink;
+	int ret;
+
+	sink = find_sink(imxmd, src, link);
+	if (!sink)
+		return -ENODEV;
+
+	v4l2_info(&imxmd->v4l2_dev, "%s:%d -> %s:%d\n",
+		  src->name, link->local_pad,
+		  sink->name, link->remote_pad);
+
+	ret = media_create_pad_link(&src->entity, link->local_pad,
+				    &sink->entity, link->remote_pad, 0);
+	if (ret)
+		v4l2_err(&imxmd->v4l2_dev,
+			 "create_pad_link failed: %d\n", ret);
+
+	return ret;
+}
+
+int imx_media_create_internal_links(struct imx_media_dev *imxmd,
+				    struct v4l2_subdev *sd)
+{
+	const struct internal_subdev *intsd;
+	const struct internal_pad *intpad;
+	const struct internal_link *link;
+	struct media_pad *pad;
+	int i, j, ret;
+
+	intsd = find_intsd_by_grp_id(sd->grp_id);
+	if (!intsd)
+		return -ENODEV;
+
+	/* create the source->sink links */
+	for (i = 0; i < sd->entity.num_pads; i++) {
+		intpad = &intsd->pad[i];
+		pad = &sd->entity.pads[i];
+
+		if (!(pad->flags & MEDIA_PAD_FL_SOURCE))
+			continue;
 
 		for (j = 0; ; j++) {
-			const struct internal_link *link;
-			char remote_devname[32];
-
 			link = &intpad->link[j];
 
-			if (!link->remote_id)
+			if (!link->remote)
 				break;
 
-			isd_id_to_devname(remote_devname,
-					  sizeof(remote_devname),
-					  link->remote_id, ipu_id);
-
-			ret = imx_media_add_pad_link(imxmd, pad,
-						     NULL, remote_devname,
-						     i, link->remote_pad);
+			ret = create_ipu_internal_link(imxmd, sd, link);
 			if (ret)
 				return ret;
 		}
@@ -230,14 +266,12 @@ static int add_internal_links(struct imx_media_dev *imxmd,
 }
 
 /* register an internal subdev as a platform device */
-static struct imx_media_subdev *
-add_internal_subdev(struct imx_media_dev *imxmd,
-		    const struct internal_subdev *isd,
-		    int ipu_id)
+static int add_internal_subdev(struct imx_media_dev *imxmd,
+			       const struct internal_subdev *isd,
+			       int ipu_id)
 {
 	struct imx_media_internal_sd_platformdata pdata;
 	struct platform_device_info pdevinfo = {0};
-	struct imx_media_subdev *imxsd;
 	struct platform_device *pdev;
 
 	pdata.grp_id = isd->id->grp_id;
@@ -258,73 +292,51 @@ add_internal_subdev(struct imx_media_dev *imxmd,
 
 	pdev = platform_device_register_full(&pdevinfo);
 	if (IS_ERR(pdev))
-		return ERR_CAST(pdev);
+		return PTR_ERR(pdev);
 
-	imxsd = imx_media_add_async_subdev(imxmd, NULL, pdev);
-	if (IS_ERR(imxsd))
-		return imxsd;
-
-	imxsd->num_sink_pads = isd->num_sink_pads;
-	imxsd->num_src_pads = isd->num_src_pads;
-
-	return imxsd;
+	return imx_media_add_async_subdev(imxmd, NULL, pdev);
 }
 
 /* adds the internal subdevs in one ipu */
-static int add_ipu_internal_subdevs(struct imx_media_dev *imxmd,
-				    struct imx_media_subdev *csi0,
-				    struct imx_media_subdev *csi1,
-				    int ipu_id)
+static int add_ipu_internal_subdevs(struct imx_media_dev *imxmd, int ipu_id)
 {
 	enum isd_enum i;
-	int ret;
 
 	for (i = 0; i < num_isd; i++) {
-		const struct internal_subdev *isd = &internal_subdev[i];
-		struct imx_media_subdev *imxsd;
+		const struct internal_subdev *isd = &int_subdev[i];
+		int ret;
 
 		/*
 		 * the CSIs are represented in the device-tree, so those
-		 * devices are added already, and are added to the async
-		 * subdev list by of_parse_subdev(), so we are given those
-		 * subdevs as csi0 and csi1.
+		 * devices are already added to the async subdev list by
+		 * of_parse_subdev().
 		 */
 		switch (isd->id->grp_id) {
 		case IMX_MEDIA_GRP_ID_CSI0:
-			imxsd = csi0;
-			break;
 		case IMX_MEDIA_GRP_ID_CSI1:
-			imxsd = csi1;
+			ret = 0;
 			break;
 		default:
-			imxsd = add_internal_subdev(imxmd, isd, ipu_id);
+			ret = add_internal_subdev(imxmd, isd, ipu_id);
 			break;
 		}
 
-		if (IS_ERR(imxsd))
-			return PTR_ERR(imxsd);
-
-		/* add the links from this subdev */
-		if (imxsd) {
-			ret = add_internal_links(imxmd, isd, imxsd, ipu_id);
-			if (ret)
-				return ret;
-		}
+		if (ret)
+			return ret;
 	}
 
 	return 0;
 }
 
-int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd,
-				   struct imx_media_subdev *csi[4])
+int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd)
 {
 	int ret;
 
-	ret = add_ipu_internal_subdevs(imxmd, csi[0], csi[1], 0);
+	ret = add_ipu_internal_subdevs(imxmd, 0);
 	if (ret)
 		goto remove;
 
-	ret = add_ipu_internal_subdevs(imxmd, csi[2], csi[3], 1);
+	ret = add_ipu_internal_subdevs(imxmd, 1);
 	if (ret)
 		goto remove;
 
@@ -337,13 +349,12 @@ int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd,
 
 void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd)
 {
-	struct imx_media_subdev *imxsd;
-	int i;
+	struct imx_media_async_subdev *imxasd;
 
-	for (i = 0; i < imxmd->subdev_notifier.num_subdevs; i++) {
-		imxsd = &imxmd->subdev[i];
-		if (!imxsd->pdev)
+	list_for_each_entry(imxasd, &imxmd->asd_list, list) {
+		if (!imxasd->pdev)
 			continue;
-		platform_device_unregister(imxsd->pdev);
+
+		platform_device_unregister(imxasd->pdev);
 	}
 }
diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
index 12df09f..acde372 100644
--- a/drivers/staging/media/imx/imx-media-of.c
+++ b/drivers/staging/media/imx/imx-media-of.c
@@ -20,34 +20,6 @@
 #include <video/imx-ipu-v3.h>
 #include "imx-media.h"
 
-static int of_add_pad_link(struct imx_media_dev *imxmd,
-			   struct imx_media_pad *pad,
-			   struct device_node *local_sd_node,
-			   struct device_node *remote_sd_node,
-			   int local_pad, int remote_pad)
-{
-	dev_dbg(imxmd->md.dev, "%s: adding %s:%d -> %s:%d\n", __func__,
-		local_sd_node->name, local_pad,
-		remote_sd_node->name, remote_pad);
-
-	return imx_media_add_pad_link(imxmd, pad, remote_sd_node, NULL,
-				      local_pad, remote_pad);
-}
-
-static void of_parse_sensor(struct imx_media_dev *imxmd,
-			    struct imx_media_subdev *sensor,
-			    struct device_node *sensor_np)
-{
-	struct device_node *endpoint;
-
-	endpoint = of_graph_get_next_endpoint(sensor_np, NULL);
-	if (endpoint) {
-		v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
-					   &sensor->sensor_ep);
-		of_node_put(endpoint);
-	}
-}
-
 static int of_get_port_count(const struct device_node *np)
 {
 	struct device_node *ports, *child;
@@ -67,15 +39,14 @@ static int of_get_port_count(const struct device_node *np)
 }
 
 /*
- * find the remote device node and remote port id (remote pad #)
- * given local endpoint node
+ * find the remote device node given local endpoint node
  */
-static void of_get_remote_pad(struct device_node *epnode,
-			      struct device_node **remote_node,
-			      int *remote_pad)
+static bool of_get_remote(struct device_node *epnode,
+			  struct device_node **remote_node)
 {
 	struct device_node *rp, *rpp;
 	struct device_node *remote;
+	bool is_csi_port;
 
 	rp = of_graph_get_remote_port(epnode);
 	rpp = of_graph_get_remote_port_parent(epnode);
@@ -83,13 +54,12 @@ static void of_get_remote_pad(struct device_node *epnode,
 	if (of_device_is_compatible(rpp, "fsl,imx6q-ipu")) {
 		/* the remote is one of the CSI ports */
 		remote = rp;
-		*remote_pad = 0;
 		of_node_put(rpp);
+		is_csi_port = true;
 	} else {
 		remote = rpp;
-		if (of_property_read_u32(rp, "reg", remote_pad))
-			*remote_pad = 0;
 		of_node_put(rp);
+		is_csi_port = false;
 	}
 
 	if (!of_device_is_available(remote)) {
@@ -98,130 +68,66 @@ static void of_get_remote_pad(struct device_node *epnode,
 	} else {
 		*remote_node = remote;
 	}
+
+	return is_csi_port;
 }
 
 static int
 of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np,
-		bool is_csi_port, struct imx_media_subdev **subdev)
+		bool is_csi_port)
 {
-	struct imx_media_subdev *imxsd;
-	int i, num_pads, ret;
+	int i, num_ports, ret;
 
 	if (!of_device_is_available(sd_np)) {
 		dev_dbg(imxmd->md.dev, "%s: %s not enabled\n", __func__,
 			sd_np->name);
-		*subdev = NULL;
 		/* unavailable is not an error */
 		return 0;
 	}
 
 	/* register this subdev with async notifier */
-	imxsd = imx_media_add_async_subdev(imxmd, sd_np, NULL);
-	ret = PTR_ERR_OR_ZERO(imxsd);
+	ret = imx_media_add_async_subdev(imxmd, of_fwnode_handle(sd_np),
+					 NULL);
 	if (ret) {
 		if (ret == -EEXIST) {
 			/* already added, everything is fine */
-			*subdev = NULL;
 			return 0;
 		}
 
 		/* other error, can't continue */
 		return ret;
 	}
-	*subdev = imxsd;
-
-	if (is_csi_port) {
-		/*
-		 * the ipu-csi has one sink port and two source ports.
-		 * The source ports are not represented in the device tree,
-		 * but are described by the internal pads and links later.
-		 */
-		num_pads = CSI_NUM_PADS;
-		imxsd->num_sink_pads = CSI_NUM_SINK_PADS;
-	} else if (of_device_is_compatible(sd_np, "fsl,imx6-mipi-csi2")) {
-		num_pads = of_get_port_count(sd_np);
-		/* the mipi csi2 receiver has only one sink port */
-		imxsd->num_sink_pads = 1;
-	} else if (of_device_is_compatible(sd_np, "video-mux")) {
-		num_pads = of_get_port_count(sd_np);
-		/* for the video mux, all but the last port are sinks */
-		imxsd->num_sink_pads = num_pads - 1;
-	} else {
-		num_pads = of_get_port_count(sd_np);
-		if (num_pads != 1) {
-			/* confused, but no reason to give up here */
-			dev_warn(imxmd->md.dev,
-				 "%s: unknown device %s with %d ports\n",
-				 __func__, sd_np->name, num_pads);
-			return 0;
-		}
-
-		/*
-		 * we got to this node from this single source port,
-		 * there are no sink pads.
-		 */
-		imxsd->num_sink_pads = 0;
-	}
-
-	if (imxsd->num_sink_pads >= num_pads)
-		return -EINVAL;
-
-	imxsd->num_src_pads = num_pads - imxsd->num_sink_pads;
-
-	dev_dbg(imxmd->md.dev, "%s: %s has %d pads (%d sink, %d src)\n",
-		__func__, sd_np->name, num_pads,
-		imxsd->num_sink_pads, imxsd->num_src_pads);
 
 	/*
-	 * With no sink, this subdev node is the original source
-	 * of video, parse it's media bus for use by the pipeline.
+	 * the ipu-csi has one sink port. The source pads are not
+	 * represented in the device tree by port nodes, but are
+	 * described by the internal pads and links later.
 	 */
-	if (imxsd->num_sink_pads == 0)
-		of_parse_sensor(imxmd, imxsd, sd_np);
+	num_ports = is_csi_port ? 1 : of_get_port_count(sd_np);
 
-	for (i = 0; i < num_pads; i++) {
+	for (i = 0; i < num_ports; i++) {
 		struct device_node *epnode = NULL, *port, *remote_np;
-		struct imx_media_subdev *remote_imxsd;
-		struct imx_media_pad *pad;
-		int remote_pad;
 
-		/* init this pad */
-		pad = &imxsd->pad[i];
-		pad->pad.flags = (i < imxsd->num_sink_pads) ?
-			MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
-
-		if (is_csi_port)
-			port = (i < imxsd->num_sink_pads) ? sd_np : NULL;
-		else
-			port = of_graph_get_port_by_id(sd_np, i);
+		port = is_csi_port ? sd_np : of_graph_get_port_by_id(sd_np, i);
 		if (!port)
 			continue;
 
 		for_each_child_of_node(port, epnode) {
-			of_get_remote_pad(epnode, &remote_np, &remote_pad);
+			bool remote_is_csi;
+
+			remote_is_csi = of_get_remote(epnode, &remote_np);
 			if (!remote_np)
 				continue;
 
-			ret = of_add_pad_link(imxmd, pad, sd_np, remote_np,
-					      i, remote_pad);
+			ret = of_parse_subdev(imxmd, remote_np, remote_is_csi);
+			of_node_put(remote_np);
 			if (ret)
 				break;
-
-			if (i < imxsd->num_sink_pads) {
-				/* follow sink endpoints upstream */
-				ret = of_parse_subdev(imxmd, remote_np,
-						      false, &remote_imxsd);
-				if (ret)
-					break;
-			}
-
-			of_node_put(remote_np);
 		}
 
 		if (port != sd_np)
 			of_node_put(port);
 		if (ret) {
-			of_node_put(remote_np);
 			of_node_put(epnode);
 			break;
 		}
@@ -230,13 +136,10 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np,
 	return ret;
 }
 
-int imx_media_of_parse(struct imx_media_dev *imxmd,
-		       struct imx_media_subdev *(*csi)[4],
-		       struct device_node *np)
+int imx_media_add_of_subdevs(struct imx_media_dev *imxmd,
+			     struct device_node *np)
 {
-	struct imx_media_subdev *lcsi;
 	struct device_node *csi_np;
-	u32 ipu_id, csi_id;
 	int i, ret;
 
 	for (i = 0; ; i++) {
@@ -244,33 +147,120 @@ int imx_media_of_parse(struct imx_media_dev *imxmd,
 		if (!csi_np)
 			break;
 
-		ret = of_parse_subdev(imxmd, csi_np, true, &lcsi);
-		if (ret)
-			goto err_put;
-
-		ret = of_property_read_u32(csi_np, "reg", &csi_id);
-		if (ret) {
-			dev_err(imxmd->md.dev,
-				"%s: csi port missing reg property!\n",
-				__func__);
-			goto err_put;
-		}
-
-		ipu_id = of_alias_get_id(csi_np->parent, "ipu");
+		ret = of_parse_subdev(imxmd, csi_np, true);
 		of_node_put(csi_np);
-
-		if (ipu_id > 1 || csi_id > 1) {
-			dev_err(imxmd->md.dev,
-				"%s: invalid ipu/csi id (%u/%u)\n",
-				__func__, ipu_id, csi_id);
-			return -EINVAL;
-		}
-
-		(*csi)[ipu_id * 2 + csi_id] = lcsi;
+		if (ret)
+			return ret;
 	}
 
 	return 0;
-err_put:
-	of_node_put(csi_np);
-	return ret;
+}
+
+/*
+ * Create a single media link to/from sd using a fwnode link.
+ *
+ * NOTE: this function assumes an OF port node is equivalent to
+ * a media pad (port id equal to media pad index), and that an
+ * OF endpoint node is equivalent to a media link.
+ */
+static int create_of_link(struct imx_media_dev *imxmd,
+			  struct v4l2_subdev *sd,
+			  struct v4l2_fwnode_link *link)
+{
+	struct v4l2_subdev *remote, *src, *sink;
+	int src_pad, sink_pad;
+
+	if (link->local_port >= sd->entity.num_pads)
+		return -EINVAL;
+
+	remote = imx_media_find_subdev_by_fwnode(imxmd, link->remote_node);
+	if (!remote)
+		return 0;
+
+	if (sd->entity.pads[link->local_port].flags & MEDIA_PAD_FL_SINK) {
+		src = remote;
+		src_pad = link->remote_port;
+		sink = sd;
+		sink_pad = link->local_port;
+	} else {
+		src = sd;
+		src_pad = link->local_port;
+		sink = remote;
+		sink_pad = link->remote_port;
+	}
+
+	/* make sure link doesn't already exist before creating */
+	if (media_entity_find_link(&src->entity.pads[src_pad],
+				   &sink->entity.pads[sink_pad]))
+		return 0;
+
+	v4l2_info(sd->v4l2_dev, "%s:%d -> %s:%d\n",
+		  src->name, src_pad, sink->name, sink_pad);
+
+	return media_create_pad_link(&src->entity, src_pad,
+				     &sink->entity, sink_pad, 0);
+}
+
+/*
+ * Create media links to/from sd using its device-tree endpoints.
+ */
+int imx_media_create_of_links(struct imx_media_dev *imxmd,
+			      struct v4l2_subdev *sd)
+{
+	struct v4l2_fwnode_link link;
+	struct device_node *ep;
+	int ret;
+
+	for_each_endpoint_of_node(sd->dev->of_node, ep) {
+		ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
+		if (ret)
+			continue;
+
+		ret = create_of_link(imxmd, sd, &link);
+		v4l2_fwnode_put_link(&link);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * Create media links to the given CSI subdevice's sink pads,
+ * using its device-tree endpoints.
+ */
+int imx_media_create_csi_of_links(struct imx_media_dev *imxmd,
+				  struct v4l2_subdev *csi)
+{
+	struct device_node *csi_np = csi->dev->of_node;
+	struct fwnode_handle *fwnode, *csi_ep;
+	struct v4l2_fwnode_link link;
+	struct device_node *ep;
+	int ret;
+
+	link.local_node = of_fwnode_handle(csi_np);
+	link.local_port = CSI_SINK_PAD;
+
+	for_each_child_of_node(csi_np, ep) {
+		csi_ep = of_fwnode_handle(ep);
+
+		fwnode = fwnode_graph_get_remote_endpoint(csi_ep);
+		if (!fwnode)
+			continue;
+
+		fwnode = fwnode_get_parent(fwnode);
+		fwnode_property_read_u32(fwnode, "reg", &link.remote_port);
+		fwnode = fwnode_get_next_parent(fwnode);
+		if (is_of_node(fwnode) &&
+		    of_node_cmp(to_of_node(fwnode)->name, "ports") == 0)
+			fwnode = fwnode_get_next_parent(fwnode);
+		link.remote_node = fwnode;
+
+		ret = create_of_link(imxmd, csi, &link);
+		fwnode_handle_put(link.remote_node);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c
index 5952387..13dafa7 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -668,38 +668,35 @@ void imx_media_grp_id_to_sd_name(char *sd_name, int sz, u32 grp_id, int ipu_id)
 }
 EXPORT_SYMBOL_GPL(imx_media_grp_id_to_sd_name);
 
-struct imx_media_subdev *
-imx_media_find_subdev_by_sd(struct imx_media_dev *imxmd,
-			    struct v4l2_subdev *sd)
+struct v4l2_subdev *
+imx_media_find_subdev_by_fwnode(struct imx_media_dev *imxmd,
+				struct fwnode_handle *fwnode)
 {
-	struct imx_media_subdev *imxsd;
-	int i;
+	struct v4l2_subdev *sd;
 
-	for (i = 0; i < imxmd->num_subdevs; i++) {
-		imxsd = &imxmd->subdev[i];
-		if (sd == imxsd->sd)
-			return imxsd;
+	list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
+		if (sd->fwnode == fwnode)
+			return sd;
 	}
 
-	return ERR_PTR(-ENODEV);
+	return NULL;
 }
-EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_sd);
+EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_fwnode);
 
-struct imx_media_subdev *
-imx_media_find_subdev_by_id(struct imx_media_dev *imxmd, u32 grp_id)
+struct v4l2_subdev *
+imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd,
+				 const char *devname)
 {
-	struct imx_media_subdev *imxsd;
-	int i;
+	struct v4l2_subdev *sd;
 
-	for (i = 0; i < imxmd->num_subdevs; i++) {
-		imxsd = &imxmd->subdev[i];
-		if (imxsd->sd && imxsd->sd->grp_id == grp_id)
-			return imxsd;
+	list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
+		if (!strcmp(devname, dev_name(sd->dev)))
+			return sd;
 	}
 
-	return ERR_PTR(-ENODEV);
+	return NULL;
 }
-EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_id);
+EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_devname);
 
 /*
  * Adds a video device to the master video device list. This is called by
@@ -708,32 +705,21 @@ EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_id);
 int imx_media_add_video_device(struct imx_media_dev *imxmd,
 			       struct imx_media_video_dev *vdev)
 {
-	int vdev_idx, ret = 0;
-
 	mutex_lock(&imxmd->mutex);
 
-	vdev_idx = imxmd->num_vdevs;
-	if (vdev_idx >= IMX_MEDIA_MAX_VDEVS) {
-		dev_err(imxmd->md.dev,
-			"%s: too many video devices! can't add %s\n",
-			__func__, vdev->vfd->name);
-		ret = -ENOSPC;
-		goto out;
-	}
+	list_add_tail(&vdev->list, &imxmd->vdev_list);
 
-	imxmd->vdev[vdev_idx] = vdev;
-	imxmd->num_vdevs++;
-out:
 	mutex_unlock(&imxmd->mutex);
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(imx_media_add_video_device);
 
 /*
- * Search upstream or downstream for a subdevice in the current pipeline
+ * Search upstream/downstream for a subdevice in the current pipeline
  * with given grp_id, starting from start_entity. Returns the subdev's
- * source/sink pad that it was reached from. Must be called with
- * mdev->graph_mutex held.
+ * source/sink pad that it was reached from. If grp_id is zero, just
+ * returns the nearest source/sink pad to start_entity. Must be called
+ * with mdev->graph_mutex held.
  */
 static struct media_pad *
 find_pipeline_pad(struct imx_media_dev *imxmd,
@@ -756,11 +742,16 @@ find_pipeline_pad(struct imx_media_dev *imxmd,
 		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			continue;
 
-		sd = media_entity_to_v4l2_subdev(pad->entity);
-		if (sd->grp_id & grp_id)
-			return pad;
+		if (grp_id != 0) {
+			sd = media_entity_to_v4l2_subdev(pad->entity);
+			if (sd->grp_id & grp_id)
+				return pad;
 
-		return find_pipeline_pad(imxmd, pad->entity, grp_id, upstream);
+			return find_pipeline_pad(imxmd, pad->entity,
+						 grp_id, upstream);
+		} else {
+			return pad;
+		}
 	}
 
 	return NULL;
@@ -789,7 +780,6 @@ find_upstream_subdev(struct imx_media_dev *imxmd,
 	return pad ? media_entity_to_v4l2_subdev(pad->entity) : NULL;
 }
 
-
 /*
  * Find the upstream mipi-csi2 virtual channel reached from the given
  * start entity in the current pipeline.
@@ -814,11 +804,30 @@ int imx_media_find_mipi_csi2_channel(struct imx_media_dev *imxmd,
 EXPORT_SYMBOL_GPL(imx_media_find_mipi_csi2_channel);
 
 /*
+ * Find a source pad reached upstream from the given start entity in
+ * the current pipeline. Must be called with mdev->graph_mutex held.
+ */
+struct media_pad *
+imx_media_find_upstream_pad(struct imx_media_dev *imxmd,
+			    struct media_entity *start_entity,
+			    u32 grp_id)
+{
+	struct media_pad *pad;
+
+	pad = find_pipeline_pad(imxmd, start_entity, grp_id, true);
+	if (!pad)
+		return ERR_PTR(-ENODEV);
+
+	return pad;
+}
+EXPORT_SYMBOL_GPL(imx_media_find_upstream_pad);
+
+/*
  * Find a subdev reached upstream from the given start entity in
  * the current pipeline.
  * Must be called with mdev->graph_mutex held.
  */
-struct imx_media_subdev *
+struct v4l2_subdev *
 imx_media_find_upstream_subdev(struct imx_media_dev *imxmd,
 			       struct media_entity *start_entity,
 			       u32 grp_id)
@@ -829,33 +838,10 @@ imx_media_find_upstream_subdev(struct imx_media_dev *imxmd,
 	if (!sd)
 		return ERR_PTR(-ENODEV);
 
-	return imx_media_find_subdev_by_sd(imxmd, sd);
+	return sd;
 }
 EXPORT_SYMBOL_GPL(imx_media_find_upstream_subdev);
 
-struct imx_media_subdev *
-__imx_media_find_sensor(struct imx_media_dev *imxmd,
-			struct media_entity *start_entity)
-{
-	return imx_media_find_upstream_subdev(imxmd, start_entity,
-					      IMX_MEDIA_GRP_ID_SENSOR);
-}
-EXPORT_SYMBOL_GPL(__imx_media_find_sensor);
-
-struct imx_media_subdev *
-imx_media_find_sensor(struct imx_media_dev *imxmd,
-		      struct media_entity *start_entity)
-{
-	struct imx_media_subdev *sensor;
-
-	mutex_lock(&imxmd->md.graph_mutex);
-	sensor = __imx_media_find_sensor(imxmd, start_entity);
-	mutex_unlock(&imxmd->md.graph_mutex);
-
-	return sensor;
-}
-EXPORT_SYMBOL_GPL(imx_media_find_sensor);
-
 /*
  * Turn current pipeline streaming on/off starting from entity.
  */
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index ac3ab11..2fd6dfd 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -11,6 +11,7 @@
 #ifndef _IMX_MEDIA_H
 #define _IMX_MEDIA_H
 
+#include <linux/platform_device.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-fwnode.h>
@@ -19,26 +20,6 @@
 #include <video/imx-ipu-v3.h>
 
 /*
- * This is somewhat arbitrary, but we need at least:
- * - 4 video devices per IPU
- * - 3 IC subdevs per IPU
- * - 1 VDIC subdev per IPU
- * - 2 CSI subdevs per IPU
- * - 1 mipi-csi2 receiver subdev
- * - 2 video-mux subdevs
- * - 2 camera sensor subdevs per IPU (1 parallel, 1 mipi-csi2)
- *
- */
-/* max video devices */
-#define IMX_MEDIA_MAX_VDEVS          8
-/* max subdevices */
-#define IMX_MEDIA_MAX_SUBDEVS       32
-/* max pads per subdev */
-#define IMX_MEDIA_MAX_PADS          16
-/* max links per pad */
-#define IMX_MEDIA_MAX_LINKS          8
-
-/*
  * Pad definitions for the subdevs with multiple source or
  * sink pads
  */
@@ -51,9 +32,6 @@ enum {
 	CSI_NUM_PADS,
 };
 
-#define CSI_NUM_SINK_PADS 1
-#define CSI_NUM_SRC_PADS  2
-
 /* ipu_vdic */
 enum {
 	VDIC_SINK_PAD_DIRECT = 0,
@@ -62,9 +40,6 @@ enum {
 	VDIC_NUM_PADS,
 };
 
-#define VDIC_NUM_SINK_PADS 2
-#define VDIC_NUM_SRC_PADS  1
-
 /* ipu_ic_prp */
 enum {
 	PRP_SINK_PAD = 0,
@@ -73,9 +48,6 @@ enum {
 	PRP_NUM_PADS,
 };
 
-#define PRP_NUM_SINK_PADS 1
-#define PRP_NUM_SRC_PADS  2
-
 /* ipu_ic_prpencvf */
 enum {
 	PRPENCVF_SINK_PAD = 0,
@@ -83,9 +55,6 @@ enum {
 	PRPENCVF_NUM_PADS,
 };
 
-#define PRPENCVF_NUM_SINK_PADS 1
-#define PRPENCVF_NUM_SRC_PADS  1
-
 /* How long to wait for EOF interrupts in the buffer-capture subdevs */
 #define IMX_MEDIA_EOF_TIMEOUT       1000
 
@@ -110,6 +79,9 @@ struct imx_media_video_dev {
 	/* the user format */
 	struct v4l2_format fmt;
 	const struct imx_media_pixfmt *cc;
+
+	/* links this vdev to master list */
+	struct list_head list;
 };
 
 static inline struct imx_media_buffer *to_imx_media_vb(struct vb2_buffer *vb)
@@ -119,25 +91,24 @@ static inline struct imx_media_buffer *to_imx_media_vb(struct vb2_buffer *vb)
 	return container_of(vbuf, struct imx_media_buffer, vbuf);
 }
 
-struct imx_media_link {
-	struct device_node *remote_sd_node;
-	char               remote_devname[32];
-	int                local_pad;
-	int                remote_pad;
-};
+/*
+ * to support control inheritance to video devices, this
+ * retrieves a pad's list_head of video devices that can
+ * be reached from the pad. Note that only the lists in
+ * source pads get populated, sink pads have empty lists.
+ */
+static inline struct list_head *
+to_pad_vdev_list(struct v4l2_subdev *sd, int pad_index)
+{
+	struct list_head *vdev_list = sd->host_priv;
 
-struct imx_media_pad {
-	struct media_pad  pad;
-	struct imx_media_link link[IMX_MEDIA_MAX_LINKS];
-	bool devnode; /* does this pad link to a device node */
-	int num_links;
+	return vdev_list ? &vdev_list[pad_index] : NULL;
+}
 
-	/*
-	 * list of video devices that can be reached from this pad,
-	 * list is only valid for source pads.
-	 */
-	struct imx_media_video_dev *vdev[IMX_MEDIA_MAX_VDEVS];
-	int num_vdevs;
+/* an entry in a pad's video device list */
+struct imx_media_pad_vdev {
+	struct imx_media_video_dev *vdev;
+	struct list_head list;
 };
 
 struct imx_media_internal_sd_platformdata {
@@ -146,23 +117,20 @@ struct imx_media_internal_sd_platformdata {
 	int ipu_id;
 };
 
-struct imx_media_subdev {
+
+struct imx_media_async_subdev {
 	struct v4l2_async_subdev asd;
-	struct v4l2_subdev       *sd; /* set when bound */
-
-	struct imx_media_pad     pad[IMX_MEDIA_MAX_PADS];
-	int num_sink_pads;
-	int num_src_pads;
-
-	/* the platform device if this is an internal subdev */
+	/* the platform device of IPU-internal subdevs */
 	struct platform_device *pdev;
-	/* the devname is needed for async devname match */
-	char devname[32];
-
-	/* if this is a sensor */
-	struct v4l2_fwnode_endpoint sensor_ep;
+	struct list_head list;
 };
 
+static inline struct imx_media_async_subdev *
+to_imx_media_asd(struct v4l2_async_subdev *asd)
+{
+	return container_of(asd, struct imx_media_async_subdev, asd);
+}
+
 struct imx_media_dev {
 	struct media_device md;
 	struct v4l2_device  v4l2_dev;
@@ -172,19 +140,14 @@ struct imx_media_dev {
 
 	struct mutex mutex; /* protect elements below */
 
-	/* master subdevice list */
-	struct imx_media_subdev subdev[IMX_MEDIA_MAX_SUBDEVS];
-	int num_subdevs;
-
 	/* master video device list */
-	struct imx_media_video_dev *vdev[IMX_MEDIA_MAX_VDEVS];
-	int num_vdevs;
+	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_subdev *async_ptrs[IMX_MEDIA_MAX_SUBDEVS];
+	struct list_head asd_list;
 	struct v4l2_async_notifier subdev_notifier;
 };
 
@@ -194,6 +157,7 @@ enum codespace_sel {
 	CS_SEL_ANY,
 };
 
+/* imx-media-utils.c */
 const struct imx_media_pixfmt *
 imx_media_find_format(u32 fourcc, enum codespace_sel cs_sel, bool allow_bayer);
 int imx_media_enum_format(u32 *fourcc, u32 index, enum codespace_sel cs_sel);
@@ -205,7 +169,6 @@ int imx_media_enum_mbus_format(u32 *code, u32 index, enum codespace_sel cs_sel,
 const struct imx_media_pixfmt *
 imx_media_find_ipu_format(u32 code, enum codespace_sel cs_sel);
 int imx_media_enum_ipu_format(u32 *code, u32 index, enum codespace_sel cs_sel);
-
 int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
 			    u32 width, u32 height, u32 code, u32 field,
 			    const struct imx_media_pixfmt **cc);
@@ -219,48 +182,26 @@ int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image,
 				    struct v4l2_mbus_framefmt *mbus);
 int imx_media_ipu_image_to_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
 				    struct ipu_image *image);
-
-struct imx_media_subdev *
-imx_media_find_async_subdev(struct imx_media_dev *imxmd,
-			    struct device_node *np,
-			    const char *devname);
-struct imx_media_subdev *
-imx_media_add_async_subdev(struct imx_media_dev *imxmd,
-			   struct device_node *np,
-			   struct platform_device *pdev);
-int imx_media_add_pad_link(struct imx_media_dev *imxmd,
-			   struct imx_media_pad *pad,
-			   struct device_node *remote_node,
-			   const char *remote_devname,
-			   int local_pad, int remote_pad);
-
 void imx_media_grp_id_to_sd_name(char *sd_name, int sz,
 				 u32 grp_id, int ipu_id);
-
-int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd,
-				   struct imx_media_subdev *csi[4]);
-void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd);
-
-struct imx_media_subdev *
-imx_media_find_subdev_by_sd(struct imx_media_dev *imxmd,
-			    struct v4l2_subdev *sd);
-struct imx_media_subdev *
-imx_media_find_subdev_by_id(struct imx_media_dev *imxmd,
-			    u32 grp_id);
+struct v4l2_subdev *
+imx_media_find_subdev_by_fwnode(struct imx_media_dev *imxmd,
+				struct fwnode_handle *fwnode);
+struct v4l2_subdev *
+imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd,
+				 const char *devname);
 int imx_media_add_video_device(struct imx_media_dev *imxmd,
 			       struct imx_media_video_dev *vdev);
 int imx_media_find_mipi_csi2_channel(struct imx_media_dev *imxmd,
 				     struct media_entity *start_entity);
-struct imx_media_subdev *
+struct media_pad *
+imx_media_find_upstream_pad(struct imx_media_dev *imxmd,
+			    struct media_entity *start_entity,
+			    u32 grp_id);
+struct v4l2_subdev *
 imx_media_find_upstream_subdev(struct imx_media_dev *imxmd,
 			       struct media_entity *start_entity,
 			       u32 grp_id);
-struct imx_media_subdev *
-__imx_media_find_sensor(struct imx_media_dev *imxmd,
-			struct media_entity *start_entity);
-struct imx_media_subdev *
-imx_media_find_sensor(struct imx_media_dev *imxmd,
-		      struct media_entity *start_entity);
 
 struct imx_media_dma_buf {
 	void          *virt;
@@ -278,6 +219,11 @@ int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd,
 				  struct media_entity *entity,
 				  bool on);
 
+/* imx-media-dev.c */
+int imx_media_add_async_subdev(struct imx_media_dev *imxmd,
+			       struct fwnode_handle *fwnode,
+			       struct platform_device *pdev);
+
 /* imx-media-fim.c */
 struct imx_media_fim;
 void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp);
@@ -288,14 +234,19 @@ int imx_media_fim_add_controls(struct imx_media_fim *fim);
 struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd);
 void imx_media_fim_free(struct imx_media_fim *fim);
 
+/* imx-media-internal-sd.c */
+int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd);
+int imx_media_create_internal_links(struct imx_media_dev *imxmd,
+				    struct v4l2_subdev *sd);
+void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd);
+
 /* imx-media-of.c */
-struct imx_media_subdev *
-imx_media_of_find_subdev(struct imx_media_dev *imxmd,
-			 struct device_node *np,
-			 const char *name);
-int imx_media_of_parse(struct imx_media_dev *dev,
-		       struct imx_media_subdev *(*csi)[4],
-		       struct device_node *np);
+int imx_media_add_of_subdevs(struct imx_media_dev *dev,
+			     struct device_node *np);
+int imx_media_create_of_links(struct imx_media_dev *imxmd,
+			      struct v4l2_subdev *sd);
+int imx_media_create_csi_of_links(struct imx_media_dev *imxmd,
+				  struct v4l2_subdev *csi);
 
 /* imx-media-capture.c */
 struct imx_media_video_dev *
@@ -310,16 +261,14 @@ void imx_media_capture_device_set_format(struct imx_media_video_dev *vdev,
 void imx_media_capture_device_error(struct imx_media_video_dev *vdev);
 
 /* subdev group ids */
-#define IMX_MEDIA_GRP_ID_SENSOR    (1 << 8)
-#define IMX_MEDIA_GRP_ID_VIDMUX    (1 << 9)
-#define IMX_MEDIA_GRP_ID_CSI2      (1 << 10)
-#define IMX_MEDIA_GRP_ID_CSI_BIT   11
+#define IMX_MEDIA_GRP_ID_CSI2      BIT(8)
+#define IMX_MEDIA_GRP_ID_CSI_BIT   9
 #define IMX_MEDIA_GRP_ID_CSI       (0x3 << IMX_MEDIA_GRP_ID_CSI_BIT)
-#define IMX_MEDIA_GRP_ID_CSI0      (1 << IMX_MEDIA_GRP_ID_CSI_BIT)
+#define IMX_MEDIA_GRP_ID_CSI0      BIT(IMX_MEDIA_GRP_ID_CSI_BIT)
 #define IMX_MEDIA_GRP_ID_CSI1      (2 << IMX_MEDIA_GRP_ID_CSI_BIT)
-#define IMX_MEDIA_GRP_ID_VDIC      (1 << 13)
-#define IMX_MEDIA_GRP_ID_IC_PRP    (1 << 14)
-#define IMX_MEDIA_GRP_ID_IC_PRPENC (1 << 15)
-#define IMX_MEDIA_GRP_ID_IC_PRPVF  (1 << 16)
+#define IMX_MEDIA_GRP_ID_VDIC      BIT(11)
+#define IMX_MEDIA_GRP_ID_IC_PRP    BIT(12)
+#define IMX_MEDIA_GRP_ID_IC_PRPENC BIT(13)
+#define IMX_MEDIA_GRP_ID_IC_PRPVF  BIT(14)
 
 #endif
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 5061f3f..477d191 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -252,8 +252,8 @@ static int csi2_dphy_wait_stopstate(struct csi2_dev *csi2)
 	u32 mask, reg;
 	int ret;
 
-	mask = PHY_STOPSTATECLK |
-		((csi2->bus.num_data_lanes - 1) << PHY_STOPSTATEDATA_BIT);
+	mask = PHY_STOPSTATECLK | (((1 << csi2->bus.num_data_lanes) - 1) <<
+				   PHY_STOPSTATEDATA_BIT);
 
 	ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
 				 (reg & mask) == mask, 0, 500000);
diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig
deleted file mode 100644
index 3e350a9..0000000
--- a/drivers/staging/media/lirc/Kconfig
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# LIRC driver(s) configuration
-#
-menuconfig LIRC_STAGING
-	bool "Linux Infrared Remote Control IR receiver/transmitter drivers"
-	depends on LIRC
-	help
-	  Say Y here, and all supported Linux Infrared Remote Control IR and
-	  RF receiver and transmitter drivers will be displayed. When paired
-	  with a remote control and the lirc daemon, the receiver drivers
-	  allow control of your Linux system via remote control.
-
-if LIRC_STAGING
-
-config LIRC_ZILOG
-	tristate "Zilog/Hauppauge IR Transmitter"
-	depends on LIRC && I2C
-	help
-	  Driver for the Zilog/Hauppauge IR Transmitter, found on
-	  PVR-150/500, HVR-1200/1250/1700/1800, HD-PVR and other cards
-endif
diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile
deleted file mode 100644
index 6655624..0000000
--- a/drivers/staging/media/lirc/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# Makefile for the lirc drivers.
-#
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_LIRC_ZILOG)	+= lirc_zilog.o
diff --git a/drivers/staging/media/lirc/TODO b/drivers/staging/media/lirc/TODO
deleted file mode 100644
index a97800a..0000000
--- a/drivers/staging/media/lirc/TODO
+++ /dev/null
@@ -1,36 +0,0 @@
-1. Both ir-kbd-i2c and lirc_zilog provide support for RX events for
-the chips supported by lirc_zilog.  Before moving lirc_zilog out of staging:
-
-a. ir-kbd-i2c needs a module parameter added to allow the user to tell
-   ir-kbd-i2c to ignore Z8 IR units.
-
-b. lirc_zilog should provide Rx key presses to the rc core like ir-kbd-i2c
-   does.
-
-
-2. lirc_zilog module ref-counting need examination.  It has not been
-verified that cdev and lirc_dev will take the proper module references on
-lirc_zilog to prevent removal of lirc_zilog when the /dev/lircN device node
-is open.
-
-(The good news is ref-counting of lirc_zilog internal structures appears to be
-complete.  Testing has shown the cx18 module can be unloaded out from under
-irw + lircd + lirc_dev, with the /dev/lirc0 device node open, with no adverse
-effects.  The cx18 module could then be reloaded and irw properly began
-receiving button presses again and ir_send worked without error.)
-
-
-3. Bridge drivers, if able, should provide a chip reset() callback
-to lirc_zilog via struct IR_i2c_init_data.  cx18 and ivtv already have routines
-to perform Z8 chip resets via GPIO manipulations.  This would allow lirc_zilog
-to bring the chip back to normal when it hangs, in the same places the
-original lirc_pvr150 driver code does.  This is not strictly needed, so it
-is not required to move lirc_zilog out of staging.
-
-Note: Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed
-and installed on Hauppauge products.  When working on either module, developers
-must consider at least the following bridge drivers which mention an IR Rx unit
-at address 0x71 (indicative of a Z8):
-
-	ivtv cx18 hdpvr pvrusb2 bt8xx cx88 saa7134
-
diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c
deleted file mode 100644
index a003603..0000000
--- a/drivers/staging/media/lirc/lirc_zilog.c
+++ /dev/null
@@ -1,1653 +0,0 @@
-/*
- * i2c IR lirc driver for devices with zilog IR processors
- *
- * Copyright (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
- * modified for PixelView (BT878P+W/FM) by
- *      Michal Kochanowicz <mkochano@pld.org.pl>
- *      Christoph Bartelmus <lirc@bartelmus.de>
- * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
- *      Ulrich Mueller <ulrich.mueller42@web.de>
- * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by
- *      Stefan Jahn <stefan@lkcc.org>
- * modified for inclusion into kernel sources by
- *      Jerome Brock <jbrock@users.sourceforge.net>
- * modified for Leadtek Winfast PVR2000 by
- *      Thomas Reitmayr (treitmayr@yahoo.com)
- * modified for Hauppauge PVR-150 IR TX device by
- *      Mark Weaver <mark@npsl.co.uk>
- * changed name from lirc_pvr150 to lirc_zilog, works on more than pvr-150
- *	Jarod Wilson <jarod@redhat.com>
- *
- * parts are cut&pasted from the lirc_i2c.c driver
- *
- * Numerous changes updating lirc_zilog.c in kernel 2.6.38 and later are
- * Copyright (C) 2011 Andy Walls <awalls@md.metrocast.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/fs.h>
-#include <linux/poll.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/completion.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/firmware.h>
-#include <linux/vmalloc.h>
-
-#include <linux/mutex.h>
-#include <linux/kthread.h>
-
-#include <media/lirc_dev.h>
-#include <media/lirc.h>
-
-/* Max transfer size done by I2C transfer functions */
-#define MAX_XFER_SIZE  64
-
-struct IR;
-
-struct IR_rx {
-	struct kref ref;
-	struct IR *ir;
-
-	/* RX device */
-	struct mutex client_lock;
-	struct i2c_client *c;
-
-	/* RX polling thread data */
-	struct task_struct *task;
-
-	/* RX read data */
-	unsigned char b[3];
-	bool hdpvr_data_fmt;
-};
-
-struct IR_tx {
-	struct kref ref;
-	struct IR *ir;
-
-	/* TX device */
-	struct mutex client_lock;
-	struct i2c_client *c;
-
-	/* TX additional actions needed */
-	int need_boot;
-	bool post_tx_ready_poll;
-};
-
-struct IR {
-	struct kref ref;
-	struct list_head list;
-
-	/* FIXME spinlock access to l->features */
-	struct lirc_dev *l;
-	struct lirc_buffer rbuf;
-
-	struct mutex ir_lock;
-	atomic_t open_count;
-
-	struct device *dev;
-	struct i2c_adapter *adapter;
-
-	spinlock_t rx_ref_lock; /* struct IR_rx kref get()/put() */
-	struct IR_rx *rx;
-
-	spinlock_t tx_ref_lock; /* struct IR_tx kref get()/put() */
-	struct IR_tx *tx;
-};
-
-/* IR transceiver instance object list */
-/*
- * This lock is used for the following:
- * a. ir_devices_list access, insertions, deletions
- * b. struct IR kref get()s and put()s
- * c. serialization of ir_probe() for the two i2c_clients for a Z8
- */
-static DEFINE_MUTEX(ir_devices_lock);
-static LIST_HEAD(ir_devices_list);
-
-/* Block size for IR transmitter */
-#define TX_BLOCK_SIZE	99
-
-/* Hauppauge IR transmitter data */
-struct tx_data_struct {
-	/* Boot block */
-	unsigned char *boot_data;
-
-	/* Start of binary data block */
-	unsigned char *datap;
-
-	/* End of binary data block */
-	unsigned char *endp;
-
-	/* Number of installed codesets */
-	unsigned int num_code_sets;
-
-	/* Pointers to codesets */
-	unsigned char **code_sets;
-
-	/* Global fixed data template */
-	int fixed[TX_BLOCK_SIZE];
-};
-
-static struct tx_data_struct *tx_data;
-static struct mutex tx_data_lock;
-
-
-/* module parameters */
-static bool debug;	/* debug output */
-static bool tx_only;	/* only handle the IR Tx function */
-
-
-/* struct IR reference counting */
-static struct IR *get_ir_device(struct IR *ir, bool ir_devices_lock_held)
-{
-	if (ir_devices_lock_held) {
-		kref_get(&ir->ref);
-	} else {
-		mutex_lock(&ir_devices_lock);
-		kref_get(&ir->ref);
-		mutex_unlock(&ir_devices_lock);
-	}
-	return ir;
-}
-
-static void release_ir_device(struct kref *ref)
-{
-	struct IR *ir = container_of(ref, struct IR, ref);
-
-	/*
-	 * Things should be in this state by now:
-	 * ir->rx set to NULL and deallocated - happens before ir->rx->ir put()
-	 * ir->rx->task kthread stopped - happens before ir->rx->ir put()
-	 * ir->tx set to NULL and deallocated - happens before ir->tx->ir put()
-	 * ir->open_count ==  0 - happens on final close()
-	 * ir_lock, tx_ref_lock, rx_ref_lock, all released
-	 */
-	if (ir->l)
-		lirc_unregister_device(ir->l);
-
-	if (kfifo_initialized(&ir->rbuf.fifo))
-		lirc_buffer_free(&ir->rbuf);
-	list_del(&ir->list);
-	kfree(ir);
-}
-
-static int put_ir_device(struct IR *ir, bool ir_devices_lock_held)
-{
-	int released;
-
-	if (ir_devices_lock_held)
-		return kref_put(&ir->ref, release_ir_device);
-
-	mutex_lock(&ir_devices_lock);
-	released = kref_put(&ir->ref, release_ir_device);
-	mutex_unlock(&ir_devices_lock);
-
-	return released;
-}
-
-/* struct IR_rx reference counting */
-static struct IR_rx *get_ir_rx(struct IR *ir)
-{
-	struct IR_rx *rx;
-
-	spin_lock(&ir->rx_ref_lock);
-	rx = ir->rx;
-	if (rx)
-		kref_get(&rx->ref);
-	spin_unlock(&ir->rx_ref_lock);
-	return rx;
-}
-
-static void destroy_rx_kthread(struct IR_rx *rx, bool ir_devices_lock_held)
-{
-	/* end up polling thread */
-	if (!IS_ERR_OR_NULL(rx->task)) {
-		kthread_stop(rx->task);
-		rx->task = NULL;
-		/* Put the ir ptr that ir_probe() gave to the rx poll thread */
-		put_ir_device(rx->ir, ir_devices_lock_held);
-	}
-}
-
-static void release_ir_rx(struct kref *ref)
-{
-	struct IR_rx *rx = container_of(ref, struct IR_rx, ref);
-	struct IR *ir = rx->ir;
-
-	/*
-	 * This release function can't do all the work, as we want
-	 * to keep the rx_ref_lock a spinlock, and killing the poll thread
-	 * and releasing the ir reference can cause a sleep.  That work is
-	 * performed by put_ir_rx()
-	 */
-	ir->l->features &= ~LIRC_CAN_REC_LIRCCODE;
-	/* Don't put_ir_device(rx->ir) here; lock can't be freed yet */
-	ir->rx = NULL;
-	/* Don't do the kfree(rx) here; we still need to kill the poll thread */
-}
-
-static int put_ir_rx(struct IR_rx *rx, bool ir_devices_lock_held)
-{
-	int released;
-	struct IR *ir = rx->ir;
-
-	spin_lock(&ir->rx_ref_lock);
-	released = kref_put(&rx->ref, release_ir_rx);
-	spin_unlock(&ir->rx_ref_lock);
-	/* Destroy the rx kthread while not holding the spinlock */
-	if (released) {
-		destroy_rx_kthread(rx, ir_devices_lock_held);
-		kfree(rx);
-		/* Make sure we're not still in a poll_table somewhere */
-		wake_up_interruptible(&ir->rbuf.wait_poll);
-	}
-	/* Do a reference put() for the rx->ir reference, if we released rx */
-	if (released)
-		put_ir_device(ir, ir_devices_lock_held);
-	return released;
-}
-
-/* struct IR_tx reference counting */
-static struct IR_tx *get_ir_tx(struct IR *ir)
-{
-	struct IR_tx *tx;
-
-	spin_lock(&ir->tx_ref_lock);
-	tx = ir->tx;
-	if (tx)
-		kref_get(&tx->ref);
-	spin_unlock(&ir->tx_ref_lock);
-	return tx;
-}
-
-static void release_ir_tx(struct kref *ref)
-{
-	struct IR_tx *tx = container_of(ref, struct IR_tx, ref);
-	struct IR *ir = tx->ir;
-
-	ir->l->features &= ~LIRC_CAN_SEND_LIRCCODE;
-	/* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */
-	ir->tx = NULL;
-	kfree(tx);
-}
-
-static int put_ir_tx(struct IR_tx *tx, bool ir_devices_lock_held)
-{
-	int released;
-	struct IR *ir = tx->ir;
-
-	spin_lock(&ir->tx_ref_lock);
-	released = kref_put(&tx->ref, release_ir_tx);
-	spin_unlock(&ir->tx_ref_lock);
-	/* Do a reference put() for the tx->ir reference, if we released tx */
-	if (released)
-		put_ir_device(ir, ir_devices_lock_held);
-	return released;
-}
-
-static int add_to_buf(struct IR *ir)
-{
-	__u16 code;
-	unsigned char codes[2];
-	unsigned char keybuf[6];
-	int got_data = 0;
-	int ret;
-	int failures = 0;
-	unsigned char sendbuf[1] = { 0 };
-	struct lirc_buffer *rbuf = ir->l->buf;
-	struct IR_rx *rx;
-	struct IR_tx *tx;
-
-	if (lirc_buffer_full(rbuf)) {
-		dev_dbg(ir->dev, "buffer overflow\n");
-		return -EOVERFLOW;
-	}
-
-	rx = get_ir_rx(ir);
-	if (!rx)
-		return -ENXIO;
-
-	/* Ensure our rx->c i2c_client remains valid for the duration */
-	mutex_lock(&rx->client_lock);
-	if (!rx->c) {
-		mutex_unlock(&rx->client_lock);
-		put_ir_rx(rx, false);
-		return -ENXIO;
-	}
-
-	tx = get_ir_tx(ir);
-
-	/*
-	 * service the device as long as it is returning
-	 * data and we have space
-	 */
-	do {
-		if (kthread_should_stop()) {
-			ret = -ENODATA;
-			break;
-		}
-
-		/*
-		 * Lock i2c bus for the duration.  RX/TX chips interfere so
-		 * this is worth it
-		 */
-		mutex_lock(&ir->ir_lock);
-
-		if (kthread_should_stop()) {
-			mutex_unlock(&ir->ir_lock);
-			ret = -ENODATA;
-			break;
-		}
-
-		/*
-		 * Send random "poll command" (?)  Windows driver does this
-		 * and it is a good point to detect chip failure.
-		 */
-		ret = i2c_master_send(rx->c, sendbuf, 1);
-		if (ret != 1) {
-			dev_err(ir->dev, "i2c_master_send failed with %d\n",
-				ret);
-			if (failures >= 3) {
-				mutex_unlock(&ir->ir_lock);
-				dev_err(ir->dev,
-					"unable to read from the IR chip after 3 resets, giving up\n");
-				break;
-			}
-
-			/* Looks like the chip crashed, reset it */
-			dev_err(ir->dev,
-				"polling the IR receiver chip failed, trying reset\n");
-
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			if (kthread_should_stop()) {
-				mutex_unlock(&ir->ir_lock);
-				ret = -ENODATA;
-				break;
-			}
-			schedule_timeout((100 * HZ + 999) / 1000);
-			if (tx)
-				tx->need_boot = 1;
-
-			++failures;
-			mutex_unlock(&ir->ir_lock);
-			ret = 0;
-			continue;
-		}
-
-		if (kthread_should_stop()) {
-			mutex_unlock(&ir->ir_lock);
-			ret = -ENODATA;
-			break;
-		}
-		ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf));
-		mutex_unlock(&ir->ir_lock);
-		if (ret != sizeof(keybuf)) {
-			dev_err(ir->dev,
-				"i2c_master_recv failed with %d -- keeping last read buffer\n",
-				ret);
-		} else {
-			rx->b[0] = keybuf[3];
-			rx->b[1] = keybuf[4];
-			rx->b[2] = keybuf[5];
-			dev_dbg(ir->dev,
-				"key (0x%02x/0x%02x)\n",
-				rx->b[0], rx->b[1]);
-		}
-
-		/* key pressed ? */
-		if (rx->hdpvr_data_fmt) {
-			if (got_data && (keybuf[0] == 0x80)) {
-				ret = 0;
-				break;
-			} else if (got_data && (keybuf[0] == 0x00)) {
-				ret = -ENODATA;
-				break;
-			}
-		} else if ((rx->b[0] & 0x80) == 0) {
-			ret = got_data ? 0 : -ENODATA;
-			break;
-		}
-
-		/* look what we have */
-		code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2);
-
-		codes[0] = (code >> 8) & 0xff;
-		codes[1] = code & 0xff;
-
-		/* return it */
-		lirc_buffer_write(rbuf, codes);
-		++got_data;
-		ret = 0;
-	} while (!lirc_buffer_full(rbuf));
-
-	mutex_unlock(&rx->client_lock);
-	if (tx)
-		put_ir_tx(tx, false);
-	put_ir_rx(rx, false);
-	return ret;
-}
-
-/*
- * Main function of the polling thread -- from lirc_dev.
- * We don't fit the LIRC model at all anymore.  This is horrible, but
- * basically we have a single RX/TX device with a nasty failure mode
- * that needs to be accounted for across the pair.  lirc lets us provide
- * fops, but prevents us from using the internal polling, etc. if we do
- * so.  Hence the replication.  Might be neater to extend the LIRC model
- * to account for this but I'd think it's a very special case of seriously
- * messed up hardware.
- */
-static int lirc_thread(void *arg)
-{
-	struct IR *ir = arg;
-	struct lirc_buffer *rbuf = ir->l->buf;
-
-	dev_dbg(ir->dev, "poll thread started\n");
-
-	while (!kthread_should_stop()) {
-		set_current_state(TASK_INTERRUPTIBLE);
-
-		/* if device not opened, we can sleep half a second */
-		if (atomic_read(&ir->open_count) == 0) {
-			schedule_timeout(HZ / 2);
-			continue;
-		}
-
-		/*
-		 * This is ~113*2 + 24 + jitter (2*repeat gap + code length).
-		 * We use this interval as the chip resets every time you poll
-		 * it (bad!).  This is therefore just sufficient to catch all
-		 * of the button presses.  It makes the remote much more
-		 * responsive.  You can see the difference by running irw and
-		 * holding down a button.  With 100ms, the old polling
-		 * interval, you'll notice breaks in the repeat sequence
-		 * corresponding to lost keypresses.
-		 */
-		schedule_timeout((260 * HZ) / 1000);
-		if (kthread_should_stop())
-			break;
-		if (!add_to_buf(ir))
-			wake_up_interruptible(&rbuf->wait_poll);
-	}
-
-	dev_dbg(ir->dev, "poll thread ended\n");
-	return 0;
-}
-
-/* safe read of a uint32 (always network byte order) */
-static int read_uint32(unsigned char **data,
-		       unsigned char *endp, unsigned int *val)
-{
-	if (*data + 4 > endp)
-		return 0;
-	*val = ((*data)[0] << 24) | ((*data)[1] << 16) |
-	       ((*data)[2] << 8) | (*data)[3];
-	*data += 4;
-	return 1;
-}
-
-/* safe read of a uint8 */
-static int read_uint8(unsigned char **data,
-		      unsigned char *endp, unsigned char *val)
-{
-	if (*data + 1 > endp)
-		return 0;
-	*val = *((*data)++);
-	return 1;
-}
-
-/* safe skipping of N bytes */
-static int skip(unsigned char **data,
-		unsigned char *endp, unsigned int distance)
-{
-	if (*data + distance > endp)
-		return 0;
-	*data += distance;
-	return 1;
-}
-
-/* decompress key data into the given buffer */
-static int get_key_data(unsigned char *buf,
-			unsigned int codeset, unsigned int key)
-{
-	unsigned char *data, *endp, *diffs, *key_block;
-	unsigned char keys, ndiffs, id;
-	unsigned int base, lim, pos, i;
-
-	/* Binary search for the codeset */
-	for (base = 0, lim = tx_data->num_code_sets; lim; lim >>= 1) {
-		pos = base + (lim >> 1);
-		data = tx_data->code_sets[pos];
-
-		if (!read_uint32(&data, tx_data->endp, &i))
-			goto corrupt;
-
-		if (i == codeset) {
-			break;
-		} else if (codeset > i) {
-			base = pos + 1;
-			--lim;
-		}
-	}
-	/* Not found? */
-	if (!lim)
-		return -EPROTO;
-
-	/* Set end of data block */
-	endp = pos < tx_data->num_code_sets - 1 ?
-		tx_data->code_sets[pos + 1] : tx_data->endp;
-
-	/* Read the block header */
-	if (!read_uint8(&data, endp, &keys) ||
-	    !read_uint8(&data, endp, &ndiffs) ||
-	    ndiffs > TX_BLOCK_SIZE || keys == 0)
-		goto corrupt;
-
-	/* Save diffs & skip */
-	diffs = data;
-	if (!skip(&data, endp, ndiffs))
-		goto corrupt;
-
-	/* Read the id of the first key */
-	if (!read_uint8(&data, endp, &id))
-		goto corrupt;
-
-	/* Unpack the first key's data */
-	for (i = 0; i < TX_BLOCK_SIZE; ++i) {
-		if (tx_data->fixed[i] == -1) {
-			if (!read_uint8(&data, endp, &buf[i]))
-				goto corrupt;
-		} else {
-			buf[i] = (unsigned char)tx_data->fixed[i];
-		}
-	}
-
-	/* Early out key found/not found */
-	if (key == id)
-		return 0;
-	if (keys == 1)
-		return -EPROTO;
-
-	/* Sanity check */
-	key_block = data;
-	if (!skip(&data, endp, (keys - 1) * (ndiffs + 1)))
-		goto corrupt;
-
-	/* Binary search for the key */
-	for (base = 0, lim = keys - 1; lim; lim >>= 1) {
-		/* Seek to block */
-		unsigned char *key_data;
-
-		pos = base + (lim >> 1);
-		key_data = key_block + (ndiffs + 1) * pos;
-
-		if (*key_data == key) {
-			/* skip key id */
-			++key_data;
-
-			/* found, so unpack the diffs */
-			for (i = 0; i < ndiffs; ++i) {
-				unsigned char val;
-
-				if (!read_uint8(&key_data, endp, &val) ||
-				    diffs[i] >= TX_BLOCK_SIZE)
-					goto corrupt;
-				buf[diffs[i]] = val;
-			}
-
-			return 0;
-		} else if (key > *key_data) {
-			base = pos + 1;
-			--lim;
-		}
-	}
-	/* Key not found */
-	return -EPROTO;
-
-corrupt:
-	pr_err("firmware is corrupt\n");
-	return -EFAULT;
-}
-
-/* send a block of data to the IR TX device */
-static int send_data_block(struct IR_tx *tx, unsigned char *data_block)
-{
-	int i, j, ret;
-	unsigned char buf[5];
-
-	for (i = 0; i < TX_BLOCK_SIZE;) {
-		int tosend = TX_BLOCK_SIZE - i;
-
-		if (tosend > 4)
-			tosend = 4;
-		buf[0] = (unsigned char)(i + 1);
-		for (j = 0; j < tosend; ++j)
-			buf[1 + j] = data_block[i + j];
-		dev_dbg(tx->ir->dev, "%*ph", 5, buf);
-		ret = i2c_master_send(tx->c, buf, tosend + 1);
-		if (ret != tosend + 1) {
-			dev_err(tx->ir->dev,
-				"i2c_master_send failed with %d\n", ret);
-			return ret < 0 ? ret : -EFAULT;
-		}
-		i += tosend;
-	}
-	return 0;
-}
-
-/* send boot data to the IR TX device */
-static int send_boot_data(struct IR_tx *tx)
-{
-	int ret, i;
-	unsigned char buf[4];
-
-	/* send the boot block */
-	ret = send_data_block(tx, tx_data->boot_data);
-	if (ret != 0)
-		return ret;
-
-	/* Hit the go button to activate the new boot data */
-	buf[0] = 0x00;
-	buf[1] = 0x20;
-	ret = i2c_master_send(tx->c, buf, 2);
-	if (ret != 2) {
-		dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret);
-		return ret < 0 ? ret : -EFAULT;
-	}
-
-	/*
-	 * Wait for zilog to settle after hitting go post boot block upload.
-	 * Without this delay, the HD-PVR and HVR-1950 both return an -EIO
-	 * upon attempting to get firmware revision, and tx probe thus fails.
-	 */
-	for (i = 0; i < 10; i++) {
-		ret = i2c_master_send(tx->c, buf, 1);
-		if (ret == 1)
-			break;
-		udelay(100);
-	}
-
-	if (ret != 1) {
-		dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret);
-		return ret < 0 ? ret : -EFAULT;
-	}
-
-	/* Here comes the firmware version... (hopefully) */
-	ret = i2c_master_recv(tx->c, buf, 4);
-	if (ret != 4) {
-		dev_err(tx->ir->dev, "i2c_master_recv failed with %d\n", ret);
-		return 0;
-	}
-	if ((buf[0] != 0x80) && (buf[0] != 0xa0)) {
-		dev_err(tx->ir->dev, "unexpected IR TX init response: %02x\n",
-			buf[0]);
-		return 0;
-	}
-	dev_notice(tx->ir->dev,
-		   "Zilog/Hauppauge IR blaster firmware version %d.%d.%d loaded\n",
-		   buf[1], buf[2], buf[3]);
-
-	return 0;
-}
-
-/* unload "firmware", lock held */
-static void fw_unload_locked(void)
-{
-	if (tx_data) {
-		vfree(tx_data->code_sets);
-
-		vfree(tx_data->datap);
-
-		vfree(tx_data);
-		tx_data = NULL;
-		pr_debug("successfully unloaded IR blaster firmware\n");
-	}
-}
-
-/* unload "firmware" for the IR TX device */
-static void fw_unload(void)
-{
-	mutex_lock(&tx_data_lock);
-	fw_unload_locked();
-	mutex_unlock(&tx_data_lock);
-}
-
-/* load "firmware" for the IR TX device */
-static int fw_load(struct IR_tx *tx)
-{
-	int ret;
-	unsigned int i;
-	unsigned char *data, version, num_global_fixed;
-	const struct firmware *fw_entry;
-
-	/* Already loaded? */
-	mutex_lock(&tx_data_lock);
-	if (tx_data) {
-		ret = 0;
-		goto out;
-	}
-
-	/* Request codeset data file */
-	ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->dev);
-	if (ret != 0) {
-		dev_err(tx->ir->dev,
-			"firmware haup-ir-blaster.bin not available (%d)\n",
-			ret);
-		ret = ret < 0 ? ret : -EFAULT;
-		goto out;
-	}
-	dev_dbg(tx->ir->dev, "firmware of size %zu loaded\n", fw_entry->size);
-
-	/* Parse the file */
-	tx_data = vmalloc(sizeof(*tx_data));
-	if (!tx_data) {
-		release_firmware(fw_entry);
-		ret = -ENOMEM;
-		goto out;
-	}
-	tx_data->code_sets = NULL;
-
-	/* Copy the data so hotplug doesn't get confused and timeout */
-	tx_data->datap = vmalloc(fw_entry->size);
-	if (!tx_data->datap) {
-		release_firmware(fw_entry);
-		vfree(tx_data);
-		ret = -ENOMEM;
-		goto out;
-	}
-	memcpy(tx_data->datap, fw_entry->data, fw_entry->size);
-	tx_data->endp = tx_data->datap + fw_entry->size;
-	release_firmware(fw_entry); fw_entry = NULL;
-
-	/* Check version */
-	data = tx_data->datap;
-	if (!read_uint8(&data, tx_data->endp, &version))
-		goto corrupt;
-	if (version != 1) {
-		dev_err(tx->ir->dev,
-			"unsupported code set file version (%u, expected 1) -- please upgrade to a newer driver\n",
-			version);
-		fw_unload_locked();
-		ret = -EFAULT;
-		goto out;
-	}
-
-	/* Save boot block for later */
-	tx_data->boot_data = data;
-	if (!skip(&data, tx_data->endp, TX_BLOCK_SIZE))
-		goto corrupt;
-
-	if (!read_uint32(&data, tx_data->endp,
-			 &tx_data->num_code_sets))
-		goto corrupt;
-
-	dev_dbg(tx->ir->dev, "%u IR blaster codesets loaded\n",
-		tx_data->num_code_sets);
-
-	tx_data->code_sets = vmalloc(
-		tx_data->num_code_sets * sizeof(char *));
-	if (!tx_data->code_sets) {
-		fw_unload_locked();
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	for (i = 0; i < TX_BLOCK_SIZE; ++i)
-		tx_data->fixed[i] = -1;
-
-	/* Read global fixed data template */
-	if (!read_uint8(&data, tx_data->endp, &num_global_fixed) ||
-	    num_global_fixed > TX_BLOCK_SIZE)
-		goto corrupt;
-	for (i = 0; i < num_global_fixed; ++i) {
-		unsigned char pos, val;
-
-		if (!read_uint8(&data, tx_data->endp, &pos) ||
-		    !read_uint8(&data, tx_data->endp, &val) ||
-		    pos >= TX_BLOCK_SIZE)
-			goto corrupt;
-		tx_data->fixed[pos] = (int)val;
-	}
-
-	/* Filch out the position of each code set */
-	for (i = 0; i < tx_data->num_code_sets; ++i) {
-		unsigned int id;
-		unsigned char keys;
-		unsigned char ndiffs;
-
-		/* Save the codeset position */
-		tx_data->code_sets[i] = data;
-
-		/* Read header */
-		if (!read_uint32(&data, tx_data->endp, &id) ||
-		    !read_uint8(&data, tx_data->endp, &keys) ||
-		    !read_uint8(&data, tx_data->endp, &ndiffs) ||
-		    ndiffs > TX_BLOCK_SIZE || keys == 0)
-			goto corrupt;
-
-		/* skip diff positions */
-		if (!skip(&data, tx_data->endp, ndiffs))
-			goto corrupt;
-
-		/*
-		 * After the diffs we have the first key id + data -
-		 * global fixed
-		 */
-		if (!skip(&data, tx_data->endp,
-			  1 + TX_BLOCK_SIZE - num_global_fixed))
-			goto corrupt;
-
-		/* Then we have keys-1 blocks of key id+diffs */
-		if (!skip(&data, tx_data->endp,
-			  (ndiffs + 1) * (keys - 1)))
-			goto corrupt;
-	}
-	ret = 0;
-	goto out;
-
-corrupt:
-	dev_err(tx->ir->dev, "firmware is corrupt\n");
-	fw_unload_locked();
-	ret = -EFAULT;
-
-out:
-	mutex_unlock(&tx_data_lock);
-	return ret;
-}
-
-/* copied from lirc_dev */
-static ssize_t read(struct file *filep, char __user *outbuf, size_t n,
-		    loff_t *ppos)
-{
-	struct IR *ir = lirc_get_pdata(filep);
-	struct IR_rx *rx;
-	struct lirc_buffer *rbuf = ir->l->buf;
-	int ret = 0, written = 0, retries = 0;
-	unsigned int m;
-	DECLARE_WAITQUEUE(wait, current);
-
-	dev_dbg(ir->dev, "read called\n");
-	if (n % rbuf->chunk_size) {
-		dev_dbg(ir->dev, "read result = -EINVAL\n");
-		return -EINVAL;
-	}
-
-	rx = get_ir_rx(ir);
-	if (!rx)
-		return -ENXIO;
-
-	/*
-	 * we add ourselves to the task queue before buffer check
-	 * to avoid losing scan code (in case when queue is awaken somewhere
-	 * between while condition checking and scheduling)
-	 */
-	add_wait_queue(&rbuf->wait_poll, &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-
-	/*
-	 * while we didn't provide 'length' bytes, device is opened in blocking
-	 * mode and 'copy_to_user' is happy, wait for data.
-	 */
-	while (written < n && ret == 0) {
-		if (lirc_buffer_empty(rbuf)) {
-			/*
-			 * According to the read(2) man page, 'written' can be
-			 * returned as less than 'n', instead of blocking
-			 * again, returning -EWOULDBLOCK, or returning
-			 * -ERESTARTSYS
-			 */
-			if (written)
-				break;
-			if (filep->f_flags & O_NONBLOCK) {
-				ret = -EWOULDBLOCK;
-				break;
-			}
-			if (signal_pending(current)) {
-				ret = -ERESTARTSYS;
-				break;
-			}
-			schedule();
-			set_current_state(TASK_INTERRUPTIBLE);
-		} else {
-			unsigned char buf[MAX_XFER_SIZE];
-
-			if (rbuf->chunk_size > sizeof(buf)) {
-				dev_err(ir->dev,
-					"chunk_size is too big (%d)!\n",
-					rbuf->chunk_size);
-				ret = -EINVAL;
-				break;
-			}
-			m = lirc_buffer_read(rbuf, buf);
-			if (m == rbuf->chunk_size) {
-				ret = copy_to_user(outbuf + written, buf,
-						   rbuf->chunk_size);
-				written += rbuf->chunk_size;
-			} else {
-				retries++;
-			}
-			if (retries >= 5) {
-				dev_err(ir->dev, "Buffer read failed!\n");
-				ret = -EIO;
-			}
-		}
-	}
-
-	remove_wait_queue(&rbuf->wait_poll, &wait);
-	put_ir_rx(rx, false);
-	set_current_state(TASK_RUNNING);
-
-	dev_dbg(ir->dev, "read result = %d (%s)\n", ret,
-		ret ? "Error" : "OK");
-
-	return ret ? ret : written;
-}
-
-/* send a keypress to the IR TX device */
-static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key)
-{
-	unsigned char data_block[TX_BLOCK_SIZE];
-	unsigned char buf[2];
-	int i, ret;
-
-	/* Get data for the codeset/key */
-	ret = get_key_data(data_block, code, key);
-
-	if (ret == -EPROTO) {
-		dev_err(tx->ir->dev,
-			"failed to get data for code %u, key %u -- check lircd.conf entries\n",
-			code, key);
-		return ret;
-	} else if (ret != 0) {
-		return ret;
-	}
-
-	/* Send the data block */
-	ret = send_data_block(tx, data_block);
-	if (ret != 0)
-		return ret;
-
-	/* Send data block length? */
-	buf[0] = 0x00;
-	buf[1] = 0x40;
-	ret = i2c_master_send(tx->c, buf, 2);
-	if (ret != 2) {
-		dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret);
-		return ret < 0 ? ret : -EFAULT;
-	}
-
-	/* Give the z8 a moment to process data block */
-	for (i = 0; i < 10; i++) {
-		ret = i2c_master_send(tx->c, buf, 1);
-		if (ret == 1)
-			break;
-		udelay(100);
-	}
-
-	if (ret != 1) {
-		dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret);
-		return ret < 0 ? ret : -EFAULT;
-	}
-
-	/* Send finished download? */
-	ret = i2c_master_recv(tx->c, buf, 1);
-	if (ret != 1) {
-		dev_err(tx->ir->dev, "i2c_master_recv failed with %d\n", ret);
-		return ret < 0 ? ret : -EFAULT;
-	}
-	if (buf[0] != 0xA0) {
-		dev_err(tx->ir->dev, "unexpected IR TX response #1: %02x\n",
-			buf[0]);
-		return -EFAULT;
-	}
-
-	/* Send prepare command? */
-	buf[0] = 0x00;
-	buf[1] = 0x80;
-	ret = i2c_master_send(tx->c, buf, 2);
-	if (ret != 2) {
-		dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret);
-		return ret < 0 ? ret : -EFAULT;
-	}
-
-	/*
-	 * The sleep bits aren't necessary on the HD PVR, and in fact, the
-	 * last i2c_master_recv always fails with a -5, so for now, we're
-	 * going to skip this whole mess and say we're done on the HD PVR
-	 */
-	if (!tx->post_tx_ready_poll) {
-		dev_dbg(tx->ir->dev, "sent code %u, key %u\n", code, key);
-		return 0;
-	}
-
-	/*
-	 * This bit NAKs until the device is ready, so we retry it
-	 * sleeping a bit each time.  This seems to be what the windows
-	 * driver does, approximately.
-	 * Try for up to 1s.
-	 */
-	for (i = 0; i < 20; ++i) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((50 * HZ + 999) / 1000);
-		ret = i2c_master_send(tx->c, buf, 1);
-		if (ret == 1)
-			break;
-		dev_dbg(tx->ir->dev,
-			"NAK expected: i2c_master_send failed with %d (try %d)\n",
-			ret, i + 1);
-	}
-	if (ret != 1) {
-		dev_err(tx->ir->dev,
-			"IR TX chip never got ready: last i2c_master_send failed with %d\n",
-			ret);
-		return ret < 0 ? ret : -EFAULT;
-	}
-
-	/* Seems to be an 'ok' response */
-	i = i2c_master_recv(tx->c, buf, 1);
-	if (i != 1) {
-		dev_err(tx->ir->dev, "i2c_master_recv failed with %d\n", ret);
-		return -EFAULT;
-	}
-	if (buf[0] != 0x80) {
-		dev_err(tx->ir->dev, "unexpected IR TX response #2: %02x\n",
-			buf[0]);
-		return -EFAULT;
-	}
-
-	/* Oh good, it worked */
-	dev_dbg(tx->ir->dev, "sent code %u, key %u\n", code, key);
-	return 0;
-}
-
-/*
- * Write a code to the device.  We take in a 32-bit number (an int) and then
- * decode this to a codeset/key index.  The key data is then decompressed and
- * sent to the device.  We have a spin lock as per i2c documentation to prevent
- * multiple concurrent sends which would probably cause the device to explode.
- */
-static ssize_t write(struct file *filep, const char __user *buf, size_t n,
-		     loff_t *ppos)
-{
-	struct IR *ir = lirc_get_pdata(filep);
-	struct IR_tx *tx;
-	size_t i;
-	int failures = 0;
-
-	/* Validate user parameters */
-	if (n % sizeof(int))
-		return -EINVAL;
-
-	/* Get a struct IR_tx reference */
-	tx = get_ir_tx(ir);
-	if (!tx)
-		return -ENXIO;
-
-	/* Ensure our tx->c i2c_client remains valid for the duration */
-	mutex_lock(&tx->client_lock);
-	if (!tx->c) {
-		mutex_unlock(&tx->client_lock);
-		put_ir_tx(tx, false);
-		return -ENXIO;
-	}
-
-	/* Lock i2c bus for the duration */
-	mutex_lock(&ir->ir_lock);
-
-	/* Send each keypress */
-	for (i = 0; i < n;) {
-		int ret = 0;
-		int command;
-
-		if (copy_from_user(&command, buf + i, sizeof(command))) {
-			mutex_unlock(&ir->ir_lock);
-			mutex_unlock(&tx->client_lock);
-			put_ir_tx(tx, false);
-			return -EFAULT;
-		}
-
-		/* Send boot data first if required */
-		if (tx->need_boot == 1) {
-			/* Make sure we have the 'firmware' loaded, first */
-			ret = fw_load(tx);
-			if (ret != 0) {
-				mutex_unlock(&ir->ir_lock);
-				mutex_unlock(&tx->client_lock);
-				put_ir_tx(tx, false);
-				if (ret != -ENOMEM)
-					ret = -EIO;
-				return ret;
-			}
-			/* Prep the chip for transmitting codes */
-			ret = send_boot_data(tx);
-			if (ret == 0)
-				tx->need_boot = 0;
-		}
-
-		/* Send the code */
-		if (ret == 0) {
-			ret = send_code(tx, (unsigned int)command >> 16,
-					    (unsigned int)command & 0xFFFF);
-			if (ret == -EPROTO) {
-				mutex_unlock(&ir->ir_lock);
-				mutex_unlock(&tx->client_lock);
-				put_ir_tx(tx, false);
-				return ret;
-			}
-		}
-
-		/*
-		 * Hmm, a failure.  If we've had a few then give up, otherwise
-		 * try a reset
-		 */
-		if (ret != 0) {
-			/* Looks like the chip crashed, reset it */
-			dev_err(tx->ir->dev,
-				"sending to the IR transmitter chip failed, trying reset\n");
-
-			if (failures >= 3) {
-				dev_err(tx->ir->dev,
-					"unable to send to the IR chip after 3 resets, giving up\n");
-				mutex_unlock(&ir->ir_lock);
-				mutex_unlock(&tx->client_lock);
-				put_ir_tx(tx, false);
-				return ret;
-			}
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout((100 * HZ + 999) / 1000);
-			tx->need_boot = 1;
-			++failures;
-		} else {
-			i += sizeof(int);
-		}
-	}
-
-	/* Release i2c bus */
-	mutex_unlock(&ir->ir_lock);
-
-	mutex_unlock(&tx->client_lock);
-
-	/* Give back our struct IR_tx reference */
-	put_ir_tx(tx, false);
-
-	/* All looks good */
-	return n;
-}
-
-/* copied from lirc_dev */
-static __poll_t poll(struct file *filep, poll_table *wait)
-{
-	struct IR *ir = lirc_get_pdata(filep);
-	struct IR_rx *rx;
-	struct lirc_buffer *rbuf = ir->l->buf;
-	__poll_t ret;
-
-	dev_dbg(ir->dev, "%s called\n", __func__);
-
-	rx = get_ir_rx(ir);
-	if (!rx) {
-		/*
-		 * Revisit this, if our poll function ever reports writeable
-		 * status for Tx
-		 */
-		dev_dbg(ir->dev, "%s result = POLLERR\n", __func__);
-		return POLLERR;
-	}
-
-	/*
-	 * Add our lirc_buffer's wait_queue to the poll_table. A wake up on
-	 * that buffer's wait queue indicates we may have a new poll status.
-	 */
-	poll_wait(filep, &rbuf->wait_poll, wait);
-
-	/* Indicate what ops could happen immediately without blocking */
-	ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN | POLLRDNORM);
-
-	dev_dbg(ir->dev, "%s result = %s\n", __func__,
-		ret ? "POLLIN|POLLRDNORM" : "none");
-	return ret;
-}
-
-static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
-{
-	struct IR *ir = lirc_get_pdata(filep);
-	unsigned long __user *uptr = (unsigned long __user *)arg;
-	int result;
-	unsigned long mode, features;
-
-	features = ir->l->features;
-
-	switch (cmd) {
-	case LIRC_GET_LENGTH:
-		result = put_user(13UL, uptr);
-		break;
-	case LIRC_GET_FEATURES:
-		result = put_user(features, uptr);
-		break;
-	case LIRC_GET_REC_MODE:
-		if (!(features & LIRC_CAN_REC_MASK))
-			return -ENOTTY;
-
-		result = put_user(LIRC_REC2MODE
-				  (features & LIRC_CAN_REC_MASK),
-				  uptr);
-		break;
-	case LIRC_SET_REC_MODE:
-		if (!(features & LIRC_CAN_REC_MASK))
-			return -ENOTTY;
-
-		result = get_user(mode, uptr);
-		if (!result && !(LIRC_MODE2REC(mode) & features))
-			result = -ENOTTY;
-		break;
-	case LIRC_GET_SEND_MODE:
-		if (!(features & LIRC_CAN_SEND_MASK))
-			return -ENOTTY;
-
-		result = put_user(LIRC_MODE_LIRCCODE, uptr);
-		break;
-	case LIRC_SET_SEND_MODE:
-		if (!(features & LIRC_CAN_SEND_MASK))
-			return -ENOTTY;
-
-		result = get_user(mode, uptr);
-		if (!result && mode != LIRC_MODE_LIRCCODE)
-			return -EINVAL;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return result;
-}
-
-/*
- * Open the IR device.
- */
-static int open(struct inode *node, struct file *filep)
-{
-	struct IR *ir;
-
-	lirc_init_pdata(node, filep);
-	ir = lirc_get_pdata(filep);
-
-	atomic_inc(&ir->open_count);
-
-	nonseekable_open(node, filep);
-	return 0;
-}
-
-/* Close the IR device */
-static int close(struct inode *node, struct file *filep)
-{
-	struct IR *ir = lirc_get_pdata(filep);
-
-	atomic_dec(&ir->open_count);
-
-	put_ir_device(ir, false);
-	return 0;
-}
-
-static int ir_remove(struct i2c_client *client);
-static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id);
-
-#define ID_FLAG_TX	0x01
-#define ID_FLAG_HDPVR	0x02
-
-static const struct i2c_device_id ir_transceiver_id[] = {
-	{ "ir_tx_z8f0811_haup",  ID_FLAG_TX                 },
-	{ "ir_rx_z8f0811_haup",  0                          },
-	{ "ir_tx_z8f0811_hdpvr", ID_FLAG_HDPVR | ID_FLAG_TX },
-	{ "ir_rx_z8f0811_hdpvr", ID_FLAG_HDPVR              },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, ir_transceiver_id);
-
-static struct i2c_driver driver = {
-	.driver = {
-		.name	= "Zilog/Hauppauge i2c IR",
-	},
-	.probe		= ir_probe,
-	.remove		= ir_remove,
-	.id_table	= ir_transceiver_id,
-};
-
-static const struct file_operations lirc_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.read		= read,
-	.write		= write,
-	.poll		= poll,
-	.unlocked_ioctl	= ioctl,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl	= ioctl,
-#endif
-	.open		= open,
-	.release	= close
-};
-
-static int ir_remove(struct i2c_client *client)
-{
-	if (strncmp("ir_tx_z8", client->name, 8) == 0) {
-		struct IR_tx *tx = i2c_get_clientdata(client);
-
-		if (tx) {
-			mutex_lock(&tx->client_lock);
-			tx->c = NULL;
-			mutex_unlock(&tx->client_lock);
-			put_ir_tx(tx, false);
-		}
-	} else if (strncmp("ir_rx_z8", client->name, 8) == 0) {
-		struct IR_rx *rx = i2c_get_clientdata(client);
-
-		if (rx) {
-			mutex_lock(&rx->client_lock);
-			rx->c = NULL;
-			mutex_unlock(&rx->client_lock);
-			put_ir_rx(rx, false);
-		}
-	}
-	return 0;
-}
-
-/* ir_devices_lock must be held */
-static struct IR *get_ir_device_by_adapter(struct i2c_adapter *adapter)
-{
-	struct IR *ir;
-
-	if (list_empty(&ir_devices_list))
-		return NULL;
-
-	list_for_each_entry(ir, &ir_devices_list, list)
-		if (ir->adapter == adapter) {
-			get_ir_device(ir, true);
-			return ir;
-		}
-
-	return NULL;
-}
-
-static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
-	struct IR *ir;
-	struct IR_tx *tx;
-	struct IR_rx *rx;
-	struct i2c_adapter *adap = client->adapter;
-	int ret;
-	bool tx_probe = false;
-
-	dev_dbg(&client->dev, "%s: %s on i2c-%d (%s), client addr=0x%02x\n",
-		__func__, id->name, adap->nr, adap->name, client->addr);
-
-	/*
-	 * The IR receiver    is at i2c address 0x71.
-	 * The IR transmitter is at i2c address 0x70.
-	 */
-
-	if (id->driver_data & ID_FLAG_TX)
-		tx_probe = true;
-	else if (tx_only) /* module option */
-		return -ENXIO;
-
-	pr_info("probing IR %s on %s (i2c-%d)\n",
-		tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
-
-	mutex_lock(&ir_devices_lock);
-
-	/* Use a single struct IR instance for both the Rx and Tx functions */
-	ir = get_ir_device_by_adapter(adap);
-	if (!ir) {
-		ir = kzalloc(sizeof(*ir), GFP_KERNEL);
-		if (!ir) {
-			ret = -ENOMEM;
-			goto out_no_ir;
-		}
-		kref_init(&ir->ref);
-
-		/* store for use in ir_probe() again, and open() later on */
-		INIT_LIST_HEAD(&ir->list);
-		list_add_tail(&ir->list, &ir_devices_list);
-
-		ir->adapter = adap;
-		ir->dev = &adap->dev;
-		mutex_init(&ir->ir_lock);
-		atomic_set(&ir->open_count, 0);
-		spin_lock_init(&ir->tx_ref_lock);
-		spin_lock_init(&ir->rx_ref_lock);
-
-		/* set lirc_dev stuff */
-		ir->l = lirc_allocate_device();
-		if (!ir->l) {
-			ret = -ENOMEM;
-			goto out_put_ir;
-		}
-
-		snprintf(ir->l->name, sizeof(ir->l->name), "lirc_zilog");
-		ir->l->code_length = 13;
-		ir->l->fops = &lirc_fops;
-		ir->l->owner = THIS_MODULE;
-		ir->l->dev.parent = &adap->dev;
-
-		/*
-		 * FIXME this is a pointer reference to us, but no refcount.
-		 *
-		 * This OK for now, since lirc_dev currently won't touch this
-		 * buffer as we provide our own lirc_fops.
-		 *
-		 * Currently our own lirc_fops rely on this ir->l->buf pointer
-		 */
-		ir->l->buf = &ir->rbuf;
-		/* This will be returned by lirc_get_pdata() */
-		ir->l->data = ir;
-		ret = lirc_buffer_init(ir->l->buf, 2, BUFLEN / 2);
-		if (ret) {
-			lirc_free_device(ir->l);
-			ir->l = NULL;
-			goto out_put_ir;
-		}
-	}
-
-	if (tx_probe) {
-		/* Get the IR_rx instance for later, if already allocated */
-		rx = get_ir_rx(ir);
-
-		/* Set up a struct IR_tx instance */
-		tx = kzalloc(sizeof(*tx), GFP_KERNEL);
-		if (!tx) {
-			ret = -ENOMEM;
-			goto out_put_xx;
-		}
-		kref_init(&tx->ref);
-		ir->tx = tx;
-
-		ir->l->features |= LIRC_CAN_SEND_LIRCCODE;
-		mutex_init(&tx->client_lock);
-		tx->c = client;
-		tx->need_boot = 1;
-		tx->post_tx_ready_poll =
-			       (id->driver_data & ID_FLAG_HDPVR) ? false : true;
-
-		/* An ir ref goes to the struct IR_tx instance */
-		tx->ir = get_ir_device(ir, true);
-
-		/* A tx ref goes to the i2c_client */
-		i2c_set_clientdata(client, get_ir_tx(ir));
-
-		/*
-		 * Load the 'firmware'.  We do this before registering with
-		 * lirc_dev, so the first firmware load attempt does not happen
-		 * after a open() or write() call on the device.
-		 *
-		 * Failure here is not deemed catastrophic, so the receiver will
-		 * still be usable.  Firmware load will be retried in write(),
-		 * if it is needed.
-		 */
-		fw_load(tx);
-
-		/* Proceed only if the Rx client is also ready or not needed */
-		if (!rx && !tx_only) {
-			dev_info(tx->ir->dev,
-				 "probe of IR Tx on %s (i2c-%d) done. Waiting on IR Rx.\n",
-				 adap->name, adap->nr);
-			goto out_ok;
-		}
-	} else {
-		/* Get the IR_tx instance for later, if already allocated */
-		tx = get_ir_tx(ir);
-
-		/* Set up a struct IR_rx instance */
-		rx = kzalloc(sizeof(*rx), GFP_KERNEL);
-		if (!rx) {
-			ret = -ENOMEM;
-			goto out_put_xx;
-		}
-		kref_init(&rx->ref);
-		ir->rx = rx;
-
-		ir->l->features |= LIRC_CAN_REC_LIRCCODE;
-		mutex_init(&rx->client_lock);
-		rx->c = client;
-		rx->hdpvr_data_fmt =
-			       (id->driver_data & ID_FLAG_HDPVR) ? true : false;
-
-		/* An ir ref goes to the struct IR_rx instance */
-		rx->ir = get_ir_device(ir, true);
-
-		/* An rx ref goes to the i2c_client */
-		i2c_set_clientdata(client, get_ir_rx(ir));
-
-		/*
-		 * Start the polling thread.
-		 * It will only perform an empty loop around schedule_timeout()
-		 * until we register with lirc_dev and the first user open()
-		 */
-		/* An ir ref goes to the new rx polling kthread */
-		rx->task = kthread_run(lirc_thread, get_ir_device(ir, true),
-				       "zilog-rx-i2c-%d", adap->nr);
-		if (IS_ERR(rx->task)) {
-			ret = PTR_ERR(rx->task);
-			dev_err(tx->ir->dev,
-				"%s: could not start IR Rx polling thread\n",
-				__func__);
-			/* Failed kthread, so put back the ir ref */
-			put_ir_device(ir, true);
-			/* Failure exit, so put back rx ref from i2c_client */
-			i2c_set_clientdata(client, NULL);
-			put_ir_rx(rx, true);
-			ir->l->features &= ~LIRC_CAN_REC_LIRCCODE;
-			goto out_put_tx;
-		}
-
-		/* Proceed only if the Tx client is also ready */
-		if (!tx) {
-			pr_info("probe of IR Rx on %s (i2c-%d) done. Waiting on IR Tx.\n",
-				adap->name, adap->nr);
-			goto out_ok;
-		}
-	}
-
-	/* register with lirc */
-	ret = lirc_register_device(ir->l);
-	if (ret < 0) {
-		dev_err(tx->ir->dev,
-			"%s: lirc_register_device() failed: %i\n",
-			__func__, ret);
-		lirc_free_device(ir->l);
-		ir->l = NULL;
-		goto out_put_xx;
-	}
-
-	dev_info(ir->dev,
-		 "IR unit on %s (i2c-%d) registered as lirc%d and ready\n",
-		 adap->name, adap->nr, ir->l->minor);
-
-out_ok:
-	if (rx)
-		put_ir_rx(rx, true);
-	if (tx)
-		put_ir_tx(tx, true);
-	put_ir_device(ir, true);
-	dev_info(ir->dev,
-		 "probe of IR %s on %s (i2c-%d) done\n",
-		 tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
-	mutex_unlock(&ir_devices_lock);
-	return 0;
-
-out_put_xx:
-	if (rx)
-		put_ir_rx(rx, true);
-out_put_tx:
-	if (tx)
-		put_ir_tx(tx, true);
-out_put_ir:
-	put_ir_device(ir, true);
-out_no_ir:
-	dev_err(&client->dev,
-		"%s: probing IR %s on %s (i2c-%d) failed with %d\n",
-		__func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr, ret);
-	mutex_unlock(&ir_devices_lock);
-	return ret;
-}
-
-static int __init zilog_init(void)
-{
-	int ret;
-
-	pr_notice("Zilog/Hauppauge IR driver initializing\n");
-
-	mutex_init(&tx_data_lock);
-
-	request_module("firmware_class");
-
-	ret = i2c_add_driver(&driver);
-	if (ret)
-		pr_err("initialization failed\n");
-	else
-		pr_notice("initialization complete\n");
-
-	return ret;
-}
-
-static void __exit zilog_exit(void)
-{
-	i2c_del_driver(&driver);
-	/* if loaded */
-	fw_unload();
-	pr_notice("Zilog/Hauppauge IR driver unloaded\n");
-}
-
-module_init(zilog_init);
-module_exit(zilog_exit);
-
-MODULE_DESCRIPTION("Zilog/Hauppauge infrared transmitter driver (i2c stack)");
-MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller, Stefan Jahn, Jerome Brock, Mark Weaver, Andy Walls");
-MODULE_LICENSE("GPL");
-/* for compat with old name, which isn't all that accurate anymore */
-MODULE_ALIAS("lirc_pvr150");
-
-module_param(debug, bool, 0644);
-MODULE_PARM_DESC(debug, "Enable debugging messages");
-
-module_param(tx_only, bool, 0644);
-MODULE_PARM_DESC(tx_only, "Only handle the IR transmit function");
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index c26c99fd..b1036ba 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -893,7 +893,7 @@ void omap4iss_put(struct iss_device *iss)
 		return;
 
 	mutex_lock(&iss->iss_mutex);
-	BUG_ON(iss->ref_count == 0);
+	WARN_ON(iss->ref_count == 0);
 	if (--iss->ref_count == 0) {
 		iss_disable_interrupts(iss);
 		/* Reset the ISS if an entity has failed to stop. This is the
diff --git a/drivers/staging/media/tegra-vde/Kconfig b/drivers/staging/media/tegra-vde/Kconfig
new file mode 100644
index 0000000..5c49146
--- /dev/null
+++ b/drivers/staging/media/tegra-vde/Kconfig
@@ -0,0 +1,8 @@
+config TEGRA_VDE
+	tristate "NVIDIA Tegra Video Decoder Engine driver"
+	depends on ARCH_TEGRA || COMPILE_TEST
+	select DMA_SHARED_BUFFER
+	select SRAM
+	help
+	    Say Y here to enable support for the NVIDIA Tegra video decoder
+	    driver.
diff --git a/drivers/staging/media/tegra-vde/Makefile b/drivers/staging/media/tegra-vde/Makefile
new file mode 100644
index 0000000..444c1d6
--- /dev/null
+++ b/drivers/staging/media/tegra-vde/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TEGRA_VDE)	+= tegra-vde.o
diff --git a/drivers/staging/media/tegra-vde/TODO b/drivers/staging/media/tegra-vde/TODO
new file mode 100644
index 0000000..31aaa3e
--- /dev/null
+++ b/drivers/staging/media/tegra-vde/TODO
@@ -0,0 +1,4 @@
+TODO:
+	- Implement V4L2 API once it gains support for stateless decoders.
+
+Contact: Dmitry Osipenko <digetx@gmail.com>
diff --git a/drivers/staging/media/tegra-vde/tegra-vde.c b/drivers/staging/media/tegra-vde/tegra-vde.c
new file mode 100644
index 0000000..c47659e
--- /dev/null
+++ b/drivers/staging/media/tegra-vde/tegra-vde.c
@@ -0,0 +1,1213 @@
+/*
+ * NVIDIA Tegra Video decoder driver
+ *
+ * Copyright (C) 2016-2017 Dmitry Osipenko <digetx@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-buf.h>
+#include <linux/genalloc.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include <soc/tegra/pmc.h>
+
+#include "uapi.h"
+
+#define ICMDQUE_WR		0x00
+#define CMDQUE_CONTROL		0x08
+#define INTR_STATUS		0x18
+#define BSE_INT_ENB		0x40
+#define BSE_CONFIG		0x44
+
+#define BSE_ICMDQUE_EMPTY	BIT(3)
+#define BSE_DMA_BUSY		BIT(23)
+
+#define VDE_WR(__data, __addr)				\
+do {							\
+	dev_dbg(vde->miscdev.parent,			\
+		"%s: %d: 0x%08X => " #__addr ")\n",	\
+		__func__, __LINE__, (u32)(__data));	\
+	writel_relaxed(__data, __addr);			\
+} while (0)
+
+struct video_frame {
+	struct dma_buf_attachment *y_dmabuf_attachment;
+	struct dma_buf_attachment *cb_dmabuf_attachment;
+	struct dma_buf_attachment *cr_dmabuf_attachment;
+	struct dma_buf_attachment *aux_dmabuf_attachment;
+	struct sg_table *y_sgt;
+	struct sg_table *cb_sgt;
+	struct sg_table *cr_sgt;
+	struct sg_table *aux_sgt;
+	dma_addr_t y_addr;
+	dma_addr_t cb_addr;
+	dma_addr_t cr_addr;
+	dma_addr_t aux_addr;
+	u32 frame_num;
+	u32 flags;
+};
+
+struct tegra_vde {
+	void __iomem *sxe;
+	void __iomem *bsev;
+	void __iomem *mbe;
+	void __iomem *ppe;
+	void __iomem *mce;
+	void __iomem *tfe;
+	void __iomem *ppb;
+	void __iomem *vdma;
+	void __iomem *frameid;
+	struct mutex lock;
+	struct miscdevice miscdev;
+	struct reset_control *rst;
+	struct gen_pool *iram_pool;
+	struct completion decode_completion;
+	struct clk *clk;
+	dma_addr_t iram_lists_addr;
+	u32 *iram;
+};
+
+static void tegra_vde_set_bits(struct tegra_vde *vde,
+			       u32 mask, void __iomem *regs)
+{
+	u32 value = readl_relaxed(regs);
+
+	VDE_WR(value | mask, regs);
+}
+
+static int tegra_vde_wait_mbe(struct tegra_vde *vde)
+{
+	u32 tmp;
+
+	return readl_relaxed_poll_timeout(vde->mbe + 0x8C, tmp,
+					  (tmp >= 0x10), 1, 100);
+}
+
+static int tegra_vde_setup_mbe_frame_idx(struct tegra_vde *vde,
+					 unsigned int refs_nb,
+					 bool setup_refs)
+{
+	u32 frame_idx_enb_mask = 0;
+	u32 value;
+	unsigned int frame_idx;
+	unsigned int idx;
+	int err;
+
+	VDE_WR(0xD0000000 | (0 << 23), vde->mbe + 0x80);
+	VDE_WR(0xD0200000 | (0 << 23), vde->mbe + 0x80);
+
+	err = tegra_vde_wait_mbe(vde);
+	if (err)
+		return err;
+
+	if (!setup_refs)
+		return 0;
+
+	for (idx = 0, frame_idx = 1; idx < refs_nb; idx++, frame_idx++) {
+		VDE_WR(0xD0000000 | (frame_idx << 23), vde->mbe + 0x80);
+		VDE_WR(0xD0200000 | (frame_idx << 23), vde->mbe + 0x80);
+
+		frame_idx_enb_mask |= frame_idx << (6 * (idx % 4));
+
+		if (idx % 4 == 3 || idx == refs_nb - 1) {
+			value = 0xC0000000;
+			value |= (idx >> 2) << 24;
+			value |= frame_idx_enb_mask;
+
+			VDE_WR(value, vde->mbe + 0x80);
+
+			err = tegra_vde_wait_mbe(vde);
+			if (err)
+				return err;
+
+			frame_idx_enb_mask = 0;
+		}
+	}
+
+	return 0;
+}
+
+static void tegra_vde_mbe_set_0xa_reg(struct tegra_vde *vde, int reg, u32 val)
+{
+	VDE_WR(0xA0000000 | (reg << 24) | (val & 0xFFFF), vde->mbe + 0x80);
+	VDE_WR(0xA0000000 | ((reg + 1) << 24) | (val >> 16), vde->mbe + 0x80);
+}
+
+static int tegra_vde_wait_bsev(struct tegra_vde *vde, bool wait_dma)
+{
+	struct device *dev = vde->miscdev.parent;
+	u32 value;
+	int err;
+
+	err = readl_relaxed_poll_timeout(vde->bsev + INTR_STATUS, value,
+					 !(value & BIT(2)), 1, 100);
+	if (err) {
+		dev_err(dev, "BSEV unknown bit timeout\n");
+		return err;
+	}
+
+	err = readl_relaxed_poll_timeout(vde->bsev + INTR_STATUS, value,
+					 (value & BSE_ICMDQUE_EMPTY), 1, 100);
+	if (err) {
+		dev_err(dev, "BSEV ICMDQUE flush timeout\n");
+		return err;
+	}
+
+	if (!wait_dma)
+		return 0;
+
+	err = readl_relaxed_poll_timeout(vde->bsev + INTR_STATUS, value,
+					 !(value & BSE_DMA_BUSY), 1, 100);
+	if (err) {
+		dev_err(dev, "BSEV DMA timeout\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static int tegra_vde_push_to_bsev_icmdqueue(struct tegra_vde *vde,
+					    u32 value, bool wait_dma)
+{
+	VDE_WR(value, vde->bsev + ICMDQUE_WR);
+
+	return tegra_vde_wait_bsev(vde, wait_dma);
+}
+
+static void tegra_vde_setup_frameid(struct tegra_vde *vde,
+				    struct video_frame *frame,
+				    unsigned int frameid,
+				    u32 mbs_width, u32 mbs_height)
+{
+	u32 y_addr  = frame ? frame->y_addr  : 0x6CDEAD00;
+	u32 cb_addr = frame ? frame->cb_addr : 0x6CDEAD00;
+	u32 cr_addr = frame ? frame->cr_addr : 0x6CDEAD00;
+	u32 value1 = frame ? ((mbs_width << 16) | mbs_height) : 0;
+	u32 value2 = frame ? ((((mbs_width + 1) >> 1) << 6) | 1) : 0;
+
+	VDE_WR(y_addr  >> 8, vde->frameid + 0x000 + frameid * 4);
+	VDE_WR(cb_addr >> 8, vde->frameid + 0x100 + frameid * 4);
+	VDE_WR(cr_addr >> 8, vde->frameid + 0x180 + frameid * 4);
+	VDE_WR(value1,       vde->frameid + 0x080 + frameid * 4);
+	VDE_WR(value2,       vde->frameid + 0x280 + frameid * 4);
+}
+
+static void tegra_setup_frameidx(struct tegra_vde *vde,
+				 struct video_frame *frames,
+				 unsigned int frames_nb,
+				 u32 mbs_width, u32 mbs_height)
+{
+	unsigned int idx;
+
+	for (idx = 0; idx < frames_nb; idx++)
+		tegra_vde_setup_frameid(vde, &frames[idx], idx,
+					mbs_width, mbs_height);
+
+	for (; idx < 17; idx++)
+		tegra_vde_setup_frameid(vde, NULL, idx, 0, 0);
+}
+
+static void tegra_vde_setup_iram_entry(struct tegra_vde *vde,
+				       unsigned int table,
+				       unsigned int row,
+				       u32 value1, u32 value2)
+{
+	u32 *iram_tables = vde->iram;
+
+	dev_dbg(vde->miscdev.parent, "IRAM table %u: row %u: 0x%08X 0x%08X\n",
+		table, row, value1, value2);
+
+	iram_tables[0x20 * table + row * 2] = value1;
+	iram_tables[0x20 * table + row * 2 + 1] = value2;
+}
+
+static void tegra_vde_setup_iram_tables(struct tegra_vde *vde,
+					struct video_frame *dpb_frames,
+					unsigned int ref_frames_nb,
+					unsigned int with_earlier_poc_nb)
+{
+	struct video_frame *frame;
+	u32 value, aux_addr;
+	int with_later_poc_nb;
+	unsigned int i, k;
+
+	dev_dbg(vde->miscdev.parent, "DPB: Frame 0: frame_num = %d\n",
+		dpb_frames[0].frame_num);
+
+	dev_dbg(vde->miscdev.parent, "REF L0:\n");
+
+	for (i = 0; i < 16; i++) {
+		if (i < ref_frames_nb) {
+			frame = &dpb_frames[i + 1];
+
+			aux_addr = frame->aux_addr;
+
+			value  = (i + 1) << 26;
+			value |= !(frame->flags & FLAG_B_FRAME) << 25;
+			value |= 1 << 24;
+			value |= frame->frame_num;
+
+			dev_dbg(vde->miscdev.parent,
+				"\tFrame %d: frame_num = %d B_frame = %d\n",
+				i + 1, frame->frame_num,
+				(frame->flags & FLAG_B_FRAME));
+		} else {
+			aux_addr = 0x6ADEAD00;
+			value = 0;
+		}
+
+		tegra_vde_setup_iram_entry(vde, 0, i, value, aux_addr);
+		tegra_vde_setup_iram_entry(vde, 1, i, value, aux_addr);
+		tegra_vde_setup_iram_entry(vde, 2, i, value, aux_addr);
+		tegra_vde_setup_iram_entry(vde, 3, i, value, aux_addr);
+	}
+
+	if (!(dpb_frames[0].flags & FLAG_B_FRAME))
+		return;
+
+	if (with_earlier_poc_nb >= ref_frames_nb)
+		return;
+
+	with_later_poc_nb = ref_frames_nb - with_earlier_poc_nb;
+
+	dev_dbg(vde->miscdev.parent,
+		"REF L1: with_later_poc_nb %d with_earlier_poc_nb %d\n",
+		 with_later_poc_nb, with_earlier_poc_nb);
+
+	for (i = 0, k = with_earlier_poc_nb; i < with_later_poc_nb; i++, k++) {
+		frame = &dpb_frames[k + 1];
+
+		aux_addr = frame->aux_addr;
+
+		value  = (k + 1) << 26;
+		value |= !(frame->flags & FLAG_B_FRAME) << 25;
+		value |= 1 << 24;
+		value |= frame->frame_num;
+
+		dev_dbg(vde->miscdev.parent,
+			"\tFrame %d: frame_num = %d\n",
+			k + 1, frame->frame_num);
+
+		tegra_vde_setup_iram_entry(vde, 2, i, value, aux_addr);
+	}
+
+	for (k = 0; i < ref_frames_nb; i++, k++) {
+		frame = &dpb_frames[k + 1];
+
+		aux_addr = frame->aux_addr;
+
+		value  = (k + 1) << 26;
+		value |= !(frame->flags & FLAG_B_FRAME) << 25;
+		value |= 1 << 24;
+		value |= frame->frame_num;
+
+		dev_dbg(vde->miscdev.parent,
+			"\tFrame %d: frame_num = %d\n",
+			k + 1, frame->frame_num);
+
+		tegra_vde_setup_iram_entry(vde, 2, i, value, aux_addr);
+	}
+}
+
+static int tegra_vde_setup_hw_context(struct tegra_vde *vde,
+				      struct tegra_vde_h264_decoder_ctx *ctx,
+				      struct video_frame *dpb_frames,
+				      dma_addr_t bitstream_data_addr,
+				      size_t bitstream_data_size,
+				      unsigned int macroblocks_nb)
+{
+	struct device *dev = vde->miscdev.parent;
+	u32 value;
+	int err;
+
+	tegra_vde_set_bits(vde, 0x000A, vde->sxe + 0xF0);
+	tegra_vde_set_bits(vde, 0x000B, vde->bsev + CMDQUE_CONTROL);
+	tegra_vde_set_bits(vde, 0x8002, vde->mbe + 0x50);
+	tegra_vde_set_bits(vde, 0x000A, vde->mbe + 0xA0);
+	tegra_vde_set_bits(vde, 0x000A, vde->ppe + 0x14);
+	tegra_vde_set_bits(vde, 0x000A, vde->ppe + 0x28);
+	tegra_vde_set_bits(vde, 0x0A00, vde->mce + 0x08);
+	tegra_vde_set_bits(vde, 0x000A, vde->tfe + 0x00);
+	tegra_vde_set_bits(vde, 0x0005, vde->vdma + 0x04);
+
+	VDE_WR(0x00000000, vde->vdma + 0x1C);
+	VDE_WR(0x00000000, vde->vdma + 0x00);
+	VDE_WR(0x00000007, vde->vdma + 0x04);
+	VDE_WR(0x00000007, vde->frameid + 0x200);
+	VDE_WR(0x00000005, vde->tfe + 0x04);
+	VDE_WR(0x00000000, vde->mbe + 0x84);
+	VDE_WR(0x00000010, vde->sxe + 0x08);
+	VDE_WR(0x00000150, vde->sxe + 0x54);
+	VDE_WR(0x0000054C, vde->sxe + 0x58);
+	VDE_WR(0x00000E34, vde->sxe + 0x5C);
+	VDE_WR(0x063C063C, vde->mce + 0x10);
+	VDE_WR(0x0003FC00, vde->bsev + INTR_STATUS);
+	VDE_WR(0x0000150D, vde->bsev + BSE_CONFIG);
+	VDE_WR(0x00000100, vde->bsev + BSE_INT_ENB);
+	VDE_WR(0x00000000, vde->bsev + 0x98);
+	VDE_WR(0x00000060, vde->bsev + 0x9C);
+
+	memset(vde->iram + 128, 0, macroblocks_nb / 2);
+
+	tegra_setup_frameidx(vde, dpb_frames, ctx->dpb_frames_nb,
+			     ctx->pic_width_in_mbs, ctx->pic_height_in_mbs);
+
+	tegra_vde_setup_iram_tables(vde, dpb_frames,
+				    ctx->dpb_frames_nb - 1,
+				    ctx->dpb_ref_frames_with_earlier_poc_nb);
+	wmb();
+
+	VDE_WR(0x00000000, vde->bsev + 0x8C);
+	VDE_WR(bitstream_data_addr + bitstream_data_size,
+	       vde->bsev + 0x54);
+
+	value = ctx->pic_width_in_mbs << 11 | ctx->pic_height_in_mbs << 3;
+
+	VDE_WR(value, vde->bsev + 0x88);
+
+	err = tegra_vde_wait_bsev(vde, false);
+	if (err)
+		return err;
+
+	err = tegra_vde_push_to_bsev_icmdqueue(vde, 0x800003FC, false);
+	if (err)
+		return err;
+
+	value = 0x01500000;
+	value |= ((vde->iram_lists_addr + 512) >> 2) & 0xFFFF;
+
+	err = tegra_vde_push_to_bsev_icmdqueue(vde, value, true);
+	if (err)
+		return err;
+
+	err = tegra_vde_push_to_bsev_icmdqueue(vde, 0x840F054C, false);
+	if (err)
+		return err;
+
+	err = tegra_vde_push_to_bsev_icmdqueue(vde, 0x80000080, false);
+	if (err)
+		return err;
+
+	value = 0x0E340000 | ((vde->iram_lists_addr >> 2) & 0xFFFF);
+
+	err = tegra_vde_push_to_bsev_icmdqueue(vde, value, true);
+	if (err)
+		return err;
+
+	value = 0x00800005;
+	value |= ctx->pic_width_in_mbs << 11;
+	value |= ctx->pic_height_in_mbs << 3;
+
+	VDE_WR(value, vde->sxe + 0x10);
+
+	value = !ctx->baseline_profile << 17;
+	value |= ctx->level_idc << 13;
+	value |= ctx->log2_max_pic_order_cnt_lsb << 7;
+	value |= ctx->pic_order_cnt_type << 5;
+	value |= ctx->log2_max_frame_num;
+
+	VDE_WR(value, vde->sxe + 0x40);
+
+	value = ctx->pic_init_qp << 25;
+	value |= !!(ctx->deblocking_filter_control_present_flag) << 2;
+	value |= !!ctx->pic_order_present_flag;
+
+	VDE_WR(value, vde->sxe + 0x44);
+
+	value = ctx->chroma_qp_index_offset;
+	value |= ctx->num_ref_idx_l0_active_minus1 << 5;
+	value |= ctx->num_ref_idx_l1_active_minus1 << 10;
+	value |= !!ctx->constrained_intra_pred_flag << 15;
+
+	VDE_WR(value, vde->sxe + 0x48);
+
+	value = 0x0C000000;
+	value |= !!(dpb_frames[0].flags & FLAG_B_FRAME) << 24;
+
+	VDE_WR(value, vde->sxe + 0x4C);
+
+	value = 0x03800000;
+	value |= min_t(size_t, bitstream_data_size, SZ_1M);
+
+	VDE_WR(value, vde->sxe + 0x68);
+
+	VDE_WR(bitstream_data_addr, vde->sxe + 0x6C);
+
+	value = 0x10000005;
+	value |= ctx->pic_width_in_mbs << 11;
+	value |= ctx->pic_height_in_mbs << 3;
+
+	VDE_WR(value, vde->mbe + 0x80);
+
+	value = 0x26800000;
+	value |= ctx->level_idc << 4;
+	value |= !ctx->baseline_profile << 1;
+	value |= !!ctx->direct_8x8_inference_flag;
+
+	VDE_WR(value, vde->mbe + 0x80);
+
+	VDE_WR(0xF4000001, vde->mbe + 0x80);
+	VDE_WR(0x20000000, vde->mbe + 0x80);
+	VDE_WR(0xF4000101, vde->mbe + 0x80);
+
+	value = 0x20000000;
+	value |= ctx->chroma_qp_index_offset << 8;
+
+	VDE_WR(value, vde->mbe + 0x80);
+
+	err = tegra_vde_setup_mbe_frame_idx(vde,
+					    ctx->dpb_frames_nb - 1,
+					    ctx->pic_order_cnt_type == 0);
+	if (err) {
+		dev_err(dev, "MBE frames setup failed %d\n", err);
+		return err;
+	}
+
+	tegra_vde_mbe_set_0xa_reg(vde, 0, 0x000009FC);
+	tegra_vde_mbe_set_0xa_reg(vde, 2, 0x61DEAD00);
+	tegra_vde_mbe_set_0xa_reg(vde, 4, 0x62DEAD00);
+	tegra_vde_mbe_set_0xa_reg(vde, 6, 0x63DEAD00);
+	tegra_vde_mbe_set_0xa_reg(vde, 8, dpb_frames[0].aux_addr);
+
+	value = 0xFC000000;
+	value |= !!(dpb_frames[0].flags & FLAG_B_FRAME) << 2;
+
+	if (!ctx->baseline_profile)
+		value |= !!(dpb_frames[0].flags & FLAG_REFERENCE) << 1;
+
+	VDE_WR(value, vde->mbe + 0x80);
+
+	err = tegra_vde_wait_mbe(vde);
+	if (err) {
+		dev_err(dev, "MBE programming failed %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static void tegra_vde_decode_frame(struct tegra_vde *vde,
+				   unsigned int macroblocks_nb)
+{
+	reinit_completion(&vde->decode_completion);
+
+	VDE_WR(0x00000001, vde->bsev + 0x8C);
+	VDE_WR(0x20000000 | (macroblocks_nb - 1), vde->sxe + 0x00);
+}
+
+static void tegra_vde_detach_and_put_dmabuf(struct dma_buf_attachment *a,
+					    struct sg_table *sgt,
+					    enum dma_data_direction dma_dir)
+{
+	struct dma_buf *dmabuf = a->dmabuf;
+
+	dma_buf_unmap_attachment(a, sgt, dma_dir);
+	dma_buf_detach(dmabuf, a);
+	dma_buf_put(dmabuf);
+}
+
+static int tegra_vde_attach_dmabuf(struct device *dev,
+				   int fd,
+				   unsigned long offset,
+				   unsigned int min_size,
+				   struct dma_buf_attachment **a,
+				   dma_addr_t *addr,
+				   struct sg_table **s,
+				   size_t *size,
+				   enum dma_data_direction dma_dir)
+{
+	struct dma_buf_attachment *attachment;
+	struct dma_buf *dmabuf;
+	struct sg_table *sgt;
+	int err;
+
+	dmabuf = dma_buf_get(fd);
+	if (IS_ERR(dmabuf)) {
+		dev_err(dev, "Invalid dmabuf FD\n");
+		return PTR_ERR(dmabuf);
+	}
+
+	if ((u64)offset + min_size > dmabuf->size) {
+		dev_err(dev, "Too small dmabuf size %zu @0x%lX, "
+			     "should be at least %d\n",
+			dmabuf->size, offset, min_size);
+		return -EINVAL;
+	}
+
+	attachment = dma_buf_attach(dmabuf, dev);
+	if (IS_ERR(attachment)) {
+		dev_err(dev, "Failed to attach dmabuf\n");
+		err = PTR_ERR(attachment);
+		goto err_put;
+	}
+
+	sgt = dma_buf_map_attachment(attachment, dma_dir);
+	if (IS_ERR(sgt)) {
+		dev_err(dev, "Failed to get dmabufs sg_table\n");
+		err = PTR_ERR(sgt);
+		goto err_detach;
+	}
+
+	if (sgt->nents != 1) {
+		dev_err(dev, "Sparse DMA region is unsupported\n");
+		err = -EINVAL;
+		goto err_unmap;
+	}
+
+	*addr = sg_dma_address(sgt->sgl) + offset;
+	*a = attachment;
+	*s = sgt;
+
+	if (size)
+		*size = dmabuf->size - offset;
+
+	return 0;
+
+err_unmap:
+	dma_buf_unmap_attachment(attachment, sgt, dma_dir);
+err_detach:
+	dma_buf_detach(dmabuf, attachment);
+err_put:
+	dma_buf_put(dmabuf);
+
+	return err;
+}
+
+static int tegra_vde_attach_dmabufs_to_frame(struct device *dev,
+					     struct video_frame *frame,
+					     struct tegra_vde_h264_frame *src,
+					     enum dma_data_direction dma_dir,
+					     bool baseline_profile,
+					     size_t csize)
+{
+	int err;
+
+	err = tegra_vde_attach_dmabuf(dev, src->y_fd,
+				      src->y_offset, csize * 4,
+				      &frame->y_dmabuf_attachment,
+				      &frame->y_addr,
+				      &frame->y_sgt,
+				      NULL, dma_dir);
+	if (err)
+		return err;
+
+	err = tegra_vde_attach_dmabuf(dev, src->cb_fd,
+				      src->cb_offset, csize,
+				      &frame->cb_dmabuf_attachment,
+				      &frame->cb_addr,
+				      &frame->cb_sgt,
+				      NULL, dma_dir);
+	if (err)
+		goto err_release_y;
+
+	err = tegra_vde_attach_dmabuf(dev, src->cr_fd,
+				      src->cr_offset, csize,
+				      &frame->cr_dmabuf_attachment,
+				      &frame->cr_addr,
+				      &frame->cr_sgt,
+				      NULL, dma_dir);
+	if (err)
+		goto err_release_cb;
+
+	if (baseline_profile) {
+		frame->aux_addr = 0x64DEAD00;
+		return 0;
+	}
+
+	err = tegra_vde_attach_dmabuf(dev, src->aux_fd,
+				      src->aux_offset, csize,
+				      &frame->aux_dmabuf_attachment,
+				      &frame->aux_addr,
+				      &frame->aux_sgt,
+				      NULL, dma_dir);
+	if (err)
+		goto err_release_cr;
+
+	return 0;
+
+err_release_cr:
+	tegra_vde_detach_and_put_dmabuf(frame->cr_dmabuf_attachment,
+					frame->cr_sgt, dma_dir);
+err_release_cb:
+	tegra_vde_detach_and_put_dmabuf(frame->cb_dmabuf_attachment,
+					frame->cb_sgt, dma_dir);
+err_release_y:
+	tegra_vde_detach_and_put_dmabuf(frame->y_dmabuf_attachment,
+					frame->y_sgt, dma_dir);
+
+	return err;
+}
+
+static void tegra_vde_release_frame_dmabufs(struct video_frame *frame,
+					    enum dma_data_direction dma_dir,
+					    bool baseline_profile)
+{
+	if (!baseline_profile)
+		tegra_vde_detach_and_put_dmabuf(frame->aux_dmabuf_attachment,
+						frame->aux_sgt, dma_dir);
+
+	tegra_vde_detach_and_put_dmabuf(frame->cr_dmabuf_attachment,
+					frame->cr_sgt, dma_dir);
+
+	tegra_vde_detach_and_put_dmabuf(frame->cb_dmabuf_attachment,
+					frame->cb_sgt, dma_dir);
+
+	tegra_vde_detach_and_put_dmabuf(frame->y_dmabuf_attachment,
+					frame->y_sgt, dma_dir);
+}
+
+static int tegra_vde_validate_frame(struct device *dev,
+				    struct tegra_vde_h264_frame *frame)
+{
+	if (frame->frame_num > 0x7FFFFF) {
+		dev_err(dev, "Bad frame_num %u\n", frame->frame_num);
+		return -EINVAL;
+	}
+
+	if (frame->y_offset & 0xFF) {
+		dev_err(dev, "Bad y_offset 0x%X\n", frame->y_offset);
+		return -EINVAL;
+	}
+
+	if (frame->cb_offset & 0xFF) {
+		dev_err(dev, "Bad cb_offset 0x%X\n", frame->cb_offset);
+		return -EINVAL;
+	}
+
+	if (frame->cr_offset & 0xFF) {
+		dev_err(dev, "Bad cr_offset 0x%X\n", frame->cr_offset);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int tegra_vde_validate_h264_ctx(struct device *dev,
+				       struct tegra_vde_h264_decoder_ctx *ctx)
+{
+	if (ctx->dpb_frames_nb == 0 || ctx->dpb_frames_nb > 17) {
+		dev_err(dev, "Bad DPB size %u\n", ctx->dpb_frames_nb);
+		return -EINVAL;
+	}
+
+	if (ctx->level_idc > 15) {
+		dev_err(dev, "Bad level value %u\n", ctx->level_idc);
+		return -EINVAL;
+	}
+
+	if (ctx->pic_init_qp > 52) {
+		dev_err(dev, "Bad pic_init_qp value %u\n", ctx->pic_init_qp);
+		return -EINVAL;
+	}
+
+	if (ctx->log2_max_pic_order_cnt_lsb > 16) {
+		dev_err(dev, "Bad log2_max_pic_order_cnt_lsb value %u\n",
+			ctx->log2_max_pic_order_cnt_lsb);
+		return -EINVAL;
+	}
+
+	if (ctx->log2_max_frame_num > 16) {
+		dev_err(dev, "Bad log2_max_frame_num value %u\n",
+			ctx->log2_max_frame_num);
+		return -EINVAL;
+	}
+
+	if (ctx->chroma_qp_index_offset > 31) {
+		dev_err(dev, "Bad chroma_qp_index_offset value %u\n",
+			ctx->chroma_qp_index_offset);
+		return -EINVAL;
+	}
+
+	if (ctx->pic_order_cnt_type > 2) {
+		dev_err(dev, "Bad pic_order_cnt_type value %u\n",
+			ctx->pic_order_cnt_type);
+		return -EINVAL;
+	}
+
+	if (ctx->num_ref_idx_l0_active_minus1 > 15) {
+		dev_err(dev, "Bad num_ref_idx_l0_active_minus1 value %u\n",
+			ctx->num_ref_idx_l0_active_minus1);
+		return -EINVAL;
+	}
+
+	if (ctx->num_ref_idx_l1_active_minus1 > 15) {
+		dev_err(dev, "Bad num_ref_idx_l1_active_minus1 value %u\n",
+			ctx->num_ref_idx_l1_active_minus1);
+		return -EINVAL;
+	}
+
+	if (!ctx->pic_width_in_mbs || ctx->pic_width_in_mbs > 127) {
+		dev_err(dev, "Bad pic_width_in_mbs value %u\n",
+			ctx->pic_width_in_mbs);
+		return -EINVAL;
+	}
+
+	if (!ctx->pic_height_in_mbs || ctx->pic_height_in_mbs > 127) {
+		dev_err(dev, "Bad pic_height_in_mbs value %u\n",
+			ctx->pic_height_in_mbs);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde,
+				       unsigned long vaddr)
+{
+	struct device *dev = vde->miscdev.parent;
+	struct tegra_vde_h264_decoder_ctx ctx;
+	struct tegra_vde_h264_frame frames[17];
+	struct tegra_vde_h264_frame __user *frames_user;
+	struct video_frame *dpb_frames;
+	struct dma_buf_attachment *bitstream_data_dmabuf_attachment;
+	struct sg_table *bitstream_sgt;
+	enum dma_data_direction dma_dir;
+	dma_addr_t bitstream_data_addr;
+	dma_addr_t bsev_ptr;
+	size_t bitstream_data_size;
+	unsigned int macroblocks_nb;
+	unsigned int read_bytes;
+	unsigned int i;
+	long timeout;
+	int ret, err;
+
+	if (copy_from_user(&ctx, (void __user *)vaddr, sizeof(ctx)))
+		return -EFAULT;
+
+	ret = tegra_vde_validate_h264_ctx(dev, &ctx);
+	if (ret)
+		return ret;
+
+	ret = tegra_vde_attach_dmabuf(dev, ctx.bitstream_data_fd,
+				      ctx.bitstream_data_offset, 0,
+				      &bitstream_data_dmabuf_attachment,
+				      &bitstream_data_addr,
+				      &bitstream_sgt,
+				      &bitstream_data_size,
+				      DMA_TO_DEVICE);
+	if (ret)
+		return ret;
+
+	dpb_frames = kcalloc(ctx.dpb_frames_nb, sizeof(*dpb_frames),
+			     GFP_KERNEL);
+	if (!dpb_frames) {
+		ret = -ENOMEM;
+		goto release_bitstream_dmabuf;
+	}
+
+	macroblocks_nb = ctx.pic_width_in_mbs * ctx.pic_height_in_mbs;
+	frames_user = u64_to_user_ptr(ctx.dpb_frames_ptr);
+
+	if (copy_from_user(frames, frames_user,
+			   ctx.dpb_frames_nb * sizeof(*frames))) {
+		ret = -EFAULT;
+		goto free_dpb_frames;
+	}
+
+	for (i = 0; i < ctx.dpb_frames_nb; i++) {
+		ret = tegra_vde_validate_frame(dev, &frames[i]);
+		if (ret)
+			goto release_dpb_frames;
+
+		dpb_frames[i].flags = frames[i].flags;
+		dpb_frames[i].frame_num = frames[i].frame_num;
+
+		dma_dir = (i == 0) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+		ret = tegra_vde_attach_dmabufs_to_frame(dev, &dpb_frames[i],
+							&frames[i], dma_dir,
+							ctx.baseline_profile,
+							macroblocks_nb * 64);
+		if (ret)
+			goto release_dpb_frames;
+	}
+
+	ret = mutex_lock_interruptible(&vde->lock);
+	if (ret)
+		goto release_dpb_frames;
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0)
+		goto unlock;
+
+	/*
+	 * We rely on the VDE registers reset value, otherwise VDE
+	 * causes bus lockup.
+	 */
+	ret = reset_control_reset(vde->rst);
+	if (ret) {
+		dev_err(dev, "Failed to reset HW: %d\n", ret);
+		goto put_runtime_pm;
+	}
+
+	ret = tegra_vde_setup_hw_context(vde, &ctx, dpb_frames,
+					 bitstream_data_addr,
+					 bitstream_data_size,
+					 macroblocks_nb);
+	if (ret)
+		goto put_runtime_pm;
+
+	tegra_vde_decode_frame(vde, macroblocks_nb);
+
+	timeout = wait_for_completion_interruptible_timeout(
+			&vde->decode_completion, msecs_to_jiffies(1000));
+	if (timeout == 0) {
+		bsev_ptr = readl_relaxed(vde->bsev + 0x10);
+		macroblocks_nb = readl_relaxed(vde->sxe + 0xC8) & 0x1FFF;
+		read_bytes = bsev_ptr ? bsev_ptr - bitstream_data_addr : 0;
+
+		dev_err(dev, "Decoding failed: "
+				"read 0x%X bytes, %u macroblocks parsed\n",
+			read_bytes, macroblocks_nb);
+
+		ret = -EIO;
+	} else if (timeout < 0) {
+		ret = timeout;
+	}
+
+	err = reset_control_assert(vde->rst);
+	if (err)
+		dev_err(dev, "Failed to assert HW reset: %d\n", err);
+
+put_runtime_pm:
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+unlock:
+	mutex_unlock(&vde->lock);
+
+release_dpb_frames:
+	while (i--) {
+		dma_dir = (i == 0) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+		tegra_vde_release_frame_dmabufs(&dpb_frames[i], dma_dir,
+						ctx.baseline_profile);
+	}
+
+free_dpb_frames:
+	kfree(dpb_frames);
+
+release_bitstream_dmabuf:
+	tegra_vde_detach_and_put_dmabuf(bitstream_data_dmabuf_attachment,
+					bitstream_sgt, DMA_TO_DEVICE);
+
+	return ret;
+}
+
+static long tegra_vde_unlocked_ioctl(struct file *filp,
+				     unsigned int cmd, unsigned long arg)
+{
+	struct miscdevice *miscdev = filp->private_data;
+	struct tegra_vde *vde = container_of(miscdev, struct tegra_vde,
+					     miscdev);
+
+	switch (cmd) {
+	case TEGRA_VDE_IOCTL_DECODE_H264:
+		return tegra_vde_ioctl_decode_h264(vde, arg);
+	}
+
+	dev_err(miscdev->parent, "Invalid IOCTL command %u\n", cmd);
+
+	return -ENOTTY;
+}
+
+static const struct file_operations tegra_vde_fops = {
+	.owner		= THIS_MODULE,
+	.unlocked_ioctl	= tegra_vde_unlocked_ioctl,
+};
+
+static irqreturn_t tegra_vde_isr(int irq, void *data)
+{
+	struct tegra_vde *vde = data;
+
+	tegra_vde_set_bits(vde, 0, vde->frameid + 0x208);
+	complete(&vde->decode_completion);
+
+	return IRQ_HANDLED;
+}
+
+static int tegra_vde_runtime_suspend(struct device *dev)
+{
+	struct tegra_vde *vde = dev_get_drvdata(dev);
+	int err;
+
+	err = tegra_powergate_power_off(TEGRA_POWERGATE_VDEC);
+	if (err) {
+		dev_err(dev, "Failed to power down HW: %d\n", err);
+		return err;
+	}
+
+	clk_disable_unprepare(vde->clk);
+
+	return 0;
+}
+
+static int tegra_vde_runtime_resume(struct device *dev)
+{
+	struct tegra_vde *vde = dev_get_drvdata(dev);
+	int err;
+
+	err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_VDEC,
+						vde->clk, vde->rst);
+	if (err) {
+		dev_err(dev, "Failed to power up HW : %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int tegra_vde_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *regs;
+	struct tegra_vde *vde;
+	int irq, err;
+
+	vde = devm_kzalloc(dev, sizeof(*vde), GFP_KERNEL);
+	if (!vde)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, vde);
+
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sxe");
+	if (!regs)
+		return -ENODEV;
+
+	vde->sxe = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(vde->sxe))
+		return PTR_ERR(vde->sxe);
+
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bsev");
+	if (!regs)
+		return -ENODEV;
+
+	vde->bsev = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(vde->bsev))
+		return PTR_ERR(vde->bsev);
+
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mbe");
+	if (!regs)
+		return -ENODEV;
+
+	vde->mbe = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(vde->mbe))
+		return PTR_ERR(vde->mbe);
+
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppe");
+	if (!regs)
+		return -ENODEV;
+
+	vde->ppe = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(vde->ppe))
+		return PTR_ERR(vde->ppe);
+
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mce");
+	if (!regs)
+		return -ENODEV;
+
+	vde->mce = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(vde->mce))
+		return PTR_ERR(vde->mce);
+
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tfe");
+	if (!regs)
+		return -ENODEV;
+
+	vde->tfe = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(vde->tfe))
+		return PTR_ERR(vde->tfe);
+
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppb");
+	if (!regs)
+		return -ENODEV;
+
+	vde->ppb = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(vde->ppb))
+		return PTR_ERR(vde->ppb);
+
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vdma");
+	if (!regs)
+		return -ENODEV;
+
+	vde->vdma = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(vde->vdma))
+		return PTR_ERR(vde->vdma);
+
+	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "frameid");
+	if (!regs)
+		return -ENODEV;
+
+	vde->frameid = devm_ioremap_resource(dev, regs);
+	if (IS_ERR(vde->frameid))
+		return PTR_ERR(vde->frameid);
+
+	vde->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(vde->clk)) {
+		err = PTR_ERR(vde->clk);
+		dev_err(dev, "Could not get VDE clk %d\n", err);
+		return err;
+	}
+
+	vde->rst = devm_reset_control_get(dev, NULL);
+	if (IS_ERR(vde->rst)) {
+		err = PTR_ERR(vde->rst);
+		dev_err(dev, "Could not get VDE reset %d\n", err);
+		return err;
+	}
+
+	irq = platform_get_irq_byname(pdev, "sync-token");
+	if (irq < 0)
+		return irq;
+
+	err = devm_request_irq(dev, irq, tegra_vde_isr, 0,
+			       dev_name(dev), vde);
+	if (err) {
+		dev_err(dev, "Could not request IRQ %d\n", err);
+		return err;
+	}
+
+	vde->iram_pool = of_gen_pool_get(dev->of_node, "iram", 0);
+	if (!vde->iram_pool) {
+		dev_err(dev, "Could not get IRAM pool\n");
+		return -EPROBE_DEFER;
+	}
+
+	vde->iram = gen_pool_dma_alloc(vde->iram_pool,
+				       gen_pool_size(vde->iram_pool),
+				       &vde->iram_lists_addr);
+	if (!vde->iram) {
+		dev_err(dev, "Could not reserve IRAM\n");
+		return -ENOMEM;
+	}
+
+	mutex_init(&vde->lock);
+	init_completion(&vde->decode_completion);
+
+	vde->miscdev.minor = MISC_DYNAMIC_MINOR;
+	vde->miscdev.name = "tegra_vde";
+	vde->miscdev.fops = &tegra_vde_fops;
+	vde->miscdev.parent = dev;
+
+	err = misc_register(&vde->miscdev);
+	if (err) {
+		dev_err(dev, "Failed to register misc device: %d\n", err);
+		goto err_gen_free;
+	}
+
+	pm_runtime_enable(dev);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_set_autosuspend_delay(dev, 300);
+
+	if (!pm_runtime_enabled(dev)) {
+		err = tegra_vde_runtime_resume(dev);
+		if (err)
+			goto err_misc_unreg;
+	}
+
+	return 0;
+
+err_misc_unreg:
+	misc_deregister(&vde->miscdev);
+
+err_gen_free:
+	gen_pool_free(vde->iram_pool, (unsigned long)vde->iram,
+		      gen_pool_size(vde->iram_pool));
+
+	return err;
+}
+
+static int tegra_vde_remove(struct platform_device *pdev)
+{
+	struct tegra_vde *vde = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	int err;
+
+	if (!pm_runtime_enabled(dev)) {
+		err = tegra_vde_runtime_suspend(dev);
+		if (err)
+			return err;
+	}
+
+	pm_runtime_dont_use_autosuspend(dev);
+	pm_runtime_disable(dev);
+
+	misc_deregister(&vde->miscdev);
+
+	gen_pool_free(vde->iram_pool, (unsigned long)vde->iram,
+		      gen_pool_size(vde->iram_pool));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tegra_vde_pm_suspend(struct device *dev)
+{
+	struct tegra_vde *vde = dev_get_drvdata(dev);
+	int err;
+
+	mutex_lock(&vde->lock);
+
+	err = pm_runtime_force_suspend(dev);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int tegra_vde_pm_resume(struct device *dev)
+{
+	struct tegra_vde *vde = dev_get_drvdata(dev);
+	int err;
+
+	err = pm_runtime_force_resume(dev);
+	if (err < 0)
+		return err;
+
+	mutex_unlock(&vde->lock);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops tegra_vde_pm_ops = {
+	SET_RUNTIME_PM_OPS(tegra_vde_runtime_suspend,
+			   tegra_vde_runtime_resume,
+			   NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(tegra_vde_pm_suspend,
+				tegra_vde_pm_resume)
+};
+
+static const struct of_device_id tegra_vde_of_match[] = {
+	{ .compatible = "nvidia,tegra20-vde", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, tegra_vde_of_match);
+
+static struct platform_driver tegra_vde_driver = {
+	.probe		= tegra_vde_probe,
+	.remove		= tegra_vde_remove,
+	.driver		= {
+		.name		= "tegra-vde",
+		.of_match_table = tegra_vde_of_match,
+		.pm		= &tegra_vde_pm_ops,
+	},
+};
+module_platform_driver(tegra_vde_driver);
+
+MODULE_DESCRIPTION("NVIDIA Tegra Video Decoder driver");
+MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/tegra-vde/uapi.h b/drivers/staging/media/tegra-vde/uapi.h
new file mode 100644
index 0000000..a50c7bc
--- /dev/null
+++ b/drivers/staging/media/tegra-vde/uapi.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016-2017 Dmitry Osipenko <digetx@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _UAPI_TEGRA_VDE_H_
+#define _UAPI_TEGRA_VDE_H_
+
+#include <linux/types.h>
+#include <asm/ioctl.h>
+
+#define FLAG_B_FRAME		(1 << 0)
+#define FLAG_REFERENCE		(1 << 1)
+
+struct tegra_vde_h264_frame {
+	__s32 y_fd;
+	__s32 cb_fd;
+	__s32 cr_fd;
+	__s32 aux_fd;
+	__u32 y_offset;
+	__u32 cb_offset;
+	__u32 cr_offset;
+	__u32 aux_offset;
+	__u32 frame_num;
+	__u32 flags;
+
+	__u32 reserved;
+} __attribute__((packed));
+
+struct tegra_vde_h264_decoder_ctx {
+	__s32 bitstream_data_fd;
+	__u32 bitstream_data_offset;
+
+	__u64 dpb_frames_ptr;
+	__u8  dpb_frames_nb;
+	__u8  dpb_ref_frames_with_earlier_poc_nb;
+
+	// SPS
+	__u8  baseline_profile;
+	__u8  level_idc;
+	__u8  log2_max_pic_order_cnt_lsb;
+	__u8  log2_max_frame_num;
+	__u8  pic_order_cnt_type;
+	__u8  direct_8x8_inference_flag;
+	__u8  pic_width_in_mbs;
+	__u8  pic_height_in_mbs;
+
+	// PPS
+	__u8  pic_init_qp;
+	__u8  deblocking_filter_control_present_flag;
+	__u8  constrained_intra_pred_flag;
+	__u8  chroma_qp_index_offset;
+	__u8  pic_order_present_flag;
+
+	// Slice header
+	__u8  num_ref_idx_l0_active_minus1;
+	__u8  num_ref_idx_l1_active_minus1;
+
+	__u32 reserved;
+} __attribute__((packed));
+
+#define VDE_IOCTL_BASE			('v' + 0x20)
+
+#define VDE_IO(nr)			_IO(VDE_IOCTL_BASE, nr)
+#define VDE_IOR(nr, type)		_IOR(VDE_IOCTL_BASE, nr, type)
+#define VDE_IOW(nr, type)		_IOW(VDE_IOCTL_BASE, nr, type)
+#define VDE_IOWR(nr, type)		_IOWR(VDE_IOCTL_BASE, nr, type)
+
+#define TEGRA_VDE_DECODE_H264		0x00
+
+#define TEGRA_VDE_IOCTL_DECODE_H264	\
+	VDE_IOW(TEGRA_VDE_DECODE_H264, struct tegra_vde_h264_decoder_ctx)
+
+#endif // _UAPI_TEGRA_VDE_H_
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 315ae29..b6adc54 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -301,13 +301,13 @@
 	  thermal zone if trip points reached.
 
 config ARMADA_THERMAL
-	tristate "Armada 370/XP thermal management"
+	tristate "Marvell EBU Armada SoCs thermal management"
 	depends on ARCH_MVEBU || COMPILE_TEST
 	depends on HAS_IOMEM
 	depends on OF
 	help
 	  Enable this option if you want to have support for thermal management
-	  controller present in Armada 370 and Armada XP SoC.
+	  controller present in Marvell EBU Armada SoCs (370,375,XP,38x,7K,8K).
 
 config DA9062_THERMAL
 	tristate "DA9062/DA9061 Dialog Semiconductor thermal driver"
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 706d747..4c275ec 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -1,5 +1,5 @@
 /*
- * Marvell Armada 370/XP thermal sensor driver
+ * Marvell EBU Armada SoCs thermal sensor driver
  *
  * Copyright (C) 2013 Marvell
  *
@@ -23,8 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/of_device.h>
 #include <linux/thermal.h>
-
-#define THERMAL_VALID_MASK		0x1
+#include <linux/iopoll.h>
 
 /* Thermal Manager Control and Status Register */
 #define PMU_TDC0_SW_RST_MASK		(0x1 << 1)
@@ -39,14 +38,38 @@
 #define A375_UNIT_CONTROL_MASK		0x7
 #define A375_READOUT_INVERT		BIT(15)
 #define A375_HW_RESETn			BIT(8)
-#define A380_HW_RESET			BIT(8)
+
+/* Legacy bindings */
+#define LEGACY_CONTROL_MEM_LEN		0x4
+
+/* Current bindings with the 2 control registers under the same memory area */
+#define LEGACY_CONTROL1_OFFSET		0x0
+#define CONTROL0_OFFSET			0x0
+#define CONTROL1_OFFSET			0x4
+
+/* Errata fields */
+#define CONTROL0_TSEN_TC_TRIM_MASK	0x7
+#define CONTROL0_TSEN_TC_TRIM_VAL	0x3
+
+/* TSEN refers to the temperature sensors within the AP */
+#define CONTROL0_TSEN_START		BIT(0)
+#define CONTROL0_TSEN_RESET		BIT(1)
+#define CONTROL0_TSEN_ENABLE		BIT(2)
+
+/* EXT_TSEN refers to the external temperature sensors, out of the AP */
+#define CONTROL1_EXT_TSEN_SW_RESET	BIT(7)
+#define CONTROL1_EXT_TSEN_HW_RESETn	BIT(8)
+
+#define STATUS_POLL_PERIOD_US		1000
+#define STATUS_POLL_TIMEOUT_US		100000
 
 struct armada_thermal_data;
 
 /* Marvell EBU Thermal Sensor Dev Structure */
 struct armada_thermal_priv {
-	void __iomem *sensor;
-	void __iomem *control;
+	void __iomem *status;
+	void __iomem *control0;
+	void __iomem *control1;
 	struct armada_thermal_data *data;
 };
 
@@ -59,107 +82,142 @@ struct armada_thermal_data {
 	bool (*is_valid)(struct armada_thermal_priv *);
 
 	/* Formula coeficients: temp = (b - m * reg) / div */
-	unsigned long coef_b;
-	unsigned long coef_m;
-	unsigned long coef_div;
+	s64 coef_b;
+	s64 coef_m;
+	u32 coef_div;
 	bool inverted;
+	bool signed_sample;
 
 	/* Register shift and mask to access the sensor temperature */
 	unsigned int temp_shift;
 	unsigned int temp_mask;
-	unsigned int is_valid_shift;
+	u32 is_valid_bit;
+	bool needs_control0;
 };
 
 static void armadaxp_init_sensor(struct platform_device *pdev,
 				 struct armada_thermal_priv *priv)
 {
-	unsigned long reg;
+	u32 reg;
 
-	reg = readl_relaxed(priv->control);
+	reg = readl_relaxed(priv->control1);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	/* Reference calibration value */
 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	/* Reset the sensor */
-	reg = readl_relaxed(priv->control);
-	writel((reg | PMU_TDC0_SW_RST_MASK), priv->control);
+	reg = readl_relaxed(priv->control1);
+	writel((reg | PMU_TDC0_SW_RST_MASK), priv->control1);
 
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	/* Enable the sensor */
-	reg = readl_relaxed(priv->sensor);
+	reg = readl_relaxed(priv->status);
 	reg &= ~PMU_TM_DISABLE_MASK;
-	writel(reg, priv->sensor);
+	writel(reg, priv->status);
 }
 
 static void armada370_init_sensor(struct platform_device *pdev,
 				  struct armada_thermal_priv *priv)
 {
-	unsigned long reg;
+	u32 reg;
 
-	reg = readl_relaxed(priv->control);
+	reg = readl_relaxed(priv->control1);
 	reg |= PMU_TDC0_OTF_CAL_MASK;
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	/* Reference calibration value */
 	reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
 	reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
 	reg &= ~PMU_TDC0_START_CAL_MASK;
-	writel(reg, priv->control);
+	writel(reg, priv->control1);
 
-	mdelay(10);
+	msleep(10);
 }
 
 static void armada375_init_sensor(struct platform_device *pdev,
 				  struct armada_thermal_priv *priv)
 {
-	unsigned long reg;
+	u32 reg;
 
-	reg = readl(priv->control + 4);
+	reg = readl(priv->control1);
 	reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT);
 	reg &= ~A375_READOUT_INVERT;
 	reg &= ~A375_HW_RESETn;
 
-	writel(reg, priv->control + 4);
-	mdelay(20);
+	writel(reg, priv->control1);
+	msleep(20);
 
 	reg |= A375_HW_RESETn;
-	writel(reg, priv->control + 4);
-	mdelay(50);
+	writel(reg, priv->control1);
+	msleep(50);
+}
+
+static void armada_wait_sensor_validity(struct armada_thermal_priv *priv)
+{
+	u32 reg;
+
+	readl_relaxed_poll_timeout(priv->status, reg,
+				   reg & priv->data->is_valid_bit,
+				   STATUS_POLL_PERIOD_US,
+				   STATUS_POLL_TIMEOUT_US);
 }
 
 static void armada380_init_sensor(struct platform_device *pdev,
 				  struct armada_thermal_priv *priv)
 {
-	unsigned long reg = readl_relaxed(priv->control);
+	u32 reg = readl_relaxed(priv->control1);
 
-	/* Reset hardware once */
-	if (!(reg & A380_HW_RESET)) {
-		reg |= A380_HW_RESET;
-		writel(reg, priv->control);
-		mdelay(10);
+	/* Disable the HW/SW reset */
+	reg |= CONTROL1_EXT_TSEN_HW_RESETn;
+	reg &= ~CONTROL1_EXT_TSEN_SW_RESET;
+	writel(reg, priv->control1);
+
+	/* Set Tsen Tc Trim to correct default value (errata #132698) */
+	if (priv->control0) {
+		reg = readl_relaxed(priv->control0);
+		reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
+		reg |= CONTROL0_TSEN_TC_TRIM_VAL;
+		writel(reg, priv->control0);
 	}
+
+	/* Wait the sensors to be valid or the core will warn the user */
+	armada_wait_sensor_validity(priv);
+}
+
+static void armada_ap806_init_sensor(struct platform_device *pdev,
+				     struct armada_thermal_priv *priv)
+{
+	u32 reg;
+
+	reg = readl_relaxed(priv->control0);
+	reg &= ~CONTROL0_TSEN_RESET;
+	reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;
+	writel(reg, priv->control0);
+
+	/* Wait the sensors to be valid or the core will warn the user */
+	armada_wait_sensor_validity(priv);
 }
 
 static bool armada_is_valid(struct armada_thermal_priv *priv)
 {
-	unsigned long reg = readl_relaxed(priv->sensor);
+	u32 reg = readl_relaxed(priv->status);
 
-	return (reg >> priv->data->is_valid_shift) & THERMAL_VALID_MASK;
+	return reg & priv->data->is_valid_bit;
 }
 
 static int armada_get_temp(struct thermal_zone_device *thermal,
-			  int *temp)
+			   int *temp)
 {
 	struct armada_thermal_priv *priv = thermal->devdata;
-	unsigned long reg;
-	unsigned long m, b, div;
+	u32 reg, div;
+	s64 sample, b, m;
 
 	/* Valid check */
 	if (priv->data->is_valid && !priv->data->is_valid(priv)) {
@@ -168,8 +226,13 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 		return -EIO;
 	}
 
-	reg = readl_relaxed(priv->sensor);
+	reg = readl_relaxed(priv->status);
 	reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
+	if (priv->data->signed_sample)
+		/* The most significant bit is the sign bit */
+		sample = sign_extend32(reg, fls(priv->data->temp_mask) - 1);
+	else
+		sample = reg;
 
 	/* Get formula coeficients */
 	b = priv->data->coef_b;
@@ -177,9 +240,10 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
 	div = priv->data->coef_div;
 
 	if (priv->data->inverted)
-		*temp = ((m * reg) - b) / div;
+		*temp = div_s64((m * sample) - b, div);
 	else
-		*temp = (b - (m * reg)) / div;
+		*temp = div_s64(b - (m * sample), div);
+
 	return 0;
 }
 
@@ -191,45 +255,73 @@ static const struct armada_thermal_data armadaxp_data = {
 	.init_sensor = armadaxp_init_sensor,
 	.temp_shift = 10,
 	.temp_mask = 0x1ff,
-	.coef_b = 3153000000UL,
-	.coef_m = 10000000UL,
+	.coef_b = 3153000000ULL,
+	.coef_m = 10000000ULL,
 	.coef_div = 13825,
 };
 
 static const struct armada_thermal_data armada370_data = {
 	.is_valid = armada_is_valid,
 	.init_sensor = armada370_init_sensor,
-	.is_valid_shift = 9,
+	.is_valid_bit = BIT(9),
 	.temp_shift = 10,
 	.temp_mask = 0x1ff,
-	.coef_b = 3153000000UL,
-	.coef_m = 10000000UL,
+	.coef_b = 3153000000ULL,
+	.coef_m = 10000000ULL,
 	.coef_div = 13825,
 };
 
 static const struct armada_thermal_data armada375_data = {
 	.is_valid = armada_is_valid,
 	.init_sensor = armada375_init_sensor,
-	.is_valid_shift = 10,
+	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x1ff,
-	.coef_b = 3171900000UL,
-	.coef_m = 10000000UL,
+	.coef_b = 3171900000ULL,
+	.coef_m = 10000000ULL,
 	.coef_div = 13616,
+	.needs_control0 = true,
 };
 
 static const struct armada_thermal_data armada380_data = {
 	.is_valid = armada_is_valid,
 	.init_sensor = armada380_init_sensor,
-	.is_valid_shift = 10,
+	.is_valid_bit = BIT(10),
 	.temp_shift = 0,
 	.temp_mask = 0x3ff,
-	.coef_b = 1172499100UL,
-	.coef_m = 2000096UL,
+	.coef_b = 1172499100ULL,
+	.coef_m = 2000096ULL,
 	.coef_div = 4201,
 	.inverted = true,
 };
 
+static const struct armada_thermal_data armada_ap806_data = {
+	.is_valid = armada_is_valid,
+	.init_sensor = armada_ap806_init_sensor,
+	.is_valid_bit = BIT(16),
+	.temp_shift = 0,
+	.temp_mask = 0x3ff,
+	.coef_b = -150000LL,
+	.coef_m = 423ULL,
+	.coef_div = 1,
+	.inverted = true,
+	.signed_sample = true,
+	.needs_control0 = true,
+};
+
+static const struct armada_thermal_data armada_cp110_data = {
+	.is_valid = armada_is_valid,
+	.init_sensor = armada380_init_sensor,
+	.is_valid_bit = BIT(10),
+	.temp_shift = 0,
+	.temp_mask = 0x3ff,
+	.coef_b = 1172499100ULL,
+	.coef_m = 2000096ULL,
+	.coef_div = 4201,
+	.inverted = true,
+	.needs_control0 = true,
+};
+
 static const struct of_device_id armada_thermal_id_table[] = {
 	{
 		.compatible = "marvell,armadaxp-thermal",
@@ -248,6 +340,14 @@ static const struct of_device_id armada_thermal_id_table[] = {
 		.data       = &armada380_data,
 	},
 	{
+		.compatible = "marvell,armada-ap806-thermal",
+		.data       = &armada_ap806_data,
+	},
+	{
+		.compatible = "marvell,armada-cp110-thermal",
+		.data       = &armada_cp110_data,
+	},
+	{
 		/* sentinel */
 	},
 };
@@ -255,6 +355,7 @@ MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
 
 static int armada_thermal_probe(struct platform_device *pdev)
 {
+	void __iomem *control = NULL;
 	struct thermal_zone_device *thermal;
 	const struct of_device_id *match;
 	struct armada_thermal_priv *priv;
@@ -269,20 +370,40 @@ static int armada_thermal_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->sensor = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(priv->sensor))
-		return PTR_ERR(priv->sensor);
+	priv->status = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->status))
+		return PTR_ERR(priv->status);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	priv->control = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(priv->control))
-		return PTR_ERR(priv->control);
+	control = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(control))
+		return PTR_ERR(control);
 
 	priv->data = (struct armada_thermal_data *)match->data;
+
+	/*
+	 * Legacy DT bindings only described "control1" register (also referred
+	 * as "control MSB" on old documentation). New bindings cover
+	 * "control0/control LSB" and "control1/control MSB" registers within
+	 * the same resource, which is then of size 8 instead of 4.
+	 */
+	if (resource_size(res) == LEGACY_CONTROL_MEM_LEN) {
+		/* ->control0 unavailable in this configuration */
+		if (priv->data->needs_control0) {
+			dev_err(&pdev->dev, "No access to control0 register\n");
+			return -EINVAL;
+		}
+
+		priv->control1 = control + LEGACY_CONTROL1_OFFSET;
+	} else {
+		priv->control0 = control + CONTROL0_OFFSET;
+		priv->control1 = control + CONTROL1_OFFSET;
+	}
+
 	priv->data->init_sensor(pdev, priv);
 
-	thermal = thermal_zone_device_register("armada_thermal", 0, 0,
-					       priv, &ops, NULL, 0, 0);
+	thermal = thermal_zone_device_register(dev_name(&pdev->dev), 0, 0, priv,
+					       &ops, NULL, 0, 0);
 	if (IS_ERR(thermal)) {
 		dev_err(&pdev->dev,
 			"Failed to register thermal zone device\n");
@@ -316,5 +437,5 @@ static struct platform_driver armada_thermal_driver = {
 module_platform_driver(armada_thermal_driver);
 
 MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");
-MODULE_DESCRIPTION("Armada 370/XP thermal driver");
+MODULE_DESCRIPTION("Marvell EBU Armada SoCs thermal driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index 2d855a9..761d055 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -527,7 +527,7 @@ static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor,
 static int hisi_thermal_probe(struct platform_device *pdev)
 {
 	struct hisi_thermal_data *data;
-	int const (*platform_probe)(struct hisi_thermal_data *);
+	int (*platform_probe)(struct hisi_thermal_data *);
 	struct device *dev = &pdev->dev;
 	int ret;
 
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index e7d4ffc..a67781b 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -70,10 +70,6 @@ enum imx_thermal_trip {
 #define IMX_POLLING_DELAY		2000 /* millisecond */
 #define IMX_PASSIVE_DELAY		1000
 
-#define FACTOR0				10000000
-#define FACTOR1				15976
-#define FACTOR2				4297157
-
 #define TEMPMON_IMX6Q			1
 #define TEMPMON_IMX6SX			2
 
@@ -347,78 +343,74 @@ static struct thermal_zone_device_ops imx_tz_ops = {
 	.set_trip_temp = imx_set_trip_temp,
 };
 
-static int imx_init_calib(struct platform_device *pdev, u32 val)
+static int imx_init_calib(struct platform_device *pdev, u32 ocotp_ana1)
 {
 	struct imx_thermal_data *data = platform_get_drvdata(pdev);
-	int t1, n1;
+	int n1;
 	u64 temp64;
 
-	if (val == 0 || val == ~0) {
+	if (ocotp_ana1 == 0 || ocotp_ana1 == ~0) {
 		dev_err(&pdev->dev, "invalid sensor calibration data\n");
 		return -EINVAL;
 	}
 
 	/*
-	 * Sensor data layout:
-	 *   [31:20] - sensor value @ 25C
-	 * Use universal formula now and only need sensor value @ 25C
-	 * slope = 0.4297157 - (0.0015976 * 25C fuse)
+	 * The sensor is calibrated at 25 °C (aka T1) and the value measured
+	 * (aka N1) at this temperature is provided in bits [31:20] in the
+	 * i.MX's OCOTP value ANA1.
+	 * To find the actual temperature T, the following formula has to be used
+	 * when reading value n from the sensor:
+	 *
+	 * T = T1 + (N - N1) / (0.4148468 - 0.0015423 * N1) °C + 3.580661 °C
+	 *   = [T1' - N1 / (0.4148468 - 0.0015423 * N1) °C] + N / (0.4148468 - 0.0015423 * N1) °C
+	 *   = [T1' + N1 / (0.0015423 * N1 - 0.4148468) °C] - N / (0.0015423 * N1 - 0.4148468) °C
+	 *   = c2 - c1 * N
+	 *
+	 * with
+	 *
+	 *  T1' = 28.580661 °C
+	 *   c1 = 1 / (0.0015423 * N1 - 0.4297157) °C
+	 *   c2 = T1' + N1 / (0.0015423 * N1 - 0.4148468) °C
+	 *      = T1' + N1 * c1
 	 */
-	n1 = val >> 20;
-	t1 = 25; /* t1 always 25C */
+	n1 = ocotp_ana1 >> 20;
 
-	/*
-	 * Derived from linear interpolation:
-	 * slope = 0.4297157 - (0.0015976 * 25C fuse)
-	 * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
-	 * (Nmeas - n1) / (Tmeas - t1) = slope
-	 * We want to reduce this down to the minimum computation necessary
-	 * for each temperature read.  Also, we want Tmeas in millicelsius
-	 * and we don't want to lose precision from integer division. So...
-	 * Tmeas = (Nmeas - n1) / slope + t1
-	 * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
-	 * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
-	 * Let constant c1 = (-1000 / slope)
-	 * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
-	 * Let constant c2 = n1 *c1 + 1000 * t1
-	 * milli_Tmeas = c2 - Nmeas * c1
-	 */
-	temp64 = FACTOR0;
-	temp64 *= 1000;
-	do_div(temp64, FACTOR1 * n1 - FACTOR2);
+	temp64 = 10000000; /* use 10^7 as fixed point constant for values in formula */
+	temp64 *= 1000; /* to get result in °mC */
+	do_div(temp64, 15423 * n1 - 4148468);
 	data->c1 = temp64;
-	data->c2 = n1 * data->c1 + 1000 * t1;
+	data->c2 = n1 * data->c1 + 28581;
 
 	return 0;
 }
 
-static void imx_init_temp_grade(struct platform_device *pdev, u32 val)
+static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0)
 {
 	struct imx_thermal_data *data = platform_get_drvdata(pdev);
 
 	/* The maximum die temp is specified by the Temperature Grade */
-	switch ((val >> 6) & 0x3) {
-	case 0: /* Commercial (0 to 95C) */
+	switch ((ocotp_mem0 >> 6) & 0x3) {
+	case 0: /* Commercial (0 to 95 °C) */
 		data->temp_grade = "Commercial";
 		data->temp_max = 95000;
 		break;
-	case 1: /* Extended Commercial (-20 to 105C) */
+	case 1: /* Extended Commercial (-20 °C to 105 °C) */
 		data->temp_grade = "Extended Commercial";
 		data->temp_max = 105000;
 		break;
-	case 2: /* Industrial (-40 to 105C) */
+	case 2: /* Industrial (-40 °C to 105 °C) */
 		data->temp_grade = "Industrial";
 		data->temp_max = 105000;
 		break;
-	case 3: /* Automotive (-40 to 125C) */
+	case 3: /* Automotive (-40 °C to 125 °C) */
 		data->temp_grade = "Automotive";
 		data->temp_max = 125000;
 		break;
 	}
 
 	/*
-	 * Set the critical trip point at 5C under max
-	 * Set the passive trip point at 10C under max (can change via sysfs)
+	 * Set the critical trip point at 5 °C under max
+	 * Set the passive trip point at 10 °C under max (changeable via sysfs)
 	 */
 	data->temp_critical = data->temp_max - (1000 * 5);
 	data->temp_passive = data->temp_max - (1000 * 10);
diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c
index 8ee38f5..e26b01c 100644
--- a/drivers/thermal/int340x_thermal/int3400_thermal.c
+++ b/drivers/thermal/int340x_thermal/int3400_thermal.c
@@ -211,7 +211,7 @@ static void int3400_notify(acpi_handle handle,
 				thermal_prop);
 		break;
 	default:
-		dev_err(&priv->adev->dev, "Unsupported event [0x%x]\n", event);
+		/* Ignore unknown notification codes sent to INT3400 device */
 		break;
 	}
 }
@@ -319,17 +319,21 @@ static int int3400_thermal_probe(struct platform_device *pdev)
 
 	result = sysfs_create_group(&pdev->dev.kobj, &uuid_attribute_group);
 	if (result)
-		goto free_zone;
+		goto free_rel_misc;
 
 	result = acpi_install_notify_handler(
 			priv->adev->handle, ACPI_DEVICE_NOTIFY, int3400_notify,
 			(void *)priv);
 	if (result)
-		goto free_zone;
+		goto free_sysfs;
 
 	return 0;
 
-free_zone:
+free_sysfs:
+	sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group);
+free_rel_misc:
+	if (!priv->rel_misc_dev_res)
+		acpi_thermal_rel_misc_device_remove(priv->adev->handle);
 	thermal_zone_device_unregister(priv->thermal);
 free_art_trt:
 	kfree(priv->trts);
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index 1e61c09..c75661a 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -32,15 +32,10 @@
 #include <linux/types.h>
 
 /* AUXADC Registers */
-#define AUXADC_CON0_V		0x000
-#define AUXADC_CON1_V		0x004
 #define AUXADC_CON1_SET_V	0x008
 #define AUXADC_CON1_CLR_V	0x00c
 #define AUXADC_CON2_V		0x010
 #define AUXADC_DATA(channel)	(0x14 + (channel) * 4)
-#define AUXADC_MISC_V		0x094
-
-#define AUXADC_CON1_CHANNEL(x)	BIT(x)
 
 #define APMIXED_SYS_TS_CON1	0x604
 
@@ -158,8 +153,6 @@
 /* The number of sensing points per bank */
 #define MT2712_NUM_SENSORS_PER_ZONE	4
 
-#define THERMAL_NAME    "mtk-thermal"
-
 struct mtk_thermal;
 
 struct thermal_bank_cfg {
@@ -765,7 +758,7 @@ static struct platform_driver mtk_thermal_driver = {
 	.probe = mtk_thermal_probe,
 	.remove = mtk_thermal_remove,
 	.driver = {
-		.name = THERMAL_NAME,
+		.name = "mtk-thermal",
 		.of_match_table = mtk_thermal_of_match,
 	},
 };
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index d04ec3b..e09f035 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -30,7 +30,6 @@
 #include <linux/err.h>
 #include <linux/export.h>
 #include <linux/string.h>
-#include <linux/thermal.h>
 
 #include "thermal_core.h"
 
diff --git a/drivers/thermal/power_allocator.c b/drivers/thermal/power_allocator.c
index b4d3116..3055f9a 100644
--- a/drivers/thermal/power_allocator.c
+++ b/drivers/thermal/power_allocator.c
@@ -523,6 +523,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz)
 	struct thermal_instance *instance;
 	struct power_allocator_params *params = tz->governor_data;
 
+	mutex_lock(&tz->lock);
 	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
 		if ((instance->trip != params->trip_max_desired_temperature) ||
 		    (!cdev_is_power_actor(instance->cdev)))
@@ -534,6 +535,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz)
 		mutex_unlock(&instance->cdev->lock);
 		thermal_cdev_update(instance->cdev);
 	}
+	mutex_unlock(&tz->lock);
 }
 
 /**
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index 075db1d..455b58c 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -341,62 +341,6 @@ static int tegra_thermctl_get_temp(void *data, int *out_temp)
 	return 0;
 }
 
-static int
-thermtrip_program(struct device *dev, const struct tegra_tsensor_group *sg,
-		  int trip_temp);
-static int
-throttrip_program(struct device *dev, const struct tegra_tsensor_group *sg,
-		  struct soctherm_throt_cfg *stc, int trip_temp);
-static struct soctherm_throt_cfg *
-find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name);
-
-static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
-{
-	struct tegra_thermctl_zone *zone = data;
-	struct thermal_zone_device *tz = zone->tz;
-	struct tegra_soctherm *ts = zone->ts;
-	const struct tegra_tsensor_group *sg = zone->sg;
-	struct device *dev = zone->dev;
-	enum thermal_trip_type type;
-	int ret;
-
-	if (!tz)
-		return -EINVAL;
-
-	ret = tz->ops->get_trip_type(tz, trip, &type);
-	if (ret)
-		return ret;
-
-	if (type == THERMAL_TRIP_CRITICAL) {
-		return thermtrip_program(dev, sg, temp);
-	} else if (type == THERMAL_TRIP_HOT) {
-		int i;
-
-		for (i = 0; i < THROTTLE_SIZE; i++) {
-			struct thermal_cooling_device *cdev;
-			struct soctherm_throt_cfg *stc;
-
-			if (!ts->throt_cfgs[i].init)
-				continue;
-
-			cdev = ts->throt_cfgs[i].cdev;
-			if (get_thermal_instance(tz, cdev, trip))
-				stc = find_throttle_cfg_by_name(ts, cdev->type);
-			else
-				continue;
-
-			return throttrip_program(dev, sg, stc, temp);
-		}
-	}
-
-	return 0;
-}
-
-static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
-	.get_temp = tegra_thermctl_get_temp,
-	.set_trip_temp = tegra_thermctl_set_trip_temp,
-};
-
 /**
  * enforce_temp_range() - check and enforce temperature range [min, max]
  * @trip_temp: the trip temperature to check
@@ -527,6 +471,53 @@ find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name)
 	return NULL;
 }
 
+static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
+{
+	struct tegra_thermctl_zone *zone = data;
+	struct thermal_zone_device *tz = zone->tz;
+	struct tegra_soctherm *ts = zone->ts;
+	const struct tegra_tsensor_group *sg = zone->sg;
+	struct device *dev = zone->dev;
+	enum thermal_trip_type type;
+	int ret;
+
+	if (!tz)
+		return -EINVAL;
+
+	ret = tz->ops->get_trip_type(tz, trip, &type);
+	if (ret)
+		return ret;
+
+	if (type == THERMAL_TRIP_CRITICAL) {
+		return thermtrip_program(dev, sg, temp);
+	} else if (type == THERMAL_TRIP_HOT) {
+		int i;
+
+		for (i = 0; i < THROTTLE_SIZE; i++) {
+			struct thermal_cooling_device *cdev;
+			struct soctherm_throt_cfg *stc;
+
+			if (!ts->throt_cfgs[i].init)
+				continue;
+
+			cdev = ts->throt_cfgs[i].cdev;
+			if (get_thermal_instance(tz, cdev, trip))
+				stc = find_throttle_cfg_by_name(ts, cdev->type);
+			else
+				continue;
+
+			return throttrip_program(dev, sg, stc, temp);
+		}
+	}
+
+	return 0;
+}
+
+static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
+	.get_temp = tegra_thermctl_get_temp,
+	.set_trip_temp = tegra_thermctl_set_trip_temp,
+};
+
 static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
 {
 	int ntrips, i, ret;
diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c
index 541af59..c4a508a 100644
--- a/drivers/thermal/thermal_hwmon.c
+++ b/drivers/thermal/thermal_hwmon.c
@@ -59,14 +59,6 @@ static LIST_HEAD(thermal_hwmon_list);
 static DEFINE_MUTEX(thermal_hwmon_list_lock);
 
 static ssize_t
-name_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev);
-	return sprintf(buf, "%s\n", hwmon->type);
-}
-static DEVICE_ATTR_RO(name);
-
-static ssize_t
 temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	int temperature;
@@ -165,15 +157,12 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
 
 	INIT_LIST_HEAD(&hwmon->tz_list);
 	strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
-	hwmon->device = hwmon_device_register(NULL);
+	hwmon->device = hwmon_device_register_with_info(NULL, hwmon->type,
+							hwmon, NULL, NULL);
 	if (IS_ERR(hwmon->device)) {
 		result = PTR_ERR(hwmon->device);
 		goto free_mem;
 	}
-	dev_set_drvdata(hwmon->device, hwmon);
-	result = device_create_file(hwmon->device, &dev_attr_name);
-	if (result)
-		goto free_mem;
 
  register_sys_interface:
 	temp = kzalloc(sizeof(*temp), GFP_KERNEL);
@@ -222,10 +211,8 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
  free_temp_mem:
 	kfree(temp);
  unregister_name:
-	if (new_hwmon_device) {
-		device_remove_file(hwmon->device, &dev_attr_name);
+	if (new_hwmon_device)
 		hwmon_device_unregister(hwmon->device);
-	}
  free_mem:
 	if (new_hwmon_device)
 		kfree(hwmon);
@@ -267,7 +254,6 @@ void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
 	list_del(&hwmon->node);
 	mutex_unlock(&thermal_hwmon_list_lock);
 
-	device_remove_file(hwmon->device, &dev_attr_name);
 	hwmon_device_unregister(hwmon->device);
 	kfree(hwmon);
 }
diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
index d93eee2..1a6c88b 100644
--- a/drivers/thermal/x86_pkg_temp_thermal.c
+++ b/drivers/thermal/x86_pkg_temp_thermal.c
@@ -96,12 +96,12 @@ static int pkg_temp_debugfs_init(void)
 		return -ENOENT;
 
 	d = debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs,
-				(u32 *)&pkg_interrupt_cnt);
+			       &pkg_interrupt_cnt);
 	if (!d)
 		goto err_out;
 
 	d = debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs,
-				(u32 *)&pkg_work_cnt);
+			       &pkg_work_cnt);
 	if (!d)
 		goto err_out;
 
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 9c3f816..c613d2e 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1015,7 +1015,7 @@ static int vhost_net_release(struct inode *inode, struct file *f)
 	vhost_net_stop(n, &tx_sock, &rx_sock);
 	vhost_net_flush(n);
 	vhost_dev_stop(&n->dev);
-	vhost_dev_cleanup(&n->dev, false);
+	vhost_dev_cleanup(&n->dev);
 	vhost_net_vq_reset(n);
 	if (tx_sock)
 		sockfd_put(tx_sock);
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 71517b3..7ad5709 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -586,8 +586,7 @@ vhost_scsi_get_tag(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg,
 	sg = cmd->tvc_sgl;
 	prot_sg = cmd->tvc_prot_sgl;
 	pages = cmd->tvc_upages;
-	memset(cmd, 0, sizeof(struct vhost_scsi_cmd));
-
+	memset(cmd, 0, sizeof(*cmd));
 	cmd->tvc_sgl = sg;
 	cmd->tvc_prot_sgl = prot_sg;
 	cmd->tvc_upages = pages;
@@ -1420,7 +1419,7 @@ static int vhost_scsi_release(struct inode *inode, struct file *f)
 	mutex_unlock(&vs->dev.mutex);
 	vhost_scsi_clear_endpoint(vs, &t);
 	vhost_dev_stop(&vs->dev);
-	vhost_dev_cleanup(&vs->dev, false);
+	vhost_dev_cleanup(&vs->dev);
 	/* Jobs can re-queue themselves in evt kick handler. Do extra flush. */
 	vhost_scsi_flush(vs);
 	kfree(vs->dev.vqs);
@@ -1725,7 +1724,7 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
 		return -EEXIST;
 	}
 
-	tv_nexus = kzalloc(sizeof(struct vhost_scsi_nexus), GFP_KERNEL);
+	tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
 	if (!tv_nexus) {
 		mutex_unlock(&tpg->tv_tpg_mutex);
 		pr_err("Unable to allocate struct vhost_scsi_nexus\n");
@@ -1926,7 +1925,7 @@ vhost_scsi_make_tpg(struct se_wwn *wwn,
 	if (kstrtou16(name + 5, 10, &tpgt) || tpgt >= VHOST_SCSI_MAX_TARGET)
 		return ERR_PTR(-EINVAL);
 
-	tpg = kzalloc(sizeof(struct vhost_scsi_tpg), GFP_KERNEL);
+	tpg = kzalloc(sizeof(*tpg), GFP_KERNEL);
 	if (!tpg) {
 		pr_err("Unable to allocate struct vhost_scsi_tpg");
 		return ERR_PTR(-ENOMEM);
@@ -1980,7 +1979,7 @@ vhost_scsi_make_tport(struct target_fabric_configfs *tf,
 	/* if (vhost_scsi_parse_wwn(name, &wwpn, 1) < 0)
 		return ERR_PTR(-EINVAL); */
 
-	tport = kzalloc(sizeof(struct vhost_scsi_tport), GFP_KERNEL);
+	tport = kzalloc(sizeof(*tport), GFP_KERNEL);
 	if (!tport) {
 		pr_err("Unable to allocate struct vhost_scsi_tport");
 		return ERR_PTR(-ENOMEM);
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index 3cc98c0..906b8f0 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -157,7 +157,7 @@ static int vhost_test_release(struct inode *inode, struct file *f)
 
 	vhost_test_stop(n, &private);
 	vhost_test_flush(n);
-	vhost_dev_cleanup(&n->dev, false);
+	vhost_dev_cleanup(&n->dev);
 	/* We do an extra flush before freeing memory,
 	 * since jobs can re-queue themselves. */
 	vhost_test_flush(n);
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 8d43746..2db5af8 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -181,7 +181,6 @@ void vhost_work_init(struct vhost_work *work, vhost_work_fn_t fn)
 {
 	clear_bit(VHOST_WORK_QUEUED, &work->flags);
 	work->fn = fn;
-	init_waitqueue_head(&work->done);
 }
 EXPORT_SYMBOL_GPL(vhost_work_init);
 
@@ -319,10 +318,8 @@ static void vhost_vq_reset(struct vhost_dev *dev,
 	vq->acked_features = 0;
 	vq->log_base = NULL;
 	vq->error_ctx = NULL;
-	vq->error = NULL;
 	vq->kick = NULL;
 	vq->call_ctx = NULL;
-	vq->call = NULL;
 	vq->log_ctx = NULL;
 	vhost_reset_is_le(vq);
 	vhost_disable_cross_endian(vq);
@@ -422,7 +419,6 @@ void vhost_dev_init(struct vhost_dev *dev,
 	dev->nvqs = nvqs;
 	mutex_init(&dev->mutex);
 	dev->log_ctx = NULL;
-	dev->log_file = NULL;
 	dev->umem = NULL;
 	dev->iotlb = NULL;
 	dev->mm = NULL;
@@ -544,7 +540,7 @@ void vhost_dev_reset_owner(struct vhost_dev *dev, struct vhost_umem *umem)
 {
 	int i;
 
-	vhost_dev_cleanup(dev, true);
+	vhost_dev_cleanup(dev);
 
 	/* Restore memory to default empty mapping. */
 	INIT_LIST_HEAD(&umem->umem_list);
@@ -611,31 +607,23 @@ static void vhost_clear_msg(struct vhost_dev *dev)
 	spin_unlock(&dev->iotlb_lock);
 }
 
-/* Caller should have device mutex if and only if locked is set */
-void vhost_dev_cleanup(struct vhost_dev *dev, bool locked)
+void vhost_dev_cleanup(struct vhost_dev *dev)
 {
 	int i;
 
 	for (i = 0; i < dev->nvqs; ++i) {
 		if (dev->vqs[i]->error_ctx)
 			eventfd_ctx_put(dev->vqs[i]->error_ctx);
-		if (dev->vqs[i]->error)
-			fput(dev->vqs[i]->error);
 		if (dev->vqs[i]->kick)
 			fput(dev->vqs[i]->kick);
 		if (dev->vqs[i]->call_ctx)
 			eventfd_ctx_put(dev->vqs[i]->call_ctx);
-		if (dev->vqs[i]->call)
-			fput(dev->vqs[i]->call);
 		vhost_vq_reset(dev, dev->vqs[i]);
 	}
 	vhost_dev_free_iovecs(dev);
 	if (dev->log_ctx)
 		eventfd_ctx_put(dev->log_ctx);
 	dev->log_ctx = NULL;
-	if (dev->log_file)
-		fput(dev->log_file);
-	dev->log_file = NULL;
 	/* No one will access memory at this point */
 	vhost_umem_clean(dev->umem);
 	dev->umem = NULL;
@@ -1492,38 +1480,24 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
 			r = -EFAULT;
 			break;
 		}
-		eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
-		if (IS_ERR(eventfp)) {
-			r = PTR_ERR(eventfp);
+		ctx = f.fd == -1 ? NULL : eventfd_ctx_fdget(f.fd);
+		if (IS_ERR(ctx)) {
+			r = PTR_ERR(ctx);
 			break;
 		}
-		if (eventfp != vq->call) {
-			filep = vq->call;
-			ctx = vq->call_ctx;
-			vq->call = eventfp;
-			vq->call_ctx = eventfp ?
-				eventfd_ctx_fileget(eventfp) : NULL;
-		} else
-			filep = eventfp;
+		swap(ctx, vq->call_ctx);
 		break;
 	case VHOST_SET_VRING_ERR:
 		if (copy_from_user(&f, argp, sizeof f)) {
 			r = -EFAULT;
 			break;
 		}
-		eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
-		if (IS_ERR(eventfp)) {
-			r = PTR_ERR(eventfp);
+		ctx = f.fd == -1 ? NULL : eventfd_ctx_fdget(f.fd);
+		if (IS_ERR(ctx)) {
+			r = PTR_ERR(ctx);
 			break;
 		}
-		if (eventfp != vq->error) {
-			filep = vq->error;
-			vq->error = eventfp;
-			ctx = vq->error_ctx;
-			vq->error_ctx = eventfp ?
-				eventfd_ctx_fileget(eventfp) : NULL;
-		} else
-			filep = eventfp;
+		swap(ctx, vq->error_ctx);
 		break;
 	case VHOST_SET_VRING_ENDIAN:
 		r = vhost_set_vring_endian(vq, argp);
@@ -1551,7 +1525,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp)
 	if (pollstop && vq->handle_kick)
 		vhost_poll_stop(&vq->poll);
 
-	if (ctx)
+	if (!IS_ERR_OR_NULL(ctx))
 		eventfd_ctx_put(ctx);
 	if (filep)
 		fput(filep);
@@ -1594,8 +1568,7 @@ EXPORT_SYMBOL_GPL(vhost_init_device_iotlb);
 /* Caller must have device mutex */
 long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
 {
-	struct file *eventfp, *filep = NULL;
-	struct eventfd_ctx *ctx = NULL;
+	struct eventfd_ctx *ctx;
 	u64 p;
 	long r;
 	int i, fd;
@@ -1641,19 +1614,12 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
 		r = get_user(fd, (int __user *)argp);
 		if (r < 0)
 			break;
-		eventfp = fd == -1 ? NULL : eventfd_fget(fd);
-		if (IS_ERR(eventfp)) {
-			r = PTR_ERR(eventfp);
+		ctx = fd == -1 ? NULL : eventfd_ctx_fdget(fd);
+		if (IS_ERR(ctx)) {
+			r = PTR_ERR(ctx);
 			break;
 		}
-		if (eventfp != d->log_file) {
-			filep = d->log_file;
-			d->log_file = eventfp;
-			ctx = d->log_ctx;
-			d->log_ctx = eventfp ?
-				eventfd_ctx_fileget(eventfp) : NULL;
-		} else
-			filep = eventfp;
+		swap(ctx, d->log_ctx);
 		for (i = 0; i < d->nvqs; ++i) {
 			mutex_lock(&d->vqs[i]->mutex);
 			d->vqs[i]->log_ctx = d->log_ctx;
@@ -1661,8 +1627,6 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
 		}
 		if (ctx)
 			eventfd_ctx_put(ctx);
-		if (filep)
-			fput(filep);
 		break;
 	default:
 		r = -ENOIOCTLCMD;
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 7876a3d..ac4b605 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -20,10 +20,6 @@ typedef void (*vhost_work_fn_t)(struct vhost_work *work);
 struct vhost_work {
 	struct llist_node	  node;
 	vhost_work_fn_t		  fn;
-	wait_queue_head_t	  done;
-	int			  flushing;
-	unsigned		  queue_seq;
-	unsigned		  done_seq;
 	unsigned long		  flags;
 };
 
@@ -96,8 +92,6 @@ struct vhost_virtqueue {
 	struct vring_used __user *used;
 	const struct vhost_umem_node *meta_iotlb[VHOST_NUM_ADDRS];
 	struct file *kick;
-	struct file *call;
-	struct file *error;
 	struct eventfd_ctx *call_ctx;
 	struct eventfd_ctx *error_ctx;
 	struct eventfd_ctx *log_ctx;
@@ -163,7 +157,6 @@ struct vhost_dev {
 	struct mutex mutex;
 	struct vhost_virtqueue **vqs;
 	int nvqs;
-	struct file *log_file;
 	struct eventfd_ctx *log_ctx;
 	struct llist_head work_list;
 	struct task_struct *worker;
@@ -181,7 +174,7 @@ bool vhost_dev_has_owner(struct vhost_dev *dev);
 long vhost_dev_check_owner(struct vhost_dev *);
 struct vhost_umem *vhost_dev_reset_owner_prepare(void);
 void vhost_dev_reset_owner(struct vhost_dev *, struct vhost_umem *);
-void vhost_dev_cleanup(struct vhost_dev *, bool locked);
+void vhost_dev_cleanup(struct vhost_dev *);
 void vhost_dev_stop(struct vhost_dev *);
 long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, void __user *argp);
 long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp);
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 5a5e981..0d14e2f 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -599,7 +599,7 @@ static int vhost_vsock_dev_release(struct inode *inode, struct file *file)
 	}
 	spin_unlock_bh(&vsock->send_pkt_list_lock);
 
-	vhost_dev_cleanup(&vsock->dev, false);
+	vhost_dev_cleanup(&vsock->dev);
 	kfree(vsock->dev.vqs);
 	vhost_vsock_free(vsock);
 	return 0;
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
index 9269d56..b90ef96 100644
--- a/drivers/video/console/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -67,7 +67,6 @@ const struct consw dummy_con = {
     .con_switch =	DUMMY,
     .con_blank =	DUMMY,
     .con_font_set =	DUMMY,
-    .con_font_get =	DUMMY,
     .con_font_default =	DUMMY,
     .con_font_copy =	DUMMY,
 };
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 445b1dc..a17ba14 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -422,7 +422,10 @@ static const char *vgacon_startup(void)
 		vga_video_port_val = VGA_CRT_DM;
 		if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) {
 			static struct resource ega_console_resource =
-			    { .name = "ega", .start = 0x3B0, .end = 0x3BF };
+			    { .name	= "ega",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3B0,
+			      .end	= 0x3BF };
 			vga_video_type = VIDEO_TYPE_EGAM;
 			vga_vram_size = 0x8000;
 			display_desc = "EGA+";
@@ -430,9 +433,15 @@ static const char *vgacon_startup(void)
 					 &ega_console_resource);
 		} else {
 			static struct resource mda1_console_resource =
-			    { .name = "mda", .start = 0x3B0, .end = 0x3BB };
+			    { .name	= "mda",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3B0,
+			      .end	= 0x3BB };
 			static struct resource mda2_console_resource =
-			    { .name = "mda", .start = 0x3BF, .end = 0x3BF };
+			    { .name	= "mda",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3BF,
+			      .end	= 0x3BF };
 			vga_video_type = VIDEO_TYPE_MDA;
 			vga_vram_size = 0x2000;
 			display_desc = "*MDA";
@@ -454,15 +463,21 @@ static const char *vgacon_startup(void)
 			vga_vram_size = 0x8000;
 
 			if (!screen_info.orig_video_isVGA) {
-				static struct resource ega_console_resource
-				    = { .name = "ega", .start = 0x3C0, .end = 0x3DF };
+				static struct resource ega_console_resource =
+				    { .name	= "ega",
+				      .flags	= IORESOURCE_IO,
+				      .start	= 0x3C0,
+				      .end	= 0x3DF };
 				vga_video_type = VIDEO_TYPE_EGAC;
 				display_desc = "EGA";
 				request_resource(&ioport_resource,
 						 &ega_console_resource);
 			} else {
-				static struct resource vga_console_resource
-				    = { .name = "vga+", .start = 0x3C0, .end = 0x3DF };
+				static struct resource vga_console_resource =
+				    { .name	= "vga+",
+				      .flags	= IORESOURCE_IO,
+				      .start	= 0x3C0,
+				      .end	= 0x3DF };
 				vga_video_type = VIDEO_TYPE_VGAC;
 				display_desc = "VGA+";
 				request_resource(&ioport_resource,
@@ -494,7 +509,10 @@ static const char *vgacon_startup(void)
 			}
 		} else {
 			static struct resource cga_console_resource =
-			    { .name = "cga", .start = 0x3D4, .end = 0x3D5 };
+			    { .name	= "cga",
+			      .flags	= IORESOURCE_IO,
+			      .start	= 0x3D4,
+			      .end	= 0x3D5 };
 			vga_video_type = VIDEO_TYPE_CGA;
 			vga_vram_size = 0x2000;
 			display_desc = "*CGA";
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 2566cfb..6962b45 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1188,7 +1188,7 @@
           830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
           Say Y if you have and plan to use such a board.
 
-	  To make FB_INTELFB=Y work you need to say AGP_INTEL=y too.
+	  To make FB_INTEL=Y work you need to say AGP_INTEL=y too.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called intelfb.
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index e06358d..3dee267 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -1119,7 +1119,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
 		goto put_display_node;
 	}
 
-	timings_np = of_find_node_by_name(display_np, "display-timings");
+	timings_np = of_get_child_by_name(display_np, "display-timings");
 	if (!timings_np) {
 		dev_err(dev, "failed to find display-timings node\n");
 		ret = -ENODEV;
@@ -1140,6 +1140,12 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
 		fb_add_videomode(&fb_vm, &info->modelist);
 	}
 
+	/*
+	 * FIXME: Make sure we are not referencing any fields in display_np
+	 * and timings_np and drop our references to them before returning to
+	 * avoid leaking the nodes on probe deferral and driver unbind.
+	 */
+
 	return 0;
 
 put_timings_node:
diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
index 4d77dae..87608c0 100644
--- a/drivers/video/fbdev/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
@@ -583,8 +583,8 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
 	int hTotal, vTotal, num, denom, m, n;
 	unsigned long long hz, vclk;
 	long xtal;
-	struct timeval start_tv, stop_tv;
-	long total_secs, total_usecs;
+	ktime_t start_time, stop_time;
+	u64 total_usecs;
 	int i;
 
 	/* Ugh, we cut interrupts, bad bad bad, but we want some precision
@@ -600,7 +600,7 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
 		if (((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0)
 			break;
 
-	do_gettimeofday(&start_tv);
+	start_time = ktime_get();
 
 	for(i=0; i<1000000; i++)
 		if (((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) != 0)
@@ -610,18 +610,14 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
 		if (((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0)
 			break;
 	
-	do_gettimeofday(&stop_tv);
+	stop_time = ktime_get();
 	
 	local_irq_enable();
 
-	total_secs = stop_tv.tv_sec - start_tv.tv_sec;
-	if (total_secs > 10)
+	total_usecs = ktime_us_delta(stop_time, start_time);
+	if (total_usecs >= 10 * USEC_PER_SEC || total_usecs == 0)
 		return -1;
-	total_usecs = stop_tv.tv_usec - start_tv.tv_usec;
-	total_usecs += total_secs * 1000000;
-	if (total_usecs < 0)
-		total_usecs = -total_usecs;
-	hz = 1000000/total_usecs;
+	hz = USEC_PER_SEC/(u32)total_usecs;
  
 	hTotal = ((INREG(CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8;
 	vTotal = ((INREG(CRTC_V_TOTAL_DISP) & 0x3ff) + 1);
diff --git a/drivers/video/fbdev/au1200fb.h b/drivers/video/fbdev/au1200fb.h
index e267271..b34fff3 100644
--- a/drivers/video/fbdev/au1200fb.h
+++ b/drivers/video/fbdev/au1200fb.h
@@ -284,289 +284,3 @@ struct au1200_lcd {
 
 /********************************************************************/
 #endif /* _AU1200LCD_H */
-/*
- * BRIEF MODULE DESCRIPTION
- *	Hardware definitions for the Au1200 LCD controller
- *
- * Copyright 2004 AMD
- * Author:	AMD
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the	License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
- *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
- *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _AU1200LCD_H
-#define _AU1200LCD_H
-
-/********************************************************************/
-#define AU1200_LCD_ADDR		0xB5000000
-
-#define uint8 unsigned char
-#define uint32 unsigned int
-
-struct au1200_lcd {
-	volatile uint32	reserved0;
-	volatile uint32	screen;
-	volatile uint32	backcolor;
-	volatile uint32	horztiming;
-	volatile uint32	verttiming;
-	volatile uint32	clkcontrol;
-	volatile uint32	pwmdiv;
-	volatile uint32	pwmhi;
-	volatile uint32	reserved1;
-	volatile uint32	winenable;
-	volatile uint32	colorkey;
-	volatile uint32	colorkeymsk;
-	struct
-	{
-		volatile uint32	cursorctrl;
-		volatile uint32	cursorpos;
-		volatile uint32	cursorcolor0;
-		volatile uint32	cursorcolor1;
-		volatile uint32	cursorcolor2;
-		uint32	cursorcolor3;
-	} hwc;
-	volatile uint32	intstatus;
-	volatile uint32	intenable;
-	volatile uint32	outmask;
-	volatile uint32	fifoctrl;
-	uint32	reserved2[(0x0100-0x0058)/4];
-	struct
-	{
-		volatile uint32	winctrl0;
-		volatile uint32	winctrl1;
-		volatile uint32	winctrl2;
-		volatile uint32	winbuf0;
-		volatile uint32	winbuf1;
-		volatile uint32	winbufctrl;
-		uint32	winreserved0;
-		uint32	winreserved1;
-	} window[4];
-
-	uint32	reserved3[(0x0400-0x0180)/4];
-
-	volatile uint32	palette[(0x0800-0x0400)/4];
-
-	volatile uint8	cursorpattern[256];
-};
-
-/* lcd_screen */
-#define LCD_SCREEN_SEN		(1<<31)
-#define LCD_SCREEN_SX		(0x07FF<<19)
-#define LCD_SCREEN_SY		(0x07FF<< 8)
-#define LCD_SCREEN_SWP		(1<<7)
-#define LCD_SCREEN_SWD		(1<<6)
-#define LCD_SCREEN_PT		(7<<0)
-#define LCD_SCREEN_PT_TFT	(0<<0)
-#define LCD_SCREEN_SX_N(WIDTH)	((WIDTH-1)<<19)
-#define LCD_SCREEN_SY_N(HEIGHT)	((HEIGHT-1)<<8)
-#define LCD_SCREEN_PT_CSTN	(1<<0)
-#define LCD_SCREEN_PT_CDSTN	(2<<0)
-#define LCD_SCREEN_PT_M8STN	(3<<0)
-#define LCD_SCREEN_PT_M4STN	(4<<0)
-
-/* lcd_backcolor */
-#define LCD_BACKCOLOR_SBGR		(0xFF<<16)
-#define LCD_BACKCOLOR_SBGG		(0xFF<<8)
-#define LCD_BACKCOLOR_SBGB		(0xFF<<0)
-#define LCD_BACKCOLOR_SBGR_N(N)	((N)<<16)
-#define LCD_BACKCOLOR_SBGG_N(N)	((N)<<8)
-#define LCD_BACKCOLOR_SBGB_N(N)	((N)<<0)
-
-/* lcd_winenable */
-#define LCD_WINENABLE_WEN3		(1<<3)
-#define LCD_WINENABLE_WEN2		(1<<2)
-#define LCD_WINENABLE_WEN1		(1<<1)
-#define LCD_WINENABLE_WEN0		(1<<0)
-
-/* lcd_colorkey */
-#define LCD_COLORKEY_CKR		(0xFF<<16)
-#define LCD_COLORKEY_CKG		(0xFF<<8)
-#define LCD_COLORKEY_CKB		(0xFF<<0)
-#define LCD_COLORKEY_CKR_N(N)	((N)<<16)
-#define LCD_COLORKEY_CKG_N(N)	((N)<<8)
-#define LCD_COLORKEY_CKB_N(N)	((N)<<0)
-
-/* lcd_colorkeymsk */
-#define LCD_COLORKEYMSK_CKMR		(0xFF<<16)
-#define LCD_COLORKEYMSK_CKMG		(0xFF<<8)
-#define LCD_COLORKEYMSK_CKMB		(0xFF<<0)
-#define LCD_COLORKEYMSK_CKMR_N(N)	((N)<<16)
-#define LCD_COLORKEYMSK_CKMG_N(N)	((N)<<8)
-#define LCD_COLORKEYMSK_CKMB_N(N)	((N)<<0)
-
-/* lcd windows control 0 */
-#define LCD_WINCTRL0_OX		(0x07FF<<21)
-#define LCD_WINCTRL0_OY		(0x07FF<<10)
-#define LCD_WINCTRL0_A		(0x00FF<<2)
-#define LCD_WINCTRL0_AEN	(1<<1)
-#define LCD_WINCTRL0_OX_N(N) ((N)<<21)
-#define LCD_WINCTRL0_OY_N(N) ((N)<<10)
-#define LCD_WINCTRL0_A_N(N) ((N)<<2)
-
-/* lcd windows control 1 */
-#define LCD_WINCTRL1_PRI	(3<<30)
-#define LCD_WINCTRL1_PIPE	(1<<29)
-#define LCD_WINCTRL1_FRM	(0xF<<25)
-#define LCD_WINCTRL1_CCO	(1<<24)
-#define LCD_WINCTRL1_PO		(3<<22)
-#define LCD_WINCTRL1_SZX	(0x07FF<<11)
-#define LCD_WINCTRL1_SZY	(0x07FF<<0)
-#define LCD_WINCTRL1_FRM_1BPP	(0<<25)
-#define LCD_WINCTRL1_FRM_2BPP	(1<<25)
-#define LCD_WINCTRL1_FRM_4BPP	(2<<25)
-#define LCD_WINCTRL1_FRM_8BPP	(3<<25)
-#define LCD_WINCTRL1_FRM_12BPP	(4<<25)
-#define LCD_WINCTRL1_FRM_16BPP655	(5<<25)
-#define LCD_WINCTRL1_FRM_16BPP565	(6<<25)
-#define LCD_WINCTRL1_FRM_16BPP556	(7<<25)
-#define LCD_WINCTRL1_FRM_16BPPI1555	(8<<25)
-#define LCD_WINCTRL1_FRM_16BPPI5551	(9<<25)
-#define LCD_WINCTRL1_FRM_16BPPA1555	(10<<25)
-#define LCD_WINCTRL1_FRM_16BPPA5551	(11<<25)
-#define LCD_WINCTRL1_FRM_24BPP		(12<<25)
-#define LCD_WINCTRL1_FRM_32BPP		(13<<25)
-#define LCD_WINCTRL1_PRI_N(N)	((N)<<30)
-#define LCD_WINCTRL1_PO_00		(0<<22)
-#define LCD_WINCTRL1_PO_01		(1<<22)
-#define LCD_WINCTRL1_PO_10		(2<<22)
-#define LCD_WINCTRL1_PO_11		(3<<22)
-#define LCD_WINCTRL1_SZX_N(N)	((N-1)<<11)
-#define LCD_WINCTRL1_SZY_N(N)	((N-1)<<0)
-
-/* lcd windows control 2 */
-#define LCD_WINCTRL2_CKMODE		(3<<24)
-#define LCD_WINCTRL2_DBM		(1<<23)
-#define LCD_WINCTRL2_RAM		(3<<21)
-#define LCD_WINCTRL2_BX			(0x1FFF<<8)
-#define LCD_WINCTRL2_SCX		(0xF<<4)
-#define LCD_WINCTRL2_SCY		(0xF<<0)
-#define LCD_WINCTRL2_CKMODE_00		(0<<24)
-#define LCD_WINCTRL2_CKMODE_01		(1<<24)
-#define LCD_WINCTRL2_CKMODE_10		(2<<24)
-#define LCD_WINCTRL2_CKMODE_11		(3<<24)
-#define LCD_WINCTRL2_RAM_NONE		(0<<21)
-#define LCD_WINCTRL2_RAM_PALETTE	(1<<21)
-#define LCD_WINCTRL2_RAM_GAMMA		(2<<21)
-#define LCD_WINCTRL2_RAM_BUFFER		(3<<21)
-#define LCD_WINCTRL2_BX_N(N)	((N)<<8)
-#define LCD_WINCTRL2_SCX_1		(0<<4)
-#define LCD_WINCTRL2_SCX_2		(1<<4)
-#define LCD_WINCTRL2_SCX_4		(2<<4)
-#define LCD_WINCTRL2_SCY_1		(0<<0)
-#define LCD_WINCTRL2_SCY_2		(1<<0)
-#define LCD_WINCTRL2_SCY_4		(2<<0)
-
-/* lcd windows buffer control */
-#define LCD_WINBUFCTRL_DB		(1<<1)
-#define LCD_WINBUFCTRL_DBN		(1<<0)
-
-/* lcd_intstatus, lcd_intenable */
-#define LCD_INT_IFO				(0xF<<14)
-#define LCD_INT_IFU				(0xF<<10)
-#define LCD_INT_OFO				(1<<9)
-#define LCD_INT_OFU				(1<<8)
-#define LCD_INT_WAIT			(1<<3)
-#define LCD_INT_SD				(1<<2)
-#define LCD_INT_SA				(1<<1)
-#define LCD_INT_SS				(1<<0)
-
-/* lcd_horztiming */
-#define LCD_HORZTIMING_HND2		(0x1FF<<18)
-#define LCD_HORZTIMING_HND1		(0x1FF<<9)
-#define LCD_HORZTIMING_HPW		(0x1FF<<0)
-#define LCD_HORZTIMING_HND2_N(N)(((N)-1)<<18)
-#define LCD_HORZTIMING_HND1_N(N)(((N)-1)<<9)
-#define LCD_HORZTIMING_HPW_N(N)	(((N)-1)<<0)
-
-/* lcd_verttiming */
-#define LCD_VERTTIMING_VND2		(0x1FF<<18)
-#define LCD_VERTTIMING_VND1		(0x1FF<<9)
-#define LCD_VERTTIMING_VPW		(0x1FF<<0)
-#define LCD_VERTTIMING_VND2_N(N)(((N)-1)<<18)
-#define LCD_VERTTIMING_VND1_N(N)(((N)-1)<<9)
-#define LCD_VERTTIMING_VPW_N(N)	(((N)-1)<<0)
-
-/* lcd_clkcontrol */
-#define LCD_CLKCONTROL_EXT		(1<<22)
-#define LCD_CLKCONTROL_DELAY	(3<<20)
-#define LCD_CLKCONTROL_CDD		(1<<19)
-#define LCD_CLKCONTROL_IB		(1<<18)
-#define LCD_CLKCONTROL_IC		(1<<17)
-#define LCD_CLKCONTROL_IH		(1<<16)
-#define LCD_CLKCONTROL_IV		(1<<15)
-#define LCD_CLKCONTROL_BF		(0x1F<<10)
-#define LCD_CLKCONTROL_PCD		(0x3FF<<0)
-#define LCD_CLKCONTROL_BF_N(N)	(((N)-1)<<10)
-#define LCD_CLKCONTROL_PCD_N(N)	((N)<<0)
-
-/* lcd_pwmdiv */
-#define LCD_PWMDIV_EN			(1<<31)
-#define LCD_PWMDIV_PWMDIV		(0x1FFFF<<0)
-#define LCD_PWMDIV_PWMDIV_N(N)	((N)<<0)
-
-/* lcd_pwmhi */
-#define LCD_PWMHI_PWMHI1		(0xFFFF<<16)
-#define LCD_PWMHI_PWMHI0		(0xFFFF<<0)
-#define LCD_PWMHI_PWMHI1_N(N)	((N)<<16)
-#define LCD_PWMHI_PWMHI0_N(N)	((N)<<0)
-
-/* lcd_hwccon */
-#define LCD_HWCCON_EN			(1<<0)
-
-/* lcd_cursorpos */
-#define LCD_CURSORPOS_HWCXOFF		(0x1F<<27)
-#define LCD_CURSORPOS_HWCXPOS		(0x07FF<<16)
-#define LCD_CURSORPOS_HWCYOFF		(0x1F<<11)
-#define LCD_CURSORPOS_HWCYPOS		(0x07FF<<0)
-#define LCD_CURSORPOS_HWCXOFF_N(N)	((N)<<27)
-#define LCD_CURSORPOS_HWCXPOS_N(N)	((N)<<16)
-#define LCD_CURSORPOS_HWCYOFF_N(N)	((N)<<11)
-#define LCD_CURSORPOS_HWCYPOS_N(N)	((N)<<0)
-
-/* lcd_cursorcolor */
-#define LCD_CURSORCOLOR_HWCA		(0xFF<<24)
-#define LCD_CURSORCOLOR_HWCR		(0xFF<<16)
-#define LCD_CURSORCOLOR_HWCG		(0xFF<<8)
-#define LCD_CURSORCOLOR_HWCB		(0xFF<<0)
-#define LCD_CURSORCOLOR_HWCA_N(N)	((N)<<24)
-#define LCD_CURSORCOLOR_HWCR_N(N)	((N)<<16)
-#define LCD_CURSORCOLOR_HWCG_N(N)	((N)<<8)
-#define LCD_CURSORCOLOR_HWCB_N(N)	((N)<<0)
-
-/* lcd_fifoctrl */
-#define LCD_FIFOCTRL_F3IF		(1<<29)
-#define LCD_FIFOCTRL_F3REQ		(0x1F<<24)
-#define LCD_FIFOCTRL_F2IF		(1<<29)
-#define LCD_FIFOCTRL_F2REQ		(0x1F<<16)
-#define LCD_FIFOCTRL_F1IF		(1<<29)
-#define LCD_FIFOCTRL_F1REQ		(0x1F<<8)
-#define LCD_FIFOCTRL_F0IF		(1<<29)
-#define LCD_FIFOCTRL_F0REQ		(0x1F<<0)
-#define LCD_FIFOCTRL_F3REQ_N(N)	((N-1)<<24)
-#define LCD_FIFOCTRL_F2REQ_N(N)	((N-1)<<16)
-#define LCD_FIFOCTRL_F1REQ_N(N)	((N-1)<<8)
-#define LCD_FIFOCTRL_F0REQ_N(N)	((N-1)<<0)
-
-/* lcd_outmask */
-#define LCD_OUTMASK_MASK		(0x00FFFFFF)
-
-/********************************************************************/
-#endif /* _AU1200LCD_H */
diff --git a/drivers/video/fbdev/auo_k190x.c b/drivers/video/fbdev/auo_k190x.c
index 1e383c5..9d24d1b 100644
--- a/drivers/video/fbdev/auo_k190x.c
+++ b/drivers/video/fbdev/auo_k190x.c
@@ -1056,13 +1056,12 @@ int auok190x_common_probe(struct platform_device *pdev,
 	/* videomemory handling */
 
 	videomemorysize = roundup((panel->w * panel->h) * 2, PAGE_SIZE);
-	videomemory = vmalloc(videomemorysize);
+	videomemory = vzalloc(videomemorysize);
 	if (!videomemory) {
 		ret = -ENOMEM;
 		goto err_irq;
 	}
 
-	memset(videomemory, 0, videomemorysize);
 	info->screen_base = (char *)videomemory;
 	info->fix.smem_len = videomemorysize;
 
diff --git a/drivers/video/fbdev/intelfb/intelfbhw.c b/drivers/video/fbdev/intelfb/intelfbhw.c
index 83fec57..57aff74 100644
--- a/drivers/video/fbdev/intelfb/intelfbhw.c
+++ b/drivers/video/fbdev/intelfb/intelfbhw.c
@@ -181,7 +181,9 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
 		return 1;
 
 	/* Find the bridge device.  It is always 0:0.0 */
-	if (!(bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)))) {
+	bridge_dev = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus), 0,
+						 PCI_DEVFN(0, 0));
+	if (!bridge_dev) {
 		ERR_MSG("cannot find bridge device\n");
 		return 1;
 	}
diff --git a/drivers/video/fbdev/mmp/core.c b/drivers/video/fbdev/mmp/core.c
index a0f4960..3a6bb65 100644
--- a/drivers/video/fbdev/mmp/core.c
+++ b/drivers/video/fbdev/mmp/core.c
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/export.h>
+#include <linux/module.h>
 #include <video/mmp_disp.h>
 
 static struct mmp_overlay *path_get_overlay(struct mmp_path *path,
@@ -249,3 +250,7 @@ void mmp_unregister_path(struct mmp_path *path)
 	mutex_unlock(&disp_lock);
 }
 EXPORT_SYMBOL_GPL(mmp_unregister_path);
+
+MODULE_AUTHOR("Zhou Zhu <zzhu3@marvell.com>");
+MODULE_DESCRIPTION("Marvell MMP display framework");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c
index 79b1dc7..246bea3 100644
--- a/drivers/video/fbdev/mxsfb.c
+++ b/drivers/video/fbdev/mxsfb.c
@@ -169,7 +169,6 @@ struct mxsfb_devdata {
 };
 
 struct mxsfb_info {
-	struct fb_info fb_info;
 	struct platform_device *pdev;
 	struct clk *clk;
 	struct clk *clk_axi;
@@ -208,8 +207,6 @@ static const struct mxsfb_devdata mxsfb_devdata[] = {
 	},
 };
 
-#define to_imxfb_host(x) (container_of(x, struct mxsfb_info, fb_info))
-
 /* mask and shift depends on architecture */
 static inline u32 set_hsync_pulse_width(struct mxsfb_info *host, unsigned val)
 {
@@ -269,7 +266,7 @@ static inline unsigned chan_to_field(unsigned chan, struct fb_bitfield *bf)
 static int mxsfb_check_var(struct fb_var_screeninfo *var,
 		struct fb_info *fb_info)
 {
-	struct mxsfb_info *host = to_imxfb_host(fb_info);
+	struct mxsfb_info *host = fb_info->par;
 	const struct fb_bitfield *rgb = NULL;
 
 	if (var->xres < MIN_XRES)
@@ -330,7 +327,7 @@ static inline void mxsfb_disable_axi_clk(struct mxsfb_info *host)
 
 static void mxsfb_enable_controller(struct fb_info *fb_info)
 {
-	struct mxsfb_info *host = to_imxfb_host(fb_info);
+	struct mxsfb_info *host = fb_info->par;
 	u32 reg;
 	int ret;
 
@@ -367,7 +364,7 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
 
 static void mxsfb_disable_controller(struct fb_info *fb_info)
 {
-	struct mxsfb_info *host = to_imxfb_host(fb_info);
+	struct mxsfb_info *host = fb_info->par;
 	unsigned loop;
 	u32 reg;
 	int ret;
@@ -409,7 +406,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
 
 static int mxsfb_set_par(struct fb_info *fb_info)
 {
-	struct mxsfb_info *host = to_imxfb_host(fb_info);
+	struct mxsfb_info *host = fb_info->par;
 	u32 ctrl, vdctrl0, vdctrl4;
 	int line_size, fb_size;
 	int reenable = 0;
@@ -569,7 +566,7 @@ static int mxsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 
 static int mxsfb_blank(int blank, struct fb_info *fb_info)
 {
-	struct mxsfb_info *host = to_imxfb_host(fb_info);
+	struct mxsfb_info *host = fb_info->par;
 
 	switch (blank) {
 	case FB_BLANK_POWERDOWN:
@@ -591,7 +588,7 @@ static int mxsfb_blank(int blank, struct fb_info *fb_info)
 static int mxsfb_pan_display(struct fb_var_screeninfo *var,
 		struct fb_info *fb_info)
 {
-	struct mxsfb_info *host = to_imxfb_host(fb_info);
+	struct mxsfb_info *host = fb_info->par;
 	unsigned offset;
 
 	if (var->xoffset != 0)
@@ -622,10 +619,10 @@ static struct fb_ops mxsfb_ops = {
 	.fb_imageblit = cfb_imageblit,
 };
 
-static int mxsfb_restore_mode(struct mxsfb_info *host,
+static int mxsfb_restore_mode(struct fb_info *fb_info,
 			struct fb_videomode *vmode)
 {
-	struct fb_info *fb_info = &host->fb_info;
+	struct mxsfb_info *host = fb_info->par;
 	unsigned line_count;
 	unsigned period;
 	unsigned long pa, fbsize;
@@ -726,10 +723,10 @@ static int mxsfb_restore_mode(struct mxsfb_info *host,
 	return ret;
 }
 
-static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host,
+static int mxsfb_init_fbinfo_dt(struct fb_info *fb_info,
 				struct fb_videomode *vmode)
 {
-	struct fb_info *fb_info = &host->fb_info;
+	struct mxsfb_info *host = fb_info->par;
 	struct fb_var_screeninfo *var = &fb_info->var;
 	struct device *dev = &host->pdev->dev;
 	struct device_node *np = host->pdev->dev.of_node;
@@ -805,12 +802,12 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host,
 	return ret;
 }
 
-static int mxsfb_init_fbinfo(struct mxsfb_info *host,
+static int mxsfb_init_fbinfo(struct fb_info *fb_info,
 			struct fb_videomode *vmode)
 {
 	int ret;
+	struct mxsfb_info *host = fb_info->par;
 	struct device *dev = &host->pdev->dev;
-	struct fb_info *fb_info = &host->fb_info;
 	struct fb_var_screeninfo *var = &fb_info->var;
 	dma_addr_t fb_phys;
 	void *fb_virt;
@@ -824,7 +821,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host,
 	fb_info->fix.visual = FB_VISUAL_TRUECOLOR,
 	fb_info->fix.accel = FB_ACCEL_NONE;
 
-	ret = mxsfb_init_fbinfo_dt(host, vmode);
+	ret = mxsfb_init_fbinfo_dt(fb_info, vmode);
 	if (ret)
 		return ret;
 
@@ -843,16 +840,16 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host,
 	fb_info->screen_base = fb_virt;
 	fb_info->screen_size = fb_info->fix.smem_len = fb_size;
 
-	if (mxsfb_restore_mode(host, vmode))
+	if (mxsfb_restore_mode(fb_info, vmode))
 		memset(fb_virt, 0, fb_size);
 
 	return 0;
 }
 
-static void mxsfb_free_videomem(struct mxsfb_info *host)
+static void mxsfb_free_videomem(struct fb_info *fb_info)
 {
+	struct mxsfb_info *host = fb_info->par;
 	struct device *dev = &host->pdev->dev;
-	struct fb_info *fb_info = &host->fb_info;
 
 	dma_free_wc(dev, fb_info->screen_size, fb_info->screen_base,
 		    fb_info->fix.smem_start);
@@ -902,7 +899,7 @@ static int mxsfb_probe(struct platform_device *pdev)
 	if (mode == NULL)
 		return -ENOMEM;
 
-	host = to_imxfb_host(fb_info);
+	host = fb_info->par;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	host->base = devm_ioremap_resource(&pdev->dev, res);
@@ -941,7 +938,7 @@ static int mxsfb_probe(struct platform_device *pdev)
 		goto fb_release;
 	}
 
-	ret = mxsfb_init_fbinfo(host, mode);
+	ret = mxsfb_init_fbinfo(fb_info, mode);
 	if (ret != 0)
 		goto fb_release;
 
@@ -982,13 +979,13 @@ static int mxsfb_probe(struct platform_device *pdev)
 static int mxsfb_remove(struct platform_device *pdev)
 {
 	struct fb_info *fb_info = platform_get_drvdata(pdev);
-	struct mxsfb_info *host = to_imxfb_host(fb_info);
+	struct mxsfb_info *host = fb_info->par;
 
 	if (host->enabled)
 		mxsfb_disable_controller(fb_info);
 
 	unregister_framebuffer(fb_info);
-	mxsfb_free_videomem(host);
+	mxsfb_free_videomem(fb_info);
 
 	framebuffer_release(fb_info);
 
@@ -998,7 +995,7 @@ static int mxsfb_remove(struct platform_device *pdev)
 static void mxsfb_shutdown(struct platform_device *pdev)
 {
 	struct fb_info *fb_info = platform_get_drvdata(pdev);
-	struct mxsfb_info *host = to_imxfb_host(fb_info);
+	struct mxsfb_info *host = fb_info->par;
 
 	mxsfb_enable_axi_clk(host);
 
diff --git a/drivers/video/fbdev/nvidia/nv_hw.c b/drivers/video/fbdev/nvidia/nv_hw.c
index 81c80ac3..8335da4 100644
--- a/drivers/video/fbdev/nvidia/nv_hw.c
+++ b/drivers/video/fbdev/nvidia/nv_hw.c
@@ -683,10 +683,11 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
 	nv10_sim_state sim_data;
 	unsigned int M, N, P, pll, MClk, NVClk, memctrl;
 	struct pci_dev *dev;
+	int domain = pci_domain_nr(par->pci_dev->bus);
 
 	if ((par->Chipset & 0x0FF0) == 0x01A0) {
 		unsigned int uMClkPostDiv;
-		dev = pci_get_bus_and_slot(0, 3);
+		dev = pci_get_domain_bus_and_slot(domain, 0, 3);
 		pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
 		uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
 
@@ -694,7 +695,7 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
 			uMClkPostDiv = 4;
 		MClk = 400000 / uMClkPostDiv;
 	} else {
-		dev = pci_get_bus_and_slot(0, 5);
+		dev = pci_get_domain_bus_and_slot(domain, 0, 5);
 		pci_read_config_dword(dev, 0x4c, &MClk);
 		MClk /= 1000;
 	}
@@ -707,13 +708,13 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
 	sim_data.pix_bpp = (char)pixelDepth;
 	sim_data.enable_video = 0;
 	sim_data.enable_mp = 0;
-	dev = pci_get_bus_and_slot(0, 1);
+	dev = pci_get_domain_bus_and_slot(domain, 0, 1);
 	pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
 	pci_dev_put(dev);
 	sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
 	sim_data.memory_width = 64;
 
-	dev = pci_get_bus_and_slot(0, 3);
+	dev = pci_get_domain_bus_and_slot(domain, 0, 3);
 	pci_read_config_dword(dev, 0, &memctrl);
 	pci_dev_put(dev);
 	memctrl >>= 16;
@@ -721,7 +722,7 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
 	if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
 		u32 dimm[3];
 
-		dev = pci_get_bus_and_slot(0, 2);
+		dev = pci_get_domain_bus_and_slot(domain, 0, 2);
 		pci_read_config_dword(dev, 0x40, &dimm[0]);
 		dimm[0] = (dimm[0] >> 8) & 0x4f;
 		pci_read_config_dword(dev, 0x44, &dimm[1]);
diff --git a/drivers/video/fbdev/nvidia/nv_setup.c b/drivers/video/fbdev/nvidia/nv_setup.c
index 2f2e162..b17acd2 100644
--- a/drivers/video/fbdev/nvidia/nv_setup.c
+++ b/drivers/video/fbdev/nvidia/nv_setup.c
@@ -264,7 +264,8 @@ static void nv10GetConfig(struct nvidia_par *par)
 	}
 #endif
 
-	dev = pci_get_bus_and_slot(0, 1);
+	dev = pci_get_domain_bus_and_slot(pci_domain_nr(par->pci_dev->bus),
+					  0, 1);
 	if ((par->Chipset & 0xffff) == 0x01a0) {
 		u32 amt;
 
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dispc.c b/drivers/video/fbdev/omap2/omapfb/dss/dispc.c
index 7a75dfd..fb605ae 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dispc.c
@@ -3976,52 +3976,33 @@ static const struct dispc_features omap54xx_dispc_feats = {
 	.has_writeback		=	true,
 };
 
-static int dispc_init_features(struct platform_device *pdev)
+static const struct dispc_features *dispc_get_features(void)
 {
-	const struct dispc_features *src;
-	struct dispc_features *dst;
-
-	dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
-	if (!dst) {
-		dev_err(&pdev->dev, "Failed to allocate DISPC Features\n");
-		return -ENOMEM;
-	}
-
 	switch (omapdss_get_version()) {
 	case OMAPDSS_VER_OMAP24xx:
-		src = &omap24xx_dispc_feats;
-		break;
+		return &omap24xx_dispc_feats;
 
 	case OMAPDSS_VER_OMAP34xx_ES1:
-		src = &omap34xx_rev1_0_dispc_feats;
-		break;
+		return &omap34xx_rev1_0_dispc_feats;
 
 	case OMAPDSS_VER_OMAP34xx_ES3:
 	case OMAPDSS_VER_OMAP3630:
 	case OMAPDSS_VER_AM35xx:
 	case OMAPDSS_VER_AM43xx:
-		src = &omap34xx_rev3_0_dispc_feats;
-		break;
+		return &omap34xx_rev3_0_dispc_feats;
 
 	case OMAPDSS_VER_OMAP4430_ES1:
 	case OMAPDSS_VER_OMAP4430_ES2:
 	case OMAPDSS_VER_OMAP4:
-		src = &omap44xx_dispc_feats;
-		break;
+		return &omap44xx_dispc_feats;
 
 	case OMAPDSS_VER_OMAP5:
 	case OMAPDSS_VER_DRA7xx:
-		src = &omap54xx_dispc_feats;
-		break;
+		return &omap54xx_dispc_feats;
 
 	default:
-		return -ENODEV;
+		return NULL;
 	}
-
-	memcpy(dst, src, sizeof(*dst));
-	dispc.feat = dst;
-
-	return 0;
 }
 
 static irqreturn_t dispc_irq_handler(int irq, void *arg)
@@ -4078,9 +4059,9 @@ static int dispc_bind(struct device *dev, struct device *master, void *data)
 
 	spin_lock_init(&dispc.control_lock);
 
-	r = dispc_init_features(dispc.pdev);
-	if (r)
-		return r;
+	dispc.feat = dispc_get_features();
+	if (!dispc.feat)
+		return -ENODEV;
 
 	dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
 	if (!dispc_mem) {
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss.c b/drivers/video/fbdev/omap2/omapfb/dss/dss.c
index 48c6500..39fe724 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dss.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dss.c
@@ -887,58 +887,37 @@ static const struct dss_features dra7xx_dss_feats = {
 	.num_ports		=	ARRAY_SIZE(dra7xx_ports),
 };
 
-static int dss_init_features(struct platform_device *pdev)
+static const struct dss_features *dss_get_features(void)
 {
-	const struct dss_features *src;
-	struct dss_features *dst;
-
-	dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
-	if (!dst) {
-		dev_err(&pdev->dev, "Failed to allocate local DSS Features\n");
-		return -ENOMEM;
-	}
-
 	switch (omapdss_get_version()) {
 	case OMAPDSS_VER_OMAP24xx:
-		src = &omap24xx_dss_feats;
-		break;
+		return &omap24xx_dss_feats;
 
 	case OMAPDSS_VER_OMAP34xx_ES1:
 	case OMAPDSS_VER_OMAP34xx_ES3:
 	case OMAPDSS_VER_AM35xx:
-		src = &omap34xx_dss_feats;
-		break;
+		return &omap34xx_dss_feats;
 
 	case OMAPDSS_VER_OMAP3630:
-		src = &omap3630_dss_feats;
-		break;
+		return &omap3630_dss_feats;
 
 	case OMAPDSS_VER_OMAP4430_ES1:
 	case OMAPDSS_VER_OMAP4430_ES2:
 	case OMAPDSS_VER_OMAP4:
-		src = &omap44xx_dss_feats;
-		break;
+		return &omap44xx_dss_feats;
 
 	case OMAPDSS_VER_OMAP5:
-		src = &omap54xx_dss_feats;
-		break;
+		return &omap54xx_dss_feats;
 
 	case OMAPDSS_VER_AM43xx:
-		src = &am43xx_dss_feats;
-		break;
+		return &am43xx_dss_feats;
 
 	case OMAPDSS_VER_DRA7xx:
-		src = &dra7xx_dss_feats;
-		break;
+		return &dra7xx_dss_feats;
 
 	default:
-		return -ENODEV;
+		return NULL;
 	}
-
-	memcpy(dst, src, sizeof(*dst));
-	dss.feat = dst;
-
-	return 0;
 }
 
 static void dss_uninit_ports(struct platform_device *pdev);
@@ -1104,9 +1083,9 @@ static int dss_bind(struct device *dev)
 
 	dss.pdev = pdev;
 
-	r = dss_init_features(dss.pdev);
-	if (r)
-		return r;
+	dss.feat = dss_get_features();
+	if (!dss.feat)
+		return -ENODEV;
 
 	dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
 	if (!dss_mem) {
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
index ec78d61..28de56e 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
@@ -673,10 +673,7 @@ static int hdmi_audio_register(struct device *dev)
 		dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
 		&pdata, sizeof(pdata));
 
-	if (IS_ERR(hdmi.audio_pdev))
-		return PTR_ERR(hdmi.audio_pdev);
-
-	return 0;
+	return PTR_ERR_OR_ZERO(hdmi.audio_pdev);
 }
 
 /* HDMI HW IP initialisation */
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi_phy.c
index 9a13c35..eee09b4b 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi_phy.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi_phy.c
@@ -189,47 +189,30 @@ static const struct hdmi_phy_features omap54xx_phy_feats = {
 	.max_phy	=	186000000,
 };
 
-static int hdmi_phy_init_features(struct platform_device *pdev)
+static const struct hdmi_phy_features *hdmi_phy_get_features(void)
 {
-	struct hdmi_phy_features *dst;
-	const struct hdmi_phy_features *src;
-
-	dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
-	if (!dst) {
-		dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n");
-		return -ENOMEM;
-	}
-
 	switch (omapdss_get_version()) {
 	case OMAPDSS_VER_OMAP4430_ES1:
 	case OMAPDSS_VER_OMAP4430_ES2:
 	case OMAPDSS_VER_OMAP4:
-		src = &omap44xx_phy_feats;
-		break;
+		return &omap44xx_phy_feats;
 
 	case OMAPDSS_VER_OMAP5:
 	case OMAPDSS_VER_DRA7xx:
-		src = &omap54xx_phy_feats;
-		break;
+		return &omap54xx_phy_feats;
 
 	default:
-		return -ENODEV;
+		return NULL;
 	}
-
-	memcpy(dst, src, sizeof(*dst));
-	phy_feat = dst;
-
-	return 0;
 }
 
 int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy)
 {
-	int r;
 	struct resource *res;
 
-	r = hdmi_phy_init_features(pdev);
-	if (r)
-		return r;
+	phy_feat = hdmi_phy_get_features();
+	if (!phy_feat)
+		return -ENODEV;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
 	if (!res) {
diff --git a/drivers/video/fbdev/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c
index 55fbb43..0955622 100644
--- a/drivers/video/fbdev/pxa3xx-gcu.c
+++ b/drivers/video/fbdev/pxa3xx-gcu.c
@@ -104,7 +104,7 @@ struct pxa3xx_gcu_priv {
 	wait_queue_head_t	  wait_idle;
 	wait_queue_head_t	  wait_free;
 	spinlock_t		  spinlock;
-	struct timeval 		  base_time;
+	struct timespec64	  base_time;
 
 	struct pxa3xx_gcu_batch *free;
 	struct pxa3xx_gcu_batch *ready;
@@ -126,18 +126,20 @@ gc_writel(struct pxa3xx_gcu_priv *priv, unsigned int off, unsigned long val)
 
 #define QPRINT(priv, level, msg)					\
 	do {								\
-		struct timeval tv;					\
+		struct timespec64 ts;					\
 		struct pxa3xx_gcu_shared *shared = priv->shared;	\
 		u32 base = gc_readl(priv, REG_GCRBBR);			\
 									\
-		do_gettimeofday(&tv);					\
+		ktime_get_ts64(&ts);					\
+		ts = timespec64_sub(ts, priv->base_time);		\
 									\
-		printk(level "%ld.%03ld.%03ld - %-17s: %-21s (%s, "	\
+		printk(level "%lld.%03ld.%03ld - %-17s: %-21s (%s, "	\
 			"STATUS "					\
 			"0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, "	\
 			"T %5ld)\n",					\
-			tv.tv_sec - priv->base_time.tv_sec,		\
-			tv.tv_usec / 1000, tv.tv_usec % 1000,		\
+			(s64)(ts.tv_sec),				\
+			ts.tv_nsec / NSEC_PER_MSEC,			\
+			(ts.tv_nsec % NSEC_PER_MSEC) / USEC_PER_MSEC,	\
 			__func__, msg,					\
 			shared->hw_running ? "running" : "   idle",	\
 			gc_readl(priv, REG_GCISCR),			\
@@ -164,7 +166,7 @@ pxa3xx_gcu_reset(struct pxa3xx_gcu_priv *priv)
 	priv->shared->buffer_phys = priv->shared_phys;
 	priv->shared->magic = PXA3XX_GCU_SHARED_MAGIC;
 
-	do_gettimeofday(&priv->base_time);
+	ktime_get_ts64(&priv->base_time);
 
 	/* set up the ring buffer pointers */
 	gc_writel(priv, REG_GCRBLR, 0);
diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c
index 1ea78bb..ff82823 100644
--- a/drivers/video/fbdev/riva/fbdev.c
+++ b/drivers/video/fbdev/riva/fbdev.c
@@ -780,7 +780,7 @@ static int riva_load_video_mode(struct fb_info *info)
 	else
 		newmode.misc_output |= 0x80;	
 
-	rc = CalcStateExt(&par->riva, &newmode.ext, bpp, width,
+	rc = CalcStateExt(&par->riva, &newmode.ext, par->pdev, bpp, width,
 			  hDisplaySize, height, dotClock);
 	if (rc)
 		goto out;
diff --git a/drivers/video/fbdev/riva/nv_driver.c b/drivers/video/fbdev/riva/nv_driver.c
index f3694cf..a3d9c66 100644
--- a/drivers/video/fbdev/riva/nv_driver.c
+++ b/drivers/video/fbdev/riva/nv_driver.c
@@ -159,6 +159,7 @@ unsigned long riva_get_memlen(struct riva_par *par)
 	unsigned int chipset = par->Chipset;
 	struct pci_dev* dev;
 	u32 amt;
+	int domain = pci_domain_nr(par->pdev->bus);
 
 	switch (chip->Architecture) {
 	case NV_ARCH_03:
@@ -226,12 +227,12 @@ unsigned long riva_get_memlen(struct riva_par *par)
 	case NV_ARCH_30:
 		if(chipset == NV_CHIP_IGEFORCE2) {
 
-			dev = pci_get_bus_and_slot(0, 1);
+			dev = pci_get_domain_bus_and_slot(domain, 0, 1);
 			pci_read_config_dword(dev, 0x7C, &amt);
 			pci_dev_put(dev);
 			memlen = (((amt >> 6) & 31) + 1) * 1024;
 		} else if (chipset == NV_CHIP_0x01F0) {
-			dev = pci_get_bus_and_slot(0, 1);
+			dev = pci_get_domain_bus_and_slot(domain, 0, 1);
 			pci_read_config_dword(dev, 0x84, &amt);
 			pci_dev_put(dev);
 			memlen = (((amt >> 4) & 127) + 1) * 1024;
@@ -417,6 +418,6 @@ riva_common_setup(struct riva_par *par)
 	}
 	par->riva.flatPanel = (par->FlatPanel > 0) ? TRUE : FALSE;
 
-	RivaGetConfig(&par->riva, par->Chipset);
+	RivaGetConfig(&par->riva, par->pdev, par->Chipset);
 }
 
diff --git a/drivers/video/fbdev/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c
index 8bdf37f..0601c13 100644
--- a/drivers/video/fbdev/riva/riva_hw.c
+++ b/drivers/video/fbdev/riva/riva_hw.c
@@ -1108,7 +1108,8 @@ static void nForceUpdateArbitrationSettings
     unsigned      pixelDepth,
     unsigned     *burst,
     unsigned     *lwm,
-    RIVA_HW_INST *chip
+    RIVA_HW_INST *chip,
+    struct pci_dev *pdev
 )
 {
     nv10_fifo_info fifo_data;
@@ -1116,8 +1117,9 @@ static void nForceUpdateArbitrationSettings
     unsigned int M, N, P, pll, MClk, NVClk;
     unsigned int uMClkPostDiv;
     struct pci_dev *dev;
+    int domain = pci_domain_nr(pdev->bus);
 
-    dev = pci_get_bus_and_slot(0, 3);
+    dev = pci_get_domain_bus_and_slot(domain, 0, 3);
     pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
     pci_dev_put(dev);
     uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
@@ -1132,7 +1134,7 @@ static void nForceUpdateArbitrationSettings
     sim_data.enable_video   = 0;
     sim_data.enable_mp      = 0;
 
-    dev = pci_get_bus_and_slot(0, 1);
+    dev = pci_get_domain_bus_and_slot(domain, 0, 1);
     pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
     pci_dev_put(dev);
     sim_data.memory_type    = (sim_data.memory_type >> 12) & 1;
@@ -1234,6 +1236,7 @@ int CalcStateExt
 (
     RIVA_HW_INST  *chip,
     RIVA_HW_STATE *state,
+    struct pci_dev *pdev,
     int            bpp,
     int            width,
     int            hDisplaySize,
@@ -1300,7 +1303,7 @@ int CalcStateExt
                                           pixelDepth * 8,
                                          &(state->arbitration0),
                                          &(state->arbitration1),
-                                          chip);
+                                          chip, pdev);
             } else {
                 nv10UpdateArbitrationSettings(VClk, 
                                           pixelDepth * 8, 
@@ -2102,10 +2105,12 @@ static void nv4GetConfig
 static void nv10GetConfig
 (
     RIVA_HW_INST *chip,
+    struct pci_dev *pdev,
     unsigned int chipset
 )
 {
     struct pci_dev* dev;
+    int domain = pci_domain_nr(pdev->bus);
     u32 amt;
 
 #ifdef __BIG_ENDIAN
@@ -2118,12 +2123,12 @@ static void nv10GetConfig
      * Fill in chip configuration.
      */
     if(chipset == NV_CHIP_IGEFORCE2) {
-        dev = pci_get_bus_and_slot(0, 1);
+        dev = pci_get_domain_bus_and_slot(domain, 0, 1);
         pci_read_config_dword(dev, 0x7C, &amt);
         pci_dev_put(dev);
         chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
     } else if(chipset == NV_CHIP_0x01F0) {
-        dev = pci_get_bus_and_slot(0, 1);
+        dev = pci_get_domain_bus_and_slot(domain, 0, 1);
         pci_read_config_dword(dev, 0x84, &amt);
         pci_dev_put(dev);
         chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
@@ -2224,6 +2229,7 @@ static void nv10GetConfig
 int RivaGetConfig
 (
     RIVA_HW_INST *chip,
+    struct pci_dev *pdev,
     unsigned int chipset
 )
 {
@@ -2245,7 +2251,7 @@ int RivaGetConfig
         case NV_ARCH_10:
         case NV_ARCH_20:
         case NV_ARCH_30:
-            nv10GetConfig(chip, chipset);
+            nv10GetConfig(chip, pdev, chipset);
             break;
         default:
             return (-1);
diff --git a/drivers/video/fbdev/riva/riva_hw.h b/drivers/video/fbdev/riva/riva_hw.h
index c2769f7..5e7b354 100644
--- a/drivers/video/fbdev/riva/riva_hw.h
+++ b/drivers/video/fbdev/riva/riva_hw.h
@@ -536,6 +536,7 @@ extern int CalcStateExt
 (
     RIVA_HW_INST  *chip,
     RIVA_HW_STATE *state,
+    struct pci_dev *pdev,
     int            bpp,
     int            width,
     int            hDisplaySize,
@@ -546,7 +547,7 @@ extern int CalcStateExt
 /*
  * External routines.
  */
-int RivaGetConfig(RIVA_HW_INST *, unsigned int);
+int RivaGetConfig(RIVA_HW_INST *chip, struct pci_dev *pdev, unsigned int c);
 /*
  * FIFO Free Count. Should attempt to yield processor if RIVA is busy.
  */
diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index 2275e80..8db7085 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1086,8 +1086,7 @@ static int ufx_ops_open(struct fb_info *info, int user)
 
 		struct fb_deferred_io *fbdefio;
 
-		fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL);
-
+		fbdefio = kzalloc(sizeof(*fbdefio), GFP_KERNEL);
 		if (fbdefio) {
 			fbdefio->delay = UFX_DEFIO_WRITE_DELAY;
 			fbdefio->deferred_io = ufx_dpy_deferred_io;
@@ -1875,7 +1874,7 @@ static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size)
 	INIT_LIST_HEAD(&dev->urbs.list);
 
 	while (i < count) {
-		unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL);
+		unode = kzalloc(sizeof(*unode), GFP_KERNEL);
 		if (!unode)
 			break;
 		unode->dev = dev;
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
index d44f142..452a420 100644
--- a/drivers/video/fbdev/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
@@ -16,8 +16,6 @@
  * from Florian Echtler, Henrik Bjerregaard Pedersen, and others.
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -32,7 +30,7 @@
 #include <video/udlfb.h>
 #include "edid.h"
 
-static struct fb_fix_screeninfo dlfb_fix = {
+static const struct fb_fix_screeninfo dlfb_fix = {
 	.id =           "udlfb",
 	.type =         FB_TYPE_PACKED_PIXELS,
 	.visual =       FB_VISUAL_TRUECOLOR,
@@ -76,10 +74,10 @@ static int pixel_limit; /* Optionally force a pixel resolution limit */
 
 /* dlfb keeps a list of urbs for efficient bulk transfers */
 static void dlfb_urb_completion(struct urb *urb);
-static struct urb *dlfb_get_urb(struct dlfb_data *dev);
-static int dlfb_submit_urb(struct dlfb_data *dev, struct urb * urb, size_t len);
-static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size);
-static void dlfb_free_urb_list(struct dlfb_data *dev);
+static struct urb *dlfb_get_urb(struct dlfb_data *dlfb);
+static int dlfb_submit_urb(struct dlfb_data *dlfb, struct urb * urb, size_t len);
+static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size);
+static void dlfb_free_urb_list(struct dlfb_data *dlfb);
 
 /*
  * All DisplayLink bulk operations start with 0xAF, followed by specific code
@@ -274,7 +272,7 @@ static char *dlfb_set_vid_cmds(char *wrptr, struct fb_var_screeninfo *var)
  * and then generates the appropriate command sequence that then drives the
  * display controller.
  */
-static int dlfb_set_video_mode(struct dlfb_data *dev,
+static int dlfb_set_video_mode(struct dlfb_data *dlfb,
 				struct fb_var_screeninfo *var)
 {
 	char *buf;
@@ -283,10 +281,10 @@ static int dlfb_set_video_mode(struct dlfb_data *dev,
 	int writesize;
 	struct urb *urb;
 
-	if (!atomic_read(&dev->usb_active))
+	if (!atomic_read(&dlfb->usb_active))
 		return -EPERM;
 
-	urb = dlfb_get_urb(dev);
+	urb = dlfb_get_urb(dlfb);
 	if (!urb)
 		return -ENOMEM;
 
@@ -302,7 +300,7 @@ static int dlfb_set_video_mode(struct dlfb_data *dev,
 	/* set base for 16bpp segment to 0 */
 	wrptr = dlfb_set_base16bpp(wrptr, 0);
 	/* set base for 8bpp segment to end of fb */
-	wrptr = dlfb_set_base8bpp(wrptr, dev->info->fix.smem_len);
+	wrptr = dlfb_set_base8bpp(wrptr, dlfb->info->fix.smem_len);
 
 	wrptr = dlfb_set_vid_cmds(wrptr, var);
 	wrptr = dlfb_blanking(wrptr, FB_BLANK_UNBLANK);
@@ -310,9 +308,9 @@ static int dlfb_set_video_mode(struct dlfb_data *dev,
 
 	writesize = wrptr - buf;
 
-	retval = dlfb_submit_urb(dev, urb, writesize);
+	retval = dlfb_submit_urb(dlfb, urb, writesize);
 
-	dev->blank_mode = FB_BLANK_UNBLANK;
+	dlfb->blank_mode = FB_BLANK_UNBLANK;
 
 	return retval;
 }
@@ -333,8 +331,8 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
 	pos = (unsigned long)info->fix.smem_start + offset;
 
-	pr_notice("mmap() framebuffer addr:%lu size:%lu\n",
-		  pos, size);
+	dev_dbg(info->dev, "mmap() framebuffer addr:%lu size:%lu\n",
+		pos, size);
 
 	while (size > 0) {
 		page = vmalloc_to_pfn((void *)pos);
@@ -505,8 +503,6 @@ static void dlfb_compress_hline(
 	*command_buffer_ptr = cmd;
 	*pixel_start_ptr = pixel;
 	*device_address_ptr = dev_addr;
-
-	return;
 }
 
 /*
@@ -515,13 +511,13 @@ static void dlfb_compress_hline(
  * (that we can only write to, slowly, and can never read), and (optionally)
  * our shadow copy that tracks what's been sent to that hardware buffer.
  */
-static int dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
+static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr,
 			      const char *front, char **urb_buf_ptr,
 			      u32 byte_offset, u32 byte_width,
 			      int *ident_ptr, int *sent_ptr)
 {
 	const u8 *line_start, *line_end, *next_pixel;
-	u32 dev_addr = dev->base16 + byte_offset;
+	u32 dev_addr = dlfb->base16 + byte_offset;
 	struct urb *urb = *urb_ptr;
 	u8 *cmd = *urb_buf_ptr;
 	u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
@@ -530,9 +526,9 @@ static int dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
 	next_pixel = line_start;
 	line_end = next_pixel + byte_width;
 
-	if (dev->backing_buffer) {
+	if (dlfb->backing_buffer) {
 		int offset;
-		const u8 *back_start = (u8 *) (dev->backing_buffer
+		const u8 *back_start = (u8 *) (dlfb->backing_buffer
 						+ byte_offset);
 
 		*ident_ptr += dlfb_trim_hline(back_start, &next_pixel,
@@ -556,10 +552,10 @@ static int dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
 
 		if (cmd >= cmd_end) {
 			int len = cmd - (u8 *) urb->transfer_buffer;
-			if (dlfb_submit_urb(dev, urb, len))
+			if (dlfb_submit_urb(dlfb, urb, len))
 				return 1; /* lost pixels is set */
 			*sent_ptr += len;
-			urb = dlfb_get_urb(dev);
+			urb = dlfb_get_urb(dlfb);
 			if (!urb)
 				return 1; /* lost_pixels is set */
 			*urb_ptr = urb;
@@ -573,7 +569,7 @@ static int dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
 	return 0;
 }
 
-static int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
+static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y,
 	       int width, int height, char *data)
 {
 	int i, ret;
@@ -591,24 +587,24 @@ static int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
 	x = aligned_x;
 
 	if ((width <= 0) ||
-	    (x + width > dev->info->var.xres) ||
-	    (y + height > dev->info->var.yres))
+	    (x + width > dlfb->info->var.xres) ||
+	    (y + height > dlfb->info->var.yres))
 		return -EINVAL;
 
-	if (!atomic_read(&dev->usb_active))
+	if (!atomic_read(&dlfb->usb_active))
 		return 0;
 
-	urb = dlfb_get_urb(dev);
+	urb = dlfb_get_urb(dlfb);
 	if (!urb)
 		return 0;
 	cmd = urb->transfer_buffer;
 
 	for (i = y; i < y + height ; i++) {
-		const int line_offset = dev->info->fix.line_length * i;
+		const int line_offset = dlfb->info->fix.line_length * i;
 		const int byte_offset = line_offset + (x * BPP);
 
-		if (dlfb_render_hline(dev, &urb,
-				      (char *) dev->info->fix.smem_start,
+		if (dlfb_render_hline(dlfb, &urb,
+				      (char *) dlfb->info->fix.smem_start,
 				      &cmd, byte_offset, width * BPP,
 				      &bytes_identical, &bytes_sent))
 			goto error;
@@ -617,19 +613,19 @@ static int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
 	if (cmd > (char *) urb->transfer_buffer) {
 		/* Send partial buffer remaining before exiting */
 		int len = cmd - (char *) urb->transfer_buffer;
-		ret = dlfb_submit_urb(dev, urb, len);
+		ret = dlfb_submit_urb(dlfb, urb, len);
 		bytes_sent += len;
 	} else
 		dlfb_urb_completion(urb);
 
 error:
-	atomic_add(bytes_sent, &dev->bytes_sent);
-	atomic_add(bytes_identical, &dev->bytes_identical);
-	atomic_add(width*height*2, &dev->bytes_rendered);
+	atomic_add(bytes_sent, &dlfb->bytes_sent);
+	atomic_add(bytes_identical, &dlfb->bytes_identical);
+	atomic_add(width*height*2, &dlfb->bytes_rendered);
 	end_cycles = get_cycles();
 	atomic_add(((unsigned int) ((end_cycles - start_cycles)
 		    >> 10)), /* Kcycles */
-		   &dev->cpu_kcycles_used);
+		   &dlfb->cpu_kcycles_used);
 
 	return 0;
 }
@@ -644,7 +640,7 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf,
 			  size_t count, loff_t *ppos)
 {
 	ssize_t result;
-	struct dlfb_data *dev = info->par;
+	struct dlfb_data *dlfb = info->par;
 	u32 offset = (u32) *ppos;
 
 	result = fb_sys_write(info, buf, count, ppos);
@@ -654,7 +650,7 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf,
 		int lines = min((u32)((result / info->fix.line_length) + 1),
 				(u32)info->var.yres);
 
-		dlfb_handle_damage(dev, 0, start, info->var.xres,
+		dlfb_handle_damage(dlfb, 0, start, info->var.xres,
 			lines, info->screen_base);
 	}
 
@@ -666,33 +662,33 @@ static void dlfb_ops_copyarea(struct fb_info *info,
 				const struct fb_copyarea *area)
 {
 
-	struct dlfb_data *dev = info->par;
+	struct dlfb_data *dlfb = info->par;
 
 	sys_copyarea(info, area);
 
-	dlfb_handle_damage(dev, area->dx, area->dy,
+	dlfb_handle_damage(dlfb, area->dx, area->dy,
 			area->width, area->height, info->screen_base);
 }
 
 static void dlfb_ops_imageblit(struct fb_info *info,
 				const struct fb_image *image)
 {
-	struct dlfb_data *dev = info->par;
+	struct dlfb_data *dlfb = info->par;
 
 	sys_imageblit(info, image);
 
-	dlfb_handle_damage(dev, image->dx, image->dy,
+	dlfb_handle_damage(dlfb, image->dx, image->dy,
 			image->width, image->height, info->screen_base);
 }
 
 static void dlfb_ops_fillrect(struct fb_info *info,
 			  const struct fb_fillrect *rect)
 {
-	struct dlfb_data *dev = info->par;
+	struct dlfb_data *dlfb = info->par;
 
 	sys_fillrect(info, rect);
 
-	dlfb_handle_damage(dev, rect->dx, rect->dy, rect->width,
+	dlfb_handle_damage(dlfb, rect->dx, rect->dy, rect->width,
 			      rect->height, info->screen_base);
 }
 
@@ -707,7 +703,7 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
 {
 	struct page *cur;
 	struct fb_deferred_io *fbdefio = info->fbdefio;
-	struct dlfb_data *dev = info->par;
+	struct dlfb_data *dlfb = info->par;
 	struct urb *urb;
 	char *cmd;
 	cycles_t start_cycles, end_cycles;
@@ -718,12 +714,12 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
 	if (!fb_defio)
 		return;
 
-	if (!atomic_read(&dev->usb_active))
+	if (!atomic_read(&dlfb->usb_active))
 		return;
 
 	start_cycles = get_cycles();
 
-	urb = dlfb_get_urb(dev);
+	urb = dlfb_get_urb(dlfb);
 	if (!urb)
 		return;
 
@@ -732,7 +728,7 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
 	/* walk the written page list and render each to device */
 	list_for_each_entry(cur, &fbdefio->pagelist, lru) {
 
-		if (dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start,
+		if (dlfb_render_hline(dlfb, &urb, (char *) info->fix.smem_start,
 				  &cmd, cur->index << PAGE_SHIFT,
 				  PAGE_SIZE, &bytes_identical, &bytes_sent))
 			goto error;
@@ -742,25 +738,24 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
 	if (cmd > (char *) urb->transfer_buffer) {
 		/* Send partial buffer remaining before exiting */
 		int len = cmd - (char *) urb->transfer_buffer;
-		dlfb_submit_urb(dev, urb, len);
+		dlfb_submit_urb(dlfb, urb, len);
 		bytes_sent += len;
 	} else
 		dlfb_urb_completion(urb);
 
 error:
-	atomic_add(bytes_sent, &dev->bytes_sent);
-	atomic_add(bytes_identical, &dev->bytes_identical);
-	atomic_add(bytes_rendered, &dev->bytes_rendered);
+	atomic_add(bytes_sent, &dlfb->bytes_sent);
+	atomic_add(bytes_identical, &dlfb->bytes_identical);
+	atomic_add(bytes_rendered, &dlfb->bytes_rendered);
 	end_cycles = get_cycles();
 	atomic_add(((unsigned int) ((end_cycles - start_cycles)
 		    >> 10)), /* Kcycles */
-		   &dev->cpu_kcycles_used);
+		   &dlfb->cpu_kcycles_used);
 }
 
-static int dlfb_get_edid(struct dlfb_data *dev, char *edid, int len)
+static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len)
 {
-	int i;
-	int ret;
+	int i, ret;
 	char *rbuf;
 
 	rbuf = kmalloc(2, GFP_KERNEL);
@@ -768,12 +763,13 @@ static int dlfb_get_edid(struct dlfb_data *dev, char *edid, int len)
 		return 0;
 
 	for (i = 0; i < len; i++) {
-		ret = usb_control_msg(dev->udev,
-				      usb_rcvctrlpipe(dev->udev, 0), 0x02,
+		ret = usb_control_msg(dlfb->udev,
+				      usb_rcvctrlpipe(dlfb->udev, 0), 0x02,
 				      (0x80 | (0x02 << 5)), i << 8, 0xA1,
 				      rbuf, 2, USB_CTRL_GET_TIMEOUT);
 		if (ret < 2) {
-			pr_err("Read EDID byte %d failed: %d\n", i, ret);
+			dev_err(&dlfb->udev->dev,
+				"Read EDID byte %d failed: %d\n", i, ret);
 			i--;
 			break;
 		}
@@ -789,15 +785,15 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
 				unsigned long arg)
 {
 
-	struct dlfb_data *dev = info->par;
+	struct dlfb_data *dlfb = info->par;
 
-	if (!atomic_read(&dev->usb_active))
+	if (!atomic_read(&dlfb->usb_active))
 		return 0;
 
 	/* TODO: Update X server to get this from sysfs instead */
 	if (cmd == DLFB_IOCTL_RETURN_EDID) {
 		void __user *edid = (void __user *)arg;
-		if (copy_to_user(edid, dev->edid, dev->edid_size))
+		if (copy_to_user(edid, dlfb->edid, dlfb->edid_size))
 			return -EFAULT;
 		return 0;
 	}
@@ -832,7 +828,7 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
 		if (area.y > info->var.yres)
 			area.y = info->var.yres;
 
-		dlfb_handle_damage(dev, area.x, area.y, area.w, area.h,
+		dlfb_handle_damage(dlfb, area.x, area.y, area.w, area.h,
 			   info->screen_base);
 	}
 
@@ -873,7 +869,7 @@ dlfb_ops_setcolreg(unsigned regno, unsigned red, unsigned green,
  */
 static int dlfb_ops_open(struct fb_info *info, int user)
 {
-	struct dlfb_data *dev = info->par;
+	struct dlfb_data *dlfb = info->par;
 
 	/*
 	 * fbcon aggressively connects to first framebuffer it finds,
@@ -884,12 +880,12 @@ static int dlfb_ops_open(struct fb_info *info, int user)
 		return -EBUSY;
 
 	/* If the USB device is gone, we don't accept new opens */
-	if (dev->virtualized)
+	if (dlfb->virtualized)
 		return -ENODEV;
 
-	dev->fb_count++;
+	dlfb->fb_count++;
 
-	kref_get(&dev->kref);
+	kref_get(&dlfb->kref);
 
 	if (fb_defio && (info->fbdefio == NULL)) {
 		/* enable defio at last moment if not disabled by client */
@@ -907,8 +903,8 @@ static int dlfb_ops_open(struct fb_info *info, int user)
 		fb_deferred_io_init(info);
 	}
 
-	pr_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n",
-	    info->node, user, info, dev->fb_count);
+	dev_dbg(info->dev, "open, user=%d fb_info=%p count=%d\n",
+		user, info, dlfb->fb_count);
 
 	return 0;
 }
@@ -920,15 +916,11 @@ static int dlfb_ops_open(struct fb_info *info, int user)
  */
 static void dlfb_free(struct kref *kref)
 {
-	struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
+	struct dlfb_data *dlfb = container_of(kref, struct dlfb_data, kref);
 
-	vfree(dev->backing_buffer);
-
-	kfree(dev->edid);
-
-	pr_warn("freeing dlfb_data %p\n", dev);
-
-	kfree(dev);
+	vfree(dlfb->backing_buffer);
+	kfree(dlfb->edid);
+	kfree(dlfb);
 }
 
 static void dlfb_release_urb_work(struct work_struct *work)
@@ -936,16 +928,14 @@ static void dlfb_release_urb_work(struct work_struct *work)
 	struct urb_node *unode = container_of(work, struct urb_node,
 					      release_urb_work.work);
 
-	up(&unode->dev->urbs.limit_sem);
+	up(&unode->dlfb->urbs.limit_sem);
 }
 
-static void dlfb_free_framebuffer(struct dlfb_data *dev)
+static void dlfb_free_framebuffer(struct dlfb_data *dlfb)
 {
-	struct fb_info *info = dev->info;
+	struct fb_info *info = dlfb->info;
 
 	if (info) {
-		int node = info->node;
-
 		unregister_framebuffer(info);
 
 		if (info->cmap.len != 0)
@@ -956,48 +946,45 @@ static void dlfb_free_framebuffer(struct dlfb_data *dev)
 
 		fb_destroy_modelist(&info->modelist);
 
-		dev->info = NULL;
+		dlfb->info = NULL;
 
 		/* Assume info structure is freed after this point */
 		framebuffer_release(info);
-
-		pr_warn("fb_info for /dev/fb%d has been freed\n", node);
 	}
 
 	/* ref taken in probe() as part of registering framebfufer */
-	kref_put(&dev->kref, dlfb_free);
+	kref_put(&dlfb->kref, dlfb_free);
 }
 
 static void dlfb_free_framebuffer_work(struct work_struct *work)
 {
-	struct dlfb_data *dev = container_of(work, struct dlfb_data,
+	struct dlfb_data *dlfb = container_of(work, struct dlfb_data,
 					     free_framebuffer_work.work);
-	dlfb_free_framebuffer(dev);
+	dlfb_free_framebuffer(dlfb);
 }
 /*
  * Assumes caller is holding info->lock mutex (for open and release at least)
  */
 static int dlfb_ops_release(struct fb_info *info, int user)
 {
-	struct dlfb_data *dev = info->par;
+	struct dlfb_data *dlfb = info->par;
 
-	dev->fb_count--;
+	dlfb->fb_count--;
 
 	/* We can't free fb_info here - fbmem will touch it when we return */
-	if (dev->virtualized && (dev->fb_count == 0))
-		schedule_delayed_work(&dev->free_framebuffer_work, HZ);
+	if (dlfb->virtualized && (dlfb->fb_count == 0))
+		schedule_delayed_work(&dlfb->free_framebuffer_work, HZ);
 
-	if ((dev->fb_count == 0) && (info->fbdefio)) {
+	if ((dlfb->fb_count == 0) && (info->fbdefio)) {
 		fb_deferred_io_cleanup(info);
 		kfree(info->fbdefio);
 		info->fbdefio = NULL;
 		info->fbops->fb_mmap = dlfb_ops_mmap;
 	}
 
-	pr_warn("released /dev/fb%d user=%d count=%d\n",
-		  info->node, user, dev->fb_count);
+	dev_dbg(info->dev, "release, user=%d count=%d\n", user, dlfb->fb_count);
 
-	kref_put(&dev->kref, dlfb_free);
+	kref_put(&dlfb->kref, dlfb_free);
 
 	return 0;
 }
@@ -1006,19 +993,10 @@ static int dlfb_ops_release(struct fb_info *info, int user)
  * Check whether a video mode is supported by the DisplayLink chip
  * We start from monitor's modes, so don't need to filter that here
  */
-static int dlfb_is_valid_mode(struct fb_videomode *mode,
-		struct fb_info *info)
+static int dlfb_is_valid_mode(struct fb_videomode *mode, struct dlfb_data *dlfb)
 {
-	struct dlfb_data *dev = info->par;
-
-	if (mode->xres * mode->yres > dev->sku_pixel_limit) {
-		pr_warn("%dx%d beyond chip capabilities\n",
-		       mode->xres, mode->yres);
+	if (mode->xres * mode->yres > dlfb->sku_pixel_limit)
 		return 0;
-	}
-
-	pr_info("%dx%d @ %d Hz valid mode\n", mode->xres, mode->yres,
-		mode->refresh);
 
 	return 1;
 }
@@ -1039,6 +1017,7 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
 				struct fb_info *info)
 {
 	struct fb_videomode mode;
+	struct dlfb_data *dlfb = info->par;
 
 	/* TODO: support dynamically changing framebuffer size */
 	if ((var->xres * var->yres * 2) > info->fix.smem_len)
@@ -1049,7 +1028,7 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
 
 	fb_var_to_videomode(&mode, var);
 
-	if (!dlfb_is_valid_mode(&mode, info))
+	if (!dlfb_is_valid_mode(&mode, dlfb))
 		return -EINVAL;
 
 	return 0;
@@ -1057,16 +1036,14 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
 
 static int dlfb_ops_set_par(struct fb_info *info)
 {
-	struct dlfb_data *dev = info->par;
+	struct dlfb_data *dlfb = info->par;
 	int result;
 	u16 *pix_framebuffer;
 	int i;
 
-	pr_notice("set_par mode %dx%d\n", info->var.xres, info->var.yres);
+	result = dlfb_set_video_mode(dlfb, &info->var);
 
-	result = dlfb_set_video_mode(dev, &info->var);
-
-	if ((result == 0) && (dev->fb_count == 0)) {
+	if ((result == 0) && (dlfb->fb_count == 0)) {
 
 		/* paint greenscreen */
 
@@ -1074,7 +1051,7 @@ static int dlfb_ops_set_par(struct fb_info *info)
 		for (i = 0; i < info->fix.smem_len / 2; i++)
 			pix_framebuffer[i] = 0x37e6;
 
-		dlfb_handle_damage(dev, 0, 0, info->var.xres, info->var.yres,
+		dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres,
 				   info->screen_base);
 	}
 
@@ -1101,21 +1078,21 @@ static char *dlfb_dummy_render(char *buf)
  */
 static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
 {
-	struct dlfb_data *dev = info->par;
+	struct dlfb_data *dlfb = info->par;
 	char *bufptr;
 	struct urb *urb;
 
-	pr_debug("/dev/fb%d FB_BLANK mode %d --> %d\n",
-		 info->node, dev->blank_mode, blank_mode);
+	dev_dbg(info->dev, "blank, mode %d --> %d\n",
+		dlfb->blank_mode, blank_mode);
 
-	if ((dev->blank_mode == FB_BLANK_POWERDOWN) &&
+	if ((dlfb->blank_mode == FB_BLANK_POWERDOWN) &&
 	    (blank_mode != FB_BLANK_POWERDOWN)) {
 
 		/* returning from powerdown requires a fresh modeset */
-		dlfb_set_video_mode(dev, &info->var);
+		dlfb_set_video_mode(dlfb, &info->var);
 	}
 
-	urb = dlfb_get_urb(dev);
+	urb = dlfb_get_urb(dlfb);
 	if (!urb)
 		return 0;
 
@@ -1127,10 +1104,10 @@ static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
 	/* seems like a render op is needed to have blank change take effect */
 	bufptr = dlfb_dummy_render(bufptr);
 
-	dlfb_submit_urb(dev, urb, bufptr -
+	dlfb_submit_urb(dlfb, urb, bufptr -
 			(char *) urb->transfer_buffer);
 
-	dev->blank_mode = blank_mode;
+	dlfb->blank_mode = blank_mode;
 
 	return 0;
 }
@@ -1157,7 +1134,7 @@ static struct fb_ops dlfb_ops = {
  * Assumes &info->lock held by caller
  * Assumes no active clients have framebuffer open
  */
-static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
+static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info)
 {
 	int retval = -ENOMEM;
 	int old_len = info->fix.smem_len;
@@ -1166,8 +1143,6 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
 	unsigned char *new_fb;
 	unsigned char *new_back = NULL;
 
-	pr_warn("Reallocating framebuffer. Addresses will change!\n");
-
 	new_len = info->fix.line_length * info->var.yres;
 
 	if (PAGE_ALIGN(new_len) > old_len) {
@@ -1176,7 +1151,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
 		 */
 		new_fb = vmalloc(new_len);
 		if (!new_fb) {
-			pr_err("Virtual framebuffer alloc failed\n");
+			dev_err(info->dev, "Virtual framebuffer alloc failed\n");
 			goto error;
 		}
 
@@ -1199,10 +1174,11 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
 		if (shadow)
 			new_back = vzalloc(new_len);
 		if (!new_back)
-			pr_info("No shadow/backing buffer allocated\n");
+			dev_info(info->dev,
+				 "No shadow/backing buffer allocated\n");
 		else {
-			vfree(dev->backing_buffer);
-			dev->backing_buffer = new_back;
+			vfree(dlfb->backing_buffer);
+			dlfb->backing_buffer = new_back;
 		}
 	}
 
@@ -1226,18 +1202,22 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
  * monspecs is NULL, and fb_var_screeninfo is set to safe VESA mode
  * Returns 0 if successful
  */
-static int dlfb_setup_modes(struct dlfb_data *dev,
+static int dlfb_setup_modes(struct dlfb_data *dlfb,
 			   struct fb_info *info,
 			   char *default_edid, size_t default_edid_size)
 {
-	int i;
-	const struct fb_videomode *default_vmode = NULL;
-	int result = 0;
 	char *edid;
-	int tries = 3;
+	int i, result = 0, tries = 3;
+	struct device *dev = info->device;
+	struct fb_videomode *mode;
+	const struct fb_videomode *default_vmode = NULL;
 
-	if (info->dev) /* only use mutex if info has been registered */
+	if (info->dev) {
+		/* only use mutex if info has been registered */
 		mutex_lock(&info->lock);
+		/* parent device is used otherwise */
+		dev = info->dev;
+	}
 
 	edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
 	if (!edid) {
@@ -1255,27 +1235,26 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
 	 */
 	while (tries--) {
 
-		i = dlfb_get_edid(dev, edid, EDID_LENGTH);
+		i = dlfb_get_edid(dlfb, edid, EDID_LENGTH);
 
 		if (i >= EDID_LENGTH)
 			fb_edid_to_monspecs(edid, &info->monspecs);
 
 		if (info->monspecs.modedb_len > 0) {
-			dev->edid = edid;
-			dev->edid_size = i;
+			dlfb->edid = edid;
+			dlfb->edid_size = i;
 			break;
 		}
 	}
 
 	/* If that fails, use a previously returned EDID if available */
 	if (info->monspecs.modedb_len == 0) {
+		dev_err(dev, "Unable to get valid EDID from device/display\n");
 
-		pr_err("Unable to get valid EDID from device/display\n");
-
-		if (dev->edid) {
-			fb_edid_to_monspecs(dev->edid, &info->monspecs);
+		if (dlfb->edid) {
+			fb_edid_to_monspecs(dlfb->edid, &info->monspecs);
 			if (info->monspecs.modedb_len > 0)
-				pr_err("Using previously queried EDID\n");
+				dev_err(dev, "Using previously queried EDID\n");
 		}
 	}
 
@@ -1285,9 +1264,9 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
 			fb_edid_to_monspecs(default_edid, &info->monspecs);
 			if (info->monspecs.modedb_len > 0) {
 				memcpy(edid, default_edid, default_edid_size);
-				dev->edid = edid;
-				dev->edid_size = default_edid_size;
-				pr_err("Using default/backup EDID\n");
+				dlfb->edid = edid;
+				dlfb->edid_size = default_edid_size;
+				dev_err(dev, "Using default/backup EDID\n");
 			}
 		}
 	}
@@ -1296,10 +1275,12 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
 	if (info->monspecs.modedb_len > 0) {
 
 		for (i = 0; i < info->monspecs.modedb_len; i++) {
-			if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info))
-				fb_add_videomode(&info->monspecs.modedb[i],
-					&info->modelist);
-			else {
+			mode = &info->monspecs.modedb[i];
+			if (dlfb_is_valid_mode(mode, dlfb)) {
+				fb_add_videomode(mode, &info->modelist);
+			} else {
+				dev_dbg(dev, "Specified mode %dx%d too big\n",
+					mode->xres, mode->yres);
 				if (i == 0)
 					/* if we've removed top/best mode */
 					info->monspecs.misc
@@ -1323,10 +1304,12 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
 		 * But at least the user has a chance to choose
 		 */
 		for (i = 0; i < VESA_MODEDB_SIZE; i++) {
-			if (dlfb_is_valid_mode((struct fb_videomode *)
-						&vesa_modes[i], info))
-				fb_add_videomode(&vesa_modes[i],
-						 &info->modelist);
+			mode = (struct fb_videomode *)&vesa_modes[i];
+			if (dlfb_is_valid_mode(mode, dlfb))
+				fb_add_videomode(mode, &info->modelist);
+			else
+				dev_dbg(dev, "VESA mode %dx%d too big\n",
+					mode->xres, mode->yres);
 		}
 
 		/*
@@ -1341,7 +1324,7 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
 	}
 
 	/* If we have good mode and no active clients*/
-	if ((default_vmode != NULL) && (dev->fb_count == 0)) {
+	if ((default_vmode != NULL) && (dlfb->fb_count == 0)) {
 
 		fb_videomode_to_var(&info->var, default_vmode);
 		dlfb_var_color_format(&info->var);
@@ -1353,13 +1336,13 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
 		info->fix.line_length = info->var.xres *
 			(info->var.bits_per_pixel / 8);
 
-		result = dlfb_realloc_framebuffer(dev, info);
+		result = dlfb_realloc_framebuffer(dlfb, info);
 
 	} else
 		result = -EINVAL;
 
 error:
-	if (edid && (dev->edid != edid))
+	if (edid && (dlfb->edid != edid))
 		kfree(edid);
 
 	if (info->dev)
@@ -1371,33 +1354,33 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
 static ssize_t metrics_bytes_rendered_show(struct device *fbdev,
 				   struct device_attribute *a, char *buf) {
 	struct fb_info *fb_info = dev_get_drvdata(fbdev);
-	struct dlfb_data *dev = fb_info->par;
+	struct dlfb_data *dlfb = fb_info->par;
 	return snprintf(buf, PAGE_SIZE, "%u\n",
-			atomic_read(&dev->bytes_rendered));
+			atomic_read(&dlfb->bytes_rendered));
 }
 
 static ssize_t metrics_bytes_identical_show(struct device *fbdev,
 				   struct device_attribute *a, char *buf) {
 	struct fb_info *fb_info = dev_get_drvdata(fbdev);
-	struct dlfb_data *dev = fb_info->par;
+	struct dlfb_data *dlfb = fb_info->par;
 	return snprintf(buf, PAGE_SIZE, "%u\n",
-			atomic_read(&dev->bytes_identical));
+			atomic_read(&dlfb->bytes_identical));
 }
 
 static ssize_t metrics_bytes_sent_show(struct device *fbdev,
 				   struct device_attribute *a, char *buf) {
 	struct fb_info *fb_info = dev_get_drvdata(fbdev);
-	struct dlfb_data *dev = fb_info->par;
+	struct dlfb_data *dlfb = fb_info->par;
 	return snprintf(buf, PAGE_SIZE, "%u\n",
-			atomic_read(&dev->bytes_sent));
+			atomic_read(&dlfb->bytes_sent));
 }
 
 static ssize_t metrics_cpu_kcycles_used_show(struct device *fbdev,
 				   struct device_attribute *a, char *buf) {
 	struct fb_info *fb_info = dev_get_drvdata(fbdev);
-	struct dlfb_data *dev = fb_info->par;
+	struct dlfb_data *dlfb = fb_info->par;
 	return snprintf(buf, PAGE_SIZE, "%u\n",
-			atomic_read(&dev->cpu_kcycles_used));
+			atomic_read(&dlfb->cpu_kcycles_used));
 }
 
 static ssize_t edid_show(
@@ -1406,21 +1389,18 @@ static ssize_t edid_show(
 			 char *buf, loff_t off, size_t count) {
 	struct device *fbdev = container_of(kobj, struct device, kobj);
 	struct fb_info *fb_info = dev_get_drvdata(fbdev);
-	struct dlfb_data *dev = fb_info->par;
+	struct dlfb_data *dlfb = fb_info->par;
 
-	if (dev->edid == NULL)
+	if (dlfb->edid == NULL)
 		return 0;
 
-	if ((off >= dev->edid_size) || (count > dev->edid_size))
+	if ((off >= dlfb->edid_size) || (count > dlfb->edid_size))
 		return 0;
 
-	if (off + count > dev->edid_size)
-		count = dev->edid_size - off;
+	if (off + count > dlfb->edid_size)
+		count = dlfb->edid_size - off;
 
-	pr_info("sysfs edid copy %p to %p, %d bytes\n",
-		dev->edid, buf, (int) count);
-
-	memcpy(buf, dev->edid, count);
+	memcpy(buf, dlfb->edid, count);
 
 	return count;
 }
@@ -1431,21 +1411,20 @@ static ssize_t edid_store(
 			char *src, loff_t src_off, size_t src_size) {
 	struct device *fbdev = container_of(kobj, struct device, kobj);
 	struct fb_info *fb_info = dev_get_drvdata(fbdev);
-	struct dlfb_data *dev = fb_info->par;
+	struct dlfb_data *dlfb = fb_info->par;
 	int ret;
 
 	/* We only support write of entire EDID at once, no offset*/
 	if ((src_size != EDID_LENGTH) || (src_off != 0))
 		return -EINVAL;
 
-	ret = dlfb_setup_modes(dev, fb_info, src, src_size);
+	ret = dlfb_setup_modes(dlfb, fb_info, src, src_size);
 	if (ret)
 		return ret;
 
-	if (!dev->edid || memcmp(src, dev->edid, src_size))
+	if (!dlfb->edid || memcmp(src, dlfb->edid, src_size))
 		return -EINVAL;
 
-	pr_info("sysfs written EDID is new default\n");
 	dlfb_ops_set_par(fb_info);
 	return src_size;
 }
@@ -1455,12 +1434,12 @@ static ssize_t metrics_reset_store(struct device *fbdev,
 			   const char *buf, size_t count)
 {
 	struct fb_info *fb_info = dev_get_drvdata(fbdev);
-	struct dlfb_data *dev = fb_info->par;
+	struct dlfb_data *dlfb = fb_info->par;
 
-	atomic_set(&dev->bytes_rendered, 0);
-	atomic_set(&dev->bytes_identical, 0);
-	atomic_set(&dev->bytes_sent, 0);
-	atomic_set(&dev->cpu_kcycles_used, 0);
+	atomic_set(&dlfb->bytes_rendered, 0);
+	atomic_set(&dlfb->bytes_identical, 0);
+	atomic_set(&dlfb->bytes_sent, 0);
+	atomic_set(&dlfb->cpu_kcycles_used, 0);
 
 	return count;
 }
@@ -1473,7 +1452,7 @@ static const struct bin_attribute edid_attr = {
 	.write = edid_store
 };
 
-static struct device_attribute fb_device_attrs[] = {
+static const struct device_attribute fb_device_attrs[] = {
 	__ATTR_RO(metrics_bytes_rendered),
 	__ATTR_RO(metrics_bytes_identical),
 	__ATTR_RO(metrics_bytes_sent),
@@ -1484,7 +1463,7 @@ static struct device_attribute fb_device_attrs[] = {
 /*
  * This is necessary before we can communicate with the display controller.
  */
-static int dlfb_select_std_channel(struct dlfb_data *dev)
+static int dlfb_select_std_channel(struct dlfb_data *dlfb)
 {
 	int ret;
 	void *buf;
@@ -1499,7 +1478,7 @@ static int dlfb_select_std_channel(struct dlfb_data *dev)
 	if (!buf)
 		return -ENOMEM;
 
-	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+	ret = usb_control_msg(dlfb->udev, usb_sndctrlpipe(dlfb->udev, 0),
 			NR_USB_REQUEST_CHANNEL,
 			(USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0,
 			buf, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
@@ -1509,8 +1488,8 @@ static int dlfb_select_std_channel(struct dlfb_data *dev)
 	return ret;
 }
 
-static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
-					struct usb_interface *interface)
+static int dlfb_parse_vendor_descriptor(struct dlfb_data *dlfb,
+					struct usb_interface *intf)
 {
 	char *desc;
 	char *buf;
@@ -1522,20 +1501,21 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
 		return false;
 	desc = buf;
 
-	total_len = usb_get_descriptor(interface_to_usbdev(interface),
+	total_len = usb_get_descriptor(interface_to_usbdev(intf),
 					0x5f, /* vendor specific */
 					0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
 
 	/* if not found, look in configuration descriptor */
 	if (total_len < 0) {
-		if (0 == usb_get_extra_descriptor(interface->cur_altsetting,
+		if (0 == usb_get_extra_descriptor(intf->cur_altsetting,
 			0x5f, &desc))
 			total_len = (int) desc[0];
 	}
 
 	if (total_len > 5) {
-		pr_info("vendor descriptor length:%x data:%11ph\n", total_len,
-			desc);
+		dev_info(&intf->dev,
+			 "vendor descriptor length: %d data: %11ph\n",
+			 total_len, desc);
 
 		if ((desc[0] != total_len) || /* descriptor length */
 		    (desc[1] != 0x5f) ||   /* vendor descriptor type */
@@ -1560,9 +1540,10 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
 			case 0x0200: { /* max_area */
 				u32 max_area;
 				max_area = le32_to_cpu(*((u32 *)desc));
-				pr_warn("DL chip limited to %d pixel modes\n",
-					max_area);
-				dev->sku_pixel_limit = max_area;
+				dev_warn(&intf->dev,
+					 "DL chip limited to %d pixel modes\n",
+					 max_area);
+				dlfb->sku_pixel_limit = max_area;
 				break;
 			}
 			default:
@@ -1571,14 +1552,15 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
 			desc += length;
 		}
 	} else {
-		pr_info("vendor descriptor not available (%d)\n", total_len);
+		dev_info(&intf->dev, "vendor descriptor not available (%d)\n",
+			 total_len);
 	}
 
 	goto success;
 
 unrecognized:
 	/* allow udlfb to load for now even if firmware unrecognized */
-	pr_err("Unrecognized vendor firmware descriptor\n");
+	dev_err(&intf->dev, "Unrecognized vendor firmware descriptor\n");
 
 success:
 	kfree(buf);
@@ -1587,75 +1569,66 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
 
 static void dlfb_init_framebuffer_work(struct work_struct *work);
 
-static int dlfb_usb_probe(struct usb_interface *interface,
-			const struct usb_device_id *id)
+static int dlfb_usb_probe(struct usb_interface *intf,
+			  const struct usb_device_id *id)
 {
-	struct usb_device *usbdev;
-	struct dlfb_data *dev;
+	struct dlfb_data *dlfb;
 	int retval = -ENOMEM;
+	struct usb_device *usbdev = interface_to_usbdev(intf);
 
 	/* usb initialization */
-
-	usbdev = interface_to_usbdev(interface);
-
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (dev == NULL) {
-		dev_err(&interface->dev, "dlfb_usb_probe: failed alloc of dev struct\n");
+	dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL);
+	if (!dlfb) {
+		dev_err(&intf->dev, "%s: failed to allocate dlfb\n", __func__);
 		goto error;
 	}
 
-	kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */
+	kref_init(&dlfb->kref); /* matching kref_put in usb .disconnect fn */
 
-	dev->udev = usbdev;
-	dev->gdev = &usbdev->dev; /* our generic struct device * */
-	usb_set_intfdata(interface, dev);
+	dlfb->udev = usbdev;
+	usb_set_intfdata(intf, dlfb);
 
-	pr_info("%s %s - serial #%s\n",
-		usbdev->manufacturer, usbdev->product, usbdev->serial);
-	pr_info("vid_%04x&pid_%04x&rev_%04x driver's dlfb_data struct at %p\n",
-		le16_to_cpu(usbdev->descriptor.idVendor),
-		le16_to_cpu(usbdev->descriptor.idProduct),
-		le16_to_cpu(usbdev->descriptor.bcdDevice), dev);
-	pr_info("console enable=%d\n", console);
-	pr_info("fb_defio enable=%d\n", fb_defio);
-	pr_info("shadow enable=%d\n", shadow);
+	dev_dbg(&intf->dev, "console enable=%d\n", console);
+	dev_dbg(&intf->dev, "fb_defio enable=%d\n", fb_defio);
+	dev_dbg(&intf->dev, "shadow enable=%d\n", shadow);
 
-	dev->sku_pixel_limit = 2048 * 1152; /* default to maximum */
+	dlfb->sku_pixel_limit = 2048 * 1152; /* default to maximum */
 
-	if (!dlfb_parse_vendor_descriptor(dev, interface)) {
-		pr_err("firmware not recognized. Assume incompatible device\n");
+	if (!dlfb_parse_vendor_descriptor(dlfb, intf)) {
+		dev_err(&intf->dev,
+			"firmware not recognized, incompatible device?\n");
 		goto error;
 	}
 
 	if (pixel_limit) {
-		pr_warn("DL chip limit of %d overridden"
-			" by module param to %d\n",
-			dev->sku_pixel_limit, pixel_limit);
-		dev->sku_pixel_limit = pixel_limit;
+		dev_warn(&intf->dev,
+			 "DL chip limit of %d overridden to %d\n",
+			 dlfb->sku_pixel_limit, pixel_limit);
+		dlfb->sku_pixel_limit = pixel_limit;
 	}
 
 
-	if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
+	if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
 		retval = -ENOMEM;
-		pr_err("dlfb_alloc_urb_list failed\n");
+		dev_err(&intf->dev, "unable to allocate urb list\n");
 		goto error;
 	}
 
-	kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */
+	kref_get(&dlfb->kref); /* matching kref_put in free_framebuffer_work */
 
-	/* We don't register a new USB class. Our client interface is fbdev */
+	/* We don't register a new USB class. Our client interface is dlfbev */
 
 	/* Workitem keep things fast & simple during USB enumeration */
-	INIT_DELAYED_WORK(&dev->init_framebuffer_work,
+	INIT_DELAYED_WORK(&dlfb->init_framebuffer_work,
 			  dlfb_init_framebuffer_work);
-	schedule_delayed_work(&dev->init_framebuffer_work, 0);
+	schedule_delayed_work(&dlfb->init_framebuffer_work, 0);
 
 	return 0;
 
 error:
-	if (dev) {
+	if (dlfb) {
 
-		kref_put(&dev->kref, dlfb_free); /* last ref from kref_init */
+		kref_put(&dlfb->kref, dlfb_free); /* last ref from kref_init */
 
 		/* dev has been deallocated. Do not dereference */
 	}
@@ -1665,97 +1638,101 @@ static int dlfb_usb_probe(struct usb_interface *interface,
 
 static void dlfb_init_framebuffer_work(struct work_struct *work)
 {
-	struct dlfb_data *dev = container_of(work, struct dlfb_data,
-					     init_framebuffer_work.work);
+	int i, retval;
 	struct fb_info *info;
-	int retval;
-	int i;
+	const struct device_attribute *attr;
+	struct dlfb_data *dlfb = container_of(work, struct dlfb_data,
+					     init_framebuffer_work.work);
 
 	/* allocates framebuffer driver structure, not framebuffer memory */
-	info = framebuffer_alloc(0, dev->gdev);
+	info = framebuffer_alloc(0, &dlfb->udev->dev);
 	if (!info) {
-		pr_err("framebuffer_alloc failed\n");
+		dev_err(&dlfb->udev->dev, "framebuffer_alloc failed\n");
 		goto error;
 	}
 
-	dev->info = info;
-	info->par = dev;
-	info->pseudo_palette = dev->pseudo_palette;
+	dlfb->info = info;
+	info->par = dlfb;
+	info->pseudo_palette = dlfb->pseudo_palette;
 	info->fbops = &dlfb_ops;
 
 	retval = fb_alloc_cmap(&info->cmap, 256, 0);
 	if (retval < 0) {
-		pr_err("fb_alloc_cmap failed %x\n", retval);
+		dev_err(info->device, "cmap allocation failed: %d\n", retval);
 		goto error;
 	}
 
-	INIT_DELAYED_WORK(&dev->free_framebuffer_work,
+	INIT_DELAYED_WORK(&dlfb->free_framebuffer_work,
 			  dlfb_free_framebuffer_work);
 
 	INIT_LIST_HEAD(&info->modelist);
 
-	retval = dlfb_setup_modes(dev, info, NULL, 0);
+	retval = dlfb_setup_modes(dlfb, info, NULL, 0);
 	if (retval != 0) {
-		pr_err("unable to find common mode for display and adapter\n");
+		dev_err(info->device,
+			"unable to find common mode for display and adapter\n");
 		goto error;
 	}
 
 	/* ready to begin using device */
 
-	atomic_set(&dev->usb_active, 1);
-	dlfb_select_std_channel(dev);
+	atomic_set(&dlfb->usb_active, 1);
+	dlfb_select_std_channel(dlfb);
 
 	dlfb_ops_check_var(&info->var, info);
 	dlfb_ops_set_par(info);
 
 	retval = register_framebuffer(info);
 	if (retval < 0) {
-		pr_err("register_framebuffer failed %d\n", retval);
+		dev_err(info->device, "unable to register framebuffer: %d\n",
+			retval);
 		goto error;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) {
-		retval = device_create_file(info->dev, &fb_device_attrs[i]);
-		if (retval) {
-			pr_warn("device_create_file failed %d\n", retval);
-		}
+		attr = &fb_device_attrs[i];
+		retval = device_create_file(info->dev, attr);
+		if (retval)
+			dev_warn(info->device,
+				 "failed to create '%s' attribute: %d\n",
+				 attr->attr.name, retval);
 	}
 
 	retval = device_create_bin_file(info->dev, &edid_attr);
-	if (retval) {
-		pr_warn("device_create_bin_file failed %d\n", retval);
-	}
+	if (retval)
+		dev_warn(info->device, "failed to create '%s' attribute: %d\n",
+			 edid_attr.attr.name, retval);
 
-	pr_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
-			" Using %dK framebuffer memory\n", info->node,
-			info->var.xres, info->var.yres,
-			((dev->backing_buffer) ?
-			info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
+	dev_info(info->device,
+		 "%s is DisplayLink USB device (%dx%d, %dK framebuffer memory)\n",
+		 dev_name(info->dev), info->var.xres, info->var.yres,
+		 ((dlfb->backing_buffer) ?
+		 info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
 	return;
 
 error:
-	dlfb_free_framebuffer(dev);
+	dlfb_free_framebuffer(dlfb);
 }
 
-static void dlfb_usb_disconnect(struct usb_interface *interface)
+static void dlfb_usb_disconnect(struct usb_interface *intf)
 {
-	struct dlfb_data *dev;
+	struct dlfb_data *dlfb;
 	struct fb_info *info;
 	int i;
 
-	dev = usb_get_intfdata(interface);
-	info = dev->info;
+	dlfb = usb_get_intfdata(intf);
+	info = dlfb->info;
 
-	pr_info("USB disconnect starting\n");
+	dev_dbg(&intf->dev, "USB disconnect starting\n");
 
 	/* we virtualize until all fb clients release. Then we free */
-	dev->virtualized = true;
+	dlfb->virtualized = true;
 
 	/* When non-active we'll update virtual framebuffer, but no new urbs */
-	atomic_set(&dev->usb_active, 0);
+	atomic_set(&dlfb->usb_active, 0);
 
 	/* this function will wait for all in-flight urbs to complete */
-	dlfb_free_urb_list(dev);
+	dlfb_free_urb_list(dlfb);
 
 	if (info) {
 		/* remove udlfb's sysfs interfaces */
@@ -1765,20 +1742,17 @@ static void dlfb_usb_disconnect(struct usb_interface *interface)
 		unlink_framebuffer(info);
 	}
 
-	usb_set_intfdata(interface, NULL);
-	dev->udev = NULL;
-	dev->gdev = NULL;
+	usb_set_intfdata(intf, NULL);
+	dlfb->udev = NULL;
 
 	/* if clients still have us open, will be freed on last close */
-	if (dev->fb_count == 0)
-		schedule_delayed_work(&dev->free_framebuffer_work, 0);
+	if (dlfb->fb_count == 0)
+		schedule_delayed_work(&dlfb->free_framebuffer_work, 0);
 
 	/* release reference taken by kref_init in probe() */
-	kref_put(&dev->kref, dlfb_free);
+	kref_put(&dlfb->kref, dlfb_free);
 
 	/* consider dlfb_data freed */
-
-	return;
 }
 
 static struct usb_driver dlfb_driver = {
@@ -1793,26 +1767,32 @@ module_usb_driver(dlfb_driver);
 static void dlfb_urb_completion(struct urb *urb)
 {
 	struct urb_node *unode = urb->context;
-	struct dlfb_data *dev = unode->dev;
+	struct dlfb_data *dlfb = unode->dlfb;
 	unsigned long flags;
 
-	/* sync/async unlink faults aren't errors */
-	if (urb->status) {
-		if (!(urb->status == -ENOENT ||
-		    urb->status == -ECONNRESET ||
-		    urb->status == -ESHUTDOWN)) {
-			pr_err("%s - nonzero write bulk status received: %d\n",
-				__func__, urb->status);
-			atomic_set(&dev->lost_pixels, 1);
-		}
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* sync/async unlink faults aren't errors */
+		break;
+	default:
+		dev_err(&dlfb->udev->dev,
+			"%s - nonzero write bulk status received: %d\n",
+			__func__, urb->status);
+		atomic_set(&dlfb->lost_pixels, 1);
+		break;
 	}
 
-	urb->transfer_buffer_length = dev->urbs.size; /* reset to actual */
+	urb->transfer_buffer_length = dlfb->urbs.size; /* reset to actual */
 
-	spin_lock_irqsave(&dev->urbs.lock, flags);
-	list_add_tail(&unode->entry, &dev->urbs.list);
-	dev->urbs.available++;
-	spin_unlock_irqrestore(&dev->urbs.lock, flags);
+	spin_lock_irqsave(&dlfb->urbs.lock, flags);
+	list_add_tail(&unode->entry, &dlfb->urbs.list);
+	dlfb->urbs.available++;
+	spin_unlock_irqrestore(&dlfb->urbs.lock, flags);
 
 	/*
 	 * When using fb_defio, we deadlock if up() is called
@@ -1821,65 +1801,63 @@ static void dlfb_urb_completion(struct urb *urb)
 	if (fb_defio)
 		schedule_delayed_work(&unode->release_urb_work, 0);
 	else
-		up(&dev->urbs.limit_sem);
+		up(&dlfb->urbs.limit_sem);
 }
 
-static void dlfb_free_urb_list(struct dlfb_data *dev)
+static void dlfb_free_urb_list(struct dlfb_data *dlfb)
 {
-	int count = dev->urbs.count;
+	int count = dlfb->urbs.count;
 	struct list_head *node;
 	struct urb_node *unode;
 	struct urb *urb;
 	int ret;
 	unsigned long flags;
 
-	pr_notice("Freeing all render urbs\n");
-
 	/* keep waiting and freeing, until we've got 'em all */
 	while (count--) {
 
 		/* Getting interrupted means a leak, but ok at disconnect */
-		ret = down_interruptible(&dev->urbs.limit_sem);
+		ret = down_interruptible(&dlfb->urbs.limit_sem);
 		if (ret)
 			break;
 
-		spin_lock_irqsave(&dev->urbs.lock, flags);
+		spin_lock_irqsave(&dlfb->urbs.lock, flags);
 
-		node = dev->urbs.list.next; /* have reserved one with sem */
+		node = dlfb->urbs.list.next; /* have reserved one with sem */
 		list_del_init(node);
 
-		spin_unlock_irqrestore(&dev->urbs.lock, flags);
+		spin_unlock_irqrestore(&dlfb->urbs.lock, flags);
 
 		unode = list_entry(node, struct urb_node, entry);
 		urb = unode->urb;
 
 		/* Free each separately allocated piece */
-		usb_free_coherent(urb->dev, dev->urbs.size,
+		usb_free_coherent(urb->dev, dlfb->urbs.size,
 				  urb->transfer_buffer, urb->transfer_dma);
 		usb_free_urb(urb);
 		kfree(node);
 	}
 
-	dev->urbs.count = 0;
+	dlfb->urbs.count = 0;
 }
 
-static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
+static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size)
 {
 	int i = 0;
 	struct urb *urb;
 	struct urb_node *unode;
 	char *buf;
 
-	spin_lock_init(&dev->urbs.lock);
+	spin_lock_init(&dlfb->urbs.lock);
 
-	dev->urbs.size = size;
-	INIT_LIST_HEAD(&dev->urbs.list);
+	dlfb->urbs.size = size;
+	INIT_LIST_HEAD(&dlfb->urbs.list);
 
 	while (i < count) {
-		unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL);
+		unode = kzalloc(sizeof(*unode), GFP_KERNEL);
 		if (!unode)
 			break;
-		unode->dev = dev;
+		unode->dlfb = dlfb;
 
 		INIT_DELAYED_WORK(&unode->release_urb_work,
 			  dlfb_release_urb_work);
@@ -1891,7 +1869,7 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
 		}
 		unode->urb = urb;
 
-		buf = usb_alloc_coherent(dev->udev, MAX_TRANSFER, GFP_KERNEL,
+		buf = usb_alloc_coherent(dlfb->udev, MAX_TRANSFER, GFP_KERNEL,
 					 &urb->transfer_dma);
 		if (!buf) {
 			kfree(unode);
@@ -1900,69 +1878,64 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
 		}
 
 		/* urb->transfer_buffer_length set to actual before submit */
-		usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 1),
+		usb_fill_bulk_urb(urb, dlfb->udev, usb_sndbulkpipe(dlfb->udev, 1),
 			buf, size, dlfb_urb_completion, unode);
 		urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-		list_add_tail(&unode->entry, &dev->urbs.list);
+		list_add_tail(&unode->entry, &dlfb->urbs.list);
 
 		i++;
 	}
 
-	sema_init(&dev->urbs.limit_sem, i);
-	dev->urbs.count = i;
-	dev->urbs.available = i;
-
-	pr_notice("allocated %d %d byte urbs\n", i, (int) size);
+	sema_init(&dlfb->urbs.limit_sem, i);
+	dlfb->urbs.count = i;
+	dlfb->urbs.available = i;
 
 	return i;
 }
 
-static struct urb *dlfb_get_urb(struct dlfb_data *dev)
+static struct urb *dlfb_get_urb(struct dlfb_data *dlfb)
 {
 	int ret;
 	struct list_head *entry;
 	struct urb_node *unode;
-	struct urb *urb = NULL;
 	unsigned long flags;
 
 	/* Wait for an in-flight buffer to complete and get re-queued */
-	ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT);
+	ret = down_timeout(&dlfb->urbs.limit_sem, GET_URB_TIMEOUT);
 	if (ret) {
-		atomic_set(&dev->lost_pixels, 1);
-		pr_warn("wait for urb interrupted: %x available: %d\n",
-		       ret, dev->urbs.available);
-		goto error;
+		atomic_set(&dlfb->lost_pixels, 1);
+		dev_warn(&dlfb->udev->dev,
+			 "wait for urb interrupted: %d available: %d\n",
+			 ret, dlfb->urbs.available);
+		return NULL;
 	}
 
-	spin_lock_irqsave(&dev->urbs.lock, flags);
+	spin_lock_irqsave(&dlfb->urbs.lock, flags);
 
-	BUG_ON(list_empty(&dev->urbs.list)); /* reserved one with limit_sem */
-	entry = dev->urbs.list.next;
+	BUG_ON(list_empty(&dlfb->urbs.list)); /* reserved one with limit_sem */
+	entry = dlfb->urbs.list.next;
 	list_del_init(entry);
-	dev->urbs.available--;
+	dlfb->urbs.available--;
 
-	spin_unlock_irqrestore(&dev->urbs.lock, flags);
+	spin_unlock_irqrestore(&dlfb->urbs.lock, flags);
 
 	unode = list_entry(entry, struct urb_node, entry);
-	urb = unode->urb;
-
-error:
-	return urb;
+	return unode->urb;
 }
 
-static int dlfb_submit_urb(struct dlfb_data *dev, struct urb *urb, size_t len)
+static int dlfb_submit_urb(struct dlfb_data *dlfb, struct urb *urb, size_t len)
 {
 	int ret;
 
-	BUG_ON(len > dev->urbs.size);
+	BUG_ON(len > dlfb->urbs.size);
 
 	urb->transfer_buffer_length = len; /* set to actual payload len */
 	ret = usb_submit_urb(urb, GFP_KERNEL);
 	if (ret) {
 		dlfb_urb_completion(urb); /* because no one else will */
-		atomic_set(&dev->lost_pixels, 1);
-		pr_err("usb_submit_urb error %x\n", ret);
+		atomic_set(&dlfb->lost_pixels, 1);
+		dev_err(&dlfb->udev->dev, "submit urb error: %d\n", ret);
 	}
 	return ret;
 }
diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c
index da653a0..5412790 100644
--- a/drivers/video/fbdev/vfb.c
+++ b/drivers/video/fbdev/vfb.c
@@ -239,8 +239,23 @@ static int vfb_check_var(struct fb_var_screeninfo *var,
  */
 static int vfb_set_par(struct fb_info *info)
 {
+	switch (info->var.bits_per_pixel) {
+	case 1:
+		info->fix.visual = FB_VISUAL_MONO01;
+		break;
+	case 8:
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		break;
+	case 16:
+	case 24:
+	case 32:
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+		break;
+	}
+
 	info->fix.line_length = get_line_length(info->var.xres_virtual,
 						info->var.bits_per_pixel);
+
 	return 0;
 }
 
@@ -450,6 +465,8 @@ static int vfb_probe(struct platform_device *dev)
 		goto err2;
 	platform_set_drvdata(dev, info);
 
+	vfb_set_par(info);
+
 	fb_info(info, "Virtual frame buffer device, using %ldK of video memory\n",
 		videomemorysize >> 10);
 	return 0;
diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c
index 5f0690c..2c6a576 100644
--- a/drivers/video/fbdev/vga16fb.c
+++ b/drivers/video/fbdev/vga16fb.c
@@ -1055,7 +1055,6 @@ static void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
 	case FB_TYPE_VGA_PLANES:
 		if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
 			width = width/8;
-			height = height;
 			line_ofs = info->fix.line_length - width;
 
 			setmode(1);
diff --git a/drivers/video/fbdev/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c
index 1a1176b..5c5cd29 100644
--- a/drivers/video/fbdev/vt8500lcdfb.c
+++ b/drivers/video/fbdev/vt8500lcdfb.c
@@ -289,10 +289,8 @@ static int vt8500lcd_probe(struct platform_device *pdev)
 
 	fbi = devm_kzalloc(&pdev->dev, sizeof(struct vt8500lcd_info)
 			+ sizeof(u32) * 16, GFP_KERNEL);
-	if (!fbi) {
-		dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
+	if (!fbi)
 		return -ENOMEM;
-	}
 
 	strcpy(fbi->fb.fix.id, "VT8500 LCD");
 
diff --git a/drivers/video/fbdev/wm8505fb.c b/drivers/video/fbdev/wm8505fb.c
index 253ffe9..8f0d537 100644
--- a/drivers/video/fbdev/wm8505fb.c
+++ b/drivers/video/fbdev/wm8505fb.c
@@ -276,10 +276,8 @@ static int wm8505fb_probe(struct platform_device *pdev)
 
 	fbi = devm_kzalloc(&pdev->dev, sizeof(struct wm8505fb_info) +
 			sizeof(u32) * 16, GFP_KERNEL);
-	if (!fbi) {
-		dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
+	if (!fbi)
 		return -ENOMEM;
-	}
 
 	strcpy(fbi->fb.fix.id, DRIVER_NAME);
 
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index cff773f..3589764 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -5,7 +5,11 @@
 	  bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_RPMSG
 	  or CONFIG_S390_GUEST.
 
-menu "Virtio drivers"
+menuconfig VIRTIO_MENU
+	bool "Virtio drivers"
+	default y
+
+if VIRTIO_MENU
 
 config VIRTIO_PCI
 	tristate "PCI driver for virtio devices"
@@ -79,4 +83,4 @@
 
 	 If unsure, say 'N'.
 
-endmenu
+endif # VIRTIO_MENU
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index bf7ff39..59e36ef 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -303,11 +303,21 @@ void unregister_virtio_driver(struct virtio_driver *driver)
 }
 EXPORT_SYMBOL_GPL(unregister_virtio_driver);
 
+/**
+ * register_virtio_device - register virtio device
+ * @dev        : virtio device to be registered
+ *
+ * On error, the caller must call put_device on &@dev->dev (and not kfree),
+ * as another code path may have obtained a reference to @dev.
+ *
+ * Returns: 0 on suceess, -error on failure
+ */
 int register_virtio_device(struct virtio_device *dev)
 {
 	int err;
 
 	dev->dev.bus = &virtio_bus;
+	device_initialize(&dev->dev);
 
 	/* Assign a unique device index and hence name. */
 	err = ida_simple_get(&virtio_index_ida, 0, 0, GFP_KERNEL);
@@ -330,9 +340,11 @@ int register_virtio_device(struct virtio_device *dev)
 
 	INIT_LIST_HEAD(&dev->vqs);
 
-	/* device_register() causes the bus infrastructure to look for a
-	 * matching driver. */
-	err = device_register(&dev->dev);
+	/*
+	 * device_add() causes the bus infrastructure to look for a matching
+	 * driver.
+	 */
+	err = device_add(&dev->dev);
 	if (err)
 		ida_simple_remove(&virtio_index_ida, dev->index);
 out:
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index a1fb52c..dfe5684 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -257,11 +257,13 @@ static unsigned int update_balloon_stats(struct virtio_balloon *vb)
 	struct sysinfo i;
 	unsigned int idx = 0;
 	long available;
+	unsigned long caches;
 
 	all_vm_events(events);
 	si_meminfo(&i);
 
 	available = si_mem_available();
+	caches = global_node_page_state(NR_FILE_PAGES);
 
 #ifdef CONFIG_VM_EVENT_COUNTERS
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_IN,
@@ -277,6 +279,8 @@ static unsigned int update_balloon_stats(struct virtio_balloon *vb)
 				pages_to_bytes(i.totalram));
 	update_stat(vb, idx++, VIRTIO_BALLOON_S_AVAIL,
 				pages_to_bytes(available));
+	update_stat(vb, idx++, VIRTIO_BALLOON_S_CACHES,
+				pages_to_bytes(caches));
 
 	return idx;
 }
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index c92131e..67763d3 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -662,10 +662,8 @@ static int vm_cmdline_set(const char *device,
 	pdev = platform_device_register_resndata(&vm_cmdline_parent,
 			"virtio-mmio", vm_cmdline_id++,
 			resources, ARRAY_SIZE(resources), NULL, 0);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
 
-	return 0;
+	return PTR_ERR_OR_ZERO(pdev);
 }
 
 static int vm_cmdline_get_device(struct device *dev, void *data)
@@ -725,7 +723,7 @@ static void vm_unregister_cmdline_devices(void)
 
 /* Platform driver */
 
-static struct of_device_id virtio_mmio_match[] = {
+static const struct of_device_id virtio_mmio_match[] = {
 	{ .compatible = "virtio,mmio", },
 	{},
 };
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index 1c4797e..48d4d1c 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -513,7 +513,7 @@ static void virtio_pci_release_dev(struct device *_d)
 static int virtio_pci_probe(struct pci_dev *pci_dev,
 			    const struct pci_device_id *id)
 {
-	struct virtio_pci_device *vp_dev;
+	struct virtio_pci_device *vp_dev, *reg_dev = NULL;
 	int rc;
 
 	/* allocate our structure and fill it out */
@@ -551,6 +551,7 @@ static int virtio_pci_probe(struct pci_dev *pci_dev,
 	pci_set_master(pci_dev);
 
 	rc = register_virtio_device(&vp_dev->vdev);
+	reg_dev = vp_dev;
 	if (rc)
 		goto err_register;
 
@@ -564,7 +565,10 @@ static int virtio_pci_probe(struct pci_dev *pci_dev,
 err_probe:
 	pci_disable_device(pci_dev);
 err_enable_device:
-	kfree(vp_dev);
+	if (reg_dev)
+		put_device(&vp_dev->vdev.dev);
+	else
+		kfree(vp_dev);
 	return rc;
 }
 
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 5bf613d..aff773b 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -328,16 +328,18 @@
 
 	  Not sure? It's safe to say N.
 
-config GEMINI_WATCHDOG
-	tristate "Gemini watchdog"
-	depends on ARCH_GEMINI
+config FTWDT010_WATCHDOG
+	tristate "Faraday Technology FTWDT010 watchdog"
+	depends on ARM || COMPILE_TEST
 	select WATCHDOG_CORE
+	default ARCH_GEMINI
 	help
-	  Say Y here if to include support for the watchdog timer
-	  embedded in the Cortina Systems Gemini family of devices.
+	  Say Y here if to include support for the Faraday Technology
+	  FTWDT010 watchdog timer embedded in the Cortina Systems Gemini
+	  family of devices.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called gemini_wdt.
+	  module will be called ftwdt010_wdt.
 
 config IXP4XX_WATCHDOG
 	tristate "IXP4xx Watchdog"
@@ -748,12 +750,12 @@
 	  Renesas RZ/A SoCs. These watchdogs can be used to reset a system.
 
 config ASPEED_WATCHDOG
-	tristate "Aspeed 2400 watchdog support"
+	tristate "Aspeed BMC watchdog support"
 	depends on ARCH_ASPEED || COMPILE_TEST
 	select WATCHDOG_CORE
 	help
 	  Say Y here to include support for the watchdog timer
-	  in Apseed BMC SoCs.
+	  in Aspeed BMC SoCs.
 
 	  This driver is required to reboot the SoC.
 
@@ -794,14 +796,23 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called uniphier_wdt.
 
-# AVR32 Architecture
-
-config AT32AP700X_WDT
-	tristate "AT32AP700x watchdog"
-	depends on CPU_AT32AP700X || COMPILE_TEST
+config RTD119X_WATCHDOG
+	bool "Realtek RTD119x/RTD129x watchdog support"
+	depends on ARCH_REALTEK || COMPILE_TEST
+	depends on OF
+	select WATCHDOG_CORE
+	default ARCH_REALTEK
 	help
-	  Watchdog timer embedded into AT32AP700x devices. This will reboot
-	  your system when the timeout is reached.
+	  Say Y here to include support for the watchdog timer in
+	  Realtek RTD1295 SoCs.
+
+config SPRD_WATCHDOG
+	tristate "Spreadtrum watchdog support"
+	depends on ARCH_SPRD || COMPILE_TEST
+	select WATCHDOG_CORE
+	help
+	  Say Y here to include watchdog timer supported
+	  by Spreadtrum system.
 
 # BLACKFIN Architecture
 
@@ -1458,7 +1469,7 @@
 
 config INDYDOG
 	tristate "Indy/I2 Hardware Watchdog"
-	depends on SGI_HAS_INDYDOG || (MIPS && COMPILE_TEST)
+	depends on SGI_HAS_INDYDOG
 	help
 	  Hardware driver for the Indy's/I2's watchdog. This is a
 	  watchdog timer that will reboot the machine after a 60 second
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 135c5e8..0474d38 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -46,7 +46,7 @@
 obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o
 obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
 obj-$(CONFIG_977_WATCHDOG) += wdt977.o
-obj-$(CONFIG_GEMINI_WATCHDOG) += gemini_wdt.o
+obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
 obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
 obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
 obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
@@ -88,9 +88,8 @@
 obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o
 obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o
 obj-$(CONFIG_UNIPHIER_WATCHDOG) += uniphier_wdt.o
-
-# AVR32 Architecture
-obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
+obj-$(CONFIG_RTD119X_WATCHDOG) += rtd119x_wdt.o
+obj-$(CONFIG_SPRD_WATCHDOG) += sprd_wdt.o
 
 # BLACKFIN Architecture
 obj-$(CONFIG_BFIN_WDT) += bfin_wdt.o
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index 7d7db0c..f619443 100644
--- a/drivers/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
@@ -181,7 +181,7 @@ static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		if (advwdt_set_heartbeat(new_timeout))
 			return -EINVAL;
 		advwdt_ping();
-		/* Fall */
+		/* fall through */
 	case WDIOC_GETTIMEOUT:
 		return put_user(timeout, p);
 	default:
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index 3a17fbd..60f0c2e 100644
--- a/drivers/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
@@ -223,8 +223,8 @@ static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		if (ali_settimer(new_timeout))
 			return -EINVAL;
 		ali_keepalive();
-		/* Fall */
 	}
+		/* fall through */
 	case WDIOC_GETTIMEOUT:
 		return put_user(timeout, p);
 	default:
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index 79cc766..ca5b91e 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -243,9 +243,13 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
 	if (of_property_read_bool(np, "aspeed,external-signal"))
 		wdt->ctrl |= WDT_CTRL_WDT_EXT;
 
-	writel(wdt->ctrl, wdt->base + WDT_CTRL);
-
 	if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE)  {
+		/*
+		 * The watchdog is running, but invoke aspeed_wdt_start() to
+		 * write wdt->ctrl to WDT_CTRL to ensure the watchdog's
+		 * configuration conforms to the driver's expectations.
+		 * Primarily, ensure we're using the 1MHz clock source.
+		 */
 		aspeed_wdt_start(&wdt->wdd);
 		set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
 	}
@@ -312,7 +316,18 @@ static struct platform_driver aspeed_watchdog_driver = {
 		.of_match_table = of_match_ptr(aspeed_wdt_of_table),
 	},
 };
-module_platform_driver(aspeed_watchdog_driver);
+
+static int __init aspeed_wdt_init(void)
+{
+	return platform_driver_register(&aspeed_watchdog_driver);
+}
+arch_initcall(aspeed_wdt_init);
+
+static void __exit aspeed_wdt_exit(void)
+{
+	platform_driver_unregister(&aspeed_watchdog_driver);
+}
+module_exit(aspeed_wdt_exit);
 
 MODULE_DESCRIPTION("Aspeed Watchdog Driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
deleted file mode 100644
index 81ba892..0000000
--- a/drivers/watchdog/at32ap700x_wdt.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Watchdog driver for Atmel AT32AP700X devices
- *
- * Copyright (C) 2005-2006 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *
- * Errata: WDT Clear is blocked after WDT Reset
- *
- * A watchdog timer event will, after reset, block writes to the WDT_CLEAR
- * register, preventing the program to clear the next Watchdog Timer Reset.
- *
- * If you still want to use the WDT after a WDT reset a small code can be
- * insterted at the startup checking the AVR32_PM.rcause register for WDT reset
- * and use a GPIO pin to reset the system. This method requires that one of the
- * GPIO pins are available and connected externally to the RESET_N pin. After
- * the GPIO pin has pulled down the reset line the GPIO will be reset and leave
- * the pin tristated with pullup.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/platform_device.h>
-#include <linux/watchdog.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-
-#define TIMEOUT_MIN		1
-#define TIMEOUT_MAX		2
-#define TIMEOUT_DEFAULT		TIMEOUT_MAX
-
-/* module parameters */
-static int timeout =  TIMEOUT_DEFAULT;
-module_param(timeout, int, 0);
-MODULE_PARM_DESC(timeout,
-		"Timeout value. Limited to be 1 or 2 seconds. (default="
-		__MODULE_STRING(TIMEOUT_DEFAULT) ")");
-
-static bool nowayout = WATCHDOG_NOWAYOUT;
-module_param(nowayout, bool, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
-		__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-
-/* Watchdog registers and write/read macro */
-#define WDT_CTRL		0x00
-#define WDT_CTRL_EN		   0
-#define WDT_CTRL_PSEL		   8
-#define WDT_CTRL_KEY		  24
-
-#define WDT_CLR			0x04
-
-#define WDT_RCAUSE		0x10
-#define WDT_RCAUSE_POR		   0
-#define WDT_RCAUSE_EXT		   2
-#define WDT_RCAUSE_WDT		   3
-#define WDT_RCAUSE_JTAG		   4
-#define WDT_RCAUSE_SERP		   5
-
-#define WDT_BIT(name)		(1 << WDT_##name)
-#define WDT_BF(name, value)	((value) << WDT_##name)
-
-#define wdt_readl(dev, reg)				\
-	__raw_readl((dev)->regs + WDT_##reg)
-#define wdt_writel(dev, reg, value)			\
-	__raw_writel((value), (dev)->regs + WDT_##reg)
-
-struct wdt_at32ap700x {
-	void __iomem		*regs;
-	spinlock_t		io_lock;
-	int			timeout;
-	int			boot_status;
-	unsigned long		users;
-	struct miscdevice	miscdev;
-};
-
-static struct wdt_at32ap700x *wdt;
-static char expect_release;
-
-/*
- * Disable the watchdog.
- */
-static inline void at32_wdt_stop(void)
-{
-	unsigned long psel;
-
-	spin_lock(&wdt->io_lock);
-	psel = wdt_readl(wdt, CTRL) & WDT_BF(CTRL_PSEL, 0x0f);
-	wdt_writel(wdt, CTRL, psel | WDT_BF(CTRL_KEY, 0x55));
-	wdt_writel(wdt, CTRL, psel | WDT_BF(CTRL_KEY, 0xaa));
-	spin_unlock(&wdt->io_lock);
-}
-
-/*
- * Enable and reset the watchdog.
- */
-static inline void at32_wdt_start(void)
-{
-	/* 0xf is 2^16 divider = 2 sec, 0xe is 2^15 divider = 1 sec */
-	unsigned long psel = (wdt->timeout > 1) ? 0xf : 0xe;
-
-	spin_lock(&wdt->io_lock);
-	wdt_writel(wdt, CTRL, WDT_BIT(CTRL_EN)
-			| WDT_BF(CTRL_PSEL, psel)
-			| WDT_BF(CTRL_KEY, 0x55));
-	wdt_writel(wdt, CTRL, WDT_BIT(CTRL_EN)
-			| WDT_BF(CTRL_PSEL, psel)
-			| WDT_BF(CTRL_KEY, 0xaa));
-	spin_unlock(&wdt->io_lock);
-}
-
-/*
- * Pat the watchdog timer.
- */
-static inline void at32_wdt_pat(void)
-{
-	spin_lock(&wdt->io_lock);
-	wdt_writel(wdt, CLR, 0x42);
-	spin_unlock(&wdt->io_lock);
-}
-
-/*
- * Watchdog device is opened, and watchdog starts running.
- */
-static int at32_wdt_open(struct inode *inode, struct file *file)
-{
-	if (test_and_set_bit(1, &wdt->users))
-		return -EBUSY;
-
-	at32_wdt_start();
-	return nonseekable_open(inode, file);
-}
-
-/*
- * Close the watchdog device.
- */
-static int at32_wdt_close(struct inode *inode, struct file *file)
-{
-	if (expect_release == 42) {
-		at32_wdt_stop();
-	} else {
-		dev_dbg(wdt->miscdev.parent,
-			"unexpected close, not stopping watchdog!\n");
-		at32_wdt_pat();
-	}
-	clear_bit(1, &wdt->users);
-	expect_release = 0;
-	return 0;
-}
-
-/*
- * Change the watchdog time interval.
- */
-static int at32_wdt_settimeout(int time)
-{
-	/*
-	 * All counting occurs at 1 / SLOW_CLOCK (32 kHz) and max prescaler is
-	 * 2 ^ 16 allowing up to 2 seconds timeout.
-	 */
-	if ((time < TIMEOUT_MIN) || (time > TIMEOUT_MAX))
-		return -EINVAL;
-
-	/*
-	 * Set new watchdog time. It will be used when at32_wdt_start() is
-	 * called.
-	 */
-	wdt->timeout = time;
-	return 0;
-}
-
-/*
- * Get the watchdog status.
- */
-static int at32_wdt_get_status(void)
-{
-	int rcause;
-	int status = 0;
-
-	rcause = wdt_readl(wdt, RCAUSE);
-
-	switch (rcause) {
-	case WDT_BIT(RCAUSE_EXT):
-		status = WDIOF_EXTERN1;
-		break;
-	case WDT_BIT(RCAUSE_WDT):
-		status = WDIOF_CARDRESET;
-		break;
-	case WDT_BIT(RCAUSE_POR):  /* fall through */
-	case WDT_BIT(RCAUSE_JTAG): /* fall through */
-	case WDT_BIT(RCAUSE_SERP): /* fall through */
-	default:
-		break;
-	}
-
-	return status;
-}
-
-static const struct watchdog_info at32_wdt_info = {
-	.identity	= "at32ap700x watchdog",
-	.options	= WDIOF_SETTIMEOUT |
-			  WDIOF_KEEPALIVEPING |
-			  WDIOF_MAGICCLOSE,
-};
-
-/*
- * Handle commands from user-space.
- */
-static long at32_wdt_ioctl(struct file *file,
-				unsigned int cmd, unsigned long arg)
-{
-	int ret = -ENOTTY;
-	int time;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	switch (cmd) {
-	case WDIOC_GETSUPPORT:
-		ret = copy_to_user(argp, &at32_wdt_info,
-				sizeof(at32_wdt_info)) ? -EFAULT : 0;
-		break;
-	case WDIOC_GETSTATUS:
-		ret = put_user(0, p);
-		break;
-	case WDIOC_GETBOOTSTATUS:
-		ret = put_user(wdt->boot_status, p);
-		break;
-	case WDIOC_SETOPTIONS:
-		ret = get_user(time, p);
-		if (ret)
-			break;
-		if (time & WDIOS_DISABLECARD)
-			at32_wdt_stop();
-		if (time & WDIOS_ENABLECARD)
-			at32_wdt_start();
-		ret = 0;
-		break;
-	case WDIOC_KEEPALIVE:
-		at32_wdt_pat();
-		ret = 0;
-		break;
-	case WDIOC_SETTIMEOUT:
-		ret = get_user(time, p);
-		if (ret)
-			break;
-		ret = at32_wdt_settimeout(time);
-		if (ret)
-			break;
-		/* Enable new time value */
-		at32_wdt_start();
-		/* fall through */
-	case WDIOC_GETTIMEOUT:
-		ret = put_user(wdt->timeout, p);
-		break;
-	}
-
-	return ret;
-}
-
-static ssize_t at32_wdt_write(struct file *file, const char __user *data,
-				size_t len, loff_t *ppos)
-{
-	/* See if we got the magic character 'V' and reload the timer */
-	if (len) {
-		if (!nowayout) {
-			size_t i;
-
-			/*
-			 * note: just in case someone wrote the magic
-			 * character five months ago...
-			 */
-			expect_release = 0;
-
-			/*
-			 * scan to see whether or not we got the magic
-			 * character
-			 */
-			for (i = 0; i != len; i++) {
-				char c;
-				if (get_user(c, data + i))
-					return -EFAULT;
-				if (c == 'V')
-					expect_release = 42;
-			}
-		}
-		/* someone wrote to us, we should pat the watchdog */
-		at32_wdt_pat();
-	}
-	return len;
-}
-
-static const struct file_operations at32_wdt_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.unlocked_ioctl	= at32_wdt_ioctl,
-	.open		= at32_wdt_open,
-	.release	= at32_wdt_close,
-	.write		= at32_wdt_write,
-};
-
-static int __init at32_wdt_probe(struct platform_device *pdev)
-{
-	struct resource	*regs;
-	int ret;
-
-	if (wdt) {
-		dev_dbg(&pdev->dev, "only 1 wdt instance supported.\n");
-		return -EBUSY;
-	}
-
-	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!regs) {
-		dev_dbg(&pdev->dev, "missing mmio resource\n");
-		return -ENXIO;
-	}
-
-	wdt = devm_kzalloc(&pdev->dev, sizeof(struct wdt_at32ap700x),
-			GFP_KERNEL);
-	if (!wdt)
-		return -ENOMEM;
-
-	wdt->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
-	if (!wdt->regs) {
-		ret = -ENOMEM;
-		dev_dbg(&pdev->dev, "could not map I/O memory\n");
-		goto err_free;
-	}
-
-	spin_lock_init(&wdt->io_lock);
-	wdt->boot_status = at32_wdt_get_status();
-
-	/* Work-around for watchdog silicon errata. */
-	if (wdt->boot_status & WDIOF_CARDRESET) {
-		dev_info(&pdev->dev, "CPU must be reset with external "
-				"reset or POR due to silicon errata.\n");
-		ret = -EIO;
-		goto err_free;
-	} else {
-		wdt->users = 0;
-	}
-
-	wdt->miscdev.minor	= WATCHDOG_MINOR;
-	wdt->miscdev.name	= "watchdog";
-	wdt->miscdev.fops	= &at32_wdt_fops;
-	wdt->miscdev.parent	= &pdev->dev;
-
-	platform_set_drvdata(pdev, wdt);
-
-	if (at32_wdt_settimeout(timeout)) {
-		at32_wdt_settimeout(TIMEOUT_DEFAULT);
-		dev_dbg(&pdev->dev,
-			"default timeout invalid, set to %d sec.\n",
-			TIMEOUT_DEFAULT);
-	}
-
-	ret = misc_register(&wdt->miscdev);
-	if (ret) {
-		dev_dbg(&pdev->dev, "failed to register wdt miscdev\n");
-		goto err_free;
-	}
-
-	dev_info(&pdev->dev,
-		"AT32AP700X WDT at 0x%p, timeout %d sec (nowayout=%d)\n",
-		wdt->regs, wdt->timeout, nowayout);
-
-	return 0;
-
-err_free:
-	wdt = NULL;
-	return ret;
-}
-
-static int __exit at32_wdt_remove(struct platform_device *pdev)
-{
-	if (wdt && platform_get_drvdata(pdev) == wdt) {
-		/* Stop the timer before we leave */
-		if (!nowayout)
-			at32_wdt_stop();
-
-		misc_deregister(&wdt->miscdev);
-		wdt = NULL;
-	}
-	return 0;
-}
-
-static void at32_wdt_shutdown(struct platform_device *pdev)
-{
-	at32_wdt_stop();
-}
-
-#ifdef CONFIG_PM
-static int at32_wdt_suspend(struct platform_device *pdev, pm_message_t message)
-{
-	at32_wdt_stop();
-	return 0;
-}
-
-static int at32_wdt_resume(struct platform_device *pdev)
-{
-	if (wdt->users)
-		at32_wdt_start();
-	return 0;
-}
-#else
-#define at32_wdt_suspend NULL
-#define at32_wdt_resume NULL
-#endif
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:at32_wdt");
-
-static struct platform_driver at32_wdt_driver = {
-	.remove		= __exit_p(at32_wdt_remove),
-	.suspend	= at32_wdt_suspend,
-	.resume		= at32_wdt_resume,
-	.driver		= {
-		.name	= "at32_wdt",
-	},
-	.shutdown	= at32_wdt_shutdown,
-};
-
-module_platform_driver_probe(at32_wdt_driver, at32_wdt_probe);
-
-MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
-MODULE_DESCRIPTION("Watchdog driver for Atmel AT32AP700X");
-MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
index 9083d3d..814dff6 100644
--- a/drivers/watchdog/da9062_wdt.c
+++ b/drivers/watchdog/da9062_wdt.c
@@ -46,22 +46,6 @@ static void da9062_set_window_start(struct da9062_watchdog *wdt)
 	wdt->j_time_stamp = jiffies;
 }
 
-static void da9062_apply_window_protection(struct da9062_watchdog *wdt)
-{
-	unsigned long delay = msecs_to_jiffies(DA9062_RESET_PROTECTION_MS);
-	unsigned long timeout = wdt->j_time_stamp + delay;
-	unsigned long now = jiffies;
-	unsigned int diff_ms;
-
-	/* if time-limit has not elapsed then wait for remainder */
-	if (time_before(now, timeout)) {
-		diff_ms = jiffies_to_msecs(timeout-now);
-		dev_dbg(wdt->hw->dev,
-			"Kicked too quickly. Delaying %u msecs\n", diff_ms);
-		msleep(diff_ms);
-	}
-}
-
 static unsigned int da9062_wdt_timeout_to_sel(unsigned int secs)
 {
 	unsigned int i;
@@ -78,8 +62,6 @@ static int da9062_reset_watchdog_timer(struct da9062_watchdog *wdt)
 {
 	int ret;
 
-	da9062_apply_window_protection(wdt);
-
 	ret = regmap_update_bits(wdt->hw->regmap,
 			   DA9062AA_CONTROL_F,
 			   DA9062AA_WATCHDOG_MASK,
@@ -100,6 +82,13 @@ static int da9062_wdt_update_timeout_register(struct da9062_watchdog *wdt,
 	if (ret)
 		return ret;
 
+	regmap_update_bits(chip->regmap,
+				  DA9062AA_CONTROL_D,
+				  DA9062AA_TWDSCALE_MASK,
+				  DA9062_TWDSCALE_DISABLE);
+
+	usleep_range(150, 300);
+
 	return regmap_update_bits(chip->regmap,
 				  DA9062AA_CONTROL_D,
 				  DA9062AA_TWDSCALE_MASK,
@@ -175,6 +164,25 @@ static int da9062_wdt_set_timeout(struct watchdog_device *wdd,
 	return ret;
 }
 
+static int da9062_wdt_restart(struct watchdog_device *wdd, unsigned long action,
+			      void *data)
+{
+	struct da9062_watchdog *wdt = watchdog_get_drvdata(wdd);
+	int ret;
+
+	ret = regmap_write(wdt->hw->regmap,
+			   DA9062AA_CONTROL_F,
+			   DA9062AA_SHUTDOWN_MASK);
+	if (ret)
+		dev_alert(wdt->hw->dev, "Failed to shutdown (err = %d)\n",
+			  ret);
+
+	/* wait for reset to assert... */
+	mdelay(500);
+
+	return ret;
+}
+
 static const struct watchdog_info da9062_watchdog_info = {
 	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
 	.identity = "DA9062 WDT",
@@ -186,6 +194,7 @@ static const struct watchdog_ops da9062_watchdog_ops = {
 	.stop = da9062_wdt_stop,
 	.ping = da9062_wdt_ping,
 	.set_timeout = da9062_wdt_set_timeout,
+	.restart = da9062_wdt_restart,
 };
 
 static const struct of_device_id da9062_compatible_id_table[] = {
@@ -215,10 +224,13 @@ static int da9062_wdt_probe(struct platform_device *pdev)
 	wdt->wdtdev.ops = &da9062_watchdog_ops;
 	wdt->wdtdev.min_timeout = DA9062_WDT_MIN_TIMEOUT;
 	wdt->wdtdev.max_timeout = DA9062_WDT_MAX_TIMEOUT;
+	wdt->wdtdev.min_hw_heartbeat_ms = DA9062_RESET_PROTECTION_MS;
 	wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
 	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
 	wdt->wdtdev.parent = &pdev->dev;
 
+	watchdog_set_restart_priority(&wdt->wdtdev, 128);
+
 	watchdog_set_drvdata(&wdt->wdtdev, wdt);
 
 	ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev);
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 2f46487..3e4c592 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -140,6 +140,42 @@ static unsigned int davinci_wdt_get_timeleft(struct watchdog_device *wdd)
 	return wdd->timeout - timer_counter;
 }
 
+static int davinci_wdt_restart(struct watchdog_device *wdd,
+			       unsigned long action, void *data)
+{
+	struct davinci_wdt_device *davinci_wdt = watchdog_get_drvdata(wdd);
+	u32 tgcr, wdtcr;
+
+	/* disable, internal clock source */
+	iowrite32(0, davinci_wdt->base + TCR);
+
+	/* reset timer, set mode to 64-bit watchdog, and unreset */
+	tgcr = 0;
+	iowrite32(tgcr, davinci_wdt->base + TGCR);
+	tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET;
+	iowrite32(tgcr, davinci_wdt->base + TGCR);
+
+	/* clear counter and period regs */
+	iowrite32(0, davinci_wdt->base + TIM12);
+	iowrite32(0, davinci_wdt->base + TIM34);
+	iowrite32(0, davinci_wdt->base + PRD12);
+	iowrite32(0, davinci_wdt->base + PRD34);
+
+	/* put watchdog in pre-active state */
+	wdtcr = WDKEY_SEQ0 | WDEN;
+	iowrite32(wdtcr, davinci_wdt->base + WDTCR);
+
+	/* put watchdog in active state */
+	wdtcr = WDKEY_SEQ1 | WDEN;
+	iowrite32(wdtcr, davinci_wdt->base + WDTCR);
+
+	/* write an invalid value to the WDKEY field to trigger a restart */
+	wdtcr = 0x00004000;
+	iowrite32(wdtcr, davinci_wdt->base + WDTCR);
+
+	return 0;
+}
+
 static const struct watchdog_info davinci_wdt_info = {
 	.options = WDIOF_KEEPALIVEPING,
 	.identity = "DaVinci/Keystone Watchdog",
@@ -151,6 +187,7 @@ static const struct watchdog_ops davinci_wdt_ops = {
 	.stop		= davinci_wdt_ping,
 	.ping		= davinci_wdt_ping,
 	.get_timeleft	= davinci_wdt_get_timeleft,
+	.restart	= davinci_wdt_restart,
 };
 
 static int davinci_wdt_probe(struct platform_device *pdev)
@@ -195,6 +232,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
 
 	watchdog_set_drvdata(wdd, davinci_wdt);
 	watchdog_set_nowayout(wdd, 1);
+	watchdog_set_restart_priority(wdd, 128);
 
 	wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem);
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index 36be987..c2f4ff5 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -127,14 +127,27 @@ static int dw_wdt_start(struct watchdog_device *wdd)
 
 	dw_wdt_set_timeout(wdd, wdd->timeout);
 
-	set_bit(WDOG_HW_RUNNING, &wdd->status);
-
 	writel(WDOG_CONTROL_REG_WDT_EN_MASK,
 	       dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
 
 	return 0;
 }
 
+static int dw_wdt_stop(struct watchdog_device *wdd)
+{
+	struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
+
+	if (!dw_wdt->rst) {
+		set_bit(WDOG_HW_RUNNING, &wdd->status);
+		return 0;
+	}
+
+	reset_control_assert(dw_wdt->rst);
+	reset_control_deassert(dw_wdt->rst);
+
+	return 0;
+}
+
 static int dw_wdt_restart(struct watchdog_device *wdd,
 			  unsigned long action, void *data)
 {
@@ -173,6 +186,7 @@ static const struct watchdog_info dw_wdt_ident = {
 static const struct watchdog_ops dw_wdt_ops = {
 	.owner		= THIS_MODULE,
 	.start		= dw_wdt_start,
+	.stop		= dw_wdt_stop,
 	.ping		= dw_wdt_ping,
 	.set_timeout	= dw_wdt_set_timeout,
 	.get_timeleft	= dw_wdt_get_timeleft,
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index 38e9671..47f77a6 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -290,7 +290,7 @@ static long eurwdt_ioctl(struct file *file,
 		eurwdt_timeout = time;
 		eurwdt_set_timeout(time);
 		spin_unlock(&eurwdt_lock);
-		/* Fall */
+		/* fall through */
 
 	case WDIOC_GETTIMEOUT:
 		return put_user(eurwdt_timeout, p);
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index 8658dba..e0678c1 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -627,7 +627,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
 
 		if (new_options & WDIOS_ENABLECARD)
 			return watchdog_start();
-
+		/* fall through */
 
 	case WDIOC_KEEPALIVE:
 		watchdog_keepalive();
@@ -641,7 +641,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
 			return -EINVAL;
 
 		watchdog_keepalive();
-		/* Fall */
+		/* fall through */
 
 	case WDIOC_GETTIMEOUT:
 		return put_user(watchdog.timeout, uarg.i);
diff --git a/drivers/watchdog/ftwdt010_wdt.c b/drivers/watchdog/ftwdt010_wdt.c
new file mode 100644
index 0000000..a9c2912
--- /dev/null
+++ b/drivers/watchdog/ftwdt010_wdt.c
@@ -0,0 +1,236 @@
+/*
+ * Watchdog driver for Faraday Technology FTWDT010
+ *
+ * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * Inspired by the out-of-tree drivers from OpenWRT:
+ * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/watchdog.h>
+
+#define FTWDT010_WDCOUNTER	0x0
+#define FTWDT010_WDLOAD		0x4
+#define FTWDT010_WDRESTART	0x8
+#define FTWDT010_WDCR		0xC
+
+#define WDRESTART_MAGIC		0x5AB9
+
+#define WDCR_CLOCK_5MHZ		BIT(4)
+#define WDCR_WDEXT		BIT(3)
+#define WDCR_WDINTR		BIT(2)
+#define WDCR_SYS_RST		BIT(1)
+#define WDCR_ENABLE		BIT(0)
+
+#define WDT_CLOCK		5000000		/* 5 MHz */
+
+struct ftwdt010_wdt {
+	struct watchdog_device	wdd;
+	struct device		*dev;
+	void __iomem		*base;
+	bool			has_irq;
+};
+
+static inline
+struct ftwdt010_wdt *to_ftwdt010_wdt(struct watchdog_device *wdd)
+{
+	return container_of(wdd, struct ftwdt010_wdt, wdd);
+}
+
+static int ftwdt010_wdt_start(struct watchdog_device *wdd)
+{
+	struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
+	u32 enable;
+
+	writel(wdd->timeout * WDT_CLOCK, gwdt->base + FTWDT010_WDLOAD);
+	writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
+	/* set clock before enabling */
+	enable = WDCR_CLOCK_5MHZ | WDCR_SYS_RST;
+	writel(enable, gwdt->base + FTWDT010_WDCR);
+	if (gwdt->has_irq)
+		enable |= WDCR_WDINTR;
+	enable |= WDCR_ENABLE;
+	writel(enable, gwdt->base + FTWDT010_WDCR);
+
+	return 0;
+}
+
+static int ftwdt010_wdt_stop(struct watchdog_device *wdd)
+{
+	struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
+
+	writel(0, gwdt->base + FTWDT010_WDCR);
+
+	return 0;
+}
+
+static int ftwdt010_wdt_ping(struct watchdog_device *wdd)
+{
+	struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
+
+	writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
+
+	return 0;
+}
+
+static int ftwdt010_wdt_set_timeout(struct watchdog_device *wdd,
+				  unsigned int timeout)
+{
+	wdd->timeout = timeout;
+	if (watchdog_active(wdd))
+		ftwdt010_wdt_start(wdd);
+
+	return 0;
+}
+
+static irqreturn_t ftwdt010_wdt_interrupt(int irq, void *data)
+{
+	struct ftwdt010_wdt *gwdt = data;
+
+	watchdog_notify_pretimeout(&gwdt->wdd);
+
+	return IRQ_HANDLED;
+}
+
+static const struct watchdog_ops ftwdt010_wdt_ops = {
+	.start		= ftwdt010_wdt_start,
+	.stop		= ftwdt010_wdt_stop,
+	.ping		= ftwdt010_wdt_ping,
+	.set_timeout	= ftwdt010_wdt_set_timeout,
+	.owner		= THIS_MODULE,
+};
+
+static const struct watchdog_info ftwdt010_wdt_info = {
+	.options	= WDIOF_KEEPALIVEPING
+			| WDIOF_MAGICCLOSE
+			| WDIOF_SETTIMEOUT,
+	.identity	= KBUILD_MODNAME,
+};
+
+
+static int ftwdt010_wdt_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct ftwdt010_wdt *gwdt;
+	unsigned int reg;
+	int irq;
+	int ret;
+
+	gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
+	if (!gwdt)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	gwdt->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(gwdt->base))
+		return PTR_ERR(gwdt->base);
+
+	gwdt->dev = dev;
+	gwdt->wdd.info = &ftwdt010_wdt_info;
+	gwdt->wdd.ops = &ftwdt010_wdt_ops;
+	gwdt->wdd.min_timeout = 1;
+	gwdt->wdd.max_timeout = 0xFFFFFFFF / WDT_CLOCK;
+	gwdt->wdd.parent = dev;
+
+	/*
+	 * If 'timeout-sec' unspecified in devicetree, assume a 13 second
+	 * default.
+	 */
+	gwdt->wdd.timeout = 13U;
+	watchdog_init_timeout(&gwdt->wdd, 0, dev);
+
+	reg = readw(gwdt->base + FTWDT010_WDCR);
+	if (reg & WDCR_ENABLE) {
+		/* Watchdog was enabled by the bootloader, disable it. */
+		reg &= ~WDCR_ENABLE;
+		writel(reg, gwdt->base + FTWDT010_WDCR);
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq) {
+		ret = devm_request_irq(dev, irq, ftwdt010_wdt_interrupt, 0,
+				       "watchdog bark", gwdt);
+		if (ret)
+			return ret;
+		gwdt->has_irq = true;
+	}
+
+	ret = devm_watchdog_register_device(dev, &gwdt->wdd);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register watchdog\n");
+		return ret;
+	}
+
+	/* Set up platform driver data */
+	platform_set_drvdata(pdev, gwdt);
+	dev_info(dev, "FTWDT010 watchdog driver enabled\n");
+
+	return 0;
+}
+
+static int __maybe_unused ftwdt010_wdt_suspend(struct device *dev)
+{
+	struct ftwdt010_wdt *gwdt = dev_get_drvdata(dev);
+	unsigned int reg;
+
+	reg = readw(gwdt->base + FTWDT010_WDCR);
+	reg &= ~WDCR_ENABLE;
+	writel(reg, gwdt->base + FTWDT010_WDCR);
+
+	return 0;
+}
+
+static int __maybe_unused ftwdt010_wdt_resume(struct device *dev)
+{
+	struct ftwdt010_wdt *gwdt = dev_get_drvdata(dev);
+	unsigned int reg;
+
+	if (watchdog_active(&gwdt->wdd)) {
+		reg = readw(gwdt->base + FTWDT010_WDCR);
+		reg |= WDCR_ENABLE;
+		writel(reg, gwdt->base + FTWDT010_WDCR);
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops ftwdt010_wdt_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(ftwdt010_wdt_suspend,
+				ftwdt010_wdt_resume)
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id ftwdt010_wdt_match[] = {
+	{ .compatible = "faraday,ftwdt010" },
+	{ .compatible = "cortina,gemini-watchdog" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ftwdt010_wdt_match);
+#endif
+
+static struct platform_driver ftwdt010_wdt_driver = {
+	.probe		= ftwdt010_wdt_probe,
+	.driver		= {
+		.name	= "ftwdt010-wdt",
+		.of_match_table = of_match_ptr(ftwdt010_wdt_match),
+		.pm = &ftwdt010_wdt_dev_pm_ops,
+	},
+};
+module_platform_driver(ftwdt010_wdt_driver);
+MODULE_AUTHOR("Linus Walleij");
+MODULE_DESCRIPTION("Watchdog driver for Faraday Technology FTWDT010");
+MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/gemini_wdt.c b/drivers/watchdog/gemini_wdt.c
deleted file mode 100644
index 8155aa6..0000000
--- a/drivers/watchdog/gemini_wdt.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Watchdog driver for Cortina Systems Gemini SoC
- *
- * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
- *
- * Inspired by the out-of-tree drivers from OpenWRT:
- * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/watchdog.h>
-
-#define GEMINI_WDCOUNTER	0x0
-#define GEMINI_WDLOAD		0x4
-#define GEMINI_WDRESTART	0x8
-#define GEMINI_WDCR		0xC
-
-#define WDRESTART_MAGIC		0x5AB9
-
-#define WDCR_CLOCK_5MHZ		BIT(4)
-#define WDCR_SYS_RST		BIT(1)
-#define WDCR_ENABLE		BIT(0)
-
-#define WDT_CLOCK		5000000		/* 5 MHz */
-
-struct gemini_wdt {
-	struct watchdog_device	wdd;
-	struct device		*dev;
-	void __iomem		*base;
-};
-
-static inline
-struct gemini_wdt *to_gemini_wdt(struct watchdog_device *wdd)
-{
-	return container_of(wdd, struct gemini_wdt, wdd);
-}
-
-static int gemini_wdt_start(struct watchdog_device *wdd)
-{
-	struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
-
-	writel(wdd->timeout * WDT_CLOCK, gwdt->base + GEMINI_WDLOAD);
-	writel(WDRESTART_MAGIC, gwdt->base + GEMINI_WDRESTART);
-	/* set clock before enabling */
-	writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST,
-			gwdt->base + GEMINI_WDCR);
-	writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE,
-			gwdt->base + GEMINI_WDCR);
-
-	return 0;
-}
-
-static int gemini_wdt_stop(struct watchdog_device *wdd)
-{
-	struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
-
-	writel(0, gwdt->base + GEMINI_WDCR);
-
-	return 0;
-}
-
-static int gemini_wdt_ping(struct watchdog_device *wdd)
-{
-	struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
-
-	writel(WDRESTART_MAGIC, gwdt->base + GEMINI_WDRESTART);
-
-	return 0;
-}
-
-static int gemini_wdt_set_timeout(struct watchdog_device *wdd,
-				  unsigned int timeout)
-{
-	wdd->timeout = timeout;
-	if (watchdog_active(wdd))
-		gemini_wdt_start(wdd);
-
-	return 0;
-}
-
-static irqreturn_t gemini_wdt_interrupt(int irq, void *data)
-{
-	struct gemini_wdt *gwdt = data;
-
-	watchdog_notify_pretimeout(&gwdt->wdd);
-
-	return IRQ_HANDLED;
-}
-
-static const struct watchdog_ops gemini_wdt_ops = {
-	.start		= gemini_wdt_start,
-	.stop		= gemini_wdt_stop,
-	.ping		= gemini_wdt_ping,
-	.set_timeout	= gemini_wdt_set_timeout,
-	.owner		= THIS_MODULE,
-};
-
-static const struct watchdog_info gemini_wdt_info = {
-	.options	= WDIOF_KEEPALIVEPING
-			| WDIOF_MAGICCLOSE
-			| WDIOF_SETTIMEOUT,
-	.identity	= KBUILD_MODNAME,
-};
-
-
-static int gemini_wdt_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct resource *res;
-	struct gemini_wdt *gwdt;
-	unsigned int reg;
-	int irq;
-	int ret;
-
-	gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
-	if (!gwdt)
-		return -ENOMEM;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	gwdt->base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(gwdt->base))
-		return PTR_ERR(gwdt->base);
-
-	irq = platform_get_irq(pdev, 0);
-	if (!irq)
-		return -EINVAL;
-
-	gwdt->dev = dev;
-	gwdt->wdd.info = &gemini_wdt_info;
-	gwdt->wdd.ops = &gemini_wdt_ops;
-	gwdt->wdd.min_timeout = 1;
-	gwdt->wdd.max_timeout = 0xFFFFFFFF / WDT_CLOCK;
-	gwdt->wdd.parent = dev;
-
-	/*
-	 * If 'timeout-sec' unspecified in devicetree, assume a 13 second
-	 * default.
-	 */
-	gwdt->wdd.timeout = 13U;
-	watchdog_init_timeout(&gwdt->wdd, 0, dev);
-
-	reg = readw(gwdt->base + GEMINI_WDCR);
-	if (reg & WDCR_ENABLE) {
-		/* Watchdog was enabled by the bootloader, disable it. */
-		reg &= ~WDCR_ENABLE;
-		writel(reg, gwdt->base + GEMINI_WDCR);
-	}
-
-	ret = devm_request_irq(dev, irq, gemini_wdt_interrupt, 0,
-			       "watchdog bark", gwdt);
-	if (ret)
-		return ret;
-
-	ret = devm_watchdog_register_device(dev, &gwdt->wdd);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to register watchdog\n");
-		return ret;
-	}
-
-	/* Set up platform driver data */
-	platform_set_drvdata(pdev, gwdt);
-	dev_info(dev, "Gemini watchdog driver enabled\n");
-
-	return 0;
-}
-
-static int __maybe_unused gemini_wdt_suspend(struct device *dev)
-{
-	struct gemini_wdt *gwdt = dev_get_drvdata(dev);
-	unsigned int reg;
-
-	reg = readw(gwdt->base + GEMINI_WDCR);
-	reg &= ~WDCR_ENABLE;
-	writel(reg, gwdt->base + GEMINI_WDCR);
-
-	return 0;
-}
-
-static int __maybe_unused gemini_wdt_resume(struct device *dev)
-{
-	struct gemini_wdt *gwdt = dev_get_drvdata(dev);
-	unsigned int reg;
-
-	if (watchdog_active(&gwdt->wdd)) {
-		reg = readw(gwdt->base + GEMINI_WDCR);
-		reg |= WDCR_ENABLE;
-		writel(reg, gwdt->base + GEMINI_WDCR);
-	}
-
-	return 0;
-}
-
-static const struct dev_pm_ops gemini_wdt_dev_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(gemini_wdt_suspend,
-				gemini_wdt_resume)
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id gemini_wdt_match[] = {
-	{ .compatible = "cortina,gemini-watchdog" },
-	{},
-};
-MODULE_DEVICE_TABLE(of, gemini_wdt_match);
-#endif
-
-static struct platform_driver gemini_wdt_driver = {
-	.probe		= gemini_wdt_probe,
-	.driver		= {
-		.name	= "gemini-wdt",
-		.of_match_table = of_match_ptr(gemini_wdt_match),
-		.pm = &gemini_wdt_dev_pm_ops,
-	},
-};
-module_platform_driver(gemini_wdt_driver);
-MODULE_AUTHOR("Linus Walleij");
-MODULE_DESCRIPTION("Watchdog driver for Gemini");
-MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index cb66c2f..3ade281 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -12,7 +12,8 @@
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/module.h>
-#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/watchdog.h>
 
@@ -25,8 +26,7 @@ enum {
 };
 
 struct gpio_wdt_priv {
-	int			gpio;
-	bool			active_low;
+	struct gpio_desc	*gpiod;
 	bool			state;
 	bool			always_running;
 	unsigned int		hw_algo;
@@ -35,11 +35,12 @@ struct gpio_wdt_priv {
 
 static void gpio_wdt_disable(struct gpio_wdt_priv *priv)
 {
-	gpio_set_value_cansleep(priv->gpio, !priv->active_low);
+	/* Eternal ping */
+	gpiod_set_value_cansleep(priv->gpiod, 1);
 
 	/* Put GPIO back to tristate */
 	if (priv->hw_algo == HW_ALGO_TOGGLE)
-		gpio_direction_input(priv->gpio);
+		gpiod_direction_input(priv->gpiod);
 }
 
 static int gpio_wdt_ping(struct watchdog_device *wdd)
@@ -50,13 +51,13 @@ static int gpio_wdt_ping(struct watchdog_device *wdd)
 	case HW_ALGO_TOGGLE:
 		/* Toggle output pin */
 		priv->state = !priv->state;
-		gpio_set_value_cansleep(priv->gpio, priv->state);
+		gpiod_set_value_cansleep(priv->gpiod, priv->state);
 		break;
 	case HW_ALGO_LEVEL:
 		/* Pulse */
-		gpio_set_value_cansleep(priv->gpio, !priv->active_low);
+		gpiod_set_value_cansleep(priv->gpiod, 1);
 		udelay(1);
-		gpio_set_value_cansleep(priv->gpio, priv->active_low);
+		gpiod_set_value_cansleep(priv->gpiod, 0);
 		break;
 	}
 	return 0;
@@ -66,8 +67,8 @@ static int gpio_wdt_start(struct watchdog_device *wdd)
 {
 	struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
 
-	priv->state = priv->active_low;
-	gpio_direction_output(priv->gpio, priv->state);
+	priv->state = 0;
+	gpiod_direction_output(priv->gpiod, priv->state);
 
 	set_bit(WDOG_HW_RUNNING, &wdd->status);
 
@@ -80,7 +81,8 @@ static int gpio_wdt_stop(struct watchdog_device *wdd)
 
 	if (!priv->always_running) {
 		gpio_wdt_disable(priv);
-		clear_bit(WDOG_HW_RUNNING, &wdd->status);
+	} else {
+		set_bit(WDOG_HW_RUNNING, &wdd->status);
 	}
 
 	return 0;
@@ -101,44 +103,38 @@ static const struct watchdog_ops gpio_wdt_ops = {
 
 static int gpio_wdt_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct gpio_wdt_priv *priv;
-	enum of_gpio_flags flags;
+	enum gpiod_flags gflags;
 	unsigned int hw_margin;
-	unsigned long f = 0;
 	const char *algo;
 	int ret;
 
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
 	platform_set_drvdata(pdev, priv);
 
-	priv->gpio = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
-	if (!gpio_is_valid(priv->gpio))
-		return priv->gpio;
-
-	priv->active_low = flags & OF_GPIO_ACTIVE_LOW;
-
-	ret = of_property_read_string(pdev->dev.of_node, "hw_algo", &algo);
+	ret = of_property_read_string(np, "hw_algo", &algo);
 	if (ret)
 		return ret;
 	if (!strcmp(algo, "toggle")) {
 		priv->hw_algo = HW_ALGO_TOGGLE;
-		f = GPIOF_IN;
+		gflags = GPIOD_IN;
 	} else if (!strcmp(algo, "level")) {
 		priv->hw_algo = HW_ALGO_LEVEL;
-		f = priv->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+		gflags = GPIOD_OUT_LOW;
 	} else {
 		return -EINVAL;
 	}
 
-	ret = devm_gpio_request_one(&pdev->dev, priv->gpio, f,
-				    dev_name(&pdev->dev));
-	if (ret)
-		return ret;
+	priv->gpiod = devm_gpiod_get(dev, NULL, gflags);
+	if (IS_ERR(priv->gpiod))
+		return PTR_ERR(priv->gpiod);
 
-	ret = of_property_read_u32(pdev->dev.of_node,
+	ret = of_property_read_u32(np,
 				   "hw_margin_ms", &hw_margin);
 	if (ret)
 		return ret;
@@ -146,7 +142,7 @@ static int gpio_wdt_probe(struct platform_device *pdev)
 	if (hw_margin < 2 || hw_margin > 65535)
 		return -EINVAL;
 
-	priv->always_running = of_property_read_bool(pdev->dev.of_node,
+	priv->always_running = of_property_read_bool(np,
 						     "always-running");
 
 	watchdog_set_drvdata(&priv->wdd, priv);
@@ -155,9 +151,9 @@ static int gpio_wdt_probe(struct platform_device *pdev)
 	priv->wdd.ops		= &gpio_wdt_ops;
 	priv->wdd.min_timeout	= SOFT_TIMEOUT_MIN;
 	priv->wdd.max_hw_heartbeat_ms = hw_margin;
-	priv->wdd.parent	= &pdev->dev;
+	priv->wdd.parent	= dev;
 
-	if (watchdog_init_timeout(&priv->wdd, 0, &pdev->dev) < 0)
+	if (watchdog_init_timeout(&priv->wdd, 0, dev) < 0)
 		priv->wdd.timeout = SOFT_TIMEOUT_DEF;
 
 	watchdog_stop_on_reboot(&priv->wdd);
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 67fbe35..f1f00df 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -52,6 +52,7 @@ static char expect_release;
 static unsigned long hpwdt_is_open;
 
 static void __iomem *pci_mem_addr;		/* the PCI-memory address */
+static unsigned long __iomem *hpwdt_nmistat;
 static unsigned long __iomem *hpwdt_timer_reg;
 static unsigned long __iomem *hpwdt_timer_con;
 
@@ -475,6 +476,11 @@ static int hpwdt_time_left(void)
 }
 
 #ifdef CONFIG_HPWDT_NMI_DECODING
+static int hpwdt_my_nmi(void)
+{
+	return ioread8(hpwdt_nmistat) & 0x6;
+}
+
 /*
  *	NMI Handler
  */
@@ -486,6 +492,9 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
 	if (!hpwdt_nmi_decoding)
 		return NMI_DONE;
 
+	if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi())
+		return NMI_DONE;
+
 	spin_lock_irqsave(&rom_lock, rom_pl);
 	if (!die_nmi_called && !is_icru && !is_uefi)
 		asminline_call(&cmn_regs, cru_rom_addr);
@@ -700,7 +709,7 @@ static void dmi_find_icru(const struct dmi_header *dm, void *dummy)
 		smbios_proliant_ptr = (struct smbios_proliant_info *) dm;
 		if (smbios_proliant_ptr->misc_features & 0x01)
 			is_icru = 1;
-		if (smbios_proliant_ptr->misc_features & 0x408)
+		if (smbios_proliant_ptr->misc_features & 0x1400)
 			is_uefi = 1;
 	}
 }
@@ -842,6 +851,7 @@ static int hpwdt_init_one(struct pci_dev *dev,
 		retval = -ENOMEM;
 		goto error_pci_iomap;
 	}
+	hpwdt_nmistat	= pci_mem_addr + 0x6e;
 	hpwdt_timer_reg = pci_mem_addr + 0x70;
 	hpwdt_timer_con = pci_mem_addr + 0x72;
 
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index d7befd5..950c71a 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -21,14 +21,15 @@
  *	Version 0.02
  *  20050210 David Härdeman <david@2gen.com>
  *	Ported driver to kernel 2.6
+ *  20171016 Radu Rendec <rrendec@arista.com>
+ *	Change driver to use the watchdog subsystem
+ *	Add support for multiple 6300ESB devices
  */
 
 /*
  *      Includes, defines, variables, module parameters, ...
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -42,19 +43,17 @@
 #include <linux/io.h>
 
 /* Module and version information */
-#define ESB_VERSION "0.05"
 #define ESB_MODULE_NAME "i6300ESB timer"
-#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
 
 /* PCI configuration registers */
 #define ESB_CONFIG_REG  0x60            /* Config register                   */
 #define ESB_LOCK_REG    0x68            /* WDT lock register                 */
 
 /* Memory mapped registers */
-#define ESB_TIMER1_REG (BASEADDR + 0x00)/* Timer1 value after each reset     */
-#define ESB_TIMER2_REG (BASEADDR + 0x04)/* Timer2 value after each reset     */
-#define ESB_GINTSR_REG (BASEADDR + 0x08)/* General Interrupt Status Register */
-#define ESB_RELOAD_REG (BASEADDR + 0x0c)/* Reload register                   */
+#define ESB_TIMER1_REG(w) ((w)->base + 0x00)/* Timer1 value after each reset */
+#define ESB_TIMER2_REG(w) ((w)->base + 0x04)/* Timer2 value after each reset */
+#define ESB_GINTSR_REG(w) ((w)->base + 0x08)/* General Interrupt Status Reg  */
+#define ESB_RELOAD_REG(w) ((w)->base + 0x0c)/* Reload register               */
 
 /* Lock register bits */
 #define ESB_WDT_FUNC    (0x01 << 2)   /* Watchdog functionality            */
@@ -74,25 +73,18 @@
 #define ESB_UNLOCK1     0x80            /* Step 1 to unlock reset registers  */
 #define ESB_UNLOCK2     0x86            /* Step 2 to unlock reset registers  */
 
-/* internal variables */
-static void __iomem *BASEADDR;
-static DEFINE_SPINLOCK(esb_lock); /* Guards the hardware */
-static unsigned long timer_alive;
-static struct pci_dev *esb_pci;
-static unsigned short triggered; /* The status of the watchdog upon boot */
-static char esb_expect_close;
-
-/* We can only use 1 card due to the /dev/watchdog restriction */
-static int cards_found;
-
 /* module parameters */
 /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
-#define WATCHDOG_HEARTBEAT 30
-static int heartbeat = WATCHDOG_HEARTBEAT;  /* in seconds */
+#define ESB_HEARTBEAT_MIN	1
+#define ESB_HEARTBEAT_MAX	2046
+#define ESB_HEARTBEAT_DEFAULT	30
+#define ESB_HEARTBEAT_RANGE __MODULE_STRING(ESB_HEARTBEAT_MIN) \
+	"<heartbeat<" __MODULE_STRING(ESB_HEARTBEAT_MAX)
+static int heartbeat; /* in seconds */
 module_param(heartbeat, int, 0);
 MODULE_PARM_DESC(heartbeat,
-		"Watchdog heartbeat in seconds. (1<heartbeat<2046, default="
-				__MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+	"Watchdog heartbeat in seconds. (" ESB_HEARTBEAT_RANGE
+	", default=" __MODULE_STRING(ESB_HEARTBEAT_DEFAULT) ")");
 
 static bool nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, bool, 0);
@@ -100,6 +92,15 @@ MODULE_PARM_DESC(nowayout,
 		"Watchdog cannot be stopped once started (default="
 				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
+/* internal variables */
+struct esb_dev {
+	struct watchdog_device wdd;
+	void __iomem *base;
+	struct pci_dev *pdev;
+};
+
+#define to_esb_dev(wptr) container_of(wptr, struct esb_dev, wdd)
+
 /*
  * Some i6300ESB specific functions
  */
@@ -110,61 +111,58 @@ MODULE_PARM_DESC(nowayout,
  * reload register. After this the appropriate registers can be written
  * to once before they need to be unlocked again.
  */
-static inline void esb_unlock_registers(void)
+static inline void esb_unlock_registers(struct esb_dev *edev)
 {
-	writew(ESB_UNLOCK1, ESB_RELOAD_REG);
-	writew(ESB_UNLOCK2, ESB_RELOAD_REG);
+	writew(ESB_UNLOCK1, ESB_RELOAD_REG(edev));
+	writew(ESB_UNLOCK2, ESB_RELOAD_REG(edev));
 }
 
-static int esb_timer_start(void)
+static int esb_timer_start(struct watchdog_device *wdd)
 {
+	struct esb_dev *edev = to_esb_dev(wdd);
+	int _wdd_nowayout = test_bit(WDOG_NO_WAY_OUT, &wdd->status);
 	u8 val;
 
-	spin_lock(&esb_lock);
-	esb_unlock_registers();
-	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+	esb_unlock_registers(edev);
+	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG(edev));
 	/* Enable or Enable + Lock? */
-	val = ESB_WDT_ENABLE | (nowayout ? ESB_WDT_LOCK : 0x00);
-	pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
-	spin_unlock(&esb_lock);
+	val = ESB_WDT_ENABLE | (_wdd_nowayout ? ESB_WDT_LOCK : 0x00);
+	pci_write_config_byte(edev->pdev, ESB_LOCK_REG, val);
 	return 0;
 }
 
-static int esb_timer_stop(void)
+static int esb_timer_stop(struct watchdog_device *wdd)
 {
+	struct esb_dev *edev = to_esb_dev(wdd);
 	u8 val;
 
-	spin_lock(&esb_lock);
 	/* First, reset timers as suggested by the docs */
-	esb_unlock_registers();
-	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+	esb_unlock_registers(edev);
+	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG(edev));
 	/* Then disable the WDT */
-	pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x0);
-	pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val);
-	spin_unlock(&esb_lock);
+	pci_write_config_byte(edev->pdev, ESB_LOCK_REG, 0x0);
+	pci_read_config_byte(edev->pdev, ESB_LOCK_REG, &val);
 
 	/* Returns 0 if the timer was disabled, non-zero otherwise */
 	return val & ESB_WDT_ENABLE;
 }
 
-static void esb_timer_keepalive(void)
+static int esb_timer_keepalive(struct watchdog_device *wdd)
 {
-	spin_lock(&esb_lock);
-	esb_unlock_registers();
-	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+	struct esb_dev *edev = to_esb_dev(wdd);
+
+	esb_unlock_registers(edev);
+	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG(edev));
 	/* FIXME: Do we need to flush anything here? */
-	spin_unlock(&esb_lock);
+	return 0;
 }
 
-static int esb_timer_set_heartbeat(int time)
+static int esb_timer_set_heartbeat(struct watchdog_device *wdd,
+		unsigned int time)
 {
+	struct esb_dev *edev = to_esb_dev(wdd);
 	u32 val;
 
-	if (time < 0x1 || time > (2 * 0x03ff))
-		return -EINVAL;
-
-	spin_lock(&esb_lock);
-
 	/* We shift by 9, so if we are passed a value of 1 sec,
 	 * val will be 1 << 9 = 512, then write that to two
 	 * timers => 2 * 512 = 1024 (which is decremented at 1KHz)
@@ -172,162 +170,39 @@ static int esb_timer_set_heartbeat(int time)
 	val = time << 9;
 
 	/* Write timer 1 */
-	esb_unlock_registers();
-	writel(val, ESB_TIMER1_REG);
+	esb_unlock_registers(edev);
+	writel(val, ESB_TIMER1_REG(edev));
 
 	/* Write timer 2 */
-	esb_unlock_registers();
-	writel(val, ESB_TIMER2_REG);
+	esb_unlock_registers(edev);
+	writel(val, ESB_TIMER2_REG(edev));
 
 	/* Reload */
-	esb_unlock_registers();
-	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+	esb_unlock_registers(edev);
+	writew(ESB_WDT_RELOAD, ESB_RELOAD_REG(edev));
 
 	/* FIXME: Do we need to flush everything out? */
 
 	/* Done */
-	heartbeat = time;
-	spin_unlock(&esb_lock);
+	wdd->timeout = time;
 	return 0;
 }
 
 /*
- *	/dev/watchdog handling
+ * Watchdog Subsystem Interfaces
  */
 
-static int esb_open(struct inode *inode, struct file *file)
-{
-	/* /dev/watchdog can only be opened once */
-	if (test_and_set_bit(0, &timer_alive))
-		return -EBUSY;
-
-	/* Reload and activate timer */
-	esb_timer_start();
-
-	return nonseekable_open(inode, file);
-}
-
-static int esb_release(struct inode *inode, struct file *file)
-{
-	/* Shut off the timer. */
-	if (esb_expect_close == 42)
-		esb_timer_stop();
-	else {
-		pr_crit("Unexpected close, not stopping watchdog!\n");
-		esb_timer_keepalive();
-	}
-	clear_bit(0, &timer_alive);
-	esb_expect_close = 0;
-	return 0;
-}
-
-static ssize_t esb_write(struct file *file, const char __user *data,
-			  size_t len, loff_t *ppos)
-{
-	/* See if we got the magic character 'V' and reload the timer */
-	if (len) {
-		if (!nowayout) {
-			size_t i;
-
-			/* note: just in case someone wrote the magic character
-			 * five months ago... */
-			esb_expect_close = 0;
-
-			/* scan to see whether or not we got the
-			 * magic character */
-			for (i = 0; i != len; i++) {
-				char c;
-				if (get_user(c, data + i))
-					return -EFAULT;
-				if (c == 'V')
-					esb_expect_close = 42;
-			}
-		}
-
-		/* someone wrote to us, we should reload the timer */
-		esb_timer_keepalive();
-	}
-	return len;
-}
-
-static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	int new_options, retval = -EINVAL;
-	int new_heartbeat;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-	static const struct watchdog_info ident = {
-		.options =		WDIOF_SETTIMEOUT |
-					WDIOF_KEEPALIVEPING |
-					WDIOF_MAGICCLOSE,
-		.firmware_version =	0,
-		.identity =		ESB_MODULE_NAME,
-	};
-
-	switch (cmd) {
-	case WDIOC_GETSUPPORT:
-		return copy_to_user(argp, &ident,
-					sizeof(ident)) ? -EFAULT : 0;
-
-	case WDIOC_GETSTATUS:
-		return put_user(0, p);
-
-	case WDIOC_GETBOOTSTATUS:
-		return put_user(triggered, p);
-
-	case WDIOC_SETOPTIONS:
-	{
-		if (get_user(new_options, p))
-			return -EFAULT;
-
-		if (new_options & WDIOS_DISABLECARD) {
-			esb_timer_stop();
-			retval = 0;
-		}
-
-		if (new_options & WDIOS_ENABLECARD) {
-			esb_timer_start();
-			retval = 0;
-		}
-		return retval;
-	}
-	case WDIOC_KEEPALIVE:
-		esb_timer_keepalive();
-		return 0;
-
-	case WDIOC_SETTIMEOUT:
-	{
-		if (get_user(new_heartbeat, p))
-			return -EFAULT;
-		if (esb_timer_set_heartbeat(new_heartbeat))
-			return -EINVAL;
-		esb_timer_keepalive();
-		/* Fall */
-	}
-	case WDIOC_GETTIMEOUT:
-		return put_user(heartbeat, p);
-	default:
-		return -ENOTTY;
-	}
-}
-
-/*
- *      Kernel Interfaces
- */
-
-static const struct file_operations esb_fops = {
-	.owner = THIS_MODULE,
-	.llseek = no_llseek,
-	.write = esb_write,
-	.unlocked_ioctl = esb_ioctl,
-	.open = esb_open,
-	.release = esb_release,
+static struct watchdog_info esb_info = {
+	.identity = ESB_MODULE_NAME,
+	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
 };
 
-static struct miscdevice esb_miscdev = {
-	.minor = WATCHDOG_MINOR,
-	.name = "watchdog",
-	.fops = &esb_fops,
+static const struct watchdog_ops esb_ops = {
+	.owner = THIS_MODULE,
+	.start = esb_timer_start,
+	.stop = esb_timer_stop,
+	.set_timeout = esb_timer_set_heartbeat,
+	.ping = esb_timer_keepalive,
 };
 
 /*
@@ -343,38 +218,38 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
  *      Init & exit routines
  */
 
-static unsigned char esb_getdevice(struct pci_dev *pdev)
+static unsigned char esb_getdevice(struct esb_dev *edev)
 {
-	if (pci_enable_device(pdev)) {
-		pr_err("failed to enable device\n");
+	if (pci_enable_device(edev->pdev)) {
+		dev_err(&edev->pdev->dev, "failed to enable device\n");
 		goto err_devput;
 	}
 
-	if (pci_request_region(pdev, 0, ESB_MODULE_NAME)) {
-		pr_err("failed to request region\n");
+	if (pci_request_region(edev->pdev, 0, ESB_MODULE_NAME)) {
+		dev_err(&edev->pdev->dev, "failed to request region\n");
 		goto err_disable;
 	}
 
-	BASEADDR = pci_ioremap_bar(pdev, 0);
-	if (BASEADDR == NULL) {
+	edev->base = pci_ioremap_bar(edev->pdev, 0);
+	if (edev->base == NULL) {
 		/* Something's wrong here, BASEADDR has to be set */
-		pr_err("failed to get BASEADDR\n");
+		dev_err(&edev->pdev->dev, "failed to get BASEADDR\n");
 		goto err_release;
 	}
 
 	/* Done */
-	esb_pci = pdev;
+	dev_set_drvdata(&edev->pdev->dev, edev);
 	return 1;
 
 err_release:
-	pci_release_region(pdev, 0);
+	pci_release_region(edev->pdev, 0);
 err_disable:
-	pci_disable_device(pdev);
+	pci_disable_device(edev->pdev);
 err_devput:
 	return 0;
 }
 
-static void esb_initdevice(void)
+static void esb_initdevice(struct esb_dev *edev)
 {
 	u8 val1;
 	u16 val2;
@@ -391,96 +266,87 @@ static void esb_initdevice(void)
 	 * any interrupts as there is not much we can do with it
 	 * right now.
 	 */
-	pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
+	pci_write_config_word(edev->pdev, ESB_CONFIG_REG, 0x0003);
 
 	/* Check that the WDT isn't already locked */
-	pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
+	pci_read_config_byte(edev->pdev, ESB_LOCK_REG, &val1);
 	if (val1 & ESB_WDT_LOCK)
-		pr_warn("nowayout already set\n");
+		dev_warn(&edev->pdev->dev, "nowayout already set\n");
 
 	/* Set the timer to watchdog mode and disable it for now */
-	pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
+	pci_write_config_byte(edev->pdev, ESB_LOCK_REG, 0x00);
 
 	/* Check if the watchdog was previously triggered */
-	esb_unlock_registers();
-	val2 = readw(ESB_RELOAD_REG);
+	esb_unlock_registers(edev);
+	val2 = readw(ESB_RELOAD_REG(edev));
 	if (val2 & ESB_WDT_TIMEOUT)
-		triggered = WDIOF_CARDRESET;
+		edev->wdd.bootstatus = WDIOF_CARDRESET;
 
 	/* Reset WDT_TIMEOUT flag and timers */
-	esb_unlock_registers();
-	writew((ESB_WDT_TIMEOUT | ESB_WDT_RELOAD), ESB_RELOAD_REG);
+	esb_unlock_registers(edev);
+	writew((ESB_WDT_TIMEOUT | ESB_WDT_RELOAD), ESB_RELOAD_REG(edev));
 
 	/* And set the correct timeout value */
-	esb_timer_set_heartbeat(heartbeat);
+	esb_timer_set_heartbeat(&edev->wdd, edev->wdd.timeout);
 }
 
 static int esb_probe(struct pci_dev *pdev,
 		const struct pci_device_id *ent)
 {
+	struct esb_dev *edev;
 	int ret;
 
-	cards_found++;
-	if (cards_found == 1)
-		pr_info("Intel 6300ESB WatchDog Timer Driver v%s\n",
-			ESB_VERSION);
-
-	if (cards_found > 1) {
-		pr_err("This driver only supports 1 device\n");
-		return -ENODEV;
-	}
+	edev = devm_kzalloc(&pdev->dev, sizeof(*edev), GFP_KERNEL);
+	if (!edev)
+		return -ENOMEM;
 
 	/* Check whether or not the hardware watchdog is there */
-	if (!esb_getdevice(pdev) || esb_pci == NULL)
+	edev->pdev = pdev;
+	if (!esb_getdevice(edev))
 		return -ENODEV;
 
-	/* Check that the heartbeat value is within it's range;
-	   if not reset to the default */
-	if (heartbeat < 0x1 || heartbeat > 2 * 0x03ff) {
-		heartbeat = WATCHDOG_HEARTBEAT;
-		pr_info("heartbeat value must be 1<heartbeat<2046, using %d\n",
-			heartbeat);
-	}
-
 	/* Initialize the watchdog and make sure it does not run */
-	esb_initdevice();
+	edev->wdd.info = &esb_info;
+	edev->wdd.ops = &esb_ops;
+	edev->wdd.min_timeout = ESB_HEARTBEAT_MIN;
+	edev->wdd.max_timeout = ESB_HEARTBEAT_MAX;
+	edev->wdd.timeout = ESB_HEARTBEAT_DEFAULT;
+	if (watchdog_init_timeout(&edev->wdd, heartbeat, NULL))
+		dev_info(&pdev->dev,
+			"heartbeat value must be " ESB_HEARTBEAT_RANGE
+			", using %u\n", edev->wdd.timeout);
+	watchdog_set_nowayout(&edev->wdd, nowayout);
+	watchdog_stop_on_reboot(&edev->wdd);
+	watchdog_stop_on_unregister(&edev->wdd);
+	esb_initdevice(edev);
 
 	/* Register the watchdog so that userspace has access to it */
-	ret = misc_register(&esb_miscdev);
+	ret = watchdog_register_device(&edev->wdd);
 	if (ret != 0) {
-		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
-		       WATCHDOG_MINOR, ret);
+		dev_err(&pdev->dev,
+			"cannot register watchdog device (err=%d)\n", ret);
 		goto err_unmap;
 	}
-	pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
-		BASEADDR, heartbeat, nowayout);
+	dev_info(&pdev->dev,
+		"initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
+		edev->base, edev->wdd.timeout, nowayout);
 	return 0;
 
 err_unmap:
-	iounmap(BASEADDR);
-	pci_release_region(esb_pci, 0);
-	pci_disable_device(esb_pci);
-	esb_pci = NULL;
+	iounmap(edev->base);
+	pci_release_region(edev->pdev, 0);
+	pci_disable_device(edev->pdev);
 	return ret;
 }
 
 static void esb_remove(struct pci_dev *pdev)
 {
-	/* Stop the timer before we leave */
-	if (!nowayout)
-		esb_timer_stop();
+	struct esb_dev *edev = dev_get_drvdata(&pdev->dev);
 
-	/* Deregister */
-	misc_deregister(&esb_miscdev);
-	iounmap(BASEADDR);
-	pci_release_region(esb_pci, 0);
-	pci_disable_device(esb_pci);
-	esb_pci = NULL;
-}
-
-static void esb_shutdown(struct pci_dev *pdev)
-{
-	esb_timer_stop();
+	watchdog_unregister_device(&edev->wdd);
+	iounmap(edev->base);
+	pci_release_region(edev->pdev, 0);
+	pci_disable_device(edev->pdev);
 }
 
 static struct pci_driver esb_driver = {
@@ -488,7 +354,6 @@ static struct pci_driver esb_driver = {
 	.id_table	= esb_pci_tbl,
 	.probe          = esb_probe,
 	.remove         = esb_remove,
-	.shutdown       = esb_shutdown,
 };
 
 module_pci_driver(esb_driver);
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
index f2e4e1e..cc26228 100644
--- a/drivers/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
@@ -218,7 +218,7 @@ static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		if (ibwdt_set_heartbeat(new_margin))
 			return -EINVAL;
 		ibwdt_ping();
-		/* Fall */
+		/* fall through */
 
 	case WDIOC_GETTIMEOUT:
 		return put_user(timeout, p);
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 4874b0f..518dfa1 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -169,15 +169,21 @@ static int imx2_wdt_ping(struct watchdog_device *wdog)
 	return 0;
 }
 
-static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
-				unsigned int new_timeout)
+static void __imx2_wdt_set_timeout(struct watchdog_device *wdog,
+				   unsigned int new_timeout)
 {
 	struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
 
-	wdog->timeout = new_timeout;
-
 	regmap_update_bits(wdev->regmap, IMX2_WDT_WCR, IMX2_WDT_WCR_WT,
 			   WDOG_SEC_TO_COUNT(new_timeout));
+}
+
+static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
+				unsigned int new_timeout)
+{
+	__imx2_wdt_set_timeout(wdog, new_timeout);
+
+	wdog->timeout = new_timeout;
 	return 0;
 }
 
@@ -371,7 +377,11 @@ static int imx2_wdt_suspend(struct device *dev)
 
 	/* The watchdog IP block is running */
 	if (imx2_wdt_is_running(wdev)) {
-		imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME);
+		/*
+		 * Don't update wdog->timeout, we'll restore the current value
+		 * during resume.
+		 */
+		__imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME);
 		imx2_wdt_ping(wdog);
 	}
 
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index 20627f2..aafbeb9 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -146,6 +146,7 @@ static const struct watchdog_ops jz4740_wdt_ops = {
 #ifdef CONFIG_OF
 static const struct of_device_id jz4740_wdt_of_matches[] = {
 	{ .compatible = "ingenic,jz4740-watchdog", },
+	{ .compatible = "ingenic,jz4780-watchdog", },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, jz4740_wdt_of_matches);
diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c
index ea60b29..b8194b0 100644
--- a/drivers/watchdog/mei_wdt.c
+++ b/drivers/watchdog/mei_wdt.c
@@ -526,12 +526,11 @@ static ssize_t mei_dbgfs_read_state(struct file *file, char __user *ubuf,
 				    size_t cnt, loff_t *ppos)
 {
 	struct mei_wdt *wdt = file->private_data;
-	const size_t bufsz = 32;
-	char buf[bufsz];
+	char buf[32];
 	ssize_t pos;
 
-	pos = scnprintf(buf, bufsz, "state: %s\n",
-			 mei_wdt_state_str(wdt->state));
+	pos = scnprintf(buf, sizeof(buf), "state: %s\n",
+			mei_wdt_state_str(wdt->state));
 
 	return simple_read_from_buffer(ubuf, cnt, ppos, buf, pos);
 }
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 6610e92..aca2d63 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -22,7 +22,6 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/timer.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/module.h>
@@ -31,10 +30,13 @@
 #include <linux/uaccess.h>
 #include <sysdev/fsl_soc.h>
 
+#define WATCHDOG_TIMEOUT 10
+
 struct mpc8xxx_wdt {
 	__be32 res0;
 	__be32 swcrr; /* System watchdog control register */
 #define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */
+#define SWCRR_SWF  0x00000008 /* Software Watchdog Freeze (mpc8xx). */
 #define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */
 #define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/
 #define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */
@@ -52,14 +54,15 @@ struct mpc8xxx_wdt_type {
 struct mpc8xxx_wdt_ddata {
 	struct mpc8xxx_wdt __iomem *base;
 	struct watchdog_device wdd;
-	struct timer_list timer;
 	spinlock_t lock;
+	u16 swtc;
 };
 
-static u16 timeout = 0xffff;
+static u16 timeout;
 module_param(timeout, ushort, 0);
 MODULE_PARM_DESC(timeout,
-	"Watchdog timeout in ticks. (0<timeout<65536, default=65535)");
+	"Watchdog timeout in seconds. (1<timeout<65535, default="
+	__MODULE_STRING(WATCHDOG_TIMEOUT) ")");
 
 static bool reset = 1;
 module_param(reset, bool, 0);
@@ -80,31 +83,27 @@ static void mpc8xxx_wdt_keepalive(struct mpc8xxx_wdt_ddata *ddata)
 	spin_unlock(&ddata->lock);
 }
 
-static void mpc8xxx_wdt_timer_ping(struct timer_list *t)
-{
-	struct mpc8xxx_wdt_ddata *ddata = from_timer(ddata, t, timer);
-
-	mpc8xxx_wdt_keepalive(ddata);
-	/* We're pinging it twice faster than needed, just to be sure. */
-	mod_timer(&ddata->timer, jiffies + HZ * ddata->wdd.timeout / 2);
-}
-
 static int mpc8xxx_wdt_start(struct watchdog_device *w)
 {
 	struct mpc8xxx_wdt_ddata *ddata =
 		container_of(w, struct mpc8xxx_wdt_ddata, wdd);
-
-	u32 tmp = SWCRR_SWEN | SWCRR_SWPR;
+	u32 tmp = in_be32(&ddata->base->swcrr);
 
 	/* Good, fire up the show */
+	tmp &= ~(SWCRR_SWTC | SWCRR_SWF | SWCRR_SWEN | SWCRR_SWRI | SWCRR_SWPR);
+	tmp |= SWCRR_SWEN | SWCRR_SWPR | (ddata->swtc << 16);
+
 	if (reset)
 		tmp |= SWCRR_SWRI;
 
-	tmp |= timeout << 16;
-
 	out_be32(&ddata->base->swcrr, tmp);
 
-	del_timer_sync(&ddata->timer);
+	tmp = in_be32(&ddata->base->swcrr);
+	if (!(tmp & SWCRR_SWEN))
+		return -EOPNOTSUPP;
+
+	ddata->swtc = tmp >> 16;
+	set_bit(WDOG_HW_RUNNING, &ddata->wdd.status);
 
 	return 0;
 }
@@ -118,17 +117,8 @@ static int mpc8xxx_wdt_ping(struct watchdog_device *w)
 	return 0;
 }
 
-static int mpc8xxx_wdt_stop(struct watchdog_device *w)
-{
-	struct mpc8xxx_wdt_ddata *ddata =
-		container_of(w, struct mpc8xxx_wdt_ddata, wdd);
-
-	mod_timer(&ddata->timer, jiffies);
-	return 0;
-}
-
 static struct watchdog_info mpc8xxx_wdt_info = {
-	.options = WDIOF_KEEPALIVEPING,
+	.options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT,
 	.firmware_version = 1,
 	.identity = "MPC8xxx",
 };
@@ -137,7 +127,6 @@ static struct watchdog_ops mpc8xxx_wdt_ops = {
 	.owner = THIS_MODULE,
 	.start = mpc8xxx_wdt_start,
 	.ping = mpc8xxx_wdt_ping,
-	.stop = mpc8xxx_wdt_stop,
 };
 
 static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
@@ -148,7 +137,6 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
 	struct mpc8xxx_wdt_ddata *ddata;
 	u32 freq = fsl_get_sys_freq();
 	bool enabled;
-	unsigned int timeout_sec;
 
 	wdt_type = of_device_get_match_data(&ofdev->dev);
 	if (!wdt_type)
@@ -173,26 +161,17 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
 	}
 
 	spin_lock_init(&ddata->lock);
-	timer_setup(&ddata->timer, mpc8xxx_wdt_timer_ping, 0);
 
 	ddata->wdd.info = &mpc8xxx_wdt_info,
 	ddata->wdd.ops = &mpc8xxx_wdt_ops,
 
-	/* Calculate the timeout in seconds */
-	timeout_sec = (timeout * wdt_type->prescaler) / freq;
-
-	ddata->wdd.timeout = timeout_sec;
+	ddata->wdd.timeout = WATCHDOG_TIMEOUT;
+	watchdog_init_timeout(&ddata->wdd, timeout, &ofdev->dev);
 
 	watchdog_set_nowayout(&ddata->wdd, nowayout);
 
-	ret = watchdog_register_device(&ddata->wdd);
-	if (ret) {
-		pr_err("cannot register watchdog device (err=%d)\n", ret);
-		return ret;
-	}
-
-	pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d (%d seconds)\n",
-		reset ? "reset" : "interrupt", timeout, timeout_sec);
+	ddata->swtc = min(ddata->wdd.timeout * freq / wdt_type->prescaler,
+			  0xffffU);
 
 	/*
 	 * If the watchdog was previously enabled or we're running on
@@ -200,7 +179,22 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
 	 * userspace handles it.
 	 */
 	if (enabled)
-		mod_timer(&ddata->timer, jiffies);
+		mpc8xxx_wdt_start(&ddata->wdd);
+
+	ddata->wdd.max_hw_heartbeat_ms = (ddata->swtc * wdt_type->prescaler) /
+					 (freq / 1000);
+	ddata->wdd.min_timeout = ddata->wdd.max_hw_heartbeat_ms / 1000;
+	if (ddata->wdd.timeout < ddata->wdd.min_timeout)
+		ddata->wdd.timeout = ddata->wdd.min_timeout;
+
+	ret = watchdog_register_device(&ddata->wdd);
+	if (ret) {
+		pr_err("cannot register watchdog device (err=%d)\n", ret);
+		return ret;
+	}
+
+	pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d sec\n",
+		reset ? "reset" : "interrupt", ddata->wdd.timeout);
 
 	platform_set_drvdata(ofdev, ddata);
 	return 0;
@@ -212,7 +206,6 @@ static int mpc8xxx_wdt_remove(struct platform_device *ofdev)
 
 	pr_crit("Watchdog removed, expect the %s soon!\n",
 		reset ? "reset" : "machine check exception");
-	del_timer_sync(&ddata->timer);
 	watchdog_unregister_device(&ddata->wdd);
 
 	return 0;
diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c
index db38f80..5c4a764 100644
--- a/drivers/watchdog/mt7621_wdt.c
+++ b/drivers/watchdog/mt7621_wdt.c
@@ -105,6 +105,11 @@ static int mt7621_wdt_bootcause(void)
 	return 0;
 }
 
+static int mt7621_wdt_is_running(struct watchdog_device *w)
+{
+	return !!(rt_wdt_r32(TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE);
+}
+
 static const struct watchdog_info mt7621_wdt_info = {
 	.identity = "Mediatek Watchdog",
 	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
@@ -128,7 +133,6 @@ static struct watchdog_device mt7621_wdt_dev = {
 static int mt7621_wdt_probe(struct platform_device *pdev)
 {
 	struct resource *res;
-	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mt7621_wdt_base = devm_ioremap_resource(&pdev->dev, res);
@@ -144,17 +148,22 @@ static int mt7621_wdt_probe(struct platform_device *pdev)
 	watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout,
 			      &pdev->dev);
 	watchdog_set_nowayout(&mt7621_wdt_dev, nowayout);
+	if (mt7621_wdt_is_running(&mt7621_wdt_dev)) {
+		/*
+		 * Make sure to apply timeout from watchdog core, taking
+		 * the prescaler of this driver here into account (the
+		 * boot loader might be using a different prescaler).
+		 *
+		 * To avoid spurious resets because of different scaling,
+		 * we first disable the watchdog, set the new prescaler
+		 * and timeout, and then re-enable the watchdog.
+		 */
+		mt7621_wdt_stop(&mt7621_wdt_dev);
+		mt7621_wdt_start(&mt7621_wdt_dev);
+		set_bit(WDOG_HW_RUNNING, &mt7621_wdt_dev.status);
+	}
 
-	ret = watchdog_register_device(&mt7621_wdt_dev);
-
-	return 0;
-}
-
-static int mt7621_wdt_remove(struct platform_device *pdev)
-{
-	watchdog_unregister_device(&mt7621_wdt_dev);
-
-	return 0;
+	return devm_watchdog_register_device(&pdev->dev, &mt7621_wdt_dev);
 }
 
 static void mt7621_wdt_shutdown(struct platform_device *pdev)
@@ -170,7 +179,6 @@ MODULE_DEVICE_TABLE(of, mt7621_wdt_match);
 
 static struct platform_driver mt7621_wdt_driver = {
 	.probe		= mt7621_wdt_probe,
-	.remove		= mt7621_wdt_remove,
 	.shutdown	= mt7621_wdt_shutdown,
 	.driver		= {
 		.name		= KBUILD_MODNAME,
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index 83af7d6..ea676d2 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -576,7 +576,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
 	/*
 	 * Let's make sure the watchdog is fully stopped, unless it's
 	 * explicitly enabled. This may be the case if the module was
-	 * removed and re-insterted, or if the bootloader explicitly
+	 * removed and re-inserted, or if the bootloader explicitly
 	 * set a running watchdog before booting the kernel.
 	 */
 	if (!orion_wdt_enabled(&dev->wdt))
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index c0d07ee..1f78f09 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -545,8 +545,8 @@ static long pcipcwd_ioctl(struct file *file, unsigned int cmd,
 			return -EINVAL;
 
 		pcipcwd_keepalive();
-		/* Fall */
 	}
+		/* fall through */
 
 	case WDIOC_GETTIMEOUT:
 		return put_user(heartbeat, p);
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index b9e376c..4d02f26 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -49,12 +49,11 @@
 #define DRIVER_VERSION "1.02"
 #define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>"
 #define DRIVER_DESC "Berkshire USB-PC Watchdog driver"
-#define DRIVER_LICENSE "GPL"
 #define DRIVER_NAME "pcwd_usb"
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
+MODULE_LICENSE("GPL");
 
 #define WATCHDOG_HEARTBEAT 0	/* default heartbeat =
 						delay-time from dip-switches */
@@ -456,8 +455,8 @@ static long usb_pcwd_ioctl(struct file *file, unsigned int cmd,
 			return -EINVAL;
 
 		usb_pcwd_keepalive(usb_pcwd_device);
-		/* Fall */
 	}
+		/* fall through */
 
 	case WDIOC_GETTIMEOUT:
 		return put_user(heartbeat, p);
diff --git a/drivers/watchdog/rtd119x_wdt.c b/drivers/watchdog/rtd119x_wdt.c
new file mode 100644
index 0000000..d001c17
--- /dev/null
+++ b/drivers/watchdog/rtd119x_wdt.c
@@ -0,0 +1,168 @@
+/*
+ * Realtek RTD129x watchdog
+ *
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+
+#define RTD119X_TCWCR		0x0
+#define RTD119X_TCWTR		0x4
+#define RTD119X_TCWOV		0xc
+
+#define RTD119X_TCWCR_WDEN_DISABLED		0xa5
+#define RTD119X_TCWCR_WDEN_ENABLED		0xff
+#define RTD119X_TCWCR_WDEN_MASK			0xff
+
+#define RTD119X_TCWTR_WDCLR			BIT(0)
+
+struct rtd119x_watchdog_device {
+	struct watchdog_device wdt_dev;
+	void __iomem *base;
+	struct clk *clk;
+};
+
+static int rtd119x_wdt_start(struct watchdog_device *wdev)
+{
+	struct rtd119x_watchdog_device *data = watchdog_get_drvdata(wdev);
+	u32 val;
+
+	val = readl_relaxed(data->base + RTD119X_TCWCR);
+	val &= ~RTD119X_TCWCR_WDEN_MASK;
+	val |= RTD119X_TCWCR_WDEN_ENABLED;
+	writel(val, data->base + RTD119X_TCWCR);
+
+	return 0;
+}
+
+static int rtd119x_wdt_stop(struct watchdog_device *wdev)
+{
+	struct rtd119x_watchdog_device *data = watchdog_get_drvdata(wdev);
+	u32 val;
+
+	val = readl_relaxed(data->base + RTD119X_TCWCR);
+	val &= ~RTD119X_TCWCR_WDEN_MASK;
+	val |= RTD119X_TCWCR_WDEN_DISABLED;
+	writel(val, data->base + RTD119X_TCWCR);
+
+	return 0;
+}
+
+static int rtd119x_wdt_ping(struct watchdog_device *wdev)
+{
+	struct rtd119x_watchdog_device *data = watchdog_get_drvdata(wdev);
+
+	writel_relaxed(RTD119X_TCWTR_WDCLR, data->base + RTD119X_TCWTR);
+
+	return rtd119x_wdt_start(wdev);
+}
+
+static int rtd119x_wdt_set_timeout(struct watchdog_device *wdev, unsigned int val)
+{
+	struct rtd119x_watchdog_device *data = watchdog_get_drvdata(wdev);
+
+	writel(val * clk_get_rate(data->clk), data->base + RTD119X_TCWOV);
+
+	data->wdt_dev.timeout = val;
+
+	return 0;
+}
+
+static const struct watchdog_ops rtd119x_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start		= rtd119x_wdt_start,
+	.stop		= rtd119x_wdt_stop,
+	.ping		= rtd119x_wdt_ping,
+	.set_timeout	= rtd119x_wdt_set_timeout,
+};
+
+static const struct watchdog_info rtd119x_wdt_info = {
+	.identity = "rtd119x-wdt",
+	.options = 0,
+};
+
+static const struct of_device_id rtd119x_wdt_dt_ids[] = {
+	 { .compatible = "realtek,rtd1295-watchdog" },
+	 { }
+};
+
+static int rtd119x_wdt_probe(struct platform_device *pdev)
+{
+	struct rtd119x_watchdog_device *data;
+	struct resource *res;
+	int ret;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	data->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(data->base))
+		return PTR_ERR(data->base);
+
+	data->clk = of_clk_get(pdev->dev.of_node, 0);
+	if (IS_ERR(data->clk))
+		return PTR_ERR(data->clk);
+
+	ret = clk_prepare_enable(data->clk);
+	if (ret) {
+		clk_put(data->clk);
+		return ret;
+	}
+
+	data->wdt_dev.info = &rtd119x_wdt_info;
+	data->wdt_dev.ops = &rtd119x_wdt_ops;
+	data->wdt_dev.timeout = 120;
+	data->wdt_dev.max_timeout = 0xffffffff / clk_get_rate(data->clk);
+	data->wdt_dev.min_timeout = 1;
+	data->wdt_dev.parent = &pdev->dev;
+
+	watchdog_stop_on_reboot(&data->wdt_dev);
+	watchdog_set_drvdata(&data->wdt_dev, data);
+	platform_set_drvdata(pdev, data);
+
+	writel_relaxed(RTD119X_TCWTR_WDCLR, data->base + RTD119X_TCWTR);
+	rtd119x_wdt_set_timeout(&data->wdt_dev, data->wdt_dev.timeout);
+	rtd119x_wdt_stop(&data->wdt_dev);
+
+	ret = devm_watchdog_register_device(&pdev->dev, &data->wdt_dev);
+	if (ret) {
+		clk_disable_unprepare(data->clk);
+		clk_put(data->clk);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rtd119x_wdt_remove(struct platform_device *pdev)
+{
+	struct rtd119x_watchdog_device *data = platform_get_drvdata(pdev);
+
+	watchdog_unregister_device(&data->wdt_dev);
+
+	clk_disable_unprepare(data->clk);
+	clk_put(data->clk);
+
+	return 0;
+}
+
+static struct platform_driver rtd119x_wdt_driver = {
+	.probe = rtd119x_wdt_probe,
+	.remove = rtd119x_wdt_remove,
+	.driver = {
+		.name = "rtd1295-watchdog",
+		.of_match_table	= rtd119x_wdt_dt_ids,
+	},
+};
+builtin_platform_driver(rtd119x_wdt_driver);
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index 028618c..41aaae2 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -16,6 +16,11 @@
  *	See AMD Publication 43009 "AMD SB700/710/750 Register Reference Guide",
  *	    AMD Publication 45482 "AMD SB800-Series Southbridges Register
  *	                                                      Reference Guide"
+ *	    AMD Publication 48751 "BIOS and Kernel Developer’s Guide (BKDG)
+ *				for AMD Family 16h Models 00h-0Fh Processors"
+ *	    AMD Publication 51192 "AMD Bolton FCH Register Reference Guide"
+ *	    AMD Publication 52740 "BIOS and Kernel Developer’s Guide (BKDG)
+ *				for AMD Family 16h Models 30h-3Fh Processors"
  */
 
 /*
@@ -24,38 +29,36 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/init.h>
-#include <linux/fs.h>
 #include <linux/pci.h>
-#include <linux/ioport.h>
 #include <linux/platform_device.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
 
 #include "sp5100_tco.h"
 
-/* Module and version information */
-#define TCO_VERSION "0.05"
-#define TCO_MODULE_NAME "SP5100 TCO timer"
-#define TCO_DRIVER_NAME   TCO_MODULE_NAME ", v" TCO_VERSION
+#define TCO_DRIVER_NAME	"sp5100-tco"
 
 /* internal variables */
-static u32 tcobase_phys;
-static u32 tco_wdt_fired;
-static void __iomem *tcobase;
-static unsigned int pm_iobase;
-static DEFINE_SPINLOCK(tco_lock);	/* Guards the hardware */
-static unsigned long timer_alive;
-static char tco_expect_close;
-static struct pci_dev *sp5100_tco_pci;
+
+enum tco_reg_layout {
+	sp5100, sb800, efch
+};
+
+struct sp5100_tco {
+	struct watchdog_device wdd;
+	void __iomem *tcobase;
+	enum tco_reg_layout tco_reg_layout;
+};
 
 /* the watchdog platform device */
 static struct platform_device *sp5100_tco_platform_device;
+/* the associated PCI device */
+static struct pci_dev *sp5100_tco_pci;
 
 /* module parameters */
 
@@ -74,83 +77,105 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started."
  * Some TCO specific functions
  */
 
-static bool tco_has_sp5100_reg_layout(struct pci_dev *dev)
+static enum tco_reg_layout tco_reg_layout(struct pci_dev *dev)
 {
-	return dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
-	       dev->revision < 0x40;
+	if (dev->vendor == PCI_VENDOR_ID_ATI &&
+	    dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
+	    dev->revision < 0x40) {
+		return sp5100;
+	} else if (dev->vendor == PCI_VENDOR_ID_AMD &&
+	    ((dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
+	     dev->revision >= 0x41) ||
+	    (dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS &&
+	     dev->revision >= 0x49))) {
+		return efch;
+	}
+	return sb800;
 }
 
-static void tco_timer_start(void)
+static int tco_timer_start(struct watchdog_device *wdd)
 {
+	struct sp5100_tco *tco = watchdog_get_drvdata(wdd);
 	u32 val;
-	unsigned long flags;
 
-	spin_lock_irqsave(&tco_lock, flags);
-	val = readl(SP5100_WDT_CONTROL(tcobase));
+	val = readl(SP5100_WDT_CONTROL(tco->tcobase));
 	val |= SP5100_WDT_START_STOP_BIT;
-	writel(val, SP5100_WDT_CONTROL(tcobase));
-	spin_unlock_irqrestore(&tco_lock, flags);
-}
+	writel(val, SP5100_WDT_CONTROL(tco->tcobase));
 
-static void tco_timer_stop(void)
-{
-	u32 val;
-	unsigned long flags;
-
-	spin_lock_irqsave(&tco_lock, flags);
-	val = readl(SP5100_WDT_CONTROL(tcobase));
-	val &= ~SP5100_WDT_START_STOP_BIT;
-	writel(val, SP5100_WDT_CONTROL(tcobase));
-	spin_unlock_irqrestore(&tco_lock, flags);
-}
-
-static void tco_timer_keepalive(void)
-{
-	u32 val;
-	unsigned long flags;
-
-	spin_lock_irqsave(&tco_lock, flags);
-	val = readl(SP5100_WDT_CONTROL(tcobase));
-	val |= SP5100_WDT_TRIGGER_BIT;
-	writel(val, SP5100_WDT_CONTROL(tcobase));
-	spin_unlock_irqrestore(&tco_lock, flags);
-}
-
-static int tco_timer_set_heartbeat(int t)
-{
-	unsigned long flags;
-
-	if (t < 0 || t > 0xffff)
-		return -EINVAL;
-
-	/* Write new heartbeat to watchdog */
-	spin_lock_irqsave(&tco_lock, flags);
-	writel(t, SP5100_WDT_COUNT(tcobase));
-	spin_unlock_irqrestore(&tco_lock, flags);
-
-	heartbeat = t;
 	return 0;
 }
 
-static void tco_timer_enable(void)
+static int tco_timer_stop(struct watchdog_device *wdd)
 {
-	int val;
+	struct sp5100_tco *tco = watchdog_get_drvdata(wdd);
+	u32 val;
 
-	if (!tco_has_sp5100_reg_layout(sp5100_tco_pci)) {
+	val = readl(SP5100_WDT_CONTROL(tco->tcobase));
+	val &= ~SP5100_WDT_START_STOP_BIT;
+	writel(val, SP5100_WDT_CONTROL(tco->tcobase));
+
+	return 0;
+}
+
+static int tco_timer_ping(struct watchdog_device *wdd)
+{
+	struct sp5100_tco *tco = watchdog_get_drvdata(wdd);
+	u32 val;
+
+	val = readl(SP5100_WDT_CONTROL(tco->tcobase));
+	val |= SP5100_WDT_TRIGGER_BIT;
+	writel(val, SP5100_WDT_CONTROL(tco->tcobase));
+
+	return 0;
+}
+
+static int tco_timer_set_timeout(struct watchdog_device *wdd,
+				 unsigned int t)
+{
+	struct sp5100_tco *tco = watchdog_get_drvdata(wdd);
+
+	/* Write new heartbeat to watchdog */
+	writel(t, SP5100_WDT_COUNT(tco->tcobase));
+
+	wdd->timeout = t;
+
+	return 0;
+}
+
+static u8 sp5100_tco_read_pm_reg8(u8 index)
+{
+	outb(index, SP5100_IO_PM_INDEX_REG);
+	return inb(SP5100_IO_PM_DATA_REG);
+}
+
+static void sp5100_tco_update_pm_reg8(u8 index, u8 reset, u8 set)
+{
+	u8 val;
+
+	outb(index, SP5100_IO_PM_INDEX_REG);
+	val = inb(SP5100_IO_PM_DATA_REG);
+	val &= reset;
+	val |= set;
+	outb(val, SP5100_IO_PM_DATA_REG);
+}
+
+static void tco_timer_enable(struct sp5100_tco *tco)
+{
+	u32 val;
+
+	switch (tco->tco_reg_layout) {
+	case sb800:
 		/* For SB800 or later */
 		/* Set the Watchdog timer resolution to 1 sec */
-		outb(SB800_PM_WATCHDOG_CONFIG, SB800_IO_PM_INDEX_REG);
-		val = inb(SB800_IO_PM_DATA_REG);
-		val |= SB800_PM_WATCHDOG_SECOND_RES;
-		outb(val, SB800_IO_PM_DATA_REG);
+		sp5100_tco_update_pm_reg8(SB800_PM_WATCHDOG_CONFIG,
+					  0xff, SB800_PM_WATCHDOG_SECOND_RES);
 
 		/* Enable watchdog decode bit and watchdog timer */
-		outb(SB800_PM_WATCHDOG_CONTROL, SB800_IO_PM_INDEX_REG);
-		val = inb(SB800_IO_PM_DATA_REG);
-		val |= SB800_PCI_WATCHDOG_DECODE_EN;
-		val &= ~SB800_PM_WATCHDOG_DISABLE;
-		outb(val, SB800_IO_PM_DATA_REG);
-	} else {
+		sp5100_tco_update_pm_reg8(SB800_PM_WATCHDOG_CONTROL,
+					  ~SB800_PM_WATCHDOG_DISABLE,
+					  SB800_PCI_WATCHDOG_DECODE_EN);
+		break;
+	case sp5100:
 		/* For SP5100 or SB7x0 */
 		/* Enable watchdog decode bit */
 		pci_read_config_dword(sp5100_tco_pci,
@@ -164,142 +189,242 @@ static void tco_timer_enable(void)
 				       val);
 
 		/* Enable Watchdog timer and set the resolution to 1 sec */
-		outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG);
-		val = inb(SP5100_IO_PM_DATA_REG);
-		val |= SP5100_PM_WATCHDOG_SECOND_RES;
-		val &= ~SP5100_PM_WATCHDOG_DISABLE;
-		outb(val, SP5100_IO_PM_DATA_REG);
+		sp5100_tco_update_pm_reg8(SP5100_PM_WATCHDOG_CONTROL,
+					  ~SP5100_PM_WATCHDOG_DISABLE,
+					  SP5100_PM_WATCHDOG_SECOND_RES);
+		break;
+	case efch:
+		/* Set the Watchdog timer resolution to 1 sec and enable */
+		sp5100_tco_update_pm_reg8(EFCH_PM_DECODEEN3,
+					  ~EFCH_PM_WATCHDOG_DISABLE,
+					  EFCH_PM_DECODEEN_SECOND_RES);
+		break;
 	}
 }
 
-/*
- *	/dev/watchdog handling
- */
-
-static int sp5100_tco_open(struct inode *inode, struct file *file)
+static u32 sp5100_tco_read_pm_reg32(u8 index)
 {
-	/* /dev/watchdog can only be opened once */
-	if (test_and_set_bit(0, &timer_alive))
+	u32 val = 0;
+	int i;
+
+	for (i = 3; i >= 0; i--)
+		val = (val << 8) + sp5100_tco_read_pm_reg8(index + i);
+
+	return val;
+}
+
+static int sp5100_tco_setupdevice(struct device *dev,
+				  struct watchdog_device *wdd)
+{
+	struct sp5100_tco *tco = watchdog_get_drvdata(wdd);
+	const char *dev_name;
+	u32 mmio_addr = 0, val;
+	int ret;
+
+	/* Request the IO ports used by this driver */
+	if (!request_muxed_region(SP5100_IO_PM_INDEX_REG,
+				  SP5100_PM_IOPORTS_SIZE, "sp5100_tco")) {
+		dev_err(dev, "I/O address 0x%04x already in use\n",
+			SP5100_IO_PM_INDEX_REG);
 		return -EBUSY;
+	}
 
-	/* Reload and activate timer */
-	tco_timer_start();
-	tco_timer_keepalive();
-	return nonseekable_open(inode, file);
+	/*
+	 * Determine type of southbridge chipset.
+	 */
+	switch (tco->tco_reg_layout) {
+	case sp5100:
+		dev_name = SP5100_DEVNAME;
+		mmio_addr = sp5100_tco_read_pm_reg32(SP5100_PM_WATCHDOG_BASE) &
+								0xfffffff8;
+		break;
+	case sb800:
+		dev_name = SB800_DEVNAME;
+		mmio_addr = sp5100_tco_read_pm_reg32(SB800_PM_WATCHDOG_BASE) &
+								0xfffffff8;
+		break;
+	case efch:
+		dev_name = SB800_DEVNAME;
+		val = sp5100_tco_read_pm_reg8(EFCH_PM_DECODEEN);
+		if (val & EFCH_PM_DECODEEN_WDT_TMREN)
+			mmio_addr = EFCH_PM_WDT_ADDR;
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	/* Check MMIO address conflict */
+	if (!mmio_addr ||
+	    !devm_request_mem_region(dev, mmio_addr, SP5100_WDT_MEM_MAP_SIZE,
+				     dev_name)) {
+		if (mmio_addr)
+			dev_dbg(dev, "MMIO address 0x%08x already in use\n",
+				mmio_addr);
+		switch (tco->tco_reg_layout) {
+		case sp5100:
+			/*
+			 * Secondly, Find the watchdog timer MMIO address
+			 * from SBResource_MMIO register.
+			 */
+			/* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */
+			pci_read_config_dword(sp5100_tco_pci,
+					      SP5100_SB_RESOURCE_MMIO_BASE,
+					      &mmio_addr);
+			if ((mmio_addr & (SB800_ACPI_MMIO_DECODE_EN |
+					  SB800_ACPI_MMIO_SEL)) !=
+						  SB800_ACPI_MMIO_DECODE_EN) {
+				ret = -ENODEV;
+				goto unreg_region;
+			}
+			mmio_addr &= ~0xFFF;
+			mmio_addr += SB800_PM_WDT_MMIO_OFFSET;
+			break;
+		case sb800:
+			/* Read SBResource_MMIO from AcpiMmioEn(PM_Reg: 24h) */
+			mmio_addr =
+				sp5100_tco_read_pm_reg32(SB800_PM_ACPI_MMIO_EN);
+			if ((mmio_addr & (SB800_ACPI_MMIO_DECODE_EN |
+					  SB800_ACPI_MMIO_SEL)) !=
+						  SB800_ACPI_MMIO_DECODE_EN) {
+				ret = -ENODEV;
+				goto unreg_region;
+			}
+			mmio_addr &= ~0xFFF;
+			mmio_addr += SB800_PM_WDT_MMIO_OFFSET;
+			break;
+		case efch:
+			val = sp5100_tco_read_pm_reg8(EFCH_PM_ISACONTROL);
+			if (!(val & EFCH_PM_ISACONTROL_MMIOEN)) {
+				ret = -ENODEV;
+				goto unreg_region;
+			}
+			mmio_addr = EFCH_PM_ACPI_MMIO_ADDR +
+				    EFCH_PM_ACPI_MMIO_WDT_OFFSET;
+			break;
+		}
+		dev_dbg(dev, "Got 0x%08x from SBResource_MMIO register\n",
+			mmio_addr);
+		if (!devm_request_mem_region(dev, mmio_addr,
+					     SP5100_WDT_MEM_MAP_SIZE,
+					     dev_name)) {
+			dev_dbg(dev, "MMIO address 0x%08x already in use\n",
+				mmio_addr);
+			ret = -EBUSY;
+			goto unreg_region;
+		}
+	}
+
+	tco->tcobase = devm_ioremap(dev, mmio_addr, SP5100_WDT_MEM_MAP_SIZE);
+	if (!tco->tcobase) {
+		dev_err(dev, "failed to get tcobase address\n");
+		ret = -ENOMEM;
+		goto unreg_region;
+	}
+
+	dev_info(dev, "Using 0x%08x for watchdog MMIO address\n", mmio_addr);
+
+	/* Setup the watchdog timer */
+	tco_timer_enable(tco);
+
+	val = readl(SP5100_WDT_CONTROL(tco->tcobase));
+	if (val & SP5100_WDT_DISABLED) {
+		dev_err(dev, "Watchdog hardware is disabled\n");
+		ret = -ENODEV;
+		goto unreg_region;
+	}
+
+	/*
+	 * Save WatchDogFired status, because WatchDogFired flag is
+	 * cleared here.
+	 */
+	if (val & SP5100_WDT_FIRED)
+		wdd->bootstatus = WDIOF_CARDRESET;
+	/* Set watchdog action to reset the system */
+	val &= ~SP5100_WDT_ACTION_RESET;
+	writel(val, SP5100_WDT_CONTROL(tco->tcobase));
+
+	/* Set a reasonable heartbeat before we stop the timer */
+	tco_timer_set_timeout(wdd, wdd->timeout);
+
+	/*
+	 * Stop the TCO before we change anything so we don't race with
+	 * a zeroed timer.
+	 */
+	tco_timer_stop(wdd);
+
+	release_region(SP5100_IO_PM_INDEX_REG, SP5100_PM_IOPORTS_SIZE);
+
+	return 0;
+
+unreg_region:
+	release_region(SP5100_IO_PM_INDEX_REG, SP5100_PM_IOPORTS_SIZE);
+	return ret;
 }
 
-static int sp5100_tco_release(struct inode *inode, struct file *file)
+static struct watchdog_info sp5100_tco_wdt_info = {
+	.identity = "SP5100 TCO timer",
+	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
+};
+
+static const struct watchdog_ops sp5100_tco_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = tco_timer_start,
+	.stop = tco_timer_stop,
+	.ping = tco_timer_ping,
+	.set_timeout = tco_timer_set_timeout,
+};
+
+static int sp5100_tco_probe(struct platform_device *pdev)
 {
-	/* Shut off the timer. */
-	if (tco_expect_close == 42) {
-		tco_timer_stop();
-	} else {
-		pr_crit("Unexpected close, not stopping watchdog!\n");
-		tco_timer_keepalive();
+	struct device *dev = &pdev->dev;
+	struct watchdog_device *wdd;
+	struct sp5100_tco *tco;
+	int ret;
+
+	tco = devm_kzalloc(dev, sizeof(*tco), GFP_KERNEL);
+	if (!tco)
+		return -ENOMEM;
+
+	tco->tco_reg_layout = tco_reg_layout(sp5100_tco_pci);
+
+	wdd = &tco->wdd;
+	wdd->parent = dev;
+	wdd->info = &sp5100_tco_wdt_info;
+	wdd->ops = &sp5100_tco_wdt_ops;
+	wdd->timeout = WATCHDOG_HEARTBEAT;
+	wdd->min_timeout = 1;
+	wdd->max_timeout = 0xffff;
+
+	if (watchdog_init_timeout(wdd, heartbeat, NULL))
+		dev_info(dev, "timeout value invalid, using %d\n",
+			 wdd->timeout);
+	watchdog_set_nowayout(wdd, nowayout);
+	watchdog_stop_on_reboot(wdd);
+	watchdog_stop_on_unregister(wdd);
+	watchdog_set_drvdata(wdd, tco);
+
+	ret = sp5100_tco_setupdevice(dev, wdd);
+	if (ret)
+		return ret;
+
+	ret = devm_watchdog_register_device(dev, wdd);
+	if (ret) {
+		dev_err(dev, "cannot register watchdog device (err=%d)\n", ret);
+		return ret;
 	}
-	clear_bit(0, &timer_alive);
-	tco_expect_close = 0;
+
+	/* Show module parameters */
+	dev_info(dev, "initialized. heartbeat=%d sec (nowayout=%d)\n",
+		 wdd->timeout, nowayout);
+
 	return 0;
 }
 
-static ssize_t sp5100_tco_write(struct file *file, const char __user *data,
-				size_t len, loff_t *ppos)
-{
-	/* See if we got the magic character 'V' and reload the timer */
-	if (len) {
-		if (!nowayout) {
-			size_t i;
-
-			/* note: just in case someone wrote the magic character
-			 * five months ago... */
-			tco_expect_close = 0;
-
-			/* scan to see whether or not we got the magic character
-			 */
-			for (i = 0; i != len; i++) {
-				char c;
-				if (get_user(c, data + i))
-					return -EFAULT;
-				if (c == 'V')
-					tco_expect_close = 42;
-			}
-		}
-
-		/* someone wrote to us, we should reload the timer */
-		tco_timer_keepalive();
-	}
-	return len;
-}
-
-static long sp5100_tco_ioctl(struct file *file, unsigned int cmd,
-			     unsigned long arg)
-{
-	int new_options, retval = -EINVAL;
-	int new_heartbeat;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-	static const struct watchdog_info ident = {
-		.options =		WDIOF_SETTIMEOUT |
-					WDIOF_KEEPALIVEPING |
-					WDIOF_MAGICCLOSE,
-		.firmware_version =	0,
-		.identity =		TCO_MODULE_NAME,
-	};
-
-	switch (cmd) {
-	case WDIOC_GETSUPPORT:
-		return copy_to_user(argp, &ident,
-			sizeof(ident)) ? -EFAULT : 0;
-	case WDIOC_GETSTATUS:
-	case WDIOC_GETBOOTSTATUS:
-		return put_user(0, p);
-	case WDIOC_SETOPTIONS:
-		if (get_user(new_options, p))
-			return -EFAULT;
-		if (new_options & WDIOS_DISABLECARD) {
-			tco_timer_stop();
-			retval = 0;
-		}
-		if (new_options & WDIOS_ENABLECARD) {
-			tco_timer_start();
-			tco_timer_keepalive();
-			retval = 0;
-		}
-		return retval;
-	case WDIOC_KEEPALIVE:
-		tco_timer_keepalive();
-		return 0;
-	case WDIOC_SETTIMEOUT:
-		if (get_user(new_heartbeat, p))
-			return -EFAULT;
-		if (tco_timer_set_heartbeat(new_heartbeat))
-			return -EINVAL;
-		tco_timer_keepalive();
-		/* Fall through */
-	case WDIOC_GETTIMEOUT:
-		return put_user(heartbeat, p);
-	default:
-		return -ENOTTY;
-	}
-}
-
-/*
- * Kernel Interfaces
- */
-
-static const struct file_operations sp5100_tco_fops = {
-	.owner =		THIS_MODULE,
-	.llseek =		no_llseek,
-	.write =		sp5100_tco_write,
-	.unlocked_ioctl =	sp5100_tco_ioctl,
-	.open =			sp5100_tco_open,
-	.release =		sp5100_tco_release,
-};
-
-static struct miscdevice sp5100_tco_miscdev = {
-	.minor =	WATCHDOG_MINOR,
-	.name =		"watchdog",
-	.fops =		&sp5100_tco_fops,
+static struct platform_driver sp5100_tco_driver = {
+	.probe		= sp5100_tco_probe,
+	.driver		= {
+		.name	= TCO_DRIVER_NAME,
+	},
 };
 
 /*
@@ -321,15 +446,10 @@ static const struct pci_device_id sp5100_tco_pci_tbl[] = {
 };
 MODULE_DEVICE_TABLE(pci, sp5100_tco_pci_tbl);
 
-/*
- * Init & exit routines
- */
-static unsigned char sp5100_tco_setupdevice(void)
+static int __init sp5100_tco_init(void)
 {
 	struct pci_dev *dev = NULL;
-	const char *dev_name = NULL;
-	u32 val;
-	u32 index_reg, data_reg, base_addr;
+	int err;
 
 	/* Match the PCI device */
 	for_each_pci_dev(dev) {
@@ -340,233 +460,16 @@ static unsigned char sp5100_tco_setupdevice(void)
 	}
 
 	if (!sp5100_tco_pci)
-		return 0;
-
-	pr_info("PCI Vendor ID: 0x%x, Device ID: 0x%x, Revision ID: 0x%x\n",
-		sp5100_tco_pci->vendor, sp5100_tco_pci->device,
-		sp5100_tco_pci->revision);
-
-	/*
-	 * Determine type of southbridge chipset.
-	 */
-	if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) {
-		dev_name = SP5100_DEVNAME;
-		index_reg = SP5100_IO_PM_INDEX_REG;
-		data_reg = SP5100_IO_PM_DATA_REG;
-		base_addr = SP5100_PM_WATCHDOG_BASE;
-	} else {
-		dev_name = SB800_DEVNAME;
-		index_reg = SB800_IO_PM_INDEX_REG;
-		data_reg = SB800_IO_PM_DATA_REG;
-		base_addr = SB800_PM_WATCHDOG_BASE;
-	}
-
-	/* Request the IO ports used by this driver */
-	pm_iobase = SP5100_IO_PM_INDEX_REG;
-	if (!request_region(pm_iobase, SP5100_PM_IOPORTS_SIZE, dev_name)) {
-		pr_err("I/O address 0x%04x already in use\n", pm_iobase);
-		goto exit;
-	}
-
-	/*
-	 * First, Find the watchdog timer MMIO address from indirect I/O.
-	 */
-	outb(base_addr+3, index_reg);
-	val = inb(data_reg);
-	outb(base_addr+2, index_reg);
-	val = val << 8 | inb(data_reg);
-	outb(base_addr+1, index_reg);
-	val = val << 8 | inb(data_reg);
-	outb(base_addr+0, index_reg);
-	/* Low three bits of BASE are reserved */
-	val = val << 8 | (inb(data_reg) & 0xf8);
-
-	pr_debug("Got 0x%04x from indirect I/O\n", val);
-
-	/* Check MMIO address conflict */
-	if (request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
-								dev_name))
-		goto setup_wdt;
-	else
-		pr_debug("MMIO address 0x%04x already in use\n", val);
-
-	/*
-	 * Secondly, Find the watchdog timer MMIO address
-	 * from SBResource_MMIO register.
-	 */
-	if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) {
-		/* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */
-		pci_read_config_dword(sp5100_tco_pci,
-				      SP5100_SB_RESOURCE_MMIO_BASE, &val);
-	} else {
-		/* Read SBResource_MMIO from AcpiMmioEn(PM_Reg: 24h) */
-		outb(SB800_PM_ACPI_MMIO_EN+3, SB800_IO_PM_INDEX_REG);
-		val = inb(SB800_IO_PM_DATA_REG);
-		outb(SB800_PM_ACPI_MMIO_EN+2, SB800_IO_PM_INDEX_REG);
-		val = val << 8 | inb(SB800_IO_PM_DATA_REG);
-		outb(SB800_PM_ACPI_MMIO_EN+1, SB800_IO_PM_INDEX_REG);
-		val = val << 8 | inb(SB800_IO_PM_DATA_REG);
-		outb(SB800_PM_ACPI_MMIO_EN+0, SB800_IO_PM_INDEX_REG);
-		val = val << 8 | inb(SB800_IO_PM_DATA_REG);
-	}
-
-	/* The SBResource_MMIO is enabled and mapped memory space? */
-	if ((val & (SB800_ACPI_MMIO_DECODE_EN | SB800_ACPI_MMIO_SEL)) ==
-						  SB800_ACPI_MMIO_DECODE_EN) {
-		/* Clear unnecessary the low twelve bits */
-		val &= ~0xFFF;
-		/* Add the Watchdog Timer offset to base address. */
-		val += SB800_PM_WDT_MMIO_OFFSET;
-		/* Check MMIO address conflict */
-		if (request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
-								   dev_name)) {
-			pr_debug("Got 0x%04x from SBResource_MMIO register\n",
-				val);
-			goto setup_wdt;
-		} else
-			pr_debug("MMIO address 0x%04x already in use\n", val);
-	} else
-		pr_debug("SBResource_MMIO is disabled(0x%04x)\n", val);
-
-	pr_notice("failed to find MMIO address, giving up.\n");
-	goto  unreg_region;
-
-setup_wdt:
-	tcobase_phys = val;
-
-	tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE);
-	if (!tcobase) {
-		pr_err("failed to get tcobase address\n");
-		goto unreg_mem_region;
-	}
-
-	pr_info("Using 0x%04x for watchdog MMIO address\n", val);
-
-	/* Setup the watchdog timer */
-	tco_timer_enable();
-
-	/* Check that the watchdog action is set to reset the system */
-	val = readl(SP5100_WDT_CONTROL(tcobase));
-	/*
-	 * Save WatchDogFired status, because WatchDogFired flag is
-	 * cleared here.
-	 */
-	tco_wdt_fired = val & SP5100_PM_WATCHDOG_FIRED;
-	val &= ~SP5100_PM_WATCHDOG_ACTION_RESET;
-	writel(val, SP5100_WDT_CONTROL(tcobase));
-
-	/* Set a reasonable heartbeat before we stop the timer */
-	tco_timer_set_heartbeat(heartbeat);
-
-	/*
-	 * Stop the TCO before we change anything so we don't race with
-	 * a zeroed timer.
-	 */
-	tco_timer_stop();
-
-	/* Done */
-	return 1;
-
-unreg_mem_region:
-	release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
-unreg_region:
-	release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
-exit:
-	return 0;
-}
-
-static int sp5100_tco_init(struct platform_device *dev)
-{
-	int ret;
-
-	/*
-	 * Check whether or not the hardware watchdog is there. If found, then
-	 * set it up.
-	 */
-	if (!sp5100_tco_setupdevice())
 		return -ENODEV;
 
-	/* Check to see if last reboot was due to watchdog timeout */
-	pr_info("Last reboot was %striggered by watchdog.\n",
-		tco_wdt_fired ? "" : "not ");
-
-	/*
-	 * Check that the heartbeat value is within it's range.
-	 * If not, reset to the default.
-	 */
-	if (tco_timer_set_heartbeat(heartbeat)) {
-		heartbeat = WATCHDOG_HEARTBEAT;
-		tco_timer_set_heartbeat(heartbeat);
-	}
-
-	ret = misc_register(&sp5100_tco_miscdev);
-	if (ret != 0) {
-		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
-		       WATCHDOG_MINOR, ret);
-		goto exit;
-	}
-
-	clear_bit(0, &timer_alive);
-
-	/* Show module parameters */
-	pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
-		tcobase, heartbeat, nowayout);
-
-	return 0;
-
-exit:
-	iounmap(tcobase);
-	release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
-	release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
-	return ret;
-}
-
-static void sp5100_tco_cleanup(void)
-{
-	/* Stop the timer before we leave */
-	if (!nowayout)
-		tco_timer_stop();
-
-	/* Deregister */
-	misc_deregister(&sp5100_tco_miscdev);
-	iounmap(tcobase);
-	release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
-	release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
-}
-
-static int sp5100_tco_remove(struct platform_device *dev)
-{
-	if (tcobase)
-		sp5100_tco_cleanup();
-	return 0;
-}
-
-static void sp5100_tco_shutdown(struct platform_device *dev)
-{
-	tco_timer_stop();
-}
-
-static struct platform_driver sp5100_tco_driver = {
-	.probe		= sp5100_tco_init,
-	.remove		= sp5100_tco_remove,
-	.shutdown	= sp5100_tco_shutdown,
-	.driver		= {
-		.name	= TCO_MODULE_NAME,
-	},
-};
-
-static int __init sp5100_tco_init_module(void)
-{
-	int err;
-
-	pr_info("SP5100/SB800 TCO WatchDog Timer Driver v%s\n", TCO_VERSION);
+	pr_info("SP5100/SB800 TCO WatchDog Timer Driver\n");
 
 	err = platform_driver_register(&sp5100_tco_driver);
 	if (err)
 		return err;
 
-	sp5100_tco_platform_device = platform_device_register_simple(
-					TCO_MODULE_NAME, -1, NULL, 0);
+	sp5100_tco_platform_device =
+		platform_device_register_simple(TCO_DRIVER_NAME, -1, NULL, 0);
 	if (IS_ERR(sp5100_tco_platform_device)) {
 		err = PTR_ERR(sp5100_tco_platform_device);
 		goto unreg_platform_driver;
@@ -579,15 +482,14 @@ static int __init sp5100_tco_init_module(void)
 	return err;
 }
 
-static void __exit sp5100_tco_cleanup_module(void)
+static void __exit sp5100_tco_exit(void)
 {
 	platform_device_unregister(sp5100_tco_platform_device);
 	platform_driver_unregister(&sp5100_tco_driver);
-	pr_info("SP5100/SB800 TCO Watchdog Module Unloaded\n");
 }
 
-module_init(sp5100_tco_init_module);
-module_exit(sp5100_tco_cleanup_module);
+module_init(sp5100_tco_init);
+module_exit(sp5100_tco_exit);
 
 MODULE_AUTHOR("Priyanka Gupta");
 MODULE_DESCRIPTION("TCO timer driver for SP5100/SB800 chipset");
diff --git a/drivers/watchdog/sp5100_tco.h b/drivers/watchdog/sp5100_tco.h
index 1af4dee..87eaf35 100644
--- a/drivers/watchdog/sp5100_tco.h
+++ b/drivers/watchdog/sp5100_tco.h
@@ -7,6 +7,8 @@
  *	TCO timer driver for sp5100 chipsets
  */
 
+#include <linux/bitops.h>
+
 /*
  * Some address definitions for the Watchdog
  */
@@ -14,8 +16,11 @@
 #define SP5100_WDT_CONTROL(base)	((base) + 0x00) /* Watchdog Control */
 #define SP5100_WDT_COUNT(base)		((base) + 0x04) /* Watchdog Count */
 
-#define SP5100_WDT_START_STOP_BIT	(1 << 0)
-#define SP5100_WDT_TRIGGER_BIT		(1 << 7)
+#define SP5100_WDT_START_STOP_BIT	BIT(0)
+#define SP5100_WDT_FIRED		BIT(1)
+#define SP5100_WDT_ACTION_RESET		BIT(2)
+#define SP5100_WDT_DISABLED		BIT(3)
+#define SP5100_WDT_TRIGGER_BIT		BIT(7)
 
 #define SP5100_PM_IOPORTS_SIZE		0x02
 
@@ -24,43 +29,57 @@
  * read them from a register.
  */
 
-/*  For SP5100/SB7x0 chipset */
+/*  For SP5100/SB7x0/SB8x0 chipset */
 #define SP5100_IO_PM_INDEX_REG		0xCD6
 #define SP5100_IO_PM_DATA_REG		0xCD7
 
+/* For SP5100/SB7x0 chipset */
 #define SP5100_SB_RESOURCE_MMIO_BASE	0x9C
 
 #define SP5100_PM_WATCHDOG_CONTROL	0x69
 #define SP5100_PM_WATCHDOG_BASE		0x6C
 
-#define SP5100_PM_WATCHDOG_FIRED	(1 << 1)
-#define SP5100_PM_WATCHDOG_ACTION_RESET	(1 << 2)
-
 #define SP5100_PCI_WATCHDOG_MISC_REG	0x41
-#define SP5100_PCI_WATCHDOG_DECODE_EN	(1 << 3)
+#define SP5100_PCI_WATCHDOG_DECODE_EN	BIT(3)
 
-#define SP5100_PM_WATCHDOG_DISABLE	(1 << 0)
-#define SP5100_PM_WATCHDOG_SECOND_RES	(3 << 1)
+#define SP5100_PM_WATCHDOG_DISABLE	((u8)BIT(0))
+#define SP5100_PM_WATCHDOG_SECOND_RES	GENMASK(2, 1)
 
 #define SP5100_DEVNAME			"SP5100 TCO"
 
-
 /*  For SB8x0(or later) chipset */
-#define SB800_IO_PM_INDEX_REG		0xCD6
-#define SB800_IO_PM_DATA_REG		0xCD7
-
 #define SB800_PM_ACPI_MMIO_EN		0x24
 #define SB800_PM_WATCHDOG_CONTROL	0x48
 #define SB800_PM_WATCHDOG_BASE		0x48
 #define SB800_PM_WATCHDOG_CONFIG	0x4C
 
-#define SB800_PCI_WATCHDOG_DECODE_EN	(1 << 0)
-#define SB800_PM_WATCHDOG_DISABLE	(1 << 2)
-#define SB800_PM_WATCHDOG_SECOND_RES	(3 << 0)
-#define SB800_ACPI_MMIO_DECODE_EN	(1 << 0)
-#define SB800_ACPI_MMIO_SEL		(1 << 1)
-
+#define SB800_PCI_WATCHDOG_DECODE_EN	BIT(0)
+#define SB800_PM_WATCHDOG_DISABLE	((u8)BIT(1))
+#define SB800_PM_WATCHDOG_SECOND_RES	GENMASK(1, 0)
+#define SB800_ACPI_MMIO_DECODE_EN	BIT(0)
+#define SB800_ACPI_MMIO_SEL		BIT(1)
 
 #define SB800_PM_WDT_MMIO_OFFSET	0xB00
 
 #define SB800_DEVNAME			"SB800 TCO"
+
+/* For recent chips with embedded FCH (rev 40+) */
+
+#define EFCH_PM_DECODEEN		0x00
+
+#define EFCH_PM_DECODEEN_WDT_TMREN	BIT(7)
+
+
+#define EFCH_PM_DECODEEN3		0x00
+#define EFCH_PM_DECODEEN_SECOND_RES	GENMASK(1, 0)
+#define EFCH_PM_WATCHDOG_DISABLE	((u8)GENMASK(3, 2))
+
+/* WDT MMIO if enabled with PM00_DECODEEN_WDT_TMREN */
+#define EFCH_PM_WDT_ADDR		0xfeb00000
+
+#define EFCH_PM_ISACONTROL		0x04
+
+#define EFCH_PM_ISACONTROL_MMIOEN	BIT(1)
+
+#define EFCH_PM_ACPI_MMIO_ADDR		0xfed80000
+#define EFCH_PM_ACPI_MMIO_WDT_OFFSET	0x00000b00
diff --git a/drivers/watchdog/sprd_wdt.c b/drivers/watchdog/sprd_wdt.c
new file mode 100644
index 0000000..a8b280f
--- /dev/null
+++ b/drivers/watchdog/sprd_wdt.c
@@ -0,0 +1,399 @@
+/*
+ * Spreadtrum watchdog driver
+ * Copyright (C) 2017 Spreadtrum - http://www.spreadtrum.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+
+#define SPRD_WDT_LOAD_LOW		0x0
+#define SPRD_WDT_LOAD_HIGH		0x4
+#define SPRD_WDT_CTRL			0x8
+#define SPRD_WDT_INT_CLR		0xc
+#define SPRD_WDT_INT_RAW		0x10
+#define SPRD_WDT_INT_MSK		0x14
+#define SPRD_WDT_CNT_LOW		0x18
+#define SPRD_WDT_CNT_HIGH		0x1c
+#define SPRD_WDT_LOCK			0x20
+#define SPRD_WDT_IRQ_LOAD_LOW		0x2c
+#define SPRD_WDT_IRQ_LOAD_HIGH		0x30
+
+/* WDT_CTRL */
+#define SPRD_WDT_INT_EN_BIT		BIT(0)
+#define SPRD_WDT_CNT_EN_BIT		BIT(1)
+#define SPRD_WDT_NEW_VER_EN		BIT(2)
+#define SPRD_WDT_RST_EN_BIT		BIT(3)
+
+/* WDT_INT_CLR */
+#define SPRD_WDT_INT_CLEAR_BIT		BIT(0)
+#define SPRD_WDT_RST_CLEAR_BIT		BIT(3)
+
+/* WDT_INT_RAW */
+#define SPRD_WDT_INT_RAW_BIT		BIT(0)
+#define SPRD_WDT_RST_RAW_BIT		BIT(3)
+#define SPRD_WDT_LD_BUSY_BIT		BIT(4)
+
+/* 1s equal to 32768 counter steps */
+#define SPRD_WDT_CNT_STEP		32768
+
+#define SPRD_WDT_UNLOCK_KEY		0xe551
+#define SPRD_WDT_MIN_TIMEOUT		3
+#define SPRD_WDT_MAX_TIMEOUT		60
+
+#define SPRD_WDT_CNT_HIGH_SHIFT		16
+#define SPRD_WDT_LOW_VALUE_MASK		GENMASK(15, 0)
+#define SPRD_WDT_LOAD_TIMEOUT		1000
+
+struct sprd_wdt {
+	void __iomem *base;
+	struct watchdog_device wdd;
+	struct clk *enable;
+	struct clk *rtc_enable;
+	int irq;
+};
+
+static inline struct sprd_wdt *to_sprd_wdt(struct watchdog_device *wdd)
+{
+	return container_of(wdd, struct sprd_wdt, wdd);
+}
+
+static inline void sprd_wdt_lock(void __iomem *addr)
+{
+	writel_relaxed(0x0, addr + SPRD_WDT_LOCK);
+}
+
+static inline void sprd_wdt_unlock(void __iomem *addr)
+{
+	writel_relaxed(SPRD_WDT_UNLOCK_KEY, addr + SPRD_WDT_LOCK);
+}
+
+static irqreturn_t sprd_wdt_isr(int irq, void *dev_id)
+{
+	struct sprd_wdt *wdt = (struct sprd_wdt *)dev_id;
+
+	sprd_wdt_unlock(wdt->base);
+	writel_relaxed(SPRD_WDT_INT_CLEAR_BIT, wdt->base + SPRD_WDT_INT_CLR);
+	sprd_wdt_lock(wdt->base);
+	watchdog_notify_pretimeout(&wdt->wdd);
+	return IRQ_HANDLED;
+}
+
+static u32 sprd_wdt_get_cnt_value(struct sprd_wdt *wdt)
+{
+	u32 val;
+
+	val = readl_relaxed(wdt->base + SPRD_WDT_CNT_HIGH) <<
+		SPRD_WDT_CNT_HIGH_SHIFT;
+	val |= readl_relaxed(wdt->base + SPRD_WDT_CNT_LOW) &
+		SPRD_WDT_LOW_VALUE_MASK;
+
+	return val;
+}
+
+static int sprd_wdt_load_value(struct sprd_wdt *wdt, u32 timeout,
+			       u32 pretimeout)
+{
+	u32 val, delay_cnt = 0;
+	u32 tmr_step = timeout * SPRD_WDT_CNT_STEP;
+	u32 prtmr_step = pretimeout * SPRD_WDT_CNT_STEP;
+
+	sprd_wdt_unlock(wdt->base);
+	writel_relaxed((tmr_step >> SPRD_WDT_CNT_HIGH_SHIFT) &
+		      SPRD_WDT_LOW_VALUE_MASK, wdt->base + SPRD_WDT_LOAD_HIGH);
+	writel_relaxed((tmr_step & SPRD_WDT_LOW_VALUE_MASK),
+		       wdt->base + SPRD_WDT_LOAD_LOW);
+	writel_relaxed((prtmr_step >> SPRD_WDT_CNT_HIGH_SHIFT) &
+			SPRD_WDT_LOW_VALUE_MASK,
+		       wdt->base + SPRD_WDT_IRQ_LOAD_HIGH);
+	writel_relaxed(prtmr_step & SPRD_WDT_LOW_VALUE_MASK,
+		       wdt->base + SPRD_WDT_IRQ_LOAD_LOW);
+	sprd_wdt_lock(wdt->base);
+
+	/*
+	 * Waiting the load value operation done,
+	 * it needs two or three RTC clock cycles.
+	 */
+	do {
+		val = readl_relaxed(wdt->base + SPRD_WDT_INT_RAW);
+		if (!(val & SPRD_WDT_LD_BUSY_BIT))
+			break;
+
+		cpu_relax();
+	} while (delay_cnt++ < SPRD_WDT_LOAD_TIMEOUT);
+
+	if (delay_cnt >= SPRD_WDT_LOAD_TIMEOUT)
+		return -EBUSY;
+	return 0;
+}
+
+static int sprd_wdt_enable(struct sprd_wdt *wdt)
+{
+	u32 val;
+	int ret;
+
+	ret = clk_prepare_enable(wdt->enable);
+	if (ret)
+		return ret;
+	ret = clk_prepare_enable(wdt->rtc_enable);
+	if (ret)
+		return ret;
+
+	sprd_wdt_unlock(wdt->base);
+	val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
+	val |= SPRD_WDT_NEW_VER_EN;
+	writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
+	sprd_wdt_lock(wdt->base);
+	return 0;
+}
+
+static void sprd_wdt_disable(void *_data)
+{
+	struct sprd_wdt *wdt = _data;
+
+	sprd_wdt_unlock(wdt->base);
+	writel_relaxed(0x0, wdt->base + SPRD_WDT_CTRL);
+	sprd_wdt_lock(wdt->base);
+
+	clk_disable_unprepare(wdt->rtc_enable);
+	clk_disable_unprepare(wdt->enable);
+}
+
+static int sprd_wdt_start(struct watchdog_device *wdd)
+{
+	struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+	u32 val;
+	int ret;
+
+	ret = sprd_wdt_load_value(wdt, wdd->timeout, wdd->pretimeout);
+	if (ret)
+		return ret;
+
+	sprd_wdt_unlock(wdt->base);
+	val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
+	val |= SPRD_WDT_CNT_EN_BIT | SPRD_WDT_INT_EN_BIT | SPRD_WDT_RST_EN_BIT;
+	writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
+	sprd_wdt_lock(wdt->base);
+	set_bit(WDOG_HW_RUNNING, &wdd->status);
+
+	return 0;
+}
+
+static int sprd_wdt_stop(struct watchdog_device *wdd)
+{
+	struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+	u32 val;
+
+	sprd_wdt_unlock(wdt->base);
+	val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
+	val &= ~(SPRD_WDT_CNT_EN_BIT | SPRD_WDT_RST_EN_BIT |
+		SPRD_WDT_INT_EN_BIT);
+	writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
+	sprd_wdt_lock(wdt->base);
+	return 0;
+}
+
+static int sprd_wdt_set_timeout(struct watchdog_device *wdd,
+				u32 timeout)
+{
+	struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+
+	if (timeout == wdd->timeout)
+		return 0;
+
+	wdd->timeout = timeout;
+
+	return sprd_wdt_load_value(wdt, timeout, wdd->pretimeout);
+}
+
+static int sprd_wdt_set_pretimeout(struct watchdog_device *wdd,
+				   u32 new_pretimeout)
+{
+	struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+
+	if (new_pretimeout < wdd->min_timeout)
+		return -EINVAL;
+
+	wdd->pretimeout = new_pretimeout;
+
+	return sprd_wdt_load_value(wdt, wdd->timeout, new_pretimeout);
+}
+
+static u32 sprd_wdt_get_timeleft(struct watchdog_device *wdd)
+{
+	struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+	u32 val;
+
+	val = sprd_wdt_get_cnt_value(wdt);
+	val = val / SPRD_WDT_CNT_STEP;
+
+	return val;
+}
+
+static const struct watchdog_ops sprd_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = sprd_wdt_start,
+	.stop = sprd_wdt_stop,
+	.set_timeout = sprd_wdt_set_timeout,
+	.set_pretimeout = sprd_wdt_set_pretimeout,
+	.get_timeleft = sprd_wdt_get_timeleft,
+};
+
+static const struct watchdog_info sprd_wdt_info = {
+	.options = WDIOF_SETTIMEOUT |
+		   WDIOF_PRETIMEOUT |
+		   WDIOF_MAGICCLOSE |
+		   WDIOF_KEEPALIVEPING,
+	.identity = "Spreadtrum Watchdog Timer",
+};
+
+static int sprd_wdt_probe(struct platform_device *pdev)
+{
+	struct resource *wdt_res;
+	struct sprd_wdt *wdt;
+	int ret;
+
+	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+	if (!wdt)
+		return -ENOMEM;
+
+	wdt_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	wdt->base = devm_ioremap_resource(&pdev->dev, wdt_res);
+	if (IS_ERR(wdt->base)) {
+		dev_err(&pdev->dev, "failed to map memory resource\n");
+		return PTR_ERR(wdt->base);
+	}
+
+	wdt->enable = devm_clk_get(&pdev->dev, "enable");
+	if (IS_ERR(wdt->enable)) {
+		dev_err(&pdev->dev, "can't get the enable clock\n");
+		return PTR_ERR(wdt->enable);
+	}
+
+	wdt->rtc_enable = devm_clk_get(&pdev->dev, "rtc_enable");
+	if (IS_ERR(wdt->rtc_enable)) {
+		dev_err(&pdev->dev, "can't get the rtc enable clock\n");
+		return PTR_ERR(wdt->rtc_enable);
+	}
+
+	wdt->irq = platform_get_irq(pdev, 0);
+	if (wdt->irq < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ resource\n");
+		return wdt->irq;
+	}
+
+	ret = devm_request_irq(&pdev->dev, wdt->irq, sprd_wdt_isr,
+			       IRQF_NO_SUSPEND, "sprd-wdt", (void *)wdt);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register irq\n");
+		return ret;
+	}
+
+	wdt->wdd.info = &sprd_wdt_info;
+	wdt->wdd.ops = &sprd_wdt_ops;
+	wdt->wdd.parent = &pdev->dev;
+	wdt->wdd.min_timeout = SPRD_WDT_MIN_TIMEOUT;
+	wdt->wdd.max_timeout = SPRD_WDT_MAX_TIMEOUT;
+	wdt->wdd.timeout = SPRD_WDT_MAX_TIMEOUT;
+
+	ret = sprd_wdt_enable(wdt);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to enable wdt\n");
+		return ret;
+	}
+	ret = devm_add_action(&pdev->dev, sprd_wdt_disable, wdt);
+	if (ret) {
+		sprd_wdt_disable(wdt);
+		dev_err(&pdev->dev, "Failed to add wdt disable action\n");
+		return ret;
+	}
+
+	watchdog_set_nowayout(&wdt->wdd, WATCHDOG_NOWAYOUT);
+	watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
+
+	ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
+	if (ret) {
+		sprd_wdt_disable(wdt);
+		dev_err(&pdev->dev, "failed to register watchdog\n");
+		return ret;
+	}
+	platform_set_drvdata(pdev, wdt);
+
+	return 0;
+}
+
+static int __maybe_unused sprd_wdt_pm_suspend(struct device *dev)
+{
+	struct watchdog_device *wdd = dev_get_drvdata(dev);
+	struct sprd_wdt *wdt = dev_get_drvdata(dev);
+
+	if (watchdog_active(wdd))
+		sprd_wdt_stop(&wdt->wdd);
+	sprd_wdt_disable(wdt);
+
+	return 0;
+}
+
+static int __maybe_unused sprd_wdt_pm_resume(struct device *dev)
+{
+	struct watchdog_device *wdd = dev_get_drvdata(dev);
+	struct sprd_wdt *wdt = dev_get_drvdata(dev);
+	int ret;
+
+	ret = sprd_wdt_enable(wdt);
+	if (ret)
+		return ret;
+
+	if (watchdog_active(wdd)) {
+		ret = sprd_wdt_start(&wdt->wdd);
+		if (ret) {
+			sprd_wdt_disable(wdt);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops sprd_wdt_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(sprd_wdt_pm_suspend,
+				sprd_wdt_pm_resume)
+};
+
+static const struct of_device_id sprd_wdt_match_table[] = {
+	{ .compatible = "sprd,sp9860-wdt", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, sprd_wdt_match_table);
+
+static struct platform_driver sprd_watchdog_driver = {
+	.probe	= sprd_wdt_probe,
+	.driver	= {
+		.name = "sprd-wdt",
+		.of_match_table = sprd_wdt_match_table,
+		.pm = &sprd_wdt_pm_ops,
+	},
+};
+module_platform_driver(sprd_watchdog_driver);
+
+MODULE_AUTHOR("Eric Long <eric.long@spreadtrum.com>");
+MODULE_DESCRIPTION("Spreadtrum Watchdog Timer Controller Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
index be64a86..c97ad56 100644
--- a/drivers/watchdog/stm32_iwdg.c
+++ b/drivers/watchdog/stm32_iwdg.c
@@ -1,12 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Driver for STM32 Independent Watchdog
  *
- * Copyright (C) Yannick Fertre 2017
- * Author: Yannick Fertre <yannick.fertre@st.com>
+ * Copyright (C) STMicroelectronics 2017
+ * Author: Yannick Fertre <yannick.fertre@st.com> for STMicroelectronics.
  *
  * This driver is based on tegra_wdt.c
  *
- * License terms:  GNU General Public License (GPL), version 2
  */
 
 #include <linux/clk.h>
diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c
index 9728fa3..802e31b 100644
--- a/drivers/watchdog/sunxi_wdt.c
+++ b/drivers/watchdog/sunxi_wdt.c
@@ -234,7 +234,6 @@ MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids);
 static int sunxi_wdt_probe(struct platform_device *pdev)
 {
 	struct sunxi_wdt_dev *sunxi_wdt;
-	const struct of_device_id *device;
 	struct resource *res;
 	int err;
 
@@ -242,12 +241,10 @@ static int sunxi_wdt_probe(struct platform_device *pdev)
 	if (!sunxi_wdt)
 		return -EINVAL;
 
-	device = of_match_device(sunxi_wdt_dt_ids, &pdev->dev);
-	if (!device)
+	sunxi_wdt->wdt_regs = of_device_get_match_data(&pdev->dev);
+	if (!sunxi_wdt->wdt_regs)
 		return -ENODEV;
 
-	sunxi_wdt->wdt_regs = device->data;
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	sunxi_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(sunxi_wdt->wdt_base))
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
index 8a8d952..eb8fa25 100644
--- a/drivers/watchdog/watchdog_core.c
+++ b/drivers/watchdog/watchdog_core.c
@@ -97,6 +97,7 @@ static void watchdog_check_min_max_timeout(struct watchdog_device *wdd)
 
 /**
  * watchdog_init_timeout() - initialize the timeout field
+ * @wdd: watchdog device
  * @timeout_parm: timeout module parameter
  * @dev: Device that stores the timeout-sec property
  *
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 1e971a5..ffbdc46 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -36,9 +36,10 @@
 #include <linux/errno.h>	/* For the -ENODEV/... values */
 #include <linux/fs.h>		/* For file operations */
 #include <linux/init.h>		/* For __init/__exit/... */
-#include <linux/jiffies.h>	/* For timeout functions */
+#include <linux/hrtimer.h>	/* For hrtimers */
 #include <linux/kernel.h>	/* For printk/panic/... */
 #include <linux/kref.h>		/* For data references */
+#include <linux/kthread.h>	/* For kthread_work */
 #include <linux/miscdevice.h>	/* For handling misc devices */
 #include <linux/module.h>	/* For module stuff/... */
 #include <linux/mutex.h>	/* For mutexes */
@@ -46,9 +47,10 @@
 #include <linux/slab.h>		/* For memory functions */
 #include <linux/types.h>	/* For standard types (like size_t) */
 #include <linux/watchdog.h>	/* For watchdog specific items */
-#include <linux/workqueue.h>	/* For workqueue */
 #include <linux/uaccess.h>	/* For copy_to_user/put_user/... */
 
+#include <uapi/linux/sched/types.h>	/* For struct sched_param */
+
 #include "watchdog_core.h"
 #include "watchdog_pretimeout.h"
 
@@ -65,9 +67,10 @@ struct watchdog_core_data {
 	struct cdev cdev;
 	struct watchdog_device *wdd;
 	struct mutex lock;
-	unsigned long last_keepalive;
-	unsigned long last_hw_keepalive;
-	struct delayed_work work;
+	ktime_t last_keepalive;
+	ktime_t last_hw_keepalive;
+	struct hrtimer timer;
+	struct kthread_work work;
 	unsigned long status;		/* Internal status bits */
 #define _WDOG_DEV_OPEN		0	/* Opened ? */
 #define _WDOG_ALLOW_RELEASE	1	/* Did we receive the magic char ? */
@@ -79,7 +82,7 @@ static dev_t watchdog_devt;
 /* Reference to watchdog device behind /dev/watchdog */
 static struct watchdog_core_data *old_wd_data;
 
-static struct workqueue_struct *watchdog_wq;
+static struct kthread_worker *watchdog_kworker;
 
 static bool handle_boot_enabled =
 	IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED);
@@ -107,18 +110,19 @@ static inline bool watchdog_need_worker(struct watchdog_device *wdd)
 		(t && !watchdog_active(wdd) && watchdog_hw_running(wdd));
 }
 
-static long watchdog_next_keepalive(struct watchdog_device *wdd)
+static ktime_t watchdog_next_keepalive(struct watchdog_device *wdd)
 {
 	struct watchdog_core_data *wd_data = wdd->wd_data;
 	unsigned int timeout_ms = wdd->timeout * 1000;
-	unsigned long keepalive_interval;
-	unsigned long last_heartbeat;
-	unsigned long virt_timeout;
+	ktime_t keepalive_interval;
+	ktime_t last_heartbeat, latest_heartbeat;
+	ktime_t virt_timeout;
 	unsigned int hw_heartbeat_ms;
 
-	virt_timeout = wd_data->last_keepalive + msecs_to_jiffies(timeout_ms);
+	virt_timeout = ktime_add(wd_data->last_keepalive,
+				 ms_to_ktime(timeout_ms));
 	hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms);
-	keepalive_interval = msecs_to_jiffies(hw_heartbeat_ms / 2);
+	keepalive_interval = ms_to_ktime(hw_heartbeat_ms / 2);
 
 	if (!watchdog_active(wdd))
 		return keepalive_interval;
@@ -128,8 +132,11 @@ static long watchdog_next_keepalive(struct watchdog_device *wdd)
 	 * after the most recent ping from userspace, the last
 	 * worker ping has to come in hw_heartbeat_ms before this timeout.
 	 */
-	last_heartbeat = virt_timeout - msecs_to_jiffies(hw_heartbeat_ms);
-	return min_t(long, last_heartbeat - jiffies, keepalive_interval);
+	last_heartbeat = ktime_sub(virt_timeout, ms_to_ktime(hw_heartbeat_ms));
+	latest_heartbeat = ktime_sub(last_heartbeat, ktime_get());
+	if (ktime_before(latest_heartbeat, keepalive_interval))
+		return latest_heartbeat;
+	return keepalive_interval;
 }
 
 static inline void watchdog_update_worker(struct watchdog_device *wdd)
@@ -137,29 +144,33 @@ static inline void watchdog_update_worker(struct watchdog_device *wdd)
 	struct watchdog_core_data *wd_data = wdd->wd_data;
 
 	if (watchdog_need_worker(wdd)) {
-		long t = watchdog_next_keepalive(wdd);
+		ktime_t t = watchdog_next_keepalive(wdd);
 
 		if (t > 0)
-			mod_delayed_work(watchdog_wq, &wd_data->work, t);
+			hrtimer_start(&wd_data->timer, t, HRTIMER_MODE_REL);
 	} else {
-		cancel_delayed_work(&wd_data->work);
+		hrtimer_cancel(&wd_data->timer);
 	}
 }
 
 static int __watchdog_ping(struct watchdog_device *wdd)
 {
 	struct watchdog_core_data *wd_data = wdd->wd_data;
-	unsigned long earliest_keepalive = wd_data->last_hw_keepalive +
-				msecs_to_jiffies(wdd->min_hw_heartbeat_ms);
+	ktime_t earliest_keepalive, now;
 	int err;
 
-	if (time_is_after_jiffies(earliest_keepalive)) {
-		mod_delayed_work(watchdog_wq, &wd_data->work,
-				 earliest_keepalive - jiffies);
+	earliest_keepalive = ktime_add(wd_data->last_hw_keepalive,
+				       ms_to_ktime(wdd->min_hw_heartbeat_ms));
+	now = ktime_get();
+
+	if (ktime_after(earliest_keepalive, now)) {
+		hrtimer_start(&wd_data->timer,
+			      ktime_sub(earliest_keepalive, now),
+			      HRTIMER_MODE_REL);
 		return 0;
 	}
 
-	wd_data->last_hw_keepalive = jiffies;
+	wd_data->last_hw_keepalive = now;
 
 	if (wdd->ops->ping)
 		err = wdd->ops->ping(wdd);  /* ping the watchdog */
@@ -192,7 +203,7 @@ static int watchdog_ping(struct watchdog_device *wdd)
 
 	set_bit(_WDOG_KEEPALIVE, &wd_data->status);
 
-	wd_data->last_keepalive = jiffies;
+	wd_data->last_keepalive = ktime_get();
 	return __watchdog_ping(wdd);
 }
 
@@ -203,12 +214,11 @@ static bool watchdog_worker_should_ping(struct watchdog_core_data *wd_data)
 	return wdd && (watchdog_active(wdd) || watchdog_hw_running(wdd));
 }
 
-static void watchdog_ping_work(struct work_struct *work)
+static void watchdog_ping_work(struct kthread_work *work)
 {
 	struct watchdog_core_data *wd_data;
 
-	wd_data = container_of(to_delayed_work(work), struct watchdog_core_data,
-			       work);
+	wd_data = container_of(work, struct watchdog_core_data, work);
 
 	mutex_lock(&wd_data->lock);
 	if (watchdog_worker_should_ping(wd_data))
@@ -216,6 +226,16 @@ static void watchdog_ping_work(struct work_struct *work)
 	mutex_unlock(&wd_data->lock);
 }
 
+static enum hrtimer_restart watchdog_timer_expired(struct hrtimer *timer)
+{
+	struct watchdog_core_data *wd_data;
+
+	wd_data = container_of(timer, struct watchdog_core_data, timer);
+
+	kthread_queue_work(watchdog_kworker, &wd_data->work);
+	return HRTIMER_NORESTART;
+}
+
 /*
  *	watchdog_start: wrapper to start the watchdog.
  *	@wdd: the watchdog device to start
@@ -230,7 +250,7 @@ static void watchdog_ping_work(struct work_struct *work)
 static int watchdog_start(struct watchdog_device *wdd)
 {
 	struct watchdog_core_data *wd_data = wdd->wd_data;
-	unsigned long started_at;
+	ktime_t started_at;
 	int err;
 
 	if (watchdog_active(wdd))
@@ -238,7 +258,7 @@ static int watchdog_start(struct watchdog_device *wdd)
 
 	set_bit(_WDOG_KEEPALIVE, &wd_data->status);
 
-	started_at = jiffies;
+	started_at = ktime_get();
 	if (watchdog_hw_running(wdd) && wdd->ops->ping)
 		err = wdd->ops->ping(wdd);
 	else
@@ -720,7 +740,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
 		err = watchdog_ping(wdd);
 		if (err < 0)
 			break;
-		/* Fall */
+		/* fall through */
 	case WDIOC_GETTIMEOUT:
 		/* timeout == 0 means that we don't know the timeout */
 		if (wdd->timeout == 0) {
@@ -769,6 +789,7 @@ static int watchdog_open(struct inode *inode, struct file *file)
 {
 	struct watchdog_core_data *wd_data;
 	struct watchdog_device *wdd;
+	bool hw_running;
 	int err;
 
 	/* Get the corresponding watchdog device */
@@ -788,7 +809,8 @@ static int watchdog_open(struct inode *inode, struct file *file)
 	 * If the /dev/watchdog device is open, we don't want the module
 	 * to be unloaded.
 	 */
-	if (!watchdog_hw_running(wdd) && !try_module_get(wdd->ops->owner)) {
+	hw_running = watchdog_hw_running(wdd);
+	if (!hw_running && !try_module_get(wdd->ops->owner)) {
 		err = -EBUSY;
 		goto out_clear;
 	}
@@ -799,7 +821,7 @@ static int watchdog_open(struct inode *inode, struct file *file)
 
 	file->private_data = wd_data;
 
-	if (!watchdog_hw_running(wdd))
+	if (!hw_running)
 		kref_get(&wd_data->kref);
 
 	/* dev/watchdog is a virtual (and thus non-seekable) filesystem */
@@ -919,10 +941,12 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
 	wd_data->wdd = wdd;
 	wdd->wd_data = wd_data;
 
-	if (!watchdog_wq)
+	if (IS_ERR_OR_NULL(watchdog_kworker))
 		return -ENODEV;
 
-	INIT_DELAYED_WORK(&wd_data->work, watchdog_ping_work);
+	kthread_init_work(&wd_data->work, watchdog_ping_work);
+	hrtimer_init(&wd_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	wd_data->timer.function = watchdog_timer_expired;
 
 	if (wdd->id == 0) {
 		old_wd_data = wd_data;
@@ -958,21 +982,20 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
 	}
 
 	/* Record time of most recent heartbeat as 'just before now'. */
-	wd_data->last_hw_keepalive = jiffies - 1;
+	wd_data->last_hw_keepalive = ktime_sub(ktime_get(), 1);
 
 	/*
 	 * If the watchdog is running, prevent its driver from being unloaded,
 	 * and schedule an immediate ping.
 	 */
 	if (watchdog_hw_running(wdd)) {
-		if (handle_boot_enabled) {
-			__module_get(wdd->ops->owner);
-			kref_get(&wd_data->kref);
-			queue_delayed_work(watchdog_wq, &wd_data->work, 0);
-		} else {
+		__module_get(wdd->ops->owner);
+		kref_get(&wd_data->kref);
+		if (handle_boot_enabled)
+			hrtimer_start(&wd_data->timer, 0, HRTIMER_MODE_REL);
+		else
 			pr_info("watchdog%d running and kernel based pre-userspace handler disabled\n",
-					wdd->id);
-		}
+				wdd->id);
 	}
 
 	return 0;
@@ -1006,7 +1029,8 @@ static void watchdog_cdev_unregister(struct watchdog_device *wdd)
 		watchdog_stop(wdd);
 	}
 
-	cancel_delayed_work_sync(&wd_data->work);
+	hrtimer_cancel(&wd_data->timer);
+	kthread_cancel_work_sync(&wd_data->work);
 
 	kref_put(&wd_data->kref, watchdog_core_data_release);
 }
@@ -1110,13 +1134,14 @@ void watchdog_dev_unregister(struct watchdog_device *wdd)
 int __init watchdog_dev_init(void)
 {
 	int err;
+	struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1,};
 
-	watchdog_wq = alloc_workqueue("watchdogd",
-				      WQ_HIGHPRI | WQ_MEM_RECLAIM, 0);
-	if (!watchdog_wq) {
-		pr_err("Failed to create watchdog workqueue\n");
-		return -ENOMEM;
+	watchdog_kworker = kthread_create_worker(0, "watchdogd");
+	if (IS_ERR(watchdog_kworker)) {
+		pr_err("Failed to create watchdog kworker\n");
+		return PTR_ERR(watchdog_kworker);
 	}
+	sched_setscheduler(watchdog_kworker->task, SCHED_FIFO, &param);
 
 	err = class_register(&watchdog_class);
 	if (err < 0) {
@@ -1135,7 +1160,7 @@ int __init watchdog_dev_init(void)
 err_alloc:
 	class_unregister(&watchdog_class);
 err_register:
-	destroy_workqueue(watchdog_wq);
+	kthread_destroy_worker(watchdog_kworker);
 	return err;
 }
 
@@ -1149,7 +1174,7 @@ void __exit watchdog_dev_exit(void)
 {
 	unregister_chrdev_region(watchdog_devt, MAX_DOGS);
 	class_unregister(&watchdog_class);
-	destroy_workqueue(watchdog_wq);
+	kthread_destroy_worker(watchdog_kworker);
 }
 
 module_param(handle_boot_enabled, bool, 0444);
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index bc7addc..10e2cda0 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -430,7 +430,7 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd,
 		if (wdtpci_set_heartbeat(new_heartbeat))
 			return -EINVAL;
 		wdtpci_ping();
-		/* Fall */
+		/* fall through */
 	case WDIOC_GETTIMEOUT:
 		return put_user(heartbeat, p);
 	default:
diff --git a/drivers/watchdog/xen_wdt.c b/drivers/watchdog/xen_wdt.c
index cf0e650..f1c016d 100644
--- a/drivers/watchdog/xen_wdt.c
+++ b/drivers/watchdog/xen_wdt.c
@@ -9,10 +9,7 @@
  *	2 of the License, or (at your option) any later version.
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define DRV_NAME	"wdt"
-#define DRV_VERSION	"0.01"
+#define DRV_NAME	"xen_wdt"
 
 #include <linux/bug.h>
 #include <linux/errno.h>
@@ -21,25 +18,20 @@
 #include <linux/kernel.h>
 #include <linux/ktime.h>
 #include <linux/init.h>
-#include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/uaccess.h>
 #include <linux/watchdog.h>
 #include <xen/xen.h>
 #include <asm/xen/hypercall.h>
 #include <xen/interface/sched.h>
 
 static struct platform_device *platform_device;
-static DEFINE_SPINLOCK(wdt_lock);
 static struct sched_watchdog wdt;
-static __kernel_time_t wdt_expires;
-static bool is_active, expect_release;
+static time64_t wdt_expires;
 
 #define WATCHDOG_TIMEOUT 60 /* in seconds */
-static unsigned int timeout = WATCHDOG_TIMEOUT;
+static unsigned int timeout;
 module_param(timeout, uint, S_IRUGO);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds "
 	"(default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
@@ -49,20 +41,18 @@ module_param(nowayout, bool, S_IRUGO);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
 	"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
-static inline __kernel_time_t set_timeout(void)
+static inline time64_t set_timeout(struct watchdog_device *wdd)
 {
-	wdt.timeout = timeout;
-	return ktime_to_timespec(ktime_get()).tv_sec + timeout;
+	wdt.timeout = wdd->timeout;
+	return ktime_get_seconds() + wdd->timeout;
 }
 
-static int xen_wdt_start(void)
+static int xen_wdt_start(struct watchdog_device *wdd)
 {
-	__kernel_time_t expires;
+	time64_t expires;
 	int err;
 
-	spin_lock(&wdt_lock);
-
-	expires = set_timeout();
+	expires = set_timeout(wdd);
 	if (!wdt.id)
 		err = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wdt);
 	else
@@ -74,36 +64,28 @@ static int xen_wdt_start(void)
 	} else
 		BUG_ON(!err);
 
-	spin_unlock(&wdt_lock);
-
 	return err;
 }
 
-static int xen_wdt_stop(void)
+static int xen_wdt_stop(struct watchdog_device *wdd)
 {
 	int err = 0;
 
-	spin_lock(&wdt_lock);
-
 	wdt.timeout = 0;
 	if (wdt.id)
 		err = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wdt);
 	if (!err)
 		wdt.id = 0;
 
-	spin_unlock(&wdt_lock);
-
 	return err;
 }
 
-static int xen_wdt_kick(void)
+static int xen_wdt_kick(struct watchdog_device *wdd)
 {
-	__kernel_time_t expires;
+	time64_t expires;
 	int err;
 
-	spin_lock(&wdt_lock);
-
-	expires = set_timeout();
+	expires = set_timeout(wdd);
 	if (wdt.id)
 		err = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wdt);
 	else
@@ -111,195 +93,72 @@ static int xen_wdt_kick(void)
 	if (!err)
 		wdt_expires = expires;
 
-	spin_unlock(&wdt_lock);
-
 	return err;
 }
 
-static int xen_wdt_open(struct inode *inode, struct file *file)
+static unsigned int xen_wdt_get_timeleft(struct watchdog_device *wdd)
 {
-	int err;
-
-	/* /dev/watchdog can only be opened once */
-	if (xchg(&is_active, true))
-		return -EBUSY;
-
-	err = xen_wdt_start();
-	if (err == -EBUSY)
-		err = xen_wdt_kick();
-	return err ?: nonseekable_open(inode, file);
+	return wdt_expires - ktime_get_seconds();
 }
 
-static int xen_wdt_release(struct inode *inode, struct file *file)
-{
-	int err = 0;
-
-	if (expect_release)
-		err = xen_wdt_stop();
-	else {
-		pr_crit("unexpected close, not stopping watchdog!\n");
-		xen_wdt_kick();
-	}
-	is_active = err;
-	expect_release = false;
-	return err;
-}
-
-static ssize_t xen_wdt_write(struct file *file, const char __user *data,
-			     size_t len, loff_t *ppos)
-{
-	/* See if we got the magic character 'V' and reload the timer */
-	if (len) {
-		if (!nowayout) {
-			size_t i;
-
-			/* in case it was set long ago */
-			expect_release = false;
-
-			/* scan to see whether or not we got the magic
-			   character */
-			for (i = 0; i != len; i++) {
-				char c;
-				if (get_user(c, data + i))
-					return -EFAULT;
-				if (c == 'V')
-					expect_release = true;
-			}
-		}
-
-		/* someone wrote to us, we should reload the timer */
-		xen_wdt_kick();
-	}
-	return len;
-}
-
-static long xen_wdt_ioctl(struct file *file, unsigned int cmd,
-			  unsigned long arg)
-{
-	int new_options, retval = -EINVAL;
-	int new_timeout;
-	int __user *argp = (void __user *)arg;
-	static const struct watchdog_info ident = {
-		.options =		WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
-		.firmware_version =	0,
-		.identity =		DRV_NAME,
-	};
-
-	switch (cmd) {
-	case WDIOC_GETSUPPORT:
-		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
-
-	case WDIOC_GETSTATUS:
-	case WDIOC_GETBOOTSTATUS:
-		return put_user(0, argp);
-
-	case WDIOC_SETOPTIONS:
-		if (get_user(new_options, argp))
-			return -EFAULT;
-
-		if (new_options & WDIOS_DISABLECARD)
-			retval = xen_wdt_stop();
-		if (new_options & WDIOS_ENABLECARD) {
-			retval = xen_wdt_start();
-			if (retval == -EBUSY)
-				retval = xen_wdt_kick();
-		}
-		return retval;
-
-	case WDIOC_KEEPALIVE:
-		xen_wdt_kick();
-		return 0;
-
-	case WDIOC_SETTIMEOUT:
-		if (get_user(new_timeout, argp))
-			return -EFAULT;
-		if (!new_timeout)
-			return -EINVAL;
-		timeout = new_timeout;
-		xen_wdt_kick();
-		/* fall through */
-	case WDIOC_GETTIMEOUT:
-		return put_user(timeout, argp);
-
-	case WDIOC_GETTIMELEFT:
-		retval = wdt_expires - ktime_to_timespec(ktime_get()).tv_sec;
-		return put_user(retval, argp);
-	}
-
-	return -ENOTTY;
-}
-
-static const struct file_operations xen_wdt_fops = {
-	.owner =		THIS_MODULE,
-	.llseek =		no_llseek,
-	.write =		xen_wdt_write,
-	.unlocked_ioctl =	xen_wdt_ioctl,
-	.open =			xen_wdt_open,
-	.release =		xen_wdt_release,
+static struct watchdog_info xen_wdt_info = {
+	.identity = DRV_NAME,
+	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
 };
 
-static struct miscdevice xen_wdt_miscdev = {
-	.minor =	WATCHDOG_MINOR,
-	.name =		"watchdog",
-	.fops =		&xen_wdt_fops,
+static const struct watchdog_ops xen_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = xen_wdt_start,
+	.stop = xen_wdt_stop,
+	.ping = xen_wdt_kick,
+	.get_timeleft = xen_wdt_get_timeleft,
 };
 
-static int xen_wdt_probe(struct platform_device *dev)
+static struct watchdog_device xen_wdt_dev = {
+	.info = &xen_wdt_info,
+	.ops = &xen_wdt_ops,
+	.timeout = WATCHDOG_TIMEOUT,
+};
+
+static int xen_wdt_probe(struct platform_device *pdev)
 {
 	struct sched_watchdog wd = { .id = ~0 };
 	int ret = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wd);
 
-	switch (ret) {
-	case -EINVAL:
-		if (!timeout) {
-			timeout = WATCHDOG_TIMEOUT;
-			pr_info("timeout value invalid, using %d\n", timeout);
-		}
-
-		ret = misc_register(&xen_wdt_miscdev);
-		if (ret) {
-			pr_err("cannot register miscdev on minor=%d (%d)\n",
-			       WATCHDOG_MINOR, ret);
-			break;
-		}
-
-		pr_info("initialized (timeout=%ds, nowayout=%d)\n",
-			timeout, nowayout);
-		break;
-
-	case -ENOSYS:
-		pr_info("not supported\n");
-		ret = -ENODEV;
-		break;
-
-	default:
-		pr_info("bogus return value %d\n", ret);
-		break;
+	if (ret == -ENOSYS) {
+		dev_err(&pdev->dev, "watchdog not supported by hypervisor\n");
+		return -ENODEV;
 	}
 
-	return ret;
-}
+	if (ret != -EINVAL) {
+		dev_err(&pdev->dev, "unexpected hypervisor error (%d)\n", ret);
+		return -ENODEV;
+	}
 
-static int xen_wdt_remove(struct platform_device *dev)
-{
-	/* Stop the timer before we leave */
-	if (!nowayout)
-		xen_wdt_stop();
+	if (watchdog_init_timeout(&xen_wdt_dev, timeout, NULL))
+		dev_info(&pdev->dev, "timeout value invalid, using %d\n",
+			xen_wdt_dev.timeout);
+	watchdog_set_nowayout(&xen_wdt_dev, nowayout);
+	watchdog_stop_on_reboot(&xen_wdt_dev);
+	watchdog_stop_on_unregister(&xen_wdt_dev);
 
-	misc_deregister(&xen_wdt_miscdev);
+	ret = devm_watchdog_register_device(&pdev->dev, &xen_wdt_dev);
+	if (ret) {
+		dev_err(&pdev->dev, "cannot register watchdog device (%d)\n",
+			ret);
+		return ret;
+	}
+
+	dev_info(&pdev->dev, "initialized (timeout=%ds, nowayout=%d)\n",
+		xen_wdt_dev.timeout, nowayout);
 
 	return 0;
 }
 
-static void xen_wdt_shutdown(struct platform_device *dev)
-{
-	xen_wdt_stop();
-}
-
 static int xen_wdt_suspend(struct platform_device *dev, pm_message_t state)
 {
 	typeof(wdt.id) id = wdt.id;
-	int rc = xen_wdt_stop();
+	int rc = xen_wdt_stop(&xen_wdt_dev);
 
 	wdt.id = id;
 	return rc;
@@ -310,13 +169,11 @@ static int xen_wdt_resume(struct platform_device *dev)
 	if (!wdt.id)
 		return 0;
 	wdt.id = 0;
-	return xen_wdt_start();
+	return xen_wdt_start(&xen_wdt_dev);
 }
 
 static struct platform_driver xen_wdt_driver = {
 	.probe          = xen_wdt_probe,
-	.remove         = xen_wdt_remove,
-	.shutdown       = xen_wdt_shutdown,
 	.suspend        = xen_wdt_suspend,
 	.resume         = xen_wdt_resume,
 	.driver         = {
@@ -331,8 +188,6 @@ static int __init xen_wdt_init_module(void)
 	if (!xen_domain())
 		return -ENODEV;
 
-	pr_info("Xen WatchDog Timer Driver v%s\n", DRV_VERSION);
-
 	err = platform_driver_register(&xen_wdt_driver);
 	if (err)
 		return err;
@@ -351,7 +206,6 @@ static void __exit xen_wdt_cleanup_module(void)
 {
 	platform_device_unregister(platform_device);
 	platform_driver_unregister(&xen_wdt_driver);
-	pr_info("module unloaded\n");
 }
 
 module_init(xen_wdt_init_module);
@@ -359,5 +213,4 @@ module_exit(xen_wdt_cleanup_module);
 
 MODULE_AUTHOR("Jan Beulich <jbeulich@novell.com>");
 MODULE_DESCRIPTION("Xen WatchDog Timer Driver");
-MODULE_VERSION(DRV_VERSION);
 MODULE_LICENSE("GPL");
diff --git a/fs/Kconfig b/fs/Kconfig
index 9774588..bc821a8 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -58,6 +58,13 @@
 	depends on ZONE_DEVICE
 	depends on TRANSPARENT_HUGEPAGE
 
+# Selected by DAX drivers that do not expect filesystem DAX to support
+# get_user_pages() of DAX mappings. I.e. "limited" indicates no support
+# for fork() of processes with MAP_SHARED mappings or support for
+# direct-I/O to a DAX mapping.
+config FS_DAX_LIMITED
+	bool
+
 endif # BLOCK
 
 # Posix ACL utility routines
diff --git a/fs/affs/dir.c b/fs/affs/dir.c
index d180b46..b2bf701 100644
--- a/fs/affs/dir.c
+++ b/fs/affs/dir.c
@@ -81,7 +81,7 @@ affs_readdir(struct file *file, struct dir_context *ctx)
 	 * we can jump directly to where we left off.
 	 */
 	ino = (u32)(long)file->private_data;
-	if (ino && inode_cmp_iversion(inode, file->f_version) == 0) {
+	if (ino && inode_eq_iversion(inode, file->f_version)) {
 		pr_debug("readdir() left off=%d\n", ino);
 		goto inside;
 	}
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 83732fe..bdb2012 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1599,6 +1599,8 @@ static int fill_files_note(struct memelfnote *note)
 
 	/* *Estimated* file count and total data size needed */
 	count = current->mm->map_count;
+	if (count > UINT_MAX / 64)
+		return -EINVAL;
 	size = count * 64;
 
 	names_ofs = (2 + 3 * count) * sizeof(data[0]);
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index dbf0705..b4336b4 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -299,7 +299,8 @@ static void finish_read(struct ceph_osd_request *req)
  * start an async read(ahead) operation.  return nr_pages we submitted
  * a read for on success, or negative error code.
  */
-static int start_read(struct inode *inode, struct list_head *page_list, int max)
+static int start_read(struct inode *inode, struct ceph_rw_context *rw_ctx,
+		      struct list_head *page_list, int max)
 {
 	struct ceph_osd_client *osdc =
 		&ceph_inode_to_client(inode)->client->osdc;
@@ -316,7 +317,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
 	int got = 0;
 	int ret = 0;
 
-	if (!current->journal_info) {
+	if (!rw_ctx) {
 		/* caller of readpages does not hold buffer and read caps
 		 * (fadvise, madvise and readahead cases) */
 		int want = CEPH_CAP_FILE_CACHE;
@@ -437,6 +438,8 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
 {
 	struct inode *inode = file_inode(file);
 	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
+	struct ceph_file_info *ci = file->private_data;
+	struct ceph_rw_context *rw_ctx;
 	int rc = 0;
 	int max = 0;
 
@@ -449,11 +452,12 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
 	if (rc == 0)
 		goto out;
 
+	rw_ctx = ceph_find_rw_context(ci);
 	max = fsc->mount_options->rsize >> PAGE_SHIFT;
-	dout("readpages %p file %p nr_pages %d max %d\n",
-	     inode, file, nr_pages, max);
+	dout("readpages %p file %p ctx %p nr_pages %d max %d\n",
+	     inode, file, rw_ctx, nr_pages, max);
 	while (!list_empty(page_list)) {
-		rc = start_read(inode, page_list, max);
+		rc = start_read(inode, rw_ctx, page_list, max);
 		if (rc < 0)
 			goto out;
 	}
@@ -574,7 +578,6 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
 	struct ceph_fs_client *fsc;
 	struct ceph_snap_context *snapc, *oldest;
 	loff_t page_off = page_offset(page);
-	long writeback_stat;
 	int err, len = PAGE_SIZE;
 	struct ceph_writeback_ctl ceph_wbc;
 
@@ -615,8 +618,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
 	dout("writepage %p page %p index %lu on %llu~%u snapc %p seq %lld\n",
 	     inode, page, page->index, page_off, len, snapc, snapc->seq);
 
-	writeback_stat = atomic_long_inc_return(&fsc->writeback_count);
-	if (writeback_stat >
+	if (atomic_long_inc_return(&fsc->writeback_count) >
 	    CONGESTION_ON_THRESH(fsc->mount_options->congestion_kb))
 		set_bdi_congested(inode_to_bdi(inode), BLK_RW_ASYNC);
 
@@ -651,6 +653,11 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
 	end_page_writeback(page);
 	ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
 	ceph_put_snap_context(snapc);  /* page's reference */
+
+	if (atomic_long_dec_return(&fsc->writeback_count) <
+	    CONGESTION_OFF_THRESH(fsc->mount_options->congestion_kb))
+		clear_bdi_congested(inode_to_bdi(inode), BLK_RW_ASYNC);
+
 	return err;
 }
 
@@ -1450,9 +1457,10 @@ static int ceph_filemap_fault(struct vm_fault *vmf)
 
 	if ((got & (CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO)) ||
 	    ci->i_inline_version == CEPH_INLINE_NONE) {
-		current->journal_info = vma->vm_file;
+		CEPH_DEFINE_RW_CONTEXT(rw_ctx, got);
+		ceph_add_rw_context(fi, &rw_ctx);
 		ret = filemap_fault(vmf);
-		current->journal_info = NULL;
+		ceph_del_rw_context(fi, &rw_ctx);
 	} else
 		ret = -EAGAIN;
 
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index a14b2c9..6582c45 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -154,13 +154,19 @@ void ceph_adjust_min_caps(struct ceph_mds_client *mdsc, int delta)
 	spin_unlock(&mdsc->caps_list_lock);
 }
 
-void ceph_reserve_caps(struct ceph_mds_client *mdsc,
+/*
+ * Called under mdsc->mutex.
+ */
+int ceph_reserve_caps(struct ceph_mds_client *mdsc,
 		      struct ceph_cap_reservation *ctx, int need)
 {
-	int i;
+	int i, j;
 	struct ceph_cap *cap;
 	int have;
 	int alloc = 0;
+	int max_caps;
+	bool trimmed = false;
+	struct ceph_mds_session *s;
 	LIST_HEAD(newcaps);
 
 	dout("reserve caps ctx=%p need=%d\n", ctx, need);
@@ -179,16 +185,37 @@ void ceph_reserve_caps(struct ceph_mds_client *mdsc,
 	spin_unlock(&mdsc->caps_list_lock);
 
 	for (i = have; i < need; i++) {
+retry:
 		cap = kmem_cache_alloc(ceph_cap_cachep, GFP_NOFS);
-		if (!cap)
-			break;
+		if (!cap) {
+			if (!trimmed) {
+				for (j = 0; j < mdsc->max_sessions; j++) {
+					s = __ceph_lookup_mds_session(mdsc, j);
+					if (!s)
+						continue;
+					mutex_unlock(&mdsc->mutex);
+
+					mutex_lock(&s->s_mutex);
+					max_caps = s->s_nr_caps - (need - i);
+					ceph_trim_caps(mdsc, s, max_caps);
+					mutex_unlock(&s->s_mutex);
+
+					ceph_put_mds_session(s);
+					mutex_lock(&mdsc->mutex);
+				}
+				trimmed = true;
+				goto retry;
+			} else {
+				pr_warn("reserve caps ctx=%p ENOMEM "
+					"need=%d got=%d\n",
+					ctx, need, have + alloc);
+				goto out_nomem;
+			}
+		}
 		list_add(&cap->caps_item, &newcaps);
 		alloc++;
 	}
-	/* we didn't manage to reserve as much as we needed */
-	if (have + alloc != need)
-		pr_warn("reserve caps ctx=%p ENOMEM need=%d got=%d\n",
-			ctx, need, have + alloc);
+	BUG_ON(have + alloc != need);
 
 	spin_lock(&mdsc->caps_list_lock);
 	mdsc->caps_total_count += alloc;
@@ -204,6 +231,24 @@ void ceph_reserve_caps(struct ceph_mds_client *mdsc,
 	dout("reserve caps ctx=%p %d = %d used + %d resv + %d avail\n",
 	     ctx, mdsc->caps_total_count, mdsc->caps_use_count,
 	     mdsc->caps_reserve_count, mdsc->caps_avail_count);
+	return 0;
+
+out_nomem:
+	while (!list_empty(&newcaps)) {
+		cap = list_first_entry(&newcaps,
+				struct ceph_cap, caps_item);
+		list_del(&cap->caps_item);
+		kmem_cache_free(ceph_cap_cachep, cap);
+	}
+
+	spin_lock(&mdsc->caps_list_lock);
+	mdsc->caps_avail_count += have;
+	mdsc->caps_reserve_count -= have;
+	BUG_ON(mdsc->caps_total_count != mdsc->caps_use_count +
+					 mdsc->caps_reserve_count +
+					 mdsc->caps_avail_count);
+	spin_unlock(&mdsc->caps_list_lock);
+	return -ENOMEM;
 }
 
 int ceph_unreserve_caps(struct ceph_mds_client *mdsc,
@@ -498,7 +543,7 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
 	 */
 	if ((issued & CEPH_CAP_FILE_SHARED) != (had & CEPH_CAP_FILE_SHARED)) {
 		if (issued & CEPH_CAP_FILE_SHARED)
-			ci->i_shared_gen++;
+			atomic_inc(&ci->i_shared_gen);
 		if (S_ISDIR(ci->vfs_inode.i_mode)) {
 			dout(" marking %p NOT complete\n", &ci->vfs_inode);
 			__ceph_dir_clear_complete(ci);
@@ -577,18 +622,30 @@ void ceph_add_cap(struct inode *inode,
 		}
 	}
 
-	if (!ci->i_snap_realm) {
+	if (!ci->i_snap_realm ||
+	    ((flags & CEPH_CAP_FLAG_AUTH) &&
+	     realmino != (u64)-1 && ci->i_snap_realm->ino != realmino)) {
 		/*
 		 * add this inode to the appropriate snap realm
 		 */
 		struct ceph_snap_realm *realm = ceph_lookup_snap_realm(mdsc,
 							       realmino);
 		if (realm) {
+			struct ceph_snap_realm *oldrealm = ci->i_snap_realm;
+			if (oldrealm) {
+				spin_lock(&oldrealm->inodes_with_caps_lock);
+				list_del_init(&ci->i_snap_realm_item);
+				spin_unlock(&oldrealm->inodes_with_caps_lock);
+			}
+
 			spin_lock(&realm->inodes_with_caps_lock);
 			ci->i_snap_realm = realm;
 			list_add(&ci->i_snap_realm_item,
 				 &realm->inodes_with_caps);
 			spin_unlock(&realm->inodes_with_caps_lock);
+
+			if (oldrealm)
+				ceph_put_snap_realm(mdsc, oldrealm);
 		} else {
 			pr_err("ceph_add_cap: couldn't find snap realm %llx\n",
 			       realmino);
@@ -890,6 +947,11 @@ int __ceph_caps_mds_wanted(struct ceph_inode_info *ci, bool check)
 /*
  * called under i_ceph_lock
  */
+static int __ceph_is_single_caps(struct ceph_inode_info *ci)
+{
+	return rb_first(&ci->i_caps) == rb_last(&ci->i_caps);
+}
+
 static int __ceph_is_any_caps(struct ceph_inode_info *ci)
 {
 	return !RB_EMPTY_ROOT(&ci->i_caps);
@@ -1703,21 +1765,24 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
 	int mds = -1;   /* keep track of how far we've gone through i_caps list
 			   to avoid an infinite loop on retry */
 	struct rb_node *p;
-	int delayed = 0, sent = 0, num;
-	bool is_delayed = flags & CHECK_CAPS_NODELAY;
+	int delayed = 0, sent = 0;
+	bool no_delay = flags & CHECK_CAPS_NODELAY;
 	bool queue_invalidate = false;
-	bool force_requeue = false;
 	bool tried_invalidate = false;
 
 	/* if we are unmounting, flush any unused caps immediately. */
 	if (mdsc->stopping)
-		is_delayed = true;
+		no_delay = true;
 
 	spin_lock(&ci->i_ceph_lock);
 
 	if (ci->i_ceph_flags & CEPH_I_FLUSH)
 		flags |= CHECK_CAPS_FLUSH;
 
+	if (!(flags & CHECK_CAPS_AUTHONLY) ||
+	    (ci->i_auth_cap && __ceph_is_single_caps(ci)))
+		__cap_delay_cancel(mdsc, ci);
+
 	goto retry_locked;
 retry:
 	spin_lock(&ci->i_ceph_lock);
@@ -1772,7 +1837,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
 	 * have cached pages, but don't want them, then try to invalidate.
 	 * If we fail, it's because pages are locked.... try again later.
 	 */
-	if ((!is_delayed || mdsc->stopping) &&
+	if ((!no_delay || mdsc->stopping) &&
 	    !S_ISDIR(inode->i_mode) &&		/* ignore readdir cache */
 	    !(ci->i_wb_ref || ci->i_wrbuffer_ref) &&   /* no dirty pages... */
 	    inode->i_data.nrpages &&		/* have cached pages */
@@ -1781,27 +1846,16 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
 	    !tried_invalidate) {
 		dout("check_caps trying to invalidate on %p\n", inode);
 		if (try_nonblocking_invalidate(inode) < 0) {
-			if (revoking & (CEPH_CAP_FILE_CACHE|
-					CEPH_CAP_FILE_LAZYIO)) {
-				dout("check_caps queuing invalidate\n");
-				queue_invalidate = true;
-				ci->i_rdcache_revoking = ci->i_rdcache_gen;
-			} else {
-				dout("check_caps failed to invalidate pages\n");
-				/* we failed to invalidate pages.  check these
-				   caps again later. */
-				force_requeue = true;
-				__cap_set_timeouts(mdsc, ci);
-			}
+			dout("check_caps queuing invalidate\n");
+			queue_invalidate = true;
+			ci->i_rdcache_revoking = ci->i_rdcache_gen;
 		}
 		tried_invalidate = true;
 		goto retry_locked;
 	}
 
-	num = 0;
 	for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
 		cap = rb_entry(p, struct ceph_cap, ci_node);
-		num++;
 
 		/* avoid looping forever */
 		if (mds >= cap->mds ||
@@ -1864,7 +1918,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
 		    cap->mds_wanted == want)
 			continue;     /* nope, all good */
 
-		if (is_delayed)
+		if (no_delay)
 			goto ack;
 
 		/* delay? */
@@ -1955,15 +2009,8 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
 		goto retry; /* retake i_ceph_lock and restart our cap scan. */
 	}
 
-	/*
-	 * Reschedule delayed caps release if we delayed anything,
-	 * otherwise cancel.
-	 */
-	if (delayed && is_delayed)
-		force_requeue = true;   /* __send_cap delayed release; requeue */
-	if (!delayed && !is_delayed)
-		__cap_delay_cancel(mdsc, ci);
-	else if (!is_delayed || force_requeue)
+	/* Reschedule delayed caps release if we delayed anything */
+	if (delayed)
 		__cap_delay_requeue(mdsc, ci);
 
 	spin_unlock(&ci->i_ceph_lock);
@@ -2160,7 +2207,7 @@ int ceph_write_inode(struct inode *inode, struct writeback_control *wbc)
 	u64 flush_tid;
 	int err = 0;
 	int dirty;
-	int wait = wbc->sync_mode == WB_SYNC_ALL;
+	int wait = (wbc->sync_mode == WB_SYNC_ALL && !wbc->for_sync);
 
 	dout("write_inode %p wait=%d\n", inode, wait);
 	if (wait) {
@@ -3426,7 +3473,14 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex,
 	 */
 
 	issued = cap->issued;
-	WARN_ON(issued != cap->implemented);
+	if (issued != cap->implemented)
+		pr_err_ratelimited("handle_cap_export: issued != implemented: "
+				"ino (%llx.%llx) mds%d seq %d mseq %d "
+				"issued %s implemented %s\n",
+				ceph_vinop(inode), mds, cap->seq, cap->mseq,
+				ceph_cap_string(issued),
+				ceph_cap_string(cap->implemented));
+
 
 	tcap = __get_cap_for_mds(ci, target);
 	if (tcap) {
@@ -3572,12 +3626,13 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
 		if ((ph->flags & CEPH_CAP_FLAG_AUTH) &&
 		    (ocap->seq != le32_to_cpu(ph->seq) ||
 		     ocap->mseq != le32_to_cpu(ph->mseq))) {
-			pr_err("handle_cap_import: mismatched seq/mseq: "
-			       "ino (%llx.%llx) mds%d seq %d mseq %d "
-			       "importer mds%d has peer seq %d mseq %d\n",
-			       ceph_vinop(inode), peer, ocap->seq,
-			       ocap->mseq, mds, le32_to_cpu(ph->seq),
-			       le32_to_cpu(ph->mseq));
+			pr_err_ratelimited("handle_cap_import: "
+					"mismatched seq/mseq: ino (%llx.%llx) "
+					"mds%d seq %d mseq %d importer mds%d "
+					"has peer seq %d mseq %d\n",
+					ceph_vinop(inode), peer, ocap->seq,
+					ocap->mseq, mds, le32_to_cpu(ph->seq),
+					le32_to_cpu(ph->mseq));
 		}
 		__ceph_remove_cap(ocap, (ph->flags & CEPH_CAP_FLAG_RELEASE));
 	}
@@ -3939,11 +3994,20 @@ int ceph_encode_inode_release(void **p, struct inode *inode,
 
 	cap = __get_cap_for_mds(ci, mds);
 	if (cap && __cap_is_valid(cap)) {
-		if (force ||
-		    ((cap->issued & drop) &&
-		     (cap->issued & unless) == 0)) {
-			if ((cap->issued & drop) &&
-			    (cap->issued & unless) == 0) {
+		unless &= cap->issued;
+		if (unless) {
+			if (unless & CEPH_CAP_AUTH_EXCL)
+				drop &= ~CEPH_CAP_AUTH_SHARED;
+			if (unless & CEPH_CAP_LINK_EXCL)
+				drop &= ~CEPH_CAP_LINK_SHARED;
+			if (unless & CEPH_CAP_XATTR_EXCL)
+				drop &= ~CEPH_CAP_XATTR_SHARED;
+			if (unless & CEPH_CAP_FILE_EXCL)
+				drop &= ~CEPH_CAP_FILE_SHARED;
+		}
+
+		if (force || (cap->issued & drop)) {
+			if (cap->issued & drop) {
 				int wanted = __ceph_caps_wanted(ci);
 				if ((ci->i_ceph_flags & CEPH_I_NODELAY) == 0)
 					wanted |= cap->mds_wanted;
@@ -3975,7 +4039,7 @@ int ceph_encode_inode_release(void **p, struct inode *inode,
 			*p += sizeof(*rel);
 			ret = 1;
 		} else {
-			dout("encode_inode_release %p cap %p %s\n",
+			dout("encode_inode_release %p cap %p %s (noop)\n",
 			     inode, cap, ceph_cap_string(cap->issued));
 		}
 	}
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 8a52666..0c43468 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -173,7 +173,7 @@ __dcache_find_get_entry(struct dentry *parent, u64 idx,
  * the MDS if/when the directory is modified).
  */
 static int __dcache_readdir(struct file *file,  struct dir_context *ctx,
-			    u32 shared_gen)
+			    int shared_gen)
 {
 	struct ceph_file_info *fi = file->private_data;
 	struct dentry *parent = file->f_path.dentry;
@@ -184,7 +184,7 @@ static int __dcache_readdir(struct file *file,  struct dir_context *ctx,
 	u64 idx = 0;
 	int err = 0;
 
-	dout("__dcache_readdir %p v%u at %llx\n", dir, shared_gen, ctx->pos);
+	dout("__dcache_readdir %p v%u at %llx\n", dir, (unsigned)shared_gen, ctx->pos);
 
 	/* search start position */
 	if (ctx->pos > 2) {
@@ -231,11 +231,17 @@ static int __dcache_readdir(struct file *file,  struct dir_context *ctx,
 			goto out;
 		}
 
-		di = ceph_dentry(dentry);
 		spin_lock(&dentry->d_lock);
-		if (di->lease_shared_gen == shared_gen &&
-		    d_really_is_positive(dentry) &&
-		    fpos_cmp(ctx->pos, di->offset) <= 0) {
+		di = ceph_dentry(dentry);
+		if (d_unhashed(dentry) ||
+		    d_really_is_negative(dentry) ||
+		    di->lease_shared_gen != shared_gen) {
+			spin_unlock(&dentry->d_lock);
+			dput(dentry);
+			err = -EAGAIN;
+			goto out;
+		}
+		if (fpos_cmp(ctx->pos, di->offset) <= 0) {
 			emit_dentry = true;
 		}
 		spin_unlock(&dentry->d_lock);
@@ -333,7 +339,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
 	    ceph_snap(inode) != CEPH_SNAPDIR &&
 	    __ceph_dir_is_complete_ordered(ci) &&
 	    __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1)) {
-		u32 shared_gen = ci->i_shared_gen;
+		int shared_gen = atomic_read(&ci->i_shared_gen);
 		spin_unlock(&ci->i_ceph_lock);
 		err = __dcache_readdir(file, ctx, shared_gen);
 		if (err != -EAGAIN)
@@ -381,6 +387,7 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
 		if (op == CEPH_MDS_OP_READDIR) {
 			req->r_direct_hash = ceph_frag_value(frag);
 			__set_bit(CEPH_MDS_R_DIRECT_IS_HASH, &req->r_req_flags);
+			req->r_inode_drop = CEPH_CAP_FILE_EXCL;
 		}
 		if (fi->last_name) {
 			req->r_path2 = kstrdup(fi->last_name, GFP_KERNEL);
@@ -750,7 +757,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
 			spin_unlock(&ci->i_ceph_lock);
 			dout(" dir %p complete, -ENOENT\n", dir);
 			d_add(dentry, NULL);
-			di->lease_shared_gen = ci->i_shared_gen;
+			di->lease_shared_gen = atomic_read(&ci->i_shared_gen);
 			return NULL;
 		}
 		spin_unlock(&ci->i_ceph_lock);
@@ -835,7 +842,7 @@ static int ceph_mknod(struct inode *dir, struct dentry *dentry,
 	set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
 	req->r_args.mknod.mode = cpu_to_le32(mode);
 	req->r_args.mknod.rdev = cpu_to_le32(rdev);
-	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+	req->r_dentry_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_AUTH_EXCL;
 	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
 	if (acls.pagelist) {
 		req->r_pagelist = acls.pagelist;
@@ -887,7 +894,7 @@ static int ceph_symlink(struct inode *dir, struct dentry *dentry,
 	set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
 	req->r_dentry = dget(dentry);
 	req->r_num_caps = 2;
-	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+	req->r_dentry_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_AUTH_EXCL;
 	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
 	err = ceph_mdsc_do_request(mdsc, dir, req);
 	if (!err && !req->r_reply_info.head->is_dentry)
@@ -936,7 +943,7 @@ static int ceph_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 	req->r_parent = dir;
 	set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags);
 	req->r_args.mkdir.mode = cpu_to_le32(mode);
-	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+	req->r_dentry_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_AUTH_EXCL;
 	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
 	if (acls.pagelist) {
 		req->r_pagelist = acls.pagelist;
@@ -983,7 +990,7 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
 	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
 	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
 	/* release LINK_SHARED on source inode (mds will lock it) */
-	req->r_old_inode_drop = CEPH_CAP_LINK_SHARED;
+	req->r_old_inode_drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
 	err = ceph_mdsc_do_request(mdsc, dir, req);
 	if (err) {
 		d_drop(dentry);
@@ -1096,7 +1103,7 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
 	req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
 	req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
 	/* release LINK_RDCACHE on source inode (mds will lock it) */
-	req->r_old_inode_drop = CEPH_CAP_LINK_SHARED;
+	req->r_old_inode_drop = CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL;
 	if (d_really_is_positive(new_dentry))
 		req->r_inode_drop = drop_caps_for_unlink(d_inode(new_dentry));
 	err = ceph_mdsc_do_request(mdsc, old_dir, req);
@@ -1106,16 +1113,7 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
 		 * do_request, above).  If there is no trace, we need
 		 * to do it here.
 		 */
-
-		/* d_move screws up sibling dentries' offsets */
-		ceph_dir_clear_complete(old_dir);
-		ceph_dir_clear_complete(new_dir);
-
 		d_move(old_dentry, new_dentry);
-
-		/* ensure target dentry is invalidated, despite
-		   rehashing bug in vfs_rename_dir */
-		ceph_invalidate_dentry_lease(new_dentry);
 	}
 	ceph_mdsc_put_request(req);
 	return err;
@@ -1199,12 +1197,12 @@ static int dir_lease_is_valid(struct inode *dir, struct dentry *dentry)
 	int valid = 0;
 
 	spin_lock(&ci->i_ceph_lock);
-	if (ci->i_shared_gen == di->lease_shared_gen)
+	if (atomic_read(&ci->i_shared_gen) == di->lease_shared_gen)
 		valid = __ceph_caps_issued_mask(ci, CEPH_CAP_FILE_SHARED, 1);
 	spin_unlock(&ci->i_ceph_lock);
 	dout("dir_lease_is_valid dir %p v%u dentry %p v%u = %d\n",
-	     dir, (unsigned)ci->i_shared_gen, dentry,
-	     (unsigned)di->lease_shared_gen, valid);
+	     dir, (unsigned)atomic_read(&ci->i_shared_gen),
+	     dentry, (unsigned)di->lease_shared_gen, valid);
 	return valid;
 }
 
@@ -1332,24 +1330,37 @@ static void ceph_d_release(struct dentry *dentry)
  */
 static void ceph_d_prune(struct dentry *dentry)
 {
-	dout("ceph_d_prune %p\n", dentry);
+	struct ceph_inode_info *dir_ci;
+	struct ceph_dentry_info *di;
+
+	dout("ceph_d_prune %pd %p\n", dentry, dentry);
 
 	/* do we have a valid parent? */
 	if (IS_ROOT(dentry))
 		return;
 
-	/* if we are not hashed, we don't affect dir's completeness */
-	if (d_unhashed(dentry))
+	/* we hold d_lock, so d_parent is stable */
+	dir_ci = ceph_inode(d_inode(dentry->d_parent));
+	if (dir_ci->i_vino.snap == CEPH_SNAPDIR)
 		return;
 
-	if (ceph_snap(d_inode(dentry->d_parent)) == CEPH_SNAPDIR)
+	/* who calls d_delete() should also disable dcache readdir */
+	if (d_really_is_negative(dentry))
 		return;
 
-	/*
-	 * we hold d_lock, so d_parent is stable, and d_fsdata is never
-	 * cleared until d_release
-	 */
-	ceph_dir_clear_complete(d_inode(dentry->d_parent));
+	/* d_fsdata does not get cleared until d_release */
+	if (!d_unhashed(dentry)) {
+		__ceph_dir_clear_complete(dir_ci);
+		return;
+	}
+
+	/* Disable dcache readdir just in case that someone called d_drop()
+	 * or d_invalidate(), but MDS didn't revoke CEPH_CAP_FILE_SHARED
+	 * properly (dcache readdir is still enabled) */
+	di = ceph_dentry(dentry);
+	if (di->offset > 0 &&
+	    di->lease_shared_gen == atomic_read(&dir_ci->i_shared_gen))
+		__ceph_dir_clear_ordered(dir_ci);
 }
 
 /*
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 5c17125f..6639926 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -181,6 +181,10 @@ static int ceph_init_file(struct inode *inode, struct file *file, int fmode)
 			return -ENOMEM;
 		}
 		cf->fmode = fmode;
+
+		spin_lock_init(&cf->rw_contexts_lock);
+		INIT_LIST_HEAD(&cf->rw_contexts);
+
 		cf->next_offset = 2;
 		cf->readdir_cache_idx = -1;
 		file->private_data = cf;
@@ -396,7 +400,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
 	req->r_dentry = dget(dentry);
 	req->r_num_caps = 2;
 	if (flags & O_CREAT) {
-		req->r_dentry_drop = CEPH_CAP_FILE_SHARED;
+		req->r_dentry_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_AUTH_EXCL;
 		req->r_dentry_unless = CEPH_CAP_FILE_EXCL;
 		if (acls.pagelist) {
 			req->r_pagelist = acls.pagelist;
@@ -464,6 +468,7 @@ int ceph_release(struct inode *inode, struct file *file)
 		ceph_mdsc_put_request(cf->last_readdir);
 	kfree(cf->last_name);
 	kfree(cf->dir_info);
+	WARN_ON(!list_empty(&cf->rw_contexts));
 	kmem_cache_free(ceph_file_cachep, cf);
 
 	/* wake up anyone waiting for caps on this inode */
@@ -1199,12 +1204,13 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)
 			retry_op = READ_INLINE;
 		}
 	} else {
+		CEPH_DEFINE_RW_CONTEXT(rw_ctx, got);
 		dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n",
 		     inode, ceph_vinop(inode), iocb->ki_pos, (unsigned)len,
 		     ceph_cap_string(got));
-		current->journal_info = filp;
+		ceph_add_rw_context(fi, &rw_ctx);
 		ret = generic_file_read_iter(iocb, to);
-		current->journal_info = NULL;
+		ceph_del_rw_context(fi, &rw_ctx);
 	}
 	dout("aio_read %p %llx.%llx dropping cap refs on %s = %d\n",
 	     inode, ceph_vinop(inode), ceph_cap_string(got), (int)ret);
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index ab81652..c6ec5aa 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -494,7 +494,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
 	ci->i_wrbuffer_ref = 0;
 	ci->i_wrbuffer_ref_head = 0;
 	atomic_set(&ci->i_filelock_ref, 0);
-	ci->i_shared_gen = 0;
+	atomic_set(&ci->i_shared_gen, 0);
 	ci->i_rdcache_gen = 0;
 	ci->i_rdcache_revoking = 0;
 
@@ -1041,7 +1041,7 @@ static void update_dentry_lease(struct dentry *dentry,
 	if (ceph_snap(dir) != CEPH_NOSNAP)
 		goto out_unlock;
 
-	di->lease_shared_gen = ceph_inode(dir)->i_shared_gen;
+	di->lease_shared_gen = atomic_read(&ceph_inode(dir)->i_shared_gen);
 
 	if (duration == 0)
 		goto out_unlock;
@@ -1080,6 +1080,27 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in)
 
 	BUG_ON(d_inode(dn));
 
+	if (S_ISDIR(in->i_mode)) {
+		/* If inode is directory, d_splice_alias() below will remove
+		 * 'realdn' from its origin parent. We need to ensure that
+		 * origin parent's readdir cache will not reference 'realdn'
+		 */
+		realdn = d_find_any_alias(in);
+		if (realdn) {
+			struct ceph_dentry_info *di = ceph_dentry(realdn);
+			spin_lock(&realdn->d_lock);
+
+			realdn->d_op->d_prune(realdn);
+
+			di->time = jiffies;
+			di->lease_shared_gen = 0;
+			di->offset = 0;
+
+			spin_unlock(&realdn->d_lock);
+			dput(realdn);
+		}
+	}
+
 	/* dn must be unhashed */
 	if (!d_unhashed(dn))
 		d_drop(dn);
@@ -1295,8 +1316,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req)
 		if (!rinfo->head->is_target) {
 			dout("fill_trace null dentry\n");
 			if (d_really_is_positive(dn)) {
-				ceph_dir_clear_ordered(dir);
 				dout("d_delete %p\n", dn);
+				ceph_dir_clear_ordered(dir);
 				d_delete(dn);
 			} else if (have_lease) {
 				if (d_unhashed(dn))
@@ -1323,7 +1344,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req)
 			dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
 			     dn, d_inode(dn), ceph_vinop(d_inode(dn)),
 			     ceph_vinop(in));
-			ceph_dir_clear_ordered(dir);
 			d_invalidate(dn);
 			have_lease = false;
 		}
@@ -1573,9 +1593,19 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
 		} else if (d_really_is_positive(dn) &&
 			   (ceph_ino(d_inode(dn)) != tvino.ino ||
 			    ceph_snap(d_inode(dn)) != tvino.snap)) {
+			struct ceph_dentry_info *di = ceph_dentry(dn);
 			dout(" dn %p points to wrong inode %p\n",
 			     dn, d_inode(dn));
-			__ceph_dir_clear_ordered(ci);
+
+			spin_lock(&dn->d_lock);
+			if (di->offset > 0 &&
+			    di->lease_shared_gen ==
+			    atomic_read(&ci->i_shared_gen)) {
+				__ceph_dir_clear_ordered(ci);
+				di->offset = 0;
+			}
+			spin_unlock(&dn->d_lock);
+
 			d_delete(dn);
 			dput(dn);
 			goto retry_lookup;
@@ -1600,9 +1630,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req,
 				 &req->r_caps_reservation);
 		if (ret < 0) {
 			pr_err("fill_inode badness on %p\n", in);
-			if (d_really_is_positive(dn))
-				__ceph_dir_clear_ordered(ci);
-			else
+			if (d_really_is_negative(dn))
 				iput(in);
 			d_drop(dn);
 			err = ret;
@@ -2000,8 +2028,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
 			ceph_encode_timespec(&req->r_args.setattr.atime,
 					     &attr->ia_atime);
 			mask |= CEPH_SETATTR_ATIME;
-			release |= CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_RD |
-				CEPH_CAP_FILE_WR;
+			release |= CEPH_CAP_FILE_SHARED |
+				   CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
 		}
 	}
 	if (ia_valid & ATTR_MTIME) {
@@ -2022,8 +2050,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
 			ceph_encode_timespec(&req->r_args.setattr.mtime,
 					     &attr->ia_mtime);
 			mask |= CEPH_SETATTR_MTIME;
-			release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD |
-				CEPH_CAP_FILE_WR;
+			release |= CEPH_CAP_FILE_SHARED |
+				   CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
 		}
 	}
 	if (ia_valid & ATTR_SIZE) {
@@ -2041,8 +2069,8 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
 			req->r_args.setattr.old_size =
 				cpu_to_le64(inode->i_size);
 			mask |= CEPH_SETATTR_SIZE;
-			release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_RD |
-				CEPH_CAP_FILE_WR;
+			release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL |
+				   CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
 		}
 	}
 
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 1b46825..2e8f90f 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -604,10 +604,20 @@ static void __register_request(struct ceph_mds_client *mdsc,
 			       struct ceph_mds_request *req,
 			       struct inode *dir)
 {
+	int ret = 0;
+
 	req->r_tid = ++mdsc->last_tid;
-	if (req->r_num_caps)
-		ceph_reserve_caps(mdsc, &req->r_caps_reservation,
-				  req->r_num_caps);
+	if (req->r_num_caps) {
+		ret = ceph_reserve_caps(mdsc, &req->r_caps_reservation,
+					req->r_num_caps);
+		if (ret < 0) {
+			pr_err("__register_request %p "
+			       "failed to reserve caps: %d\n", req, ret);
+			/* set req->r_err to fail early from __do_request */
+			req->r_err = ret;
+			return;
+		}
+	}
 	dout("__register_request %p tid %lld\n", req, req->r_tid);
 	ceph_mdsc_get_request(req);
 	insert_request(&mdsc->request_tree, req);
@@ -1545,9 +1555,9 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
 /*
  * Trim session cap count down to some max number.
  */
-static int trim_caps(struct ceph_mds_client *mdsc,
-		     struct ceph_mds_session *session,
-		     int max_caps)
+int ceph_trim_caps(struct ceph_mds_client *mdsc,
+		   struct ceph_mds_session *session,
+		   int max_caps)
 {
 	int trim_caps = session->s_nr_caps - max_caps;
 
@@ -2438,11 +2448,14 @@ int ceph_mdsc_do_request(struct ceph_mds_client *mdsc,
  */
 void ceph_invalidate_dir_request(struct ceph_mds_request *req)
 {
-	struct inode *inode = req->r_parent;
+	struct inode *dir = req->r_parent;
+	struct inode *old_dir = req->r_old_dentry_dir;
 
-	dout("invalidate_dir_request %p (complete, lease(s))\n", inode);
+	dout("invalidate_dir_request %p %p (complete, lease(s))\n", dir, old_dir);
 
-	ceph_dir_clear_complete(inode);
+	ceph_dir_clear_complete(dir);
+	if (old_dir)
+		ceph_dir_clear_complete(old_dir);
 	if (req->r_dentry)
 		ceph_invalidate_dentry_lease(req->r_dentry);
 	if (req->r_old_dentry)
@@ -2773,7 +2786,7 @@ static void handle_session(struct ceph_mds_session *session,
 		break;
 
 	case CEPH_SESSION_RECALL_STATE:
-		trim_caps(mdsc, session, le32_to_cpu(h->max_caps));
+		ceph_trim_caps(mdsc, session, le32_to_cpu(h->max_caps));
 		break;
 
 	case CEPH_SESSION_FLUSHMSG:
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 837ac4b..71e3b78 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -444,4 +444,7 @@ ceph_mdsc_open_export_target_session(struct ceph_mds_client *mdsc, int target);
 extern void ceph_mdsc_open_export_target_sessions(struct ceph_mds_client *mdsc,
 					  struct ceph_mds_session *session);
 
+extern int ceph_trim_caps(struct ceph_mds_client *mdsc,
+			  struct ceph_mds_session *session,
+			  int max_caps);
 #endif
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
index 8a2ca41..07cf95e 100644
--- a/fs/ceph/snap.c
+++ b/fs/ceph/snap.c
@@ -922,13 +922,17 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
 			/*
 			 * Move the inode to the new realm
 			 */
-			spin_lock(&realm->inodes_with_caps_lock);
+			oldrealm = ci->i_snap_realm;
+			spin_lock(&oldrealm->inodes_with_caps_lock);
 			list_del_init(&ci->i_snap_realm_item);
+			spin_unlock(&oldrealm->inodes_with_caps_lock);
+
+			spin_lock(&realm->inodes_with_caps_lock);
 			list_add(&ci->i_snap_realm_item,
 				 &realm->inodes_with_caps);
-			oldrealm = ci->i_snap_realm;
 			ci->i_snap_realm = realm;
 			spin_unlock(&realm->inodes_with_caps_lock);
+
 			spin_unlock(&ci->i_ceph_lock);
 
 			ceph_get_snap_realm(mdsc, realm);
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 2beeec0..21b2e5b 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -256,7 +256,8 @@ struct ceph_inode_xattr {
  */
 struct ceph_dentry_info {
 	struct ceph_mds_session *lease_session;
-	u32 lease_gen, lease_shared_gen;
+	int lease_shared_gen;
+	u32 lease_gen;
 	u32 lease_seq;
 	unsigned long lease_renew_after, lease_renew_from;
 	struct list_head lru;
@@ -353,7 +354,7 @@ struct ceph_inode_info {
 	int i_rd_ref, i_rdcache_ref, i_wr_ref, i_wb_ref;
 	int i_wrbuffer_ref, i_wrbuffer_ref_head;
 	atomic_t i_filelock_ref;
-	u32 i_shared_gen;       /* increment each time we get FILE_SHARED */
+	atomic_t i_shared_gen;       /* increment each time we get FILE_SHARED */
 	u32 i_rdcache_gen;      /* incremented each time we get FILE_CACHE. */
 	u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */
 
@@ -648,7 +649,7 @@ extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci, bool check);
 extern void ceph_caps_init(struct ceph_mds_client *mdsc);
 extern void ceph_caps_finalize(struct ceph_mds_client *mdsc);
 extern void ceph_adjust_min_caps(struct ceph_mds_client *mdsc, int delta);
-extern void ceph_reserve_caps(struct ceph_mds_client *mdsc,
+extern int ceph_reserve_caps(struct ceph_mds_client *mdsc,
 			     struct ceph_cap_reservation *ctx, int need);
 extern int ceph_unreserve_caps(struct ceph_mds_client *mdsc,
 			       struct ceph_cap_reservation *ctx);
@@ -668,6 +669,9 @@ struct ceph_file_info {
 	short fmode;     /* initialized on open */
 	short flags;     /* CEPH_F_* */
 
+	spinlock_t rw_contexts_lock;
+	struct list_head rw_contexts;
+
 	/* readdir: position within the dir */
 	u32 frag;
 	struct ceph_mds_request *last_readdir;
@@ -684,6 +688,49 @@ struct ceph_file_info {
 	int dir_info_len;
 };
 
+struct ceph_rw_context {
+	struct list_head list;
+	struct task_struct *thread;
+	int caps;
+};
+
+#define CEPH_DEFINE_RW_CONTEXT(_name, _caps)	\
+	struct ceph_rw_context _name = {	\
+		.thread = current,		\
+		.caps = _caps,			\
+	}
+
+static inline void ceph_add_rw_context(struct ceph_file_info *cf,
+				       struct ceph_rw_context *ctx)
+{
+	spin_lock(&cf->rw_contexts_lock);
+	list_add(&ctx->list, &cf->rw_contexts);
+	spin_unlock(&cf->rw_contexts_lock);
+}
+
+static inline void ceph_del_rw_context(struct ceph_file_info *cf,
+				       struct ceph_rw_context *ctx)
+{
+	spin_lock(&cf->rw_contexts_lock);
+	list_del(&ctx->list);
+	spin_unlock(&cf->rw_contexts_lock);
+}
+
+static inline struct ceph_rw_context*
+ceph_find_rw_context(struct ceph_file_info *cf)
+{
+	struct ceph_rw_context *ctx, *found = NULL;
+	spin_lock(&cf->rw_contexts_lock);
+	list_for_each_entry(ctx, &cf->rw_contexts, list) {
+		if (ctx->thread == current) {
+			found = ctx;
+			break;
+		}
+	}
+	spin_unlock(&cf->rw_contexts_lock);
+	return found;
+}
+
 struct ceph_readdir_cache_control {
 	struct page  *page;
 	struct dentry **dentries;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 5fc5dc6..ef80085 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1218,23 +1218,11 @@ COMPATIBLE_IOCTL(DMX_SET_PES_FILTER)
 COMPATIBLE_IOCTL(DMX_SET_BUFFER_SIZE)
 COMPATIBLE_IOCTL(DMX_GET_PES_PIDS)
 COMPATIBLE_IOCTL(DMX_GET_STC)
-COMPATIBLE_IOCTL(FE_GET_INFO)
-COMPATIBLE_IOCTL(FE_DISEQC_RESET_OVERLOAD)
-COMPATIBLE_IOCTL(FE_DISEQC_SEND_MASTER_CMD)
-COMPATIBLE_IOCTL(FE_DISEQC_RECV_SLAVE_REPLY)
-COMPATIBLE_IOCTL(FE_DISEQC_SEND_BURST)
-COMPATIBLE_IOCTL(FE_SET_TONE)
-COMPATIBLE_IOCTL(FE_SET_VOLTAGE)
-COMPATIBLE_IOCTL(FE_ENABLE_HIGH_LNB_VOLTAGE)
-COMPATIBLE_IOCTL(FE_READ_STATUS)
-COMPATIBLE_IOCTL(FE_READ_BER)
-COMPATIBLE_IOCTL(FE_READ_SIGNAL_STRENGTH)
-COMPATIBLE_IOCTL(FE_READ_SNR)
-COMPATIBLE_IOCTL(FE_READ_UNCORRECTED_BLOCKS)
-COMPATIBLE_IOCTL(FE_SET_FRONTEND)
-COMPATIBLE_IOCTL(FE_GET_FRONTEND)
-COMPATIBLE_IOCTL(FE_GET_EVENT)
-COMPATIBLE_IOCTL(FE_DISHNETWORK_SEND_LEGACY_CMD)
+COMPATIBLE_IOCTL(DMX_REQBUFS)
+COMPATIBLE_IOCTL(DMX_QUERYBUF)
+COMPATIBLE_IOCTL(DMX_EXPBUF)
+COMPATIBLE_IOCTL(DMX_QBUF)
+COMPATIBLE_IOCTL(DMX_DQBUF)
 COMPATIBLE_IOCTL(VIDEO_STOP)
 COMPATIBLE_IOCTL(VIDEO_PLAY)
 COMPATIBLE_IOCTL(VIDEO_FREEZE)
diff --git a/fs/cramfs/Kconfig b/fs/cramfs/Kconfig
index 58e2fe4..5933f99 100644
--- a/fs/cramfs/Kconfig
+++ b/fs/cramfs/Kconfig
@@ -33,8 +33,7 @@
 
 config CRAMFS_MTD
 	bool "Support CramFs image directly mapped in physical memory"
-	depends on CRAMFS && MTD
-	depends on CRAMFS=m || MTD=y
+	depends on CRAMFS && CRAMFS <= MTD
 	default y if !CRAMFS_BLOCKDEV
 	help
 	  This option allows the CramFs driver to load data directly from
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c
index c5a53fc..f013867 100644
--- a/fs/exofs/dir.c
+++ b/fs/exofs/dir.c
@@ -242,7 +242,7 @@ exofs_readdir(struct file *file, struct dir_context *ctx)
 	unsigned long n = pos >> PAGE_SHIFT;
 	unsigned long npages = dir_pages(inode);
 	unsigned chunk_mask = ~(exofs_chunk_size(inode)-1);
-	bool need_revalidate = inode_cmp_iversion(inode, file->f_version);
+	bool need_revalidate = !inode_eq_iversion(inode, file->f_version);
 
 	if (pos > inode->i_size - EXOFS_DIR_REC_LEN(1))
 		return 0;
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 4111085..3b8114d 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -294,7 +294,7 @@ ext2_readdir(struct file *file, struct dir_context *ctx)
 	unsigned long npages = dir_pages(inode);
 	unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
 	unsigned char *types = NULL;
-	bool need_revalidate = inode_cmp_iversion(inode, file->f_version);
+	bool need_revalidate = !inode_eq_iversion(inode, file->f_version);
 
 	if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
 		return 0;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index db5f9da..7666c06 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -962,8 +962,11 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
 
 	if (sbi->s_mount_opt & EXT2_MOUNT_DAX) {
 		err = bdev_dax_supported(sb, blocksize);
-		if (err)
-			goto failed_mount;
+		if (err) {
+			ext2_msg(sb, KERN_ERR,
+				"DAX unsupported by block device. Turning off DAX.");
+			sbi->s_mount_opt &= ~EXT2_MOUNT_DAX;
+		}
 	}
 
 	/* If the blocksize doesn't match, re-read the thing.. */
@@ -1228,7 +1231,7 @@ static void ext2_clear_super_error(struct super_block *sb)
 		 * write and hope for the best.
 		 */
 		ext2_msg(sb, KERN_ERR,
-		       "previous I/O error to superblock detected\n");
+		       "previous I/O error to superblock detected");
 		clear_buffer_write_io_error(sbh);
 		set_buffer_uptodate(sbh);
 	}
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index afda0a0..da87cf7 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -209,7 +209,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
 		 * readdir(2), then we might be pointing to an invalid
 		 * dirent right now.  Scan from the start of the block
 		 * to make sure. */
-		if (inode_cmp_iversion(inode, file->f_version)) {
+		if (!inode_eq_iversion(inode, file->f_version)) {
 			for (i = 0; i < sb->s_blocksize && i < offset; ) {
 				de = (struct ext4_dir_entry_2 *)
 					(bh->b_data + i);
@@ -569,7 +569,7 @@ static int ext4_dx_readdir(struct file *file, struct dir_context *ctx)
 		 * cached entries.
 		 */
 		if ((!info->curr_node) ||
-		    inode_cmp_iversion(inode, file->f_version)) {
+		    !inode_eq_iversion(inode, file->f_version)) {
 			info->curr_node = NULL;
 			free_rb_tree_fname(&info->root);
 			file->f_version = inode_query_iversion(inode);
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 7c4165b..70cf4c7 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -1487,7 +1487,7 @@ int ext4_read_inline_dir(struct file *file,
 	 * dirent right now.  Scan from the start of the inline
 	 * dir to make sure.
 	 */
-	if (inode_cmp_iversion(inode, file->f_version)) {
+	if (!inode_eq_iversion(inode, file->f_version)) {
 		for (i = 0; i < extra_size && i < offset;) {
 			/*
 			 * "." is with offset 0 and
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 421222e..39bf464 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3712,11 +3712,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 		if (ext4_has_feature_inline_data(sb)) {
 			ext4_msg(sb, KERN_ERR, "Cannot use DAX on a filesystem"
 					" that may contain inline data");
-			goto failed_mount;
+			sbi->s_mount_opt &= ~EXT4_MOUNT_DAX;
 		}
 		err = bdev_dax_supported(sb, blocksize);
-		if (err)
-			goto failed_mount;
+		if (err) {
+			ext4_msg(sb, KERN_ERR,
+				"DAX unsupported by block device. Turning off DAX.");
+			sbi->s_mount_opt &= ~EXT4_MOUNT_DAX;
+		}
 	}
 
 	if (ext4_has_feature_encrypt(sb) && es->s_encryption_level) {
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index cefea792c..2649759 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -46,7 +46,7 @@ static int vfat_revalidate_shortname(struct dentry *dentry)
 {
 	int ret = 1;
 	spin_lock(&dentry->d_lock);
-	if (inode_cmp_iversion(d_inode(dentry->d_parent), vfat_d_version(dentry)))
+	if (!inode_eq_iversion(d_inode(dentry->d_parent), vfat_d_version(dentry)))
 		ret = 0;
 	spin_unlock(&dentry->d_lock);
 	return ret;
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index e8120a2..15e06fb 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -444,7 +444,7 @@ static int hfsplus_symlink(struct inode *dir, struct dentry *dentry,
 	int res = -ENOMEM;
 
 	mutex_lock(&sbi->vh_mutex);
-	inode = hfsplus_new_inode(dir->i_sb, S_IFLNK | S_IRWXUGO);
+	inode = hfsplus_new_inode(dir->i_sb, dir, S_IFLNK | S_IRWXUGO);
 	if (!inode)
 		goto out;
 
@@ -486,7 +486,7 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry,
 	int res = -ENOMEM;
 
 	mutex_lock(&sbi->vh_mutex);
-	inode = hfsplus_new_inode(dir->i_sb, mode);
+	inode = hfsplus_new_inode(dir->i_sb, dir, mode);
 	if (!inode)
 		goto out;
 
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index a015044..d9255ab 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -478,7 +478,8 @@ extern const struct address_space_operations hfsplus_aops;
 extern const struct address_space_operations hfsplus_btree_aops;
 extern const struct dentry_operations hfsplus_dentry_operations;
 
-struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode);
+struct inode *hfsplus_new_inode(struct super_block *sb, struct inode *dir,
+				umode_t mode);
 void hfsplus_delete_inode(struct inode *inode);
 void hfsplus_inode_read_fork(struct inode *inode,
 			     struct hfsplus_fork_raw *fork);
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 190c60e..c0c8d43 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -354,7 +354,8 @@ static const struct file_operations hfsplus_file_operations = {
 	.unlocked_ioctl = hfsplus_ioctl,
 };
 
-struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode)
+struct inode *hfsplus_new_inode(struct super_block *sb, struct inode *dir,
+				umode_t mode)
 {
 	struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
 	struct inode *inode = new_inode(sb);
@@ -364,9 +365,7 @@ struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode)
 		return NULL;
 
 	inode->i_ino = sbi->next_cnid++;
-	inode->i_mode = mode;
-	inode->i_uid = current_fsuid();
-	inode->i_gid = current_fsgid();
+	inode_init_owner(inode, dir, mode);
 	set_nlink(inode, 1);
 	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
 
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 1d458b7..513c357 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -549,7 +549,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
 
 		if (!sbi->hidden_dir) {
 			mutex_lock(&sbi->vh_mutex);
-			sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR);
+			sbi->hidden_dir = hfsplus_new_inode(sb, root, S_IFDIR);
 			if (!sbi->hidden_dir) {
 				mutex_unlock(&sbi->vh_mutex);
 				err = -ENOMEM;
diff --git a/fs/inode.c b/fs/inode.c
index e2ca0f4..ef36236 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -498,7 +498,6 @@ EXPORT_SYMBOL(__remove_inode_hash);
 
 void clear_inode(struct inode *inode)
 {
-	might_sleep();
 	/*
 	 * We have to cycle tree_lock here because reclaim can be still in the
 	 * process of removing the last page (in __delete_from_page_cache())
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index ceeaf0fb..7d89354 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1314,7 +1314,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
 
 	if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
 			&& (fattr->valid & NFS_ATTR_FATTR_CHANGE)
-			&& !inode_cmp_iversion_raw(inode, fattr->pre_change_attr)) {
+			&& inode_eq_iversion_raw(inode, fattr->pre_change_attr)) {
 		inode_set_iversion_raw(inode, fattr->change_attr);
 		if (S_ISDIR(inode->i_mode))
 			nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
@@ -1373,7 +1373,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
 
 	if (!nfs_file_has_buffered_writers(nfsi)) {
 		/* Verify a few of the more important attributes */
-		if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && inode_cmp_iversion_raw(inode, fattr->change_attr))
+		if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && !inode_eq_iversion_raw(inode, fattr->change_attr))
 			invalid |= NFS_INO_INVALID_ATTR | NFS_INO_REVAL_PAGECACHE;
 
 		if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&inode->i_mtime, &fattr->mtime))
@@ -1803,7 +1803,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 
 	/* More cache consistency checks */
 	if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
-		if (inode_cmp_iversion_raw(inode, fattr->change_attr)) {
+		if (!inode_eq_iversion_raw(inode, fattr->change_attr)) {
 			dprintk("NFS: change_attr change on server for file %s/%ld\n",
 					inode->i_sb->s_id, inode->i_ino);
 			/* Could it be a race with writeback? */
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index 6c5009c..68cb9e4 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -130,7 +130,7 @@ int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *segbuf,
 }
 
 int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned int flags,
-		       time_t ctime, __u64 cno)
+		       time64_t ctime, __u64 cno)
 {
 	int err;
 
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
index 7bbccc0..10e1693 100644
--- a/fs/nilfs2/segbuf.h
+++ b/fs/nilfs2/segbuf.h
@@ -46,7 +46,7 @@ struct nilfs_segsum_info {
 	unsigned long		nfileblk;
 	u64			seg_seq;
 	__u64			cno;
-	time_t			ctime;
+	time64_t		ctime;
 	sector_t		next;
 };
 
@@ -120,7 +120,7 @@ void nilfs_segbuf_map_cont(struct nilfs_segment_buffer *segbuf,
 			   struct nilfs_segment_buffer *prev);
 void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64,
 				  struct the_nilfs *);
-int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned int, time_t,
+int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned int, time64_t,
 		       __u64);
 int nilfs_segbuf_extend_segsum(struct nilfs_segment_buffer *);
 int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *,
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 9f3ffba..0953635 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2040,7 +2040,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
 			goto out;
 
 		/* Update time stamp */
-		sci->sc_seg_ctime = get_seconds();
+		sci->sc_seg_ctime = ktime_get_real_seconds();
 
 		err = nilfs_segctor_collect(sci, nilfs, mode);
 		if (unlikely(err))
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 84084a4..04634e3 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -157,7 +157,7 @@ struct nilfs_sc_info {
 	unsigned long		sc_blk_cnt;
 	unsigned long		sc_datablk_cnt;
 	unsigned long		sc_nblk_this_inc;
-	time_t			sc_seg_ctime;
+	time64_t		sc_seg_ctime;
 	__u64			sc_cno;
 	unsigned long		sc_flags;
 
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index 1341a41..c7fa139 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -526,7 +526,7 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
  * @modtime: modification time (option)
  */
 int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
-				   unsigned long nblocks, time_t modtime)
+				   unsigned long nblocks, time64_t modtime)
 {
 	struct buffer_head *bh;
 	struct nilfs_segment_usage *su;
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
index 158a919..673a891 100644
--- a/fs/nilfs2/sufile.h
+++ b/fs/nilfs2/sufile.h
@@ -35,7 +35,7 @@ int nilfs_sufile_set_alloc_range(struct inode *sufile, __u64 start, __u64 end);
 int nilfs_sufile_alloc(struct inode *, __u64 *);
 int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum);
 int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
-				   unsigned long nblocks, time_t modtime);
+				   unsigned long nblocks, time64_t modtime);
 int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
 ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned int,
 				size_t);
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 3073b64..6ffeca8 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -283,10 +283,10 @@ int nilfs_commit_super(struct super_block *sb, int flag)
 {
 	struct the_nilfs *nilfs = sb->s_fs_info;
 	struct nilfs_super_block **sbp = nilfs->ns_sbp;
-	time_t t;
+	time64_t t;
 
 	/* nilfs->ns_sem must be locked by the caller. */
-	t = get_seconds();
+	t = ktime_get_real_seconds();
 	nilfs->ns_sbwtime = t;
 	sbp[0]->s_wtime = cpu_to_le64(t);
 	sbp[0]->s_sum = 0;
diff --git a/fs/nilfs2/sysfs.c b/fs/nilfs2/sysfs.c
index 490303e..4b25837 100644
--- a/fs/nilfs2/sysfs.c
+++ b/fs/nilfs2/sysfs.c
@@ -31,7 +31,7 @@ static struct kset *nilfs_kset;
 #define NILFS_SHOW_TIME(time_t_val, buf) ({ \
 		struct tm res; \
 		int count = 0; \
-		time_to_tm(time_t_val, 0, &res); \
+		time64_to_tm(time_t_val, 0, &res); \
 		res.tm_year += 1900; \
 		res.tm_mon += 1; \
 		count = scnprintf(buf, PAGE_SIZE, \
@@ -579,7 +579,7 @@ nilfs_segctor_last_seg_write_time_show(struct nilfs_segctor_attr *attr,
 					struct the_nilfs *nilfs,
 					char *buf)
 {
-	time_t ctime;
+	time64_t ctime;
 
 	down_read(&nilfs->ns_segctor_sem);
 	ctime = nilfs->ns_ctime;
@@ -593,13 +593,13 @@ nilfs_segctor_last_seg_write_time_secs_show(struct nilfs_segctor_attr *attr,
 					    struct the_nilfs *nilfs,
 					    char *buf)
 {
-	time_t ctime;
+	time64_t ctime;
 
 	down_read(&nilfs->ns_segctor_sem);
 	ctime = nilfs->ns_ctime;
 	up_read(&nilfs->ns_segctor_sem);
 
-	return snprintf(buf, PAGE_SIZE, "%llu\n", (unsigned long long)ctime);
+	return snprintf(buf, PAGE_SIZE, "%llu\n", ctime);
 }
 
 static ssize_t
@@ -607,7 +607,7 @@ nilfs_segctor_last_nongc_write_time_show(struct nilfs_segctor_attr *attr,
 					 struct the_nilfs *nilfs,
 					 char *buf)
 {
-	time_t nongc_ctime;
+	time64_t nongc_ctime;
 
 	down_read(&nilfs->ns_segctor_sem);
 	nongc_ctime = nilfs->ns_nongc_ctime;
@@ -621,14 +621,13 @@ nilfs_segctor_last_nongc_write_time_secs_show(struct nilfs_segctor_attr *attr,
 						struct the_nilfs *nilfs,
 						char *buf)
 {
-	time_t nongc_ctime;
+	time64_t nongc_ctime;
 
 	down_read(&nilfs->ns_segctor_sem);
 	nongc_ctime = nilfs->ns_nongc_ctime;
 	up_read(&nilfs->ns_segctor_sem);
 
-	return snprintf(buf, PAGE_SIZE, "%llu\n",
-			(unsigned long long)nongc_ctime);
+	return snprintf(buf, PAGE_SIZE, "%llu\n", nongc_ctime);
 }
 
 static ssize_t
@@ -728,7 +727,7 @@ nilfs_superblock_sb_write_time_show(struct nilfs_superblock_attr *attr,
 				     struct the_nilfs *nilfs,
 				     char *buf)
 {
-	time_t sbwtime;
+	time64_t sbwtime;
 
 	down_read(&nilfs->ns_sem);
 	sbwtime = nilfs->ns_sbwtime;
@@ -742,13 +741,13 @@ nilfs_superblock_sb_write_time_secs_show(struct nilfs_superblock_attr *attr,
 					 struct the_nilfs *nilfs,
 					 char *buf)
 {
-	time_t sbwtime;
+	time64_t sbwtime;
 
 	down_read(&nilfs->ns_sem);
 	sbwtime = nilfs->ns_sbwtime;
 	up_read(&nilfs->ns_sem);
 
-	return snprintf(buf, PAGE_SIZE, "%llu\n", (unsigned long long)sbwtime);
+	return snprintf(buf, PAGE_SIZE, "%llu\n", sbwtime);
 }
 
 static ssize_t
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 883d732..36da177 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -116,7 +116,7 @@ struct the_nilfs {
 	 */
 	struct buffer_head     *ns_sbh[2];
 	struct nilfs_super_block *ns_sbp[2];
-	time_t			ns_sbwtime;
+	time64_t		ns_sbwtime;
 	unsigned int		ns_sbwcount;
 	unsigned int		ns_sbsize;
 	unsigned int		ns_mount_state;
@@ -131,8 +131,8 @@ struct the_nilfs {
 	__u64			ns_nextnum;
 	unsigned long		ns_pseg_offset;
 	__u64			ns_cno;
-	time_t			ns_ctime;
-	time_t			ns_nongc_ctime;
+	time64_t		ns_ctime;
+	time64_t		ns_nongc_ctime;
 	atomic_t		ns_ndirtyblks;
 
 	/*
@@ -267,7 +267,7 @@ struct nilfs_root {
 
 static inline int nilfs_sb_need_update(struct the_nilfs *nilfs)
 {
-	u64 t = get_seconds();
+	u64 t = ktime_get_real_seconds();
 
 	return t < nilfs->ns_sbwtime ||
 		t > nilfs->ns_sbwtime + nilfs->ns_sb_update_freq;
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index b7520e20..977763d 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -1776,7 +1776,7 @@ static int ocfs2_dir_foreach_blk_id(struct inode *inode,
 		 * readdir(2), then we might be pointing to an invalid
 		 * dirent right now.  Scan from the start of the block
 		 * to make sure. */
-		if (inode_cmp_iversion(inode, *f_version)) {
+		if (!inode_eq_iversion(inode, *f_version)) {
 			for (i = 0; i < i_size_read(inode) && i < offset; ) {
 				de = (struct ocfs2_dir_entry *)
 					(data->id_data + i);
@@ -1870,7 +1870,7 @@ static int ocfs2_dir_foreach_blk_el(struct inode *inode,
 		 * readdir(2), then we might be pointing to an invalid
 		 * dirent right now.  Scan from the start of the block
 		 * to make sure. */
-		if (inode_cmp_iversion(inode, *f_version)) {
+		if (!inode_eq_iversion(inode, *f_version)) {
 			for (i = 0; i < sb->s_blocksize && i < offset; ) {
 				de = (struct ocfs2_dir_entry *) (bh->b_data + i);
 				/* It's too expensive to do a full
diff --git a/fs/pipe.c b/fs/pipe.c
index a449ca0..0913aed 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -35,11 +35,6 @@
  */
 unsigned int pipe_max_size = 1048576;
 
-/*
- * Minimum pipe size, as required by POSIX
- */
-unsigned int pipe_min_size = PAGE_SIZE;
-
 /* Maximum allocatable pages per user. Hard limit is unset by default, soft
  * matches default values.
  */
@@ -610,12 +605,21 @@ static unsigned long account_pipe_buffers(struct user_struct *user,
 
 static bool too_many_pipe_buffers_soft(unsigned long user_bufs)
 {
-	return pipe_user_pages_soft && user_bufs >= pipe_user_pages_soft;
+	unsigned long soft_limit = READ_ONCE(pipe_user_pages_soft);
+
+	return soft_limit && user_bufs > soft_limit;
 }
 
 static bool too_many_pipe_buffers_hard(unsigned long user_bufs)
 {
-	return pipe_user_pages_hard && user_bufs >= pipe_user_pages_hard;
+	unsigned long hard_limit = READ_ONCE(pipe_user_pages_hard);
+
+	return hard_limit && user_bufs > hard_limit;
+}
+
+static bool is_unprivileged_user(void)
+{
+	return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
 }
 
 struct pipe_inode_info *alloc_pipe_info(void)
@@ -624,22 +628,23 @@ struct pipe_inode_info *alloc_pipe_info(void)
 	unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
 	struct user_struct *user = get_current_user();
 	unsigned long user_bufs;
+	unsigned int max_size = READ_ONCE(pipe_max_size);
 
 	pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT);
 	if (pipe == NULL)
 		goto out_free_uid;
 
-	if (pipe_bufs * PAGE_SIZE > pipe_max_size && !capable(CAP_SYS_RESOURCE))
-		pipe_bufs = pipe_max_size >> PAGE_SHIFT;
+	if (pipe_bufs * PAGE_SIZE > max_size && !capable(CAP_SYS_RESOURCE))
+		pipe_bufs = max_size >> PAGE_SHIFT;
 
 	user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
 
-	if (too_many_pipe_buffers_soft(user_bufs)) {
+	if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) {
 		user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
 		pipe_bufs = 1;
 	}
 
-	if (too_many_pipe_buffers_hard(user_bufs))
+	if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user())
 		goto out_revert_acct;
 
 	pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer),
@@ -1020,18 +1025,16 @@ const struct file_operations pipefifo_fops = {
  * Currently we rely on the pipe array holding a power-of-2 number
  * of pages. Returns 0 on error.
  */
-unsigned int round_pipe_size(unsigned int size)
+unsigned int round_pipe_size(unsigned long size)
 {
-	unsigned long nr_pages;
-
-	if (size < pipe_min_size)
-		size = pipe_min_size;
-
-	nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	if (nr_pages == 0)
+	if (size > (1U << 31))
 		return 0;
 
-	return roundup_pow_of_two(nr_pages) << PAGE_SHIFT;
+	/* Minimum pipe size, as required by POSIX */
+	if (size < PAGE_SIZE)
+		return PAGE_SIZE;
+
+	return roundup_pow_of_two(size);
 }
 
 /*
@@ -1046,8 +1049,6 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
 	long ret = 0;
 
 	size = round_pipe_size(arg);
-	if (size == 0)
-		return -EINVAL;
 	nr_pages = size >> PAGE_SHIFT;
 
 	if (!nr_pages)
@@ -1069,7 +1070,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
 	if (nr_pages > pipe->buffers &&
 			(too_many_pipe_buffers_hard(user_bufs) ||
 			 too_many_pipe_buffers_soft(user_bufs)) &&
-			!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
+			is_unprivileged_user()) {
 		ret = -EPERM;
 		goto out_revert_acct;
 	}
@@ -1125,16 +1126,6 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
 }
 
 /*
- * This should work even if CONFIG_PROC_FS isn't set, as proc_dopipe_max_size
- * will return an error.
- */
-int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
-		 size_t *lenp, loff_t *ppos)
-{
-	return proc_dopipe_max_size(table, write, buf, lenp, ppos);
-}
-
-/*
  * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
  * location, so checking ->i_pipe is not enough to verify that this is a
  * pipe.
diff --git a/fs/proc/array.c b/fs/proc/array.c
index d67a72d..5988035 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -736,16 +736,10 @@ static int children_seq_open(struct inode *inode, struct file *file)
 	return ret;
 }
 
-int children_seq_release(struct inode *inode, struct file *file)
-{
-	seq_release(inode, file);
-	return 0;
-}
-
 const struct file_operations proc_tid_children_operations = {
 	.open    = children_seq_open,
 	.read    = seq_read,
 	.llseek  = seq_lseek,
-	.release = children_seq_release,
+	.release = seq_release,
 };
 #endif /* CONFIG_PROC_CHILDREN */
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 60316b5..9298324 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -75,6 +75,7 @@
 #include <linux/ptrace.h>
 #include <linux/tracehook.h>
 #include <linux/printk.h>
+#include <linux/cache.h>
 #include <linux/cgroup.h>
 #include <linux/cpuset.h>
 #include <linux/audit.h>
@@ -100,6 +101,8 @@
 #include "internal.h"
 #include "fd.h"
 
+#include "../../lib/kstrtox.h"
+
 /* NOTE:
  *	Implementing inode permission operations in /proc is almost
  *	certainly an error.  Permission checks need to happen during
@@ -110,8 +113,8 @@
  *	in /proc for a task before it execs a suid executable.
  */
 
-static u8 nlink_tid;
-static u8 nlink_tgid;
+static u8 nlink_tid __ro_after_init;
+static u8 nlink_tgid __ro_after_init;
 
 struct pid_entry {
 	const char *name;
@@ -1370,7 +1373,7 @@ static ssize_t proc_fail_nth_write(struct file *file, const char __user *buf,
 	task = get_proc_task(file_inode(file));
 	if (!task)
 		return -ESRCH;
-	WRITE_ONCE(task->fail_nth, n);
+	task->fail_nth = n;
 	put_task_struct(task);
 
 	return count;
@@ -1386,8 +1389,7 @@ static ssize_t proc_fail_nth_read(struct file *file, char __user *buf,
 	task = get_proc_task(file_inode(file));
 	if (!task)
 		return -ESRCH;
-	len = snprintf(numbuf, sizeof(numbuf), "%u\n",
-			READ_ONCE(task->fail_nth));
+	len = snprintf(numbuf, sizeof(numbuf), "%u\n", task->fail_nth);
 	len = simple_read_from_buffer(buf, count, ppos, numbuf, len);
 	put_task_struct(task);
 
@@ -1907,8 +1909,33 @@ bool proc_fill_cache(struct file *file, struct dir_context *ctx,
 static int dname_to_vma_addr(struct dentry *dentry,
 			     unsigned long *start, unsigned long *end)
 {
-	if (sscanf(dentry->d_name.name, "%lx-%lx", start, end) != 2)
+	const char *str = dentry->d_name.name;
+	unsigned long long sval, eval;
+	unsigned int len;
+
+	len = _parse_integer(str, 16, &sval);
+	if (len & KSTRTOX_OVERFLOW)
 		return -EINVAL;
+	if (sval != (unsigned long)sval)
+		return -EINVAL;
+	str += len;
+
+	if (*str != '-')
+		return -EINVAL;
+	str++;
+
+	len = _parse_integer(str, 16, &eval);
+	if (len & KSTRTOX_OVERFLOW)
+		return -EINVAL;
+	if (eval != (unsigned long)eval)
+		return -EINVAL;
+	str += len;
+
+	if (*str != '\0')
+		return -EINVAL;
+
+	*start = sval;
+	*end = eval;
 
 	return 0;
 }
@@ -2000,9 +2027,9 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
 }
 
 struct map_files_info {
+	unsigned long	start;
+	unsigned long	end;
 	fmode_t		mode;
-	unsigned int	len;
-	unsigned char	name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */
 };
 
 /*
@@ -2172,10 +2199,9 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
 			if (++pos <= ctx->pos)
 				continue;
 
+			info.start = vma->vm_start;
+			info.end = vma->vm_end;
 			info.mode = vma->vm_file->f_mode;
-			info.len = snprintf(info.name,
-					sizeof(info.name), "%lx-%lx",
-					vma->vm_start, vma->vm_end);
 			if (flex_array_put(fa, i++, &info, GFP_KERNEL))
 				BUG();
 		}
@@ -2183,9 +2209,13 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
 	up_read(&mm->mmap_sem);
 
 	for (i = 0; i < nr_files; i++) {
+		char buf[4 * sizeof(long) + 2];	/* max: %lx-%lx\0 */
+		unsigned int len;
+
 		p = flex_array_get(fa, i);
+		len = snprintf(buf, sizeof(buf), "%lx-%lx", p->start, p->end);
 		if (!proc_fill_cache(file, ctx,
-				      p->name, p->len,
+				      buf, len,
 				      proc_map_files_instantiate,
 				      task,
 				      (void *)(unsigned long)p->mode))
@@ -3018,11 +3048,11 @@ static const struct inode_operations proc_tgid_base_inode_operations = {
 static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
 {
 	struct dentry *dentry, *leader, *dir;
-	char buf[PROC_NUMBUF];
+	char buf[10 + 1];
 	struct qstr name;
 
 	name.name = buf;
-	name.len = snprintf(buf, sizeof(buf), "%d", pid);
+	name.len = snprintf(buf, sizeof(buf), "%u", pid);
 	/* no ->d_hash() rejects on procfs */
 	dentry = d_hash_and_lookup(mnt->mnt_root, &name);
 	if (dentry) {
@@ -3034,7 +3064,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
 		return;
 
 	name.name = buf;
-	name.len = snprintf(buf, sizeof(buf), "%d", tgid);
+	name.len = snprintf(buf, sizeof(buf), "%u", tgid);
 	leader = d_hash_and_lookup(mnt->mnt_root, &name);
 	if (!leader)
 		goto out;
@@ -3046,7 +3076,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
 		goto out_put_leader;
 
 	name.name = buf;
-	name.len = snprintf(buf, sizeof(buf), "%d", pid);
+	name.len = snprintf(buf, sizeof(buf), "%u", pid);
 	dentry = d_hash_and_lookup(dir, &name);
 	if (dentry) {
 		d_invalidate(dentry);
@@ -3225,14 +3255,14 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx)
 	for (iter = next_tgid(ns, iter);
 	     iter.task;
 	     iter.tgid += 1, iter = next_tgid(ns, iter)) {
-		char name[PROC_NUMBUF];
+		char name[10 + 1];
 		int len;
 
 		cond_resched();
 		if (!has_pid_permissions(ns, iter.task, HIDEPID_INVISIBLE))
 			continue;
 
-		len = snprintf(name, sizeof(name), "%d", iter.tgid);
+		len = snprintf(name, sizeof(name), "%u", iter.tgid);
 		ctx->pos = iter.tgid + TGID_OFFSET;
 		if (!proc_fill_cache(file, ctx, name, len,
 				     proc_pid_instantiate, iter.task, NULL)) {
@@ -3560,10 +3590,10 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx)
 	for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);
 	     task;
 	     task = next_tid(task), ctx->pos++) {
-		char name[PROC_NUMBUF];
+		char name[10 + 1];
 		int len;
 		tid = task_pid_nr_ns(task, ns);
-		len = snprintf(name, sizeof(name), "%d", tid);
+		len = snprintf(name, sizeof(name), "%u", tid);
 		if (!proc_fill_cache(file, ctx, name, len,
 				proc_task_instantiate, task, NULL)) {
 			/* returning this tgid failed, save it as the first
diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
index 290ba85..a8ac48a 100644
--- a/fs/proc/consoles.c
+++ b/fs/proc/consoles.c
@@ -55,8 +55,7 @@ static int show_console_dev(struct seq_file *m, void *v)
 	if (dev)
 		seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev));
 
-	seq_printf(m, "\n");
-
+	seq_putc(m, '\n');
 	return 0;
 }
 
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
index 96fc702..6b80cd1 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -236,7 +236,7 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx,
 	for (fd = ctx->pos - 2;
 	     fd < files_fdtable(files)->max_fds;
 	     fd++, ctx->pos++) {
-		char name[PROC_NUMBUF];
+		char name[10 + 1];
 		int len;
 
 		if (!fcheck_files(files, fd))
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 793a675..5d709fa 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -28,7 +28,7 @@
 
 static DEFINE_RWLOCK(proc_subdir_lock);
 
-static int proc_match(unsigned int len, const char *name, struct proc_dir_entry *de)
+static int proc_match(const char *name, struct proc_dir_entry *de, unsigned int len)
 {
 	if (len < de->namelen)
 		return -1;
@@ -60,7 +60,7 @@ static struct proc_dir_entry *pde_subdir_find(struct proc_dir_entry *dir,
 		struct proc_dir_entry *de = rb_entry(node,
 						     struct proc_dir_entry,
 						     subdir_node);
-		int result = proc_match(len, name, de);
+		int result = proc_match(name, de, len);
 
 		if (result < 0)
 			node = node->rb_left;
@@ -84,7 +84,7 @@ static bool pde_subdir_insert(struct proc_dir_entry *dir,
 		struct proc_dir_entry *this = rb_entry(*new,
 						       struct proc_dir_entry,
 						       subdir_node);
-		int result = proc_match(de->namelen, de->name, this);
+		int result = proc_match(de->name, this, de->namelen);
 
 		parent = *new;
 		if (result < 0)
@@ -211,8 +211,8 @@ void proc_free_inum(unsigned int inum)
  * Don't create negative dentries here, return -ENOENT by hand
  * instead.
  */
-struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
-		struct dentry *dentry)
+struct dentry *proc_lookup_de(struct inode *dir, struct dentry *dentry,
+			      struct proc_dir_entry *de)
 {
 	struct inode *inode;
 
@@ -235,7 +235,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
 struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
 		unsigned int flags)
 {
-	return proc_lookup_de(PDE(dir), dir, dentry);
+	return proc_lookup_de(dir, dentry, PDE(dir));
 }
 
 /*
@@ -247,8 +247,8 @@ struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
  * value of the readdir() call, as long as it's non-negative
  * for success..
  */
-int proc_readdir_de(struct proc_dir_entry *de, struct file *file,
-		    struct dir_context *ctx)
+int proc_readdir_de(struct file *file, struct dir_context *ctx,
+		    struct proc_dir_entry *de)
 {
 	int i;
 
@@ -292,7 +292,7 @@ int proc_readdir(struct file *file, struct dir_context *ctx)
 {
 	struct inode *inode = file_inode(file);
 
-	return proc_readdir_de(PDE(inode), file, ctx);
+	return proc_readdir_de(file, ctx, PDE(inode));
 }
 
 /*
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 8dacaab..6e87249 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -5,6 +5,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
+#include <linux/cache.h>
 #include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/kernel.h>
@@ -52,7 +53,7 @@ static void proc_evict_inode(struct inode *inode)
 	}
 }
 
-static struct kmem_cache * proc_inode_cachep;
+static struct kmem_cache *proc_inode_cachep __ro_after_init;
 
 static struct inode *proc_alloc_inode(struct super_block *sb)
 {
@@ -128,12 +129,12 @@ enum {BIAS = -1U<<31};
 
 static inline int use_pde(struct proc_dir_entry *pde)
 {
-	return atomic_inc_unless_negative(&pde->in_use);
+	return likely(atomic_inc_unless_negative(&pde->in_use));
 }
 
 static void unuse_pde(struct proc_dir_entry *pde)
 {
-	if (atomic_dec_return(&pde->in_use) == BIAS)
+	if (unlikely(atomic_dec_return(&pde->in_use) == BIAS))
 		complete(pde->pde_unload_completion);
 }
 
@@ -166,7 +167,7 @@ static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
 		spin_lock(&pde->pde_unload_lock);
 		/* After ->release. */
 		list_del(&pdeo->lh);
-		if (pdeo->c)
+		if (unlikely(pdeo->c))
 			complete(pdeo->c);
 		kfree(pdeo);
 	}
@@ -420,7 +421,7 @@ static const char *proc_get_link(struct dentry *dentry,
 				 struct delayed_call *done)
 {
 	struct proc_dir_entry *pde = PDE(inode);
-	if (unlikely(!use_pde(pde)))
+	if (!use_pde(pde))
 		return ERR_PTR(-EINVAL);
 	set_delayed_call(done, proc_put_link, pde);
 	return pde->data;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 4a67188..d697c8a 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -31,24 +31,28 @@ struct mempolicy;
  * subdir_node is used to build the rb tree "subdir" of the parent.
  */
 struct proc_dir_entry {
+	/*
+	 * number of callers into module in progress;
+	 * negative -> it's going away RSN
+	 */
+	atomic_t in_use;
+	atomic_t count;		/* use count */
+	struct list_head pde_openers;	/* who did ->open, but not ->release */
+	/* protects ->pde_openers and all struct pde_opener instances */
+	spinlock_t pde_unload_lock;
+	struct completion *pde_unload_completion;
+	const struct inode_operations *proc_iops;
+	const struct file_operations *proc_fops;
+	void *data;
 	unsigned int low_ino;
-	umode_t mode;
 	nlink_t nlink;
 	kuid_t uid;
 	kgid_t gid;
 	loff_t size;
-	const struct inode_operations *proc_iops;
-	const struct file_operations *proc_fops;
 	struct proc_dir_entry *parent;
 	struct rb_root_cached subdir;
 	struct rb_node subdir_node;
-	void *data;
-	atomic_t count;		/* use count */
-	atomic_t in_use;	/* number of callers into module in progress; */
-			/* negative -> it's going away RSN */
-	struct completion *pde_unload_completion;
-	struct list_head pde_openers;	/* who did ->open, but not ->release */
-	spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
+	umode_t mode;
 	u8 namelen;
 	char name[];
 } __randomize_layout;
@@ -149,10 +153,9 @@ extern bool proc_fill_cache(struct file *, struct dir_context *, const char *, i
  * generic.c
  */
 extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int);
-extern struct dentry *proc_lookup_de(struct proc_dir_entry *, struct inode *,
-				     struct dentry *);
+struct dentry *proc_lookup_de(struct inode *, struct dentry *, struct proc_dir_entry *);
 extern int proc_readdir(struct file *, struct dir_context *);
-extern int proc_readdir_de(struct proc_dir_entry *, struct file *, struct dir_context *);
+int proc_readdir_de(struct file *, struct dir_context *, struct proc_dir_entry *);
 
 static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde)
 {
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 4bc85cb..e8a93bc 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -512,23 +512,15 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
 				return -EFAULT;
 		} else {
 			if (kern_addr_valid(start)) {
-				unsigned long n;
-
 				/*
 				 * Using bounce buffer to bypass the
 				 * hardened user copy kernel text checks.
 				 */
-				memcpy(buf, (char *) start, tsz);
-				n = copy_to_user(buffer, buf, tsz);
-				/*
-				 * We cannot distinguish between fault on source
-				 * and fault on destination. When this happens
-				 * we clear too and hope it will trigger the
-				 * EFAULT again.
-				 */
-				if (n) { 
-					if (clear_user(buffer + tsz - n,
-								n))
+				if (probe_kernel_read(buf, (void *) start, tsz)) {
+					if (clear_user(buffer, tsz))
+						return -EFAULT;
+				} else {
+					if (copy_to_user(buffer, buf, tsz))
 						return -EFAULT;
 				}
 			} else {
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index a2bf369..68c06ae 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -135,7 +135,7 @@ static struct dentry *proc_tgid_net_lookup(struct inode *dir,
 	de = ERR_PTR(-ENOENT);
 	net = get_proc_task_net(dir);
 	if (net != NULL) {
-		de = proc_lookup_de(net->proc_net, dir, dentry);
+		de = proc_lookup_de(dir, dentry, net->proc_net);
 		put_net(net);
 	}
 	return de;
@@ -172,7 +172,7 @@ static int proc_tgid_net_readdir(struct file *file, struct dir_context *ctx)
 	ret = -EINVAL;
 	net = get_proc_task_net(file_inode(file));
 	if (net != NULL) {
-		ret = proc_readdir_de(net->proc_net, file, ctx);
+		ret = proc_readdir_de(file, ctx, net->proc_net);
 		put_net(net);
 	}
 	return ret;
diff --git a/fs/proc/self.c b/fs/proc/self.c
index 31326bb..4d7d061 100644
--- a/fs/proc/self.c
+++ b/fs/proc/self.c
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <linux/cache.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/pid_namespace.h>
@@ -17,11 +18,11 @@ static const char *proc_self_get_link(struct dentry *dentry,
 
 	if (!tgid)
 		return ERR_PTR(-ENOENT);
-	/* 11 for max length of signed int in decimal + NULL term */
-	name = kmalloc(12, dentry ? GFP_KERNEL : GFP_ATOMIC);
+	/* max length of unsigned int in decimal + NULL term */
+	name = kmalloc(10 + 1, dentry ? GFP_KERNEL : GFP_ATOMIC);
 	if (unlikely(!name))
 		return dentry ? ERR_PTR(-ENOMEM) : ERR_PTR(-ECHILD);
-	sprintf(name, "%d", tgid);
+	sprintf(name, "%u", tgid);
 	set_delayed_call(done, kfree_link, name);
 	return name;
 }
@@ -30,7 +31,7 @@ static const struct inode_operations proc_self_inode_operations = {
 	.get_link	= proc_self_get_link,
 };
 
-static unsigned self_inum;
+static unsigned self_inum __ro_after_init;
 
 int proc_setup_self(struct super_block *s)
 {
diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c
index b813e3b..9d2efac 100644
--- a/fs/proc/thread_self.c
+++ b/fs/proc/thread_self.c
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <linux/cache.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/pid_namespace.h>
@@ -18,11 +19,10 @@ static const char *proc_thread_self_get_link(struct dentry *dentry,
 
 	if (!pid)
 		return ERR_PTR(-ENOENT);
-	name = kmalloc(PROC_NUMBUF + 6 + PROC_NUMBUF,
-				dentry ? GFP_KERNEL : GFP_ATOMIC);
+	name = kmalloc(10 + 6 + 10 + 1, dentry ? GFP_KERNEL : GFP_ATOMIC);
 	if (unlikely(!name))
 		return dentry ? ERR_PTR(-ENOMEM) : ERR_PTR(-ECHILD);
-	sprintf(name, "%d/task/%d", tgid, pid);
+	sprintf(name, "%u/task/%u", tgid, pid);
 	set_delayed_call(done, kfree_link, name);
 	return name;
 }
@@ -31,7 +31,7 @@ static const struct inode_operations proc_thread_self_inode_operations = {
 	.get_link	= proc_thread_self_get_link,
 };
 
-static unsigned thread_self_inum;
+static unsigned thread_self_inum __ro_after_init;
 
 int proc_setup_thread_self(struct super_block *s)
 {
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 885d445a..a45f0af 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -1178,18 +1178,16 @@ fs_initcall(vmcore_init);
 /* Cleanup function for vmcore module. */
 void vmcore_cleanup(void)
 {
-	struct list_head *pos, *next;
-
 	if (proc_vmcore) {
 		proc_remove(proc_vmcore);
 		proc_vmcore = NULL;
 	}
 
 	/* clear the vmcore list. */
-	list_for_each_safe(pos, next, &vmcore_list) {
+	while (!list_empty(&vmcore_list)) {
 		struct vmcore *m;
 
-		m = list_entry(pos, struct vmcore, list);
+		m = list_first_entry(&vmcore_list, struct vmcore, list);
 		list_del(&m->list);
 		kfree(m);
 	}
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index 14626b3..0927a4b 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -62,6 +62,11 @@ udf_disk_stamp_to_time(struct timespec *dest, struct timestamp src)
 	dest->tv_sec -= offset * 60;
 	dest->tv_nsec = 1000 * (src.centiseconds * 10000 +
 			src.hundredsOfMicroseconds * 100 + src.microseconds);
+	/*
+	 * Sanitize nanosecond field since reportedly some filesystems are
+	 * recorded with bogus sub-second values.
+	 */
+	dest->tv_nsec %= NSEC_PER_SEC;
 	return dest;
 }
 
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 50dfce0..b721d0b 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -429,7 +429,7 @@ ufs_readdir(struct file *file, struct dir_context *ctx)
 	unsigned long n = pos >> PAGE_SHIFT;
 	unsigned long npages = dir_pages(inode);
 	unsigned chunk_mask = ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
-	bool need_revalidate = inode_cmp_iversion(inode, file->f_version);
+	bool need_revalidate = !inode_eq_iversion(inode, file->f_version);
 	unsigned flags = UFS_SB(sb)->s_flags;
 
 	UFSD("BEGIN\n");
diff --git a/include/asm-generic/audit_dir_write.h b/include/asm-generic/audit_dir_write.h
index da09fb9..dd5a9dd 100644
--- a/include/asm-generic/audit_dir_write.h
+++ b/include/asm-generic/audit_dir_write.h
@@ -27,7 +27,9 @@ __NR_mknod,
 __NR_mkdirat,
 __NR_mknodat,
 __NR_unlinkat,
+#ifdef __NR_renameat
 __NR_renameat,
+#endif
 __NR_linkat,
 __NR_symlinkat,
 #endif
diff --git a/include/asm-generic/bitops/find.h b/include/asm-generic/bitops/find.h
index 1ba611e..8a1ee10 100644
--- a/include/asm-generic/bitops/find.h
+++ b/include/asm-generic/bitops/find.h
@@ -16,6 +16,22 @@ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
 		size, unsigned long offset);
 #endif
 
+#ifndef find_next_and_bit
+/**
+ * find_next_and_bit - find the next set bit in both memory regions
+ * @addr1: The first address to base the search on
+ * @addr2: The second address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The bitmap size in bits
+ *
+ * Returns the bit number for the next set bit
+ * If no bits are set, returns @size.
+ */
+extern unsigned long find_next_and_bit(const unsigned long *addr1,
+		const unsigned long *addr2, unsigned long size,
+		unsigned long offset);
+#endif
+
 #ifndef find_next_zero_bit
 /**
  * find_next_zero_bit - find the next cleared bit in a memory region
@@ -55,8 +71,12 @@ extern unsigned long find_first_zero_bit(const unsigned long *addr,
 					 unsigned long size);
 #else /* CONFIG_GENERIC_FIND_FIRST_BIT */
 
+#ifndef find_first_bit
 #define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
+#endif
+#ifndef find_first_zero_bit
 #define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
+#endif
 
 #endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
 
diff --git a/include/asm-generic/pci_iomap.h b/include/asm-generic/pci_iomap.h
index b1e17fc..854f96a 100644
--- a/include/asm-generic/pci_iomap.h
+++ b/include/asm-generic/pci_iomap.h
@@ -1,12 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /* Generic I/O port emulation, based on MN10300 code
  *
  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
  */
 #ifndef __ASM_GENERIC_PCI_IOMAP_H
 #define __ASM_GENERIC_PCI_IOMAP_H
diff --git a/include/asm-generic/qrwlock_types.h b/include/asm-generic/qrwlock_types.h
index 137ecdd..c36f1d5 100644
--- a/include/asm-generic/qrwlock_types.h
+++ b/include/asm-generic/qrwlock_types.h
@@ -3,6 +3,7 @@
 #define __ASM_GENERIC_QRWLOCK_TYPES_H
 
 #include <linux/types.h>
+#include <asm/byteorder.h>
 #include <asm/spinlock_types.h>
 
 /*
diff --git a/include/dt-bindings/clock/jz4770-cgu.h b/include/dt-bindings/clock/jz4770-cgu.h
new file mode 100644
index 0000000..d68a769
--- /dev/null
+++ b/include/dt-bindings/clock/jz4770-cgu.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides clock numbers for the ingenic,jz4770-cgu DT binding.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4770_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4770_CGU_H__
+
+#define JZ4770_CLK_EXT		0
+#define JZ4770_CLK_OSC32K	1
+#define JZ4770_CLK_PLL0		2
+#define JZ4770_CLK_PLL1		3
+#define JZ4770_CLK_CCLK		4
+#define JZ4770_CLK_H0CLK	5
+#define JZ4770_CLK_H1CLK	6
+#define JZ4770_CLK_H2CLK	7
+#define JZ4770_CLK_C1CLK	8
+#define JZ4770_CLK_PCLK		9
+#define JZ4770_CLK_MMC0_MUX	10
+#define JZ4770_CLK_MMC0		11
+#define JZ4770_CLK_MMC1_MUX	12
+#define JZ4770_CLK_MMC1		13
+#define JZ4770_CLK_MMC2_MUX	14
+#define JZ4770_CLK_MMC2		15
+#define JZ4770_CLK_CIM		16
+#define JZ4770_CLK_UHC		17
+#define JZ4770_CLK_GPU		18
+#define JZ4770_CLK_BCH		19
+#define JZ4770_CLK_LPCLK_MUX	20
+#define JZ4770_CLK_GPS		21
+#define JZ4770_CLK_SSI_MUX	22
+#define JZ4770_CLK_PCM_MUX	23
+#define JZ4770_CLK_I2S		24
+#define JZ4770_CLK_OTG		25
+#define JZ4770_CLK_SSI0		26
+#define JZ4770_CLK_SSI1		27
+#define JZ4770_CLK_SSI2		28
+#define JZ4770_CLK_PCM0		29
+#define JZ4770_CLK_PCM1		30
+#define JZ4770_CLK_DMA		31
+#define JZ4770_CLK_I2C0		32
+#define JZ4770_CLK_I2C1		33
+#define JZ4770_CLK_I2C2		34
+#define JZ4770_CLK_UART0	35
+#define JZ4770_CLK_UART1	36
+#define JZ4770_CLK_UART2	37
+#define JZ4770_CLK_UART3	38
+#define JZ4770_CLK_IPU		39
+#define JZ4770_CLK_ADC		40
+#define JZ4770_CLK_AIC		41
+#define JZ4770_CLK_AUX		42
+#define JZ4770_CLK_VPU		43
+#define JZ4770_CLK_UHC_PHY	44
+#define JZ4770_CLK_OTG_PHY	45
+#define JZ4770_CLK_EXT512	46
+#define JZ4770_CLK_RTC		47
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4770_CGU_H__ */
diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h
new file mode 100644
index 0000000..e518e4e
--- /dev/null
+++ b/include/kvm/arm_psci.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __KVM_ARM_PSCI_H__
+#define __KVM_ARM_PSCI_H__
+
+#include <linux/kvm_host.h>
+#include <uapi/linux/psci.h>
+
+#define KVM_ARM_PSCI_0_1	PSCI_VERSION(0, 1)
+#define KVM_ARM_PSCI_0_2	PSCI_VERSION(0, 2)
+#define KVM_ARM_PSCI_1_0	PSCI_VERSION(1, 0)
+
+#define KVM_ARM_PSCI_LATEST	KVM_ARM_PSCI_1_0
+
+/*
+ * We need the KVM pointer independently from the vcpu as we can call
+ * this from HYP, and need to apply kern_hyp_va on it...
+ */
+static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm)
+{
+	/*
+	 * Our PSCI implementation stays the same across versions from
+	 * v0.2 onward, only adding the few mandatory functions (such
+	 * as FEATURES with 1.0) that are required by newer
+	 * revisions. It is thus safe to return the latest.
+	 */
+	if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
+		return KVM_ARM_PSCI_LATEST;
+
+	return KVM_ARM_PSCI_0_1;
+}
+
+
+int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
+
+#endif /* __KVM_ARM_PSCI_H__ */
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index 4c5bca38..a031897 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -14,14 +14,16 @@
 #ifndef __LINUX_ARM_SMCCC_H
 #define __LINUX_ARM_SMCCC_H
 
+#include <uapi/linux/const.h>
+
 /*
  * This file provides common defines for ARM SMC Calling Convention as
  * specified in
  * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
  */
 
-#define ARM_SMCCC_STD_CALL		0
-#define ARM_SMCCC_FAST_CALL		1
+#define ARM_SMCCC_STD_CALL	        _AC(0,U)
+#define ARM_SMCCC_FAST_CALL	        _AC(1,U)
 #define ARM_SMCCC_TYPE_SHIFT		31
 
 #define ARM_SMCCC_SMC_32		0
@@ -60,6 +62,24 @@
 #define ARM_SMCCC_QUIRK_NONE		0
 #define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */
 
+#define ARM_SMCCC_VERSION_1_0		0x10000
+#define ARM_SMCCC_VERSION_1_1		0x10001
+
+#define ARM_SMCCC_VERSION_FUNC_ID					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   0, 0)
+
+#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   0, 1)
+
+#define ARM_SMCCC_ARCH_WORKAROUND_1					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   0, 0x8000)
+
 #ifndef __ASSEMBLY__
 
 #include <linux/linkage.h>
@@ -130,5 +150,146 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
 
 #define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
 
+/* SMCCC v1.1 implementation madness follows */
+#ifdef CONFIG_ARM64
+
+#define SMCCC_SMC_INST	"smc	#0"
+#define SMCCC_HVC_INST	"hvc	#0"
+
+#elif defined(CONFIG_ARM)
+#include <asm/opcodes-sec.h>
+#include <asm/opcodes-virt.h>
+
+#define SMCCC_SMC_INST	__SMC(0)
+#define SMCCC_HVC_INST	__HVC(0)
+
+#endif
+
+#define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x
+
+#define __count_args(...)						\
+	___count_args(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)
+
+#define __constraint_write_0						\
+	"+r" (r0), "=&r" (r1), "=&r" (r2), "=&r" (r3)
+#define __constraint_write_1						\
+	"+r" (r0), "+r" (r1), "=&r" (r2), "=&r" (r3)
+#define __constraint_write_2						\
+	"+r" (r0), "+r" (r1), "+r" (r2), "=&r" (r3)
+#define __constraint_write_3						\
+	"+r" (r0), "+r" (r1), "+r" (r2), "+r" (r3)
+#define __constraint_write_4	__constraint_write_3
+#define __constraint_write_5	__constraint_write_4
+#define __constraint_write_6	__constraint_write_5
+#define __constraint_write_7	__constraint_write_6
+
+#define __constraint_read_0
+#define __constraint_read_1
+#define __constraint_read_2
+#define __constraint_read_3
+#define __constraint_read_4	"r" (r4)
+#define __constraint_read_5	__constraint_read_4, "r" (r5)
+#define __constraint_read_6	__constraint_read_5, "r" (r6)
+#define __constraint_read_7	__constraint_read_6, "r" (r7)
+
+#define __declare_arg_0(a0, res)					\
+	struct arm_smccc_res   *___res = res;				\
+	register u32           r0 asm("r0") = a0;			\
+	register unsigned long r1 asm("r1");				\
+	register unsigned long r2 asm("r2");				\
+	register unsigned long r3 asm("r3")
+
+#define __declare_arg_1(a0, a1, res)					\
+	struct arm_smccc_res   *___res = res;				\
+	register u32           r0 asm("r0") = a0;			\
+	register typeof(a1)    r1 asm("r1") = a1;			\
+	register unsigned long r2 asm("r2");				\
+	register unsigned long r3 asm("r3")
+
+#define __declare_arg_2(a0, a1, a2, res)				\
+	struct arm_smccc_res   *___res = res;				\
+	register u32           r0 asm("r0") = a0;			\
+	register typeof(a1)    r1 asm("r1") = a1;			\
+	register typeof(a2)    r2 asm("r2") = a2;			\
+	register unsigned long r3 asm("r3")
+
+#define __declare_arg_3(a0, a1, a2, a3, res)				\
+	struct arm_smccc_res   *___res = res;				\
+	register u32           r0 asm("r0") = a0;			\
+	register typeof(a1)    r1 asm("r1") = a1;			\
+	register typeof(a2)    r2 asm("r2") = a2;			\
+	register typeof(a3)    r3 asm("r3") = a3
+
+#define __declare_arg_4(a0, a1, a2, a3, a4, res)			\
+	__declare_arg_3(a0, a1, a2, a3, res);				\
+	register typeof(a4) r4 asm("r4") = a4
+
+#define __declare_arg_5(a0, a1, a2, a3, a4, a5, res)			\
+	__declare_arg_4(a0, a1, a2, a3, a4, res);			\
+	register typeof(a5) r5 asm("r5") = a5
+
+#define __declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res)		\
+	__declare_arg_5(a0, a1, a2, a3, a4, a5, res);			\
+	register typeof(a6) r6 asm("r6") = a6
+
+#define __declare_arg_7(a0, a1, a2, a3, a4, a5, a6, a7, res)		\
+	__declare_arg_6(a0, a1, a2, a3, a4, a5, a6, res);		\
+	register typeof(a7) r7 asm("r7") = a7
+
+#define ___declare_args(count, ...) __declare_arg_ ## count(__VA_ARGS__)
+#define __declare_args(count, ...)  ___declare_args(count, __VA_ARGS__)
+
+#define ___constraints(count)						\
+	: __constraint_write_ ## count					\
+	: __constraint_read_ ## count					\
+	: "memory"
+#define __constraints(count)	___constraints(count)
+
+/*
+ * We have an output list that is not necessarily used, and GCC feels
+ * entitled to optimise the whole sequence away. "volatile" is what
+ * makes it stick.
+ */
+#define __arm_smccc_1_1(inst, ...)					\
+	do {								\
+		__declare_args(__count_args(__VA_ARGS__), __VA_ARGS__);	\
+		asm volatile(inst "\n"					\
+			     __constraints(__count_args(__VA_ARGS__)));	\
+		if (___res)						\
+			*___res = (typeof(*___res)){r0, r1, r2, r3};	\
+	} while (0)
+
+/*
+ * arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
+ *
+ * This is a variadic macro taking one to eight source arguments, and
+ * an optional return structure.
+ *
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ *
+ * This macro is used to make SMC calls following SMC Calling Convention v1.1.
+ * The content of the supplied param are copied to registers 0 to 7 prior
+ * to the SMC instruction. The return values are updated with the content
+ * from register 0 to 3 on return from the SMC instruction if not NULL.
+ */
+#define arm_smccc_1_1_smc(...)	__arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
+
+/*
+ * arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
+ *
+ * This is a variadic macro taking one to eight source arguments, and
+ * an optional return structure.
+ *
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ *
+ * This macro is used to make HVC calls following SMC Calling Convention v1.1.
+ * The content of the supplied param are copied to registers 0 to 7 prior
+ * to the HVC instruction. The return values are updated with the content
+ * from register 0 to 3 on return from the HVC instruction if not NULL.
+ */
+#define arm_smccc_1_1_hvc(...)	__arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
+
 #endif /*__ASSEMBLY__*/
 #endif /*__LINUX_ARM_SMCCC_H*/
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 3489253..5f11fbd 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -64,9 +64,14 @@
  *  bitmap_find_free_region(bitmap, bits, order)  Find and allocate bit region
  *  bitmap_release_region(bitmap, pos, order)   Free specified bit region
  *  bitmap_allocate_region(bitmap, pos, order)  Allocate specified bit region
- *  bitmap_from_u32array(dst, nbits, buf, nwords)  *dst = *buf (nwords 32b words)
- *  bitmap_to_u32array(buf, nwords, src, nbits) *buf = *dst (nwords 32b words)
+ *  bitmap_from_arr32(dst, buf, nbits)          Copy nbits from u32[] buf to dst
+ *  bitmap_to_arr32(buf, src, nbits)            Copy nbits from buf to u32[] dst
  *
+ * Note, bitmap_zero() and bitmap_fill() operate over the region of
+ * unsigned longs, that is, bits behind bitmap till the unsigned long
+ * boundary will be zeroed or filled as well. Consider to use
+ * bitmap_clear() or bitmap_set() to make explicit zeroing or filling
+ * respectively.
  */
 
 /**
@@ -83,8 +88,12 @@
  *  test_and_change_bit(bit, addr)      Change bit and return old value
  *  find_first_zero_bit(addr, nbits)    Position first zero bit in *addr
  *  find_first_bit(addr, nbits)         Position first set bit in *addr
- *  find_next_zero_bit(addr, nbits, bit)  Position next zero bit in *addr >= bit
+ *  find_next_zero_bit(addr, nbits, bit)
+ *                                      Position next zero bit in *addr >= bit
  *  find_next_bit(addr, nbits, bit)     Position next set bit in *addr >= bit
+ *  find_next_and_bit(addr1, addr2, nbits, bit)
+ *                                      Same as find_next_bit, but in
+ *                                      (*addr1 & *addr2)
  *
  */
 
@@ -174,14 +183,7 @@ extern void bitmap_fold(unsigned long *dst, const unsigned long *orig,
 extern int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order);
 extern void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order);
 extern int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order);
-extern unsigned int bitmap_from_u32array(unsigned long *bitmap,
-					 unsigned int nbits,
-					 const u32 *buf,
-					 unsigned int nwords);
-extern unsigned int bitmap_to_u32array(u32 *buf,
-				       unsigned int nwords,
-				       const unsigned long *bitmap,
-				       unsigned int nbits);
+
 #ifdef __BIG_ENDIAN
 extern void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits);
 #else
@@ -209,12 +211,12 @@ static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
 
 static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
 {
-	unsigned int nlongs = BITS_TO_LONGS(nbits);
-	if (!small_const_nbits(nbits)) {
-		unsigned int len = (nlongs - 1) * sizeof(unsigned long);
-		memset(dst, 0xff,  len);
+	if (small_const_nbits(nbits))
+		*dst = ~0UL;
+	else {
+		unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
+		memset(dst, 0xff, len);
 	}
-	dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
 }
 
 static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
@@ -228,6 +230,35 @@ static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
 	}
 }
 
+/*
+ * Copy bitmap and clear tail bits in last word.
+ */
+static inline void bitmap_copy_clear_tail(unsigned long *dst,
+		const unsigned long *src, unsigned int nbits)
+{
+	bitmap_copy(dst, src, nbits);
+	if (nbits % BITS_PER_LONG)
+		dst[nbits / BITS_PER_LONG] &= BITMAP_LAST_WORD_MASK(nbits);
+}
+
+/*
+ * On 32-bit systems bitmaps are represented as u32 arrays internally, and
+ * therefore conversion is not needed when copying data from/to arrays of u32.
+ */
+#if BITS_PER_LONG == 64
+extern void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf,
+							unsigned int nbits);
+extern void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap,
+							unsigned int nbits);
+#else
+#define bitmap_from_arr32(bitmap, buf, nbits)			\
+	bitmap_copy_clear_tail((unsigned long *) (bitmap),	\
+			(const unsigned long *) (buf), (nbits))
+#define bitmap_to_arr32(buf, bitmap, nbits)			\
+	bitmap_copy_clear_tail((unsigned long *) (buf),		\
+			(const unsigned long *) (bitmap), (nbits))
+#endif
+
 static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
 			const unsigned long *src2, unsigned int nbits)
 {
diff --git a/include/linux/build_bug.h b/include/linux/build_bug.h
index 3efed0d7..43d1fd5 100644
--- a/include/linux/build_bug.h
+++ b/include/linux/build_bug.h
@@ -8,7 +8,6 @@
 #define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
 #define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
 #define BUILD_BUG_ON_ZERO(e) (0)
-#define BUILD_BUG_ON_NULL(e) ((void *)0)
 #define BUILD_BUG_ON_INVALID(e) (0)
 #define BUILD_BUG_ON_MSG(cond, msg) (0)
 #define BUILD_BUG_ON(condition) (0)
@@ -28,7 +27,6 @@
  * aren't permitted).
  */
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
-#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:(-!!(e)); }))
 
 /*
  * BUILD_BUG_ON_INVALID() permits the compiler to check the validity of the
diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h
index 3b609ed..d02a4df 100644
--- a/include/linux/compiler-clang.h
+++ b/include/linux/compiler-clang.h
@@ -19,3 +19,11 @@
 
 #define randomized_struct_fields_start	struct {
 #define randomized_struct_fields_end	};
+
+/* all clang versions usable with the kernel support KASAN ABI version 5 */
+#define KASAN_ABI_VERSION 5
+
+/* emulate gcc's __SANITIZE_ADDRESS__ flag */
+#if __has_feature(address_sanitizer)
+#define __SANITIZE_ADDRESS__
+#endif
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 75b5651..d4a2a7d 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -640,7 +640,7 @@ static inline int cpulist_parse(const char *buf, struct cpumask *dstp)
 /**
  * cpumask_size - size to allocate for a 'struct cpumask' in bytes
  */
-static inline size_t cpumask_size(void)
+static inline unsigned int cpumask_size(void)
 {
 	return BITS_TO_LONGS(nr_cpumask_bits) * sizeof(long);
 }
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 1b8e415..934633a 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -112,7 +112,7 @@ static inline int cpuset_do_slab_mem_spread(void)
 	return task_spread_slab(current);
 }
 
-extern int current_cpuset_is_being_rebound(void);
+extern bool current_cpuset_is_being_rebound(void);
 
 extern void rebuild_sched_domains(void);
 
@@ -247,9 +247,9 @@ static inline int cpuset_do_slab_mem_spread(void)
 	return 0;
 }
 
-static inline int current_cpuset_is_being_rebound(void)
+static inline bool current_cpuset_is_being_rebound(void)
 {
-	return 0;
+	return false;
 }
 
 static inline void rebuild_sched_domains(void)
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
index a992e6c..f7ac2aa 100644
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -2,13 +2,13 @@
 #ifndef LINUX_CRASH_DUMP_H
 #define LINUX_CRASH_DUMP_H
 
-#ifdef CONFIG_CRASH_DUMP
 #include <linux/kexec.h>
 #include <linux/proc_fs.h>
 #include <linux/elf.h>
 
 #include <asm/pgtable.h> /* for pgprot_t */
 
+#ifdef CONFIG_CRASH_DUMP
 #define ELFCORE_ADDR_MAX	(-1ULL)
 #define ELFCORE_ADDR_ERR	(-2ULL)
 
@@ -52,13 +52,13 @@ void vmcore_cleanup(void);
  * has passed the elf core header address on command line.
  *
  * This is not just a test if CONFIG_CRASH_DUMP is enabled or not. It will
- * return 1 if CONFIG_CRASH_DUMP=y and if kernel is booting after a panic of
- * previous kernel.
+ * return true if CONFIG_CRASH_DUMP=y and if kernel is booting after a panic
+ * of previous kernel.
  */
 
-static inline int is_kdump_kernel(void)
+static inline bool is_kdump_kernel(void)
 {
-	return (elfcorehdr_addr != ELFCORE_ADDR_MAX) ? 1 : 0;
+	return elfcorehdr_addr != ELFCORE_ADDR_MAX;
 }
 
 /* is_vmcore_usable() checks if the kernel is booting after a panic and
@@ -89,7 +89,7 @@ extern int register_oldmem_pfn_is_ram(int (*fn)(unsigned long pfn));
 extern void unregister_oldmem_pfn_is_ram(void);
 
 #else /* !CONFIG_CRASH_DUMP */
-static inline int is_kdump_kernel(void) { return 0; }
+static inline bool is_kdump_kernel(void) { return 0; }
 #endif /* CONFIG_CRASH_DUMP */
 
 extern unsigned long saved_max_pfn;
diff --git a/include/linux/fb.h b/include/linux/fb.h
index d1e5bed..f577d3c 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -569,7 +569,10 @@ static inline struct apertures_struct *alloc_apertures(unsigned int max_num) {
 #define fb_memcpy_fromfb sbus_memcpy_fromio
 #define fb_memcpy_tofb sbus_memcpy_toio
 
-#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) || defined(__arm__)
+#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) ||	\
+	defined(__hppa__) || defined(__sh__) || defined(__powerpc__) ||	\
+	defined(__avr32__) || defined(__bfin__) || defined(__arm__) ||	\
+	defined(__aarch64__)
 
 #define fb_readb __raw_readb
 #define fb_readw __raw_readw
diff --git a/include/linux/genl_magic_func.h b/include/linux/genl_magic_func.h
index 6049676..83f81ac 100644
--- a/include/linux/genl_magic_func.h
+++ b/include/linux/genl_magic_func.h
@@ -2,6 +2,7 @@
 #ifndef GENL_MAGIC_FUNC_H
 #define GENL_MAGIC_FUNC_H
 
+#include <linux/build_bug.h>
 #include <linux/genl_magic_struct.h>
 
 /*
@@ -132,17 +133,6 @@ static void dprint_array(const char *dir, int nla_type,
  * use one static buffer for parsing of nested attributes */
 static struct nlattr *nested_attr_tb[128];
 
-#ifndef BUILD_BUG_ON
-/* Force a compilation error if condition is true */
-#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition))
-/* Force a compilation error if condition is true, but also produce a
-   result (of value 0 and type size_t), so the expression can be used
-   e.g. in a structure initializer (or where-ever else comma expressions
-   aren't permitted). */
-#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
-#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
-#endif
-
 #undef GENL_struct
 #define GENL_struct(tag_name, tag_number, s_name, s_fields)		\
 /* *_from_attrs functions are static, but potentially unused */		\
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index f3274d9..8dad3dd 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -83,7 +83,9 @@
 /*
  * Decoding Capability Register
  */
+#define cap_5lp_support(c)	(((c) >> 60) & 1)
 #define cap_pi_support(c)	(((c) >> 59) & 1)
+#define cap_fl1gp_support(c)	(((c) >> 56) & 1)
 #define cap_read_drain(c)	(((c) >> 55) & 1)
 #define cap_write_drain(c)	(((c) >> 54) & 1)
 #define cap_max_amask_val(c)	(((c) >> 48) & 0x3f)
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 93b4183..da0ebae 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -265,7 +265,7 @@ extern struct resource * __devm_request_region(struct device *dev,
 extern void __devm_release_region(struct device *dev, struct resource *parent,
 				  resource_size_t start, resource_size_t n);
 extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size);
-extern int iomem_is_exclusive(u64 addr);
+extern bool iomem_is_exclusive(u64 addr);
 
 extern int
 walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
diff --git a/include/linux/iversion.h b/include/linux/iversion.h
index 3d2fd06..be50ef7 100644
--- a/include/linux/iversion.h
+++ b/include/linux/iversion.h
@@ -45,7 +45,7 @@
  *
  * With this implementation, the value should always appear to observers to
  * increase over time if the file has changed. It's recommended to use
- * inode_cmp_iversion() helper to compare values.
+ * inode_eq_iversion() helper to compare values.
  *
  * Note that some filesystems (e.g. NFS and AFS) just use the field to store
  * a server-provided value (for the most part). For that reason, those
@@ -305,33 +305,33 @@ inode_query_iversion(struct inode *inode)
 }
 
 /**
- * inode_cmp_iversion_raw - check whether the raw i_version counter has changed
+ * inode_eq_iversion_raw - check whether the raw i_version counter has changed
  * @inode: inode to check
  * @old: old value to check against its i_version
  *
- * Compare the current raw i_version counter with a previous one. Returns false
- * if they are the same or true if they are different.
+ * Compare the current raw i_version counter with a previous one. Returns true
+ * if they are the same or false if they are different.
  */
 static inline bool
-inode_cmp_iversion_raw(const struct inode *inode, u64 old)
+inode_eq_iversion_raw(const struct inode *inode, u64 old)
 {
-	return inode_peek_iversion_raw(inode) != old;
+	return inode_peek_iversion_raw(inode) == old;
 }
 
 /**
- * inode_cmp_iversion - check whether the i_version counter has changed
+ * inode_eq_iversion - check whether the i_version counter has changed
  * @inode: inode to check
  * @old: old value to check against its i_version
  *
- * Compare an i_version counter with a previous one. Returns false if they are
- * the same, and true if they are different.
+ * Compare an i_version counter with a previous one. Returns true if they are
+ * the same, and false if they are different.
  *
  * Note that we don't need to set the QUERIED flag in this case, as the value
  * in the inode is not being recorded for later use.
  */
 static inline bool
-inode_cmp_iversion(const struct inode *inode, u64 old)
+inode_eq_iversion(const struct inode *inode, u64 old)
 {
-	return inode_peek_iversion(inode) != old;
+	return inode_peek_iversion(inode) == old;
 }
 #endif
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index e0340ca..b6a29c1 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -393,7 +393,7 @@ extern bool ____wrong_branch_error(void);
 		branch = !arch_static_branch_jump(&(x)->key, true);		\
 	else									\
 		branch = ____wrong_branch_error();				\
-	branch;									\
+	likely(branch);								\
 })
 
 #define static_branch_unlikely(x)						\
@@ -405,7 +405,7 @@ extern bool ____wrong_branch_error(void);
 		branch = arch_static_branch(&(x)->key, false);			\
 	else									\
 		branch = ____wrong_branch_error();				\
-	branch;									\
+	unlikely(branch);							\
 })
 
 #else /* !HAVE_JUMP_LABEL */
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index d79d1e7..657a83b 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -167,7 +167,7 @@ static inline int kallsyms_show_value(void)
 
 static inline void print_ip_sym(unsigned long ip)
 {
-	printk("[<%p>] %pS\n", (void *) ip, (void *) ip);
+	printk("[<%px>] %pS\n", (void *) ip, (void *) ip);
 }
 
 #endif /*_LINUX_KALLSYMS_H*/
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index e3eb834..adc1347 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -11,8 +11,6 @@ struct task_struct;
 
 #ifdef CONFIG_KASAN
 
-#define KASAN_SHADOW_SCALE_SHIFT 3
-
 #include <asm/kasan.h>
 #include <asm/pgtable.h>
 
@@ -56,14 +54,14 @@ void kasan_poison_object_data(struct kmem_cache *cache, void *object);
 void kasan_init_slab_obj(struct kmem_cache *cache, const void *object);
 
 void kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags);
-void kasan_kfree_large(const void *ptr);
-void kasan_poison_kfree(void *ptr);
+void kasan_kfree_large(void *ptr, unsigned long ip);
+void kasan_poison_kfree(void *ptr, unsigned long ip);
 void kasan_kmalloc(struct kmem_cache *s, const void *object, size_t size,
 		  gfp_t flags);
 void kasan_krealloc(const void *object, size_t new_size, gfp_t flags);
 
 void kasan_slab_alloc(struct kmem_cache *s, void *object, gfp_t flags);
-bool kasan_slab_free(struct kmem_cache *s, void *object);
+bool kasan_slab_free(struct kmem_cache *s, void *object, unsigned long ip);
 
 struct kasan_cache {
 	int alloc_meta_offset;
@@ -108,8 +106,8 @@ static inline void kasan_init_slab_obj(struct kmem_cache *cache,
 				const void *object) {}
 
 static inline void kasan_kmalloc_large(void *ptr, size_t size, gfp_t flags) {}
-static inline void kasan_kfree_large(const void *ptr) {}
-static inline void kasan_poison_kfree(void *ptr) {}
+static inline void kasan_kfree_large(void *ptr, unsigned long ip) {}
+static inline void kasan_poison_kfree(void *ptr, unsigned long ip) {}
 static inline void kasan_kmalloc(struct kmem_cache *s, const void *object,
 				size_t size, gfp_t flags) {}
 static inline void kasan_krealloc(const void *object, size_t new_size,
@@ -117,7 +115,8 @@ static inline void kasan_krealloc(const void *object, size_t new_size,
 
 static inline void kasan_slab_alloc(struct kmem_cache *s, void *object,
 				   gfp_t flags) {}
-static inline bool kasan_slab_free(struct kmem_cache *s, void *object)
+static inline bool kasan_slab_free(struct kmem_cache *s, void *object,
+				   unsigned long ip)
 {
 	return false;
 }
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
index 7b45959..e251533 100644
--- a/include/linux/kfifo.h
+++ b/include/linux/kfifo.h
@@ -113,7 +113,8 @@ struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void);
  * array is a part of the structure and the fifo type where the array is
  * outside of the fifo structure.
  */
-#define	__is_kfifo_ptr(fifo)	(sizeof(*fifo) == sizeof(struct __kfifo))
+#define	__is_kfifo_ptr(fifo) \
+	(sizeof(*fifo) == sizeof(STRUCT_KFIFO_PTR(typeof(*(fifo)->type))))
 
 /**
  * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object
diff --git a/include/linux/led-class-flash.h b/include/linux/led-class-flash.h
index e97966d..700efaa 100644
--- a/include/linux/led-class-flash.h
+++ b/include/linux/led-class-flash.h
@@ -121,6 +121,8 @@ extern void led_classdev_flash_unregister(struct led_classdev_flash *fled_cdev);
 static inline int led_set_flash_strobe(struct led_classdev_flash *fled_cdev,
 					bool state)
 {
+	if (!fled_cdev)
+		return -EINVAL;
 	return fled_cdev->ops->strobe_set(fled_cdev, state);
 }
 
@@ -136,6 +138,8 @@ static inline int led_set_flash_strobe(struct led_classdev_flash *fled_cdev,
 static inline int led_get_flash_strobe(struct led_classdev_flash *fled_cdev,
 					bool *state)
 {
+	if (!fled_cdev)
+		return -EINVAL;
 	if (fled_cdev->ops->strobe_get)
 		return fled_cdev->ops->strobe_get(fled_cdev, state);
 
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index f8109dd..ff855ed 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -47,6 +47,17 @@ enum {
 
 	/* region flag indicating to direct-map persistent memory by default */
 	ND_REGION_PAGEMAP = 0,
+	/*
+	 * Platform ensures entire CPU store data path is flushed to pmem on
+	 * system power loss.
+	 */
+	ND_REGION_PERSIST_CACHE = 1,
+	/*
+	 * Platform provides mechanisms to automatically flush outstanding
+	 * write data from memory controler to pmem on system power loss.
+	 * (ADR)
+	 */
+	ND_REGION_PERSIST_MEMCTRL = 2,
 
 	/* mark newly adjusted resources as requiring a label update */
 	DPA_RESOURCE_ADJUSTED = 1 << 0,
diff --git a/include/linux/lockref.h b/include/linux/lockref.h
index ef3c934..2eac320 100644
--- a/include/linux/lockref.h
+++ b/include/linux/lockref.h
@@ -44,7 +44,7 @@ extern void lockref_mark_dead(struct lockref *);
 extern int lockref_get_not_dead(struct lockref *);
 
 /* Must be called under spinlock for reliable results */
-static inline int __lockref_is_dead(const struct lockref *l)
+static inline bool __lockref_is_dead(const struct lockref *l)
 {
 	return ((int)l->count < 0);
 }
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 7ed0f77..8be5077 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -332,8 +332,8 @@ void memblock_enforce_memory_limit(phys_addr_t memory_limit);
 void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
 void memblock_mem_limit_remove_map(phys_addr_t limit);
 bool memblock_is_memory(phys_addr_t addr);
-int memblock_is_map_memory(phys_addr_t addr);
-int memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
+bool memblock_is_map_memory(phys_addr_t addr);
+bool memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
 bool memblock_is_reserved(phys_addr_t addr);
 bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size);
 
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 58e110a..aba5f86 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -13,6 +13,7 @@ struct pglist_data;
 struct mem_section;
 struct memory_block;
 struct resource;
+struct vmem_altmap;
 
 #ifdef CONFIG_MEMORY_HOTPLUG
 /*
@@ -125,24 +126,26 @@ static inline bool movable_node_is_enabled(void)
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
 extern bool is_pageblock_removable_nolock(struct page *page);
-extern int arch_remove_memory(u64 start, u64 size);
+extern int arch_remove_memory(u64 start, u64 size,
+		struct vmem_altmap *altmap);
 extern int __remove_pages(struct zone *zone, unsigned long start_pfn,
-	unsigned long nr_pages);
+	unsigned long nr_pages, struct vmem_altmap *altmap);
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
 /* reasonably generic interface to expand the physical pages */
-extern int __add_pages(int nid, unsigned long start_pfn,
-	unsigned long nr_pages, bool want_memblock);
+extern int __add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
+		struct vmem_altmap *altmap, bool want_memblock);
 
 #ifndef CONFIG_ARCH_HAS_ADD_PAGES
 static inline int add_pages(int nid, unsigned long start_pfn,
-			    unsigned long nr_pages, bool want_memblock)
+		unsigned long nr_pages, struct vmem_altmap *altmap,
+		bool want_memblock)
 {
-	return __add_pages(nid, start_pfn, nr_pages, want_memblock);
+	return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
 }
 #else /* ARCH_HAS_ADD_PAGES */
-int add_pages(int nid, unsigned long start_pfn,
-	      unsigned long nr_pages, bool want_memblock);
+int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
+		struct vmem_altmap *altmap, bool want_memblock);
 #endif /* ARCH_HAS_ADD_PAGES */
 
 #ifdef CONFIG_NUMA
@@ -318,15 +321,17 @@ extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
 		void *arg, int (*func)(struct memory_block *, void *));
 extern int add_memory(int nid, u64 start, u64 size);
 extern int add_memory_resource(int nid, struct resource *resource, bool online);
-extern int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock);
+extern int arch_add_memory(int nid, u64 start, u64 size,
+		struct vmem_altmap *altmap, bool want_memblock);
 extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
-		unsigned long nr_pages);
+		unsigned long nr_pages, struct vmem_altmap *altmap);
 extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
 extern bool is_memblock_offlined(struct memory_block *mem);
 extern void remove_memory(int nid, u64 start, u64 size);
-extern int sparse_add_one_section(struct pglist_data *pgdat, unsigned long start_pfn);
+extern int sparse_add_one_section(struct pglist_data *pgdat,
+		unsigned long start_pfn, struct vmem_altmap *altmap);
 extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms,
-		unsigned long map_offset);
+		unsigned long map_offset, struct vmem_altmap *altmap);
 extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
 					  unsigned long pnum);
 extern bool allow_online_pfn_range(int nid, unsigned long pfn, unsigned long nr_pages,
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 10d23c36..7b4899c0 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -26,18 +26,6 @@ struct vmem_altmap {
 	unsigned long alloc;
 };
 
-unsigned long vmem_altmap_offset(struct vmem_altmap *altmap);
-void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns);
-
-#ifdef CONFIG_ZONE_DEVICE
-struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start);
-#else
-static inline struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start)
-{
-	return NULL;
-}
-#endif
-
 /*
  * Specialize ZONE_DEVICE memory into multiple types each having differents
  * usage.
@@ -125,8 +113,9 @@ typedef void (*dev_page_free_t)(struct page *page, void *data);
 struct dev_pagemap {
 	dev_page_fault_t page_fault;
 	dev_page_free_t page_free;
-	struct vmem_altmap *altmap;
-	const struct resource *res;
+	struct vmem_altmap altmap;
+	bool altmap_valid;
+	struct resource res;
 	struct percpu_ref *ref;
 	struct device *dev;
 	void *data;
@@ -134,15 +123,17 @@ struct dev_pagemap {
 };
 
 #ifdef CONFIG_ZONE_DEVICE
-void *devm_memremap_pages(struct device *dev, struct resource *res,
-		struct percpu_ref *ref, struct vmem_altmap *altmap);
-struct dev_pagemap *find_dev_pagemap(resource_size_t phys);
+void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap);
+struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
+		struct dev_pagemap *pgmap);
+
+unsigned long vmem_altmap_offset(struct vmem_altmap *altmap);
+void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns);
 
 static inline bool is_zone_device_page(const struct page *page);
 #else
 static inline void *devm_memremap_pages(struct device *dev,
-		struct resource *res, struct percpu_ref *ref,
-		struct vmem_altmap *altmap)
+		struct dev_pagemap *pgmap)
 {
 	/*
 	 * Fail attempts to call devm_memremap_pages() without
@@ -153,11 +144,22 @@ static inline void *devm_memremap_pages(struct device *dev,
 	return ERR_PTR(-ENXIO);
 }
 
-static inline struct dev_pagemap *find_dev_pagemap(resource_size_t phys)
+static inline struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
+		struct dev_pagemap *pgmap)
 {
 	return NULL;
 }
-#endif
+
+static inline unsigned long vmem_altmap_offset(struct vmem_altmap *altmap)
+{
+	return 0;
+}
+
+static inline void vmem_altmap_free(struct vmem_altmap *altmap,
+		unsigned long nr_pfns)
+{
+}
+#endif /* CONFIG_ZONE_DEVICE */
 
 #if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC)
 static inline bool is_device_private_page(const struct page *page)
@@ -173,39 +175,6 @@ static inline bool is_device_public_page(const struct page *page)
 }
 #endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */
 
-/**
- * get_dev_pagemap() - take a new live reference on the dev_pagemap for @pfn
- * @pfn: page frame number to lookup page_map
- * @pgmap: optional known pgmap that already has a reference
- *
- * @pgmap allows the overhead of a lookup to be bypassed when @pfn lands in the
- * same mapping.
- */
-static inline struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
-		struct dev_pagemap *pgmap)
-{
-	const struct resource *res = pgmap ? pgmap->res : NULL;
-	resource_size_t phys = PFN_PHYS(pfn);
-
-	/*
-	 * In the cached case we're already holding a live reference so
-	 * we can simply do a blind increment
-	 */
-	if (res && phys >= res->start && phys <= res->end) {
-		percpu_ref_get(pgmap->ref);
-		return pgmap;
-	}
-
-	/* fall back to slow path lookup */
-	rcu_read_lock();
-	pgmap = find_dev_pagemap(phys);
-	if (pgmap && !percpu_ref_tryget_live(pgmap->ref))
-		pgmap = NULL;
-	rcu_read_unlock();
-
-	return pgmap;
-}
-
 static inline void put_dev_pagemap(struct dev_pagemap *pgmap)
 {
 	if (pgmap)
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index fb7e8b2..6ed79a8 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -1277,7 +1277,7 @@ mlx5_get_vector_affinity(struct mlx5_core_dev *dev, int vector)
 	int eqn;
 	int err;
 
-	err = mlx5_vector2eqn(dev, vector, &eqn, &irq);
+	err = mlx5_vector2eqn(dev, MLX5_EQ_VEC_COMP_BASE + vector, &eqn, &irq);
 	if (err)
 		return NULL;
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 173d248..ad06d42 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2075,8 +2075,8 @@ static inline void zero_resv_unavail(void) {}
 #endif
 
 extern void set_dma_reserve(unsigned long new_dma_reserve);
-extern void memmap_init_zone(unsigned long, int, unsigned long,
-				unsigned long, enum memmap_context);
+extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long,
+		enum memmap_context, struct vmem_altmap *);
 extern void setup_per_zone_wmarks(void);
 extern int __meminit init_per_zone_wmark_min(void);
 extern void mem_init(void);
@@ -2544,7 +2544,8 @@ void sparse_mem_maps_populate_node(struct page **map_map,
 				   unsigned long map_count,
 				   int nodeid);
 
-struct page *sparse_mem_map_populate(unsigned long pnum, int nid);
+struct page *sparse_mem_map_populate(unsigned long pnum, int nid,
+		struct vmem_altmap *altmap);
 pgd_t *vmemmap_pgd_populate(unsigned long addr, int node);
 p4d_t *vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node);
 pud_t *vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node);
@@ -2552,20 +2553,17 @@ pmd_t *vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node);
 pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node);
 void *vmemmap_alloc_block(unsigned long size, int node);
 struct vmem_altmap;
-void *__vmemmap_alloc_block_buf(unsigned long size, int node,
-		struct vmem_altmap *altmap);
-static inline void *vmemmap_alloc_block_buf(unsigned long size, int node)
-{
-	return __vmemmap_alloc_block_buf(size, node, NULL);
-}
-
+void *vmemmap_alloc_block_buf(unsigned long size, int node);
+void *altmap_alloc_block_buf(unsigned long size, struct vmem_altmap *altmap);
 void vmemmap_verify(pte_t *, int, unsigned long, unsigned long);
 int vmemmap_populate_basepages(unsigned long start, unsigned long end,
 			       int node);
-int vmemmap_populate(unsigned long start, unsigned long end, int node);
+int vmemmap_populate(unsigned long start, unsigned long end, int node,
+		struct vmem_altmap *altmap);
 void vmemmap_populate_print_last(void);
 #ifdef CONFIG_MEMORY_HOTPLUG
-void vmemmap_free(unsigned long start, unsigned long end);
+void vmemmap_free(unsigned long start, unsigned long end,
+		struct vmem_altmap *altmap);
 #endif
 void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
 				  unsigned long nr_pages);
diff --git a/include/linux/module.h b/include/linux/module.h
index 8dc7065..d44df9b 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -491,7 +491,7 @@ extern struct mutex module_mutex;
 /* FIXME: It'd be nice to isolate modules during init, too, so they
    aren't used before they (may) fail.  But presently too much code
    (IDE & SCSI) require entry into the module during init.*/
-static inline int module_is_live(struct module *mod)
+static inline bool module_is_live(struct module *mod)
 {
 	return mod->state != MODULE_STATE_GOING;
 }
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 153274f..f25c134 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -138,9 +138,9 @@ extern void __mutex_init(struct mutex *lock, const char *name,
  * mutex_is_locked - is the mutex locked
  * @lock: the mutex to be queried
  *
- * Returns 1 if the mutex is locked, 0 if unlocked.
+ * Returns true if the mutex is locked, false if unlocked.
  */
-static inline int mutex_is_locked(struct mutex *lock)
+static inline bool mutex_is_locked(struct mutex *lock)
 {
 	/*
 	 * XXX think about spin_is_locked
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 4c77f39..5eef6c8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3228,6 +3228,12 @@ static inline int netif_set_real_num_rx_queues(struct net_device *dev,
 }
 #endif
 
+static inline struct netdev_rx_queue *
+__netif_get_rx_queue(struct net_device *dev, unsigned int rxq)
+{
+	return dev->_rx + rxq;
+}
+
 #ifdef CONFIG_SYSFS
 static inline unsigned int get_netdev_rx_queue_index(
 		struct netdev_rx_queue *queue)
diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h
index cddfaff..4fa654e 100644
--- a/include/linux/of_iommu.h
+++ b/include/linux/of_iommu.h
@@ -34,9 +34,6 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev,
 
 extern struct of_device_id __iommu_of_table;
 
-typedef int (*of_iommu_init_fn)(struct device_node *);
-
-#define IOMMU_OF_DECLARE(name, compat, fn) \
-	_OF_DECLARE(iommu, name, compat, fn, of_iommu_init_fn)
+#define IOMMU_OF_DECLARE(name, compat)	OF_DECLARE_1(iommu, name, compat, NULL)
 
 #endif /* __OF_IOMMU_H */
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index bf588a0..88865e0 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -9,8 +9,7 @@ struct pci_dev;
 struct of_phandle_args;
 struct device_node;
 
-#ifdef CONFIG_OF_PCI
-int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq);
+#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_PCI)
 struct device_node *of_pci_find_child_device(struct device_node *parent,
 					     unsigned int devfn);
 int of_pci_get_devfn(struct device_node *np);
@@ -23,11 +22,6 @@ int of_pci_map_rid(struct device_node *np, u32 rid,
 		   const char *map_name, const char *map_mask_name,
 		   struct device_node **target, u32 *id_out);
 #else
-static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
-{
-	return 0;
-}
-
 static inline struct device_node *of_pci_find_child_device(struct device_node *parent,
 					     unsigned int devfn)
 {
diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h
index 3cc06b0..df28af5 100644
--- a/include/linux/pci-aspm.h
+++ b/include/linux/pci-aspm.h
@@ -24,43 +24,12 @@
 #define PCIE_LINK_STATE_CLKPM	4
 
 #ifdef CONFIG_PCIEASPM
-void pcie_aspm_init_link_state(struct pci_dev *pdev);
-void pcie_aspm_exit_link_state(struct pci_dev *pdev);
-void pcie_aspm_pm_state_change(struct pci_dev *pdev);
-void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
 void pci_disable_link_state(struct pci_dev *pdev, int state);
 void pci_disable_link_state_locked(struct pci_dev *pdev, int state);
 void pcie_no_aspm(void);
 #else
-static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
-{
-}
-static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev)
-{
-}
-static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev)
-{
-}
-static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
-{
-}
-static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
-{
-}
-static inline void pcie_no_aspm(void)
-{
-}
+static inline void pci_disable_link_state(struct pci_dev *pdev, int state) { }
+static inline void pcie_no_aspm(void) { }
 #endif
 
-#ifdef CONFIG_PCIEASPM_DEBUG /* this depends on CONFIG_PCIEASPM */
-void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev);
-void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev);
-#else
-static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
-{
-}
-static inline void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
-{
-}
-#endif
 #endif /* LINUX_ASPM_H */
diff --git a/include/linux/pci-dma-compat.h b/include/linux/pci-dma-compat.h
index d1f9fda..0dd1a3f 100644
--- a/include/linux/pci-dma-compat.h
+++ b/include/linux/pci-dma-compat.h
@@ -17,91 +17,90 @@ static inline void *
 pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 		     dma_addr_t *dma_handle)
 {
-	return dma_alloc_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, dma_handle, GFP_ATOMIC);
+	return dma_alloc_coherent(&hwdev->dev, size, dma_handle, GFP_ATOMIC);
 }
 
 static inline void *
 pci_zalloc_consistent(struct pci_dev *hwdev, size_t size,
 		      dma_addr_t *dma_handle)
 {
-	return dma_zalloc_coherent(hwdev == NULL ? NULL : &hwdev->dev,
-				   size, dma_handle, GFP_ATOMIC);
+	return dma_zalloc_coherent(&hwdev->dev, size, dma_handle, GFP_ATOMIC);
 }
 
 static inline void
 pci_free_consistent(struct pci_dev *hwdev, size_t size,
 		    void *vaddr, dma_addr_t dma_handle)
 {
-	dma_free_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, vaddr, dma_handle);
+	dma_free_coherent(&hwdev->dev, size, vaddr, dma_handle);
 }
 
 static inline dma_addr_t
 pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
 {
-	return dma_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction);
+	return dma_map_single(&hwdev->dev, ptr, size, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
 		 size_t size, int direction)
 {
-	dma_unmap_single(hwdev == NULL ? NULL : &hwdev->dev, dma_addr, size, (enum dma_data_direction)direction);
+	dma_unmap_single(&hwdev->dev, dma_addr, size, (enum dma_data_direction)direction);
 }
 
 static inline dma_addr_t
 pci_map_page(struct pci_dev *hwdev, struct page *page,
 	     unsigned long offset, size_t size, int direction)
 {
-	return dma_map_page(hwdev == NULL ? NULL : &hwdev->dev, page, offset, size, (enum dma_data_direction)direction);
+	return dma_map_page(&hwdev->dev, page, offset, size, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
 	       size_t size, int direction)
 {
-	dma_unmap_page(hwdev == NULL ? NULL : &hwdev->dev, dma_address, size, (enum dma_data_direction)direction);
+	dma_unmap_page(&hwdev->dev, dma_address, size, (enum dma_data_direction)direction);
 }
 
 static inline int
 pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 	   int nents, int direction)
 {
-	return dma_map_sg(hwdev == NULL ? NULL : &hwdev->dev, sg, nents, (enum dma_data_direction)direction);
+	return dma_map_sg(&hwdev->dev, sg, nents, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
 	     int nents, int direction)
 {
-	dma_unmap_sg(hwdev == NULL ? NULL : &hwdev->dev, sg, nents, (enum dma_data_direction)direction);
+	dma_unmap_sg(&hwdev->dev, sg, nents, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle,
 		    size_t size, int direction)
 {
-	dma_sync_single_for_cpu(hwdev == NULL ? NULL : &hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
+	dma_sync_single_for_cpu(&hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle,
 		    size_t size, int direction)
 {
-	dma_sync_single_for_device(hwdev == NULL ? NULL : &hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
+	dma_sync_single_for_device(&hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg,
 		int nelems, int direction)
 {
-	dma_sync_sg_for_cpu(hwdev == NULL ? NULL : &hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
+	dma_sync_sg_for_cpu(&hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
 }
 
 static inline void
 pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg,
 		int nelems, int direction)
 {
-	dma_sync_sg_for_device(hwdev == NULL ? NULL : &hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
+	dma_sync_sg_for_device(&hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
 }
 
 static inline int
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
index 809c2f1..baadad1 100644
--- a/include/linux/pci-ecam.h
+++ b/include/linux/pci-ecam.h
@@ -1,17 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright 2016 Broadcom
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation (the "GPL").
- *
- * 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 version 2 (GPLv2) for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 (GPLv2) along with this source code.
  */
 #ifndef DRIVERS_PCI_ECAM_H
 #define DRIVERS_PCI_ECAM_H
diff --git a/include/linux/pci-ep-cfs.h b/include/linux/pci-ep-cfs.h
index 263b89e..f42b0fd 100644
--- a/include/linux/pci-ep-cfs.h
+++ b/include/linux/pci-ep-cfs.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /**
  * PCI Endpoint ConfigFS header file
  *
  * Copyright (C) 2017 Texas Instruments
  * Author: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 of
- * the License as published by the Free Software Foundation.
  */
 
 #ifndef __LINUX_PCI_EP_CFS_H
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index f7a04e1..a1a5e5d 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /**
  * PCI Endpoint *Controller* (EPC) header file
  *
  * Copyright (C) 2017 Texas Instruments
  * Author: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 of
- * the License as published by the Free Software Foundation.
  */
 
 #ifndef __LINUX_PCI_EPC_H
@@ -39,17 +36,20 @@ enum pci_epc_irq_type {
  * @owner: the module owner containing the ops
  */
 struct pci_epc_ops {
-	int	(*write_header)(struct pci_epc *pci_epc,
+	int	(*write_header)(struct pci_epc *epc, u8 func_no,
 				struct pci_epf_header *hdr);
-	int	(*set_bar)(struct pci_epc *epc, enum pci_barno bar,
+	int	(*set_bar)(struct pci_epc *epc, u8 func_no,
+			   enum pci_barno bar,
 			   dma_addr_t bar_phys, size_t size, int flags);
-	void	(*clear_bar)(struct pci_epc *epc, enum pci_barno bar);
-	int	(*map_addr)(struct pci_epc *epc, phys_addr_t addr,
-			    u64 pci_addr, size_t size);
-	void	(*unmap_addr)(struct pci_epc *epc, phys_addr_t addr);
-	int	(*set_msi)(struct pci_epc *epc, u8 interrupts);
-	int	(*get_msi)(struct pci_epc *epc);
-	int	(*raise_irq)(struct pci_epc *pci_epc,
+	void	(*clear_bar)(struct pci_epc *epc, u8 func_no,
+			     enum pci_barno bar);
+	int	(*map_addr)(struct pci_epc *epc, u8 func_no,
+			    phys_addr_t addr, u64 pci_addr, size_t size);
+	void	(*unmap_addr)(struct pci_epc *epc, u8 func_no,
+			      phys_addr_t addr);
+	int	(*set_msi)(struct pci_epc *epc, u8 func_no, u8 interrupts);
+	int	(*get_msi)(struct pci_epc *epc, u8 func_no);
+	int	(*raise_irq)(struct pci_epc *epc, u8 func_no,
 			     enum pci_epc_irq_type type, u8 interrupt_num);
 	int	(*start)(struct pci_epc *epc);
 	void	(*stop)(struct pci_epc *epc);
@@ -124,17 +124,21 @@ void pci_epc_destroy(struct pci_epc *epc);
 int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf);
 void pci_epc_linkup(struct pci_epc *epc);
 void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf);
-int pci_epc_write_header(struct pci_epc *epc, struct pci_epf_header *hdr);
-int pci_epc_set_bar(struct pci_epc *epc, enum pci_barno bar,
+int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
+			 struct pci_epf_header *hdr);
+int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
+		    enum pci_barno bar,
 		    dma_addr_t bar_phys, size_t size, int flags);
-void pci_epc_clear_bar(struct pci_epc *epc, int bar);
-int pci_epc_map_addr(struct pci_epc *epc, phys_addr_t phys_addr,
+void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, int bar);
+int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
+		     phys_addr_t phys_addr,
 		     u64 pci_addr, size_t size);
-void pci_epc_unmap_addr(struct pci_epc *epc, phys_addr_t phys_addr);
-int pci_epc_set_msi(struct pci_epc *epc, u8 interrupts);
-int pci_epc_get_msi(struct pci_epc *epc);
-int pci_epc_raise_irq(struct pci_epc *epc, enum pci_epc_irq_type type,
-		      u8 interrupt_num);
+void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
+			phys_addr_t phys_addr);
+int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
+int pci_epc_get_msi(struct pci_epc *epc, u8 func_no);
+int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+		      enum pci_epc_irq_type type, u8 interrupt_num);
 int pci_epc_start(struct pci_epc *epc);
 void pci_epc_stop(struct pci_epc *epc);
 struct pci_epc *pci_epc_get(const char *epc_name);
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 60d551a..e897bf0 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /**
  * PCI Endpoint *Function* (EPF) header file
  *
  * Copyright (C) 2017 Texas Instruments
  * Author: Kishon Vijay Abraham I <kishon@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 of
- * the License as published by the Free Software Foundation.
  */
 
 #ifndef __LINUX_PCI_EPF_H
diff --git a/include/linux/pci.h b/include/linux/pci.h
index ad35aac..024a1be 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -48,17 +48,17 @@
  * In the interest of not exposing interfaces to user-space unnecessarily,
  * the following kernel-only defines are being added here.
  */
-#define PCI_DEVID(bus, devfn)  ((((u16)(bus)) << 8) | (devfn))
+#define PCI_DEVID(bus, devfn)	((((u16)(bus)) << 8) | (devfn))
 /* return bus from PCI devid = ((u16)bus_number) << 8) | devfn */
 #define PCI_BUS_NUM(x) (((x) >> 8) & 0xff)
 
 /* pci_slot represents a physical slot */
 struct pci_slot {
-	struct pci_bus *bus;		/* The bus this slot is on */
-	struct list_head list;		/* node in list of slots on this bus */
-	struct hotplug_slot *hotplug;	/* Hotplug info (migrate over time) */
-	unsigned char number;		/* PCI_SLOT(pci_dev->devfn) */
-	struct kobject kobj;
+	struct pci_bus		*bus;		/* Bus this slot is on */
+	struct list_head	list;		/* Node in list of slots */
+	struct hotplug_slot	*hotplug;	/* Hotplug info (move here) */
+	unsigned char		number;		/* PCI_SLOT(pci_dev->devfn) */
+	struct kobject		kobj;
 };
 
 static inline const char *pci_slot_name(const struct pci_slot *slot)
@@ -72,9 +72,7 @@ enum pci_mmap_state {
 	pci_mmap_mem
 };
 
-/*
- *  For PCI devices, the region numbers are assigned this way:
- */
+/* For PCI devices, the region numbers are assigned this way: */
 enum {
 	/* #0-5: standard PCI resources */
 	PCI_STD_RESOURCES,
@@ -83,23 +81,23 @@ enum {
 	/* #6: expansion ROM resource */
 	PCI_ROM_RESOURCE,
 
-	/* device specific resources */
+	/* Device-specific resources */
 #ifdef CONFIG_PCI_IOV
 	PCI_IOV_RESOURCES,
 	PCI_IOV_RESOURCE_END = PCI_IOV_RESOURCES + PCI_SRIOV_NUM_BARS - 1,
 #endif
 
-	/* resources assigned to buses behind the bridge */
+	/* Resources assigned to buses behind the bridge */
 #define PCI_BRIDGE_RESOURCE_NUM 4
 
 	PCI_BRIDGE_RESOURCES,
 	PCI_BRIDGE_RESOURCE_END = PCI_BRIDGE_RESOURCES +
 				  PCI_BRIDGE_RESOURCE_NUM - 1,
 
-	/* total resources associated with a PCI device */
+	/* Total resources associated with a PCI device */
 	PCI_NUM_RESOURCES,
 
-	/* preserve this for compatibility */
+	/* Preserve this for compatibility */
 	DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES,
 };
 
@@ -152,9 +150,10 @@ static inline const char *pci_power_name(pci_power_t state)
 #define PCI_PM_D3COLD_WAIT	100
 #define PCI_PM_BUS_WAIT		50
 
-/** The pci_channel state describes connectivity between the CPU and
- *  the pci device.  If some PCI bus between here and the pci device
- *  has crashed or locked up, this info is reflected here.
+/**
+ * The pci_channel state describes connectivity between the CPU and
+ * the PCI device.  If some PCI bus between here and the PCI device
+ * has crashed or locked up, this info is reflected here.
  */
 typedef unsigned int __bitwise pci_channel_state_t;
 
@@ -184,9 +183,7 @@ enum pcie_reset_state {
 
 typedef unsigned short __bitwise pci_dev_flags_t;
 enum pci_dev_flags {
-	/* INTX_DISABLE in PCI_COMMAND register disables MSI
-	 * generation too.
-	 */
+	/* INTX_DISABLE in PCI_COMMAND register disables MSI too */
 	PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) (1 << 0),
 	/* Device configuration is irrevocably lost if disabled into D3 */
 	PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) (1 << 1),
@@ -202,7 +199,7 @@ enum pci_dev_flags {
 	PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 7),
 	/* Get VPD from function 0 VPD */
 	PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 << 8),
-	/* a non-root bridge where translation occurs, stop alias search here */
+	/* A non-root bridge where translation occurs, stop alias search here */
 	PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT = (__force pci_dev_flags_t) (1 << 9),
 	/* Do not use FLR even if device advertises PCI_AF_CAP */
 	PCI_DEV_FLAGS_NO_FLR_RESET = (__force pci_dev_flags_t) (1 << 10),
@@ -222,17 +219,17 @@ enum pci_bus_flags {
 	PCI_BUS_FLAGS_NO_AERSID	= (__force pci_bus_flags_t) 4,
 };
 
-/* These values come from the PCI Express Spec */
+/* Values from Link Status register, PCIe r3.1, sec 7.8.8 */
 enum pcie_link_width {
 	PCIE_LNK_WIDTH_RESRV	= 0x00,
 	PCIE_LNK_X1		= 0x01,
 	PCIE_LNK_X2		= 0x02,
 	PCIE_LNK_X4		= 0x04,
 	PCIE_LNK_X8		= 0x08,
-	PCIE_LNK_X12		= 0x0C,
+	PCIE_LNK_X12		= 0x0c,
 	PCIE_LNK_X16		= 0x10,
 	PCIE_LNK_X32		= 0x20,
-	PCIE_LNK_WIDTH_UNKNOWN  = 0xFF,
+	PCIE_LNK_WIDTH_UNKNOWN	= 0xff,
 };
 
 /* Based on the PCI Hotplug Spec, but some values are made up by us */
@@ -263,15 +260,15 @@ enum pci_bus_speed {
 };
 
 struct pci_cap_saved_data {
-	u16 cap_nr;
-	bool cap_extended;
-	unsigned int size;
-	u32 data[0];
+	u16		cap_nr;
+	bool		cap_extended;
+	unsigned int	size;
+	u32		data[0];
 };
 
 struct pci_cap_saved_state {
-	struct hlist_node next;
-	struct pci_cap_saved_data cap;
+	struct hlist_node		next;
+	struct pci_cap_saved_data	cap;
 };
 
 struct irq_affinity;
@@ -280,19 +277,17 @@ struct pci_vpd;
 struct pci_sriov;
 struct pci_ats;
 
-/*
- * The pci_dev structure is used to describe PCI devices.
- */
+/* The pci_dev structure describes PCI devices */
 struct pci_dev {
-	struct list_head bus_list;	/* node in per-bus list */
-	struct pci_bus	*bus;		/* bus this device is on */
-	struct pci_bus	*subordinate;	/* bus this device bridges to */
+	struct list_head bus_list;	/* Node in per-bus list */
+	struct pci_bus	*bus;		/* Bus this device is on */
+	struct pci_bus	*subordinate;	/* Bus this device bridges to */
 
-	void		*sysdata;	/* hook for sys-specific extension */
-	struct proc_dir_entry *procent;	/* device entry in /proc/bus/pci */
+	void		*sysdata;	/* Hook for sys-specific extension */
+	struct proc_dir_entry *procent;	/* Device entry in /proc/bus/pci */
 	struct pci_slot	*slot;		/* Physical slot this device is in */
 
-	unsigned int	devfn;		/* encoded device & function index */
+	unsigned int	devfn;		/* Encoded device & function index */
 	unsigned short	vendor;
 	unsigned short	device;
 	unsigned short	subsystem_vendor;
@@ -307,12 +302,12 @@ struct pci_dev {
 	u8		msi_cap;	/* MSI capability offset */
 	u8		msix_cap;	/* MSI-X capability offset */
 	u8		pcie_mpss:3;	/* PCIe Max Payload Size Supported */
-	u8		rom_base_reg;	/* which config register controls the ROM */
-	u8		pin;		/* which interrupt pin this device uses */
-	u16		pcie_flags_reg;	/* cached PCIe Capabilities Register */
-	unsigned long	*dma_alias_mask;/* mask of enabled devfn aliases */
+	u8		rom_base_reg;	/* Config register controlling ROM */
+	u8		pin;		/* Interrupt pin this device uses */
+	u16		pcie_flags_reg;	/* Cached PCIe Capabilities Register */
+	unsigned long	*dma_alias_mask;/* Mask of enabled devfn aliases */
 
-	struct pci_driver *driver;	/* which driver has allocated this device */
+	struct pci_driver *driver;	/* Driver bound to this device */
 	u64		dma_mask;	/* Mask of the bits of bus address this
 					   device implements.  Normally this is
 					   0xffffffff.  You only need to change
@@ -321,9 +316,9 @@ struct pci_dev {
 
 	struct device_dma_parameters dma_parms;
 
-	pci_power_t     current_state;  /* Current operating state. In ACPI-speak,
-					   this is D0-D3, D0 being fully functional,
-					   and D3 being off. */
+	pci_power_t	current_state;	/* Current operating state. In ACPI,
+					   this is D0-D3, D0 being fully
+					   functional, and D3 being off. */
 	u8		pm_cap;		/* PM capability offset */
 	unsigned int	pme_support:5;	/* Bitmask of states from which PME#
 					   can be generated */
@@ -334,10 +329,10 @@ struct pci_dev {
 	unsigned int	no_d3cold:1;	/* D3cold is forbidden */
 	unsigned int	bridge_d3:1;	/* Allow D3 for bridge */
 	unsigned int	d3cold_allowed:1;	/* D3cold is allowed by user */
-	unsigned int	mmio_always_on:1;	/* disallow turning off io/mem
-						   decoding during bar sizing */
+	unsigned int	mmio_always_on:1;	/* Disallow turning off io/mem
+						   decoding during BAR sizing */
 	unsigned int	wakeup_prepared:1;
-	unsigned int	runtime_d3cold:1;	/* whether go through runtime
+	unsigned int	runtime_d3cold:1;	/* Whether go through runtime
 						   D3cold, not set for devices
 						   powered on/off by the
 						   corresponding bridge */
@@ -350,12 +345,14 @@ struct pci_dev {
 
 #ifdef CONFIG_PCIEASPM
 	struct pcie_link_state	*link_state;	/* ASPM link state */
+	unsigned int	ltr_path:1;	/* Latency Tolerance Reporting
+					   supported from root to here */
 #endif
 
-	pci_channel_state_t error_state;	/* current connectivity state */
-	struct	device	dev;		/* Generic device interface */
+	pci_channel_state_t error_state;	/* Current connectivity state */
+	struct device	dev;			/* Generic device interface */
 
-	int		cfg_size;	/* Size of configuration space */
+	int		cfg_size;		/* Size of config space */
 
 	/*
 	 * Instead of touching interrupt line and base address registers
@@ -364,47 +361,47 @@ struct pci_dev {
 	unsigned int	irq;
 	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
 
-	bool match_driver;		/* Skip attaching driver */
-	/* These fields are used by common fixups */
-	unsigned int	transparent:1;	/* Subtractive decode PCI bridge */
-	unsigned int	multifunction:1;/* Part of multi-function device */
-	/* keep track of device state */
+	bool		match_driver;		/* Skip attaching driver */
+
+	unsigned int	transparent:1;		/* Subtractive decode bridge */
+	unsigned int	multifunction:1;	/* Multi-function device */
+
 	unsigned int	is_added:1;
-	unsigned int	is_busmaster:1; /* device is busmaster */
-	unsigned int	no_msi:1;	/* device may not use msi */
-	unsigned int	no_64bit_msi:1; /* device may only use 32-bit MSIs */
-	unsigned int	block_cfg_access:1;	/* config space access is blocked */
-	unsigned int	broken_parity_status:1;	/* Device generates false positive parity */
-	unsigned int	irq_reroute_variant:2;	/* device needs IRQ rerouting variant */
+	unsigned int	is_busmaster:1;		/* Is busmaster */
+	unsigned int	no_msi:1;		/* May not use MSI */
+	unsigned int	no_64bit_msi:1; 	/* May only use 32-bit MSIs */
+	unsigned int	block_cfg_access:1;	/* Config space access blocked */
+	unsigned int	broken_parity_status:1;	/* Generates false positive parity */
+	unsigned int	irq_reroute_variant:2;	/* Needs IRQ rerouting variant */
 	unsigned int	msi_enabled:1;
 	unsigned int	msix_enabled:1;
-	unsigned int	ari_enabled:1;	/* ARI forwarding */
-	unsigned int	ats_enabled:1;	/* Address Translation Service */
+	unsigned int	ari_enabled:1;		/* ARI forwarding */
+	unsigned int	ats_enabled:1;		/* Address Translation Svc */
 	unsigned int	pasid_enabled:1;	/* Process Address Space ID */
 	unsigned int	pri_enabled:1;		/* Page Request Interface */
 	unsigned int	is_managed:1;
-	unsigned int    needs_freset:1; /* Dev requires fundamental reset */
+	unsigned int	needs_freset:1;		/* Requires fundamental reset */
 	unsigned int	state_saved:1;
 	unsigned int	is_physfn:1;
 	unsigned int	is_virtfn:1;
 	unsigned int	reset_fn:1;
-	unsigned int    is_hotplug_bridge:1;
-	unsigned int	is_thunderbolt:1; /* Thunderbolt controller */
-	unsigned int    __aer_firmware_first_valid:1;
+	unsigned int	is_hotplug_bridge:1;
+	unsigned int	is_thunderbolt:1;	/* Thunderbolt controller */
+	unsigned int	__aer_firmware_first_valid:1;
 	unsigned int	__aer_firmware_first:1;
-	unsigned int	broken_intx_masking:1; /* INTx masking can't be used */
-	unsigned int	io_window_1k:1;	/* Intel P2P bridge 1K I/O windows */
+	unsigned int	broken_intx_masking:1;	/* INTx masking can't be used */
+	unsigned int	io_window_1k:1;		/* Intel bridge 1K I/O windows */
 	unsigned int	irq_managed:1;
 	unsigned int	has_secondary_link:1;
-	unsigned int	non_compliant_bars:1;	/* broken BARs; ignore them */
-	unsigned int	is_probed:1;		/* device probing in progress */
+	unsigned int	non_compliant_bars:1;	/* Broken BARs; ignore them */
+	unsigned int	is_probed:1;		/* Device probing in progress */
 	pci_dev_flags_t dev_flags;
 	atomic_t	enable_cnt;	/* pci_enable_device has been called */
 
-	u32		saved_config_space[16]; /* config space saved at suspend time */
+	u32		saved_config_space[16]; /* Config space saved at suspend time */
 	struct hlist_head saved_cap_space;
-	struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
-	int rom_attr_enabled;		/* has display of the rom attribute been enabled? */
+	struct bin_attribute *rom_attr;		/* Attribute descriptor for sysfs ROM entry */
+	int		rom_attr_enabled;	/* Display of ROM attribute enabled? */
 	struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
 	struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
 
@@ -419,12 +416,12 @@ struct pci_dev {
 	struct pci_vpd *vpd;
 #ifdef CONFIG_PCI_ATS
 	union {
-		struct pci_sriov *sriov;	/* SR-IOV capability related */
-		struct pci_dev *physfn;	/* the PF this VF is associated with */
+		struct pci_sriov	*sriov;		/* PF: SR-IOV info */
+		struct pci_dev		*physfn;	/* VF: related PF */
 	};
 	u16		ats_cap;	/* ATS Capability offset */
 	u8		ats_stu;	/* ATS Smallest Translation Unit */
-	atomic_t	ats_ref_cnt;	/* number of VFs with ATS enabled */
+	atomic_t	ats_ref_cnt;	/* Number of VFs with ATS enabled */
 #endif
 #ifdef CONFIG_PCI_PRI
 	u32		pri_reqs_alloc; /* Number of PRI requests allocated */
@@ -432,11 +429,11 @@ struct pci_dev {
 #ifdef CONFIG_PCI_PASID
 	u16		pasid_features;
 #endif
-	phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */
-	size_t romlen; /* Length of ROM if it's not from the BAR */
-	char *driver_override; /* Driver name to force a match */
+	phys_addr_t	rom;		/* Physical address if not from BAR */
+	size_t		romlen;		/* Length if not from BAR */
+	char		*driver_override; /* Driver name to force a match */
 
-	unsigned long priv_flags; /* Private flags for the pci driver */
+	unsigned long	priv_flags;	/* Private flags for the PCI driver */
 };
 
 static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
@@ -459,26 +456,26 @@ static inline int pci_channel_offline(struct pci_dev *pdev)
 }
 
 struct pci_host_bridge {
-	struct device dev;
-	struct pci_bus *bus;		/* root bus */
-	struct pci_ops *ops;
-	void *sysdata;
-	int busnr;
+	struct device	dev;
+	struct pci_bus	*bus;		/* Root bus */
+	struct pci_ops	*ops;
+	void		*sysdata;
+	int		busnr;
 	struct list_head windows;	/* resource_entry */
-	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* platform IRQ swizzler */
+	u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
 	int (*map_irq)(const struct pci_dev *, u8, u8);
 	void (*release_fn)(struct pci_host_bridge *);
-	void *release_data;
+	void		*release_data;
 	struct msi_controller *msi;
-	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
-	unsigned int no_ext_tags:1;		/* no Extended Tags */
+	unsigned int	ignore_reset_delay:1;	/* For entire hierarchy */
+	unsigned int	no_ext_tags:1;		/* No Extended Tags */
 	/* Resource alignment requirements */
 	resource_size_t (*align_resource)(struct pci_dev *dev,
 			const struct resource *res,
 			resource_size_t start,
 			resource_size_t size,
 			resource_size_t align);
-	unsigned long private[0] ____cacheline_aligned;
+	unsigned long	private[0] ____cacheline_aligned;
 };
 
 #define	to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev)
@@ -500,8 +497,8 @@ void pci_free_host_bridge(struct pci_host_bridge *bridge);
 struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);
 
 void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
-		     void (*release_fn)(struct pci_host_bridge *),
-		     void *release_data);
+				 void (*release_fn)(struct pci_host_bridge *),
+				 void *release_data);
 
 int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge);
 
@@ -521,32 +518,32 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge);
 #define PCI_SUBTRACTIVE_DECODE	0x1
 
 struct pci_bus_resource {
-	struct list_head list;
-	struct resource *res;
-	unsigned int flags;
+	struct list_head	list;
+	struct resource		*res;
+	unsigned int		flags;
 };
 
 #define PCI_REGION_FLAG_MASK	0x0fU	/* These bits of resource flags tell us the PCI region flags */
 
 struct pci_bus {
-	struct list_head node;		/* node in list of buses */
-	struct pci_bus	*parent;	/* parent bus this bridge is on */
-	struct list_head children;	/* list of child buses */
-	struct list_head devices;	/* list of devices on this bus */
-	struct pci_dev	*self;		/* bridge device as seen by parent */
-	struct list_head slots;		/* list of slots on this bus;
+	struct list_head node;		/* Node in list of buses */
+	struct pci_bus	*parent;	/* Parent bus this bridge is on */
+	struct list_head children;	/* List of child buses */
+	struct list_head devices;	/* List of devices on this bus */
+	struct pci_dev	*self;		/* Bridge device as seen by parent */
+	struct list_head slots;		/* List of slots on this bus;
 					   protected by pci_slot_mutex */
 	struct resource *resource[PCI_BRIDGE_RESOURCE_NUM];
-	struct list_head resources;	/* address space routed to this bus */
-	struct resource busn_res;	/* bus numbers routed to this bus */
+	struct list_head resources;	/* Address space routed to this bus */
+	struct resource busn_res;	/* Bus numbers routed to this bus */
 
-	struct pci_ops	*ops;		/* configuration access functions */
+	struct pci_ops	*ops;		/* Configuration access functions */
 	struct msi_controller *msi;	/* MSI controller */
-	void		*sysdata;	/* hook for sys-specific extension */
-	struct proc_dir_entry *procdir;	/* directory entry in /proc/bus/pci */
+	void		*sysdata;	/* Hook for sys-specific extension */
+	struct proc_dir_entry *procdir;	/* Directory entry in /proc/bus/pci */
 
-	unsigned char	number;		/* bus number */
-	unsigned char	primary;	/* number of primary bridge */
+	unsigned char	number;		/* Bus number */
+	unsigned char	primary;	/* Number of primary bridge */
 	unsigned char	max_bus_speed;	/* enum pci_bus_speed */
 	unsigned char	cur_bus_speed;	/* enum pci_bus_speed */
 #ifdef CONFIG_PCI_DOMAINS_GENERIC
@@ -555,12 +552,12 @@ struct pci_bus {
 
 	char		name[48];
 
-	unsigned short  bridge_ctl;	/* manage NO_ISA/FBB/et al behaviors */
-	pci_bus_flags_t bus_flags;	/* inherited by child buses */
+	unsigned short	bridge_ctl;	/* Manage NO_ISA/FBB/et al behaviors */
+	pci_bus_flags_t bus_flags;	/* Inherited by child buses */
 	struct device		*bridge;
 	struct device		dev;
-	struct bin_attribute	*legacy_io; /* legacy I/O for this bus */
-	struct bin_attribute	*legacy_mem; /* legacy mem */
+	struct bin_attribute	*legacy_io;	/* Legacy I/O for this bus */
+	struct bin_attribute	*legacy_mem;	/* Legacy mem */
 	unsigned int		is_added:1;
 };
 
@@ -617,9 +614,7 @@ static inline bool pci_dev_msi_enabled(struct pci_dev *pci_dev)
 static inline bool pci_dev_msi_enabled(struct pci_dev *pci_dev) { return false; }
 #endif
 
-/*
- * Error values that may be returned by PCI functions.
- */
+/* Error values that may be returned by PCI functions */
 #define PCIBIOS_SUCCESSFUL		0x00
 #define PCIBIOS_FUNC_NOT_SUPPORTED	0x81
 #define PCIBIOS_BAD_VENDOR_ID		0x83
@@ -628,9 +623,7 @@ static inline bool pci_dev_msi_enabled(struct pci_dev *pci_dev) { return false;
 #define PCIBIOS_SET_FAILED		0x88
 #define PCIBIOS_BUFFER_TOO_SMALL	0x89
 
-/*
- * Translate above to generic errno for passing back through non-PCI code.
- */
+/* Translate above to generic errno for passing back through non-PCI code */
 static inline int pcibios_err_to_errno(int err)
 {
 	if (err <= PCIBIOS_SUCCESSFUL)
@@ -680,13 +673,13 @@ typedef u32 pci_bus_addr_t;
 #endif
 
 struct pci_bus_region {
-	pci_bus_addr_t start;
-	pci_bus_addr_t end;
+	pci_bus_addr_t	start;
+	pci_bus_addr_t	end;
 };
 
 struct pci_dynids {
-	spinlock_t lock;            /* protects list, index */
-	struct list_head list;      /* for IDs added at runtime */
+	spinlock_t		lock;	/* Protects list, index */
+	struct list_head	list;	/* For IDs added at runtime */
 };
 
 
@@ -700,13 +693,13 @@ struct pci_dynids {
 typedef unsigned int __bitwise pci_ers_result_t;
 
 enum pci_ers_result {
-	/* no result/none/not supported in device driver */
+	/* No result/none/not supported in device driver */
 	PCI_ERS_RESULT_NONE = (__force pci_ers_result_t) 1,
 
 	/* Device driver can recover without slot reset */
 	PCI_ERS_RESULT_CAN_RECOVER = (__force pci_ers_result_t) 2,
 
-	/* Device driver wants slot to be reset. */
+	/* Device driver wants slot to be reset */
 	PCI_ERS_RESULT_NEED_RESET = (__force pci_ers_result_t) 3,
 
 	/* Device has completely failed, is unrecoverable */
@@ -742,27 +735,27 @@ struct pci_error_handlers {
 
 struct module;
 struct pci_driver {
-	struct list_head node;
-	const char *name;
-	const struct pci_device_id *id_table;	/* must be non-NULL for probe to be called */
-	int  (*probe)  (struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
-	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
-	int  (*suspend) (struct pci_dev *dev, pm_message_t state);	/* Device suspended */
-	int  (*suspend_late) (struct pci_dev *dev, pm_message_t state);
-	int  (*resume_early) (struct pci_dev *dev);
-	int  (*resume) (struct pci_dev *dev);	                /* Device woken up */
+	struct list_head	node;
+	const char		*name;
+	const struct pci_device_id *id_table;	/* Must be non-NULL for probe to be called */
+	int  (*probe)(struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
+	void (*remove)(struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
+	int  (*suspend)(struct pci_dev *dev, pm_message_t state);	/* Device suspended */
+	int  (*suspend_late)(struct pci_dev *dev, pm_message_t state);
+	int  (*resume_early)(struct pci_dev *dev);
+	int  (*resume) (struct pci_dev *dev);	/* Device woken up */
 	void (*shutdown) (struct pci_dev *dev);
-	int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */
+	int  (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* On PF */
 	const struct pci_error_handlers *err_handler;
 	const struct attribute_group **groups;
 	struct device_driver	driver;
-	struct pci_dynids dynids;
+	struct pci_dynids	dynids;
 };
 
 #define	to_pci_driver(drv) container_of(drv, struct pci_driver, driver)
 
 /**
- * PCI_DEVICE - macro used to describe a specific pci device
+ * PCI_DEVICE - macro used to describe a specific PCI device
  * @vend: the 16 bit PCI Vendor ID
  * @dev: the 16 bit PCI Device ID
  *
@@ -775,7 +768,7 @@ struct pci_driver {
 	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
 
 /**
- * PCI_DEVICE_SUB - macro used to describe a specific pci device with subsystem
+ * PCI_DEVICE_SUB - macro used to describe a specific PCI device with subsystem
  * @vend: the 16 bit PCI Vendor ID
  * @dev: the 16 bit PCI Device ID
  * @subvend: the 16 bit PCI Subvendor ID
@@ -789,7 +782,7 @@ struct pci_driver {
 	.subvendor = (subvend), .subdevice = (subdev)
 
 /**
- * PCI_DEVICE_CLASS - macro used to describe a specific pci device class
+ * PCI_DEVICE_CLASS - macro used to describe a specific PCI device class
  * @dev_class: the class, subclass, prog-if triple for this device
  * @dev_class_mask: the class mask for this device
  *
@@ -803,7 +796,7 @@ struct pci_driver {
 	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
 
 /**
- * PCI_VDEVICE - macro used to describe a specific pci device in short form
+ * PCI_VDEVICE - macro used to describe a specific PCI device in short form
  * @vend: the vendor name
  * @dev: the 16 bit PCI Device ID
  *
@@ -812,22 +805,21 @@ struct pci_driver {
  * to PCI_ANY_ID. The macro allows the next field to follow as the device
  * private data.
  */
-
 #define PCI_VDEVICE(vend, dev) \
 	.vendor = PCI_VENDOR_ID_##vend, .device = (dev), \
 	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0
 
 enum {
-	PCI_REASSIGN_ALL_RSRC	= 0x00000001,	/* ignore firmware setup */
-	PCI_REASSIGN_ALL_BUS	= 0x00000002,	/* reassign all bus numbers */
-	PCI_PROBE_ONLY		= 0x00000004,	/* use existing setup */
-	PCI_CAN_SKIP_ISA_ALIGN	= 0x00000008,	/* don't do ISA alignment */
-	PCI_ENABLE_PROC_DOMAINS	= 0x00000010,	/* enable domains in /proc */
+	PCI_REASSIGN_ALL_RSRC	= 0x00000001,	/* Ignore firmware setup */
+	PCI_REASSIGN_ALL_BUS	= 0x00000002,	/* Reassign all bus numbers */
+	PCI_PROBE_ONLY		= 0x00000004,	/* Use existing setup */
+	PCI_CAN_SKIP_ISA_ALIGN	= 0x00000008,	/* Don't do ISA alignment */
+	PCI_ENABLE_PROC_DOMAINS	= 0x00000010,	/* Enable domains in /proc */
 	PCI_COMPAT_DOMAIN_0	= 0x00000020,	/* ... except domain 0 */
-	PCI_SCAN_ALL_PCIE_DEVS	= 0x00000040,	/* scan all, not just dev 0 */
+	PCI_SCAN_ALL_PCIE_DEVS	= 0x00000040,	/* Scan all, not just dev 0 */
 };
 
-/* these external functions are only available when PCI support is enabled */
+/* These external functions are only available when PCI support is enabled */
 #ifdef CONFIG_PCI
 
 extern unsigned int pci_flags;
@@ -840,11 +832,11 @@ static inline int pci_has_flag(int flag) { return pci_flags & flag; }
 void pcie_bus_configure_settings(struct pci_bus *bus);
 
 enum pcie_bus_config_types {
-	PCIE_BUS_TUNE_OFF,	/* don't touch MPS at all */
-	PCIE_BUS_DEFAULT,	/* ensure MPS matches upstream bridge */
-	PCIE_BUS_SAFE,		/* use largest MPS boot-time devices support */
-	PCIE_BUS_PERFORMANCE,	/* use MPS and MRRS for best performance */
-	PCIE_BUS_PEER2PEER,	/* set MPS = 128 for all devices */
+	PCIE_BUS_TUNE_OFF,	/* Don't touch MPS at all */
+	PCIE_BUS_DEFAULT,	/* Ensure MPS matches upstream bridge */
+	PCIE_BUS_SAFE,		/* Use largest MPS boot-time devices support */
+	PCIE_BUS_PERFORMANCE,	/* Use MPS and MRRS for best performance */
+	PCIE_BUS_PEER2PEER,	/* Set MPS = 128 for all devices */
 };
 
 extern enum pcie_bus_config_types pcie_bus_config;
@@ -853,7 +845,7 @@ extern struct bus_type pci_bus_type;
 
 /* Do NOT directly access these two variables, unless you are arch-specific PCI
  * code, or PCI core code. */
-extern struct list_head pci_root_buses;	/* list of all known PCI buses */
+extern struct list_head pci_root_buses;	/* List of all known PCI buses */
 /* Some device drivers need know if PCI is initiated */
 int no_pci_devices(void);
 
@@ -887,12 +879,13 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 				    struct pci_ops *ops, void *sysdata,
 				    struct list_head *resources);
+int pci_host_probe(struct pci_host_bridge *bridge);
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
 int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
 void pci_bus_release_busn_res(struct pci_bus *b);
 struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
-					     struct pci_ops *ops, void *sysdata,
-					     struct list_head *resources);
+				  struct pci_ops *ops, void *sysdata,
+				  struct list_head *resources);
 int pci_scan_root_bus_bridge(struct pci_host_bridge *bridge);
 struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
 				int busnr);
@@ -949,10 +942,10 @@ int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap);
 struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
 
 struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
-				struct pci_dev *from);
+			       struct pci_dev *from);
 struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
-				unsigned int ss_vendor, unsigned int ss_device,
-				struct pci_dev *from);
+			       unsigned int ss_vendor, unsigned int ss_device,
+			       struct pci_dev *from);
 struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn);
 struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus,
 					    unsigned int devfn);
@@ -1028,7 +1021,7 @@ static inline int pcie_capability_clear_dword(struct pci_dev *dev, int pos,
 	return pcie_capability_clear_and_set_dword(dev, pos, clear, 0);
 }
 
-/* user-space driven config access */
+/* User-space driven config access */
 int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
 int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val);
 int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val);
@@ -1171,7 +1164,7 @@ unsigned int pci_rescan_bus(struct pci_bus *bus);
 void pci_lock_rescan_remove(void);
 void pci_unlock_rescan_remove(void);
 
-/* Vital product data routines */
+/* Vital Product Data routines */
 ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
 ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
 int pci_set_vpd_size(struct pci_dev *dev, size_t len);
@@ -1256,9 +1249,7 @@ static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
 int __must_check __pci_register_driver(struct pci_driver *, struct module *,
 				       const char *mod_name);
 
-/*
- * pci_register_driver must be a macro so that KBUILD_MODNAME can be expanded
- */
+/* pci_register_driver() must be a macro so KBUILD_MODNAME can be expanded */
 #define pci_register_driver(driver)		\
 	__pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
 
@@ -1273,8 +1264,7 @@ void pci_unregister_driver(struct pci_driver *dev);
  * use this macro once, and calling it replaces module_init() and module_exit()
  */
 #define module_pci_driver(__pci_driver) \
-	module_driver(__pci_driver, pci_register_driver, \
-		       pci_unregister_driver)
+	module_driver(__pci_driver, pci_register_driver, pci_unregister_driver)
 
 /**
  * builtin_pci_driver() - Helper macro for registering a PCI driver
@@ -1313,10 +1303,10 @@ resource_size_t pcibios_iov_resource_alignment(struct pci_dev *dev, int resno);
 int pci_set_vga_state(struct pci_dev *pdev, bool decode,
 		      unsigned int command_bits, u32 flags);
 
-#define PCI_IRQ_LEGACY		(1 << 0) /* allow legacy interrupts */
-#define PCI_IRQ_MSI		(1 << 1) /* allow MSI interrupts */
-#define PCI_IRQ_MSIX		(1 << 2) /* allow MSI-X interrupts */
-#define PCI_IRQ_AFFINITY	(1 << 3) /* auto-assign affinity */
+#define PCI_IRQ_LEGACY		(1 << 0) /* Allow legacy interrupts */
+#define PCI_IRQ_MSI		(1 << 1) /* Allow MSI interrupts */
+#define PCI_IRQ_MSIX		(1 << 2) /* Allow MSI-X interrupts */
+#define PCI_IRQ_AFFINITY	(1 << 3) /* Auto-assign affinity */
 #define PCI_IRQ_ALL_TYPES \
 	(PCI_IRQ_LEGACY | PCI_IRQ_MSI | PCI_IRQ_MSIX)
 
@@ -1335,8 +1325,8 @@ int pci_set_vga_state(struct pci_dev *pdev, bool decode,
 #define	pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr)
 
 struct msix_entry {
-	u32	vector;	/* kernel uses to write allocated vector */
-	u16	entry;	/* driver uses to specify entry, OS writes */
+	u32	vector;	/* Kernel uses to write allocated vector */
+	u16	entry;	/* Driver uses to specify entry, OS writes */
 };
 
 #ifdef CONFIG_PCI_MSI
@@ -1376,10 +1366,10 @@ static inline int pci_msi_enabled(void) { return 0; }
 static inline int pci_enable_msi(struct pci_dev *dev)
 { return -ENOSYS; }
 static inline int pci_enable_msix_range(struct pci_dev *dev,
-		      struct msix_entry *entries, int minvec, int maxvec)
+			struct msix_entry *entries, int minvec, int maxvec)
 { return -ENOSYS; }
 static inline int pci_enable_msix_exact(struct pci_dev *dev,
-		      struct msix_entry *entries, int nvec)
+			struct msix_entry *entries, int nvec)
 { return -ENOSYS; }
 
 static inline int
@@ -1544,9 +1534,9 @@ static inline int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
 int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent);
 #endif
 
-/* some architectures require additional setup to direct VGA traffic */
+/* Some architectures require additional setup to direct VGA traffic */
 typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,
-		      unsigned int command_bits, u32 flags);
+				    unsigned int command_bits, u32 flags);
 void pci_register_set_vga_state(arch_set_vga_state_t func);
 
 static inline int
@@ -1585,10 +1575,9 @@ static inline void pci_clear_flags(int flags) { }
 static inline int pci_has_flag(int flag) { return 0; }
 
 /*
- *  If the system does not have PCI, clearly these return errors.  Define
- *  these as simple inline functions to avoid hair in drivers.
+ * If the system does not have PCI, clearly these return errors.  Define
+ * these as simple inline functions to avoid hair in drivers.
  */
-
 #define _PCI_NOP(o, s, t) \
 	static inline int pci_##o##_config_##s(struct pci_dev *dev, \
 						int where, t val) \
@@ -1687,6 +1676,13 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
 #define dev_is_pf(d) (false)
 static inline bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags)
 { return false; }
+static inline int pci_irqd_intx_xlate(struct irq_domain *d,
+				      struct device_node *node,
+				      const u32 *intspec,
+				      unsigned int intsize,
+				      unsigned long *out_hwirq,
+				      unsigned int *out_type)
+{ return -EINVAL; }
 #endif /* CONFIG_PCI */
 
 /* Include architecture-dependent settings and functions */
@@ -1727,8 +1723,10 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma);
 #define pci_root_bus_fwnode(bus)	NULL
 #endif
 
-/* these helpers provide future and backwards compatibility
- * for accessing popular PCI BAR info */
+/*
+ * These helpers provide future and backwards compatibility
+ * for accessing popular PCI BAR info
+ */
 #define pci_resource_start(dev, bar)	((dev)->resource[(bar)].start)
 #define pci_resource_end(dev, bar)	((dev)->resource[(bar)].end)
 #define pci_resource_flags(dev, bar)	((dev)->resource[(bar)].flags)
@@ -1740,7 +1738,8 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma);
 	 (pci_resource_end((dev), (bar)) -		\
 	  pci_resource_start((dev), (bar)) + 1))
 
-/* Similar to the helpers above, these manipulate per-pci_dev
+/*
+ * Similar to the helpers above, these manipulate per-pci_dev
  * driver-specific data.  They are really just a wrapper around
  * the generic device structure functions of these calls.
  */
@@ -1754,16 +1753,14 @@ static inline void pci_set_drvdata(struct pci_dev *pdev, void *data)
 	dev_set_drvdata(&pdev->dev, data);
 }
 
-/* If you want to know what to call your pci_dev, ask this function.
- * Again, it's a wrapper around the generic device.
- */
 static inline const char *pci_name(const struct pci_dev *pdev)
 {
 	return dev_name(&pdev->dev);
 }
 
 
-/* Some archs don't want to expose struct resource to userland as-is
+/*
+ * Some archs don't want to expose struct resource to userland as-is
  * in sysfs and /proc
  */
 #ifdef HAVE_ARCH_PCI_RESOURCE_TO_USER
@@ -1782,16 +1779,16 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
 
 
 /*
- *  The world is not perfect and supplies us with broken PCI devices.
- *  For at least a part of these bugs we need a work-around, so both
- *  generic (drivers/pci/quirks.c) and per-architecture code can define
- *  fixup hooks to be called for particular buggy devices.
+ * The world is not perfect and supplies us with broken PCI devices.
+ * For at least a part of these bugs we need a work-around, so both
+ * generic (drivers/pci/quirks.c) and per-architecture code can define
+ * fixup hooks to be called for particular buggy devices.
  */
 
 struct pci_fixup {
-	u16 vendor;		/* You can use PCI_ANY_ID here of course */
-	u16 device;		/* You can use PCI_ANY_ID here of course */
-	u32 class;		/* You can use PCI_ANY_ID here too */
+	u16 vendor;			/* Or PCI_ANY_ID */
+	u16 device;			/* Or PCI_ANY_ID */
+	u32 class;			/* Or PCI_ANY_ID */
 	unsigned int class_shift;	/* should be 0, 8, 16 */
 	void (*hook)(struct pci_dev *dev);
 };
@@ -1833,23 +1830,19 @@ enum pci_fixup_pass {
 #define DECLARE_PCI_FIXUP_CLASS_RESUME(vendor, device, class,		\
 					 class_shift, hook)		\
 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume,			\
-		resume##hook, vendor, device, class,	\
-		class_shift, hook)
+		resume##hook, vendor, device, class, class_shift, hook)
 #define DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(vendor, device, class,	\
 					 class_shift, hook)		\
 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early,		\
-		resume_early##hook, vendor, device,	\
-		class, class_shift, hook)
+		resume_early##hook, vendor, device, class, class_shift, hook)
 #define DECLARE_PCI_FIXUP_CLASS_SUSPEND(vendor, device, class,		\
 					 class_shift, hook)		\
 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend,			\
-		suspend##hook, vendor, device, class,	\
-		class_shift, hook)
+		suspend##hook, vendor, device, class, class_shift, hook)
 #define DECLARE_PCI_FIXUP_CLASS_SUSPEND_LATE(vendor, device, class,	\
 					 class_shift, hook)		\
 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend_late,		\
-		suspend_late##hook, vendor, device,	\
-		class, class_shift, hook)
+		suspend_late##hook, vendor, device, class, class_shift, hook)
 
 #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook)			\
 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early,			\
@@ -1865,20 +1858,16 @@ enum pci_fixup_pass {
 		hook, vendor, device, PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook)			\
 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume,			\
-		resume##hook, vendor, device,		\
-		PCI_ANY_ID, 0, hook)
+		resume##hook, vendor, device, PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook)		\
 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early,		\
-		resume_early##hook, vendor, device,	\
-		PCI_ANY_ID, 0, hook)
+		resume_early##hook, vendor, device, PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook)			\
 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend,			\
-		suspend##hook, vendor, device,		\
-		PCI_ANY_ID, 0, hook)
+		suspend##hook, vendor, device, PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_SUSPEND_LATE(vendor, device, hook)		\
 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend_late,		\
-		suspend_late##hook, vendor, device,	\
-		PCI_ANY_ID, 0, hook)
+		suspend_late##hook, vendor, device, PCI_ANY_ID, 0, hook)
 
 #ifdef CONFIG_PCI_QUIRKS
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
@@ -2064,6 +2053,7 @@ void pci_request_acs(void);
 bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
 bool pci_acs_path_enabled(struct pci_dev *start,
 			  struct pci_dev *end, u16 acs_flags);
+int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask);
 
 #define PCI_VPD_LRDT			0x80	/* Large Resource Data Type */
 #define PCI_VPD_LRDT_ID(x)		((x) | PCI_VPD_LRDT)
@@ -2115,7 +2105,7 @@ static inline u16 pci_vpd_lrdt_size(const u8 *lrdt)
  */
 static inline u16 pci_vpd_lrdt_tag(const u8 *lrdt)
 {
-    return (u16)(lrdt[0] & PCI_VPD_LRDT_TIN_MASK);
+	return (u16)(lrdt[0] & PCI_VPD_LRDT_TIN_MASK);
 }
 
 /**
@@ -2185,6 +2175,9 @@ void pci_release_of_node(struct pci_dev *dev);
 void pci_set_bus_of_node(struct pci_bus *bus);
 void pci_release_bus_of_node(struct pci_bus *bus);
 struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus);
+int pci_parse_request_of_pci_ranges(struct device *dev,
+				    struct list_head *resources,
+				    struct resource **bus_range);
 
 /* Arch may override this (weak) */
 struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus);
@@ -2200,7 +2193,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
 	return bus ? bus->dev.of_node : NULL;
 }
 
-#else /* CONFIG_OF */
+#else	/* CONFIG_OF */
 static inline void pci_set_of_node(struct pci_dev *dev) { }
 static inline void pci_release_of_node(struct pci_dev *dev) { }
 static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
@@ -2209,6 +2202,12 @@ static inline struct device_node *
 pci_device_to_OF_node(const struct pci_dev *pdev) { return NULL; }
 static inline struct irq_domain *
 pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
+static inline int pci_parse_request_of_pci_ranges(struct device *dev,
+						  struct list_head *resources,
+						  struct resource **bus_range)
+{
+	return -EINVAL;
+}
 #endif  /* CONFIG_OF */
 
 #ifdef CONFIG_ACPI
@@ -2234,7 +2233,7 @@ int pci_for_each_dma_alias(struct pci_dev *pdev,
 			   int (*fn)(struct pci_dev *pdev,
 				     u16 alias, void *data), void *data);
 
-/* helper functions for operation of device flag */
+/* Helper functions for operation of device flag */
 static inline void pci_set_dev_assigned(struct pci_dev *pdev)
 {
 	pdev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED;
@@ -2317,7 +2316,19 @@ static inline void pci_uevent_ers(struct pci_dev *pdev,
 	}
 }
 
-/* provide the legacy pci_dma_* API */
+/* Provide the legacy pci_dma_* API */
 #include <linux/pci-dma-compat.h>
 
+#define pci_printk(level, pdev, fmt, arg...) \
+	dev_printk(level, &(pdev)->dev, fmt, ##arg)
+
+#define pci_emerg(pdev, fmt, arg...)	dev_emerg(&(pdev)->dev, fmt, ##arg)
+#define pci_alert(pdev, fmt, arg...)	dev_alert(&(pdev)->dev, fmt, ##arg)
+#define pci_crit(pdev, fmt, arg...)	dev_crit(&(pdev)->dev, fmt, ##arg)
+#define pci_err(pdev, fmt, arg...)	dev_err(&(pdev)->dev, fmt, ##arg)
+#define pci_warn(pdev, fmt, arg...)	dev_warn(&(pdev)->dev, fmt, ##arg)
+#define pci_notice(pdev, fmt, arg...)	dev_notice(&(pdev)->dev, fmt, ##arg)
+#define pci_info(pdev, fmt, arg...)	dev_info(&(pdev)->dev, fmt, ##arg)
+#define pci_dbg(pdev, fmt, arg...)	dev_dbg(&(pdev)->dev, fmt, ##arg)
+
 #endif /* LINUX_PCI_H */
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
index 2e855af..2621302 100644
--- a/include/linux/pci_hotplug.h
+++ b/include/linux/pci_hotplug.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * PCI HotPlug Core Functions
  *
@@ -7,21 +8,6 @@
  *
  * All rights reserved.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  * Send feedback to <kristen.c.accardi@intel.com>
  *
  */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index ab20dc5..eb13e84 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2381,6 +2381,8 @@
 
 #define PCI_VENDOR_ID_LENOVO		0x17aa
 
+#define PCI_VENDOR_ID_CDNS		0x17cd
+
 #define PCI_VENDOR_ID_ARECA		0x17d3
 #define PCI_DEVICE_ID_ARECA_1110	0x1110
 #define PCI_DEVICE_ID_ARECA_1120	0x1120
diff --git a/include/linux/pfn_t.h b/include/linux/pfn_t.h
index 43b1d76..a03c264 100644
--- a/include/linux/pfn_t.h
+++ b/include/linux/pfn_t.h
@@ -15,8 +15,10 @@
 #define PFN_SG_LAST (1ULL << (BITS_PER_LONG_LONG - 2))
 #define PFN_DEV (1ULL << (BITS_PER_LONG_LONG - 3))
 #define PFN_MAP (1ULL << (BITS_PER_LONG_LONG - 4))
+#define PFN_SPECIAL (1ULL << (BITS_PER_LONG_LONG - 5))
 
 #define PFN_FLAGS_TRACE \
+	{ PFN_SPECIAL,	"SPECIAL" }, \
 	{ PFN_SG_CHAIN,	"SG_CHAIN" }, \
 	{ PFN_SG_LAST,	"SG_LAST" }, \
 	{ PFN_DEV,	"DEV" }, \
@@ -120,4 +122,15 @@ pud_t pud_mkdevmap(pud_t pud);
 #endif
 #endif /* __HAVE_ARCH_PTE_DEVMAP */
 
+#ifdef __HAVE_ARCH_PTE_SPECIAL
+static inline bool pfn_t_special(pfn_t pfn)
+{
+	return (pfn.val & PFN_SPECIAL) == PFN_SPECIAL;
+}
+#else
+static inline bool pfn_t_special(pfn_t pfn)
+{
+	return false;
+}
+#endif /* __HAVE_ARCH_PTE_SPECIAL */
 #endif /* _LINUX_PFN_T_H_ */
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 2dc5e98..5a3bb3b 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -167,10 +167,9 @@ void pipe_lock(struct pipe_inode_info *);
 void pipe_unlock(struct pipe_inode_info *);
 void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *);
 
-extern unsigned int pipe_max_size, pipe_min_size;
+extern unsigned int pipe_max_size;
 extern unsigned long pipe_user_pages_hard;
 extern unsigned long pipe_user_pages_soft;
-int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *);
 
 /* Drop the inode semaphore and wait for a pipe event, atomically */
 void pipe_wait(struct pipe_inode_info *pipe);
@@ -191,6 +190,6 @@ long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
 struct pipe_inode_info *get_pipe_info(struct file *file);
 
 int create_pipe_files(struct file **, int);
-unsigned int round_pipe_size(unsigned int size);
+unsigned int round_pipe_size(unsigned long size);
 
 #endif
diff --git a/include/linux/platform_data/mlxcpld-hotplug.h b/include/linux/platform_data/mlxcpld-hotplug.h
deleted file mode 100644
index e4cfcff..0000000
--- a/include/linux/platform_data/mlxcpld-hotplug.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * include/linux/platform_data/mlxcpld-hotplug.h
- * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
- * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H
-#define __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H
-
-/**
- * struct mlxcpld_hotplug_device - I2C device data:
- * @adapter: I2C device adapter;
- * @client: I2C device client;
- * @brdinfo: device board information;
- * @bus: I2C bus, where device is attached;
- *
- * Structure represents I2C hotplug device static data (board topology) and
- * dynamic data (related kernel objects handles).
- */
-struct mlxcpld_hotplug_device {
-	struct i2c_adapter *adapter;
-	struct i2c_client *client;
-	struct i2c_board_info brdinfo;
-	u16 bus;
-};
-
-/**
- * struct mlxcpld_hotplug_platform_data - device platform data:
- * @top_aggr_offset: offset of top aggregation interrupt register;
- * @top_aggr_mask: top aggregation interrupt common mask;
- * @top_aggr_psu_mask: top aggregation interrupt PSU mask;
- * @psu_reg_offset: offset of PSU interrupt register;
- * @psu_mask: PSU interrupt mask;
- * @psu_count: number of equipped replaceable PSUs;
- * @psu: pointer to PSU devices data array;
- * @top_aggr_pwr_mask: top aggregation interrupt power mask;
- * @pwr_reg_offset: offset of power interrupt register
- * @pwr_mask: power interrupt mask;
- * @pwr_count: number of power sources;
- * @pwr: pointer to power devices data array;
- * @top_aggr_fan_mask: top aggregation interrupt FAN mask;
- * @fan_reg_offset: offset of FAN interrupt register;
- * @fan_mask: FAN interrupt mask;
- * @fan_count: number of equipped replaceable FANs;
- * @fan: pointer to FAN devices data array;
- *
- * Structure represents board platform data, related to system hotplug events,
- * like FAN, PSU, power cable insertion and removing. This data provides the
- * number of hot-pluggable devices and hardware description for event handling.
- */
-struct mlxcpld_hotplug_platform_data {
-	u16 top_aggr_offset;
-	u8 top_aggr_mask;
-	u8 top_aggr_psu_mask;
-	u16 psu_reg_offset;
-	u8 psu_mask;
-	u8 psu_count;
-	struct mlxcpld_hotplug_device *psu;
-	u8 top_aggr_pwr_mask;
-	u16 pwr_reg_offset;
-	u8 pwr_mask;
-	u8 pwr_count;
-	struct mlxcpld_hotplug_device *pwr;
-	u8 top_aggr_fan_mask;
-	u16 fan_reg_offset;
-	u8 fan_mask;
-	u8 fan_count;
-	struct mlxcpld_hotplug_device *fan;
-};
-
-#endif /* __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H */
diff --git a/include/linux/platform_data/mlxreg.h b/include/linux/platform_data/mlxreg.h
new file mode 100644
index 0000000..fcdc707
--- /dev/null
+++ b/include/linux/platform_data/mlxreg.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_MLXREG_H
+#define __LINUX_PLATFORM_DATA_MLXREG_H
+
+#define MLXREG_CORE_LABEL_MAX_SIZE	32
+
+/**
+ * struct mlxreg_hotplug_device - I2C device data:
+ *
+ * @adapter: I2C device adapter;
+ * @client: I2C device client;
+ * @brdinfo: device board information;
+ * @nr: I2C device adapter number, to which device is to be attached;
+ *
+ * Structure represents I2C hotplug device static data (board topology) and
+ * dynamic data (related kernel objects handles).
+ */
+struct mlxreg_hotplug_device {
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	struct i2c_board_info *brdinfo;
+	int nr;
+};
+
+/**
+ * struct mlxreg_core_data - attributes control data:
+ *
+ * @label: attribute label;
+ * @label: attribute register offset;
+ * @reg: attribute register;
+ * @mask: attribute access mask;
+ * @mode: access mode;
+ * @bit: attribute effective bit;
+ * @np - pointer to node platform associated with attribute;
+ * @hpdev - hotplug device data;
+ * @health_cntr: dynamic device health indication counter;
+ * @attached: true if device has been attached after good health indication;
+ */
+struct mlxreg_core_data {
+	char label[MLXREG_CORE_LABEL_MAX_SIZE];
+	u32 reg;
+	u32 mask;
+	u32 bit;
+	umode_t	mode;
+	struct device_node *np;
+	struct mlxreg_hotplug_device hpdev;
+	u8 health_cntr;
+	bool attached;
+};
+
+/**
+ * struct mlxreg_core_item - same type components controlled by the driver:
+ *
+ * @data: component data;
+ * @aggr_mask: group aggregation mask;
+ * @reg: group interrupt status register;
+ * @mask: group interrupt mask;
+ * @cache: last status value for elements fro the same group;
+ * @count: number of available elements in the group;
+ * @ind: element's index inside the group;
+ * @inversed: if 0: 0 for signal status is OK, if 1 - 1 is OK;
+ * @health: true if device has health indication, false in other case;
+ */
+struct mlxreg_core_item {
+	struct mlxreg_core_data *data;
+	u32 aggr_mask;
+	u32 reg;
+	u32 mask;
+	u32 cache;
+	u8 count;
+	u8 ind;
+	u8 inversed;
+	u8 health;
+};
+
+/**
+ * struct mlxreg_core_platform_data - platform data:
+ *
+ * @led_data: led private data;
+ * @regmap: register map of parent device;
+ * @counter: number of led instances;
+ */
+struct mlxreg_core_platform_data {
+	struct mlxreg_core_data *data;
+	void *regmap;
+	int counter;
+};
+
+/**
+ * struct mlxreg_core_hotplug_platform_data - hotplug platform data:
+ *
+ * @items: same type components with the hotplug capability;
+ * @irq: platform interrupt number;
+ * @regmap: register map of parent device;
+ * @counter: number of the components with the hotplug capability;
+ * @cell: location of top aggregation interrupt register;
+ * @mask: top aggregation interrupt common mask;
+ * @cell_low: location of low aggregation interrupt register;
+ * @mask_low: low aggregation interrupt common mask;
+ */
+struct mlxreg_core_hotplug_platform_data {
+	struct mlxreg_core_item *items;
+	int irq;
+	void *regmap;
+	int counter;
+	u32 cell;
+	u32 mask;
+	u32 cell_low;
+	u32 mask_low;
+};
+
+#endif /* __LINUX_PLATFORM_DATA_MLXREG_H */
diff --git a/include/linux/psci.h b/include/linux/psci.h
index f724fd8..8b1b3b5 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -25,6 +25,17 @@ bool psci_tos_resident_on(int cpu);
 int psci_cpu_init_idle(unsigned int cpu);
 int psci_cpu_suspend_enter(unsigned long index);
 
+enum psci_conduit {
+	PSCI_CONDUIT_NONE,
+	PSCI_CONDUIT_SMC,
+	PSCI_CONDUIT_HVC,
+};
+
+enum smccc_version {
+	SMCCC_VERSION_1_0,
+	SMCCC_VERSION_1_1,
+};
+
 struct psci_operations {
 	u32 (*get_version)(void);
 	int (*cpu_suspend)(u32 state, unsigned long entry_point);
@@ -34,6 +45,8 @@ struct psci_operations {
 	int (*affinity_info)(unsigned long target_affinity,
 			unsigned long lowest_affinity_level);
 	int (*migrate_info_type)(void);
+	enum psci_conduit conduit;
+	enum smccc_version smccc_version;
 };
 
 extern struct psci_operations psci_ops;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 166144c..b161ef8 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -555,6 +555,14 @@ struct task_struct {
 	unsigned long			wakee_flip_decay_ts;
 	struct task_struct		*last_wakee;
 
+	/*
+	 * recent_used_cpu is initially set as the last CPU used by a task
+	 * that wakes affine another task. Waker/wakee relationships can
+	 * push tasks around a CPU where each wakeup moves to the next one.
+	 * Tracking a recently used CPU allows a quick search for a recently
+	 * used CPU that may be idle.
+	 */
+	int				recent_used_cpu;
 	int				wake_cpu;
 #endif
 	int				on_rq;
@@ -1489,6 +1497,11 @@ static inline struct thread_info *task_thread_info(struct task_struct *task)
 extern struct task_struct *find_task_by_vpid(pid_t nr);
 extern struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns);
 
+/*
+ * find a task by its virtual pid and get the task struct
+ */
+extern struct task_struct *find_get_task_by_vpid(pid_t nr);
+
 extern int wake_up_state(struct task_struct *tsk, unsigned int state);
 extern int wake_up_process(struct task_struct *tsk);
 extern void wake_up_new_task(struct task_struct *tsk);
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index bd42256..1149533 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -7,6 +7,7 @@
 #include <linux/sched.h>
 #include <linux/mm_types.h>
 #include <linux/gfp.h>
+#include <linux/sync_core.h>
 
 /*
  * Routines for handling mm_structs
@@ -194,18 +195,48 @@ static inline void memalloc_noreclaim_restore(unsigned int flags)
 
 #ifdef CONFIG_MEMBARRIER
 enum {
-	MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY	= (1U << 0),
-	MEMBARRIER_STATE_SWITCH_MM			= (1U << 1),
+	MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY		= (1U << 0),
+	MEMBARRIER_STATE_PRIVATE_EXPEDITED			= (1U << 1),
+	MEMBARRIER_STATE_GLOBAL_EXPEDITED_READY			= (1U << 2),
+	MEMBARRIER_STATE_GLOBAL_EXPEDITED			= (1U << 3),
+	MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY	= (1U << 4),
+	MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE		= (1U << 5),
 };
 
+enum {
+	MEMBARRIER_FLAG_SYNC_CORE	= (1U << 0),
+};
+
+#ifdef CONFIG_ARCH_HAS_MEMBARRIER_CALLBACKS
+#include <asm/membarrier.h>
+#endif
+
+static inline void membarrier_mm_sync_core_before_usermode(struct mm_struct *mm)
+{
+	if (likely(!(atomic_read(&mm->membarrier_state) &
+		     MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE)))
+		return;
+	sync_core_before_usermode();
+}
+
 static inline void membarrier_execve(struct task_struct *t)
 {
 	atomic_set(&t->mm->membarrier_state, 0);
 }
 #else
+#ifdef CONFIG_ARCH_HAS_MEMBARRIER_CALLBACKS
+static inline void membarrier_arch_switch_mm(struct mm_struct *prev,
+					     struct mm_struct *next,
+					     struct task_struct *tsk)
+{
+}
+#endif
 static inline void membarrier_execve(struct task_struct *t)
 {
 }
+static inline void membarrier_mm_sync_core_before_usermode(struct mm_struct *mm)
+{
+}
 #endif
 
 #endif /* _LINUX_SCHED_MM_H */
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 09c6e28..ab437dd 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -140,6 +140,20 @@ void *__seq_open_private(struct file *, const struct seq_operations *, int);
 int seq_open_private(struct file *, const struct seq_operations *, int);
 int seq_release_private(struct inode *, struct file *);
 
+#define DEFINE_SHOW_ATTRIBUTE(__name)					\
+static int __name ## _open(struct inode *inode, struct file *file)	\
+{									\
+	return single_open(file, __name ## _show, inode->i_private);	\
+}									\
+									\
+static const struct file_operations __name ## _fops = {			\
+	.owner		= THIS_MODULE,					\
+	.open		= __name ## _open,				\
+	.read		= seq_read,					\
+	.llseek		= seq_lseek,					\
+	.release	= single_release,				\
+}
+
 static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
 {
 #ifdef CONFIG_USER_NS
diff --git a/include/linux/switchtec.h b/include/linux/switchtec.h
index 6d325a7..ec93e93 100644
--- a/include/linux/switchtec.h
+++ b/include/linux/switchtec.h
@@ -100,6 +100,9 @@ struct sw_event_regs {
 	u32 gpio_interrupt_hdr;
 	u32 gpio_interrupt_data;
 	u32 reserved16[4];
+	u32 gfms_event_hdr;
+	u32 gfms_event_data;
+	u32 reserved17[4];
 } __packed;
 
 enum {
diff --git a/include/linux/sync_core.h b/include/linux/sync_core.h
new file mode 100644
index 0000000..013da4b
--- /dev/null
+++ b/include/linux/sync_core.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_SYNC_CORE_H
+#define _LINUX_SYNC_CORE_H
+
+#ifdef CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
+#include <asm/sync_core.h>
+#else
+/*
+ * This is a dummy sync_core_before_usermode() implementation that can be used
+ * on all architectures which return to user-space through core serializing
+ * instructions.
+ * If your architecture returns to user-space through non-core-serializing
+ * instructions, you need to write your own functions.
+ */
+static inline void sync_core_before_usermode(void)
+{
+}
+#endif
+
+#endif /* _LINUX_SYNC_CORE_H */
+
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 992bc99..b769ecf 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -51,9 +51,6 @@ extern int proc_dointvec_minmax(struct ctl_table *, int,
 extern int proc_douintvec_minmax(struct ctl_table *table, int write,
 				 void __user *buffer, size_t *lenp,
 				 loff_t *ppos);
-extern int proc_dopipe_max_size(struct ctl_table *table, int write,
-				void __user *buffer, size_t *lenp,
-				loff_t *ppos);
 extern int proc_dointvec_jiffies(struct ctl_table *, int,
 				 void __user *, size_t *, loff_t *);
 extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int,
diff --git a/include/linux/uuid.h b/include/linux/uuid.h
index 33b0bdb..d9c4a6c 100644
--- a/include/linux/uuid.h
+++ b/include/linux/uuid.h
@@ -17,6 +17,7 @@
 #define _LINUX_UUID_H_
 
 #include <uapi/linux/uuid.h>
+#include <linux/string.h>
 
 #define UUID_SIZE 16
 
diff --git a/include/media/cec.h b/include/media/cec.h
index 1634121..7cdf71d 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -122,6 +122,7 @@ struct cec_adap_ops {
 	/* Low-level callbacks */
 	int (*adap_enable)(struct cec_adapter *adap, bool enable);
 	int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
+	int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
 	int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
 	int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
 			     u32 signal_free_time, struct cec_msg *msg);
@@ -191,11 +192,6 @@ struct cec_adapter {
 
 	u32 tx_timeouts;
 
-#ifdef CONFIG_MEDIA_CEC_RC
-	bool rc_repeating;
-	int rc_last_scancode;
-	u64 rc_last_keypress;
-#endif
 #ifdef CONFIG_CEC_NOTIFIER
 	struct cec_notifier *notifier;
 #endif
@@ -229,6 +225,18 @@ static inline bool cec_is_sink(const struct cec_adapter *adap)
 	return adap->phys_addr == 0;
 }
 
+/**
+ * cec_is_registered() - is the CEC adapter registered?
+ *
+ * @adap:	the CEC adapter, may be NULL.
+ *
+ * Return: true if the adapter is registered, false otherwise.
+ */
+static inline bool cec_is_registered(const struct cec_adapter *adap)
+{
+	return adap && adap->devnode.registered;
+}
+
 #define cec_phys_addr_exp(pa) \
 	((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf
 
diff --git a/drivers/media/dvb-core/demux.h b/include/media/demux.h
similarity index 100%
rename from drivers/media/dvb-core/demux.h
rename to include/media/demux.h
diff --git a/drivers/media/dvb-core/dmxdev.h b/include/media/dmxdev.h
similarity index 82%
rename from drivers/media/dvb-core/dmxdev.h
rename to include/media/dmxdev.h
index 5e795f5..2f5cb2c 100644
--- a/drivers/media/dvb-core/dmxdev.h
+++ b/include/media/dmxdev.h
@@ -32,9 +32,10 @@
 
 #include <linux/dvb/dmx.h>
 
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_ringbuffer.h"
+#include <media/dvbdev.h>
+#include <media/demux.h>
+#include <media/dvb_ringbuffer.h>
+#include <media/dvb_vb2.h>
 
 /**
  * enum dmxdev_type - type of demux filter type.
@@ -89,23 +90,29 @@ struct dmxdev_feed {
 /**
  * struct dmxdev_filter - digital TV dmxdev filter
  *
- * @filter:	a dmxdev filter. Currently used only for section filter:
- *		if the filter is Section, it contains a
- *		&struct dmx_section_filter @sec pointer.
- * @feed:	a dmxdev feed. Depending on the feed type, it can be:
- *		for TS feed: a &struct list_head @ts list of TS and PES
- *		feeds;
- *		for section feed: a &struct dmx_section_feed @sec pointer.
- * @params:	dmxdev filter parameters. Depending on the feed type, it
- *		can be:
- *		for section filter: a &struct dmx_sct_filter_params @sec
- *		embedded struct;
- *		for a TS filter: a &struct dmx_pes_filter_params @pes
- *		embedded struct.
+ * @filter:	a union describing a dmxdev filter.
+ *		Currently used only for section filters.
+ * @filter.sec: a &struct dmx_section_filter pointer.
+ *		For section filter only.
+ * @feed:	a union describing a dmxdev feed.
+ *		Depending on the filter type, it can be either
+ *		@feed.ts or @feed.sec.
+ * @feed.ts:	a &struct list_head list.
+ *		For TS and PES feeds.
+ * @feed.sec:	a &struct dmx_section_feed pointer.
+ *		For section feed only.
+ * @params:	a union describing dmxdev filter parameters.
+ *		Depending on the filter type, it can be either
+ *		@params.sec or @params.pes.
+ * @params.sec:	a &struct dmx_sct_filter_params embedded struct.
+ *		For section filter only.
+ * @params.pes:	a &struct dmx_pes_filter_params embedded struct.
+ *		For PES filter only.
  * @type:	type of the dmxdev filter, as defined by &enum dmxdev_type.
  * @state:	state of the dmxdev filter, as defined by &enum dmxdev_state.
  * @dev:	pointer to &struct dmxdev.
  * @buffer:	an embedded &struct dvb_ringbuffer buffer.
+ * @vb2_ctx:	control struct for VB2 handler
  * @mutex:	protects the access to &struct dmxdev_filter.
  * @timer:	&struct timer_list embedded timer, used to check for
  *		feed timeouts.
@@ -135,6 +142,7 @@ struct dmxdev_filter {
 	enum dmxdev_state state;
 	struct dmxdev *dev;
 	struct dvb_ringbuffer buffer;
+	struct dvb_vb2_ctx vb2_ctx;
 
 	struct mutex mutex;
 
@@ -158,6 +166,7 @@ struct dmxdev_filter {
  * @exit:		flag to indicate that the demux is being released.
  * @dvr_orig_fe:	pointer to &struct dmx_frontend.
  * @dvr_buffer:		embedded &struct dvb_ringbuffer for DVB output.
+ * @dvr_vb2_ctx:	control struct for VB2 handler
  * @mutex:		protects the usage of this structure.
  * @lock:		protects access to &dmxdev->filter->data.
  */
@@ -178,6 +187,8 @@ struct dmxdev {
 	struct dvb_ringbuffer dvr_buffer;
 #define DVR_BUFFER_SIZE (10*188*1024)
 
+	struct dvb_vb2_ctx dvr_vb2_ctx;
+
 	struct mutex mutex;
 	spinlock_t lock;
 };
diff --git a/include/media/drv-intf/cx2341x.h b/include/media/drv-intf/cx2341x.h
index 9635eeb..33a97bf 100644
--- a/include/media/drv-intf/cx2341x.h
+++ b/include/media/drv-intf/cx2341x.h
@@ -29,8 +29,8 @@ enum cx2341x_port {
 
 enum cx2341x_cap {
 	CX2341X_CAP_HAS_SLICED_VBI = 1 << 0,
-	CX2341X_CAP_HAS_TS 	   = 1 << 1,
-	CX2341X_CAP_HAS_AC3 	   = 1 << 2,
+	CX2341X_CAP_HAS_TS	   = 1 << 1,
+	CX2341X_CAP_HAS_AC3	   = 1 << 2,
 };
 
 struct cx2341x_mpeg_params {
@@ -204,92 +204,92 @@ void cx2341x_handler_set_busy(struct cx2341x_handler *cxhdl, int busy);
 /* Firmware API commands */
 
 /* MPEG decoder API, specific to the cx23415 */
-#define CX2341X_DEC_PING_FW 			0x00
-#define CX2341X_DEC_START_PLAYBACK 		0x01
-#define CX2341X_DEC_STOP_PLAYBACK 		0x02
-#define CX2341X_DEC_SET_PLAYBACK_SPEED 		0x03
-#define CX2341X_DEC_STEP_VIDEO 			0x05
-#define CX2341X_DEC_SET_DMA_BLOCK_SIZE 		0x08
+#define CX2341X_DEC_PING_FW			0x00
+#define CX2341X_DEC_START_PLAYBACK		0x01
+#define CX2341X_DEC_STOP_PLAYBACK		0x02
+#define CX2341X_DEC_SET_PLAYBACK_SPEED		0x03
+#define CX2341X_DEC_STEP_VIDEO			0x05
+#define CX2341X_DEC_SET_DMA_BLOCK_SIZE		0x08
 #define CX2341X_DEC_GET_XFER_INFO		0x09
 #define CX2341X_DEC_GET_DMA_STATUS		0x0a
 #define CX2341X_DEC_SCHED_DMA_FROM_HOST		0x0b
-#define CX2341X_DEC_PAUSE_PLAYBACK 		0x0d
-#define CX2341X_DEC_HALT_FW 			0x0e
-#define CX2341X_DEC_SET_STANDARD 		0x10
+#define CX2341X_DEC_PAUSE_PLAYBACK		0x0d
+#define CX2341X_DEC_HALT_FW			0x0e
+#define CX2341X_DEC_SET_STANDARD		0x10
 #define CX2341X_DEC_GET_VERSION			0x11
-#define CX2341X_DEC_SET_STREAM_INPUT 		0x14
-#define CX2341X_DEC_GET_TIMING_INFO 		0x15
-#define CX2341X_DEC_SET_AUDIO_MODE 		0x16
+#define CX2341X_DEC_SET_STREAM_INPUT		0x14
+#define CX2341X_DEC_GET_TIMING_INFO		0x15
+#define CX2341X_DEC_SET_AUDIO_MODE		0x16
 #define CX2341X_DEC_SET_EVENT_NOTIFICATION	0x17
 #define CX2341X_DEC_SET_DISPLAY_BUFFERS		0x18
-#define CX2341X_DEC_EXTRACT_VBI 		0x19
-#define CX2341X_DEC_SET_DECODER_SOURCE 		0x1a
+#define CX2341X_DEC_EXTRACT_VBI			0x19
+#define CX2341X_DEC_SET_DECODER_SOURCE		0x1a
 #define CX2341X_DEC_SET_PREBUFFERING		0x1e
 
 /* MPEG encoder API */
-#define CX2341X_ENC_PING_FW 			0x80
-#define CX2341X_ENC_START_CAPTURE 		0x81
-#define CX2341X_ENC_STOP_CAPTURE 		0x82
-#define CX2341X_ENC_SET_AUDIO_ID 		0x89
-#define CX2341X_ENC_SET_VIDEO_ID 		0x8b
-#define CX2341X_ENC_SET_PCR_ID 			0x8d
-#define CX2341X_ENC_SET_FRAME_RATE 		0x8f
-#define CX2341X_ENC_SET_FRAME_SIZE 		0x91
-#define CX2341X_ENC_SET_BIT_RATE 		0x95
-#define CX2341X_ENC_SET_GOP_PROPERTIES 		0x97
-#define CX2341X_ENC_SET_ASPECT_RATIO 		0x99
-#define CX2341X_ENC_SET_DNR_FILTER_MODE 	0x9b
-#define CX2341X_ENC_SET_DNR_FILTER_PROPS 	0x9d
-#define CX2341X_ENC_SET_CORING_LEVELS 		0x9f
-#define CX2341X_ENC_SET_SPATIAL_FILTER_TYPE 	0xa1
-#define CX2341X_ENC_SET_VBI_LINE 		0xb7
-#define CX2341X_ENC_SET_STREAM_TYPE 		0xb9
-#define CX2341X_ENC_SET_OUTPUT_PORT 		0xbb
-#define CX2341X_ENC_SET_AUDIO_PROPERTIES 	0xbd
-#define CX2341X_ENC_HALT_FW 			0xc3
+#define CX2341X_ENC_PING_FW			0x80
+#define CX2341X_ENC_START_CAPTURE		0x81
+#define CX2341X_ENC_STOP_CAPTURE		0x82
+#define CX2341X_ENC_SET_AUDIO_ID		0x89
+#define CX2341X_ENC_SET_VIDEO_ID		0x8b
+#define CX2341X_ENC_SET_PCR_ID			0x8d
+#define CX2341X_ENC_SET_FRAME_RATE		0x8f
+#define CX2341X_ENC_SET_FRAME_SIZE		0x91
+#define CX2341X_ENC_SET_BIT_RATE		0x95
+#define CX2341X_ENC_SET_GOP_PROPERTIES		0x97
+#define CX2341X_ENC_SET_ASPECT_RATIO		0x99
+#define CX2341X_ENC_SET_DNR_FILTER_MODE		0x9b
+#define CX2341X_ENC_SET_DNR_FILTER_PROPS	0x9d
+#define CX2341X_ENC_SET_CORING_LEVELS		0x9f
+#define CX2341X_ENC_SET_SPATIAL_FILTER_TYPE	0xa1
+#define CX2341X_ENC_SET_VBI_LINE		0xb7
+#define CX2341X_ENC_SET_STREAM_TYPE		0xb9
+#define CX2341X_ENC_SET_OUTPUT_PORT		0xbb
+#define CX2341X_ENC_SET_AUDIO_PROPERTIES	0xbd
+#define CX2341X_ENC_HALT_FW			0xc3
 #define CX2341X_ENC_GET_VERSION			0xc4
-#define CX2341X_ENC_SET_GOP_CLOSURE 		0xc5
-#define CX2341X_ENC_GET_SEQ_END 		0xc6
-#define CX2341X_ENC_SET_PGM_INDEX_INFO 		0xc7
+#define CX2341X_ENC_SET_GOP_CLOSURE		0xc5
+#define CX2341X_ENC_GET_SEQ_END			0xc6
+#define CX2341X_ENC_SET_PGM_INDEX_INFO		0xc7
 #define CX2341X_ENC_SET_VBI_CONFIG		0xc8
-#define CX2341X_ENC_SET_DMA_BLOCK_SIZE 		0xc9
+#define CX2341X_ENC_SET_DMA_BLOCK_SIZE		0xc9
 #define CX2341X_ENC_GET_PREV_DMA_INFO_MB_10	0xca
 #define CX2341X_ENC_GET_PREV_DMA_INFO_MB_9	0xcb
-#define CX2341X_ENC_SCHED_DMA_TO_HOST 		0xcc
-#define CX2341X_ENC_INITIALIZE_INPUT 		0xcd
-#define CX2341X_ENC_SET_FRAME_DROP_RATE 	0xd0
-#define CX2341X_ENC_PAUSE_ENCODER 		0xd2
-#define CX2341X_ENC_REFRESH_INPUT 		0xd3
+#define CX2341X_ENC_SCHED_DMA_TO_HOST		0xcc
+#define CX2341X_ENC_INITIALIZE_INPUT		0xcd
+#define CX2341X_ENC_SET_FRAME_DROP_RATE		0xd0
+#define CX2341X_ENC_PAUSE_ENCODER		0xd2
+#define CX2341X_ENC_REFRESH_INPUT		0xd3
 #define CX2341X_ENC_SET_COPYRIGHT		0xd4
-#define CX2341X_ENC_SET_EVENT_NOTIFICATION 	0xd5
-#define CX2341X_ENC_SET_NUM_VSYNC_LINES 	0xd6
-#define CX2341X_ENC_SET_PLACEHOLDER 		0xd7
-#define CX2341X_ENC_MUTE_VIDEO 			0xd9
-#define CX2341X_ENC_MUTE_AUDIO 			0xda
+#define CX2341X_ENC_SET_EVENT_NOTIFICATION	0xd5
+#define CX2341X_ENC_SET_NUM_VSYNC_LINES		0xd6
+#define CX2341X_ENC_SET_PLACEHOLDER		0xd7
+#define CX2341X_ENC_MUTE_VIDEO			0xd9
+#define CX2341X_ENC_MUTE_AUDIO			0xda
 #define CX2341X_ENC_SET_VERT_CROP_LINE		0xdb
-#define CX2341X_ENC_MISC 			0xdc
+#define CX2341X_ENC_MISC			0xdc
 
 /* OSD API, specific to the cx23415 */
-#define CX2341X_OSD_GET_FRAMEBUFFER 		0x41
-#define CX2341X_OSD_GET_PIXEL_FORMAT 		0x42
-#define CX2341X_OSD_SET_PIXEL_FORMAT 		0x43
-#define CX2341X_OSD_GET_STATE 			0x44
-#define CX2341X_OSD_SET_STATE 			0x45
-#define CX2341X_OSD_GET_OSD_COORDS 		0x46
-#define CX2341X_OSD_SET_OSD_COORDS 		0x47
-#define CX2341X_OSD_GET_SCREEN_COORDS 		0x48
-#define CX2341X_OSD_SET_SCREEN_COORDS 		0x49
-#define CX2341X_OSD_GET_GLOBAL_ALPHA 		0x4a
-#define CX2341X_OSD_SET_GLOBAL_ALPHA 		0x4b
-#define CX2341X_OSD_SET_BLEND_COORDS 		0x4c
-#define CX2341X_OSD_GET_FLICKER_STATE 		0x4f
-#define CX2341X_OSD_SET_FLICKER_STATE 		0x50
-#define CX2341X_OSD_BLT_COPY 			0x52
-#define CX2341X_OSD_BLT_FILL 			0x53
-#define CX2341X_OSD_BLT_TEXT 			0x54
-#define CX2341X_OSD_SET_FRAMEBUFFER_WINDOW 	0x56
-#define CX2341X_OSD_SET_CHROMA_KEY 		0x60
-#define CX2341X_OSD_GET_ALPHA_CONTENT_INDEX 	0x61
-#define CX2341X_OSD_SET_ALPHA_CONTENT_INDEX 	0x62
+#define CX2341X_OSD_GET_FRAMEBUFFER		0x41
+#define CX2341X_OSD_GET_PIXEL_FORMAT		0x42
+#define CX2341X_OSD_SET_PIXEL_FORMAT		0x43
+#define CX2341X_OSD_GET_STATE			0x44
+#define CX2341X_OSD_SET_STATE			0x45
+#define CX2341X_OSD_GET_OSD_COORDS		0x46
+#define CX2341X_OSD_SET_OSD_COORDS		0x47
+#define CX2341X_OSD_GET_SCREEN_COORDS		0x48
+#define CX2341X_OSD_SET_SCREEN_COORDS		0x49
+#define CX2341X_OSD_GET_GLOBAL_ALPHA		0x4a
+#define CX2341X_OSD_SET_GLOBAL_ALPHA		0x4b
+#define CX2341X_OSD_SET_BLEND_COORDS		0x4c
+#define CX2341X_OSD_GET_FLICKER_STATE		0x4f
+#define CX2341X_OSD_SET_FLICKER_STATE		0x50
+#define CX2341X_OSD_BLT_COPY			0x52
+#define CX2341X_OSD_BLT_FILL			0x53
+#define CX2341X_OSD_BLT_TEXT			0x54
+#define CX2341X_OSD_SET_FRAMEBUFFER_WINDOW	0x56
+#define CX2341X_OSD_SET_CHROMA_KEY		0x60
+#define CX2341X_OSD_GET_ALPHA_CONTENT_INDEX	0x61
+#define CX2341X_OSD_SET_ALPHA_CONTENT_INDEX	0x62
 
 #endif /* CX2341X_H */
diff --git a/include/media/drv-intf/exynos-fimc.h b/include/media/drv-intf/exynos-fimc.h
index 69bcd2a..f9c6433 100644
--- a/include/media/drv-intf/exynos-fimc.h
+++ b/include/media/drv-intf/exynos-fimc.h
@@ -155,7 +155,8 @@ static inline struct exynos_video_entity *vdev_to_exynos_video_entity(
 }
 
 #define fimc_pipeline_call(ent, op, args...)				  \
-	(!(ent) ? -ENOENT : (((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
+	((!(ent) || !(ent)->pipe) ? -ENOENT : \
+	(((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
 	(ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD))	  \
 
 #endif /* S5P_FIMC_H_ */
diff --git a/include/media/drv-intf/msp3400.h b/include/media/drv-intf/msp3400.h
index 1e6e802..db98ce4 100644
--- a/include/media/drv-intf/msp3400.h
+++ b/include/media/drv-intf/msp3400.h
@@ -80,17 +80,17 @@
  */
 
 /* SCART input to DSP selection */
-#define MSP_IN_SCART1  		0  /* Pin SC1_IN */
-#define MSP_IN_SCART2  		1  /* Pin SC2_IN */
-#define MSP_IN_SCART3  		2  /* Pin SC3_IN */
-#define MSP_IN_SCART4  		3  /* Pin SC4_IN */
-#define MSP_IN_MONO     	6  /* Pin MONO_IN */
-#define MSP_IN_MUTE     	7  /* Mute DSP input */
-#define MSP_SCART_TO_DSP(in) 	(in)
+#define MSP_IN_SCART1		0  /* Pin SC1_IN */
+#define MSP_IN_SCART2		1  /* Pin SC2_IN */
+#define MSP_IN_SCART3		2  /* Pin SC3_IN */
+#define MSP_IN_SCART4		3  /* Pin SC4_IN */
+#define MSP_IN_MONO		6  /* Pin MONO_IN */
+#define MSP_IN_MUTE		7  /* Mute DSP input */
+#define MSP_SCART_TO_DSP(in)	(in)
 /* Tuner input to demodulator and DSP selection */
-#define MSP_IN_TUNER1 		0  /* Analog Sound IF input pin ANA_IN1 */
-#define MSP_IN_TUNER2 		1  /* Analog Sound IF input pin ANA_IN2 */
-#define MSP_TUNER_TO_DSP(in) 	((in) << 3)
+#define MSP_IN_TUNER1		0  /* Analog Sound IF input pin ANA_IN1 */
+#define MSP_IN_TUNER2		1  /* Analog Sound IF input pin ANA_IN2 */
+#define MSP_TUNER_TO_DSP(in)	((in) << 3)
 
 /* The msp has up to 5 DSP outputs, each output can independently select
    a DSP input.
@@ -109,30 +109,30 @@
    DSP. This is currently not implemented. Also not implemented is the
    multi-channel capable I2S3 input of the 44x0G. If someone can demonstrate
    a need for one of those features then additional support can be added. */
-#define MSP_DSP_IN_TUNER 	0  /* Tuner DSP input */
-#define MSP_DSP_IN_SCART 	2  /* SCART DSP input */
-#define MSP_DSP_IN_I2S1 	5  /* I2S1 DSP input */
-#define MSP_DSP_IN_I2S2 	6  /* I2S2 DSP input */
-#define MSP_DSP_IN_I2S3    	7  /* I2S3 DSP input */
-#define MSP_DSP_IN_MAIN_AVC 	11 /* MAIN AVC processed DSP input */
-#define MSP_DSP_IN_MAIN 	12 /* MAIN DSP input */
-#define MSP_DSP_IN_AUX 		13 /* AUX DSP input */
-#define MSP_DSP_TO_MAIN(in)   	((in) << 4)
-#define MSP_DSP_TO_AUX(in)    	((in) << 8)
-#define MSP_DSP_TO_SCART1(in) 	((in) << 12)
-#define MSP_DSP_TO_SCART2(in) 	((in) << 16)
-#define MSP_DSP_TO_I2S(in)    	((in) << 20)
+#define MSP_DSP_IN_TUNER	0  /* Tuner DSP input */
+#define MSP_DSP_IN_SCART	2  /* SCART DSP input */
+#define MSP_DSP_IN_I2S1		5  /* I2S1 DSP input */
+#define MSP_DSP_IN_I2S2		6  /* I2S2 DSP input */
+#define MSP_DSP_IN_I2S3		7  /* I2S3 DSP input */
+#define MSP_DSP_IN_MAIN_AVC	11 /* MAIN AVC processed DSP input */
+#define MSP_DSP_IN_MAIN		12 /* MAIN DSP input */
+#define MSP_DSP_IN_AUX		13 /* AUX DSP input */
+#define MSP_DSP_TO_MAIN(in)	((in) << 4)
+#define MSP_DSP_TO_AUX(in)	((in) << 8)
+#define MSP_DSP_TO_SCART1(in)	((in) << 12)
+#define MSP_DSP_TO_SCART2(in)	((in) << 16)
+#define MSP_DSP_TO_I2S(in)	((in) << 20)
 
 /* Output SCART select: the SCART outputs can select which input
    to use. */
-#define MSP_SC_IN_SCART1 	0  /* SCART1 input, bypassing the DSP */
-#define MSP_SC_IN_SCART2 	1  /* SCART2 input, bypassing the DSP */
-#define MSP_SC_IN_SCART3 	2  /* SCART3 input, bypassing the DSP */
-#define MSP_SC_IN_SCART4 	3  /* SCART4 input, bypassing the DSP */
-#define MSP_SC_IN_DSP_SCART1 	4  /* DSP SCART1 input */
-#define MSP_SC_IN_DSP_SCART2 	5  /* DSP SCART2 input */
-#define MSP_SC_IN_MONO 		6  /* MONO input, bypassing the DSP */
-#define MSP_SC_IN_MUTE 		7  /* MUTE output */
+#define MSP_SC_IN_SCART1	0  /* SCART1 input, bypassing the DSP */
+#define MSP_SC_IN_SCART2	1  /* SCART2 input, bypassing the DSP */
+#define MSP_SC_IN_SCART3	2  /* SCART3 input, bypassing the DSP */
+#define MSP_SC_IN_SCART4	3  /* SCART4 input, bypassing the DSP */
+#define MSP_SC_IN_DSP_SCART1	4  /* DSP SCART1 input */
+#define MSP_SC_IN_DSP_SCART2	5  /* DSP SCART2 input */
+#define MSP_SC_IN_MONO		6  /* MONO input, bypassing the DSP */
+#define MSP_SC_IN_MUTE		7  /* MUTE output */
 #define MSP_SC_TO_SCART1(in)	(in)
 #define MSP_SC_TO_SCART2(in)	((in) << 4)
 
diff --git a/include/media/drv-intf/saa7146.h b/include/media/drv-intf/saa7146.h
index 769c6cf..a7bf2c4 100644
--- a/include/media/drv-intf/saa7146.h
+++ b/include/media/drv-intf/saa7146.h
@@ -118,7 +118,7 @@ struct saa7146_dev
 {
 	struct module			*module;
 
-	struct v4l2_device 		v4l2_dev;
+	struct v4l2_device		v4l2_dev;
 	struct v4l2_ctrl_handler	ctrl_handler;
 
 	/* different device locks */
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/include/media/dvb-usb-ids.h
similarity index 98%
rename from drivers/media/dvb-core/dvb-usb-ids.h
rename to include/media/dvb-usb-ids.h
index 54d7d8a..28e2be5 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/include/media/dvb-usb-ids.h
@@ -81,6 +81,7 @@
 #define USB_VID_AZUREWAVE			0x13d3
 #define USB_VID_TECHNISAT			0x14f7
 #define USB_VID_HAMA				0x147f
+#define USB_VID_MICROSOFT			0x045e
 
 /* Product IDs */
 #define USB_PID_ADSTECH_USB2_COLD			0xa333
@@ -385,6 +386,7 @@
 #define USB_PID_SONY_PLAYTV				0x0003
 #define USB_PID_MYGICA_D689				0xd811
 #define USB_PID_MYGICA_T230				0xc688
+#define USB_PID_MYGICA_T230C				0xc689
 #define USB_PID_ELGATO_EYETV_DIVERSITY			0x0011
 #define USB_PID_ELGATO_EYETV_DTT			0x0021
 #define USB_PID_ELGATO_EYETV_DTT_2			0x003f
@@ -418,4 +420,5 @@
 #define USB_PID_WINTV_SOLOHD                            0x0264
 #define USB_PID_EVOLVEO_XTRATV_STICK			0xa115
 #define USB_PID_HAMA_DVBT_HYBRID			0x2758
+#define USB_PID_XBOX_ONE_TUNER                          0x02d5
 #endif
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.h b/include/media/dvb_ca_en50221.h
similarity index 98%
rename from drivers/media/dvb-core/dvb_ca_en50221.h
rename to include/media/dvb_ca_en50221.h
index 367687d..a1c014b 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.h
+++ b/include/media/dvb_ca_en50221.h
@@ -20,7 +20,7 @@
 #include <linux/list.h>
 #include <linux/dvb/ca.h>
 
-#include "dvbdev.h"
+#include <media/dvbdev.h>
 
 #define DVB_CA_EN50221_POLL_CAM_PRESENT	1
 #define DVB_CA_EN50221_POLL_CAM_CHANGED	2
diff --git a/drivers/media/dvb-core/dvb_demux.h b/include/media/dvb_demux.h
similarity index 94%
rename from drivers/media/dvb-core/dvb_demux.h
rename to include/media/dvb_demux.h
index cc048f0..b070920 100644
--- a/drivers/media/dvb-core/dvb_demux.h
+++ b/include/media/dvb_demux.h
@@ -24,7 +24,7 @@
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 
-#include "demux.h"
+#include <media/demux.h>
 
 /**
  * enum dvb_dmx_filter_type - type of demux feed.
@@ -94,15 +94,20 @@ struct dvb_demux_filter {
 /**
  * struct dvb_demux_feed - describes a DVB field
  *
- * @feed:	a digital TV feed. It can either be a TS or a section feed:
- *		if the feed is TS, it contains &struct dvb_ts_feed @ts;
- *		if the feed is section, it contains
- *		&struct dmx_section_feed @sec.
- * @cb:		digital TV callbacks. depending on the feed type, it can be:
- *		if the feed is TS, it contains a dmx_ts_cb() @ts callback;
- *		if the feed is section, it contains a dmx_section_cb() @sec
- *		callback.
- *
+ * @feed:	a union describing a digital TV feed.
+ *		Depending on the feed type, it can be either
+ *		@feed.ts or @feed.sec.
+ * @feed.ts:	a &struct dmx_ts_feed pointer.
+ *		For TS feed only.
+ * @feed.sec:	a &struct dmx_section_feed pointer.
+ *		For section feed only.
+ * @cb:		a union describing digital TV callbacks.
+ *		Depending on the feed type, it can be either
+ *		@cb.ts or @cb.sec.
+ * @cb.ts:	a dmx_ts_cb() calback function pointer.
+ *		For TS feed only.
+ * @cb.sec:	a dmx_section_cb() callback function pointer.
+ *		For section feed only.
  * @demux:	pointer to &struct dvb_demux.
  * @priv:	private data that can optionally be used by a DVB driver.
  * @type:	type of the filter, as defined by &enum dvb_dmx_filter_type.
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/include/media/dvb_frontend.h
similarity index 98%
rename from drivers/media/dvb-core/dvb_frontend.h
rename to include/media/dvb_frontend.h
index ace0c2f..331c826 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/include/media/dvb_frontend.h
@@ -44,7 +44,7 @@
 
 #include <linux/dvb/frontend.h>
 
-#include "dvbdev.h"
+#include <media/dvbdev.h>
 
 /*
  * Maximum number of Delivery systems per frontend. It
@@ -99,10 +99,10 @@ struct dvb_tuner_info {
  * struct analog_parameters - Parameters to tune into an analog/radio channel
  *
  * @frequency:	Frequency used by analog TV tuner (either in 62.5 kHz step,
- * 		for TV, or 62.5 Hz for radio)
+ *		for TV, or 62.5 Hz for radio)
  * @mode:	Tuner mode, as defined on enum v4l2_tuner_type
  * @audmode:	Audio mode as defined for the rxsubchans field at videodev2.h,
- * 		e. g. V4L2_TUNER_MODE_*
+ *		e. g. V4L2_TUNER_MODE_*
  * @std:	TV standard bitmap as defined at videodev2.h, e. g. V4L2_STD_*
  *
  * Hybrid tuners should be supported by both V4L2 and DVB APIs. This
@@ -205,7 +205,7 @@ enum dvbfe_search {
  * @get_frequency:	get the actual tuned frequency
  * @get_bandwidth:	get the bandwitdh used by the low pass filters
  * @get_if_frequency:	get the Intermediate Frequency, in Hz. For baseband,
- * 			should return 0.
+ *			should return 0.
  * @get_status:		returns the frontend lock status
  * @get_rf_strength:	returns the RF signal strength. Used mostly to support
  *			analog TV and radio. Digital TV should report, instead,
@@ -364,7 +364,7 @@ struct dtv_frontend_properties;
  *			implementing this callback only if DVBv3 API
  *			compatibility is wanted.
  * @read_snr:		legacy callback function to return the Signal/Noise
- * 			rate. Newer drivers should provide such info via
+ *			rate. Newer drivers should provide such info via
  *			DVBv5 API, e. g. @set_frontend/@get_frontend,
  *			implementing this callback only if DVBv3 API
  *			compatibility is wanted.
@@ -490,7 +490,7 @@ struct dvb_fe_events {
  * @fec_inner:		Forward error correction inner Code Rate
  * @transmission_mode:	Transmission Mode
  * @bandwidth_hz:	Bandwidth, in Hz. A zero value means that userspace
- * 			wants to autodetect.
+ *			wants to autodetect.
  * @guard_interval:	Guard Interval
  * @hierarchy:		Hierarchy
  * @symbol_rate:	Symbol Rate
@@ -513,6 +513,8 @@ struct dvb_fe_events {
  * @layer.interleaving:	 per layer interleaving.
  * @stream_id:		If different than zero, enable substream filtering, if
  *			hardware supports (DVB-S2 and DVB-T2).
+ * @scrambling_sequence_index:	Carries the index of the DVB-S2 physical layer
+ *				scrambling sequence.
  * @atscmh_fic_ver:	Version number of the FIC (Fast Information Channel)
  *			signaling data (only ATSC-M/H)
  * @atscmh_parade_id:	Parade identification number (only ATSC-M/H)
@@ -536,7 +538,7 @@ struct dvb_fe_events {
  * @lna:		Power ON/OFF/AUTO the Linear Now-noise Amplifier (LNA)
  * @strength:		DVBv5 API statistics: Signal Strength
  * @cnr:		DVBv5 API statistics: Signal to Noise ratio of the
- * 			(main) carrier
+ *			(main) carrier
  * @pre_bit_error:	DVBv5 API statistics: pre-Viterbi bit error count
  * @pre_bit_count:	DVBv5 API statistics: pre-Viterbi bit count
  * @post_bit_error:	DVBv5 API statistics: post-Viterbi bit error count
@@ -591,6 +593,9 @@ struct dtv_frontend_properties {
 	/* Multistream specifics */
 	u32			stream_id;
 
+	/* Physical Layer Scrambling specifics */
+	u32			scrambling_sequence_index;
+
 	/* ATSC-MH specifics */
 	u8			atscmh_fic_ver;
 	u8			atscmh_parade_id;
diff --git a/drivers/media/dvb-core/dvb_math.h b/include/media/dvb_math.h
similarity index 100%
rename from drivers/media/dvb-core/dvb_math.h
rename to include/media/dvb_math.h
diff --git a/drivers/media/dvb-core/dvb_net.h b/include/media/dvb_net.h
similarity index 98%
rename from drivers/media/dvb-core/dvb_net.h
rename to include/media/dvb_net.h
index 1eae8ba..5e31d37 100644
--- a/drivers/media/dvb-core/dvb_net.h
+++ b/include/media/dvb_net.h
@@ -24,7 +24,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
-#include "dvbdev.h"
+#include <media/dvbdev.h>
 
 #define DVB_NET_DEVICES_MAX 10
 
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.h b/include/media/dvb_ringbuffer.h
similarity index 100%
rename from drivers/media/dvb-core/dvb_ringbuffer.h
rename to include/media/dvb_ringbuffer.h
diff --git a/include/media/dvb_vb2.h b/include/media/dvb_vb2.h
new file mode 100644
index 0000000..01d1202
--- /dev/null
+++ b/include/media/dvb_vb2.h
@@ -0,0 +1,266 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * dvb-vb2.h - DVB driver helper framework for streaming I/O
+ *
+ * Copyright (C) 2015 Samsung Electronics
+ *
+ * Author: jh1009.sung@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef _DVB_VB2_H
+#define _DVB_VB2_H
+
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/dvb/dmx.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+
+/**
+ * enum dvb_buf_type - types of Digital TV memory-mapped buffers
+ *
+ * @DVB_BUF_TYPE_CAPTURE: buffer is filled by the Kernel,
+ *			  with a received Digital TV stream
+ */
+enum dvb_buf_type {
+	DVB_BUF_TYPE_CAPTURE        = 1,
+};
+
+/**
+ * enum dvb_vb2_states - states to control VB2 state machine
+ * @DVB_VB2_STATE_NONE:
+ *	VB2 engine not initialized yet, init failed or VB2 was released.
+ * @DVB_VB2_STATE_INIT:
+ *	VB2 engine initialized.
+ * @DVB_VB2_STATE_REQBUFS:
+ *	Buffers were requested
+ * @DVB_VB2_STATE_STREAMON:
+ *	VB2 is streaming. Callers should not check it directly. Instead,
+ *	they should use dvb_vb2_is_streaming().
+ *
+ * Note:
+ *
+ * Callers should not touch at the state machine directly. This
+ * is handled inside dvb_vb2.c.
+ */
+enum dvb_vb2_states {
+	DVB_VB2_STATE_NONE	= 0x0,
+	DVB_VB2_STATE_INIT	= 0x1,
+	DVB_VB2_STATE_REQBUFS	= 0x2,
+	DVB_VB2_STATE_STREAMON	= 0x4,
+};
+
+#define DVB_VB2_NAME_MAX (20)
+
+/**
+ * struct dvb_buffer - video buffer information for v4l2.
+ *
+ * @vb:		embedded struct &vb2_buffer.
+ * @list:	list of &struct dvb_buffer.
+ */
+struct dvb_buffer {
+	struct vb2_buffer	vb;
+	struct list_head	list;
+};
+
+/**
+ * struct dvb_vb2_ctx - control struct for VB2 handler
+ * @vb_q:	pointer to &struct vb2_queue with videobuf2 queue.
+ * @mutex:	mutex to serialize vb2 operations. Used by
+ *		vb2 core %wait_prepare and %wait_finish operations.
+ * @slock:	spin lock used to protect buffer filling at dvb_vb2.c.
+ * @dvb_q:	List of buffers that are not filled yet.
+ * @buf:	Pointer to the buffer that are currently being filled.
+ * @offset:	index to the next position at the @buf to be filled.
+ * @remain:	How many bytes are left to be filled at @buf.
+ * @state:	bitmask of buffer states as defined by &enum dvb_vb2_states.
+ * @buf_siz:	size of each VB2 buffer.
+ * @buf_cnt:	number of VB2 buffers.
+ * @nonblocking:
+ *		If different than zero, device is operating on non-blocking
+ *		mode.
+ * @name:	name of the device type. Currently, it can either be
+ *		"dvr" or "demux_filter".
+ */
+struct dvb_vb2_ctx {
+	struct vb2_queue	vb_q;
+	struct mutex		mutex;
+	spinlock_t		slock;
+	struct list_head	dvb_q;
+	struct dvb_buffer	*buf;
+	int	offset;
+	int	remain;
+	int	state;
+	int	buf_siz;
+	int	buf_cnt;
+	int	nonblocking;
+	char	name[DVB_VB2_NAME_MAX + 1];
+};
+
+#ifndef DVB_MMAP
+static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx,
+			       const char *name, int non_blocking)
+{
+	return 0;
+};
+static inline int dvb_vb2_release(struct dvb_vb2_ctx *ctx)
+{
+	return 0;
+};
+#define dvb_vb2_is_streaming(ctx) (0)
+#define dvb_vb2_fill_buffer(ctx, file, wait) (0)
+
+static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx,
+				    struct file *file,
+				    poll_table *wait)
+{
+	return 0;
+}
+#else
+/**
+ * dvb_vb2_init - initializes VB2 handler
+ *
+ * @ctx:	control struct for VB2 handler
+ * @name:	name for the VB2 handler
+ * @non_blocking:
+ *		if not zero, it means that the device is at non-blocking mode
+ */
+int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking);
+
+/**
+ * dvb_vb2_release - Releases the VB2 handler allocated resources and
+ *	put @ctx at DVB_VB2_STATE_NONE state.
+ * @ctx:	control struct for VB2 handler
+ */
+int dvb_vb2_release(struct dvb_vb2_ctx *ctx);
+
+/**
+ * dvb_vb2_is_streaming - checks if the VB2 handler is streaming
+ * @ctx:	control struct for VB2 handler
+ *
+ * Return: 0 if not streaming, 1 otherwise.
+ */
+int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx);
+
+/**
+ * dvb_vb2_fill_buffer - fills a VB2 buffer
+ * @ctx:	control struct for VB2 handler
+ * @src:	place where the data is stored
+ * @len:	number of bytes to be copied from @src
+ */
+int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
+			const unsigned char *src, int len);
+
+/**
+ * dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV
+ *      buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @file:	&struct file argument passed to the poll
+ *		file operation handler.
+ * @wait:	&poll_table wait argument passed to the poll
+ *		file operation handler.
+ *
+ * Implements poll syscall() logic.
+ */
+__poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file,
+		      poll_table *wait);
+#endif
+
+/**
+ * dvb_vb2_stream_on() - Wrapper to vb2_core_streamon() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ *
+ * Starts dvb streaming
+ */
+int dvb_vb2_stream_on(struct dvb_vb2_ctx *ctx);
+/**
+ * dvb_vb2_stream_off() - Wrapper to vb2_core_streamoff() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ *
+ * Stops dvb streaming
+ */
+int dvb_vb2_stream_off(struct dvb_vb2_ctx *ctx);
+
+/**
+ * dvb_vb2_reqbufs() - Wrapper to vb2_core_reqbufs() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @req:	&struct dmx_requestbuffers passed from userspace in
+ *		order to handle &DMX_REQBUFS.
+ *
+ * Initiate streaming by requesting a number of buffers. Also used to
+ * free previously requested buffers, is ``req->count`` is zero.
+ */
+int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req);
+
+/**
+ * dvb_vb2_querybuf() - Wrapper to vb2_core_querybuf() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @b:		&struct dmx_buffer passed from userspace in
+ *		order to handle &DMX_QUERYBUF.
+ *
+ *
+ */
+int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
+
+/**
+ * dvb_vb2_expbuf() - Wrapper to vb2_core_expbuf() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @exp:	&struct dmx_exportbuffer passed from userspace in
+ *		order to handle &DMX_EXPBUF.
+ *
+ * Export a buffer as a file descriptor.
+ */
+int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp);
+
+/**
+ * dvb_vb2_qbuf() - Wrapper to vb2_core_qbuf() for Digital TV buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @b:		&struct dmx_buffer passed from userspace in
+ *		order to handle &DMX_QBUF.
+ *
+ * Queue a Digital TV buffer as requested by userspace
+ */
+int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
+
+/**
+ * dvb_vb2_dqbuf() - Wrapper to vb2_core_dqbuf() for Digital TV
+ *	buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @b:		&struct dmx_buffer passed from userspace in
+ *		order to handle &DMX_DQBUF.
+ *
+ * Dequeue a Digital TV buffer to the userspace
+ */
+int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
+
+/**
+ * dvb_vb2_mmap() - Wrapper to vb2_mmap() for Digital TV buffer handling.
+ *
+ * @ctx:	control struct for VB2 handler
+ * @vma:        pointer to &struct vm_area_struct with the vma passed
+ *              to the mmap file operation handler in the driver.
+ *
+ * map Digital TV video buffers into application address space.
+ */
+int dvb_vb2_mmap(struct dvb_vb2_ctx *ctx, struct vm_area_struct *vma);
+
+#endif /* _DVB_VB2_H */
diff --git a/drivers/media/dvb-core/dvbdev.h b/include/media/dvbdev.h
similarity index 98%
rename from drivers/media/dvb-core/dvbdev.h
rename to include/media/dvbdev.h
index bbc1c20..554db87 100644
--- a/drivers/media/dvb-core/dvbdev.h
+++ b/include/media/dvbdev.h
@@ -193,7 +193,7 @@ struct dvb_device {
  * @module:	initialized with THIS_MODULE at the caller
  * @device:	pointer to struct device that corresponds to the device driver
  * @adapter_nums: Array with a list of the numbers for @dvb_register_adapter;
- * 		to select among them. Typically, initialized with:
+ *		to select among them. Typically, initialized with:
  *		DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
  */
 int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
@@ -259,7 +259,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev);
 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
 /**
  * dvb_create_media_graph - Creates media graph for the Digital TV part of the
- * 				device.
+ *				device.
  *
  * @adap:			pointer to &struct dvb_adapter
  * @create_rf_connector:	if true, it creates the RF connector too
diff --git a/include/media/i2c-addr.h b/include/media/i2c-addr.h
deleted file mode 100644
index 1b6872f5..0000000
--- a/include/media/i2c-addr.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- *	V4L I2C address list
- *
- *
- *	Copyright (C) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- *	Based on a previous mapping by
- *	Ralph Metzler (rjkm@thp.uni-koeln.de)
- *	Gerd Knorr <kraxel@goldbach.in-berlin.de>
- *
- */
-
-/* bttv address list */
-#define I2C_ADDR_TSA5522	0xc2
-#define I2C_ADDR_TDA7432	0x8a
-#define I2C_ADDR_TDA8425	0x82
-#define I2C_ADDR_TDA9840	0x84
-#define I2C_ADDR_TDA9850	0xb6 /* also used by 9855,9873 */
-#define I2C_ADDR_TDA9874	0xb0 /* also used by 9875 */
-#define I2C_ADDR_TDA9875	0xb0
-#define I2C_ADDR_HAUPEE		0xa0
-#define I2C_ADDR_STBEE		0xae
-#define I2C_ADDR_VHX		0xc0
-#define I2C_ADDR_MSP3400	0x80
-#define I2C_ADDR_MSP3400_ALT	0x88
-#define I2C_ADDR_TEA6300	0x80 /* also used by 6320 */
-#define I2C_ADDR_DPL3518	0x84
-#define I2C_ADDR_TDA9887	0x86
-
-/*
- * i2c bus addresses for the chips supported by tvaudio.c
- */
-
-#define I2C_ADDR_TDA8425	0x82
-#define I2C_ADDR_TDA9840	0x84 /* also used by TA8874Z */
-#define I2C_ADDR_TDA985x_L	0xb4 /* also used by 9873 */
-#define I2C_ADDR_TDA985x_H	0xb6
-#define I2C_ADDR_TDA9874	0xb0 /* also used by 9875 */
-
-#define I2C_ADDR_TEA6300	0x80 /* also used by 6320 */
-#define I2C_ADDR_TEA6420	0x98
-
-#define I2C_ADDR_PIC16C54	0x96 /* PV951 */
diff --git a/include/media/i2c/as3645a.h b/include/media/i2c/as3645a.h
deleted file mode 100644
index fffd4b5..0000000
--- a/include/media/i2c/as3645a.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * include/media/i2c/as3645a.h
- *
- * Copyright (C) 2008-2011 Nokia Corporation
- *
- * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.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 __AS3645A_H__
-#define __AS3645A_H__
-
-#include <media/v4l2-subdev.h>
-
-#define AS3645A_NAME				"as3645a"
-#define AS3645A_I2C_ADDR			(0x60 >> 1) /* W:0x60, R:0x61 */
-
-#define AS3645A_FLASH_TIMEOUT_MIN		100000	/* us */
-#define AS3645A_FLASH_TIMEOUT_MAX		850000
-#define AS3645A_FLASH_TIMEOUT_STEP		50000
-
-#define AS3645A_FLASH_INTENSITY_MIN		200	/* mA */
-#define AS3645A_FLASH_INTENSITY_MAX_1LED	500
-#define AS3645A_FLASH_INTENSITY_MAX_2LEDS	400
-#define AS3645A_FLASH_INTENSITY_STEP		20
-
-#define AS3645A_TORCH_INTENSITY_MIN		20	/* mA */
-#define AS3645A_TORCH_INTENSITY_MAX		160
-#define AS3645A_TORCH_INTENSITY_STEP		20
-
-#define AS3645A_INDICATOR_INTENSITY_MIN		0	/* uA */
-#define AS3645A_INDICATOR_INTENSITY_MAX		10000
-#define AS3645A_INDICATOR_INTENSITY_STEP	2500
-
-/*
- * as3645a_platform_data - Flash controller platform data
- * @set_power:	Set power callback
- * @vref:	VREF offset (0=0V, 1=+0.3V, 2=-0.3V, 3=+0.6V)
- * @peak:	Inductor peak current limit (0=1.25A, 1=1.5A, 2=1.75A, 3=2.0A)
- * @ext_strobe:	True if external flash strobe can be used
- * @flash_max_current:	Max flash current (mA, <= AS3645A_FLASH_INTENSITY_MAX)
- * @torch_max_current:	Max torch current (mA, >= AS3645A_TORCH_INTENSITY_MAX)
- * @timeout_max:	Max flash timeout (us, <= AS3645A_FLASH_TIMEOUT_MAX)
- */
-struct as3645a_platform_data {
-	int (*set_power)(struct v4l2_subdev *subdev, int on);
-	unsigned int vref;
-	unsigned int peak;
-	bool ext_strobe;
-
-	/* Flash and torch currents and timeout limits */
-	unsigned int flash_max_current;
-	unsigned int torch_max_current;
-	unsigned int timeout_max;
-};
-
-#endif /* __AS3645A_H__ */
diff --git a/include/media/i2c/bt819.h b/include/media/i2c/bt819.h
index 8025f4b..1bcf0db 100644
--- a/include/media/i2c/bt819.h
+++ b/include/media/i2c/bt819.h
@@ -30,7 +30,7 @@
 
    Note: these ioctls that internal to the kernel and are never called
    from userspace. */
-#define BT819_FIFO_RESET_LOW 	_IO('b', 0)
-#define BT819_FIFO_RESET_HIGH 	_IO('b', 1)
+#define BT819_FIFO_RESET_LOW	_IO('b', 0)
+#define BT819_FIFO_RESET_HIGH	_IO('b', 1)
 
 #endif
diff --git a/include/media/i2c/ir-kbd-i2c.h b/include/media/i2c/ir-kbd-i2c.h
index 76491c6..9f47d6a 100644
--- a/include/media/i2c/ir-kbd-i2c.h
+++ b/include/media/i2c/ir-kbd-i2c.h
@@ -19,11 +19,15 @@ struct IR_i2c {
 	u32                    polling_interval; /* in ms */
 
 	struct delayed_work    work;
-	char                   name[32];
 	char                   phys[32];
 	int                    (*get_key)(struct IR_i2c *ir,
 					  enum rc_proto *protocol,
 					  u32 *scancode, u8 *toggle);
+	/* tx */
+	struct i2c_client      *tx_c;
+	struct mutex	       lock;	/* do not poll Rx during Tx */
+	unsigned int	       carrier;
+	unsigned int	       duty_cycle;
 };
 
 enum ir_kbd_get_key_fn {
diff --git a/include/media/i2c/m52790.h b/include/media/i2c/m52790.h
index 7ddffae3..8d9db3c 100644
--- a/include/media/i2c/m52790.h
+++ b/include/media/i2c/m52790.h
@@ -23,57 +23,57 @@
 
 /* Input routing switch 1 */
 
-#define M52790_SW1_IN_MASK 	0x0003
-#define M52790_SW1_IN_TUNER 	0x0000
-#define M52790_SW1_IN_V2    	0x0001
-#define M52790_SW1_IN_V3    	0x0002
-#define M52790_SW1_IN_V4    	0x0003
+#define M52790_SW1_IN_MASK	0x0003
+#define M52790_SW1_IN_TUNER	0x0000
+#define M52790_SW1_IN_V2	0x0001
+#define M52790_SW1_IN_V3	0x0002
+#define M52790_SW1_IN_V4	0x0003
 
 /* Selects component input instead of composite */
-#define M52790_SW1_YCMIX    	0x0004
+#define M52790_SW1_YCMIX	0x0004
 
 
 /* Input routing switch 2 */
 
-#define M52790_SW2_IN_MASK 	0x0300
-#define M52790_SW2_IN_TUNER 	0x0000
-#define M52790_SW2_IN_V2    	0x0100
-#define M52790_SW2_IN_V3    	0x0200
-#define M52790_SW2_IN_V4    	0x0300
+#define M52790_SW2_IN_MASK	0x0300
+#define M52790_SW2_IN_TUNER	0x0000
+#define M52790_SW2_IN_V2	0x0100
+#define M52790_SW2_IN_V3	0x0200
+#define M52790_SW2_IN_V4	0x0300
 
 /* Selects component input instead of composite */
-#define M52790_SW2_YCMIX    	0x0400
+#define M52790_SW2_YCMIX	0x0400
 
 
 /* Output routing switch 1 */
 
 /* Enable 6dB amplifier for composite out */
-#define M52790_SW1_V_AMP    	0x0008
+#define M52790_SW1_V_AMP	0x0008
 
 /* Enable 6dB amplifier for component out */
-#define M52790_SW1_YC_AMP   	0x0010
+#define M52790_SW1_YC_AMP	0x0010
 
 /* Audio output mode */
-#define M52790_SW1_AUDIO_MASK 	0x00c0
-#define M52790_SW1_AUDIO_MUTE 	0x0000
-#define M52790_SW1_AUDIO_R 	0x0040
-#define M52790_SW1_AUDIO_L 	0x0080
+#define M52790_SW1_AUDIO_MASK	0x00c0
+#define M52790_SW1_AUDIO_MUTE	0x0000
+#define M52790_SW1_AUDIO_R	0x0040
+#define M52790_SW1_AUDIO_L	0x0080
 #define M52790_SW1_AUDIO_STEREO 0x00c0
 
 
 /* Output routing switch 2 */
 
 /* Enable 6dB amplifier for composite out */
-#define M52790_SW2_V_AMP    	0x0800
+#define M52790_SW2_V_AMP	0x0800
 
 /* Enable 6dB amplifier for component out */
-#define M52790_SW2_YC_AMP   	0x1000
+#define M52790_SW2_YC_AMP	0x1000
 
 /* Audio output mode */
-#define M52790_SW2_AUDIO_MASK 	0xc000
-#define M52790_SW2_AUDIO_MUTE 	0x0000
-#define M52790_SW2_AUDIO_R 	0x4000
-#define M52790_SW2_AUDIO_L 	0x8000
+#define M52790_SW2_AUDIO_MASK	0xc000
+#define M52790_SW2_AUDIO_MUTE	0x0000
+#define M52790_SW2_AUDIO_R	0x4000
+#define M52790_SW2_AUDIO_L	0x8000
 #define M52790_SW2_AUDIO_STEREO 0xc000
 
 
@@ -83,9 +83,9 @@
 #define M52790_IN_V3    (M52790_SW1_IN_V3 | M52790_SW2_IN_V3)
 #define M52790_IN_V4    (M52790_SW1_IN_V4 | M52790_SW2_IN_V4)
 
-#define M52790_OUT_STEREO 	(M52790_SW1_AUDIO_STEREO | \
+#define M52790_OUT_STEREO	(M52790_SW1_AUDIO_STEREO | \
 				 M52790_SW2_AUDIO_STEREO)
-#define M52790_OUT_AMP_STEREO 	(M52790_SW1_AUDIO_STEREO | \
+#define M52790_OUT_AMP_STEREO	(M52790_SW1_AUDIO_STEREO | \
 				 M52790_SW1_V_AMP | \
 				 M52790_SW2_AUDIO_STEREO | \
 				 M52790_SW2_V_AMP)
diff --git a/include/media/i2c/saa7115.h b/include/media/i2c/saa7115.h
index 53954c9..a0cda42 100644
--- a/include/media/i2c/saa7115.h
+++ b/include/media/i2c/saa7115.h
@@ -36,15 +36,15 @@
 #define SAA7115_SVIDEO3    9
 
 /* outputs */
-#define SAA7115_IPORT_ON    	1
-#define SAA7115_IPORT_OFF   	0
+#define SAA7115_IPORT_ON	1
+#define SAA7115_IPORT_OFF	0
 
 /* SAA7111 specific outputs. */
-#define SAA7111_VBI_BYPASS 	2
+#define SAA7111_VBI_BYPASS	2
 #define SAA7111_FMT_YUV422      0x00
-#define SAA7111_FMT_RGB 	0x40
-#define SAA7111_FMT_CCIR 	0x80
-#define SAA7111_FMT_YUV411 	0xc0
+#define SAA7111_FMT_RGB		0x40
+#define SAA7111_FMT_CCIR	0x80
+#define SAA7111_FMT_YUV411	0xc0
 
 /* config flags */
 /*
diff --git a/include/media/i2c/tvaudio.h b/include/media/i2c/tvaudio.h
index 1ac8184..f13e1a386 100644
--- a/include/media/i2c/tvaudio.h
+++ b/include/media/i2c/tvaudio.h
@@ -21,7 +21,22 @@
 #ifndef _TVAUDIO_H
 #define _TVAUDIO_H
 
-#include <media/i2c-addr.h>
+/*
+ * i2c bus addresses for the chips supported by tvaudio.c
+ */
+
+#define I2C_ADDR_TDA8425	0x82
+#define I2C_ADDR_TDA9840	0x84
+#define I2C_ADDR_TDA9874	0xb0 /* also used by 9875 */
+#define I2C_ADDR_TDA9875	0xb0
+#define I2C_ADDR_TDA8425	0x82
+#define I2C_ADDR_TDA9840	0x84 /* also used by TA8874Z */
+#define I2C_ADDR_TDA985x_L	0xb4 /* also used by 9873 */
+#define I2C_ADDR_TDA985x_H	0xb6
+#define I2C_ADDR_TDA9874	0xb0 /* also used by 9875 */
+#define I2C_ADDR_TEA6300	0x80 /* also used by 6320 */
+#define I2C_ADDR_TEA6420	0x98
+#define I2C_ADDR_PIC16C54	0x96 /* PV951 */
 
 /* The tvaudio module accepts the following inputs: */
 #define TVAUDIO_INPUT_TUNER  0
diff --git a/include/media/i2c/upd64031a.h b/include/media/i2c/upd64031a.h
index 48ec03c..1eba24d 100644
--- a/include/media/i2c/upd64031a.h
+++ b/include/media/i2c/upd64031a.h
@@ -18,9 +18,9 @@
 #define _UPD64031A_H_
 
 /* Ghost reduction modes */
-#define UPD64031A_GR_ON 	0
-#define UPD64031A_GR_OFF 	1
-#define UPD64031A_GR_THROUGH 	3
+#define UPD64031A_GR_ON		0
+#define UPD64031A_GR_OFF	1
+#define UPD64031A_GR_THROUGH	3
 
 /* Direct 3D/YCS Connection */
 #define UPD64031A_3DYCS_DISABLE   (0 << 2)
diff --git a/include/media/lirc.h b/include/media/lirc.h
deleted file mode 100644
index 554988c..0000000
--- a/include/media/lirc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <uapi/linux/lirc.h>
diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h
deleted file mode 100644
index d9c143d..0000000
--- a/include/media/lirc_dev.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * LIRC base driver
- *
- * by Artur Lipowski <alipowski@interia.pl>
- *        This code is licensed under GNU GPL
- *
- */
-
-#ifndef _LINUX_LIRC_DEV_H
-#define _LINUX_LIRC_DEV_H
-
-#define BUFLEN            16
-
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/ioctl.h>
-#include <linux/poll.h>
-#include <linux/kfifo.h>
-#include <media/lirc.h>
-#include <linux/device.h>
-#include <linux/cdev.h>
-
-struct lirc_buffer {
-	wait_queue_head_t wait_poll;
-	spinlock_t fifo_lock;
-	unsigned int chunk_size;
-	unsigned int size; /* in chunks */
-	/* Using chunks instead of bytes pretends to simplify boundary checking
-	 * And should allow for some performance fine tunning later */
-	struct kfifo fifo;
-};
-
-static inline void lirc_buffer_clear(struct lirc_buffer *buf)
-{
-	unsigned long flags;
-
-	if (kfifo_initialized(&buf->fifo)) {
-		spin_lock_irqsave(&buf->fifo_lock, flags);
-		kfifo_reset(&buf->fifo);
-		spin_unlock_irqrestore(&buf->fifo_lock, flags);
-	} else
-		WARN(1, "calling %s on an uninitialized lirc_buffer\n",
-		     __func__);
-}
-
-static inline int lirc_buffer_init(struct lirc_buffer *buf,
-				    unsigned int chunk_size,
-				    unsigned int size)
-{
-	int ret;
-
-	init_waitqueue_head(&buf->wait_poll);
-	spin_lock_init(&buf->fifo_lock);
-	buf->chunk_size = chunk_size;
-	buf->size = size;
-	ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL);
-
-	return ret;
-}
-
-static inline void lirc_buffer_free(struct lirc_buffer *buf)
-{
-	if (kfifo_initialized(&buf->fifo)) {
-		kfifo_free(&buf->fifo);
-	} else
-		WARN(1, "calling %s on an uninitialized lirc_buffer\n",
-		     __func__);
-}
-
-static inline int lirc_buffer_len(struct lirc_buffer *buf)
-{
-	int len;
-	unsigned long flags;
-
-	spin_lock_irqsave(&buf->fifo_lock, flags);
-	len = kfifo_len(&buf->fifo);
-	spin_unlock_irqrestore(&buf->fifo_lock, flags);
-
-	return len;
-}
-
-static inline int lirc_buffer_full(struct lirc_buffer *buf)
-{
-	return lirc_buffer_len(buf) == buf->size * buf->chunk_size;
-}
-
-static inline int lirc_buffer_empty(struct lirc_buffer *buf)
-{
-	return !lirc_buffer_len(buf);
-}
-
-static inline unsigned int lirc_buffer_read(struct lirc_buffer *buf,
-					    unsigned char *dest)
-{
-	unsigned int ret = 0;
-
-	if (lirc_buffer_len(buf) >= buf->chunk_size)
-		ret = kfifo_out_locked(&buf->fifo, dest, buf->chunk_size,
-				       &buf->fifo_lock);
-	return ret;
-
-}
-
-static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
-					     unsigned char *orig)
-{
-	unsigned int ret;
-
-	ret = kfifo_in_locked(&buf->fifo, orig, buf->chunk_size,
-			      &buf->fifo_lock);
-
-	return ret;
-}
-
-/**
- * struct lirc_dev - represents a LIRC device
- *
- * @name:		used for logging
- * @minor:		the minor device (/dev/lircX) number for the device
- * @code_length:	length of a remote control key code expressed in bits
- * @features:		lirc compatible hardware features, like LIRC_MODE_RAW,
- *			LIRC_CAN\_\*, as defined at include/media/lirc.h.
- * @buffer_size:	Number of FIFO buffers with @chunk_size size.
- *			Only used if @rbuf is NULL.
- * @chunk_size:		Size of each FIFO buffer.
- *			Only used if @rbuf is NULL.
- * @data:		private per-driver data
- * @buf:		if %NULL, lirc_dev will allocate and manage the buffer,
- *			otherwise allocated by the caller which will
- *			have to write to the buffer by other means, like irq's
- *			(see also lirc_serial.c).
- * @buf_internal:	whether lirc_dev has allocated the read buffer or not
- * @rdev:		&struct rc_dev associated with the device
- * @fops:		&struct file_operations for the device
- * @owner:		the module owning this struct
- * @attached:		if the device is still live
- * @open:		open count for the device's chardev
- * @mutex:		serialises file_operations calls
- * @dev:		&struct device assigned to the device
- * @cdev:		&struct cdev assigned to the device
- */
-struct lirc_dev {
-	char name[40];
-	unsigned int minor;
-	__u32 code_length;
-	__u32 features;
-
-	unsigned int buffer_size; /* in chunks holding one code each */
-	unsigned int chunk_size;
-	struct lirc_buffer *buf;
-	bool buf_internal;
-
-	void *data;
-	struct rc_dev *rdev;
-	const struct file_operations *fops;
-	struct module *owner;
-
-	bool attached;
-	int open;
-
-	struct mutex mutex; /* protect from simultaneous accesses */
-
-	struct device dev;
-	struct cdev cdev;
-};
-
-struct lirc_dev *lirc_allocate_device(void);
-
-void lirc_free_device(struct lirc_dev *d);
-
-int lirc_register_device(struct lirc_dev *d);
-
-void lirc_unregister_device(struct lirc_dev *d);
-
-/* Must be called in the open fop before lirc_get_pdata() can be used */
-void lirc_init_pdata(struct inode *inode, struct file *file);
-
-/* Returns the private data stored in the lirc_dev
- * associated with the given device file pointer.
- */
-void *lirc_get_pdata(struct file *file);
-
-/* default file operations
- * used by drivers if they override only some operations
- */
-int lirc_dev_fop_open(struct inode *inode, struct file *file);
-int lirc_dev_fop_close(struct inode *inode, struct file *file);
-__poll_t lirc_dev_fop_poll(struct file *file, poll_table *wait);
-long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-ssize_t lirc_dev_fop_read(struct file *file, char __user *buffer, size_t length,
-			  loff_t *ppos);
-#endif
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 222d379..a732af1 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -88,6 +88,8 @@ struct media_entity_enum {
  * @stack:		Graph traversal stack; the stack contains information
  *			on the path the media entities to be walked and the
  *			links through which they were reached.
+ * @stack.entity:	pointer to &struct media_entity at the graph.
+ * @stack.link:		pointer to &struct list_head.
  * @ent_enum:		Visited entities
  * @top:		The top of the stack
  */
@@ -247,6 +249,9 @@ enum media_entity_type {
  * @pipe:	Pipeline this entity belongs to.
  * @info:	Union with devnode information.  Kept just for backward
  *		compatibility.
+ * @info.dev:	Contains device major and minor info.
+ * @info.dev.major: device node major, if the device is a devnode.
+ * @info.dev.minor: device node minor, if the device is a devnode.
  * @major:	Devnode major number (zero if not applicable). Kept just
  *		for backward compatibility.
  * @minor:	Devnode minor number (zero if not applicable). Kept just
@@ -629,7 +634,11 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads,
  * This function must be called during the cleanup phase after unregistering
  * the entity (currently, it does nothing).
  */
-static inline void media_entity_cleanup(struct media_entity *entity) {};
+#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
+static inline void media_entity_cleanup(struct media_entity *entity) {}
+#else
+#define media_entity_cleanup(entity) do { } while (false)
+#endif
 
 /**
  * media_create_pad_link() - creates a link between two entities.
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 314a1ed..aed4272 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -17,6 +17,7 @@
 #define _RC_CORE
 
 #include <linux/spinlock.h>
+#include <linux/cdev.h>
 #include <linux/kfifo.h>
 #include <linux/time.h>
 #include <linux/timer.h>
@@ -30,9 +31,9 @@ do {								\
 } while (0)
 
 /**
- * enum rc_driver_type - type of the RC output
+ * enum rc_driver_type - type of the RC driver.
  *
- * @RC_DRIVER_SCANCODE:	 Driver or hardware generates a scancode
+ * @RC_DRIVER_SCANCODE:	 Driver or hardware generates a scancode.
  * @RC_DRIVER_IR_RAW:	 Driver or hardware generates pulse/space sequences.
  *			 It needs a Infra-Red pulse/space decoder
  * @RC_DRIVER_IR_RAW_TX: Device transmitter only,
@@ -68,6 +69,33 @@ enum rc_filter_type {
 };
 
 /**
+ * struct lirc_fh - represents an open lirc file
+ * @list: list of open file handles
+ * @rc: rcdev for this lirc chardev
+ * @carrier_low: when setting the carrier range, first the low end must be
+ *	set with an ioctl and then the high end with another ioctl
+ * @send_timeout_reports: report timeouts in lirc raw IR.
+ * @rawir: queue for incoming raw IR
+ * @scancodes: queue for incoming decoded scancodes
+ * @wait_poll: poll struct for lirc device
+ * @send_mode: lirc mode for sending, either LIRC_MODE_SCANCODE or
+ *	LIRC_MODE_PULSE
+ * @rec_mode: lirc mode for receiving, either LIRC_MODE_SCANCODE or
+ *	LIRC_MODE_MODE2
+ */
+struct lirc_fh {
+	struct list_head list;
+	struct rc_dev *rc;
+	int				carrier_low;
+	bool				send_timeout_reports;
+	DECLARE_KFIFO_PTR(rawir, unsigned int);
+	DECLARE_KFIFO_PTR(scancodes, struct lirc_scancode);
+	wait_queue_head_t		wait_poll;
+	u8				send_mode;
+	u8				rec_mode;
+};
+
+/**
  * struct rc_dev - represents a remote control device
  * @dev: driver model's view of this device
  * @managed_alloc: devm_rc_allocate_device was used to create rc_dev
@@ -106,6 +134,8 @@ enum rc_filter_type {
  * @keypressed: whether a key is currently pressed
  * @keyup_jiffies: time (in jiffies) when the current keypress should be released
  * @timer_keyup: timer for releasing a keypress
+ * @timer_repeat: timer for autorepeat events. This is needed for CEC, which
+ *	has non-standard repeats.
  * @last_keycode: keycode of last keypress
  * @last_protocol: protocol of last keypress
  * @last_scancode: scancode of last keypress
@@ -115,6 +145,15 @@ enum rc_filter_type {
  * @max_timeout: maximum timeout supported by device
  * @rx_resolution : resolution (in ns) of input sampler
  * @tx_resolution: resolution (in ns) of output sampler
+ * @lirc_dev: lirc device
+ * @lirc_cdev: lirc char cdev
+ * @gap_start: time when gap starts
+ * @gap_duration: duration of initial gap
+ * @gap: true if we're in a gap
+ * @lirc_fh_lock: protects lirc_fh list
+ * @lirc_fh: list of open files
+ * @registered: set to true by rc_register_device(), false by
+ *	rc_unregister_device
  * @change_protocol: allow changing the protocol used on hardware decoders
  * @open: callback to allow drivers to enable polling/irq when IR input device
  *	is opened.
@@ -165,6 +204,7 @@ struct rc_dev {
 	bool				keypressed;
 	unsigned long			keyup_jiffies;
 	struct timer_list		timer_keyup;
+	struct timer_list		timer_repeat;
 	u32				last_keycode;
 	enum rc_proto			last_protocol;
 	u32				last_scancode;
@@ -174,6 +214,16 @@ struct rc_dev {
 	u32				max_timeout;
 	u32				rx_resolution;
 	u32				tx_resolution;
+#ifdef CONFIG_LIRC
+	struct device			lirc_dev;
+	struct cdev			lirc_cdev;
+	ktime_t				gap_start;
+	u64				gap_duration;
+	bool				gap;
+	spinlock_t			lirc_fh_lock;
+	struct list_head		lirc_fh;
+#endif
+	bool				registered;
 	int				(*change_protocol)(struct rc_dev *dev, u64 *rc_proto);
 	int				(*open)(struct rc_dev *dev);
 	void				(*close)(struct rc_dev *dev);
@@ -248,20 +298,6 @@ int devm_rc_register_device(struct device *parent, struct rc_dev *dev);
  */
 void rc_unregister_device(struct rc_dev *dev);
 
-/**
- * rc_open - Opens a RC device
- *
- * @rdev: pointer to struct rc_dev.
- */
-int rc_open(struct rc_dev *rdev);
-
-/**
- * rc_close - Closes a RC device
- *
- * @rdev: pointer to struct rc_dev.
- */
-void rc_close(struct rc_dev *rdev);
-
 void rc_repeat(struct rc_dev *dev);
 void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
 		u8 toggle);
@@ -309,6 +345,7 @@ int ir_raw_event_store_with_filter(struct rc_dev *dev,
 void ir_raw_event_set_idle(struct rc_dev *dev, bool idle);
 int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode,
 			   struct ir_raw_event *events, unsigned int max);
+int ir_raw_encode_carrier(enum rc_proto protocol);
 
 static inline void ir_raw_event_reset(struct rc_dev *dev)
 {
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 72197cb..7046734 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -10,59 +10,7 @@
  */
 
 #include <linux/input.h>
-
-/**
- * enum rc_proto - the Remote Controller protocol
- *
- * @RC_PROTO_UNKNOWN: Protocol not known
- * @RC_PROTO_OTHER: Protocol known but proprietary
- * @RC_PROTO_RC5: Philips RC5 protocol
- * @RC_PROTO_RC5X_20: Philips RC5x 20 bit protocol
- * @RC_PROTO_RC5_SZ: StreamZap variant of RC5
- * @RC_PROTO_JVC: JVC protocol
- * @RC_PROTO_SONY12: Sony 12 bit protocol
- * @RC_PROTO_SONY15: Sony 15 bit protocol
- * @RC_PROTO_SONY20: Sony 20 bit protocol
- * @RC_PROTO_NEC: NEC protocol
- * @RC_PROTO_NECX: Extended NEC protocol
- * @RC_PROTO_NEC32: NEC 32 bit protocol
- * @RC_PROTO_SANYO: Sanyo protocol
- * @RC_PROTO_MCIR2_KBD: RC6-ish MCE keyboard
- * @RC_PROTO_MCIR2_MSE: RC6-ish MCE mouse
- * @RC_PROTO_RC6_0: Philips RC6-0-16 protocol
- * @RC_PROTO_RC6_6A_20: Philips RC6-6A-20 protocol
- * @RC_PROTO_RC6_6A_24: Philips RC6-6A-24 protocol
- * @RC_PROTO_RC6_6A_32: Philips RC6-6A-32 protocol
- * @RC_PROTO_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol
- * @RC_PROTO_SHARP: Sharp protocol
- * @RC_PROTO_XMP: XMP protocol
- * @RC_PROTO_CEC: CEC protocol
- */
-enum rc_proto {
-	RC_PROTO_UNKNOWN	= 0,
-	RC_PROTO_OTHER		= 1,
-	RC_PROTO_RC5		= 2,
-	RC_PROTO_RC5X_20	= 3,
-	RC_PROTO_RC5_SZ		= 4,
-	RC_PROTO_JVC		= 5,
-	RC_PROTO_SONY12		= 6,
-	RC_PROTO_SONY15		= 7,
-	RC_PROTO_SONY20		= 8,
-	RC_PROTO_NEC		= 9,
-	RC_PROTO_NECX		= 10,
-	RC_PROTO_NEC32		= 11,
-	RC_PROTO_SANYO		= 12,
-	RC_PROTO_MCIR2_KBD	= 13,
-	RC_PROTO_MCIR2_MSE	= 14,
-	RC_PROTO_RC6_0		= 15,
-	RC_PROTO_RC6_6A_20	= 16,
-	RC_PROTO_RC6_6A_24	= 17,
-	RC_PROTO_RC6_6A_32	= 18,
-	RC_PROTO_RC6_MCE	= 19,
-	RC_PROTO_SHARP		= 20,
-	RC_PROTO_XMP		= 21,
-	RC_PROTO_CEC		= 22,
-};
+#include <uapi/linux/lirc.h>
 
 #define RC_PROTO_BIT_NONE		0ULL
 #define RC_PROTO_BIT_UNKNOWN		BIT_ULL(RC_PROTO_UNKNOWN)
diff --git a/include/media/v4l2-tpg.h b/include/media/tpg/v4l2-tpg.h
similarity index 93%
rename from include/media/v4l2-tpg.h
rename to include/media/tpg/v4l2-tpg.h
index 13e49d8..823faded 100644
--- a/include/media/v4l2-tpg.h
+++ b/include/media/tpg/v4l2-tpg.h
@@ -26,8 +26,51 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-tpg-colors.h>
 
+struct tpg_rbg_color8 {
+	unsigned char r, g, b;
+};
+
+struct tpg_rbg_color16 {
+	__u16 r, g, b;
+};
+
+enum tpg_color {
+	TPG_COLOR_CSC_WHITE,
+	TPG_COLOR_CSC_YELLOW,
+	TPG_COLOR_CSC_CYAN,
+	TPG_COLOR_CSC_GREEN,
+	TPG_COLOR_CSC_MAGENTA,
+	TPG_COLOR_CSC_RED,
+	TPG_COLOR_CSC_BLUE,
+	TPG_COLOR_CSC_BLACK,
+	TPG_COLOR_75_YELLOW,
+	TPG_COLOR_75_CYAN,
+	TPG_COLOR_75_GREEN,
+	TPG_COLOR_75_MAGENTA,
+	TPG_COLOR_75_RED,
+	TPG_COLOR_75_BLUE,
+	TPG_COLOR_100_WHITE,
+	TPG_COLOR_100_YELLOW,
+	TPG_COLOR_100_CYAN,
+	TPG_COLOR_100_GREEN,
+	TPG_COLOR_100_MAGENTA,
+	TPG_COLOR_100_RED,
+	TPG_COLOR_100_BLUE,
+	TPG_COLOR_100_BLACK,
+	TPG_COLOR_TEXTFG,
+	TPG_COLOR_TEXTBG,
+	TPG_COLOR_RANDOM,
+	TPG_COLOR_RAMP,
+	TPG_COLOR_MAX = TPG_COLOR_RAMP + 256
+};
+
+extern const struct tpg_rbg_color8 tpg_colors[TPG_COLOR_MAX];
+extern const unsigned short tpg_rec709_to_linear[255 * 16 + 1];
+extern const unsigned short tpg_linear_to_rec709[255 * 16 + 1];
+extern const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1]
+					  [V4L2_XFER_FUNC_SMPTE2084 + 1]
+					  [TPG_COLOR_CSC_BLACK + 1];
 enum tpg_pattern {
 	TPG_PAT_75_COLORBAR,
 	TPG_PAT_100_COLORBAR,
diff --git a/include/media/tuner-types.h b/include/media/tuner-types.h
index 78f0654..df76ac8 100644
--- a/include/media/tuner-types.h
+++ b/include/media/tuner-types.h
@@ -171,6 +171,21 @@ struct tuner_params {
 	struct tuner_range *ranges;
 };
 
+/**
+ * struct tunertype - describes the known tuners.
+ *
+ * @name:	string with the tuner's name.
+ * @count:	size of &struct tuner_params array.
+ * @params:	pointer to &struct tuner_params array.
+ *
+ * @min:	minimal tuner frequency, in 62.5 kHz step.
+ *		should be multiplied to 16 to convert to MHz.
+ * @max:	minimal tuner frequency, in 62.5 kHz step.
+ *		Should be multiplied to 16 to convert to MHz.
+ * @stepsize:	frequency step, in Hz.
+ * @initdata:	optional byte sequence to initialize the tuner.
+ * @sleepdata:	optional byte sequence to power down the tuner.
+ */
 struct tunertype {
 	char *name;
 	unsigned int count;
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 6152434..1592d32 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -28,7 +28,7 @@ struct v4l2_async_notifier;
  *	in order to identify a match
  *
  * @V4L2_ASYNC_MATCH_CUSTOM: Match will use the logic provided by &struct
- * 	v4l2_async_subdev.match ops
+ *	v4l2_async_subdev.match ops
  * @V4L2_ASYNC_MATCH_DEVNAME: Match will use the device name
  * @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address
  * @V4L2_ASYNC_MATCH_FWNODE: Match will use firmware node
@@ -48,6 +48,31 @@ enum v4l2_async_match_type {
  *
  * @match_type:	type of match that will be used
  * @match:	union of per-bus type matching data sets
+ * @match.fwnode:
+ *		pointer to &struct fwnode_handle to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_FWNODE.
+ * @match.device_name:
+ *		string containing the device name to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_DEVNAME.
+ * @match.i2c:	embedded struct with I2C parameters to be matched.
+ *		Both @match.i2c.adapter_id and @match.i2c.address
+ *		should be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.i2c.adapter_id:
+ *		I2C adapter ID to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.i2c.address:
+ *		I2C address to be matched.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.custom:
+ *		Driver-specific match criteria.
+ *		Used if @match_type is %V4L2_ASYNC_MATCH_CUSTOM.
+ * @match.custom.match:
+ *		Driver-specific match function to be used if
+ *		%V4L2_ASYNC_MATCH_CUSTOM.
+ * @match.custom.priv:
+ *		Driver-specific private struct with match parameters
+ *		to be used if %V4L2_ASYNC_MATCH_CUSTOM.
  * @list:	used to link struct v4l2_async_subdev objects, waiting to be
  *		probed, to a notifier->waiting list
  *
@@ -58,12 +83,8 @@ enum v4l2_async_match_type {
 struct v4l2_async_subdev {
 	enum v4l2_async_match_type match_type;
 	union {
-		struct {
-			struct fwnode_handle *fwnode;
-		} fwnode;
-		struct {
-			const char *name;
-		} device_name;
+		struct fwnode_handle *fwnode;
+		const char *device_name;
 		struct {
 			int adapter_id;
 			unsigned short address;
@@ -167,7 +188,7 @@ void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier);
 
 /**
  * v4l2_async_register_subdev - registers a sub-device to the asynchronous
- * 	subdevice framework
+ *	subdevice framework
  *
  * @sd: pointer to &struct v4l2_subdev
  */
@@ -197,7 +218,7 @@ int __must_check v4l2_async_register_subdev_sensor_common(
 
 /**
  * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous
- * 	subdevice framework
+ *	subdevice framework
  *
  * @sd: pointer to &struct v4l2_subdev
  */
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index aac8b7b..e0d95a7 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -28,7 +28,7 @@
 
 #include <media/v4l2-dev.h>
 
-/* Common printk constucts for v4l-i2c drivers. These macros create a unique
+/* Common printk constructs for v4l-i2c drivers. These macros create a unique
    prefix consisting of the driver name, the adapter number and the i2c
    address. */
 #define v4l_printk(level, name, adapter, addr, fmt, arg...) \
@@ -50,7 +50,7 @@
 /* These three macros assume that the debug level is set with a module
    parameter called 'debug'. */
 #define v4l_dbg(level, debug, client, fmt, arg...)			     \
-	do { 								     \
+	do {								     \
 		if (debug >= (level))					     \
 			v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
 	} while (0)
@@ -80,9 +80,9 @@
 /* These three macros assume that the debug level is set with a module
    parameter called 'debug'. */
 #define v4l2_dbg(level, debug, dev, fmt, arg...)			\
-	do { 								\
+	do {								\
 		if (debug >= (level))					\
-			v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); 	\
+			v4l2_printk(KERN_DEBUG, dev, fmt , ## arg);	\
 	} while (0)
 
 /**
@@ -127,7 +127,7 @@ struct v4l2_subdev_ops;
  * @client_type:  name of the chip that's on the adapter.
  * @addr: I2C address. If zero, it will use @probe_addrs
  * @probe_addrs: array with a list of address. The last entry at such
- * 	array should be %I2C_CLIENT_END.
+ *	array should be %I2C_CLIENT_END.
  *
  * returns a &struct v4l2_subdev pointer.
  */
@@ -146,7 +146,7 @@ struct i2c_board_info;
  * @info: pointer to struct i2c_board_info used to replace the irq,
  *	 platform_data and addr arguments.
  * @probe_addrs: array with a list of address. The last entry at such
- * 	array should be %I2C_CLIENT_END.
+ *	array should be %I2C_CLIENT_END.
  *
  * returns a &struct v4l2_subdev pointer.
  */
@@ -174,17 +174,43 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
  */
 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,	/* Radio tuner addresses */
-	ADDRS_DEMOD,	/* Demod tuner addresses */
-	ADDRS_TV,	/* TV tuner addresses */
-	/* TV tuner addresses if demod is present, this excludes
-	   addresses used by the demodulator from the list of
-	   candidates. */
+	ADDRS_RADIO,
+	ADDRS_DEMOD,
+	ADDRS_TV,
 	ADDRS_TV_WITH_DEMOD,
 };
-/* Return a list of I2C tuner addresses to probe. Use only if the tuner
-   addresses are unknown. */
+/**
+ * v4l2_i2c_tuner_addrs - Return a list of I2C tuner addresses to probe.
+ *
+ * @type: type of the tuner to seek, as defined by
+ *	  &enum v4l2_i2c_tuner_type.
+ *
+ * NOTE: Use only if the tuner addresses are unknown.
+ */
 const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);
 
 /* ------------------------------------------------------------------------- */
@@ -224,10 +250,14 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
 
 /* ------------------------------------------------------------------------- */
 
-/* Note: these remaining ioctls/structs should be removed as well, but they are
-   still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET) and
-   v4l2-int-device.h (v4l2_routing). To remove these ioctls some more cleanup
-   is needed in those modules. */
+/*
+ * FIXME: these remaining ioctls/structs should be removed as well, but they
+ * are still used in tuner-simple.c (TUNER_SET_CONFIG) and cx18/ivtv (RESET).
+ * To remove these ioctls some more cleanup is needed in those modules.
+ *
+ * It doesn't make much sense on documenting them, as what we really want is
+ * to get rid of them.
+ */
 
 /* s_config */
 struct v4l2_priv_tun_config {
@@ -236,32 +266,79 @@ struct v4l2_priv_tun_config {
 };
 #define TUNER_SET_CONFIG           _IOW('d', 92, struct v4l2_priv_tun_config)
 
-#define VIDIOC_INT_RESET            	_IOW ('d', 102, u32)
-
-struct v4l2_routing {
-	u32 input;
-	u32 output;
-};
+#define VIDIOC_INT_RESET		_IOW ('d', 102, u32)
 
 /* ------------------------------------------------------------------------- */
 
 /* Miscellaneous helper functions */
 
-void v4l_bound_align_image(unsigned int *w, unsigned int wmin,
+/**
+ * v4l_bound_align_image - adjust video dimensions according to
+ *	a given constraints.
+ *
+ * @width:	pointer to width that will be adjusted if needed.
+ * @wmin:	minimum width.
+ * @wmax:	maximum width.
+ * @walign:	least significant bit on width.
+ * @height:	pointer to height that will be adjusted if needed.
+ * @hmin:	minimum height.
+ * @hmax:	maximum height.
+ * @halign:	least significant bit on width.
+ * @salign:	least significant bit for the image size (e. g.
+ *		:math:`width * height`).
+ *
+ * Clip an image to have @width between @wmin and @wmax, and @height between
+ * @hmin and @hmax, inclusive.
+ *
+ * Additionally, the @width will be a multiple of :math:`2^{walign}`,
+ * the @height will be a multiple of :math:`2^{halign}`, and the overall
+ * size :math:`width * height` will be a multiple of :math:`2^{salign}`.
+ *
+ * .. note::
+ *
+ *    #. The clipping rectangle may be shrunk or enlarged to fit the alignment
+ *       constraints.
+ *    #. @wmax must not be smaller than @wmin.
+ *    #. @hmax must not be smaller than @hmin.
+ *    #. The alignments must not be so high there are no possible image
+ *       sizes within the allowed bounds.
+ *    #. @wmin and @hmin must be at least 1 (don't use 0).
+ *    #. For @walign, @halign and @salign, if you don't care about a certain
+ *       alignment, specify ``0``, as :math:`2^0 = 1` and one byte alignment
+ *       is equivalent to no alignment.
+ *    #. If you only want to adjust downward, specify a maximum that's the
+ *       same as the initial value.
+ */
+void v4l_bound_align_image(unsigned int *width, unsigned int wmin,
 			   unsigned int wmax, unsigned int walign,
-			   unsigned int *h, unsigned int hmin,
+			   unsigned int *height, unsigned int hmin,
 			   unsigned int hmax, unsigned int halign,
 			   unsigned int salign);
 
-struct v4l2_discrete_probe {
-	const struct v4l2_frmsize_discrete	*sizes;
-	int					num_sizes;
-};
+/**
+ * v4l2_find_nearest_format - find the nearest format size among a discrete
+ *	set of resolutions.
+ *
+ * @sizes: array of &struct v4l2_frmsize_discrete image sizes.
+ * @num_sizes: length of @sizes array.
+ * @width: desired width.
+ * @height: desired height.
+ *
+ * Finds the closest resolution to minimize the width and height differences
+ * between what requested and the supported resolutions.
+ */
+const struct v4l2_frmsize_discrete *
+v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,
+			  const size_t num_sizes,
+			  s32 width, s32 height);
 
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
-		const struct v4l2_discrete_probe *probe,
-		s32 width, s32 height);
-
+/**
+ * v4l2_get_timestamp - helper routine to get a timestamp to be used when
+ *	filling streaming metadata. Internally, it uses ktime_get_ts(),
+ *	which is the recommended way to get it.
+ *
+ * @tv: pointer to &struct timeval to be filled.
+ */
 void v4l2_get_timestamp(struct timeval *tv);
 
 #endif /* V4L2_COMMON_H_ */
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index a9ced6b..05ebb9e 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -166,8 +166,15 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
  *		empty strings ("") correspond to non-existing menu items (this
  *		is in addition to the menu_skip_mask above). The last entry
  *		must be NULL.
+ *		Used only if the @type is %V4L2_CTRL_TYPE_MENU.
+ * @qmenu_int:	A 64-bit integer array for with integer menu items.
+ *		The size of array must be equal to the menu size, e. g.:
+ *		:math:`ceil(\frac{maximum - minimum}{step}) + 1`.
+ *		Used only if the @type is %V4L2_CTRL_TYPE_INTEGER_MENU.
  * @flags:	The control's flags.
- * @cur:	The control's current value.
+ * @cur:	Structure to store the current value.
+ * @cur.val:	The control's current value, if the @type is represented via
+ *		a u32 integer (see &enum v4l2_ctrl_type).
  * @val:	The control's new s32 value.
  * @priv:	The control's private pointer. For use by the driver. It is
  *		untouched by the control framework. Note that this pointer is
@@ -1139,7 +1146,7 @@ int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
 
 /**
  * v4l2_ctrl_subdev_subscribe_event - Helper function to implement
- * 	as a &struct v4l2_subdev_core_ops subscribe_event function
+ *	as a &struct v4l2_subdev_core_ops subscribe_event function
  *	that just subscribes control events.
  *
  * @sd: pointer to &struct v4l2_subdev
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index fa99f6f..53f3202 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -21,31 +21,63 @@
 
 #define VIDEO_MAJOR	81
 
-#define VFL_TYPE_GRABBER	0
-#define VFL_TYPE_VBI		1
-#define VFL_TYPE_RADIO		2
-#define VFL_TYPE_SUBDEV		3
-#define VFL_TYPE_SDR		4
-#define VFL_TYPE_TOUCH		5
-#define VFL_TYPE_MAX		6
+/**
+ * enum vfl_devnode_type - type of V4L2 device node
+ *
+ * @VFL_TYPE_GRABBER:	for video input/output devices
+ * @VFL_TYPE_VBI:	for vertical blank data (i.e. closed captions, teletext)
+ * @VFL_TYPE_RADIO:	for radio tuners
+ * @VFL_TYPE_SUBDEV:	for V4L2 subdevices
+ * @VFL_TYPE_SDR:	for Software Defined Radio tuners
+ * @VFL_TYPE_TOUCH:	for touch sensors
+ */
+enum vfl_devnode_type {
+	VFL_TYPE_GRABBER	= 0,
+	VFL_TYPE_VBI		= 1,
+	VFL_TYPE_RADIO		= 2,
+	VFL_TYPE_SUBDEV		= 3,
+	VFL_TYPE_SDR		= 4,
+	VFL_TYPE_TOUCH		= 5,
+};
+#define VFL_TYPE_MAX VFL_TYPE_TOUCH
 
-/* Is this a receiver, transmitter or mem-to-mem? */
-/* Ignored for VFL_TYPE_SUBDEV. */
-#define VFL_DIR_RX		0
-#define VFL_DIR_TX		1
-#define VFL_DIR_M2M		2
+/**
+ * enum  vfl_direction - Identifies if a &struct video_device corresponds
+ *	to a receiver, a transmitter or a mem-to-mem device.
+ *
+ * @VFL_DIR_RX:		device is a receiver.
+ * @VFL_DIR_TX:		device is a transmitter.
+ * @VFL_DIR_M2M:	device is a memory to memory device.
+ *
+ * Note: Ignored if &enum vfl_devnode_type is %VFL_TYPE_SUBDEV.
+ */
+enum vfl_devnode_direction {
+	VFL_DIR_RX,
+	VFL_DIR_TX,
+	VFL_DIR_M2M,
+};
 
 struct v4l2_ioctl_callbacks;
 struct video_device;
 struct v4l2_device;
 struct v4l2_ctrl_handler;
 
-/* Flag to mark the video_device struct as registered.
-   Drivers can clear this flag if they want to block all future
-   device access. It is cleared by video_unregister_device. */
-#define V4L2_FL_REGISTERED	(0)
-/* file->private_data points to struct v4l2_fh */
-#define V4L2_FL_USES_V4L2_FH	(1)
+/**
+ * enum v4l2_video_device_flags - Flags used by &struct video_device
+ *
+ * @V4L2_FL_REGISTERED:
+ *	indicates that a &struct video_device is registered.
+ *	Drivers can clear this flag if they want to block all future
+ *	device access. It is cleared by video_unregister_device.
+ * @V4L2_FL_USES_V4L2_FH:
+ *	indicates that file->private_data points to &struct v4l2_fh.
+ *	This flag is set by the core when v4l2_fh_init() is called.
+ *	All new drivers should use it.
+ */
+enum v4l2_video_device_flags {
+	V4L2_FL_REGISTERED	= 0,
+	V4L2_FL_USES_V4L2_FH	= 1,
+};
 
 /* Priority helper functions */
 
@@ -166,7 +198,7 @@ struct v4l2_file_operations {
 
 /*
  * Newer version of video_device, handled by videodev2.c
- * 	This version moves redundant code from video device code to
+ *	This version moves redundant code from video device code to
  *	the common handler
  */
 
@@ -189,11 +221,12 @@ struct v4l2_file_operations {
  * @prio: pointer to &struct v4l2_prio_state with device's Priority state.
  *	 If NULL, then v4l2_dev->prio will be used.
  * @name: video device name
- * @vfl_type: V4L device type
+ * @vfl_type: V4L device type, as defined by &enum vfl_devnode_type
  * @vfl_dir: V4L receiver, transmitter or m2m
  * @minor: device node 'minor'. It is set to -1 if the registration failed
  * @num: number of the video device node
- * @flags: video device flags. Use bitops to set/clear/test flags
+ * @flags: video device flags. Use bitops to set/clear/test flags.
+ *	   Contains a set of &enum v4l2_video_device_flags.
  * @index: attribute to differentiate multiple indices on one physical device
  * @fh_lock: Lock for all v4l2_fhs
  * @fh_list: List of &struct v4l2_fh
@@ -237,8 +270,8 @@ struct video_device
 
 	/* device info */
 	char name[32];
-	int vfl_type;
-	int vfl_dir;
+	enum vfl_devnode_type vfl_type;
+	enum vfl_devnode_direction vfl_dir;
 	int minor;
 	u16 num;
 	unsigned long flags;
@@ -261,18 +294,30 @@ struct video_device
 	struct mutex *lock;
 };
 
-#define media_entity_to_video_device(__e) \
-	container_of(__e, struct video_device, entity)
-/* dev to video-device */
+/**
+ * media_entity_to_video_device - Returns a &struct video_device from
+ *	the &struct media_entity embedded on it.
+ *
+ * @entity: pointer to &struct media_entity
+ */
+#define media_entity_to_video_device(entity) \
+	container_of(entity, struct video_device, entity)
+
+/**
+ * to_video_device - Returns a &struct video_device from the
+ *	&struct device embedded on it.
+ *
+ * @cd: pointer to &struct device
+ */
 #define to_video_device(cd) container_of(cd, struct video_device, dev)
 
 /**
  * __video_register_device - register video4linux devices
  *
  * @vdev: struct video_device to register
- * @type: type of device to register
+ * @type: type of device to register, as defined by &enum vfl_devnode_type
  * @nr:   which device node number is desired:
- * 	(0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ *	(0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
  * @warn_if_nr_in_use: warn if the desired device node number
  *        was already in use and another number was chosen instead.
  * @owner: module that owns the video device node
@@ -289,43 +334,37 @@ struct video_device
  *
  * Returns 0 on success.
  *
- * Valid values for @type are:
- *
- *	- %VFL_TYPE_GRABBER - A frame grabber
- *	- %VFL_TYPE_VBI - Vertical blank data (undecoded)
- *	- %VFL_TYPE_RADIO - A radio card
- *	- %VFL_TYPE_SUBDEV - A subdevice
- *	- %VFL_TYPE_SDR - Software Defined Radio
- *	- %VFL_TYPE_TOUCH - A touch sensor
- *
  * .. note::
  *
  *	This function is meant to be used only inside the V4L2 core.
  *	Drivers should use video_register_device() or
  *	video_register_device_no_warn().
  */
-int __must_check __video_register_device(struct video_device *vdev, int type,
-		int nr, int warn_if_nr_in_use, struct module *owner);
+int __must_check __video_register_device(struct video_device *vdev,
+					 enum vfl_devnode_type type,
+					 int nr, int warn_if_nr_in_use,
+					 struct module *owner);
 
 /**
  *  video_register_device - register video4linux devices
  *
  * @vdev: struct video_device to register
- * @type: type of device to register
+ * @type: type of device to register, as defined by &enum vfl_devnode_type
  * @nr:   which device node number is desired:
- * 	(0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ *	(0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
  *
  * Internally, it calls __video_register_device(). Please see its
  * documentation for more details.
  *
  * .. note::
- * 	if video_register_device fails, the release() callback of
+ *	if video_register_device fails, the release() callback of
  *	&struct video_device structure is *not* called, so the caller
  *	is responsible for freeing any data. Usually that means that
  *	you video_device_release() should be called on failure.
  */
 static inline int __must_check video_register_device(struct video_device *vdev,
-		int type, int nr)
+						     enum vfl_devnode_type type,
+						     int nr)
 {
 	return __video_register_device(vdev, type, nr, 1, vdev->fops->owner);
 }
@@ -334,9 +373,9 @@ static inline int __must_check video_register_device(struct video_device *vdev,
  *  video_register_device_no_warn - register video4linux devices
  *
  * @vdev: struct video_device to register
- * @type: type of device to register
+ * @type: type of device to register, as defined by &enum vfl_devnode_type
  * @nr:   which device node number is desired:
- * 	(0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ *	(0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
  *
  * This function is identical to video_register_device() except that no
  * warning is issued if the desired device node number was already in use.
@@ -345,13 +384,14 @@ static inline int __must_check video_register_device(struct video_device *vdev,
  * documentation for more details.
  *
  * .. note::
- * 	if video_register_device fails, the release() callback of
+ *	if video_register_device fails, the release() callback of
  *	&struct video_device structure is *not* called, so the caller
  *	is responsible for freeing any data. Usually that means that
  *	you video_device_release() should be called on failure.
  */
-static inline int __must_check video_register_device_no_warn(
-		struct video_device *vdev, int type, int nr)
+static inline int __must_check
+video_register_device_no_warn(struct video_device *vdev,
+			      enum vfl_devnode_type type, int nr)
 {
 	return __video_register_device(vdev, type, nr, 0, vdev->fops->owner);
 }
@@ -383,7 +423,7 @@ void video_device_release(struct video_device *vdev);
 
 /**
  * video_device_release_empty - helper function to implement the
- * 	video_device->release\(\) callback.
+ *	video_device->release\(\) callback.
  *
  * @vdev: pointer to &struct video_device
  *
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 8ffa940..0c9e4da 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -38,7 +38,7 @@ struct v4l2_ctrl_handler;
  * @lock: lock this struct; can be used by the driver as well
  *	if this struct is embedded into a larger struct.
  * @name: unique device name, by default the driver name + bus ID
- * @notify: notify callback called by some sub-devices.
+ * @notify: notify operation called by some sub-devices.
  * @ctrl_handler: The control handler. May be %NULL.
  * @prio: Device's priority state
  * @ref: Keep track of the references to this struct.
@@ -56,7 +56,6 @@ struct v4l2_ctrl_handler;
  *    #) @dev->driver_data points to this struct.
  *    #) @dev might be %NULL if there is no parent device
  */
-
 struct v4l2_device {
 	struct device *dev;
 #if defined(CONFIG_MEDIA_CONTROLLER)
@@ -166,7 +165,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
  * v4l2_device_register_subdev - Registers a subdev with a v4l2 device.
  *
  * @v4l2_dev: pointer to struct &v4l2_device
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  *
  * While registered, the subdev module is marked as in-use.
  *
@@ -179,7 +178,7 @@ int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
 /**
  * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device.
  *
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  *
  * .. note ::
  *
@@ -201,7 +200,7 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
 /**
  * v4l2_subdev_notify - Sends a notification to v4l2_device.
  *
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
  * @notification: type of notification. Please notice that the notification
  *	type is driver-specific.
  * @arg: arguments for the notification. Those are specific to each
@@ -214,13 +213,43 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 		sd->v4l2_dev->notify(sd, notification, arg);
 }
 
-/* Iterate over all subdevs. */
+/* Helper macros to iterate over all subdevs. */
+
+/**
+ * v4l2_device_for_each_subdev - Helper macro that interates over all
+ *	sub-devices of a given &v4l2_device.
+ *
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev pointer used as an iterator by the loop.
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ *
+ * This macro iterates over all sub-devices owned by the @v4l2_dev device.
+ * It acts as a for loop iterator and executes the next statement with
+ * the @sd variable pointing to each sub-device in turn.
+ */
 #define v4l2_device_for_each_subdev(sd, v4l2_dev)			\
 	list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
 
-/* Call the specified callback for all subdevs matching the condition.
-   Ignore any errors. Note that you cannot add or delete a subdev
-   while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_p - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev pointer used as an iterator by the loop.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...)	\
 	do {								\
 		list_for_each_entry((sd), &(v4l2_dev)->subdevs, list)	\
@@ -228,6 +257,24 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 				(sd)->ops->o->f((sd) , ##args);		\
 	} while (0)
 
+/**
+ * __v4l2_device_call_subdevs - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...)	\
 	do {								\
 		struct v4l2_subdev *__sd;				\
@@ -236,10 +283,30 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 						f , ##args);		\
 	} while (0)
 
-/* Call the specified callback for all subdevs matching the condition.
-   If the callback returns an error other than 0 or -ENOIOCTLCMD, then
-   return with that error code. Note that you cannot add or delete a
-   subdev while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_until_err_p - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @sd: pointer that will be filled by the macro with all
+ *	&struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code, zero
+ * otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \
 ({									\
 	long __err = 0;							\
@@ -253,6 +320,28 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 	(__err == -ENOIOCTLCMD) ? 0 : __err;				\
 })
 
+/**
+ * __v4l2_device_call_subdevs_until_err - Calls the specified operation for
+ *	all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \
 ({									\
 	struct v4l2_subdev *__sd;					\
@@ -260,9 +349,26 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 						f , ##args);		\
 })
 
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
-   match them all). Ignore any errors. Note that you cannot add or delete
-   a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_all - Calls the specified operation for
+ *	all subdevs matching the &v4l2_subdev.grp_id, as assigned
+ *	by the bridge driver.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ *	    Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...)		\
 	do {								\
 		struct v4l2_subdev *__sd;				\
@@ -272,10 +378,30 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 	} while (0)
 
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
-   match them all). If the callback returns an error other than 0 or
-   -ENOIOCTLCMD, then return with that error code. Note that you cannot
-   add or delete a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_until_err - Calls the specified operation for
+ *	all subdevs matching the &v4l2_subdev.grp_id, as assigned
+ *	by the bridge driver, until an error occurs.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ *	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
 #define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...)	\
 ({									\
 	struct v4l2_subdev *__sd;					\
@@ -284,10 +410,24 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 })
 
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == `0, then match them all). Ignore any errors. Note that you
- * cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_all - Calls the specified operation for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
  */
 #define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...)	\
 	do {								\
@@ -298,11 +438,28 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 	} while (0)
 
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == 0, then match them all). If the callback returns an error
- * other than 0 or %-ENOIOCTLCMD, then return with that error code. Note that
- * you cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_until_err - Calls the specified operation for
+ *	all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
  */
 #define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \
 ({									\
@@ -312,9 +469,19 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 			##args);					\
 })
 
-/*
- * Does any subdev with matching grpid (or all if grpid == 0) has the given
- * op?
+
+/**
+ * v4l2_device_has_op - checks if any subdev with matching grpid has a
+ *	given ops.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ *	   Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
  */
 #define v4l2_device_has_op(v4l2_dev, grpid, o, f)			\
 ({									\
@@ -331,9 +498,18 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
 	__result;							\
 })
 
-/*
- * Does any subdev with matching grpmsk (or all if grpmsk == 0) has the given
- * op?
+/**
+ * v4l2_device_mask_has_op - checks if any subdev with matching group
+ *	mask has a given ops.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ *	    group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ *     Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ *	The operation functions are defined in groups, according to
+ *	each element at &struct v4l2_subdev_ops.
  */
 #define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f)			\
 ({									\
diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h
index 61a1889..ebf00e0 100644
--- a/include/media/v4l2-dv-timings.h
+++ b/include/media/v4l2-dv-timings.h
@@ -203,13 +203,15 @@ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait);
  */
 struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t);
 
-/*
- * reduce_fps - check if conditions for reduced fps are true.
- * bt - v4l2 timing structure
- * For different timings reduced fps is allowed if following conditions
- * are met -
- * For CVT timings: if reduced blanking v2 (vsync == 8) is true.
- * For CEA861 timings: if V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
+/**
+ * can_reduce_fps - check if conditions for reduced fps are true.
+ * @bt: v4l2 timing structure
+ *
+ * For different timings reduced fps is allowed if the following conditions
+ * are met:
+ *
+ *   - For CVT timings: if reduced blanking v2 (vsync == 8) is true.
+ *   - For CEA861 timings: if %V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
  */
 static inline  bool can_reduce_fps(struct v4l2_bt_timings *bt)
 {
diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h
index 6741910..17833e8 100644
--- a/include/media/v4l2-event.h
+++ b/include/media/v4l2-event.h
@@ -24,40 +24,6 @@
 #include <linux/videodev2.h>
 #include <linux/wait.h>
 
-/*
- * Overview:
- *
- * Events are subscribed per-filehandle. An event specification consists of a
- * type and is optionally associated with an object identified through the
- * 'id' field. So an event is uniquely identified by the (type, id) tuple.
- *
- * The v4l2-fh struct has a list of subscribed events. The v4l2_subscribed_event
- * struct is added to that list, one for every subscribed event.
- *
- * Each v4l2_subscribed_event struct ends with an array of v4l2_kevent structs.
- * This array (ringbuffer, really) is used to store any events raised by the
- * driver. The v4l2_kevent struct links into the 'available' list of the
- * v4l2_fh struct so VIDIOC_DQEVENT will know which event to dequeue first.
- *
- * Finally, if the event subscription is associated with a particular object
- * such as a V4L2 control, then that object needs to know about that as well
- * so that an event can be raised by that object. So the 'node' field can
- * be used to link the v4l2_subscribed_event struct into a list of that
- * object.
- *
- * So to summarize:
- *
- * struct v4l2_fh has two lists: one of the subscribed events, and one of the
- * pending events.
- *
- * struct v4l2_subscribed_event has a ringbuffer of raised (pending) events of
- * that particular type.
- *
- * If struct v4l2_subscribed_event is associated with a specific object, then
- * that object will have an internal list of struct v4l2_subscribed_event so
- * it knows who subscribed an event to that object.
- */
-
 struct v4l2_fh;
 struct v4l2_subdev;
 struct v4l2_subscribed_event;
@@ -218,7 +184,7 @@ int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd,
 				  struct v4l2_event_subscription *sub);
 /**
  * v4l2_src_change_event_subscribe - helper function that calls
- * 	v4l2_event_subscribe() if the event is %V4L2_EVENT_SOURCE_CHANGE.
+ *	v4l2_event_subscribe() if the event is %V4L2_EVENT_SOURCE_CHANGE.
  *
  * @fh: pointer to struct v4l2_fh
  * @sub: pointer to &struct v4l2_event_subscription
diff --git a/include/media/v4l2-flash-led-class.h b/include/media/v4l2-flash-led-class.h
index 5c1d50f..0a5e451 100644
--- a/include/media/v4l2-flash-led-class.h
+++ b/include/media/v4l2-flash-led-class.h
@@ -91,12 +91,24 @@ struct v4l2_flash {
 	struct v4l2_ctrl **ctrls;
 };
 
+/**
+ * v4l2_subdev_to_v4l2_flash - Returns a &struct v4l2_flash from the
+ * &struct v4l2_subdev embedded on it.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
 static inline struct v4l2_flash *v4l2_subdev_to_v4l2_flash(
 							struct v4l2_subdev *sd)
 {
 	return container_of(sd, struct v4l2_flash, sd);
 }
 
+/**
+ * v4l2_ctrl_to_v4l2_flash - Returns a &struct v4l2_flash from the
+ * &struct v4l2_ctrl embedded on it.
+ *
+ * @c: pointer to &struct v4l2_ctrl
+ */
 static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c)
 {
 	return container_of(c->handler, struct v4l2_flash, hdl);
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index b5b4656..c228ec1 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -81,7 +81,17 @@ struct v4l2_fwnode_bus_mipi_csi1 {
  * struct v4l2_fwnode_endpoint - the endpoint data structure
  * @base: fwnode endpoint of the v4l2_fwnode
  * @bus_type: bus type
- * @bus: bus configuration data structure
+ * @bus: union with bus configuration data structure
+ * @bus.parallel: embedded &struct v4l2_fwnode_bus_parallel.
+ *		  Used if the bus is parallel.
+ * @bus.mipi_csi1: embedded &struct v4l2_fwnode_bus_mipi_csi1.
+ *		   Used if the bus is MIPI Alliance's Camera Serial
+ *		   Interface version 1 (MIPI CSI1) or Standard
+ *		   Mobile Imaging Architecture's Compact Camera Port 2
+ *		   (SMIA CCP2).
+ * @bus.mipi_csi2: embedded &struct v4l2_fwnode_bus_mipi_csi2.
+ *		   Used if the bus is MIPI Alliance's Camera Serial
+ *		   Interface version 2 (MIPI CSI2).
  * @link_frequencies: array of supported link frequencies
  * @nr_of_link_frequencies: number of elements in link_frequenccies array
  */
diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h
index 93f8afc..4d8626c 100644
--- a/include/media/v4l2-mediabus.h
+++ b/include/media/v4l2-mediabus.h
@@ -12,6 +12,8 @@
 #define V4L2_MEDIABUS_H
 
 #include <linux/v4l2-mediabus.h>
+#include <linux/bitops.h>
+
 
 /* Parallel flags */
 /*
@@ -20,44 +22,44 @@
  * horizontal and vertical synchronisation. In "Slave mode" the host is
  * providing these signals to the slave.
  */
-#define V4L2_MBUS_MASTER			(1 << 0)
-#define V4L2_MBUS_SLAVE				(1 << 1)
+#define V4L2_MBUS_MASTER			BIT(0)
+#define V4L2_MBUS_SLAVE				BIT(1)
 /*
  * Signal polarity flags
  * Note: in BT.656 mode HSYNC, FIELD, and VSYNC are unused
  * V4L2_MBUS_[HV]SYNC* flags should be also used for specifying
  * configuration of hardware that uses [HV]REF signals
  */
-#define V4L2_MBUS_HSYNC_ACTIVE_HIGH		(1 << 2)
-#define V4L2_MBUS_HSYNC_ACTIVE_LOW		(1 << 3)
-#define V4L2_MBUS_VSYNC_ACTIVE_HIGH		(1 << 4)
-#define V4L2_MBUS_VSYNC_ACTIVE_LOW		(1 << 5)
-#define V4L2_MBUS_PCLK_SAMPLE_RISING		(1 << 6)
-#define V4L2_MBUS_PCLK_SAMPLE_FALLING		(1 << 7)
-#define V4L2_MBUS_DATA_ACTIVE_HIGH		(1 << 8)
-#define V4L2_MBUS_DATA_ACTIVE_LOW		(1 << 9)
+#define V4L2_MBUS_HSYNC_ACTIVE_HIGH		BIT(2)
+#define V4L2_MBUS_HSYNC_ACTIVE_LOW		BIT(3)
+#define V4L2_MBUS_VSYNC_ACTIVE_HIGH		BIT(4)
+#define V4L2_MBUS_VSYNC_ACTIVE_LOW		BIT(5)
+#define V4L2_MBUS_PCLK_SAMPLE_RISING		BIT(6)
+#define V4L2_MBUS_PCLK_SAMPLE_FALLING		BIT(7)
+#define V4L2_MBUS_DATA_ACTIVE_HIGH		BIT(8)
+#define V4L2_MBUS_DATA_ACTIVE_LOW		BIT(9)
 /* FIELD = 0/1 - Field1 (odd)/Field2 (even) */
-#define V4L2_MBUS_FIELD_EVEN_HIGH		(1 << 10)
+#define V4L2_MBUS_FIELD_EVEN_HIGH		BIT(10)
 /* FIELD = 1/0 - Field1 (odd)/Field2 (even) */
-#define V4L2_MBUS_FIELD_EVEN_LOW		(1 << 11)
+#define V4L2_MBUS_FIELD_EVEN_LOW		BIT(11)
 /* Active state of Sync-on-green (SoG) signal, 0/1 for LOW/HIGH respectively. */
-#define V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH	(1 << 12)
-#define V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW		(1 << 13)
+#define V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH		BIT(12)
+#define V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW		BIT(13)
 
 /* Serial flags */
 /* How many lanes the client can use */
-#define V4L2_MBUS_CSI2_1_LANE			(1 << 0)
-#define V4L2_MBUS_CSI2_2_LANE			(1 << 1)
-#define V4L2_MBUS_CSI2_3_LANE			(1 << 2)
-#define V4L2_MBUS_CSI2_4_LANE			(1 << 3)
+#define V4L2_MBUS_CSI2_1_LANE			BIT(0)
+#define V4L2_MBUS_CSI2_2_LANE			BIT(1)
+#define V4L2_MBUS_CSI2_3_LANE			BIT(2)
+#define V4L2_MBUS_CSI2_4_LANE			BIT(3)
 /* On which channels it can send video data */
-#define V4L2_MBUS_CSI2_CHANNEL_0		(1 << 4)
-#define V4L2_MBUS_CSI2_CHANNEL_1		(1 << 5)
-#define V4L2_MBUS_CSI2_CHANNEL_2		(1 << 6)
-#define V4L2_MBUS_CSI2_CHANNEL_3		(1 << 7)
+#define V4L2_MBUS_CSI2_CHANNEL_0		BIT(4)
+#define V4L2_MBUS_CSI2_CHANNEL_1		BIT(5)
+#define V4L2_MBUS_CSI2_CHANNEL_2		BIT(6)
+#define V4L2_MBUS_CSI2_CHANNEL_3		BIT(7)
 /* Does it support only continuous or also non-continuous clock mode */
-#define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK		(1 << 8)
-#define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK	(1 << 9)
+#define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK		BIT(8)
+#define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK	BIT(9)
 
 #define V4L2_MBUS_CSI2_LANES		(V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_2_LANE | \
 					 V4L2_MBUS_CSI2_3_LANE | V4L2_MBUS_CSI2_4_LANE)
@@ -91,6 +93,13 @@ struct v4l2_mbus_config {
 	unsigned int flags;
 };
 
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ *	v4l2_pix_format fields from a &struct v4l2_mbus_framefmt.
+ *
+ * @pix_fmt:	pointer to &struct v4l2_pix_format to be filled
+ * @mbus_fmt:	pointer to &struct v4l2_mbus_framefmt to be used as model
+ */
 static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
 				const struct v4l2_mbus_framefmt *mbus_fmt)
 {
@@ -103,6 +112,15 @@ static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
 	pix_fmt->xfer_func = mbus_fmt->xfer_func;
 }
 
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ *	v4l2_mbus_framefmt from a &struct v4l2_pix_format and a
+ *	data format code.
+ *
+ * @mbus_fmt:	pointer to &struct v4l2_mbus_framefmt to be filled
+ * @pix_fmt:	pointer to &struct v4l2_pix_format to be used as model
+ * @code:	data format code (from &enum v4l2_mbus_pixelcode)
+ */
 static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt,
 			   const struct v4l2_pix_format *pix_fmt,
 			   u32 code)
@@ -117,6 +135,13 @@ static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt,
 	mbus_fmt->code = code;
 }
 
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ *	v4l2_pix_format_mplane fields from a media bus structure.
+ *
+ * @pix_mp_fmt:	pointer to &struct v4l2_pix_format_mplane to be filled
+ * @mbus_fmt:	pointer to &struct v4l2_mbus_framefmt to be used as model
+ */
 static inline void v4l2_fill_pix_format_mplane(
 				struct v4l2_pix_format_mplane *pix_mp_fmt,
 				const struct v4l2_mbus_framefmt *mbus_fmt)
@@ -130,6 +155,13 @@ static inline void v4l2_fill_pix_format_mplane(
 	pix_mp_fmt->xfer_func = mbus_fmt->xfer_func;
 }
 
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ *	v4l2_mbus_framefmt from a &struct v4l2_pix_format_mplane.
+ *
+ * @mbus_fmt:	pointer to &struct v4l2_mbus_framefmt to be filled
+ * @pix_mp_fmt:	pointer to &struct v4l2_pix_format_mplane to be used as model
+ */
 static inline void v4l2_fill_mbus_format_mplane(
 				struct v4l2_mbus_framefmt *mbus_fmt,
 				const struct v4l2_pix_format_mplane *pix_mp_fmt)
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index ec399c7..980a86c 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -108,22 +108,31 @@ struct v4l2_decode_vbi_line {
  * not yet implemented) since ops provide proper type-checking.
  */
 
-/* Subdevice external IO pin configuration */
-#define V4L2_SUBDEV_IO_PIN_DISABLE	(1 << 0) /* ENABLE assumed */
-#define V4L2_SUBDEV_IO_PIN_OUTPUT	(1 << 1)
-#define V4L2_SUBDEV_IO_PIN_INPUT	(1 << 2)
-#define V4L2_SUBDEV_IO_PIN_SET_VALUE	(1 << 3) /* Set output value */
-#define V4L2_SUBDEV_IO_PIN_ACTIVE_LOW	(1 << 4) /* ACTIVE HIGH assumed */
+/**
+ * enum v4l2_subdev_io_pin_bits - Subdevice external IO pin configuration
+ *	bits
+ *
+ * @V4L2_SUBDEV_IO_PIN_DISABLE: disables a pin config. ENABLE assumed.
+ * @V4L2_SUBDEV_IO_PIN_OUTPUT: set it if pin is an output.
+ * @V4L2_SUBDEV_IO_PIN_INPUT: set it if pin is an input.
+ * @V4L2_SUBDEV_IO_PIN_SET_VALUE: to set the output value via
+ *				  &struct v4l2_subdev_io_pin_config->value.
+ * @V4L2_SUBDEV_IO_PIN_ACTIVE_LOW: pin active is bit 0.
+ *				   Otherwise, ACTIVE HIGH is assumed.
+ */
+enum v4l2_subdev_io_pin_bits {
+	V4L2_SUBDEV_IO_PIN_DISABLE	= 0,
+	V4L2_SUBDEV_IO_PIN_OUTPUT	= 1,
+	V4L2_SUBDEV_IO_PIN_INPUT	= 2,
+	V4L2_SUBDEV_IO_PIN_SET_VALUE	= 3,
+	V4L2_SUBDEV_IO_PIN_ACTIVE_LOW	= 4,
+};
 
 /**
  * struct v4l2_subdev_io_pin_config - Subdevice external IO pin configuration
  *
- * @flags: bitmask with flags for this pin's config:
- *	   %V4L2_SUBDEV_IO_PIN_DISABLE - disables a pin config,
- *	   %V4L2_SUBDEV_IO_PIN_OUTPUT - if pin is an output,
- *	   %V4L2_SUBDEV_IO_PIN_INPUT - if pin is an input,
- *	   %V4L2_SUBDEV_IO_PIN_SET_VALUE - to set the output value via @value
- *	   and %V4L2_SUBDEV_IO_PIN_ACTIVE_LOW - if active is 0.
+ * @flags: bitmask with flags for this pin's config, whose bits are defined by
+ *	   &enum v4l2_subdev_io_pin_bits.
  * @pin: Chip external IO pin to configure
  * @function: Internal signal pad/function to route to IO pin
  * @value: Initial value for pin - e.g. GPIO output value
@@ -140,7 +149,7 @@ struct v4l2_subdev_io_pin_config {
 /**
  * struct v4l2_subdev_core_ops - Define core ops callbacks for subdevs
  *
- * @log_status: callback for %VIDIOC_LOG_STATUS ioctl handler code.
+ * @log_status: callback for VIDIOC_LOG_STATUS() ioctl handler code.
  *
  * @s_io_pin_config: configure one or more chip I/O pins for chips that
  *	multiplex different internal signal pads out to IO pins.  This function
@@ -168,9 +177,9 @@ struct v4l2_subdev_io_pin_config {
  * @compat_ioctl32: called when a 32 bits application uses a 64 bits Kernel,
  *		    in order to fix data passed from/to userspace.
  *
- * @g_register: callback for %VIDIOC_G_REGISTER ioctl handler code.
+ * @g_register: callback for VIDIOC_DBG_G_REGISTER() ioctl handler code.
  *
- * @s_register: callback for %VIDIOC_G_REGISTER ioctl handler code.
+ * @s_register: callback for VIDIOC_DBG_S_REGISTER() ioctl handler code.
  *
  * @s_power: puts subdevice in power saving mode (on == 0) or normal operation
  *	mode (on == 1).
@@ -215,29 +224,48 @@ struct v4l2_subdev_core_ops {
  * struct v4l2_subdev_tuner_ops - Callbacks used when v4l device was opened
  *	in radio mode.
  *
- * @s_radio: callback for %VIDIOC_S_RADIO ioctl handler code.
+ * @s_radio: callback that switches the tuner to radio mode.
+ *	     drivers should explicitly call it when a tuner ops should
+ *	     operate on radio mode, before being able to handle it.
+ *	     Used on devices that have both AM/FM radio receiver and TV.
  *
- * @s_frequency: callback for %VIDIOC_S_FREQUENCY ioctl handler code.
+ * @s_frequency: callback for VIDIOC_S_FREQUENCY() ioctl handler code.
  *
- * @g_frequency: callback for %VIDIOC_G_FREQUENCY ioctl handler code.
+ * @g_frequency: callback for VIDIOC_G_FREQUENCY() ioctl handler code.
  *		 freq->type must be filled in. Normally done by video_ioctl2()
  *		 or the bridge driver.
  *
- * @enum_freq_bands: callback for %VIDIOC_ENUM_FREQ_BANDS ioctl handler code.
+ * @enum_freq_bands: callback for VIDIOC_ENUM_FREQ_BANDS() ioctl handler code.
  *
- * @g_tuner: callback for %VIDIOC_G_TUNER ioctl handler code.
+ * @g_tuner: callback for VIDIOC_G_TUNER() ioctl handler code.
  *
- * @s_tuner: callback for %VIDIOC_S_TUNER ioctl handler code. @vt->type must be
+ * @s_tuner: callback for VIDIOC_S_TUNER() ioctl handler code. @vt->type must be
  *	     filled in. Normally done by video_ioctl2 or the
  *	     bridge driver.
  *
- * @g_modulator: callback for %VIDIOC_G_MODULATOR ioctl handler code.
+ * @g_modulator: callback for VIDIOC_G_MODULATOR() ioctl handler code.
  *
- * @s_modulator: callback for %VIDIOC_S_MODULATOR ioctl handler code.
+ * @s_modulator: callback for VIDIOC_S_MODULATOR() ioctl handler code.
  *
  * @s_type_addr: sets tuner type and its I2C addr.
  *
  * @s_config: sets tda9887 specific stuff, like port1, port2 and qss
+ *
+ * .. note::
+ *
+ *	On devices that have both AM/FM and TV, it is up to the driver
+ *	to explicitly call s_radio when the tuner should be switched to
+ *	radio mode, before handling other &struct v4l2_subdev_tuner_ops
+ *	that would require it. An example of such usage is::
+ *
+ *	  static void s_frequency(void *priv, const struct v4l2_frequency *f)
+ *	  {
+ *		...
+ *		if (f.type == V4L2_TUNER_RADIO)
+ *			v4l2_device_call_all(v4l2_dev, 0, tuner, s_radio);
+ *		...
+ *		v4l2_device_call_all(v4l2_dev, 0, tuner, s_frequency);
+ *	  }
  */
 struct v4l2_subdev_tuner_ops {
 	int (*s_radio)(struct v4l2_subdev *sd);
@@ -285,25 +313,32 @@ struct v4l2_subdev_audio_ops {
 	int (*s_stream)(struct v4l2_subdev *sd, int enable);
 };
 
-/* Indicates the @length field specifies maximum data length. */
-#define V4L2_MBUS_FRAME_DESC_FL_LEN_MAX		(1U << 0)
-/*
- * Indicates that the format does not have line offsets, i.e. the
- * receiver should use 1D DMA.
+/**
+ * enum v4l2_mbus_frame_desc_entry - media bus frame description flags
+ *
+ * @V4L2_MBUS_FRAME_DESC_FL_LEN_MAX:
+ *	Indicates that &struct v4l2_mbus_frame_desc_entry->length field
+ *	specifies maximum data length.
+ * @V4L2_MBUS_FRAME_DESC_FL_BLOB:
+ *	Indicates that the format does not have line offsets, i.e.
+ *	the receiver should use 1D DMA.
  */
-#define V4L2_MBUS_FRAME_DESC_FL_BLOB		(1U << 1)
+enum v4l2_mbus_frame_desc_flags {
+	V4L2_MBUS_FRAME_DESC_FL_LEN_MAX	= BIT(0),
+	V4L2_MBUS_FRAME_DESC_FL_BLOB	= BIT(1),
+};
 
 /**
  * struct v4l2_mbus_frame_desc_entry - media bus frame description structure
  *
- * @flags: bitmask flags: %V4L2_MBUS_FRAME_DESC_FL_LEN_MAX and
- *			  %V4L2_MBUS_FRAME_DESC_FL_BLOB.
- * @pixelcode: media bus pixel code, valid if FRAME_DESC_FL_BLOB is not set
- * @length: number of octets per frame, valid if V4L2_MBUS_FRAME_DESC_FL_BLOB
- *	    is set
+ * @flags:	bitmask flags, as defined by &enum v4l2_mbus_frame_desc_flags.
+ * @pixelcode:	media bus pixel code, valid if @flags
+ *		%FRAME_DESC_FL_BLOB is not set.
+ * @length:	number of octets per frame, valid if @flags
+ *		%V4L2_MBUS_FRAME_DESC_FL_LEN_MAX is set.
  */
 struct v4l2_mbus_frame_desc_entry {
-	u16 flags;
+	enum v4l2_mbus_frame_desc_flags flags;
 	u32 pixelcode;
 	u32 length;
 };
@@ -332,9 +367,9 @@ struct v4l2_mbus_frame_desc {
  *	regarding clock frequency dividers, etc. If not used, then set flags
  *	to 0. If the frequency is not supported, then -EINVAL is returned.
  *
- * @g_std: callback for %VIDIOC_G_STD ioctl handler code.
+ * @g_std: callback for VIDIOC_G_STD() ioctl handler code.
  *
- * @s_std: callback for %VIDIOC_S_STD ioctl handler code.
+ * @s_std: callback for VIDIOC_S_STD() ioctl handler code.
  *
  * @s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by
  *	video input devices.
@@ -342,7 +377,7 @@ struct v4l2_mbus_frame_desc {
  * @g_std_output: get current standard for video OUTPUT devices. This is ignored
  *	by video input devices.
  *
- * @querystd: callback for %VIDIOC_QUERYSTD ioctl handler code.
+ * @querystd: callback for VIDIOC_QUERYSTD() ioctl handler code.
  *
  * @g_tvnorms: get &v4l2_std_id with all standards supported by the video
  *	CAPTURE device. This is ignored by video output devices.
@@ -358,13 +393,15 @@ struct v4l2_mbus_frame_desc {
  *
  * @g_pixelaspect: callback to return the pixelaspect ratio.
  *
- * @g_parm: callback for %VIDIOC_G_PARM ioctl handler code.
+ * @g_parm: callback for VIDIOC_G_PARM() ioctl handler code.
  *
- * @s_parm: callback for %VIDIOC_S_PARM ioctl handler code.
+ * @s_parm: callback for VIDIOC_S_PARM() ioctl handler code.
  *
- * @g_frame_interval: callback for %VIDIOC_G_FRAMEINTERVAL ioctl handler code.
+ * @g_frame_interval: callback for VIDIOC_SUBDEV_G_FRAME_INTERVAL()
+ *		      ioctl handler code.
  *
- * @s_frame_interval: callback for %VIDIOC_S_FRAMEINTERVAL ioctl handler code.
+ * @s_frame_interval: callback for VIDIOC_SUBDEV_S_FRAME_INTERVAL()
+ *		      ioctl handler code.
  *
  * @s_dv_timings: Set custom dv timings in the sub device. This is used
  *	when sub device is capable of setting detailed timing information
@@ -372,7 +409,7 @@ struct v4l2_mbus_frame_desc {
  *
  * @g_dv_timings: Get custom dv timings in the sub device.
  *
- * @query_dv_timings: callback for %VIDIOC_QUERY_DV_TIMINGS ioctl handler code.
+ * @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code.
  *
  * @g_mbus_config: get supported mediabus configurations
  *
@@ -443,7 +480,8 @@ struct v4l2_subdev_video_ops {
  *	member (to determine whether CC data from the first or second field
  *	should be obtained).
  *
- * @g_sliced_vbi_cap: callback for %VIDIOC_SLICED_VBI_CAP ioctl handler code.
+ * @g_sliced_vbi_cap: callback for VIDIOC_G_SLICED_VBI_CAP() ioctl handler
+ *		      code.
  *
  * @s_raw_fmt: setup the video encoder/decoder for raw VBI.
  *
@@ -610,30 +648,30 @@ struct v4l2_subdev_pad_config {
  * struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations
  *
  * @init_cfg: initialize the pad config to default values
- * @enum_mbus_code: callback for %VIDIOC_SUBDEV_ENUM_MBUS_CODE ioctl handler
+ * @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE() ioctl handler
  *		    code.
- * @enum_frame_size: callback for %VIDIOC_SUBDEV_ENUM_FRAME_SIZE ioctl handler
+ * @enum_frame_size: callback for VIDIOC_SUBDEV_ENUM_FRAME_SIZE() ioctl handler
  *		     code.
  *
- * @enum_frame_interval: callback for %VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL ioctl
+ * @enum_frame_interval: callback for VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL() ioctl
  *			 handler code.
  *
- * @get_fmt: callback for %VIDIOC_SUBDEV_G_FMT ioctl handler code.
+ * @get_fmt: callback for VIDIOC_SUBDEV_G_FMT() ioctl handler code.
  *
- * @set_fmt: callback for %VIDIOC_SUBDEV_S_FMT ioctl handler code.
+ * @set_fmt: callback for VIDIOC_SUBDEV_S_FMT() ioctl handler code.
  *
- * @get_selection: callback for %VIDIOC_SUBDEV_G_SELECTION ioctl handler code.
+ * @get_selection: callback for VIDIOC_SUBDEV_G_SELECTION() ioctl handler code.
  *
- * @set_selection: callback for %VIDIOC_SUBDEV_S_SELECTION ioctl handler code.
+ * @set_selection: callback for VIDIOC_SUBDEV_S_SELECTION() ioctl handler code.
  *
- * @get_edid: callback for %VIDIOC_SUBDEV_G_EDID ioctl handler code.
+ * @get_edid: callback for VIDIOC_SUBDEV_G_EDID() ioctl handler code.
  *
- * @set_edid: callback for %VIDIOC_SUBDEV_S_EDID ioctl handler code.
+ * @set_edid: callback for VIDIOC_SUBDEV_S_EDID() ioctl handler code.
  *
- * @dv_timings_cap: callback for %VIDIOC_SUBDEV_DV_TIMINGS_CAP ioctl handler
+ * @dv_timings_cap: callback for VIDIOC_SUBDEV_DV_TIMINGS_CAP() ioctl handler
  *		    code.
  *
- * @enum_dv_timings: callback for %VIDIOC_SUBDEV_ENUM_DV_TIMINGS ioctl handler
+ * @enum_dv_timings: callback for VIDIOC_SUBDEV_ENUM_DV_TIMINGS() ioctl handler
  *		     code.
  *
  * @link_validate: used by the media controller code to check if the links
@@ -766,7 +804,7 @@ struct v4l2_subdev_platform_data {
  * @list: List of sub-devices
  * @owner: The owner is the same as the driver's &struct device owner.
  * @owner_v4l2_dev: true if the &sd->owner matches the owner of @v4l2_dev->dev
- *	ownner. Initialized by v4l2_device_register_subdev().
+ *	owner. Initialized by v4l2_device_register_subdev().
  * @flags: subdev flags. Can be:
  *   %V4L2_SUBDEV_FL_IS_I2C - Set this flag if this subdev is a i2c device;
  *   %V4L2_SUBDEV_FL_IS_SPI - Set this flag if this subdev is a spi device;
diff --git a/include/media/v4l2-tpg-colors.h b/include/media/v4l2-tpg-colors.h
deleted file mode 100644
index 2a88d1f..0000000
--- a/include/media/v4l2-tpg-colors.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * v4l2-tpg-colors.h - Color definitions for the test pattern generator
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _V4L2_TPG_COLORS_H_
-#define _V4L2_TPG_COLORS_H_
-
-struct color {
-	unsigned char r, g, b;
-};
-
-struct color16 {
-	int r, g, b;
-};
-
-enum tpg_color {
-	TPG_COLOR_CSC_WHITE,
-	TPG_COLOR_CSC_YELLOW,
-	TPG_COLOR_CSC_CYAN,
-	TPG_COLOR_CSC_GREEN,
-	TPG_COLOR_CSC_MAGENTA,
-	TPG_COLOR_CSC_RED,
-	TPG_COLOR_CSC_BLUE,
-	TPG_COLOR_CSC_BLACK,
-	TPG_COLOR_75_YELLOW,
-	TPG_COLOR_75_CYAN,
-	TPG_COLOR_75_GREEN,
-	TPG_COLOR_75_MAGENTA,
-	TPG_COLOR_75_RED,
-	TPG_COLOR_75_BLUE,
-	TPG_COLOR_100_WHITE,
-	TPG_COLOR_100_YELLOW,
-	TPG_COLOR_100_CYAN,
-	TPG_COLOR_100_GREEN,
-	TPG_COLOR_100_MAGENTA,
-	TPG_COLOR_100_RED,
-	TPG_COLOR_100_BLUE,
-	TPG_COLOR_100_BLACK,
-	TPG_COLOR_TEXTFG,
-	TPG_COLOR_TEXTBG,
-	TPG_COLOR_RANDOM,
-	TPG_COLOR_RAMP,
-	TPG_COLOR_MAX = TPG_COLOR_RAMP + 256
-};
-
-extern const struct color tpg_colors[TPG_COLOR_MAX];
-extern const unsigned short tpg_rec709_to_linear[255 * 16 + 1];
-extern const unsigned short tpg_linear_to_rec709[255 * 16 + 1];
-extern const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1]
-					  [V4L2_XFER_FUNC_SMPTE2084 + 1]
-					  [TPG_COLOR_CSC_BLACK + 1];
-
-#endif
diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h
index a14ac77..c9c8199 100644
--- a/include/media/videobuf-dvb.h
+++ b/include/media/videobuf-dvb.h
@@ -1,9 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#include <dvbdev.h>
-#include <dmxdev.h>
-#include <dvb_demux.h>
-#include <dvb_net.h>
-#include <dvb_frontend.h>
+#include <media/dvbdev.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dvb_frontend.h>
 
 #ifndef _VIDEOBUF_DVB_H_
 #define	_VIDEOBUF_DVB_H_
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index e55efc6..aa16c06 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -16,6 +16,7 @@
 #include <linux/mutex.h>
 #include <linux/poll.h>
 #include <linux/dma-buf.h>
+#include <linux/bitops.h>
 
 #define VB2_MAX_FRAME	(32)
 #define VB2_MAX_PLANES	(8)
@@ -45,7 +46,7 @@ struct vb2_fileio_data;
 struct vb2_threadio_data;
 
 /**
- * struct vb2_mem_ops - memory handling/memory allocator operations
+ * struct vb2_mem_ops - memory handling/memory allocator operations.
  * @alloc:	allocate video memory and, optionally, allocator private data,
  *		return ERR_PTR() on failure or a pointer to allocator private,
  *		per-buffer data on success; the returned private structure
@@ -69,7 +70,7 @@ struct vb2_threadio_data;
  *		 argument to other ops in this structure.
  * @put_userptr: inform the allocator that a USERPTR buffer will no longer
  *		 be used.
- * @attach_dmabuf: attach a shared struct dma_buf for a hardware operation;
+ * @attach_dmabuf: attach a shared &struct dma_buf for a hardware operation;
  *		   used for DMABUF memory types; dev is the alloc device
  *		   dbuf is the shared dma_buf; returns ERR_PTR() on failure;
  *		   allocator private per-buffer structure on success;
@@ -145,28 +146,28 @@ struct vb2_mem_ops {
 };
 
 /**
- * struct vb2_plane - plane information
- * @mem_priv:	private data with this plane
- * @dbuf:	dma_buf - shared buffer object
+ * struct vb2_plane - plane information.
+ * @mem_priv:	private data with this plane.
+ * @dbuf:	dma_buf - shared buffer object.
  * @dbuf_mapped:	flag to show whether dbuf is mapped or not
- * @bytesused:	number of bytes occupied by data in the plane (payload)
- * @length:	size of this plane (NOT the payload) in bytes
+ * @bytesused:	number of bytes occupied by data in the plane (payload).
+ * @length:	size of this plane (NOT the payload) in bytes.
  * @min_length:	minimum required size of this plane (NOT the payload) in bytes.
  *		@length is always greater or equal to @min_length.
- * @offset:	when memory in the associated struct vb2_buffer is
- *		VB2_MEMORY_MMAP, equals the offset from the start of
+ * @m:		Union with memtype-specific data.
+ * @m.offset:	when memory in the associated struct vb2_buffer is
+ *		%VB2_MEMORY_MMAP, equals the offset from the start of
  *		the device memory for this plane (or is a "cookie" that
- *		should be passed to mmap() called on the video node)
- * @userptr:	when memory is VB2_MEMORY_USERPTR, a userspace pointer
- *		pointing to this plane
- * @fd:		when memory is VB2_MEMORY_DMABUF, a userspace file
- *		descriptor associated with this plane
- * @m:		Union with memtype-specific data (@offset, @userptr or
- *		@fd).
+ *		should be passed to mmap() called on the video node).
+ * @m.userptr:	when memory is %VB2_MEMORY_USERPTR, a userspace pointer
+ *		pointing to this plane.
+ * @m.fd:	when memory is %VB2_MEMORY_DMABUF, a userspace file
+ *		descriptor associated with this plane.
  * @data_offset:	offset in the plane to the start of data; usually 0,
- *		unless there is a header in front of the data
+ *		unless there is a header in front of the data.
+ *
  * Should contain enough information to be able to cover all the fields
- * of struct v4l2_plane at videodev2.h
+ * of &struct v4l2_plane at videodev2.h.
  */
 struct vb2_plane {
 	void			*mem_priv;
@@ -184,35 +185,35 @@ struct vb2_plane {
 };
 
 /**
- * enum vb2_io_modes - queue access methods
- * @VB2_MMAP:		driver supports MMAP with streaming API
- * @VB2_USERPTR:	driver supports USERPTR with streaming API
- * @VB2_READ:		driver supports read() style access
- * @VB2_WRITE:		driver supports write() style access
- * @VB2_DMABUF:		driver supports DMABUF with streaming API
+ * enum vb2_io_modes - queue access methods.
+ * @VB2_MMAP:		driver supports MMAP with streaming API.
+ * @VB2_USERPTR:	driver supports USERPTR with streaming API.
+ * @VB2_READ:		driver supports read() style access.
+ * @VB2_WRITE:		driver supports write() style access.
+ * @VB2_DMABUF:		driver supports DMABUF with streaming API.
  */
 enum vb2_io_modes {
-	VB2_MMAP	= (1 << 0),
-	VB2_USERPTR	= (1 << 1),
-	VB2_READ	= (1 << 2),
-	VB2_WRITE	= (1 << 3),
-	VB2_DMABUF	= (1 << 4),
+	VB2_MMAP	= BIT(0),
+	VB2_USERPTR	= BIT(1),
+	VB2_READ	= BIT(2),
+	VB2_WRITE	= BIT(3),
+	VB2_DMABUF	= BIT(4),
 };
 
 /**
- * enum vb2_buffer_state - current video buffer state
- * @VB2_BUF_STATE_DEQUEUED:	buffer under userspace control
- * @VB2_BUF_STATE_PREPARING:	buffer is being prepared in videobuf
- * @VB2_BUF_STATE_PREPARED:	buffer prepared in videobuf and by the driver
- * @VB2_BUF_STATE_QUEUED:	buffer queued in videobuf, but not in driver
- * @VB2_BUF_STATE_REQUEUEING:	re-queue a buffer to the driver
+ * enum vb2_buffer_state - current video buffer state.
+ * @VB2_BUF_STATE_DEQUEUED:	buffer under userspace control.
+ * @VB2_BUF_STATE_PREPARING:	buffer is being prepared in videobuf.
+ * @VB2_BUF_STATE_PREPARED:	buffer prepared in videobuf and by the driver.
+ * @VB2_BUF_STATE_QUEUED:	buffer queued in videobuf, but not in driver.
+ * @VB2_BUF_STATE_REQUEUEING:	re-queue a buffer to the driver.
  * @VB2_BUF_STATE_ACTIVE:	buffer queued in driver and possibly used
- *				in a hardware operation
+ *				in a hardware operation.
  * @VB2_BUF_STATE_DONE:		buffer returned from driver to videobuf, but
- *				not yet dequeued to userspace
+ *				not yet dequeued to userspace.
  * @VB2_BUF_STATE_ERROR:	same as above, but the operation on the buffer
  *				has ended with an error, which will be reported
- *				to the userspace when it is dequeued
+ *				to the userspace when it is dequeued.
  */
 enum vb2_buffer_state {
 	VB2_BUF_STATE_DEQUEUED,
@@ -228,15 +229,15 @@ enum vb2_buffer_state {
 struct vb2_queue;
 
 /**
- * struct vb2_buffer - represents a video buffer
- * @vb2_queue:		the queue to which this driver belongs
- * @index:		id number of the buffer
- * @type:		buffer type
- * @memory:		the method, in which the actual data is passed
+ * struct vb2_buffer - represents a video buffer.
+ * @vb2_queue:		pointer to &struct vb2_queue with the queue to
+ *			which this driver belongs.
+ * @index:		id number of the buffer.
+ * @type:		buffer type.
+ * @memory:		the method, in which the actual data is passed.
  * @num_planes:		number of planes in the buffer
- *			on an internal driver queue
- * @planes:		private per-plane information; do not change
- * @timestamp:		frame timestamp in ns
+ *			on an internal driver queue.
+ * @timestamp:		frame timestamp in ns.
  */
 struct vb2_buffer {
 	struct vb2_queue	*vb2_queue;
@@ -244,7 +245,6 @@ struct vb2_buffer {
 	unsigned int		type;
 	unsigned int		memory;
 	unsigned int		num_planes;
-	struct vb2_plane	planes[VB2_MAX_PLANES];
 	u64			timestamp;
 
 	/* private: internal use only
@@ -254,9 +254,11 @@ struct vb2_buffer {
 	 *			all buffers queued from userspace
 	 * done_entry:		entry on the list that stores all buffers ready
 	 *			to be dequeued to userspace
+	 * vb2_plane:		per-plane information; do not change
 	 */
 	enum vb2_buffer_state	state;
 
+	struct vb2_plane	planes[VB2_MAX_PLANES];
 	struct list_head	queued_entry;
 	struct list_head	done_entry;
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -292,7 +294,7 @@ struct vb2_buffer {
 };
 
 /**
- * struct vb2_ops - driver-specific callbacks
+ * struct vb2_ops - driver-specific callbacks.
  *
  * @queue_setup:	called from VIDIOC_REQBUFS() and VIDIOC_CREATE_BUFS()
  *			handlers before memory allocation. It can be called
@@ -358,8 +360,8 @@ struct vb2_buffer {
  *			the @buf_queue callback are to be returned by the driver
  *			by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED.
  *			If you need a minimum number of buffers before you can
- *			start streaming, then set @min_buffers_needed in the
- *			vb2_queue structure. If that is non-zero then
+ *			start streaming, then set
+ *			&vb2_queue->min_buffers_needed. If that is non-zero then
  *			@start_streaming won't be called until at least that
  *			many buffers have been queued up by userspace.
  * @stop_streaming:	called when 'streaming' state must be disabled; driver
@@ -396,18 +398,18 @@ struct vb2_ops {
 };
 
 /**
- * struct vb2_buf_ops - driver-specific callbacks
+ * struct vb2_buf_ops - driver-specific callbacks.
  *
  * @verify_planes_array: Verify that a given user space structure contains
  *			enough planes for the buffer. This is called
  *			for each dequeued buffer.
- * @fill_user_buffer:	given a vb2_buffer fill in the userspace structure.
- *			For V4L2 this is a struct v4l2_buffer.
- * @fill_vb2_buffer:	given a userspace structure, fill in the vb2_buffer.
+ * @fill_user_buffer:	given a &vb2_buffer fill in the userspace structure.
+ *			For V4L2 this is a &struct v4l2_buffer.
+ * @fill_vb2_buffer:	given a userspace structure, fill in the &vb2_buffer.
  *			If the userspace structure is invalid, then this op
  *			will return an error.
  * @copy_timestamp:	copy the timestamp from a userspace structure to
- *			the vb2_buffer struct.
+ *			the &struct vb2_buffer.
  */
 struct vb2_buf_ops {
 	int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb);
@@ -418,20 +420,21 @@ struct vb2_buf_ops {
 };
 
 /**
- * struct vb2_queue - a videobuf queue
+ * struct vb2_queue - a videobuf queue.
  *
  * @type:	private buffer type whose content is defined by the vb2-core
  *		caller. For example, for V4L2, it should match
- *		the types defined on enum &v4l2_buf_type
- * @io_modes:	supported io methods (see vb2_io_modes enum)
+ *		the types defined on &enum v4l2_buf_type.
+ * @io_modes:	supported io methods (see &enum vb2_io_modes).
+ * @alloc_devs:	&struct device memory type/allocator-specific per-plane device
  * @dev:	device to use for the default allocation context if the driver
  *		doesn't fill in the @alloc_devs array.
  * @dma_attrs:	DMA attributes to use for the DMA.
  * @bidirectional: when this flag is set the DMA direction for the buffers of
- *		this queue will be overridden with DMA_BIDIRECTIONAL direction.
+ *		this queue will be overridden with %DMA_BIDIRECTIONAL direction.
  *		This is useful in cases where the hardware (firmware) writes to
- *		a buffer which is mapped as read (DMA_TO_DEVICE), or reads from
- *		buffer which is mapped for write (DMA_FROM_DEVICE) in order
+ *		a buffer which is mapped as read (%DMA_TO_DEVICE), or reads from
+ *		buffer which is mapped for write (%DMA_FROM_DEVICE) in order
  *		to satisfy some internal hardware restrictions or adds a padding
  *		needed by the processing algorithm. In case the DMA mapping is
  *		not bidirectional but the hardware (firmware) trying to access
@@ -440,10 +443,10 @@ struct vb2_buf_ops {
  * @fileio_read_once:		report EOF after reading the first buffer
  * @fileio_write_immediately:	queue buffer after each write() call
  * @allow_zero_bytesused:	allow bytesused == 0 to be passed to the driver
- * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF
+ * @quirk_poll_must_check_waiting_for_buffers: Return %POLLERR at poll when QBUF
  *              has not been called. This is a vb1 idiom that has been adopted
  *              also by vb2.
- * @lock:	pointer to a mutex that protects the vb2_queue struct. The
+ * @lock:	pointer to a mutex that protects the &struct vb2_queue. The
  *		driver can set this to a mutex to let the v4l2 core serialize
  *		the queuing ioctls. If the driver wants to handle locking
  *		itself, then this should be set to NULL. This lock is not used
@@ -454,17 +457,17 @@ struct vb2_buf_ops {
  *		drivers to easily associate an owner filehandle with the queue.
  * @ops:	driver-specific callbacks
  * @mem_ops:	memory allocator specific callbacks
- * @buf_ops:	callbacks to deliver buffer information
- *		between user-space and kernel-space
- * @drv_priv:	driver private data
+ * @buf_ops:	callbacks to deliver buffer information.
+ *		between user-space and kernel-space.
+ * @drv_priv:	driver private data.
  * @buf_struct_size: size of the driver-specific buffer structure;
  *		"0" indicates the driver doesn't want to use a custom buffer
- *		structure type. for example, sizeof(struct vb2_v4l2_buffer)
+ *		structure type. for example, ``sizeof(struct vb2_v4l2_buffer)``
  *		will be used for v4l2.
- * @timestamp_flags: Timestamp flags; V4L2_BUF_FLAG_TIMESTAMP_* and
- *		V4L2_BUF_FLAG_TSTAMP_SRC_*
+ * @timestamp_flags: Timestamp flags; ``V4L2_BUF_FLAG_TIMESTAMP_*`` and
+ *		``V4L2_BUF_FLAG_TSTAMP_SRC_*``
  * @gfp_flags:	additional gfp flags used when allocating the buffers.
- *		Typically this is 0, but it may be e.g. GFP_DMA or __GFP_DMA32
+ *		Typically this is 0, but it may be e.g. %GFP_DMA or %__GFP_DMA32
  *		to force the buffer allocation to a specific memory zone.
  * @min_buffers_needed: the minimum number of buffers needed before
  *		@start_streaming can be called. Used when a DMA engine
@@ -484,20 +487,19 @@ struct vb2_buf_ops {
  * @done_list:	list of buffers ready to be dequeued to userspace
  * @done_lock:	lock to protect done_list list
  * @done_wq:	waitqueue for processes waiting for buffers ready to be dequeued
- * @alloc_devs:	memory type/allocator-specific per-plane device
  * @streaming:	current streaming state
  * @start_streaming_called: @start_streaming was called successfully and we
  *		started streaming.
  * @error:	a fatal error occurred on the queue
  * @waiting_for_buffers: used in poll() to check if vb2 is still waiting for
  *		buffers. Only set for capture queues if qbuf has not yet been
- *		called since poll() needs to return POLLERR in that situation.
+ *		called since poll() needs to return %POLLERR in that situation.
  * @is_multiplanar: set if buffer type is multiplanar
  * @is_output:	set if buffer type is output
  * @copy_timestamp: set if vb2-core should set timestamps
  * @last_buffer_dequeued: used in poll() and DQBUF to immediately return if the
  *		last decoded buffer was already dequeued. Set for capture queues
- *		when a buffer with the V4L2_BUF_FLAG_LAST is dequeued.
+ *		when a buffer with the %V4L2_BUF_FLAG_LAST is dequeued.
  * @fileio:	file io emulator internal data, used only if emulator is active
  * @threadio:	thread io internal data, used only if thread is active
  */
@@ -525,6 +527,8 @@ struct vb2_queue {
 	gfp_t				gfp_flags;
 	u32				min_buffers_needed;
 
+	struct device			*alloc_devs[VB2_MAX_PLANES];
+
 	/* private: internal use only */
 	struct mutex			mmap_lock;
 	unsigned int			memory;
@@ -540,8 +544,6 @@ struct vb2_queue {
 	spinlock_t			done_lock;
 	wait_queue_head_t		done_wq;
 
-	struct device			*alloc_devs[VB2_MAX_PLANES];
-
 	unsigned int			streaming:1;
 	unsigned int			start_streaming_called:1;
 	unsigned int			error:1;
@@ -568,9 +570,10 @@ struct vb2_queue {
 };
 
 /**
- * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
- * @vb:		vb2_buffer to which the plane in question belongs to
- * @plane_no:	plane number for which the address is to be returned
+ * vb2_plane_vaddr() - Return a kernel virtual address of a given plane.
+ * @vb:		pointer to &struct vb2_buffer to which the plane in
+ *		question belongs to.
+ * @plane_no:	plane number for which the address is to be returned.
  *
  * This function returns a kernel virtual address of a given plane if
  * such a mapping exist, NULL otherwise.
@@ -578,9 +581,10 @@ struct vb2_queue {
 void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
 
 /**
- * vb2_plane_cookie() - Return allocator specific cookie for the given plane
- * @vb:		vb2_buffer to which the plane in question belongs to
- * @plane_no:	plane number for which the cookie is to be returned
+ * vb2_plane_cookie() - Return allocator specific cookie for the given plane.
+ * @vb:		pointer to &struct vb2_buffer to which the plane in
+ *		question belongs to.
+ * @plane_no:	plane number for which the cookie is to be returned.
  *
  * This function returns an allocator specific cookie for a given plane if
  * available, NULL otherwise. The allocator should provide some simple static
@@ -591,9 +595,11 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
 void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no);
 
 /**
- * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished
- * @vb:		vb2_buffer returned from the driver
- * @state:	either %VB2_BUF_STATE_DONE if the operation finished
+ * vb2_buffer_done() - inform videobuf that an operation on a buffer
+ *	is finished.
+ * @vb:		pointer to &struct vb2_buffer to be used.
+ * @state:	state of the buffer, as defined by &enum vb2_buffer_state.
+ *		Either %VB2_BUF_STATE_DONE if the operation finished
  *		successfully, %VB2_BUF_STATE_ERROR if the operation finished
  *		with an error or %VB2_BUF_STATE_QUEUED if the driver wants to
  *		requeue buffers. If start_streaming fails then it should return
@@ -614,8 +620,8 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no);
 void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state);
 
 /**
- * vb2_discard_done() - discard all buffers marked as DONE
- * @q:		videobuf2 queue
+ * vb2_discard_done() - discard all buffers marked as DONE.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  *
  * This function is intended to be used with suspend/resume operations. It
  * discards all 'done' buffers as they would be too old to be requested after
@@ -628,74 +634,83 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state);
 void vb2_discard_done(struct vb2_queue *q);
 
 /**
- * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2
- * @q:		videobuf2 queue
+ * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  *
  * This function will wait until all buffers that have been given to the driver
  * by &vb2_ops->buf_queue are given back to vb2 with vb2_buffer_done(). It
- * doesn't call wait_prepare()/wait_finish() pair. It is intended to be called
- * with all locks taken, for example from &vb2_ops->stop_streaming callback.
+ * doesn't call &vb2_ops->wait_prepare/&vb2_ops->wait_finish pair.
+ * It is intended to be called with all locks taken, for example from
+ * &vb2_ops->stop_streaming callback.
  */
 int vb2_wait_for_all_buffers(struct vb2_queue *q);
 
 /**
- * vb2_core_querybuf() - query video buffer information
- * @q:		videobuf queue
- * @index:	id number of the buffer
- * @pb:		buffer struct passed from userspace
+ * vb2_core_querybuf() - query video buffer information.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @index:	id number of the buffer.
+ * @pb:		buffer struct passed from userspace.
  *
- * Should be called from vidioc_querybuf ioctl handler in driver.
+ * Videobuf2 core helper to implement VIDIOC_QUERYBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
  * The passed buffer should have been verified.
+ *
  * This function fills the relevant information for the userspace.
+ *
+ * Return: returns zero on success; an error code otherwise.
  */
 void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb);
 
 /**
- * vb2_core_reqbufs() - Initiate streaming
- * @q:		videobuf2 queue
- * @memory: memory type
- * @count: requested buffer count
+ * vb2_core_reqbufs() - Initiate streaming.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @memory:	memory type, as defined by &enum vb2_memory.
+ * @count:	requested buffer count.
  *
- * Should be called from vidioc_reqbufs ioctl handler of a driver.
+ * Videobuf2 core helper to implement VIDIOC_REQBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
  *
  * This function:
  *
- * #) verifies streaming parameters passed from the userspace,
- * #) sets up the queue,
+ * #) verifies streaming parameters passed from the userspace;
+ * #) sets up the queue;
  * #) negotiates number of buffers and planes per buffer with the driver
- *    to be used during streaming,
- * #) allocates internal buffer structures (struct vb2_buffer), according to
- *    the agreed parameters,
+ *    to be used during streaming;
+ * #) allocates internal buffer structures (&struct vb2_buffer), according to
+ *    the agreed parameters;
  * #) for MMAP memory type, allocates actual video memory, using the
- *    memory handling/allocation routines provided during queue initialization
+ *    memory handling/allocation routines provided during queue initialization.
  *
  * If req->count is 0, all the memory will be freed instead.
- * If the queue has been allocated previously (by a previous vb2_reqbufs) call
- * and the queue is not busy, memory will be reallocated.
  *
- * The return values from this function are intended to be directly returned
- * from vidioc_reqbufs handler in driver.
+ * If the queue has been allocated previously by a previous vb2_core_reqbufs()
+ * call and the queue is not busy, memory will be reallocated.
+ *
+ * Return: returns zero on success; an error code otherwise.
  */
 int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
 		unsigned int *count);
 
 /**
  * vb2_core_create_bufs() - Allocate buffers and any required auxiliary structs
- * @q:		videobuf2 queue
- * @memory: memory type
- * @count: requested buffer count
- * @requested_planes: number of planes requested
- * @requested_sizes: array with the size of the planes
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @memory: memory type, as defined by &enum vb2_memory.
+ * @count: requested buffer count.
+ * @requested_planes: number of planes requested.
+ * @requested_sizes: array with the size of the planes.
  *
- * Should be called from VIDIOC_CREATE_BUFS() ioctl handler of a driver.
+ * Videobuf2 core helper to implement VIDIOC_CREATE_BUFS() operation. It is
+ * called internally by VB2 by an API-specific handler, like
+ * ``videobuf2-v4l2.h``.
+ *
  * This function:
  *
- * #) verifies parameter sanity
- * #) calls the .queue_setup() queue operation
- * #) performs any necessary memory allocations
+ * #) verifies parameter sanity;
+ * #) calls the &vb2_ops->queue_setup queue operation;
+ * #) performs any necessary memory allocations.
  *
- * Return: the return values from this function are intended to be directly
- * returned from VIDIOC_CREATE_BUFS() handler in driver.
+ * Return: returns zero on success; an error code otherwise.
  */
 int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
 			 unsigned int *count, unsigned int requested_planes,
@@ -703,57 +718,61 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
 
 /**
  * vb2_core_prepare_buf() - Pass ownership of a buffer from userspace
- *			to the kernel
- * @q:		videobuf2 queue
- * @index:	id number of the buffer
- * @pb:		buffer structure passed from userspace to vidioc_prepare_buf
- *		handler in driver
+ *			to the kernel.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @index:	id number of the buffer.
+ * @pb:		buffer structure passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_prepare_buf handler in driver.
  *
- * Should be called from vidioc_prepare_buf ioctl handler of a driver.
+ * Videobuf2 core helper to implement VIDIOC_PREPARE_BUF() operation. It is
+ * called internally by VB2 by an API-specific handler, like
+ * ``videobuf2-v4l2.h``.
+ *
  * The passed buffer should have been verified.
- * This function calls buf_prepare callback in the driver (if provided),
- * in which driver-specific buffer initialization can be performed,
  *
- * The return values from this function are intended to be directly returned
- * from vidioc_prepare_buf handler in driver.
+ * This function calls vb2_ops->buf_prepare callback in the driver
+ * (if provided), in which driver-specific buffer initialization can
+ * be performed.
+ *
+ * Return: returns zero on success; an error code otherwise.
  */
 int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb);
 
 /**
  * vb2_core_qbuf() - Queue a buffer from userspace
  *
- * @q:		videobuf2 queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  * @index:	id number of the buffer
- * @pb:		buffer structure passed from userspace to vidioc_qbuf handler
- *		in driver
+ * @pb:		buffer structure passed from userspace to
+ *		v4l2_ioctl_ops->vidioc_qbuf handler in driver
  *
- * Should be called from vidioc_qbuf ioctl handler of a driver.
- * The passed buffer should have been verified.
+ * Videobuf2 core helper to implement VIDIOC_QBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
  *
  * This function:
  *
- * #) if necessary, calls buf_prepare callback in the driver (if provided), in
- *    which driver-specific buffer initialization can be performed,
+ * #) if necessary, calls &vb2_ops->buf_prepare callback in the driver
+ *    (if provided), in which driver-specific buffer initialization can
+ *    be performed;
  * #) if streaming is on, queues the buffer in driver by the means of
  *    &vb2_ops->buf_queue callback for processing.
  *
- * The return values from this function are intended to be directly returned
- * from vidioc_qbuf handler in driver.
+ * Return: returns zero on success; an error code otherwise.
  */
 int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb);
 
 /**
  * vb2_core_dqbuf() - Dequeue a buffer to the userspace
- * @q:		videobuf2 queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue
  * @pindex:	pointer to the buffer index. May be NULL
- * @pb:		buffer structure passed from userspace to vidioc_dqbuf handler
- *		in driver
+ * @pb:		buffer structure passed from userspace to
+ *		v4l2_ioctl_ops->vidioc_dqbuf handler in driver.
  * @nonblocking: if true, this call will not sleep waiting for a buffer if no
  *		 buffers ready for dequeuing are present. Normally the driver
- *		 would be passing (file->f_flags & O_NONBLOCK) here
+ *		 would be passing (file->f_flags & O_NONBLOCK) here.
  *
- * Should be called from vidioc_dqbuf ioctl handler of a driver.
- * The passed buffer should have been verified.
+ * Videobuf2 core helper to implement VIDIOC_DQBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
  *
  * This function:
  *
@@ -763,73 +782,108 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb);
  * #) the buffer struct members are filled with relevant information for
  *    the userspace.
  *
- * The return values from this function are intended to be directly returned
- * from vidioc_dqbuf handler in driver.
+ * Return: returns zero on success; an error code otherwise.
  */
 int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb,
 		   bool nonblocking);
 
+/**
+ * vb2_core_streamon() - Implements VB2 stream ON logic
+ *
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue
+ * @type:	type of the queue to be started.
+ *		For V4L2, this is defined by &enum v4l2_buf_type type.
+ *
+ * Videobuf2 core helper to implement VIDIOC_STREAMON() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
 int vb2_core_streamon(struct vb2_queue *q, unsigned int type);
+
+/**
+ * vb2_core_streamoff() - Implements VB2 stream OFF logic
+ *
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue
+ * @type:	type of the queue to be started.
+ *		For V4L2, this is defined by &enum v4l2_buf_type type.
+ *
+ * Videobuf2 core helper to implement VIDIOC_STREAMOFF() operation. It is
+ * called internally by VB2 by an API-specific handler, like
+ * ``videobuf2-v4l2.h``.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
 int vb2_core_streamoff(struct vb2_queue *q, unsigned int type);
 
 /**
- * vb2_core_expbuf() - Export a buffer as a file descriptor
- * @q:		videobuf2 queue
- * @fd:		file descriptor associated with DMABUF (set by driver) *
- * @type:	buffer type
- * @index:	id number of the buffer
+ * vb2_core_expbuf() - Export a buffer as a file descriptor.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @fd:		pointer to the file descriptor associated with DMABUF
+ *		(set by driver).
+ * @type:	buffer type.
+ * @index:	id number of the buffer.
  * @plane:	index of the plane to be exported, 0 for single plane queues
- * @flags:	flags for newly created file, currently only O_CLOEXEC is
- *		supported, refer to manual of open syscall for more details
+ * @flags:	file flags for newly created file, as defined at
+ *		include/uapi/asm-generic/fcntl.h.
+ *		Currently, the only used flag is %O_CLOEXEC.
+ *		is supported, refer to manual of open syscall for more details.
  *
- * The return values from this function are intended to be directly returned
- * from vidioc_expbuf handler in driver.
+ *
+ * Videobuf2 core helper to implement VIDIOC_EXPBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
+ * Return: returns zero on success; an error code otherwise.
  */
 int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type,
 		unsigned int index, unsigned int plane, unsigned int flags);
 
 /**
  * vb2_core_queue_init() - initialize a videobuf2 queue
- * @q:		videobuf2 queue; this structure should be allocated in driver
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ *		This structure should be allocated in driver
  *
- * The vb2_queue structure should be allocated by the driver. The driver is
+ * The &vb2_queue structure should be allocated by the driver. The driver is
  * responsible of clearing it's content and setting initial values for some
  * required entries before calling this function.
- * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer
- * to the struct vb2_queue description in include/media/videobuf2-core.h
- * for more information.
+ *
+ * .. note::
+ *
+ *    The following fields at @q should be set before calling this function:
+ *    &vb2_queue->ops, &vb2_queue->mem_ops, &vb2_queue->type.
  */
 int vb2_core_queue_init(struct vb2_queue *q);
 
 /**
  * vb2_core_queue_release() - stop streaming, release the queue and free memory
- * @q:		videobuf2 queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  *
  * This function stops streaming and performs necessary clean ups, including
  * freeing video buffer memory. The driver is responsible for freeing
- * the vb2_queue structure itself.
+ * the &struct vb2_queue itself.
  */
 void vb2_core_queue_release(struct vb2_queue *q);
 
 /**
  * vb2_queue_error() - signal a fatal error on the queue
- * @q:		videobuf2 queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  *
  * Flag that a fatal unrecoverable error has occurred and wake up all processes
- * waiting on the queue. Polling will now set POLLERR and queuing and dequeuing
- * buffers will return -EIO.
+ * waiting on the queue. Polling will now set %POLLERR and queuing and dequeuing
+ * buffers will return %-EIO.
  *
- * The error flag will be cleared when cancelling the queue, either from
- * vb2_streamoff or vb2_queue_release. Drivers should thus not call this
+ * The error flag will be cleared when canceling the queue, either from
+ * vb2_streamoff() or vb2_queue_release(). Drivers should thus not call this
  * function before starting the stream, otherwise the error flag will remain set
  * until the queue is released when closing the device node.
  */
 void vb2_queue_error(struct vb2_queue *q);
 
 /**
- * vb2_mmap() - map video buffers into application address space
- * @q:		videobuf2 queue
- * @vma:	vma passed to the mmap file operation handler in the driver
+ * vb2_mmap() - map video buffers into application address space.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @vma:	pointer to &struct vm_area_struct with the vma passed
+ *		to the mmap file operation handler in the driver.
  *
  * Should be called from mmap file operation handler of a driver.
  * This function maps one plane of one of the available video buffers to
@@ -837,8 +891,10 @@ void vb2_queue_error(struct vb2_queue *q);
  * has to be called once per each plane per each buffer previously allocated.
  *
  * When the userspace application calls mmap, it passes to it an offset returned
- * to it earlier by the means of vidioc_querybuf handler. That offset acts as
- * a "cookie", which is then used to identify the plane to be mapped.
+ * to it earlier by the means of &v4l2_ioctl_ops->vidioc_querybuf handler.
+ * That offset acts as a "cookie", which is then used to identify the plane
+ * to be mapped.
+ *
  * This function finds a plane with a matching offset and a mapping is performed
  * by the means of a provided memory operation.
  *
@@ -848,6 +904,21 @@ void vb2_queue_error(struct vb2_queue *q);
 int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma);
 
 #ifndef CONFIG_MMU
+/**
+ * vb2_get_unmapped_area - map video buffers into application address space.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @addr:	memory address.
+ * @len:	buffer size.
+ * @pgoff:	page offset.
+ * @flags:	memory flags.
+ *
+ * This function is used in noMMU platforms to propose address mapping
+ * for a given buffer. It's intended to be used as a handler for the
+ * &file_operations->get_unmapped_area operation.
+ *
+ * This is called by the mmap() syscall routines will call this
+ * to get a proposed address for the mapping, when ``!CONFIG_MMU``.
+ */
 unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
 				    unsigned long addr,
 				    unsigned long len,
@@ -856,10 +927,12 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
 #endif
 
 /**
- * vb2_core_poll() - implements poll userspace operation
- * @q:		videobuf2 queue
- * @file:	file argument passed to the poll file operation handler
- * @wait:	wait argument passed to the poll file operation handler
+ * vb2_core_poll() - implements poll syscall() logic.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @file:	&struct file argument passed to the poll
+ *		file operation handler.
+ * @wait:	&poll_table wait argument passed to the poll
+ *		file operation handler.
  *
  * This function implements poll file operation handler for a driver.
  * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
@@ -874,16 +947,32 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
 __poll_t vb2_core_poll(struct vb2_queue *q, struct file *file,
 			   poll_table *wait);
 
+/**
+ * vb2_read() - implements read() syscall logic.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @data:	pointed to target userspace buffer
+ * @count:	number of bytes to read
+ * @ppos:	file handle position tracking pointer
+ * @nonblock:	mode selector (1 means blocking calls, 0 means nonblocking)
+ */
 size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
 		loff_t *ppos, int nonblock);
+/**
+ * vb2_read() - implements write() syscall logic.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @data:	pointed to target userspace buffer
+ * @count:	number of bytes to write
+ * @ppos:	file handle position tracking pointer
+ * @nonblock:	mode selector (1 means blocking calls, 0 means nonblocking)
+ */
 size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
 		loff_t *ppos, int nonblock);
 
 /**
- * typedef vb2_thread_fnc - callback function for use with vb2_thread
+ * typedef vb2_thread_fnc - callback function for use with vb2_thread.
  *
- * @vb: pointer to struct &vb2_buffer
- * @priv: pointer to a private pointer
+ * @vb: pointer to struct &vb2_buffer.
+ * @priv: pointer to a private data.
  *
  * This is called whenever a buffer is dequeued in the thread.
  */
@@ -891,13 +980,13 @@ typedef int (*vb2_thread_fnc)(struct vb2_buffer *vb, void *priv);
 
 /**
  * vb2_thread_start() - start a thread for the given queue.
- * @q:		videobuf queue
- * @fnc:	callback function
- * @priv:	priv pointer passed to the callback function
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @fnc:	&vb2_thread_fnc callback function.
+ * @priv:	priv pointer passed to the callback function.
  * @thread_name:the name of the thread. This will be prefixed with "vb2-".
  *
  * This starts a thread that will queue and dequeue until an error occurs
- * or @vb2_thread_stop is called.
+ * or vb2_thread_stop() is called.
  *
  * .. attention::
  *
@@ -910,13 +999,13 @@ int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv,
 
 /**
  * vb2_thread_stop() - stop the thread for the given queue.
- * @q:		videobuf queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  */
 int vb2_thread_stop(struct vb2_queue *q);
 
 /**
- * vb2_is_streaming() - return streaming status of the queue
- * @q:		videobuf queue
+ * vb2_is_streaming() - return streaming status of the queue.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  */
 static inline bool vb2_is_streaming(struct vb2_queue *q)
 {
@@ -925,15 +1014,16 @@ static inline bool vb2_is_streaming(struct vb2_queue *q)
 
 /**
  * vb2_fileio_is_active() - return true if fileio is active.
- * @q:		videobuf queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  *
  * This returns true if read() or write() is used to stream the data
  * as opposed to stream I/O. This is almost never an important distinction,
  * except in rare cases. One such case is that using read() or write() to
- * stream a format using V4L2_FIELD_ALTERNATE is not allowed since there
+ * stream a format using %V4L2_FIELD_ALTERNATE is not allowed since there
  * is no way you can pass the field information of each buffer to/from
  * userspace. A driver that supports this field format should check for
- * this in the queue_setup op and reject it if this function returns true.
+ * this in the &vb2_ops->queue_setup op and reject it if this function returns
+ * true.
  */
 static inline bool vb2_fileio_is_active(struct vb2_queue *q)
 {
@@ -941,8 +1031,8 @@ static inline bool vb2_fileio_is_active(struct vb2_queue *q)
 }
 
 /**
- * vb2_is_busy() - return busy status of the queue
- * @q:		videobuf queue
+ * vb2_is_busy() - return busy status of the queue.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  *
  * This function checks if queue has any buffers allocated.
  */
@@ -952,8 +1042,8 @@ static inline bool vb2_is_busy(struct vb2_queue *q)
 }
 
 /**
- * vb2_get_drv_priv() - return driver private data associated with the queue
- * @q:		videobuf queue
+ * vb2_get_drv_priv() - return driver private data associated with the queue.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  */
 static inline void *vb2_get_drv_priv(struct vb2_queue *q)
 {
@@ -961,10 +1051,11 @@ static inline void *vb2_get_drv_priv(struct vb2_queue *q)
 }
 
 /**
- * vb2_set_plane_payload() - set bytesused for the plane plane_no
- * @vb:		buffer for which plane payload should be set
- * @plane_no:	plane number for which payload should be set
- * @size:	payload in bytes
+ * vb2_set_plane_payload() - set bytesused for the plane @plane_no.
+ * @vb:		pointer to &struct vb2_buffer to which the plane in
+ *		question belongs to.
+ * @plane_no:	plane number for which payload should be set.
+ * @size:	payload in bytes.
  */
 static inline void vb2_set_plane_payload(struct vb2_buffer *vb,
 				 unsigned int plane_no, unsigned long size)
@@ -975,8 +1066,9 @@ static inline void vb2_set_plane_payload(struct vb2_buffer *vb,
 
 /**
  * vb2_get_plane_payload() - get bytesused for the plane plane_no
- * @vb:		buffer for which plane payload should be set
- * @plane_no:	plane number for which payload should be set
+ * @vb:		pointer to &struct vb2_buffer to which the plane in
+ *		question belongs to.
+ * @plane_no:	plane number for which payload should be set.
  */
 static inline unsigned long vb2_get_plane_payload(struct vb2_buffer *vb,
 				 unsigned int plane_no)
@@ -987,9 +1079,10 @@ static inline unsigned long vb2_get_plane_payload(struct vb2_buffer *vb,
 }
 
 /**
- * vb2_plane_size() - return plane size in bytes
- * @vb:		buffer for which plane size should be returned
- * @plane_no:	plane number for which size should be returned
+ * vb2_plane_size() - return plane size in bytes.
+ * @vb:		pointer to &struct vb2_buffer to which the plane in
+ *		question belongs to.
+ * @plane_no:	plane number for which size should be returned.
  */
 static inline unsigned long
 vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no)
@@ -1000,8 +1093,8 @@ vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no)
 }
 
 /**
- * vb2_start_streaming_called() - return streaming status of driver
- * @q:		videobuf queue
+ * vb2_start_streaming_called() - return streaming status of driver.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  */
 static inline bool vb2_start_streaming_called(struct vb2_queue *q)
 {
@@ -1009,8 +1102,8 @@ static inline bool vb2_start_streaming_called(struct vb2_queue *q)
 }
 
 /**
- * vb2_clear_last_buffer_dequeued() - clear last buffer dequeued flag of queue
- * @q:		videobuf queue
+ * vb2_clear_last_buffer_dequeued() - clear last buffer dequeued flag of queue.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  */
 static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q)
 {
@@ -1024,10 +1117,10 @@ static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q)
 
 /**
  * vb2_buffer_in_use() - return true if the buffer is in use and
- * the queue cannot be freed (by the means of REQBUFS(0)) call
+ * the queue cannot be freed (by the means of VIDIOC_REQBUFS(0)) call.
  *
- * @vb:		buffer for which plane size should be returned
- * @q:		videobuf queue
+ * @vb:		buffer for which plane size should be returned.
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  */
 bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb);
 
@@ -1035,11 +1128,11 @@ bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb);
  * vb2_verify_memory_type() - Check whether the memory type and buffer type
  * passed to a buffer operation are compatible with the queue.
  *
- * @q:		videobuf queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  * @memory:	memory model, as defined by enum &vb2_memory.
  * @type:	private buffer type whose content is defined by the vb2-core
  *		caller. For example, for V4L2, it should match
- *		the types defined on enum &v4l2_buf_type
+ *		the types defined on enum &v4l2_buf_type.
  */
 int vb2_verify_memory_type(struct vb2_queue *q,
 		enum vb2_memory memory, unsigned int type);
diff --git a/include/media/videobuf2-dvb.h b/include/media/videobuf2-dvb.h
index 5a31faa..8605366 100644
--- a/include/media/videobuf2-dvb.h
+++ b/include/media/videobuf2-dvb.h
@@ -2,12 +2,11 @@
 #ifndef _VIDEOBUF2_DVB_H_
 #define	_VIDEOBUF2_DVB_H_
 
-#include <dvbdev.h>
-#include <dmxdev.h>
-#include <dvb_demux.h>
-#include <dvb_net.h>
-#include <dvb_frontend.h>
-
+#include <media/dvbdev.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dvb_frontend.h>
 #include <media/videobuf2-v4l2.h>
 
 /* We don't actually need to include media-device.h here */
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
index a6ed091..4b5b84f 100644
--- a/include/media/videobuf2-memops.h
+++ b/include/media/videobuf2-memops.h
@@ -19,11 +19,11 @@
 #include <linux/refcount.h>
 
 /**
- * struct vb2_vmarea_handler - common vma refcount tracking handler
+ * struct vb2_vmarea_handler - common vma refcount tracking handler.
  *
- * @refcount:	pointer to refcount entry in the buffer
- * @put:	callback to function that decreases buffer refcount
- * @arg:	argument for @put callback
+ * @refcount:	pointer to &refcount_t entry in the buffer.
+ * @put:	callback to function that decreases buffer refcount.
+ * @arg:	argument for @put callback.
  */
 struct vb2_vmarea_handler {
 	refcount_t		*refcount;
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index c2fa556..3d5e2d7 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h
@@ -24,16 +24,17 @@
 #endif
 
 /**
- * struct vb2_v4l2_buffer - video buffer information for v4l2
+ * struct vb2_v4l2_buffer - video buffer information for v4l2.
  *
- * @vb2_buf:	video buffer 2
- * @flags:	buffer informational flags
- * @field:	enum v4l2_field; field order of the image in the buffer
- * @timecode:	frame timecode
- * @sequence:	sequence count of this frame
+ * @vb2_buf:	embedded struct &vb2_buffer.
+ * @flags:	buffer informational flags.
+ * @field:	field order of the image in the buffer, as defined by
+ *		&enum v4l2_field.
+ * @timecode:	frame timecode.
+ * @sequence:	sequence count of this frame.
  *
  * Should contain enough information to be able to cover all the fields
- * of struct v4l2_buffer at videodev2.h
+ * of &struct v4l2_buffer at ``videodev2.h``.
  */
 struct vb2_v4l2_buffer {
 	struct vb2_buffer	vb2_buf;
@@ -56,9 +57,9 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b);
  * vb2_reqbufs() - Wrapper for vb2_core_reqbufs() that also verifies
  * the memory and type values.
  *
- * @q:		videobuf2 queue
- * @req:	struct passed from userspace to vidioc_reqbufs handler
- *		in driver
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @req:	&struct v4l2_requestbuffers passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_reqbufs handler in driver.
  */
 int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
 
@@ -66,94 +67,99 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
  * vb2_create_bufs() - Wrapper for vb2_core_create_bufs() that also verifies
  * the memory and type values.
  *
- * @q:		videobuf2 queue
- * @create:	creation parameters, passed from userspace to vidioc_create_bufs
- *		handler in driver
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @create:	creation parameters, passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_create_bufs handler in driver
  */
 int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create);
 
 /**
  * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
  *
- * @q:		videobuf2 queue
- * @b:		buffer structure passed from userspace to vidioc_prepare_buf
- *		handler in driver
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @b:		buffer structure passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_prepare_buf handler in driver
  *
- * Should be called from vidioc_prepare_buf ioctl handler of a driver.
+ * Should be called from &v4l2_ioctl_ops->vidioc_prepare_buf ioctl handler
+ * of a driver.
+ *
  * This function:
  *
  * #) verifies the passed buffer,
- * #) calls buf_prepare callback in the driver (if provided), in which
- *    driver-specific buffer initialization can be performed.
+ * #) calls &vb2_ops->buf_prepare callback in the driver (if provided),
+ *    in which driver-specific buffer initialization can be performed.
  *
  * The return values from this function are intended to be directly returned
- * from vidioc_prepare_buf handler in driver.
+ * from &v4l2_ioctl_ops->vidioc_prepare_buf handler in driver.
  */
 int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b);
 
 /**
  * vb2_qbuf() - Queue a buffer from userspace
- * @q:		videobuf2 queue
- * @b:		buffer structure passed from userspace to VIDIOC_QBUF() handler
- *		in driver
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @b:		buffer structure passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_qbuf handler in driver
  *
- * Should be called from VIDIOC_QBUF() ioctl handler of a driver.
+ * Should be called from &v4l2_ioctl_ops->vidioc_qbuf handler of a driver.
  *
  * This function:
  *
- * #) verifies the passed buffer,
- * #) if necessary, calls buf_prepare callback in the driver (if provided), in
- *    which driver-specific buffer initialization can be performed,
- * #) if streaming is on, queues the buffer in driver by the means of buf_queue
- *    callback for processing.
+ * #) verifies the passed buffer;
+ * #) if necessary, calls &vb2_ops->buf_prepare callback in the driver
+ *    (if provided), in which driver-specific buffer initialization can
+ *    be performed;
+ * #) if streaming is on, queues the buffer in driver by the means of
+ *    &vb2_ops->buf_queue callback for processing.
  *
  * The return values from this function are intended to be directly returned
- * from VIDIOC_QBUF() handler in driver.
+ * from &v4l2_ioctl_ops->vidioc_qbuf handler in driver.
  */
 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
 
 /**
  * vb2_expbuf() - Export a buffer as a file descriptor
- * @q:		videobuf2 queue
- * @eb:		export buffer structure passed from userspace to VIDIOC_EXPBUF()
- *		handler in driver
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @eb:		export buffer structure passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_expbuf handler in driver
  *
  * The return values from this function are intended to be directly returned
- * from VIDIOC_EXPBUF() handler in driver.
+ * from &v4l2_ioctl_ops->vidioc_expbuf handler in driver.
  */
 int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
 
 /**
  * vb2_dqbuf() - Dequeue a buffer to the userspace
- * @q:		videobuf2 queue
- * @b:		buffer structure passed from userspace to VIDIOC_DQBUF() handler
- *		in driver
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @b:		buffer structure passed from userspace to
+ *		&v4l2_ioctl_ops->vidioc_dqbuf handler in driver
  * @nonblocking: if true, this call will not sleep waiting for a buffer if no
  *		 buffers ready for dequeuing are present. Normally the driver
- *		 would be passing (file->f_flags & O_NONBLOCK) here
+ *		 would be passing (&file->f_flags & %O_NONBLOCK) here
  *
- * Should be called from VIDIOC_DQBUF() ioctl handler of a driver.
+ * Should be called from &v4l2_ioctl_ops->vidioc_dqbuf ioctl handler
+ * of a driver.
  *
  * This function:
  *
- * #) verifies the passed buffer,
- * #) calls buf_finish callback in the driver (if provided), in which
+ * #) verifies the passed buffer;
+ * #) calls &vb2_ops->buf_finish callback in the driver (if provided), in which
  *    driver can perform any additional operations that may be required before
- *    returning the buffer to userspace, such as cache sync,
+ *    returning the buffer to userspace, such as cache sync;
  * #) the buffer struct members are filled with relevant information for
  *    the userspace.
  *
  * The return values from this function are intended to be directly returned
- * from VIDIOC_DQBUF() handler in driver.
+ * from &v4l2_ioctl_ops->vidioc_dqbuf handler in driver.
  */
 int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
 
 /**
  * vb2_streamon - start streaming
- * @q:		videobuf2 queue
- * @type:	type argument passed from userspace to vidioc_streamon handler
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
+ * @type:	type argument passed from userspace to vidioc_streamon handler,
+ *		as defined by &enum v4l2_buf_type.
  *
- * Should be called from vidioc_streamon handler of a driver.
+ * Should be called from &v4l2_ioctl_ops->vidioc_streamon handler of a driver.
  *
  * This function:
  *
@@ -161,13 +167,13 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
  * 2) passes any previously queued buffers to the driver and starts streaming
  *
  * The return values from this function are intended to be directly returned
- * from vidioc_streamon handler in the driver.
+ * from &v4l2_ioctl_ops->vidioc_streamon handler in the driver.
  */
 int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
 
 /**
  * vb2_streamoff - stop streaming
- * @q:		videobuf2 queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  * @type:	type argument passed from userspace to vidioc_streamoff handler
  *
  * Should be called from vidioc_streamoff handler of a driver.
@@ -186,7 +192,7 @@ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type);
 
 /**
  * vb2_queue_init() - initialize a videobuf2 queue
- * @q:		videobuf2 queue; this structure should be allocated in driver
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  *
  * The vb2_queue structure should be allocated by the driver. The driver is
  * responsible of clearing it's content and setting initial values for some
@@ -199,7 +205,7 @@ int __must_check vb2_queue_init(struct vb2_queue *q);
 
 /**
  * vb2_queue_release() - stop streaming, release the queue and free memory
- * @q:		videobuf2 queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  *
  * This function stops streaming and performs necessary clean ups, including
  * freeing video buffer memory. The driver is responsible for freeing
@@ -209,7 +215,7 @@ void vb2_queue_release(struct vb2_queue *q);
 
 /**
  * vb2_poll() - implements poll userspace operation
- * @q:		videobuf2 queue
+ * @q:		pointer to &struct vb2_queue with videobuf2 queue.
  * @file:	file argument passed to the poll file operation handler
  * @wait:	wait argument passed to the poll file operation handler
  *
@@ -270,7 +276,7 @@ unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr,
 /**
  * vb2_ops_wait_prepare - helper function to lock a struct &vb2_queue
  *
- * @vq: pointer to struct vb2_queue
+ * @vq: pointer to &struct vb2_queue
  *
  * ..note:: only use if vq->lock is non-NULL.
  */
@@ -279,7 +285,7 @@ void vb2_ops_wait_prepare(struct vb2_queue *vq);
 /**
  * vb2_ops_wait_finish - helper function to unlock a struct &vb2_queue
  *
- * @vq: pointer to struct vb2_queue
+ * @vq: pointer to &struct vb2_queue
  *
  * ..note:: only use if vq->lock is non-NULL.
  */
diff --git a/include/net/erspan.h b/include/net/erspan.h
index 5daa486..d044aa6 100644
--- a/include/net/erspan.h
+++ b/include/net/erspan.h
@@ -159,13 +159,13 @@ static inline void erspan_build_header(struct sk_buff *skb,
 	struct ethhdr *eth = (struct ethhdr *)skb->data;
 	enum erspan_encap_type enc_type;
 	struct erspan_base_hdr *ershdr;
-	struct erspan_metadata *ersmd;
 	struct qtag_prefix {
 		__be16 eth_type;
 		__be16 tci;
 	} *qp;
 	u16 vlan_tci = 0;
 	u8 tos;
+	__be32 *idx;
 
 	tos = is_ipv4 ? ip_hdr(skb)->tos :
 			(ipv6_hdr(skb)->priority << 4) +
@@ -195,8 +195,8 @@ static inline void erspan_build_header(struct sk_buff *skb,
 	set_session_id(ershdr, id);
 
 	/* Build metadata */
-	ersmd = (struct erspan_metadata *)(ershdr + 1);
-	ersmd->u.index = htonl(index & INDEX_MASK);
+	idx = (__be32 *)(ershdr + 1);
+	*idx = htonl(index & INDEX_MASK);
 }
 
 /* ERSPAN GRA: timestamp granularity
@@ -225,7 +225,7 @@ static inline void erspan_build_header_v2(struct sk_buff *skb,
 {
 	struct ethhdr *eth = (struct ethhdr *)skb->data;
 	struct erspan_base_hdr *ershdr;
-	struct erspan_metadata *md;
+	struct erspan_md2 *md2;
 	struct qtag_prefix {
 		__be16 eth_type;
 		__be16 tci;
@@ -261,15 +261,15 @@ static inline void erspan_build_header_v2(struct sk_buff *skb,
 	set_session_id(ershdr, id);
 
 	/* Build metadata */
-	md = (struct erspan_metadata *)(ershdr + 1);
-	md->u.md2.timestamp = erspan_get_timestamp();
-	md->u.md2.sgt = htons(sgt);
-	md->u.md2.p = 1;
-	md->u.md2.ft = 0;
-	md->u.md2.dir = direction;
-	md->u.md2.gra = gra;
-	md->u.md2.o = 0;
-	set_hwid(&md->u.md2, hwid);
+	md2 = (struct erspan_md2 *)(ershdr + 1);
+	md2->timestamp = erspan_get_timestamp();
+	md2->sgt = htons(sgt);
+	md2->p = 1;
+	md2->ft = 0;
+	md2->dir = direction;
+	md2->gra = gra;
+	md2->o = 0;
+	set_hwid(md2, hwid);
 }
 
 #endif
diff --git a/include/rdma/ib_hdrs.h b/include/rdma/ib_hdrs.h
index c124d51..6e35416 100644
--- a/include/rdma/ib_hdrs.h
+++ b/include/rdma/ib_hdrs.h
@@ -313,16 +313,14 @@ static inline u32 ib_bth_get_qpn(struct ib_other_headers *ohdr)
 	return (u32)((be32_to_cpu(ohdr->bth[1])) & IB_QPN_MASK);
 }
 
-static inline u8 ib_bth_get_becn(struct ib_other_headers *ohdr)
+static inline bool ib_bth_get_becn(struct ib_other_headers *ohdr)
 {
-	return (u8)((be32_to_cpu(ohdr->bth[1]) >> IB_BECN_SHIFT) &
-		     IB_BECN_MASK);
+	return (ohdr->bth[1]) & cpu_to_be32(IB_BECN_SMASK);
 }
 
-static inline u8 ib_bth_get_fecn(struct ib_other_headers *ohdr)
+static inline bool ib_bth_get_fecn(struct ib_other_headers *ohdr)
 {
-	return (u8)((be32_to_cpu(ohdr->bth[1]) >> IB_FECN_SHIFT) &
-		    IB_FECN_MASK);
+	return (ohdr->bth[1]) & cpu_to_be32(IB_FECN_SMASK);
 }
 
 static inline u8 ib_bth_get_tver(struct ib_other_headers *ohdr)
@@ -331,4 +329,13 @@ static inline u8 ib_bth_get_tver(struct ib_other_headers *ohdr)
 		    IB_BTH_TVER_MASK);
 }
 
+static inline bool ib_bth_is_solicited(struct ib_other_headers *ohdr)
+{
+	return ohdr->bth[0] & cpu_to_be32(IB_BTH_SOLICITED);
+}
+
+static inline bool ib_bth_is_migration(struct ib_other_headers *ohdr)
+{
+	return ohdr->bth[0] & cpu_to_be32(IB_BTH_MIG_REQ);
+}
 #endif                          /* IB_HDRS_H */
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 5263c86..73b2387 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -874,6 +874,7 @@ struct ib_mr_status {
 __attribute_const__ enum ib_rate mult_to_ib_rate(int mult);
 
 enum rdma_ah_attr_type {
+	RDMA_AH_ATTR_TYPE_UNDEFINED,
 	RDMA_AH_ATTR_TYPE_IB,
 	RDMA_AH_ATTR_TYPE_ROCE,
 	RDMA_AH_ATTR_TYPE_OPA,
@@ -3810,17 +3811,24 @@ static inline void rdma_ah_set_grh(struct rdma_ah_attr *attr,
 	grh->traffic_class = traffic_class;
 }
 
-/*Get AH type */
+/**
+ * rdma_ah_find_type - Return address handle type.
+ *
+ * @dev: Device to be checked
+ * @port_num: Port number
+ */
 static inline enum rdma_ah_attr_type rdma_ah_find_type(struct ib_device *dev,
-						       u32 port_num)
+						       u8 port_num)
 {
 	if (rdma_protocol_roce(dev, port_num))
 		return RDMA_AH_ATTR_TYPE_ROCE;
-	else if ((rdma_protocol_ib(dev, port_num)) &&
-		 (rdma_cap_opa_ah(dev, port_num)))
-		return RDMA_AH_ATTR_TYPE_OPA;
-	else
+	if (rdma_protocol_ib(dev, port_num)) {
+		if (rdma_cap_opa_ah(dev, port_num))
+			return RDMA_AH_ATTR_TYPE_OPA;
 		return RDMA_AH_ATTR_TYPE_IB;
+	}
+
+	return RDMA_AH_ATTR_TYPE_UNDEFINED;
 }
 
 /**
diff --git a/include/sound/soc.h b/include/sound/soc.h
index b655d98..747fd58 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -841,7 +841,7 @@ struct snd_soc_component_driver {
 	/* bits */
 	unsigned int idle_bias_on:1;
 	unsigned int suspend_bias_off:1;
-	unsigned int pmdown_time:1; /* care pmdown_time at stop */
+	unsigned int use_pmdown_time:1; /* care pmdown_time at stop */
 	unsigned int endianness:1;
 	unsigned int non_legacy_dai_naming:1;
 };
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index 254afc3..85dc965 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -280,8 +280,8 @@ typedef struct siginfo {
 #define NSIGTRAP	4
 
 /*
- * There are an additional set of SIGTRAP si_codes used by ptrace
- * that of the form: ((PTRACE_EVENT_XXX << 8) | SIGTRAP)
+ * There is an additional set of SIGTRAP si_codes used by ptrace
+ * that are of the form: ((PTRACE_EVENT_XXX << 8) | SIGTRAP)
  */
 
 /*
diff --git a/include/uapi/linux/dvb/dmx.h b/include/uapi/linux/dvb/dmx.h
index c10f132..5f3c5a9 100644
--- a/include/uapi/linux/dvb/dmx.h
+++ b/include/uapi/linux/dvb/dmx.h
@@ -211,6 +211,61 @@ struct dmx_stc {
 	__u64 stc;
 };
 
+/**
+ * struct dmx_buffer - dmx buffer info
+ *
+ * @index:	id number of the buffer
+ * @bytesused:	number of bytes occupied by data in the buffer (payload);
+ * @offset:	for buffers with memory == DMX_MEMORY_MMAP;
+ *		offset from the start of the device memory for this plane,
+ *		(or a "cookie" that should be passed to mmap() as offset)
+ * @length:	size in bytes of the buffer
+ *
+ * Contains data exchanged by application and driver using one of the streaming
+ * I/O methods.
+ */
+struct dmx_buffer {
+	__u32			index;
+	__u32			bytesused;
+	__u32			offset;
+	__u32			length;
+};
+
+/**
+ * struct dmx_requestbuffers - request dmx buffer information
+ *
+ * @count:	number of requested buffers,
+ * @size:	size in bytes of the requested buffer
+ *
+ * Contains data used for requesting a dmx buffer.
+ * All reserved fields must be set to zero.
+ */
+struct dmx_requestbuffers {
+	__u32			count;
+	__u32			size;
+};
+
+/**
+ * struct dmx_exportbuffer - export of dmx buffer as DMABUF file descriptor
+ *
+ * @index:	id number of the buffer
+ * @flags:	flags for newly created file, currently only O_CLOEXEC is
+ *		supported, refer to manual of open syscall for more details
+ * @fd:		file descriptor associated with DMABUF (set by driver)
+ *
+ * Contains data used for exporting a dmx buffer as DMABUF file descriptor.
+ * The buffer is identified by a 'cookie' returned by DMX_QUERYBUF
+ * (identical to the cookie used to mmap() the buffer to userspace). All
+ * reserved fields must be set to zero. The field reserved0 is expected to
+ * become a structure 'type' allowing an alternative layout of the structure
+ * content. Therefore this field should not be used for any other extensions.
+ */
+struct dmx_exportbuffer {
+	__u32		index;
+	__u32		flags;
+	__s32		fd;
+};
+
 #define DMX_START                _IO('o', 41)
 #define DMX_STOP                 _IO('o', 42)
 #define DMX_SET_FILTER           _IOW('o', 43, struct dmx_sct_filter_params)
@@ -231,4 +286,10 @@ typedef struct dmx_filter dmx_filter_t;
 
 #endif
 
-#endif /* _UAPI_DVBDMX_H_ */
+#define DMX_REQBUFS              _IOWR('o', 60, struct dmx_requestbuffers)
+#define DMX_QUERYBUF             _IOWR('o', 61, struct dmx_buffer)
+#define DMX_EXPBUF               _IOWR('o', 62, struct dmx_exportbuffer)
+#define DMX_QBUF                 _IOWR('o', 63, struct dmx_buffer)
+#define DMX_DQBUF                _IOWR('o', 64, struct dmx_buffer)
+
+#endif /* _DVBDMX_H_ */
diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h
index b297b65..4f9b455 100644
--- a/include/uapi/linux/dvb/frontend.h
+++ b/include/uapi/linux/dvb/frontend.h
@@ -547,7 +547,10 @@ enum fe_interleaving {
 #define DTV_STAT_ERROR_BLOCK_COUNT	68
 #define DTV_STAT_TOTAL_BLOCK_COUNT	69
 
-#define DTV_MAX_COMMAND		DTV_STAT_TOTAL_BLOCK_COUNT
+/* Physical layer scrambling */
+#define DTV_SCRAMBLING_SEQUENCE_INDEX	70
+
+#define DTV_MAX_COMMAND		DTV_SCRAMBLING_SEQUENCE_INDEX
 
 /**
  * enum fe_pilot - Type of pilot tone
@@ -756,16 +759,15 @@ enum fecap_scale_params {
 /**
  * struct dtv_stats - Used for reading a DTV status property
  *
- * @scale:	Filled with enum fecap_scale_params - the scale
- *		in usage for that parameter
+ * @scale:
+ *	Filled with enum fecap_scale_params - the scale in usage
+ *	for that parameter
  *
- * The ``{unnamed_union}`` may have either one of the values below:
- *
- * %svalue
+ * @svalue:
  *	integer value of the measure, for %FE_SCALE_DECIBEL,
  *	used for dB measures. The unit is 0.001 dB.
  *
- * %uvalue
+ * @uvalue:
  *	unsigned integer value of the measure, used when @scale is
  *	either %FE_SCALE_RELATIVE or %FE_SCALE_COUNTER.
  *
@@ -828,19 +830,19 @@ struct dtv_fe_stats {
 /**
  * struct dtv_property - store one of frontend command and its value
  *
- * @cmd:	Digital TV command.
- * @reserved:	Not used.
- * @u:		Union with the values for the command.
- * @result:	Unused
+ * @cmd:		Digital TV command.
+ * @reserved:		Not used.
+ * @u:			Union with the values for the command.
+ * @u.data:		A unsigned 32 bits integer with command value.
+ * @u.buffer:		Struct to store bigger properties.
+ *			Currently unused.
+ * @u.buffer.data:	an unsigned 32-bits array.
+ * @u.buffer.len:	number of elements of the buffer.
+ * @u.buffer.reserved1:	Reserved.
+ * @u.buffer.reserved2:	Reserved.
+ * @u.st:		a &struct dtv_fe_stats array of statistics.
+ * @result:		Currently unused.
  *
- * The @u union may have either one of the values below:
- *
- * %data
- *	an unsigned 32-bits number.
- * %st
- *	a &struct dtv_fe_stats array of statistics.
- * %buffer
- *	a buffer of up to 32 characters (currently unused).
  */
 struct dtv_property {
 	__u32 cmd;
diff --git a/include/uapi/linux/dvb/version.h b/include/uapi/linux/dvb/version.h
index 02e32ea..2c5cffe 100644
--- a/include/uapi/linux/dvb/version.h
+++ b/include/uapi/linux/dvb/version.h
@@ -25,6 +25,6 @@
 #define _DVBVERSION_H_
 
 #define DVB_API_VERSION 5
-#define DVB_API_VERSION_MINOR 10
+#define DVB_API_VERSION_MINOR 11
 
 #endif /*_DVBVERSION_H_*/
diff --git a/include/uapi/linux/dvb/video.h b/include/uapi/linux/dvb/video.h
index 4d51f98..df3d702 100644
--- a/include/uapi/linux/dvb/video.h
+++ b/include/uapi/linux/dvb/video.h
@@ -83,11 +83,11 @@ typedef enum {
 #define VIDEO_CMD_CONTINUE    (3)
 
 /* Flags for VIDEO_CMD_FREEZE */
-#define VIDEO_CMD_FREEZE_TO_BLACK     	(1 << 0)
+#define VIDEO_CMD_FREEZE_TO_BLACK	(1 << 0)
 
 /* Flags for VIDEO_CMD_STOP */
-#define VIDEO_CMD_STOP_TO_BLACK      	(1 << 0)
-#define VIDEO_CMD_STOP_IMMEDIATELY     	(1 << 1)
+#define VIDEO_CMD_STOP_TO_BLACK		(1 << 0)
+#define VIDEO_CMD_STOP_IMMEDIATELY	(1 << 1)
 
 /* Play input formats: */
 /* The decoder has no special format requirements */
@@ -124,8 +124,8 @@ struct video_command {
 /* FIELD_UNKNOWN can be used if the hardware does not know whether
    the Vsync is for an odd, even or progressive (i.e. non-interlaced)
    field. */
-#define VIDEO_VSYNC_FIELD_UNKNOWN  	(0)
-#define VIDEO_VSYNC_FIELD_ODD 		(1)
+#define VIDEO_VSYNC_FIELD_UNKNOWN	(0)
+#define VIDEO_VSYNC_FIELD_ODD		(1)
 #define VIDEO_VSYNC_FIELD_EVEN		(2)
 #define VIDEO_VSYNC_FIELD_PROGRESSIVE	(3)
 
@@ -133,8 +133,8 @@ struct video_event {
 	__s32 type;
 #define VIDEO_EVENT_SIZE_CHANGED	1
 #define VIDEO_EVENT_FRAME_RATE_CHANGED	2
-#define VIDEO_EVENT_DECODER_STOPPED 	3
-#define VIDEO_EVENT_VSYNC 		4
+#define VIDEO_EVENT_DECODER_STOPPED	3
+#define VIDEO_EVENT_VSYNC		4
 	/* unused, make sure to use atomic time for y2038 if it ever gets used */
 	long timestamp;
 	union {
@@ -268,9 +268,9 @@ typedef __u16 video_attributes_t;
 #define VIDEO_GET_PTS              _IOR('o', 57, __u64)
 
 /* Read the number of displayed frames since the decoder was started */
-#define VIDEO_GET_FRAME_COUNT  	   _IOR('o', 58, __u64)
+#define VIDEO_GET_FRAME_COUNT	   _IOR('o', 58, __u64)
 
-#define VIDEO_COMMAND     	   _IOWR('o', 59, struct video_command)
-#define VIDEO_TRY_COMMAND 	   _IOWR('o', 60, struct video_command)
+#define VIDEO_COMMAND		   _IOWR('o', 59, struct video_command)
+#define VIDEO_TRY_COMMAND	   _IOWR('o', 60, struct video_command)
 
 #endif /* _UAPI_DVBVIDEO_H_ */
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
index 061fa62..53fbae2 100644
--- a/include/uapi/linux/input-event-codes.h
+++ b/include/uapi/linux/input-event-codes.h
@@ -594,6 +594,7 @@
 #define BTN_DPAD_RIGHT		0x223
 
 #define KEY_ALS_TOGGLE		0x230	/* Ambient light sensor */
+#define KEY_ROTATE_LOCK_TOGGLE	0x231	/* Display rotation lock */
 
 #define KEY_BUTTONCONFIG		0x240	/* AL Button Configuration */
 #define KEY_TASKMANAGER		0x241	/* AL Task/Project Manager */
diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h
index c3aef431..4fe580d 100644
--- a/include/uapi/linux/lirc.h
+++ b/include/uapi/linux/lirc.h
@@ -47,12 +47,14 @@
 #define LIRC_MODE_RAW                  0x00000001
 #define LIRC_MODE_PULSE                0x00000002
 #define LIRC_MODE_MODE2                0x00000004
+#define LIRC_MODE_SCANCODE             0x00000008
 #define LIRC_MODE_LIRCCODE             0x00000010
 
 
 #define LIRC_CAN_SEND_RAW              LIRC_MODE2SEND(LIRC_MODE_RAW)
 #define LIRC_CAN_SEND_PULSE            LIRC_MODE2SEND(LIRC_MODE_PULSE)
 #define LIRC_CAN_SEND_MODE2            LIRC_MODE2SEND(LIRC_MODE_MODE2)
+#define LIRC_CAN_SEND_SCANCODE         LIRC_MODE2SEND(LIRC_MODE_SCANCODE)
 #define LIRC_CAN_SEND_LIRCCODE         LIRC_MODE2SEND(LIRC_MODE_LIRCCODE)
 
 #define LIRC_CAN_SEND_MASK             0x0000003f
@@ -64,6 +66,7 @@
 #define LIRC_CAN_REC_RAW               LIRC_MODE2REC(LIRC_MODE_RAW)
 #define LIRC_CAN_REC_PULSE             LIRC_MODE2REC(LIRC_MODE_PULSE)
 #define LIRC_CAN_REC_MODE2             LIRC_MODE2REC(LIRC_MODE_MODE2)
+#define LIRC_CAN_REC_SCANCODE          LIRC_MODE2REC(LIRC_MODE_SCANCODE)
 #define LIRC_CAN_REC_LIRCCODE          LIRC_MODE2REC(LIRC_MODE_LIRCCODE)
 
 #define LIRC_CAN_REC_MASK              LIRC_MODE2REC(LIRC_CAN_SEND_MASK)
@@ -131,4 +134,83 @@
 
 #define LIRC_SET_WIDEBAND_RECEIVER     _IOW('i', 0x00000023, __u32)
 
+/*
+ * struct lirc_scancode - decoded scancode with protocol for use with
+ *	LIRC_MODE_SCANCODE
+ *
+ * @timestamp: Timestamp in nanoseconds using CLOCK_MONOTONIC when IR
+ *	was decoded.
+ * @flags: should be 0 for transmit. When receiving scancodes,
+ *	LIRC_SCANCODE_FLAG_TOGGLE or LIRC_SCANCODE_FLAG_REPEAT can be set
+ *	depending on the protocol
+ * @rc_proto: see enum rc_proto
+ * @keycode: the translated keycode. Set to 0 for transmit.
+ * @scancode: the scancode received or to be sent
+ */
+struct lirc_scancode {
+	__u64	timestamp;
+	__u16	flags;
+	__u16	rc_proto;
+	__u32	keycode;
+	__u64	scancode;
+};
+
+/* Set if the toggle bit of rc-5 or rc-6 is enabled */
+#define LIRC_SCANCODE_FLAG_TOGGLE	1
+/* Set if this is a nec or sanyo repeat */
+#define LIRC_SCANCODE_FLAG_REPEAT	2
+
+/**
+ * enum rc_proto - the Remote Controller protocol
+ *
+ * @RC_PROTO_UNKNOWN: Protocol not known
+ * @RC_PROTO_OTHER: Protocol known but proprietary
+ * @RC_PROTO_RC5: Philips RC5 protocol
+ * @RC_PROTO_RC5X_20: Philips RC5x 20 bit protocol
+ * @RC_PROTO_RC5_SZ: StreamZap variant of RC5
+ * @RC_PROTO_JVC: JVC protocol
+ * @RC_PROTO_SONY12: Sony 12 bit protocol
+ * @RC_PROTO_SONY15: Sony 15 bit protocol
+ * @RC_PROTO_SONY20: Sony 20 bit protocol
+ * @RC_PROTO_NEC: NEC protocol
+ * @RC_PROTO_NECX: Extended NEC protocol
+ * @RC_PROTO_NEC32: NEC 32 bit protocol
+ * @RC_PROTO_SANYO: Sanyo protocol
+ * @RC_PROTO_MCIR2_KBD: RC6-ish MCE keyboard
+ * @RC_PROTO_MCIR2_MSE: RC6-ish MCE mouse
+ * @RC_PROTO_RC6_0: Philips RC6-0-16 protocol
+ * @RC_PROTO_RC6_6A_20: Philips RC6-6A-20 protocol
+ * @RC_PROTO_RC6_6A_24: Philips RC6-6A-24 protocol
+ * @RC_PROTO_RC6_6A_32: Philips RC6-6A-32 protocol
+ * @RC_PROTO_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol
+ * @RC_PROTO_SHARP: Sharp protocol
+ * @RC_PROTO_XMP: XMP protocol
+ * @RC_PROTO_CEC: CEC protocol
+ */
+enum rc_proto {
+	RC_PROTO_UNKNOWN	= 0,
+	RC_PROTO_OTHER		= 1,
+	RC_PROTO_RC5		= 2,
+	RC_PROTO_RC5X_20	= 3,
+	RC_PROTO_RC5_SZ		= 4,
+	RC_PROTO_JVC		= 5,
+	RC_PROTO_SONY12		= 6,
+	RC_PROTO_SONY15		= 7,
+	RC_PROTO_SONY20		= 8,
+	RC_PROTO_NEC		= 9,
+	RC_PROTO_NECX		= 10,
+	RC_PROTO_NEC32		= 11,
+	RC_PROTO_SANYO		= 12,
+	RC_PROTO_MCIR2_KBD	= 13,
+	RC_PROTO_MCIR2_MSE	= 14,
+	RC_PROTO_RC6_0		= 15,
+	RC_PROTO_RC6_6A_20	= 16,
+	RC_PROTO_RC6_6A_24	= 17,
+	RC_PROTO_RC6_6A_32	= 18,
+	RC_PROTO_RC6_MCE	= 19,
+	RC_PROTO_SHARP		= 20,
+	RC_PROTO_XMP		= 21,
+	RC_PROTO_CEC		= 22,
+};
+
 #endif
diff --git a/include/uapi/linux/membarrier.h b/include/uapi/linux/membarrier.h
index 4e01ad7..5891d76 100644
--- a/include/uapi/linux/membarrier.h
+++ b/include/uapi/linux/membarrier.h
@@ -31,7 +31,7 @@
  * enum membarrier_cmd - membarrier system call command
  * @MEMBARRIER_CMD_QUERY:   Query the set of supported commands. It returns
  *                          a bitmask of valid commands.
- * @MEMBARRIER_CMD_SHARED:  Execute a memory barrier on all running threads.
+ * @MEMBARRIER_CMD_GLOBAL:  Execute a memory barrier on all running threads.
  *                          Upon return from system call, the caller thread
  *                          is ensured that all running threads have passed
  *                          through a state where all memory accesses to
@@ -40,6 +40,28 @@
  *                          (non-running threads are de facto in such a
  *                          state). This covers threads from all processes
  *                          running on the system. This command returns 0.
+ * @MEMBARRIER_CMD_GLOBAL_EXPEDITED:
+ *                          Execute a memory barrier on all running threads
+ *                          of all processes which previously registered
+ *                          with MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED.
+ *                          Upon return from system call, the caller thread
+ *                          is ensured that all running threads have passed
+ *                          through a state where all memory accesses to
+ *                          user-space addresses match program order between
+ *                          entry to and return from the system call
+ *                          (non-running threads are de facto in such a
+ *                          state). This only covers threads from processes
+ *                          which registered with
+ *                          MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED.
+ *                          This command returns 0. Given that
+ *                          registration is about the intent to receive
+ *                          the barriers, it is valid to invoke
+ *                          MEMBARRIER_CMD_GLOBAL_EXPEDITED from a
+ *                          non-registered process.
+ * @MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED:
+ *                          Register the process intent to receive
+ *                          MEMBARRIER_CMD_GLOBAL_EXPEDITED memory
+ *                          barriers. Always returns 0.
  * @MEMBARRIER_CMD_PRIVATE_EXPEDITED:
  *                          Execute a memory barrier on each running
  *                          thread belonging to the same process as the current
@@ -51,7 +73,7 @@
  *                          to and return from the system call
  *                          (non-running threads are de facto in such a
  *                          state). This only covers threads from the
- *                          same processes as the caller thread. This
+ *                          same process as the caller thread. This
  *                          command returns 0 on success. The
  *                          "expedited" commands complete faster than
  *                          the non-expedited ones, they never block,
@@ -64,18 +86,54 @@
  *                          Register the process intent to use
  *                          MEMBARRIER_CMD_PRIVATE_EXPEDITED. Always
  *                          returns 0.
+ * @MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE:
+ *                          In addition to provide memory ordering
+ *                          guarantees described in
+ *                          MEMBARRIER_CMD_PRIVATE_EXPEDITED, ensure
+ *                          the caller thread, upon return from system
+ *                          call, that all its running threads siblings
+ *                          have executed a core serializing
+ *                          instruction. (architectures are required to
+ *                          guarantee that non-running threads issue
+ *                          core serializing instructions before they
+ *                          resume user-space execution). This only
+ *                          covers threads from the same process as the
+ *                          caller thread. This command returns 0 on
+ *                          success. The "expedited" commands complete
+ *                          faster than the non-expedited ones, they
+ *                          never block, but have the downside of
+ *                          causing extra overhead. If this command is
+ *                          not implemented by an architecture, -EINVAL
+ *                          is returned. A process needs to register its
+ *                          intent to use the private expedited sync
+ *                          core command prior to using it, otherwise
+ *                          this command returns -EPERM.
+ * @MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE:
+ *                          Register the process intent to use
+ *                          MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE.
+ *                          If this command is not implemented by an
+ *                          architecture, -EINVAL is returned.
+ *                          Returns 0 on success.
+ * @MEMBARRIER_CMD_SHARED:
+ *                          Alias to MEMBARRIER_CMD_GLOBAL. Provided for
+ *                          header backward compatibility.
  *
  * Command to be passed to the membarrier system call. The commands need to
  * be a single bit each, except for MEMBARRIER_CMD_QUERY which is assigned to
  * the value 0.
  */
 enum membarrier_cmd {
-	MEMBARRIER_CMD_QUERY				= 0,
-	MEMBARRIER_CMD_SHARED				= (1 << 0),
-	/* reserved for MEMBARRIER_CMD_SHARED_EXPEDITED (1 << 1) */
-	/* reserved for MEMBARRIER_CMD_PRIVATE (1 << 2) */
-	MEMBARRIER_CMD_PRIVATE_EXPEDITED		= (1 << 3),
-	MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED	= (1 << 4),
+	MEMBARRIER_CMD_QUERY					= 0,
+	MEMBARRIER_CMD_GLOBAL					= (1 << 0),
+	MEMBARRIER_CMD_GLOBAL_EXPEDITED				= (1 << 1),
+	MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED		= (1 << 2),
+	MEMBARRIER_CMD_PRIVATE_EXPEDITED			= (1 << 3),
+	MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED		= (1 << 4),
+	MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE		= (1 << 5),
+	MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE	= (1 << 6),
+
+	/* Alias for header backward compatibility. */
+	MEMBARRIER_CMD_SHARED			= MEMBARRIER_CMD_GLOBAL,
 };
 
 #endif /* _UAPI_LINUX_MEMBARRIER_H */
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 3f03567..7e27070 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -15,54 +15,6 @@
 
 #include <linux/types.h>
 
-struct nd_cmd_smart {
-	__u32 status;
-	__u8 data[128];
-} __packed;
-
-#define ND_SMART_HEALTH_VALID	(1 << 0)
-#define ND_SMART_SPARES_VALID	(1 << 1)
-#define ND_SMART_USED_VALID	(1 << 2)
-#define ND_SMART_TEMP_VALID 	(1 << 3)
-#define ND_SMART_CTEMP_VALID 	(1 << 4)
-#define ND_SMART_ALARM_VALID	(1 << 9)
-#define ND_SMART_SHUTDOWN_VALID	(1 << 10)
-#define ND_SMART_VENDOR_VALID	(1 << 11)
-#define ND_SMART_SPARE_TRIP	(1 << 0)
-#define ND_SMART_TEMP_TRIP	(1 << 1)
-#define ND_SMART_CTEMP_TRIP	(1 << 2)
-#define ND_SMART_NON_CRITICAL_HEALTH	(1 << 0)
-#define ND_SMART_CRITICAL_HEALTH	(1 << 1)
-#define ND_SMART_FATAL_HEALTH		(1 << 2)
-
-struct nd_smart_payload {
-	__u32 flags;
-	__u8 reserved0[4];
-	__u8 health;
-	__u8 spares;
-	__u8 life_used;
-	__u8 alarm_flags;
-	__u16 temperature;
-	__u16 ctrl_temperature;
-	__u8 reserved1[15];
-	__u8 shutdown_state;
-	__u32 vendor_size;
-	__u8 vendor_data[92];
-} __packed;
-
-struct nd_cmd_smart_threshold {
-	__u32 status;
-	__u8 data[8];
-} __packed;
-
-struct nd_smart_threshold_payload {
-	__u8 alarm_control;
-	__u8 reserved0;
-	__u16 temperature;
-	__u8 spares;
-	__u8 reserved[3];
-} __packed;
-
 struct nd_cmd_dimm_flags {
 	__u32 status;
 	__u32 flags;
@@ -211,12 +163,6 @@ static inline const char *nvdimm_cmd_name(unsigned cmd)
 
 #define ND_IOCTL 'N'
 
-#define ND_IOCTL_SMART			_IOWR(ND_IOCTL, ND_CMD_SMART,\
-					struct nd_cmd_smart)
-
-#define ND_IOCTL_SMART_THRESHOLD	_IOWR(ND_IOCTL, ND_CMD_SMART_THRESHOLD,\
-					struct nd_cmd_smart_threshold)
-
 #define ND_IOCTL_DIMM_FLAGS		_IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\
 					struct nd_cmd_dimm_flags)
 
@@ -263,7 +209,7 @@ enum nd_driver_flags {
 };
 
 enum {
-	ND_MIN_NAMESPACE_SIZE = 0x00400000,
+	ND_MIN_NAMESPACE_SIZE = PAGE_SIZE,
 };
 
 enum ars_masks {
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index 70c2b2a..0c79eac 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -622,15 +622,19 @@
  * safely.
  */
 #define PCI_EXP_DEVCAP2		36	/* Device Capabilities 2 */
+#define  PCI_EXP_DEVCAP2_COMP_TMOUT_DIS	0x00000010 /* Completion Timeout Disable supported */
 #define  PCI_EXP_DEVCAP2_ARI		0x00000020 /* Alternative Routing-ID */
 #define  PCI_EXP_DEVCAP2_ATOMIC_ROUTE	0x00000040 /* Atomic Op routing */
-#define PCI_EXP_DEVCAP2_ATOMIC_COMP64	0x00000100 /* Atomic 64-bit compare */
+#define  PCI_EXP_DEVCAP2_ATOMIC_COMP32	0x00000080 /* 32b AtomicOp completion */
+#define  PCI_EXP_DEVCAP2_ATOMIC_COMP64	0x00000100 /* 64b AtomicOp completion */
+#define  PCI_EXP_DEVCAP2_ATOMIC_COMP128	0x00000200 /* 128b AtomicOp completion */
 #define  PCI_EXP_DEVCAP2_LTR		0x00000800 /* Latency tolerance reporting */
 #define  PCI_EXP_DEVCAP2_OBFF_MASK	0x000c0000 /* OBFF support mechanism */
 #define  PCI_EXP_DEVCAP2_OBFF_MSG	0x00040000 /* New message signaling */
 #define  PCI_EXP_DEVCAP2_OBFF_WAKE	0x00080000 /* Re-use WAKE# for OBFF */
 #define PCI_EXP_DEVCTL2		40	/* Device Control 2 */
 #define  PCI_EXP_DEVCTL2_COMP_TIMEOUT	0x000f	/* Completion Timeout Value */
+#define  PCI_EXP_DEVCTL2_COMP_TMOUT_DIS	0x0010	/* Completion Timeout Disable */
 #define  PCI_EXP_DEVCTL2_ARI		0x0020	/* Alternative Routing-ID */
 #define PCI_EXP_DEVCTL2_ATOMIC_REQ	0x0040	/* Set Atomic requests */
 #define PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK 0x0080 /* Block atomic egress */
@@ -966,26 +970,28 @@
 
 /* Downstream Port Containment */
 #define PCI_EXP_DPC_CAP			4	/* DPC Capability */
-#define PCI_EXP_DPC_IRQ			0x1f	/* DPC Interrupt Message Number */
-#define  PCI_EXP_DPC_CAP_RP_EXT		0x20	/* Root Port Extensions for DPC */
-#define  PCI_EXP_DPC_CAP_POISONED_TLP	0x40	/* Poisoned TLP Egress Blocking Supported */
-#define  PCI_EXP_DPC_CAP_SW_TRIGGER	0x80	/* Software Triggering Supported */
-#define  PCI_EXP_DPC_RP_PIO_LOG_SIZE	0xF00	/* RP PIO log size */
+#define PCI_EXP_DPC_IRQ			0x001F	/* Interrupt Message Number */
+#define  PCI_EXP_DPC_CAP_RP_EXT		0x0020	/* Root Port Extensions */
+#define  PCI_EXP_DPC_CAP_POISONED_TLP	0x0040	/* Poisoned TLP Egress Blocking Supported */
+#define  PCI_EXP_DPC_CAP_SW_TRIGGER	0x0080	/* Software Triggering Supported */
+#define  PCI_EXP_DPC_RP_PIO_LOG_SIZE	0x0F00	/* RP PIO Log Size */
 #define  PCI_EXP_DPC_CAP_DL_ACTIVE	0x1000	/* ERR_COR signal on DL_Active supported */
 
 #define PCI_EXP_DPC_CTL			6	/* DPC control */
-#define  PCI_EXP_DPC_CTL_EN_NONFATAL 	0x02	/* Enable trigger on ERR_NONFATAL message */
-#define  PCI_EXP_DPC_CTL_INT_EN 	0x08	/* DPC Interrupt Enable */
+#define  PCI_EXP_DPC_CTL_EN_NONFATAL 	0x0002	/* Enable trigger on ERR_NONFATAL message */
+#define  PCI_EXP_DPC_CTL_INT_EN 	0x0008	/* DPC Interrupt Enable */
 
 #define PCI_EXP_DPC_STATUS		8	/* DPC Status */
-#define  PCI_EXP_DPC_STATUS_TRIGGER	0x01	/* Trigger Status */
-#define  PCI_EXP_DPC_STATUS_INTERRUPT	0x08	/* Interrupt Status */
-#define  PCI_EXP_DPC_RP_BUSY		0x10	/* Root Port Busy */
+#define  PCI_EXP_DPC_STATUS_TRIGGER	    0x0001 /* Trigger Status */
+#define  PCI_EXP_DPC_STATUS_TRIGGER_RSN	    0x0006 /* Trigger Reason */
+#define  PCI_EXP_DPC_STATUS_INTERRUPT	    0x0008 /* Interrupt Status */
+#define  PCI_EXP_DPC_RP_BUSY		    0x0010 /* Root Port Busy */
+#define  PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */
 
 #define PCI_EXP_DPC_SOURCE_ID		10	/* DPC Source Identifier */
 
 #define PCI_EXP_DPC_RP_PIO_STATUS	 0x0C	/* RP PIO Status */
-#define PCI_EXP_DPC_RP_PIO_MASK		 0x10	/* RP PIO MASK */
+#define PCI_EXP_DPC_RP_PIO_MASK		 0x10	/* RP PIO Mask */
 #define PCI_EXP_DPC_RP_PIO_SEVERITY	 0x14	/* RP PIO Severity */
 #define PCI_EXP_DPC_RP_PIO_SYSERROR	 0x18	/* RP PIO SysError */
 #define PCI_EXP_DPC_RP_PIO_EXCEPTION	 0x1C	/* RP PIO Exception */
diff --git a/include/uapi/linux/psci.h b/include/uapi/linux/psci.h
index 760e52a..b3bcabe 100644
--- a/include/uapi/linux/psci.h
+++ b/include/uapi/linux/psci.h
@@ -88,6 +88,9 @@
 		(((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT)
 #define PSCI_VERSION_MINOR(ver)			\
 		((ver) & PSCI_VERSION_MINOR_MASK)
+#define PSCI_VERSION(maj, min)						\
+	((((maj) << PSCI_VERSION_MAJOR_SHIFT) & PSCI_VERSION_MAJOR_MASK) | \
+	 ((min) & PSCI_VERSION_MINOR_MASK))
 
 /* PSCI features decoding (>=1.0) */
 #define PSCI_1_0_FEATURES_CPU_SUSPEND_PF_SHIFT	1
diff --git a/include/uapi/linux/switchtec_ioctl.h b/include/uapi/linux/switchtec_ioctl.h
index 75df443..4f4daf8 100644
--- a/include/uapi/linux/switchtec_ioctl.h
+++ b/include/uapi/linux/switchtec_ioctl.h
@@ -88,7 +88,8 @@ struct switchtec_ioctl_event_summary {
 #define SWITCHTEC_IOCTL_EVENT_FORCE_SPEED		26
 #define SWITCHTEC_IOCTL_EVENT_CREDIT_TIMEOUT		27
 #define SWITCHTEC_IOCTL_EVENT_LINK_STATE		28
-#define SWITCHTEC_IOCTL_MAX_EVENTS			29
+#define SWITCHTEC_IOCTL_EVENT_GFMS			29
+#define SWITCHTEC_IOCTL_MAX_EVENTS			30
 
 #define SWITCHTEC_IOCTL_EVENT_LOCAL_PART_IDX -1
 #define SWITCHTEC_IOCTL_EVENT_IDX_ALL -2
diff --git a/include/uapi/linux/uuid.h b/include/uapi/linux/uuid.h
index 5c04130..e5a7eec 100644
--- a/include/uapi/linux/uuid.h
+++ b/include/uapi/linux/uuid.h
@@ -19,7 +19,6 @@
 #define _UAPI_LINUX_UUID_H_
 
 #include <linux/types.h>
-#include <linux/string.h>
 
 typedef struct {
 	__u8 b[16];
diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h
index e80b465..020714d 100644
--- a/include/uapi/linux/uvcvideo.h
+++ b/include/uapi/linux/uvcvideo.h
@@ -68,4 +68,30 @@ struct uvc_xu_control_query {
 #define UVCIOC_CTRL_MAP		_IOWR('u', 0x20, struct uvc_xu_control_mapping)
 #define UVCIOC_CTRL_QUERY	_IOWR('u', 0x21, struct uvc_xu_control_query)
 
+/*
+ * Metadata node
+ */
+
+/**
+ * struct uvc_meta_buf - metadata buffer building block
+ * @ns		- system timestamp of the payload in nanoseconds
+ * @sof		- USB Frame Number
+ * @length	- length of the payload header
+ * @flags	- payload header flags
+ * @buf		- optional device-specific header data
+ *
+ * UVC metadata nodes fill buffers with possibly multiple instances of this
+ * struct. The first two fields are added by the driver, they can be used for
+ * clock synchronisation. The rest is an exact copy of a UVC payload header.
+ * Only complete objects with complete buffers are included. Therefore it's
+ * always sizeof(meta->ts) + sizeof(meta->sof) + meta->length bytes large.
+ */
+struct uvc_meta_buf {
+	__u64 ns;
+	__u16 sof;
+	__u8 length;
+	__u8 flags;
+	__u8 buf[];
+} __packed;
+
 #endif
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index a692623..cbbb750 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -67,8 +67,8 @@
 /* User-class control IDs */
 
 #define V4L2_CID_BASE			(V4L2_CTRL_CLASS_USER | 0x900)
-#define V4L2_CID_USER_BASE 		V4L2_CID_BASE
-#define V4L2_CID_USER_CLASS 		(V4L2_CTRL_CLASS_USER | 1)
+#define V4L2_CID_USER_BASE		V4L2_CID_BASE
+#define V4L2_CID_USER_CLASS		(V4L2_CTRL_CLASS_USER | 1)
 #define V4L2_CID_BRIGHTNESS		(V4L2_CID_BASE+0)
 #define V4L2_CID_CONTRAST		(V4L2_CID_BASE+1)
 #define V4L2_CID_SATURATION		(V4L2_CID_BASE+2)
@@ -102,7 +102,7 @@ enum v4l2_power_line_frequency {
 #define V4L2_CID_HUE_AUTO			(V4L2_CID_BASE+25)
 #define V4L2_CID_WHITE_BALANCE_TEMPERATURE	(V4L2_CID_BASE+26)
 #define V4L2_CID_SHARPNESS			(V4L2_CID_BASE+27)
-#define V4L2_CID_BACKLIGHT_COMPENSATION 	(V4L2_CID_BASE+28)
+#define V4L2_CID_BACKLIGHT_COMPENSATION		(V4L2_CID_BASE+28)
 #define V4L2_CID_CHROMA_AGC                     (V4L2_CID_BASE+29)
 #define V4L2_CID_COLOR_KILLER                   (V4L2_CID_BASE+30)
 #define V4L2_CID_COLORFX			(V4L2_CID_BASE+31)
@@ -194,11 +194,11 @@ enum v4l2_colorfx {
 /* The MPEG controls are applicable to all codec controls
  * and the 'MPEG' part of the define is historical */
 
-#define V4L2_CID_MPEG_BASE 			(V4L2_CTRL_CLASS_MPEG | 0x900)
-#define V4L2_CID_MPEG_CLASS 			(V4L2_CTRL_CLASS_MPEG | 1)
+#define V4L2_CID_MPEG_BASE			(V4L2_CTRL_CLASS_MPEG | 0x900)
+#define V4L2_CID_MPEG_CLASS			(V4L2_CTRL_CLASS_MPEG | 1)
 
 /*  MPEG streams, specific to multiplexed streams */
-#define V4L2_CID_MPEG_STREAM_TYPE 		(V4L2_CID_MPEG_BASE+0)
+#define V4L2_CID_MPEG_STREAM_TYPE		(V4L2_CID_MPEG_BASE+0)
 enum v4l2_mpeg_stream_type {
 	V4L2_MPEG_STREAM_TYPE_MPEG2_PS   = 0, /* MPEG-2 program stream */
 	V4L2_MPEG_STREAM_TYPE_MPEG2_TS   = 1, /* MPEG-2 transport stream */
@@ -207,26 +207,26 @@ enum v4l2_mpeg_stream_type {
 	V4L2_MPEG_STREAM_TYPE_MPEG1_VCD  = 4, /* MPEG-1 VCD-compatible stream */
 	V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */
 };
-#define V4L2_CID_MPEG_STREAM_PID_PMT 		(V4L2_CID_MPEG_BASE+1)
-#define V4L2_CID_MPEG_STREAM_PID_AUDIO 		(V4L2_CID_MPEG_BASE+2)
-#define V4L2_CID_MPEG_STREAM_PID_VIDEO 		(V4L2_CID_MPEG_BASE+3)
-#define V4L2_CID_MPEG_STREAM_PID_PCR 		(V4L2_CID_MPEG_BASE+4)
-#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO 	(V4L2_CID_MPEG_BASE+5)
-#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO 	(V4L2_CID_MPEG_BASE+6)
-#define V4L2_CID_MPEG_STREAM_VBI_FMT 		(V4L2_CID_MPEG_BASE+7)
+#define V4L2_CID_MPEG_STREAM_PID_PMT		(V4L2_CID_MPEG_BASE+1)
+#define V4L2_CID_MPEG_STREAM_PID_AUDIO		(V4L2_CID_MPEG_BASE+2)
+#define V4L2_CID_MPEG_STREAM_PID_VIDEO		(V4L2_CID_MPEG_BASE+3)
+#define V4L2_CID_MPEG_STREAM_PID_PCR		(V4L2_CID_MPEG_BASE+4)
+#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO	(V4L2_CID_MPEG_BASE+5)
+#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO	(V4L2_CID_MPEG_BASE+6)
+#define V4L2_CID_MPEG_STREAM_VBI_FMT		(V4L2_CID_MPEG_BASE+7)
 enum v4l2_mpeg_stream_vbi_fmt {
 	V4L2_MPEG_STREAM_VBI_FMT_NONE = 0,  /* No VBI in the MPEG stream */
 	V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1,  /* VBI in private packets, IVTV format */
 };
 
 /*  MPEG audio controls specific to multiplexed streams  */
-#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ 	(V4L2_CID_MPEG_BASE+100)
+#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ	(V4L2_CID_MPEG_BASE+100)
 enum v4l2_mpeg_audio_sampling_freq {
 	V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0,
 	V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1,
 	V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2,
 };
-#define V4L2_CID_MPEG_AUDIO_ENCODING 		(V4L2_CID_MPEG_BASE+101)
+#define V4L2_CID_MPEG_AUDIO_ENCODING		(V4L2_CID_MPEG_BASE+101)
 enum v4l2_mpeg_audio_encoding {
 	V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0,
 	V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1,
@@ -234,7 +234,7 @@ enum v4l2_mpeg_audio_encoding {
 	V4L2_MPEG_AUDIO_ENCODING_AAC     = 3,
 	V4L2_MPEG_AUDIO_ENCODING_AC3     = 4,
 };
-#define V4L2_CID_MPEG_AUDIO_L1_BITRATE 		(V4L2_CID_MPEG_BASE+102)
+#define V4L2_CID_MPEG_AUDIO_L1_BITRATE		(V4L2_CID_MPEG_BASE+102)
 enum v4l2_mpeg_audio_l1_bitrate {
 	V4L2_MPEG_AUDIO_L1_BITRATE_32K  = 0,
 	V4L2_MPEG_AUDIO_L1_BITRATE_64K  = 1,
@@ -251,7 +251,7 @@ enum v4l2_mpeg_audio_l1_bitrate {
 	V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12,
 	V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13,
 };
-#define V4L2_CID_MPEG_AUDIO_L2_BITRATE 		(V4L2_CID_MPEG_BASE+103)
+#define V4L2_CID_MPEG_AUDIO_L2_BITRATE		(V4L2_CID_MPEG_BASE+103)
 enum v4l2_mpeg_audio_l2_bitrate {
 	V4L2_MPEG_AUDIO_L2_BITRATE_32K  = 0,
 	V4L2_MPEG_AUDIO_L2_BITRATE_48K  = 1,
@@ -268,7 +268,7 @@ enum v4l2_mpeg_audio_l2_bitrate {
 	V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12,
 	V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13,
 };
-#define V4L2_CID_MPEG_AUDIO_L3_BITRATE 		(V4L2_CID_MPEG_BASE+104)
+#define V4L2_CID_MPEG_AUDIO_L3_BITRATE		(V4L2_CID_MPEG_BASE+104)
 enum v4l2_mpeg_audio_l3_bitrate {
 	V4L2_MPEG_AUDIO_L3_BITRATE_32K  = 0,
 	V4L2_MPEG_AUDIO_L3_BITRATE_40K  = 1,
@@ -285,32 +285,32 @@ enum v4l2_mpeg_audio_l3_bitrate {
 	V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12,
 	V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13,
 };
-#define V4L2_CID_MPEG_AUDIO_MODE 		(V4L2_CID_MPEG_BASE+105)
+#define V4L2_CID_MPEG_AUDIO_MODE		(V4L2_CID_MPEG_BASE+105)
 enum v4l2_mpeg_audio_mode {
 	V4L2_MPEG_AUDIO_MODE_STEREO       = 0,
 	V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1,
 	V4L2_MPEG_AUDIO_MODE_DUAL         = 2,
 	V4L2_MPEG_AUDIO_MODE_MONO         = 3,
 };
-#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION 	(V4L2_CID_MPEG_BASE+106)
+#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION	(V4L2_CID_MPEG_BASE+106)
 enum v4l2_mpeg_audio_mode_extension {
 	V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4  = 0,
 	V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8  = 1,
 	V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2,
 	V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3,
 };
-#define V4L2_CID_MPEG_AUDIO_EMPHASIS 		(V4L2_CID_MPEG_BASE+107)
+#define V4L2_CID_MPEG_AUDIO_EMPHASIS		(V4L2_CID_MPEG_BASE+107)
 enum v4l2_mpeg_audio_emphasis {
 	V4L2_MPEG_AUDIO_EMPHASIS_NONE         = 0,
 	V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1,
 	V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17    = 2,
 };
-#define V4L2_CID_MPEG_AUDIO_CRC 		(V4L2_CID_MPEG_BASE+108)
+#define V4L2_CID_MPEG_AUDIO_CRC			(V4L2_CID_MPEG_BASE+108)
 enum v4l2_mpeg_audio_crc {
 	V4L2_MPEG_AUDIO_CRC_NONE  = 0,
 	V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
 };
-#define V4L2_CID_MPEG_AUDIO_MUTE 		(V4L2_CID_MPEG_BASE+109)
+#define V4L2_CID_MPEG_AUDIO_MUTE		(V4L2_CID_MPEG_BASE+109)
 #define V4L2_CID_MPEG_AUDIO_AAC_BITRATE		(V4L2_CID_MPEG_BASE+110)
 #define V4L2_CID_MPEG_AUDIO_AC3_BITRATE		(V4L2_CID_MPEG_BASE+111)
 enum v4l2_mpeg_audio_ac3_bitrate {
@@ -346,33 +346,33 @@ enum v4l2_mpeg_audio_dec_playback {
 #define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113)
 
 /*  MPEG video controls specific to multiplexed streams */
-#define V4L2_CID_MPEG_VIDEO_ENCODING 		(V4L2_CID_MPEG_BASE+200)
+#define V4L2_CID_MPEG_VIDEO_ENCODING		(V4L2_CID_MPEG_BASE+200)
 enum v4l2_mpeg_video_encoding {
 	V4L2_MPEG_VIDEO_ENCODING_MPEG_1     = 0,
 	V4L2_MPEG_VIDEO_ENCODING_MPEG_2     = 1,
 	V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2,
 };
-#define V4L2_CID_MPEG_VIDEO_ASPECT 		(V4L2_CID_MPEG_BASE+201)
+#define V4L2_CID_MPEG_VIDEO_ASPECT		(V4L2_CID_MPEG_BASE+201)
 enum v4l2_mpeg_video_aspect {
 	V4L2_MPEG_VIDEO_ASPECT_1x1     = 0,
 	V4L2_MPEG_VIDEO_ASPECT_4x3     = 1,
 	V4L2_MPEG_VIDEO_ASPECT_16x9    = 2,
 	V4L2_MPEG_VIDEO_ASPECT_221x100 = 3,
 };
-#define V4L2_CID_MPEG_VIDEO_B_FRAMES 		(V4L2_CID_MPEG_BASE+202)
-#define V4L2_CID_MPEG_VIDEO_GOP_SIZE 		(V4L2_CID_MPEG_BASE+203)
-#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE 	(V4L2_CID_MPEG_BASE+204)
-#define V4L2_CID_MPEG_VIDEO_PULLDOWN 		(V4L2_CID_MPEG_BASE+205)
-#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE 	(V4L2_CID_MPEG_BASE+206)
+#define V4L2_CID_MPEG_VIDEO_B_FRAMES		(V4L2_CID_MPEG_BASE+202)
+#define V4L2_CID_MPEG_VIDEO_GOP_SIZE		(V4L2_CID_MPEG_BASE+203)
+#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE		(V4L2_CID_MPEG_BASE+204)
+#define V4L2_CID_MPEG_VIDEO_PULLDOWN		(V4L2_CID_MPEG_BASE+205)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE	(V4L2_CID_MPEG_BASE+206)
 enum v4l2_mpeg_video_bitrate_mode {
 	V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0,
 	V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1,
 };
-#define V4L2_CID_MPEG_VIDEO_BITRATE 		(V4L2_CID_MPEG_BASE+207)
-#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK 	(V4L2_CID_MPEG_BASE+208)
+#define V4L2_CID_MPEG_VIDEO_BITRATE		(V4L2_CID_MPEG_BASE+207)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK	(V4L2_CID_MPEG_BASE+208)
 #define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
-#define V4L2_CID_MPEG_VIDEO_MUTE 		(V4L2_CID_MPEG_BASE+210)
-#define V4L2_CID_MPEG_VIDEO_MUTE_YUV 		(V4L2_CID_MPEG_BASE+211)
+#define V4L2_CID_MPEG_VIDEO_MUTE		(V4L2_CID_MPEG_BASE+210)
+#define V4L2_CID_MPEG_VIDEO_MUTE_YUV		(V4L2_CID_MPEG_BASE+211)
 #define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE		(V4L2_CID_MPEG_BASE+212)
 #define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER	(V4L2_CID_MPEG_BASE+213)
 #define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB		(V4L2_CID_MPEG_BASE+214)
@@ -590,14 +590,14 @@ enum v4l2_vp8_golden_frame_sel {
 #define V4L2_CID_MPEG_VIDEO_VPX_PROFILE			(V4L2_CID_MPEG_BASE+511)
 
 /*  MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */
-#define V4L2_CID_MPEG_CX2341X_BASE 				(V4L2_CTRL_CLASS_MPEG | 0x1000)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE 	(V4L2_CID_MPEG_CX2341X_BASE+0)
+#define V4L2_CID_MPEG_CX2341X_BASE				(V4L2_CTRL_CLASS_MPEG | 0x1000)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE		(V4L2_CID_MPEG_CX2341X_BASE+0)
 enum v4l2_mpeg_cx2341x_video_spatial_filter_mode {
 	V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0,
 	V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO   = 1,
 };
-#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER 		(V4L2_CID_MPEG_CX2341X_BASE+1)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE 	(V4L2_CID_MPEG_CX2341X_BASE+2)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER		(V4L2_CID_MPEG_CX2341X_BASE+1)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE	(V4L2_CID_MPEG_CX2341X_BASE+2)
 enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type {
 	V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF                  = 0,
 	V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR               = 1,
@@ -605,18 +605,18 @@ enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type {
 	V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE      = 3,
 	V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4,
 };
-#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE 	(V4L2_CID_MPEG_CX2341X_BASE+3)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE	(V4L2_CID_MPEG_CX2341X_BASE+3)
 enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type {
 	V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF    = 0,
 	V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
 };
-#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE 	(V4L2_CID_MPEG_CX2341X_BASE+4)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE	(V4L2_CID_MPEG_CX2341X_BASE+4)
 enum v4l2_mpeg_cx2341x_video_temporal_filter_mode {
 	V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0,
 	V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO   = 1,
 };
-#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER 		(V4L2_CID_MPEG_CX2341X_BASE+5)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE 		(V4L2_CID_MPEG_CX2341X_BASE+6)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER		(V4L2_CID_MPEG_CX2341X_BASE+5)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE		(V4L2_CID_MPEG_CX2341X_BASE+6)
 enum v4l2_mpeg_cx2341x_video_median_filter_type {
 	V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF      = 0,
 	V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR      = 1,
@@ -624,11 +624,11 @@ enum v4l2_mpeg_cx2341x_video_median_filter_type {
 	V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3,
 	V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG     = 4,
 };
-#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM 	(V4L2_CID_MPEG_CX2341X_BASE+7)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP 	(V4L2_CID_MPEG_CX2341X_BASE+8)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM	(V4L2_CID_MPEG_CX2341X_BASE+7)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP	(V4L2_CID_MPEG_CX2341X_BASE+8)
 #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM	(V4L2_CID_MPEG_CX2341X_BASE+9)
-#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP 	(V4L2_CID_MPEG_CX2341X_BASE+10)
-#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS 	(V4L2_CID_MPEG_CX2341X_BASE+11)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP	(V4L2_CID_MPEG_CX2341X_BASE+10)
+#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS		(V4L2_CID_MPEG_CX2341X_BASE+11)
 
 /*  MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */
 #define V4L2_CID_MPEG_MFC51_BASE				(V4L2_CTRL_CLASS_MPEG | 0x1100)
@@ -660,8 +660,8 @@ enum v4l2_mpeg_mfc51_video_force_frame_type {
 
 /*  Camera class control IDs */
 
-#define V4L2_CID_CAMERA_CLASS_BASE 	(V4L2_CTRL_CLASS_CAMERA | 0x900)
-#define V4L2_CID_CAMERA_CLASS 		(V4L2_CTRL_CLASS_CAMERA | 1)
+#define V4L2_CID_CAMERA_CLASS_BASE	(V4L2_CTRL_CLASS_CAMERA | 0x900)
+#define V4L2_CID_CAMERA_CLASS		(V4L2_CTRL_CLASS_CAMERA | 1)
 
 #define V4L2_CID_EXPOSURE_AUTO			(V4L2_CID_CAMERA_CLASS_BASE+1)
 enum  v4l2_exposure_auto_type {
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 1c095b5..9827189 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -107,14 +107,14 @@ enum v4l2_field {
 					 transmitted first */
 };
 #define V4L2_FIELD_HAS_TOP(field)	\
-	((field) == V4L2_FIELD_TOP 	||\
+	((field) == V4L2_FIELD_TOP	||\
 	 (field) == V4L2_FIELD_INTERLACED ||\
 	 (field) == V4L2_FIELD_INTERLACED_TB ||\
 	 (field) == V4L2_FIELD_INTERLACED_BT ||\
 	 (field) == V4L2_FIELD_SEQ_TB	||\
 	 (field) == V4L2_FIELD_SEQ_BT)
 #define V4L2_FIELD_HAS_BOTTOM(field)	\
-	((field) == V4L2_FIELD_BOTTOM 	||\
+	((field) == V4L2_FIELD_BOTTOM	||\
 	 (field) == V4L2_FIELD_INTERLACED ||\
 	 (field) == V4L2_FIELD_INTERLACED_TB ||\
 	 (field) == V4L2_FIELD_INTERLACED_BT ||\
@@ -467,12 +467,12 @@ struct v4l2_capability {
  *	V I D E O   I M A G E   F O R M A T
  */
 struct v4l2_pix_format {
-	__u32         		width;
+	__u32			width;
 	__u32			height;
 	__u32			pixelformat;
 	__u32			field;		/* enum v4l2_field */
-	__u32            	bytesperline;	/* for padding, zero if unused */
-	__u32          		sizeimage;
+	__u32			bytesperline;	/* for padding, zero if unused */
+	__u32			sizeimage;
 	__u32			colorspace;	/* enum v4l2_colorspace */
 	__u32			priv;		/* private data, depends on pixelformat */
 	__u32			flags;		/* format flags (V4L2_PIX_FMT_FLAG_*) */
@@ -669,6 +669,12 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_MT21C    v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode  */
 #define V4L2_PIX_FMT_INZI     v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */
 
+/* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */
+#define V4L2_PIX_FMT_IPU3_SBGGR10	v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */
+#define V4L2_PIX_FMT_IPU3_SGBRG10	v4l2_fourcc('i', 'p', '3', 'g') /* IPU3 packed 10-bit GBRG bayer */
+#define V4L2_PIX_FMT_IPU3_SGRBG10	v4l2_fourcc('i', 'p', '3', 'G') /* IPU3 packed 10-bit GRBG bayer */
+#define V4L2_PIX_FMT_IPU3_SRGGB10	v4l2_fourcc('i', 'p', '3', 'r') /* IPU3 packed 10-bit RGGB bayer */
+
 /* SDR formats - used only for Software Defined Radio devices */
 #define V4L2_SDR_FMT_CU8          v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */
 #define V4L2_SDR_FMT_CU16LE       v4l2_fourcc('C', 'U', '1', '6') /* IQ u16le */
@@ -688,6 +694,7 @@ struct v4l2_pix_format {
 /* Meta-data formats */
 #define V4L2_META_FMT_VSP1_HGO    v4l2_fourcc('V', 'S', 'P', 'H') /* R-Car VSP1 1-D Histogram */
 #define V4L2_META_FMT_VSP1_HGT    v4l2_fourcc('V', 'S', 'P', 'T') /* R-Car VSP1 2-D Histogram */
+#define V4L2_META_FMT_UVC         v4l2_fourcc('U', 'V', 'C', 'H') /* UVC Payload Header metadata */
 
 /* priv field value to indicates that subsequent fields are valid. */
 #define V4L2_PIX_FMT_PRIV_MAGIC		0xfeedcafe
@@ -1166,7 +1173,7 @@ typedef __u64 v4l2_std_id;
 				 V4L2_STD_NTSC_M_JP     |\
 				 V4L2_STD_NTSC_M_KR)
 /* Secam macros */
-#define V4L2_STD_SECAM_DK      	(V4L2_STD_SECAM_D	|\
+#define V4L2_STD_SECAM_DK	(V4L2_STD_SECAM_D	|\
 				 V4L2_STD_SECAM_K	|\
 				 V4L2_STD_SECAM_K1)
 /* All Secam Standards */
@@ -1247,7 +1254,7 @@ struct v4l2_standard {
 };
 
 /*
- *	D V 	B T	T I M I N G S
+ *	D V	B T	T I M I N G S
  */
 
 /** struct v4l2_bt_timings - BT.656/BT.1120 timing data
@@ -1588,7 +1595,7 @@ struct v4l2_ext_controls {
 	struct v4l2_ext_control *controls;
 };
 
-#define V4L2_CTRL_ID_MASK      	  (0x0fffffff)
+#define V4L2_CTRL_ID_MASK	  (0x0fffffff)
 #ifndef __KERNEL__
 #define V4L2_CTRL_ID2CLASS(id)    ((id) & 0x0fff0000UL)
 #endif
@@ -1660,11 +1667,11 @@ struct v4l2_querymenu {
 /*  Control flags  */
 #define V4L2_CTRL_FLAG_DISABLED		0x0001
 #define V4L2_CTRL_FLAG_GRABBED		0x0002
-#define V4L2_CTRL_FLAG_READ_ONLY 	0x0004
-#define V4L2_CTRL_FLAG_UPDATE 		0x0008
-#define V4L2_CTRL_FLAG_INACTIVE 	0x0010
-#define V4L2_CTRL_FLAG_SLIDER 		0x0020
-#define V4L2_CTRL_FLAG_WRITE_ONLY 	0x0040
+#define V4L2_CTRL_FLAG_READ_ONLY	0x0004
+#define V4L2_CTRL_FLAG_UPDATE		0x0008
+#define V4L2_CTRL_FLAG_INACTIVE		0x0010
+#define V4L2_CTRL_FLAG_SLIDER		0x0020
+#define V4L2_CTRL_FLAG_WRITE_ONLY	0x0040
 #define V4L2_CTRL_FLAG_VOLATILE		0x0080
 #define V4L2_CTRL_FLAG_HAS_PAYLOAD	0x0100
 #define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE	0x0200
@@ -1778,21 +1785,21 @@ struct v4l2_hw_freq_seek {
  */
 
 struct v4l2_rds_data {
-	__u8 	lsb;
-	__u8 	msb;
-	__u8 	block;
+	__u8	lsb;
+	__u8	msb;
+	__u8	block;
 } __attribute__ ((packed));
 
-#define V4L2_RDS_BLOCK_MSK 	 0x7
-#define V4L2_RDS_BLOCK_A 	 0
-#define V4L2_RDS_BLOCK_B 	 1
-#define V4L2_RDS_BLOCK_C 	 2
-#define V4L2_RDS_BLOCK_D 	 3
-#define V4L2_RDS_BLOCK_C_ALT 	 4
-#define V4L2_RDS_BLOCK_INVALID 	 7
+#define V4L2_RDS_BLOCK_MSK	 0x7
+#define V4L2_RDS_BLOCK_A	 0
+#define V4L2_RDS_BLOCK_B	 1
+#define V4L2_RDS_BLOCK_C	 2
+#define V4L2_RDS_BLOCK_D	 3
+#define V4L2_RDS_BLOCK_C_ALT	 4
+#define V4L2_RDS_BLOCK_INVALID	 7
 
 #define V4L2_RDS_BLOCK_CORRECTED 0x40
-#define V4L2_RDS_BLOCK_ERROR 	 0x80
+#define V4L2_RDS_BLOCK_ERROR	 0x80
 
 /*
  *	A U D I O
@@ -2348,8 +2355,8 @@ struct v4l2_create_buffers {
 #define VIDIOC_S_CROP		 _IOW('V', 60, struct v4l2_crop)
 #define VIDIOC_G_JPEGCOMP	 _IOR('V', 61, struct v4l2_jpegcompression)
 #define VIDIOC_S_JPEGCOMP	 _IOW('V', 62, struct v4l2_jpegcompression)
-#define VIDIOC_QUERYSTD      	 _IOR('V', 63, v4l2_std_id)
-#define VIDIOC_TRY_FMT      	_IOWR('V', 64, struct v4l2_format)
+#define VIDIOC_QUERYSTD		 _IOR('V', 63, v4l2_std_id)
+#define VIDIOC_TRY_FMT		_IOWR('V', 64, struct v4l2_format)
 #define VIDIOC_ENUMAUDIO	_IOWR('V', 65, struct v4l2_audio)
 #define VIDIOC_ENUMAUDOUT	_IOWR('V', 66, struct v4l2_audioout)
 #define VIDIOC_G_PRIORITY	 _IOR('V', 67, __u32) /* enum v4l2_priority */
@@ -2370,8 +2377,8 @@ struct v4l2_create_buffers {
  * Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined.
  * You must be root to use these ioctls. Never use these in applications!
  */
-#define	VIDIOC_DBG_S_REGISTER 	 _IOW('V', 79, struct v4l2_dbg_register)
-#define	VIDIOC_DBG_G_REGISTER 	_IOWR('V', 80, struct v4l2_dbg_register)
+#define	VIDIOC_DBG_S_REGISTER	 _IOW('V', 79, struct v4l2_dbg_register)
+#define	VIDIOC_DBG_G_REGISTER	_IOWR('V', 80, struct v4l2_dbg_register)
 
 #define VIDIOC_S_HW_FREQ_SEEK	 _IOW('V', 82, struct v4l2_hw_freq_seek)
 #define	VIDIOC_S_DV_TIMINGS	_IOWR('V', 87, struct v4l2_dv_timings)
diff --git a/include/uapi/linux/virtio_balloon.h b/include/uapi/linux/virtio_balloon.h
index 343d7dd..4e8b830 100644
--- a/include/uapi/linux/virtio_balloon.h
+++ b/include/uapi/linux/virtio_balloon.h
@@ -52,7 +52,8 @@ struct virtio_balloon_config {
 #define VIRTIO_BALLOON_S_MEMFREE  4   /* Total amount of free memory */
 #define VIRTIO_BALLOON_S_MEMTOT   5   /* Total amount of memory */
 #define VIRTIO_BALLOON_S_AVAIL    6   /* Available memory as in /proc */
-#define VIRTIO_BALLOON_S_NR       7
+#define VIRTIO_BALLOON_S_CACHES   7   /* Disk caches */
+#define VIRTIO_BALLOON_S_NR       8
 
 /*
  * Memory statistics structure.
diff --git a/include/uapi/rdma/rdma_netlink.h b/include/uapi/rdma/rdma_netlink.h
index 17e59be..4c77e2a 100644
--- a/include/uapi/rdma/rdma_netlink.h
+++ b/include/uapi/rdma/rdma_netlink.h
@@ -227,16 +227,14 @@ enum rdma_nldev_command {
 	RDMA_NLDEV_CMD_UNSPEC,
 
 	RDMA_NLDEV_CMD_GET, /* can dump */
-	RDMA_NLDEV_CMD_SET,
-	RDMA_NLDEV_CMD_NEW,
-	RDMA_NLDEV_CMD_DEL,
 
-	RDMA_NLDEV_CMD_PORT_GET, /* can dump */
-	RDMA_NLDEV_CMD_PORT_SET,
-	RDMA_NLDEV_CMD_PORT_NEW,
-	RDMA_NLDEV_CMD_PORT_DEL,
+	/* 2 - 4 are free to use */
 
-	RDMA_NLDEV_CMD_RES_GET, /* can dump */
+	RDMA_NLDEV_CMD_PORT_GET = 5, /* can dump */
+
+	/* 6 - 8 are free to use */
+
+	RDMA_NLDEV_CMD_RES_GET = 9, /* can dump */
 
 	RDMA_NLDEV_CMD_RES_QP_GET, /* can dump */
 
diff --git a/include/video/udlfb.h b/include/video/udlfb.h
index 1252a7a..0cabe6b 100644
--- a/include/video/udlfb.h
+++ b/include/video/udlfb.h
@@ -19,7 +19,7 @@ struct dloarea {
 
 struct urb_node {
 	struct list_head entry;
-	struct dlfb_data *dev;
+	struct dlfb_data *dlfb;
 	struct delayed_work release_urb_work;
 	struct urb *urb;
 };
@@ -35,7 +35,6 @@ struct urb_list {
 
 struct dlfb_data {
 	struct usb_device *udev;
-	struct device *gdev; /* &udev->dev */
 	struct fb_info *info;
 	struct urb_list urbs;
 	struct kref kref;
diff --git a/init/Kconfig b/init/Kconfig
index a9a2e2c..e37f4b2 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1412,6 +1412,12 @@
 	  Enable the userfaultfd() system call that allows to intercept and
 	  handle page faults in userland.
 
+config ARCH_HAS_MEMBARRIER_CALLBACKS
+	bool
+
+config ARCH_HAS_MEMBARRIER_SYNC_CORE
+	bool
+
 config EMBEDDED
 	bool "Embedded system"
 	option allnoconfig_y
@@ -1915,3 +1921,6 @@
 	  functions to call on what tags.
 
 source "kernel/Kconfig.locks"
+
+config ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
+	bool
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 690ae66..360e564 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -596,7 +596,7 @@ static void wq_add(struct mqueue_inode_info *info, int sr,
 	ewp->task = current;
 
 	list_for_each_entry(walk, &info->e_wait_q[sr].list, list) {
-		if (walk->task->static_prio <= current->static_prio) {
+		if (walk->task->prio <= current->prio) {
 			list_add_tail(&ewp->list, &walk->list);
 			return;
 		}
diff --git a/ipc/msg.c b/ipc/msg.c
index 1bbc029..0dcc669 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -476,9 +476,9 @@ static int msgctl_info(struct ipc_namespace *ns, int msqid,
 static int msgctl_stat(struct ipc_namespace *ns, int msqid,
 			 int cmd, struct msqid64_ds *p)
 {
-	int err;
 	struct msg_queue *msq;
-	int success_return;
+	int id = 0;
+	int err;
 
 	memset(p, 0, sizeof(*p));
 
@@ -489,14 +489,13 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
 			err = PTR_ERR(msq);
 			goto out_unlock;
 		}
-		success_return = msq->q_perm.id;
+		id = msq->q_perm.id;
 	} else {
 		msq = msq_obtain_object_check(ns, msqid);
 		if (IS_ERR(msq)) {
 			err = PTR_ERR(msq);
 			goto out_unlock;
 		}
-		success_return = 0;
 	}
 
 	err = -EACCES;
@@ -507,6 +506,14 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
 	if (err)
 		goto out_unlock;
 
+	ipc_lock_object(&msq->q_perm);
+
+	if (!ipc_valid_object(&msq->q_perm)) {
+		ipc_unlock_object(&msq->q_perm);
+		err = -EIDRM;
+		goto out_unlock;
+	}
+
 	kernel_to_ipc64_perm(&msq->q_perm, &p->msg_perm);
 	p->msg_stime  = msq->q_stime;
 	p->msg_rtime  = msq->q_rtime;
@@ -516,9 +523,10 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
 	p->msg_qbytes = msq->q_qbytes;
 	p->msg_lspid  = msq->q_lspid;
 	p->msg_lrpid  = msq->q_lrpid;
-	rcu_read_unlock();
 
-	return success_return;
+	ipc_unlock_object(&msq->q_perm);
+	rcu_read_unlock();
+	return id;
 
 out_unlock:
 	rcu_read_unlock();
diff --git a/ipc/sem.c b/ipc/sem.c
index 87bd38f..a4af049 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1213,10 +1213,20 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
 	if (err)
 		goto out_unlock;
 
+	ipc_lock_object(&sma->sem_perm);
+
+	if (!ipc_valid_object(&sma->sem_perm)) {
+		ipc_unlock_object(&sma->sem_perm);
+		err = -EIDRM;
+		goto out_unlock;
+	}
+
 	kernel_to_ipc64_perm(&sma->sem_perm, &semid64->sem_perm);
 	semid64->sem_otime = get_semotime(sma);
 	semid64->sem_ctime = sma->sem_ctime;
 	semid64->sem_nsems = sma->sem_nsems;
+
+	ipc_unlock_object(&sma->sem_perm);
 	rcu_read_unlock();
 	return id;
 
diff --git a/ipc/shm.c b/ipc/shm.c
index 7acda23..4643865 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -909,9 +909,11 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
 			int cmd, struct shmid64_ds *tbuf)
 {
 	struct shmid_kernel *shp;
-	int result;
+	int id = 0;
 	int err;
 
+	memset(tbuf, 0, sizeof(*tbuf));
+
 	rcu_read_lock();
 	if (cmd == SHM_STAT) {
 		shp = shm_obtain_object(ns, shmid);
@@ -919,14 +921,13 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
 			err = PTR_ERR(shp);
 			goto out_unlock;
 		}
-		result = shp->shm_perm.id;
+		id = shp->shm_perm.id;
 	} else {
 		shp = shm_obtain_object_check(ns, shmid);
 		if (IS_ERR(shp)) {
 			err = PTR_ERR(shp);
 			goto out_unlock;
 		}
-		result = 0;
 	}
 
 	err = -EACCES;
@@ -937,7 +938,14 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
 	if (err)
 		goto out_unlock;
 
-	memset(tbuf, 0, sizeof(*tbuf));
+	ipc_lock_object(&shp->shm_perm);
+
+	if (!ipc_valid_object(&shp->shm_perm)) {
+		ipc_unlock_object(&shp->shm_perm);
+		err = -EIDRM;
+		goto out_unlock;
+	}
+
 	kernel_to_ipc64_perm(&shp->shm_perm, &tbuf->shm_perm);
 	tbuf->shm_segsz	= shp->shm_segsz;
 	tbuf->shm_atime	= shp->shm_atim;
@@ -946,8 +954,10 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
 	tbuf->shm_cpid	= shp->shm_cprid;
 	tbuf->shm_lpid	= shp->shm_lprid;
 	tbuf->shm_nattch = shp->shm_nattch;
+
+	ipc_unlock_object(&shp->shm_perm);
 	rcu_read_unlock();
-	return result;
+	return id;
 
 out_unlock:
 	rcu_read_unlock();
diff --git a/ipc/util.c b/ipc/util.c
index ff045fe..4ed5a17 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -23,9 +23,12 @@
  *	    tree.
  *	    - perform initial checks (capabilities, auditing and permission,
  *	      etc).
- *	    - perform read-only operations, such as STAT, INFO commands.
+ *	    - perform read-only operations, such as INFO command, that
+ *	      do not demand atomicity
  *	      acquire the ipc lock (kern_ipc_perm.lock) through
  *	      ipc_lock_object()
+ *		- perform read-only operations that demand atomicity,
+ *		  such as STAT command.
  *		- perform data updates, such as SET, RMID commands and
  *		  mechanism-specific operations (semop/semtimedop,
  *		  msgsnd/msgrcv, shmat/shmdt).
diff --git a/kernel/async.c b/kernel/async.c
index 2cbd3dd..a893d61 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -84,20 +84,24 @@ static atomic_t entry_count;
 
 static async_cookie_t lowest_in_progress(struct async_domain *domain)
 {
-	struct list_head *pending;
+	struct async_entry *first = NULL;
 	async_cookie_t ret = ASYNC_COOKIE_MAX;
 	unsigned long flags;
 
 	spin_lock_irqsave(&async_lock, flags);
 
-	if (domain)
-		pending = &domain->pending;
-	else
-		pending = &async_global_pending;
+	if (domain) {
+		if (!list_empty(&domain->pending))
+			first = list_first_entry(&domain->pending,
+					struct async_entry, domain_list);
+	} else {
+		if (!list_empty(&async_global_pending))
+			first = list_first_entry(&async_global_pending,
+					struct async_entry, global_list);
+	}
 
-	if (!list_empty(pending))
-		ret = list_first_entry(pending, struct async_entry,
-				       domain_list)->cookie;
+	if (first)
+		ret = first->cookie;
 
 	spin_unlock_irqrestore(&async_lock, flags);
 	return ret;
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 5f35f93..29ca920 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1576,25 +1576,41 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
 				__u32 __user *prog_ids, u32 cnt)
 {
 	struct bpf_prog **prog;
-	u32 i = 0, id;
+	unsigned long err = 0;
+	u32 i = 0, *ids;
+	bool nospc;
 
+	/* users of this function are doing:
+	 * cnt = bpf_prog_array_length();
+	 * if (cnt > 0)
+	 *     bpf_prog_array_copy_to_user(..., cnt);
+	 * so below kcalloc doesn't need extra cnt > 0 check, but
+	 * bpf_prog_array_length() releases rcu lock and
+	 * prog array could have been swapped with empty or larger array,
+	 * so always copy 'cnt' prog_ids to the user.
+	 * In a rare race the user will see zero prog_ids
+	 */
+	ids = kcalloc(cnt, sizeof(u32), GFP_USER);
+	if (!ids)
+		return -ENOMEM;
 	rcu_read_lock();
 	prog = rcu_dereference(progs)->progs;
 	for (; *prog; prog++) {
 		if (*prog == &dummy_bpf_prog.prog)
 			continue;
-		id = (*prog)->aux->id;
-		if (copy_to_user(prog_ids + i, &id, sizeof(id))) {
-			rcu_read_unlock();
-			return -EFAULT;
-		}
+		ids[i] = (*prog)->aux->id;
 		if (++i == cnt) {
 			prog++;
 			break;
 		}
 	}
+	nospc = !!(*prog);
 	rcu_read_unlock();
-	if (*prog)
+	err = copy_to_user(prog_ids, ids, cnt * sizeof(u32));
+	kfree(ids);
+	if (err)
+		return -EFAULT;
+	if (nospc)
 		return -ENOSPC;
 	return 0;
 }
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index f7efa7b..b42037e 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1254,9 +1254,9 @@ static int update_nodemask(struct cpuset *cs, struct cpuset *trialcs,
 	return retval;
 }
 
-int current_cpuset_is_being_rebound(void)
+bool current_cpuset_is_being_rebound(void)
 {
-	int ret;
+	bool ret;
 
 	rcu_read_lock();
 	ret = task_cs(current) == cpuset_being_rebound;
diff --git a/kernel/compat.c b/kernel/compat.c
index d1cee65..3247fe7 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -355,7 +355,7 @@ COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t,  pid, unsigned int, len,
 
 	ret = sched_getaffinity(pid, mask);
 	if (ret == 0) {
-		size_t retlen = min_t(size_t, len, cpumask_size());
+		unsigned int retlen = min(len, cpumask_size());
 
 		if (compat_put_bitmap(user_mask_ptr, cpumask_bits(mask), retlen * 8))
 			ret = -EFAULT;
diff --git a/kernel/configs/tiny.config b/kernel/configs/tiny.config
index 7fa0c4a..9bfdffc 100644
--- a/kernel/configs/tiny.config
+++ b/kernel/configs/tiny.config
@@ -10,3 +10,7 @@
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
+CONFIG_CC_STACKPROTECTOR_NONE=y
+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
+# CONFIG_CC_STACKPROTECTOR_STRONG is not set
+# CONFIG_CC_STACKPROTECTOR_AUTO is not set
diff --git a/kernel/fork.c b/kernel/fork.c
index 5c372c9..be8aa5b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -606,6 +606,11 @@ static void __mmdrop(struct mm_struct *mm)
 
 void mmdrop(struct mm_struct *mm)
 {
+	/*
+	 * The implicit full barrier implied by atomic_dec_and_test() is
+	 * required by the membarrier system call before returning to
+	 * user-space, after storing to rq->curr.
+	 */
 	if (unlikely(atomic_dec_and_test(&mm->mm_count)))
 		__mmdrop(mm);
 }
@@ -1587,6 +1592,10 @@ static __latent_entropy struct task_struct *copy_process(
 	int retval;
 	struct task_struct *p;
 
+	/*
+	 * Don't allow sharing the root directory with processes in a different
+	 * namespace
+	 */
 	if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
 		return ERR_PTR(-EINVAL);
 
@@ -2062,6 +2071,8 @@ long _do_fork(unsigned long clone_flags,
 	      int __user *child_tidptr,
 	      unsigned long tls)
 {
+	struct completion vfork;
+	struct pid *pid;
 	struct task_struct *p;
 	int trace = 0;
 	long nr;
@@ -2087,43 +2098,40 @@ long _do_fork(unsigned long clone_flags,
 	p = copy_process(clone_flags, stack_start, stack_size,
 			 child_tidptr, NULL, trace, tls, NUMA_NO_NODE);
 	add_latent_entropy();
+
+	if (IS_ERR(p))
+		return PTR_ERR(p);
+
 	/*
 	 * Do this prior waking up the new thread - the thread pointer
 	 * might get invalid after that point, if the thread exits quickly.
 	 */
-	if (!IS_ERR(p)) {
-		struct completion vfork;
-		struct pid *pid;
+	trace_sched_process_fork(current, p);
 
-		trace_sched_process_fork(current, p);
+	pid = get_task_pid(p, PIDTYPE_PID);
+	nr = pid_vnr(pid);
 
-		pid = get_task_pid(p, PIDTYPE_PID);
-		nr = pid_vnr(pid);
+	if (clone_flags & CLONE_PARENT_SETTID)
+		put_user(nr, parent_tidptr);
 
-		if (clone_flags & CLONE_PARENT_SETTID)
-			put_user(nr, parent_tidptr);
-
-		if (clone_flags & CLONE_VFORK) {
-			p->vfork_done = &vfork;
-			init_completion(&vfork);
-			get_task_struct(p);
-		}
-
-		wake_up_new_task(p);
-
-		/* forking complete and child started to run, tell ptracer */
-		if (unlikely(trace))
-			ptrace_event_pid(trace, pid);
-
-		if (clone_flags & CLONE_VFORK) {
-			if (!wait_for_vfork_done(p, &vfork))
-				ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid);
-		}
-
-		put_pid(pid);
-	} else {
-		nr = PTR_ERR(p);
+	if (clone_flags & CLONE_VFORK) {
+		p->vfork_done = &vfork;
+		init_completion(&vfork);
+		get_task_struct(p);
 	}
+
+	wake_up_new_task(p);
+
+	/* forking complete and child started to run, tell ptracer */
+	if (unlikely(trace))
+		ptrace_event_pid(trace, pid);
+
+	if (clone_flags & CLONE_VFORK) {
+		if (!wait_for_vfork_done(p, &vfork))
+			ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid);
+	}
+
+	put_pid(pid);
 	return nr;
 }
 
diff --git a/kernel/futex.c b/kernel/futex.c
index 7f719d1..1f450e0 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -862,24 +862,6 @@ static void put_pi_state(struct futex_pi_state *pi_state)
 	}
 }
 
-/*
- * Look up the task based on what TID userspace gave us.
- * We dont trust it.
- */
-static struct task_struct *futex_find_get_task(pid_t pid)
-{
-	struct task_struct *p;
-
-	rcu_read_lock();
-	p = find_task_by_vpid(pid);
-	if (p)
-		get_task_struct(p);
-
-	rcu_read_unlock();
-
-	return p;
-}
-
 #ifdef CONFIG_FUTEX_PI
 
 /*
@@ -1183,7 +1165,7 @@ static int attach_to_pi_owner(u32 uval, union futex_key *key,
 	 */
 	if (!pid)
 		return -ESRCH;
-	p = futex_find_get_task(pid);
+	p = find_get_task_by_vpid(pid);
 	if (!p)
 		return -ESRCH;
 
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index ef2a47e..6cdecc6 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -10,7 +10,6 @@
 #include <linux/jiffies.h>
 #include <linux/irq.h>
 #include <linux/module.h>
-#include <linux/kallsyms.h>
 #include <linux/interrupt.h>
 #include <linux/moduleparam.h>
 #include <linux/timer.h>
diff --git a/kernel/kcov.c b/kernel/kcov.c
index 7594c03..2c16f1a 100644
--- a/kernel/kcov.c
+++ b/kernel/kcov.c
@@ -358,7 +358,8 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
 		 */
 		if (kcov->mode != KCOV_MODE_INIT || !kcov->area)
 			return -EINVAL;
-		if (kcov->t != NULL)
+		t = current;
+		if (kcov->t != NULL || t->kcov != NULL)
 			return -EBUSY;
 		if (arg == KCOV_TRACE_PC)
 			kcov->mode = KCOV_MODE_TRACE_PC;
@@ -370,7 +371,6 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
 #endif
 		else
 			return -EINVAL;
-		t = current;
 		/* Cache in task struct for performance. */
 		t->kcov_size = kcov->size;
 		t->kcov_area = kcov->area;
diff --git a/kernel/memremap.c b/kernel/memremap.c
index 403ab9c..4849be5 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -188,13 +188,6 @@ static RADIX_TREE(pgmap_radix, GFP_KERNEL);
 #define SECTION_MASK ~((1UL << PA_SECTION_SHIFT) - 1)
 #define SECTION_SIZE (1UL << PA_SECTION_SHIFT)
 
-struct page_map {
-	struct resource res;
-	struct percpu_ref *ref;
-	struct dev_pagemap pgmap;
-	struct vmem_altmap altmap;
-};
-
 static unsigned long order_at(struct resource *res, unsigned long pgoff)
 {
 	unsigned long phys_pgoff = PHYS_PFN(res->start) + pgoff;
@@ -248,34 +241,36 @@ int device_private_entry_fault(struct vm_area_struct *vma,
 EXPORT_SYMBOL(device_private_entry_fault);
 #endif /* CONFIG_DEVICE_PRIVATE */
 
-static void pgmap_radix_release(struct resource *res)
+static void pgmap_radix_release(struct resource *res, unsigned long end_pgoff)
 {
 	unsigned long pgoff, order;
 
 	mutex_lock(&pgmap_lock);
-	foreach_order_pgoff(res, order, pgoff)
+	foreach_order_pgoff(res, order, pgoff) {
+		if (pgoff >= end_pgoff)
+			break;
 		radix_tree_delete(&pgmap_radix, PHYS_PFN(res->start) + pgoff);
+	}
 	mutex_unlock(&pgmap_lock);
 
 	synchronize_rcu();
 }
 
-static unsigned long pfn_first(struct page_map *page_map)
+static unsigned long pfn_first(struct dev_pagemap *pgmap)
 {
-	struct dev_pagemap *pgmap = &page_map->pgmap;
-	const struct resource *res = &page_map->res;
-	struct vmem_altmap *altmap = pgmap->altmap;
+	const struct resource *res = &pgmap->res;
+	struct vmem_altmap *altmap = &pgmap->altmap;
 	unsigned long pfn;
 
 	pfn = res->start >> PAGE_SHIFT;
-	if (altmap)
+	if (pgmap->altmap_valid)
 		pfn += vmem_altmap_offset(altmap);
 	return pfn;
 }
 
-static unsigned long pfn_end(struct page_map *page_map)
+static unsigned long pfn_end(struct dev_pagemap *pgmap)
 {
-	const struct resource *res = &page_map->res;
+	const struct resource *res = &pgmap->res;
 
 	return (res->start + resource_size(res)) >> PAGE_SHIFT;
 }
@@ -283,15 +278,15 @@ static unsigned long pfn_end(struct page_map *page_map)
 #define for_each_device_pfn(pfn, map) \
 	for (pfn = pfn_first(map); pfn < pfn_end(map); pfn++)
 
-static void devm_memremap_pages_release(struct device *dev, void *data)
+static void devm_memremap_pages_release(void *data)
 {
-	struct page_map *page_map = data;
-	struct resource *res = &page_map->res;
+	struct dev_pagemap *pgmap = data;
+	struct device *dev = pgmap->dev;
+	struct resource *res = &pgmap->res;
 	resource_size_t align_start, align_size;
-	struct dev_pagemap *pgmap = &page_map->pgmap;
 	unsigned long pfn;
 
-	for_each_device_pfn(pfn, page_map)
+	for_each_device_pfn(pfn, pgmap)
 		put_page(pfn_to_page(pfn));
 
 	if (percpu_ref_tryget_live(pgmap->ref)) {
@@ -301,56 +296,51 @@ static void devm_memremap_pages_release(struct device *dev, void *data)
 
 	/* pages are dead and unused, undo the arch mapping */
 	align_start = res->start & ~(SECTION_SIZE - 1);
-	align_size = ALIGN(resource_size(res), SECTION_SIZE);
+	align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
+		- align_start;
 
 	mem_hotplug_begin();
-	arch_remove_memory(align_start, align_size);
+	arch_remove_memory(align_start, align_size, pgmap->altmap_valid ?
+			&pgmap->altmap : NULL);
 	mem_hotplug_done();
 
 	untrack_pfn(NULL, PHYS_PFN(align_start), align_size);
-	pgmap_radix_release(res);
-	dev_WARN_ONCE(dev, pgmap->altmap && pgmap->altmap->alloc,
-			"%s: failed to free all reserved pages\n", __func__);
-}
-
-/* assumes rcu_read_lock() held at entry */
-struct dev_pagemap *find_dev_pagemap(resource_size_t phys)
-{
-	struct page_map *page_map;
-
-	WARN_ON_ONCE(!rcu_read_lock_held());
-
-	page_map = radix_tree_lookup(&pgmap_radix, PHYS_PFN(phys));
-	return page_map ? &page_map->pgmap : NULL;
+	pgmap_radix_release(res, -1);
+	dev_WARN_ONCE(dev, pgmap->altmap.alloc,
+		      "%s: failed to free all reserved pages\n", __func__);
 }
 
 /**
  * devm_memremap_pages - remap and provide memmap backing for the given resource
  * @dev: hosting device for @res
- * @res: "host memory" address range
- * @ref: a live per-cpu reference count
- * @altmap: optional descriptor for allocating the memmap from @res
+ * @pgmap: pointer to a struct dev_pgmap
  *
  * Notes:
- * 1/ @ref must be 'live' on entry and 'dead' before devm_memunmap_pages() time
- *    (or devm release event). The expected order of events is that @ref has
+ * 1/ At a minimum the res, ref and type members of @pgmap must be initialized
+ *    by the caller before passing it to this function
+ *
+ * 2/ The altmap field may optionally be initialized, in which case altmap_valid
+ *    must be set to true
+ *
+ * 3/ pgmap.ref must be 'live' on entry and 'dead' before devm_memunmap_pages()
+ *    time (or devm release event). The expected order of events is that ref has
  *    been through percpu_ref_kill() before devm_memremap_pages_release(). The
  *    wait for the completion of all references being dropped and
  *    percpu_ref_exit() must occur after devm_memremap_pages_release().
  *
- * 2/ @res is expected to be a host memory range that could feasibly be
+ * 4/ res is expected to be a host memory range that could feasibly be
  *    treated as a "System RAM" range, i.e. not a device mmio range, but
  *    this is not enforced.
  */
-void *devm_memremap_pages(struct device *dev, struct resource *res,
-		struct percpu_ref *ref, struct vmem_altmap *altmap)
+void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
 {
 	resource_size_t align_start, align_size, align_end;
+	struct vmem_altmap *altmap = pgmap->altmap_valid ?
+			&pgmap->altmap : NULL;
 	unsigned long pfn, pgoff, order;
 	pgprot_t pgprot = PAGE_KERNEL;
-	struct dev_pagemap *pgmap;
-	struct page_map *page_map;
 	int error, nid, is_ram, i = 0;
+	struct resource *res = &pgmap->res;
 
 	align_start = res->start & ~(SECTION_SIZE - 1);
 	align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
@@ -367,47 +357,18 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
 	if (is_ram == REGION_INTERSECTS)
 		return __va(res->start);
 
-	if (!ref)
+	if (!pgmap->ref)
 		return ERR_PTR(-EINVAL);
 
-	page_map = devres_alloc_node(devm_memremap_pages_release,
-			sizeof(*page_map), GFP_KERNEL, dev_to_node(dev));
-	if (!page_map)
-		return ERR_PTR(-ENOMEM);
-	pgmap = &page_map->pgmap;
-
-	memcpy(&page_map->res, res, sizeof(*res));
-
 	pgmap->dev = dev;
-	if (altmap) {
-		memcpy(&page_map->altmap, altmap, sizeof(*altmap));
-		pgmap->altmap = &page_map->altmap;
-	}
-	pgmap->ref = ref;
-	pgmap->res = &page_map->res;
-	pgmap->type = MEMORY_DEVICE_HOST;
-	pgmap->page_fault = NULL;
-	pgmap->page_free = NULL;
-	pgmap->data = NULL;
 
 	mutex_lock(&pgmap_lock);
 	error = 0;
 	align_end = align_start + align_size - 1;
 
 	foreach_order_pgoff(res, order, pgoff) {
-		struct dev_pagemap *dup;
-
-		rcu_read_lock();
-		dup = find_dev_pagemap(res->start + PFN_PHYS(pgoff));
-		rcu_read_unlock();
-		if (dup) {
-			dev_err(dev, "%s: %pr collides with mapping for %s\n",
-					__func__, res, dev_name(dup->dev));
-			error = -EBUSY;
-			break;
-		}
 		error = __radix_tree_insert(&pgmap_radix,
-				PHYS_PFN(res->start) + pgoff, order, page_map);
+				PHYS_PFN(res->start) + pgoff, order, pgmap);
 		if (error) {
 			dev_err(dev, "%s: failed: %d\n", __func__, error);
 			break;
@@ -427,16 +388,16 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
 		goto err_pfn_remap;
 
 	mem_hotplug_begin();
-	error = arch_add_memory(nid, align_start, align_size, false);
+	error = arch_add_memory(nid, align_start, align_size, altmap, false);
 	if (!error)
 		move_pfn_range_to_zone(&NODE_DATA(nid)->node_zones[ZONE_DEVICE],
 					align_start >> PAGE_SHIFT,
-					align_size >> PAGE_SHIFT);
+					align_size >> PAGE_SHIFT, altmap);
 	mem_hotplug_done();
 	if (error)
 		goto err_add_memory;
 
-	for_each_device_pfn(pfn, page_map) {
+	for_each_device_pfn(pfn, pgmap) {
 		struct page *page = pfn_to_page(pfn);
 
 		/*
@@ -447,19 +408,21 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
 		 */
 		list_del(&page->lru);
 		page->pgmap = pgmap;
-		percpu_ref_get(ref);
+		percpu_ref_get(pgmap->ref);
 		if (!(++i % 1024))
 			cond_resched();
 	}
-	devres_add(dev, page_map);
+
+	devm_add_action(dev, devm_memremap_pages_release, pgmap);
+
 	return __va(res->start);
 
  err_add_memory:
 	untrack_pfn(NULL, PHYS_PFN(align_start), align_size);
  err_pfn_remap:
  err_radix:
-	pgmap_radix_release(res);
-	devres_free(page_map);
+	pgmap_radix_release(res, pgoff);
+	devres_free(pgmap);
 	return ERR_PTR(error);
 }
 EXPORT_SYMBOL(devm_memremap_pages);
@@ -475,34 +438,39 @@ void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns)
 	altmap->alloc -= nr_pfns;
 }
 
-struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start)
+/**
+ * get_dev_pagemap() - take a new live reference on the dev_pagemap for @pfn
+ * @pfn: page frame number to lookup page_map
+ * @pgmap: optional known pgmap that already has a reference
+ *
+ * If @pgmap is non-NULL and covers @pfn it will be returned as-is.  If @pgmap
+ * is non-NULL but does not cover @pfn the reference to it will be released.
+ */
+struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
+		struct dev_pagemap *pgmap)
 {
-	/*
-	 * 'memmap_start' is the virtual address for the first "struct
-	 * page" in this range of the vmemmap array.  In the case of
-	 * CONFIG_SPARSEMEM_VMEMMAP a page_to_pfn conversion is simple
-	 * pointer arithmetic, so we can perform this to_vmem_altmap()
-	 * conversion without concern for the initialization state of
-	 * the struct page fields.
-	 */
-	struct page *page = (struct page *) memmap_start;
-	struct dev_pagemap *pgmap;
+	resource_size_t phys = PFN_PHYS(pfn);
 
 	/*
-	 * Unconditionally retrieve a dev_pagemap associated with the
-	 * given physical address, this is only for use in the
-	 * arch_{add|remove}_memory() for setting up and tearing down
-	 * the memmap.
+	 * In the cached case we're already holding a live reference.
 	 */
+	if (pgmap) {
+		if (phys >= pgmap->res.start && phys <= pgmap->res.end)
+			return pgmap;
+		put_dev_pagemap(pgmap);
+	}
+
+	/* fall back to slow path lookup */
 	rcu_read_lock();
-	pgmap = find_dev_pagemap(__pfn_to_phys(page_to_pfn(page)));
+	pgmap = radix_tree_lookup(&pgmap_radix, PHYS_PFN(phys));
+	if (pgmap && !percpu_ref_tryget_live(pgmap->ref))
+		pgmap = NULL;
 	rcu_read_unlock();
 
-	return pgmap ? pgmap->altmap : NULL;
+	return pgmap;
 }
 #endif /* CONFIG_ZONE_DEVICE */
 
-
 #if IS_ENABLED(CONFIG_DEVICE_PRIVATE) ||  IS_ENABLED(CONFIG_DEVICE_PUBLIC)
 void put_zone_device_private_or_public_page(struct page *page)
 {
diff --git a/kernel/module.c b/kernel/module.c
index ccdf24c..ad2d420 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3804,6 +3804,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
 	module_disable_nx(mod);
 
  ddebug_cleanup:
+	ftrace_release_mod(mod);
 	dynamic_debug_remove(mod, info->debug);
 	synchronize_sched();
 	kfree(mod->args);
@@ -3823,12 +3824,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
 	synchronize_sched();
 	mutex_unlock(&module_mutex);
  free_module:
-	/*
-	 * Ftrace needs to clean up what it initialized.
-	 * This does nothing if ftrace_module_init() wasn't called,
-	 * but it must be called outside of module_mutex.
-	 */
-	ftrace_release_mod(mod);
 	/* Free lock-classes; relies on the preceding sync_rcu() */
 	lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size);
 
diff --git a/kernel/pid.c b/kernel/pid.c
index 5d30c87..ed6c343 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -343,6 +343,19 @@ struct task_struct *find_task_by_vpid(pid_t vnr)
 	return find_task_by_pid_ns(vnr, task_active_pid_ns(current));
 }
 
+struct task_struct *find_get_task_by_vpid(pid_t nr)
+{
+	struct task_struct *task;
+
+	rcu_read_lock();
+	task = find_task_by_vpid(nr);
+	if (task)
+		get_task_struct(task);
+	rcu_read_unlock();
+
+	return task;
+}
+
 struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
 {
 	struct pid *pid;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 5e1d713..21fec73 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -1103,21 +1103,6 @@ int ptrace_request(struct task_struct *child, long request,
 	return ret;
 }
 
-static struct task_struct *ptrace_get_task_struct(pid_t pid)
-{
-	struct task_struct *child;
-
-	rcu_read_lock();
-	child = find_task_by_vpid(pid);
-	if (child)
-		get_task_struct(child);
-	rcu_read_unlock();
-
-	if (!child)
-		return ERR_PTR(-ESRCH);
-	return child;
-}
-
 #ifndef arch_ptrace_attach
 #define arch_ptrace_attach(child)	do { } while (0)
 #endif
@@ -1135,9 +1120,9 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
 		goto out;
 	}
 
-	child = ptrace_get_task_struct(pid);
-	if (IS_ERR(child)) {
-		ret = PTR_ERR(child);
+	child = find_get_task_by_vpid(pid);
+	if (!child) {
+		ret = -ESRCH;
 		goto out;
 	}
 
@@ -1281,9 +1266,9 @@ COMPAT_SYSCALL_DEFINE4(ptrace, compat_long_t, request, compat_long_t, pid,
 		goto out;
 	}
 
-	child = ptrace_get_task_struct(pid);
-	if (IS_ERR(child)) {
-		ret = PTR_ERR(child);
+	child = find_get_task_by_vpid(pid);
+	if (!child) {
+		ret = -ESRCH;
 		goto out;
 	}
 
diff --git a/kernel/relay.c b/kernel/relay.c
index 4128003..f7f40a6 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -611,7 +611,6 @@ struct rchan *relay_open(const char *base_filename,
 
 	kref_put(&chan->kref, relay_destroy_channel);
 	mutex_unlock(&relay_channels_mutex);
-	kfree(chan);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(relay_open);
diff --git a/kernel/resource.c b/kernel/resource.c
index 54ba6de..e270b50 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -1022,6 +1022,7 @@ static void __init __reserve_region_with_split(struct resource *root,
 	struct resource *conflict;
 	struct resource *res = alloc_resource(GFP_ATOMIC);
 	struct resource *next_res = NULL;
+	int type = resource_type(root);
 
 	if (!res)
 		return;
@@ -1029,7 +1030,7 @@ static void __init __reserve_region_with_split(struct resource *root,
 	res->name = name;
 	res->start = start;
 	res->end = end;
-	res->flags = IORESOURCE_BUSY;
+	res->flags = type | IORESOURCE_BUSY;
 	res->desc = IORES_DESC_NONE;
 
 	while (1) {
@@ -1064,7 +1065,7 @@ static void __init __reserve_region_with_split(struct resource *root,
 				next_res->name = name;
 				next_res->start = conflict->end + 1;
 				next_res->end = end;
-				next_res->flags = IORESOURCE_BUSY;
+				next_res->flags = type | IORESOURCE_BUSY;
 				next_res->desc = IORES_DESC_NONE;
 			}
 		} else {
@@ -1478,7 +1479,7 @@ void __devm_release_region(struct device *dev, struct resource *parent,
 EXPORT_SYMBOL(__devm_release_region);
 
 /*
- * Called from init/main.c to reserve IO ports.
+ * Reserve I/O ports or memory based on "reserve=" kernel parameter.
  */
 #define MAXRESERVE 4
 static int __init reserve_setup(char *str)
@@ -1489,26 +1490,38 @@ static int __init reserve_setup(char *str)
 	for (;;) {
 		unsigned int io_start, io_num;
 		int x = reserved;
+		struct resource *parent;
 
-		if (get_option (&str, &io_start) != 2)
+		if (get_option(&str, &io_start) != 2)
 			break;
-		if (get_option (&str, &io_num)   == 0)
+		if (get_option(&str, &io_num) == 0)
 			break;
 		if (x < MAXRESERVE) {
 			struct resource *res = reserve + x;
+
+			/*
+			 * If the region starts below 0x10000, we assume it's
+			 * I/O port space; otherwise assume it's memory.
+			 */
+			if (io_start < 0x10000) {
+				res->flags = IORESOURCE_IO;
+				parent = &ioport_resource;
+			} else {
+				res->flags = IORESOURCE_MEM;
+				parent = &iomem_resource;
+			}
 			res->name = "reserved";
 			res->start = io_start;
 			res->end = io_start + io_num - 1;
-			res->flags = IORESOURCE_BUSY;
+			res->flags |= IORESOURCE_BUSY;
 			res->desc = IORES_DESC_NONE;
 			res->child = NULL;
-			if (request_resource(res->start >= 0x10000 ? &iomem_resource : &ioport_resource, res) == 0)
+			if (request_resource(parent, res) == 0)
 				reserved = x+1;
 		}
 	}
 	return 1;
 }
-
 __setup("reserve=", reserve_setup);
 
 /*
@@ -1563,17 +1576,17 @@ static int strict_iomem_checks;
 
 /*
  * check if an address is reserved in the iomem resource tree
- * returns 1 if reserved, 0 if not reserved.
+ * returns true if reserved, false if not reserved.
  */
-int iomem_is_exclusive(u64 addr)
+bool iomem_is_exclusive(u64 addr)
 {
 	struct resource *p = &iomem_resource;
-	int err = 0;
+	bool err = false;
 	loff_t l;
 	int size = PAGE_SIZE;
 
 	if (!strict_iomem_checks)
-		return 0;
+		return false;
 
 	addr = addr & PAGE_MASK;
 
@@ -1596,7 +1609,7 @@ int iomem_is_exclusive(u64 addr)
 			continue;
 		if (IS_ENABLED(CONFIG_IO_STRICT_DEVMEM)
 				|| p->flags & IORESOURCE_EXCLUSIVE) {
-			err = 1;
+			err = true;
 			break;
 		}
 	}
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 3da7a24..bf724c1 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1630,16 +1630,16 @@ ttwu_stat(struct task_struct *p, int cpu, int wake_flags)
 
 #ifdef CONFIG_SMP
 	if (cpu == rq->cpu) {
-		schedstat_inc(rq->ttwu_local);
-		schedstat_inc(p->se.statistics.nr_wakeups_local);
+		__schedstat_inc(rq->ttwu_local);
+		__schedstat_inc(p->se.statistics.nr_wakeups_local);
 	} else {
 		struct sched_domain *sd;
 
-		schedstat_inc(p->se.statistics.nr_wakeups_remote);
+		__schedstat_inc(p->se.statistics.nr_wakeups_remote);
 		rcu_read_lock();
 		for_each_domain(rq->cpu, sd) {
 			if (cpumask_test_cpu(cpu, sched_domain_span(sd))) {
-				schedstat_inc(sd->ttwu_wake_remote);
+				__schedstat_inc(sd->ttwu_wake_remote);
 				break;
 			}
 		}
@@ -1647,14 +1647,14 @@ ttwu_stat(struct task_struct *p, int cpu, int wake_flags)
 	}
 
 	if (wake_flags & WF_MIGRATED)
-		schedstat_inc(p->se.statistics.nr_wakeups_migrate);
+		__schedstat_inc(p->se.statistics.nr_wakeups_migrate);
 #endif /* CONFIG_SMP */
 
-	schedstat_inc(rq->ttwu_count);
-	schedstat_inc(p->se.statistics.nr_wakeups);
+	__schedstat_inc(rq->ttwu_count);
+	__schedstat_inc(p->se.statistics.nr_wakeups);
 
 	if (wake_flags & WF_SYNC)
-		schedstat_inc(p->se.statistics.nr_wakeups_sync);
+		__schedstat_inc(p->se.statistics.nr_wakeups_sync);
 }
 
 static inline void ttwu_activate(struct rq *rq, struct task_struct *p, int en_flags)
@@ -2461,6 +2461,7 @@ void wake_up_new_task(struct task_struct *p)
 	 * Use __set_task_cpu() to avoid calling sched_class::migrate_task_rq,
 	 * as we're not fully set-up yet.
 	 */
+	p->recent_used_cpu = task_cpu(p);
 	__set_task_cpu(p, select_task_rq(p, task_cpu(p), SD_BALANCE_FORK, 0));
 #endif
 	rq = __task_rq_lock(p, &rf);
@@ -2698,23 +2699,27 @@ static struct rq *finish_task_switch(struct task_struct *prev)
 	prev_state = prev->state;
 	vtime_task_switch(prev);
 	perf_event_task_sched_in(prev, current);
-	/*
-	 * The membarrier system call requires a full memory barrier
-	 * after storing to rq->curr, before going back to user-space.
-	 *
-	 * TODO: This smp_mb__after_unlock_lock can go away if PPC end
-	 * up adding a full barrier to switch_mm(), or we should figure
-	 * out if a smp_mb__after_unlock_lock is really the proper API
-	 * to use.
-	 */
-	smp_mb__after_unlock_lock();
 	finish_task(prev);
 	finish_lock_switch(rq);
 	finish_arch_post_lock_switch();
 
 	fire_sched_in_preempt_notifiers(current);
-	if (mm)
+	/*
+	 * When switching through a kernel thread, the loop in
+	 * membarrier_{private,global}_expedited() may have observed that
+	 * kernel thread and not issued an IPI. It is therefore possible to
+	 * schedule between user->kernel->user threads without passing though
+	 * switch_mm(). Membarrier requires a barrier after storing to
+	 * rq->curr, before returning to userspace, so provide them here:
+	 *
+	 * - a full memory barrier for {PRIVATE,GLOBAL}_EXPEDITED, implicitly
+	 *   provided by mmdrop(),
+	 * - a sync_core for SYNC_CORE.
+	 */
+	if (mm) {
+		membarrier_mm_sync_core_before_usermode(mm);
 		mmdrop(mm);
+	}
 	if (unlikely(prev_state == TASK_DEAD)) {
 		if (prev->sched_class->task_dead)
 			prev->sched_class->task_dead(prev);
@@ -2818,6 +2823,13 @@ context_switch(struct rq *rq, struct task_struct *prev,
 	 */
 	arch_start_context_switch(prev);
 
+	/*
+	 * If mm is non-NULL, we pass through switch_mm(). If mm is
+	 * NULL, we will pass through mmdrop() in finish_task_switch().
+	 * Both of these contain the full memory barrier required by
+	 * membarrier after storing to rq->curr, before returning to
+	 * user-space.
+	 */
 	if (!mm) {
 		next->active_mm = oldmm;
 		mmgrab(oldmm);
@@ -3354,6 +3366,9 @@ static void __sched notrace __schedule(bool preempt)
 	 * Make sure that signal_pending_state()->signal_pending() below
 	 * can't be reordered with __set_current_state(TASK_INTERRUPTIBLE)
 	 * done by the caller to avoid the race with signal_wake_up().
+	 *
+	 * The membarrier system call requires a full memory barrier
+	 * after coming from user-space, before storing to rq->curr.
 	 */
 	rq_lock(rq, &rf);
 	smp_mb__after_spinlock();
@@ -3401,17 +3416,16 @@ static void __sched notrace __schedule(bool preempt)
 		/*
 		 * The membarrier system call requires each architecture
 		 * to have a full memory barrier after updating
-		 * rq->curr, before returning to user-space. For TSO
-		 * (e.g. x86), the architecture must provide its own
-		 * barrier in switch_mm(). For weakly ordered machines
-		 * for which spin_unlock() acts as a full memory
-		 * barrier, finish_lock_switch() in common code takes
-		 * care of this barrier. For weakly ordered machines for
-		 * which spin_unlock() acts as a RELEASE barrier (only
-		 * arm64 and PowerPC), arm64 has a full barrier in
-		 * switch_to(), and PowerPC has
-		 * smp_mb__after_unlock_lock() before
-		 * finish_lock_switch().
+		 * rq->curr, before returning to user-space.
+		 *
+		 * Here are the schemes providing that barrier on the
+		 * various architectures:
+		 * - mm ? switch_mm() : mmdrop() for x86, s390, sparc, PowerPC.
+		 *   switch_mm() rely on membarrier_arch_switch_mm() on PowerPC.
+		 * - finish_lock_switch() for weakly-ordered
+		 *   architectures where spin_unlock is a full barrier,
+		 * - switch_to() for arm64 (weakly-ordered, spin_unlock
+		 *   is a RELEASE barrier),
 		 */
 		++*switch_count;
 
@@ -4853,7 +4867,7 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
 
 	ret = sched_getaffinity(pid, mask);
 	if (ret == 0) {
-		size_t retlen = min_t(size_t, len, cpumask_size());
+		unsigned int retlen = min(len, cpumask_size());
 
 		if (copy_to_user(user_mask_ptr, mask, retlen))
 			ret = -EFAULT;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 7b65359..5eb3ffc 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -871,7 +871,7 @@ update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
 	    likely(wait_start > prev_wait_start))
 		wait_start -= prev_wait_start;
 
-	schedstat_set(se->statistics.wait_start, wait_start);
+	__schedstat_set(se->statistics.wait_start, wait_start);
 }
 
 static inline void
@@ -893,17 +893,17 @@ update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
 			 * time stamp can be adjusted to accumulate wait time
 			 * prior to migration.
 			 */
-			schedstat_set(se->statistics.wait_start, delta);
+			__schedstat_set(se->statistics.wait_start, delta);
 			return;
 		}
 		trace_sched_stat_wait(p, delta);
 	}
 
-	schedstat_set(se->statistics.wait_max,
+	__schedstat_set(se->statistics.wait_max,
 		      max(schedstat_val(se->statistics.wait_max), delta));
-	schedstat_inc(se->statistics.wait_count);
-	schedstat_add(se->statistics.wait_sum, delta);
-	schedstat_set(se->statistics.wait_start, 0);
+	__schedstat_inc(se->statistics.wait_count);
+	__schedstat_add(se->statistics.wait_sum, delta);
+	__schedstat_set(se->statistics.wait_start, 0);
 }
 
 static inline void
@@ -928,10 +928,10 @@ update_stats_enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
 			delta = 0;
 
 		if (unlikely(delta > schedstat_val(se->statistics.sleep_max)))
-			schedstat_set(se->statistics.sleep_max, delta);
+			__schedstat_set(se->statistics.sleep_max, delta);
 
-		schedstat_set(se->statistics.sleep_start, 0);
-		schedstat_add(se->statistics.sum_sleep_runtime, delta);
+		__schedstat_set(se->statistics.sleep_start, 0);
+		__schedstat_add(se->statistics.sum_sleep_runtime, delta);
 
 		if (tsk) {
 			account_scheduler_latency(tsk, delta >> 10, 1);
@@ -945,15 +945,15 @@ update_stats_enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
 			delta = 0;
 
 		if (unlikely(delta > schedstat_val(se->statistics.block_max)))
-			schedstat_set(se->statistics.block_max, delta);
+			__schedstat_set(se->statistics.block_max, delta);
 
-		schedstat_set(se->statistics.block_start, 0);
-		schedstat_add(se->statistics.sum_sleep_runtime, delta);
+		__schedstat_set(se->statistics.block_start, 0);
+		__schedstat_add(se->statistics.sum_sleep_runtime, delta);
 
 		if (tsk) {
 			if (tsk->in_iowait) {
-				schedstat_add(se->statistics.iowait_sum, delta);
-				schedstat_inc(se->statistics.iowait_count);
+				__schedstat_add(se->statistics.iowait_sum, delta);
+				__schedstat_inc(se->statistics.iowait_count);
 				trace_sched_stat_iowait(tsk, delta);
 			}
 
@@ -1012,10 +1012,10 @@ update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
 		struct task_struct *tsk = task_of(se);
 
 		if (tsk->state & TASK_INTERRUPTIBLE)
-			schedstat_set(se->statistics.sleep_start,
+			__schedstat_set(se->statistics.sleep_start,
 				      rq_clock(rq_of(cfs_rq)));
 		if (tsk->state & TASK_UNINTERRUPTIBLE)
-			schedstat_set(se->statistics.block_start,
+			__schedstat_set(se->statistics.block_start,
 				      rq_clock(rq_of(cfs_rq)));
 	}
 }
@@ -5692,27 +5692,31 @@ static int wake_wide(struct task_struct *p)
  *			  scheduling latency of the CPUs. This seems to work
  *			  for the overloaded case.
  */
-
-static bool
-wake_affine_idle(struct sched_domain *sd, struct task_struct *p,
-		 int this_cpu, int prev_cpu, int sync)
+static int
+wake_affine_idle(int this_cpu, int prev_cpu, int sync)
 {
 	/*
 	 * If this_cpu is idle, it implies the wakeup is from interrupt
 	 * context. Only allow the move if cache is shared. Otherwise an
 	 * interrupt intensive workload could force all tasks onto one
 	 * node depending on the IO topology or IRQ affinity settings.
+	 *
+	 * If the prev_cpu is idle and cache affine then avoid a migration.
+	 * There is no guarantee that the cache hot data from an interrupt
+	 * is more important than cache hot data on the prev_cpu and from
+	 * a cpufreq perspective, it's better to have higher utilisation
+	 * on one CPU.
 	 */
 	if (idle_cpu(this_cpu) && cpus_share_cache(this_cpu, prev_cpu))
-		return true;
+		return idle_cpu(prev_cpu) ? prev_cpu : this_cpu;
 
 	if (sync && cpu_rq(this_cpu)->nr_running == 1)
-		return true;
+		return this_cpu;
 
-	return false;
+	return nr_cpumask_bits;
 }
 
-static bool
+static int
 wake_affine_weight(struct sched_domain *sd, struct task_struct *p,
 		   int this_cpu, int prev_cpu, int sync)
 {
@@ -5726,7 +5730,7 @@ wake_affine_weight(struct sched_domain *sd, struct task_struct *p,
 		unsigned long current_load = task_h_load(current);
 
 		if (current_load > this_eff_load)
-			return true;
+			return this_cpu;
 
 		this_eff_load -= current_load;
 	}
@@ -5743,28 +5747,28 @@ wake_affine_weight(struct sched_domain *sd, struct task_struct *p,
 		prev_eff_load *= 100 + (sd->imbalance_pct - 100) / 2;
 	prev_eff_load *= capacity_of(this_cpu);
 
-	return this_eff_load <= prev_eff_load;
+	return this_eff_load <= prev_eff_load ? this_cpu : nr_cpumask_bits;
 }
 
 static int wake_affine(struct sched_domain *sd, struct task_struct *p,
 		       int prev_cpu, int sync)
 {
 	int this_cpu = smp_processor_id();
-	bool affine = false;
+	int target = nr_cpumask_bits;
 
-	if (sched_feat(WA_IDLE) && !affine)
-		affine = wake_affine_idle(sd, p, this_cpu, prev_cpu, sync);
+	if (sched_feat(WA_IDLE))
+		target = wake_affine_idle(this_cpu, prev_cpu, sync);
 
-	if (sched_feat(WA_WEIGHT) && !affine)
-		affine = wake_affine_weight(sd, p, this_cpu, prev_cpu, sync);
+	if (sched_feat(WA_WEIGHT) && target == nr_cpumask_bits)
+		target = wake_affine_weight(sd, p, this_cpu, prev_cpu, sync);
 
 	schedstat_inc(p->se.statistics.nr_wakeups_affine_attempts);
-	if (affine) {
-		schedstat_inc(sd->ttwu_move_affine);
-		schedstat_inc(p->se.statistics.nr_wakeups_affine);
-	}
+	if (target == nr_cpumask_bits)
+		return prev_cpu;
 
-	return affine;
+	schedstat_inc(sd->ttwu_move_affine);
+	schedstat_inc(p->se.statistics.nr_wakeups_affine);
+	return target;
 }
 
 static inline unsigned long task_util(struct task_struct *p);
@@ -6193,7 +6197,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
 static int select_idle_sibling(struct task_struct *p, int prev, int target)
 {
 	struct sched_domain *sd;
-	int i;
+	int i, recent_used_cpu;
 
 	if (idle_cpu(target))
 		return target;
@@ -6204,6 +6208,21 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
 	if (prev != target && cpus_share_cache(prev, target) && idle_cpu(prev))
 		return prev;
 
+	/* Check a recently used CPU as a potential idle candidate */
+	recent_used_cpu = p->recent_used_cpu;
+	if (recent_used_cpu != prev &&
+	    recent_used_cpu != target &&
+	    cpus_share_cache(recent_used_cpu, target) &&
+	    idle_cpu(recent_used_cpu) &&
+	    cpumask_test_cpu(p->recent_used_cpu, &p->cpus_allowed)) {
+		/*
+		 * Replace recent_used_cpu with prev as it is a potential
+		 * candidate for the next wake.
+		 */
+		p->recent_used_cpu = prev;
+		return recent_used_cpu;
+	}
+
 	sd = rcu_dereference(per_cpu(sd_llc, target));
 	if (!sd)
 		return target;
@@ -6357,8 +6376,7 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f
 		if (cpu == prev_cpu)
 			goto pick_cpu;
 
-		if (wake_affine(affine_sd, p, prev_cpu, sync))
-			new_cpu = cpu;
+		new_cpu = wake_affine(affine_sd, p, prev_cpu, sync);
 	}
 
 	if (sd && !(sd_flag & SD_BALANCE_FORK)) {
@@ -6372,9 +6390,12 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f
 
 	if (!sd) {
 pick_cpu:
-		if (sd_flag & SD_BALANCE_WAKE) /* XXX always ? */
+		if (sd_flag & SD_BALANCE_WAKE) { /* XXX always ? */
 			new_cpu = select_idle_sibling(p, prev_cpu, new_cpu);
 
+			if (want_affine)
+				current->recent_used_cpu = cpu;
+		}
 	} else {
 		new_cpu = find_idlest_cpu(sd, p, cpu, prev_cpu, sd_flag);
 	}
diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c
index 9bcbacba..5d07626 100644
--- a/kernel/sched/membarrier.c
+++ b/kernel/sched/membarrier.c
@@ -26,24 +26,110 @@
  * Bitmask made from a "or" of all commands within enum membarrier_cmd,
  * except MEMBARRIER_CMD_QUERY.
  */
+#ifdef CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE
+#define MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK	\
+	(MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE \
+	| MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE)
+#else
+#define MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK	0
+#endif
+
 #define MEMBARRIER_CMD_BITMASK	\
-	(MEMBARRIER_CMD_SHARED | MEMBARRIER_CMD_PRIVATE_EXPEDITED	\
-	| MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED)
+	(MEMBARRIER_CMD_GLOBAL | MEMBARRIER_CMD_GLOBAL_EXPEDITED \
+	| MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED \
+	| MEMBARRIER_CMD_PRIVATE_EXPEDITED	\
+	| MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED	\
+	| MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK)
 
 static void ipi_mb(void *info)
 {
 	smp_mb();	/* IPIs should be serializing but paranoid. */
 }
 
-static int membarrier_private_expedited(void)
+static int membarrier_global_expedited(void)
 {
 	int cpu;
 	bool fallback = false;
 	cpumask_var_t tmpmask;
 
-	if (!(atomic_read(&current->mm->membarrier_state)
-			& MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY))
-		return -EPERM;
+	if (num_online_cpus() == 1)
+		return 0;
+
+	/*
+	 * Matches memory barriers around rq->curr modification in
+	 * scheduler.
+	 */
+	smp_mb();	/* system call entry is not a mb. */
+
+	/*
+	 * Expedited membarrier commands guarantee that they won't
+	 * block, hence the GFP_NOWAIT allocation flag and fallback
+	 * implementation.
+	 */
+	if (!zalloc_cpumask_var(&tmpmask, GFP_NOWAIT)) {
+		/* Fallback for OOM. */
+		fallback = true;
+	}
+
+	cpus_read_lock();
+	for_each_online_cpu(cpu) {
+		struct task_struct *p;
+
+		/*
+		 * Skipping the current CPU is OK even through we can be
+		 * migrated at any point. The current CPU, at the point
+		 * where we read raw_smp_processor_id(), is ensured to
+		 * be in program order with respect to the caller
+		 * thread. Therefore, we can skip this CPU from the
+		 * iteration.
+		 */
+		if (cpu == raw_smp_processor_id())
+			continue;
+		rcu_read_lock();
+		p = task_rcu_dereference(&cpu_rq(cpu)->curr);
+		if (p && p->mm && (atomic_read(&p->mm->membarrier_state) &
+				   MEMBARRIER_STATE_GLOBAL_EXPEDITED)) {
+			if (!fallback)
+				__cpumask_set_cpu(cpu, tmpmask);
+			else
+				smp_call_function_single(cpu, ipi_mb, NULL, 1);
+		}
+		rcu_read_unlock();
+	}
+	if (!fallback) {
+		preempt_disable();
+		smp_call_function_many(tmpmask, ipi_mb, NULL, 1);
+		preempt_enable();
+		free_cpumask_var(tmpmask);
+	}
+	cpus_read_unlock();
+
+	/*
+	 * Memory barrier on the caller thread _after_ we finished
+	 * waiting for the last IPI. Matches memory barriers around
+	 * rq->curr modification in scheduler.
+	 */
+	smp_mb();	/* exit from system call is not a mb */
+	return 0;
+}
+
+static int membarrier_private_expedited(int flags)
+{
+	int cpu;
+	bool fallback = false;
+	cpumask_var_t tmpmask;
+
+	if (flags & MEMBARRIER_FLAG_SYNC_CORE) {
+		if (!IS_ENABLED(CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE))
+			return -EINVAL;
+		if (!(atomic_read(&current->mm->membarrier_state) &
+		      MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY))
+			return -EPERM;
+	} else {
+		if (!(atomic_read(&current->mm->membarrier_state) &
+		      MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY))
+			return -EPERM;
+	}
 
 	if (num_online_cpus() == 1)
 		return 0;
@@ -105,21 +191,69 @@ static int membarrier_private_expedited(void)
 	return 0;
 }
 
-static void membarrier_register_private_expedited(void)
+static int membarrier_register_global_expedited(void)
 {
 	struct task_struct *p = current;
 	struct mm_struct *mm = p->mm;
 
+	if (atomic_read(&mm->membarrier_state) &
+	    MEMBARRIER_STATE_GLOBAL_EXPEDITED_READY)
+		return 0;
+	atomic_or(MEMBARRIER_STATE_GLOBAL_EXPEDITED, &mm->membarrier_state);
+	if (atomic_read(&mm->mm_users) == 1 && get_nr_threads(p) == 1) {
+		/*
+		 * For single mm user, single threaded process, we can
+		 * simply issue a memory barrier after setting
+		 * MEMBARRIER_STATE_GLOBAL_EXPEDITED to guarantee that
+		 * no memory access following registration is reordered
+		 * before registration.
+		 */
+		smp_mb();
+	} else {
+		/*
+		 * For multi-mm user threads, we need to ensure all
+		 * future scheduler executions will observe the new
+		 * thread flag state for this mm.
+		 */
+		synchronize_sched();
+	}
+	atomic_or(MEMBARRIER_STATE_GLOBAL_EXPEDITED_READY,
+		  &mm->membarrier_state);
+	return 0;
+}
+
+static int membarrier_register_private_expedited(int flags)
+{
+	struct task_struct *p = current;
+	struct mm_struct *mm = p->mm;
+	int state = MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY;
+
+	if (flags & MEMBARRIER_FLAG_SYNC_CORE) {
+		if (!IS_ENABLED(CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE))
+			return -EINVAL;
+		state = MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY;
+	}
+
 	/*
 	 * We need to consider threads belonging to different thread
 	 * groups, which use the same mm. (CLONE_VM but not
 	 * CLONE_THREAD).
 	 */
-	if (atomic_read(&mm->membarrier_state)
-			& MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY)
-		return;
-	atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY,
-			&mm->membarrier_state);
+	if (atomic_read(&mm->membarrier_state) & state)
+		return 0;
+	atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED, &mm->membarrier_state);
+	if (flags & MEMBARRIER_FLAG_SYNC_CORE)
+		atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE,
+			  &mm->membarrier_state);
+	if (!(atomic_read(&mm->mm_users) == 1 && get_nr_threads(p) == 1)) {
+		/*
+		 * Ensure all future scheduler executions will observe the
+		 * new thread flag state for this process.
+		 */
+		synchronize_sched();
+	}
+	atomic_or(state, &mm->membarrier_state);
+	return 0;
 }
 
 /**
@@ -159,21 +293,28 @@ SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
 		int cmd_mask = MEMBARRIER_CMD_BITMASK;
 
 		if (tick_nohz_full_enabled())
-			cmd_mask &= ~MEMBARRIER_CMD_SHARED;
+			cmd_mask &= ~MEMBARRIER_CMD_GLOBAL;
 		return cmd_mask;
 	}
-	case MEMBARRIER_CMD_SHARED:
-		/* MEMBARRIER_CMD_SHARED is not compatible with nohz_full. */
+	case MEMBARRIER_CMD_GLOBAL:
+		/* MEMBARRIER_CMD_GLOBAL is not compatible with nohz_full. */
 		if (tick_nohz_full_enabled())
 			return -EINVAL;
 		if (num_online_cpus() > 1)
 			synchronize_sched();
 		return 0;
+	case MEMBARRIER_CMD_GLOBAL_EXPEDITED:
+		return membarrier_global_expedited();
+	case MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED:
+		return membarrier_register_global_expedited();
 	case MEMBARRIER_CMD_PRIVATE_EXPEDITED:
-		return membarrier_private_expedited();
+		return membarrier_private_expedited(0);
 	case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED:
-		membarrier_register_private_expedited();
-		return 0;
+		return membarrier_register_private_expedited(0);
+	case MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE:
+		return membarrier_private_expedited(MEMBARRIER_FLAG_SYNC_CORE);
+	case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE:
+		return membarrier_register_private_expedited(MEMBARRIER_FLAG_SYNC_CORE);
 	default:
 		return -EINVAL;
 	}
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 862a513..663b235 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -950,12 +950,13 @@ static void update_curr_rt(struct rq *rq)
 {
 	struct task_struct *curr = rq->curr;
 	struct sched_rt_entity *rt_se = &curr->rt;
+	u64 now = rq_clock_task(rq);
 	u64 delta_exec;
 
 	if (curr->sched_class != &rt_sched_class)
 		return;
 
-	delta_exec = rq_clock_task(rq) - curr->se.exec_start;
+	delta_exec = now - curr->se.exec_start;
 	if (unlikely((s64)delta_exec <= 0))
 		return;
 
@@ -968,7 +969,7 @@ static void update_curr_rt(struct rq *rq)
 	curr->se.sum_exec_runtime += delta_exec;
 	account_group_exec_runtime(curr, delta_exec);
 
-	curr->se.exec_start = rq_clock_task(rq);
+	curr->se.exec_start = now;
 	cgroup_account_cputime(curr, delta_exec);
 
 	sched_rt_avg_update(rq, delta_exec);
@@ -1907,9 +1908,8 @@ static void push_rt_tasks(struct rq *rq)
  * the rt_loop_next will cause the iterator to perform another scan.
  *
  */
-static int rto_next_cpu(struct rq *rq)
+static int rto_next_cpu(struct root_domain *rd)
 {
-	struct root_domain *rd = rq->rd;
 	int next;
 	int cpu;
 
@@ -1985,19 +1985,24 @@ static void tell_cpu_to_push(struct rq *rq)
 	 * Otherwise it is finishing up and an ipi needs to be sent.
 	 */
 	if (rq->rd->rto_cpu < 0)
-		cpu = rto_next_cpu(rq);
+		cpu = rto_next_cpu(rq->rd);
 
 	raw_spin_unlock(&rq->rd->rto_lock);
 
 	rto_start_unlock(&rq->rd->rto_loop_start);
 
-	if (cpu >= 0)
+	if (cpu >= 0) {
+		/* Make sure the rd does not get freed while pushing */
+		sched_get_rd(rq->rd);
 		irq_work_queue_on(&rq->rd->rto_push_work, cpu);
+	}
 }
 
 /* Called from hardirq context */
 void rto_push_irq_work_func(struct irq_work *work)
 {
+	struct root_domain *rd =
+		container_of(work, struct root_domain, rto_push_work);
 	struct rq *rq;
 	int cpu;
 
@@ -2013,18 +2018,20 @@ void rto_push_irq_work_func(struct irq_work *work)
 		raw_spin_unlock(&rq->lock);
 	}
 
-	raw_spin_lock(&rq->rd->rto_lock);
+	raw_spin_lock(&rd->rto_lock);
 
 	/* Pass the IPI to the next rt overloaded queue */
-	cpu = rto_next_cpu(rq);
+	cpu = rto_next_cpu(rd);
 
-	raw_spin_unlock(&rq->rd->rto_lock);
+	raw_spin_unlock(&rd->rto_lock);
 
-	if (cpu < 0)
+	if (cpu < 0) {
+		sched_put_rd(rd);
 		return;
+	}
 
 	/* Try the next RT overloaded CPU */
-	irq_work_queue_on(&rq->rd->rto_push_work, cpu);
+	irq_work_queue_on(&rd->rto_push_work, cpu);
 }
 #endif /* HAVE_RT_PUSH_IPI */
 
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 2e95505..fb5fc45 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -691,6 +691,8 @@ extern struct mutex sched_domains_mutex;
 extern void init_defrootdomain(void);
 extern int sched_init_domains(const struct cpumask *cpu_map);
 extern void rq_attach_root(struct rq *rq, struct root_domain *rd);
+extern void sched_get_rd(struct root_domain *rd);
+extern void sched_put_rd(struct root_domain *rd);
 
 #ifdef HAVE_RT_PUSH_IPI
 extern void rto_push_irq_work_func(struct irq_work *work);
diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
index baf500d..8e7b58d 100644
--- a/kernel/sched/stats.h
+++ b/kernel/sched/stats.h
@@ -31,8 +31,11 @@ rq_sched_info_dequeued(struct rq *rq, unsigned long long delta)
 		rq->rq_sched_info.run_delay += delta;
 }
 #define schedstat_enabled()		static_branch_unlikely(&sched_schedstats)
+#define __schedstat_inc(var)		do { var++; } while (0)
 #define schedstat_inc(var)		do { if (schedstat_enabled()) { var++; } } while (0)
+#define __schedstat_add(var, amt)	do { var += (amt); } while (0)
 #define schedstat_add(var, amt)		do { if (schedstat_enabled()) { var += (amt); } } while (0)
+#define __schedstat_set(var, val)		do { var = (val); } while (0)
 #define schedstat_set(var, val)		do { if (schedstat_enabled()) { var = (val); } } while (0)
 #define schedstat_val(var)		(var)
 #define schedstat_val_or_zero(var)	((schedstat_enabled()) ? (var) : 0)
@@ -48,8 +51,11 @@ static inline void
 rq_sched_info_depart(struct rq *rq, unsigned long long delta)
 {}
 #define schedstat_enabled()		0
+#define __schedstat_inc(var)		do { } while (0)
 #define schedstat_inc(var)		do { } while (0)
+#define __schedstat_add(var, amt)	do { } while (0)
 #define schedstat_add(var, amt)		do { } while (0)
+#define __schedstat_set(var, val)	do { } while (0)
 #define schedstat_set(var, val)		do { } while (0)
 #define schedstat_val(var)		0
 #define schedstat_val_or_zero(var)	0
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 034cbed..519b024 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -259,6 +259,19 @@ void rq_attach_root(struct rq *rq, struct root_domain *rd)
 		call_rcu_sched(&old_rd->rcu, free_rootdomain);
 }
 
+void sched_get_rd(struct root_domain *rd)
+{
+	atomic_inc(&rd->refcount);
+}
+
+void sched_put_rd(struct root_domain *rd)
+{
+	if (!atomic_dec_and_test(&rd->refcount))
+		return;
+
+	call_rcu_sched(&rd->rcu, free_rootdomain);
+}
+
 static int init_rootdomain(struct root_domain *rd)
 {
 	if (!zalloc_cpumask_var(&rd->span, GFP_KERNEL))
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 2fb4e27..f98f28c 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -218,6 +218,8 @@ static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
 static int proc_dostring_coredump(struct ctl_table *table, int write,
 		void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
+static int proc_dopipe_max_size(struct ctl_table *table, int write,
+		void __user *buffer, size_t *lenp, loff_t *ppos);
 
 #ifdef CONFIG_MAGIC_SYSRQ
 /* Note: sysrq code uses it's own private copy */
@@ -1812,8 +1814,7 @@ static struct ctl_table fs_table[] = {
 		.data		= &pipe_max_size,
 		.maxlen		= sizeof(pipe_max_size),
 		.mode		= 0644,
-		.proc_handler	= &pipe_proc_fn,
-		.extra1		= &pipe_min_size,
+		.proc_handler	= proc_dopipe_max_size,
 	},
 	{
 		.procname	= "pipe-user-pages-hard",
@@ -2615,29 +2616,17 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
 				 do_proc_douintvec_minmax_conv, &param);
 }
 
-struct do_proc_dopipe_max_size_conv_param {
-	unsigned int *min;
-};
-
 static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
 					unsigned int *valp,
 					int write, void *data)
 {
-	struct do_proc_dopipe_max_size_conv_param *param = data;
-
 	if (write) {
 		unsigned int val;
 
-		if (*lvalp > UINT_MAX)
-			return -EINVAL;
-
 		val = round_pipe_size(*lvalp);
 		if (val == 0)
 			return -EINVAL;
 
-		if (param->min && *param->min > val)
-			return -ERANGE;
-
 		*valp = val;
 	} else {
 		unsigned int val = *valp;
@@ -2647,14 +2636,11 @@ static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
 	return 0;
 }
 
-int proc_dopipe_max_size(struct ctl_table *table, int write,
-			 void __user *buffer, size_t *lenp, loff_t *ppos)
+static int proc_dopipe_max_size(struct ctl_table *table, int write,
+				void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-	struct do_proc_dopipe_max_size_conv_param param = {
-		.min = (unsigned int *) table->extra1,
-	};
 	return do_proc_douintvec(table, write, buffer, lenp, ppos,
-				 do_proc_dopipe_max_size_conv, &param);
+				 do_proc_dopipe_max_size_conv, NULL);
 }
 
 static void validate_coredump_safety(void)
@@ -3160,12 +3146,6 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
 	return -ENOSYS;
 }
 
-int proc_dopipe_max_size(struct ctl_table *table, int write,
-			 void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-	return -ENOSYS;
-}
-
 int proc_dointvec_jiffies(struct ctl_table *table, int write,
 		    void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -3209,7 +3189,6 @@ EXPORT_SYMBOL(proc_douintvec);
 EXPORT_SYMBOL(proc_dointvec_jiffies);
 EXPORT_SYMBOL(proc_dointvec_minmax);
 EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
-EXPORT_SYMBOL_GPL(proc_dopipe_max_size);
 EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
 EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
 EXPORT_SYMBOL(proc_dostring);
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 4559e91..4e62a4a 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -194,11 +194,7 @@ static int fill_stats_for_pid(pid_t pid, struct taskstats *stats)
 {
 	struct task_struct *tsk;
 
-	rcu_read_lock();
-	tsk = find_task_by_vpid(pid);
-	if (tsk)
-		get_task_struct(tsk);
-	rcu_read_unlock();
+	tsk = find_get_task_by_vpid(pid);
 	if (!tsk)
 		return -ESRCH;
 	fill_stats(current_user_ns(), task_active_pid_ns(current), tsk, stats);
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index ae0c8a4..2378810 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -37,7 +37,6 @@
 #include <linux/hrtimer.h>
 #include <linux/notifier.h>
 #include <linux/syscalls.h>
-#include <linux/kallsyms.h>
 #include <linux/interrupt.h>
 #include <linux/tick.h>
 #include <linux/seq_file.h>
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 64d7c19..b66c264 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -217,7 +217,7 @@
 config FRAME_WARN
 	int "Warn for stack frames larger than (needs gcc 4.4)"
 	range 0 8192
-	default 0 if KASAN
+	default 3072 if KASAN_EXTRA
 	default 2048 if GCC_PLUGIN_LATENT_ENTROPY
 	default 1280 if (!64BIT && PARISC)
 	default 1024 if (!64BIT && !PARISC)
@@ -1641,7 +1641,10 @@
 
 	  If unsure, say N.
 
-menu "Runtime Testing"
+menuconfig RUNTIME_TESTING_MENU
+	bool "Runtime Testing"
+
+if RUNTIME_TESTING_MENU
 
 config LKDTM
 	tristate "Linux Kernel Dump Test Tool Module"
@@ -1841,7 +1844,7 @@
 
 	  If unsure, say N.
 
-config TEST_FIND_BIT
+config FIND_BIT_BENCHMARK
 	tristate "Test find_bit functions"
 	default n
 	help
@@ -1929,7 +1932,7 @@
 
 	  If unsure, say N.
 
-endmenu # runtime tests
+endif # RUNTIME_TESTING_MENU
 
 config MEMTEST
 	bool "Memtest"
diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan
index bd38aab..3d35d06 100644
--- a/lib/Kconfig.kasan
+++ b/lib/Kconfig.kasan
@@ -20,6 +20,17 @@
 	  Currently CONFIG_KASAN doesn't work with CONFIG_DEBUG_SLAB
 	  (the resulting kernel does not boot).
 
+config KASAN_EXTRA
+	bool "KAsan: extra checks"
+	depends on KASAN && DEBUG_KERNEL && !COMPILE_TEST
+	help
+	  This enables further checks in the kernel address sanitizer, for now
+	  it only includes the address-use-after-scope check that can lead
+	  to excessive kernel stack usage, frame size warnings and longer
+	  compile time.
+	  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 has more
+
+
 choice
 	prompt "Instrumentation type"
 	depends on KASAN
diff --git a/lib/Makefile b/lib/Makefile
index 7adb066..a90d4fc 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -46,8 +46,8 @@
 obj-y += hexdump.o
 obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
 obj-y += kstrtox.o
+obj-$(CONFIG_FIND_BIT_BENCHMARK) += find_bit_benchmark.o
 obj-$(CONFIG_TEST_BPF) += test_bpf.o
-obj-$(CONFIG_TEST_FIND_BIT) += test_find_bit.o
 obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
 obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o
 obj-$(CONFIG_TEST_HASH) += test_hash.o test_siphash.o
diff --git a/lib/bitmap.c b/lib/bitmap.c
index d8f0c09..9e498c7 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -1106,93 +1106,6 @@ int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order)
 EXPORT_SYMBOL(bitmap_allocate_region);
 
 /**
- * bitmap_from_u32array - copy the contents of a u32 array of bits to bitmap
- *	@bitmap: array of unsigned longs, the destination bitmap, non NULL
- *	@nbits: number of bits in @bitmap
- *	@buf: array of u32 (in host byte order), the source bitmap, non NULL
- *	@nwords: number of u32 words in @buf
- *
- * copy min(nbits, 32*nwords) bits from @buf to @bitmap, remaining
- * bits between nword and nbits in @bitmap (if any) are cleared. In
- * last word of @bitmap, the bits beyond nbits (if any) are kept
- * unchanged.
- *
- * Return the number of bits effectively copied.
- */
-unsigned int
-bitmap_from_u32array(unsigned long *bitmap, unsigned int nbits,
-		     const u32 *buf, unsigned int nwords)
-{
-	unsigned int dst_idx, src_idx;
-
-	for (src_idx = dst_idx = 0; dst_idx < BITS_TO_LONGS(nbits); ++dst_idx) {
-		unsigned long part = 0;
-
-		if (src_idx < nwords)
-			part = buf[src_idx++];
-
-#if BITS_PER_LONG == 64
-		if (src_idx < nwords)
-			part |= ((unsigned long) buf[src_idx++]) << 32;
-#endif
-
-		if (dst_idx < nbits/BITS_PER_LONG)
-			bitmap[dst_idx] = part;
-		else {
-			unsigned long mask = BITMAP_LAST_WORD_MASK(nbits);
-
-			bitmap[dst_idx] = (bitmap[dst_idx] & ~mask)
-				| (part & mask);
-		}
-	}
-
-	return min_t(unsigned int, nbits, 32*nwords);
-}
-EXPORT_SYMBOL(bitmap_from_u32array);
-
-/**
- * bitmap_to_u32array - copy the contents of bitmap to a u32 array of bits
- *	@buf: array of u32 (in host byte order), the dest bitmap, non NULL
- *	@nwords: number of u32 words in @buf
- *	@bitmap: array of unsigned longs, the source bitmap, non NULL
- *	@nbits: number of bits in @bitmap
- *
- * copy min(nbits, 32*nwords) bits from @bitmap to @buf. Remaining
- * bits after nbits in @buf (if any) are cleared.
- *
- * Return the number of bits effectively copied.
- */
-unsigned int
-bitmap_to_u32array(u32 *buf, unsigned int nwords,
-		   const unsigned long *bitmap, unsigned int nbits)
-{
-	unsigned int dst_idx = 0, src_idx = 0;
-
-	while (dst_idx < nwords) {
-		unsigned long part = 0;
-
-		if (src_idx < BITS_TO_LONGS(nbits)) {
-			part = bitmap[src_idx];
-			if (src_idx >= nbits/BITS_PER_LONG)
-				part &= BITMAP_LAST_WORD_MASK(nbits);
-			src_idx++;
-		}
-
-		buf[dst_idx++] = part & 0xffffffffUL;
-
-#if BITS_PER_LONG == 64
-		if (dst_idx < nwords) {
-			part >>= 32;
-			buf[dst_idx++] = part & 0xffffffffUL;
-		}
-#endif
-	}
-
-	return min_t(unsigned int, nbits, 32*nwords);
-}
-EXPORT_SYMBOL(bitmap_to_u32array);
-
-/**
  * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order.
  * @dst:   destination buffer
  * @src:   bitmap to copy
@@ -1214,3 +1127,59 @@ void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int n
 }
 EXPORT_SYMBOL(bitmap_copy_le);
 #endif
+
+#if BITS_PER_LONG == 64
+/**
+ * bitmap_from_arr32 - copy the contents of u32 array of bits to bitmap
+ *	@bitmap: array of unsigned longs, the destination bitmap
+ *	@buf: array of u32 (in host byte order), the source bitmap
+ *	@nbits: number of bits in @bitmap
+ */
+void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf,
+						unsigned int nbits)
+{
+	unsigned int i, halfwords;
+
+	if (!nbits)
+		return;
+
+	halfwords = DIV_ROUND_UP(nbits, 32);
+	for (i = 0; i < halfwords; i++) {
+		bitmap[i/2] = (unsigned long) buf[i];
+		if (++i < halfwords)
+			bitmap[i/2] |= ((unsigned long) buf[i]) << 32;
+	}
+
+	/* Clear tail bits in last word beyond nbits. */
+	if (nbits % BITS_PER_LONG)
+		bitmap[(halfwords - 1) / 2] &= BITMAP_LAST_WORD_MASK(nbits);
+}
+EXPORT_SYMBOL(bitmap_from_arr32);
+
+/**
+ * bitmap_to_arr32 - copy the contents of bitmap to a u32 array of bits
+ *	@buf: array of u32 (in host byte order), the dest bitmap
+ *	@bitmap: array of unsigned longs, the source bitmap
+ *	@nbits: number of bits in @bitmap
+ */
+void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap, unsigned int nbits)
+{
+	unsigned int i, halfwords;
+
+	if (!nbits)
+		return;
+
+	halfwords = DIV_ROUND_UP(nbits, 32);
+	for (i = 0; i < halfwords; i++) {
+		buf[i] = (u32) (bitmap[i/2] & UINT_MAX);
+		if (++i < halfwords)
+			buf[i] = (u32) (bitmap[i/2] >> 32);
+	}
+
+	/* Clear tail bits in last element of array beyond nbits. */
+	if (nbits % BITS_PER_LONG)
+		buf[halfwords - 1] &= (u32) (UINT_MAX >> ((-nbits) & 31));
+}
+EXPORT_SYMBOL(bitmap_to_arr32);
+
+#endif
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 35fe142..beca624 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -33,10 +33,11 @@ EXPORT_SYMBOL(cpumask_next);
 int cpumask_next_and(int n, const struct cpumask *src1p,
 		     const struct cpumask *src2p)
 {
-	while ((n = cpumask_next(n, src1p)) < nr_cpu_ids)
-		if (cpumask_test_cpu(n, src2p))
-			break;
-	return n;
+	/* -1 is a legal arg here. */
+	if (n != -1)
+		cpumask_check(n);
+	return find_next_and_bit(cpumask_bits(src1p), cpumask_bits(src2p),
+		nr_cpumask_bits, n + 1);
 }
 EXPORT_SYMBOL(cpumask_next_and);
 
diff --git a/lib/find_bit.c b/lib/find_bit.c
index 6ed74f7..ee3df93 100644
--- a/lib/find_bit.c
+++ b/lib/find_bit.c
@@ -21,22 +21,29 @@
 #include <linux/export.h>
 #include <linux/kernel.h>
 
-#if !defined(find_next_bit) || !defined(find_next_zero_bit)
+#if !defined(find_next_bit) || !defined(find_next_zero_bit) || \
+		!defined(find_next_and_bit)
 
 /*
- * This is a common helper function for find_next_bit and
- * find_next_zero_bit.  The difference is the "invert" argument, which
- * is XORed with each fetched word before searching it for one bits.
+ * This is a common helper function for find_next_bit, find_next_zero_bit, and
+ * find_next_and_bit. The differences are:
+ *  - The "invert" argument, which is XORed with each fetched word before
+ *    searching it for one bits.
+ *  - The optional "addr2", which is anded with "addr1" if present.
  */
-static unsigned long _find_next_bit(const unsigned long *addr,
-		unsigned long nbits, unsigned long start, unsigned long invert)
+static inline unsigned long _find_next_bit(const unsigned long *addr1,
+		const unsigned long *addr2, unsigned long nbits,
+		unsigned long start, unsigned long invert)
 {
 	unsigned long tmp;
 
 	if (unlikely(start >= nbits))
 		return nbits;
 
-	tmp = addr[start / BITS_PER_LONG] ^ invert;
+	tmp = addr1[start / BITS_PER_LONG];
+	if (addr2)
+		tmp &= addr2[start / BITS_PER_LONG];
+	tmp ^= invert;
 
 	/* Handle 1st word. */
 	tmp &= BITMAP_FIRST_WORD_MASK(start);
@@ -47,7 +54,10 @@ static unsigned long _find_next_bit(const unsigned long *addr,
 		if (start >= nbits)
 			return nbits;
 
-		tmp = addr[start / BITS_PER_LONG] ^ invert;
+		tmp = addr1[start / BITS_PER_LONG];
+		if (addr2)
+			tmp &= addr2[start / BITS_PER_LONG];
+		tmp ^= invert;
 	}
 
 	return min(start + __ffs(tmp), nbits);
@@ -61,7 +71,7 @@ static unsigned long _find_next_bit(const unsigned long *addr,
 unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
 			    unsigned long offset)
 {
-	return _find_next_bit(addr, size, offset, 0UL);
+	return _find_next_bit(addr, NULL, size, offset, 0UL);
 }
 EXPORT_SYMBOL(find_next_bit);
 #endif
@@ -70,11 +80,21 @@ EXPORT_SYMBOL(find_next_bit);
 unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
 				 unsigned long offset)
 {
-	return _find_next_bit(addr, size, offset, ~0UL);
+	return _find_next_bit(addr, NULL, size, offset, ~0UL);
 }
 EXPORT_SYMBOL(find_next_zero_bit);
 #endif
 
+#if !defined(find_next_and_bit)
+unsigned long find_next_and_bit(const unsigned long *addr1,
+		const unsigned long *addr2, unsigned long size,
+		unsigned long offset)
+{
+	return _find_next_bit(addr1, addr2, size, offset, 0UL);
+}
+EXPORT_SYMBOL(find_next_and_bit);
+#endif
+
 #ifndef find_first_bit
 /*
  * Find the first set bit in a memory region.
@@ -146,15 +166,19 @@ static inline unsigned long ext2_swab(const unsigned long y)
 }
 
 #if !defined(find_next_bit_le) || !defined(find_next_zero_bit_le)
-static unsigned long _find_next_bit_le(const unsigned long *addr,
-		unsigned long nbits, unsigned long start, unsigned long invert)
+static inline unsigned long _find_next_bit_le(const unsigned long *addr1,
+		const unsigned long *addr2, unsigned long nbits,
+		unsigned long start, unsigned long invert)
 {
 	unsigned long tmp;
 
 	if (unlikely(start >= nbits))
 		return nbits;
 
-	tmp = addr[start / BITS_PER_LONG] ^ invert;
+	tmp = addr1[start / BITS_PER_LONG];
+	if (addr2)
+		tmp &= addr2[start / BITS_PER_LONG];
+	tmp ^= invert;
 
 	/* Handle 1st word. */
 	tmp &= ext2_swab(BITMAP_FIRST_WORD_MASK(start));
@@ -165,7 +189,10 @@ static unsigned long _find_next_bit_le(const unsigned long *addr,
 		if (start >= nbits)
 			return nbits;
 
-		tmp = addr[start / BITS_PER_LONG] ^ invert;
+		tmp = addr1[start / BITS_PER_LONG];
+		if (addr2)
+			tmp &= addr2[start / BITS_PER_LONG];
+		tmp ^= invert;
 	}
 
 	return min(start + __ffs(ext2_swab(tmp)), nbits);
@@ -176,7 +203,7 @@ static unsigned long _find_next_bit_le(const unsigned long *addr,
 unsigned long find_next_zero_bit_le(const void *addr, unsigned
 		long size, unsigned long offset)
 {
-	return _find_next_bit_le(addr, size, offset, ~0UL);
+	return _find_next_bit_le(addr, NULL, size, offset, ~0UL);
 }
 EXPORT_SYMBOL(find_next_zero_bit_le);
 #endif
@@ -185,7 +212,7 @@ EXPORT_SYMBOL(find_next_zero_bit_le);
 unsigned long find_next_bit_le(const void *addr, unsigned
 		long size, unsigned long offset)
 {
-	return _find_next_bit_le(addr, size, offset, 0UL);
+	return _find_next_bit_le(addr, NULL, size, offset, 0UL);
 }
 EXPORT_SYMBOL(find_next_bit_le);
 #endif
diff --git a/lib/test_find_bit.c b/lib/find_bit_benchmark.c
similarity index 69%
rename from lib/test_find_bit.c
rename to lib/find_bit_benchmark.c
index f4394a3..5985a25 100644
--- a/lib/test_find_bit.c
+++ b/lib/find_bit_benchmark.c
@@ -35,6 +35,7 @@
 #define SPARSE		500
 
 static DECLARE_BITMAP(bitmap, BITMAP_LEN) __initdata;
+static DECLARE_BITMAP(bitmap2, BITMAP_LEN) __initdata;
 
 /*
  * This is Schlemiel the Painter's algorithm. It should be called after
@@ -43,16 +44,15 @@ static DECLARE_BITMAP(bitmap, BITMAP_LEN) __initdata;
 static int __init test_find_first_bit(void *bitmap, unsigned long len)
 {
 	unsigned long i, cnt;
-	cycles_t cycles;
+	ktime_t time;
 
-	cycles = get_cycles();
+	time = ktime_get();
 	for (cnt = i = 0; i < len; cnt++) {
 		i = find_first_bit(bitmap, len);
 		__clear_bit(i, bitmap);
 	}
-	cycles = get_cycles() - cycles;
-	pr_err("find_first_bit:\t\t%llu cycles,\t%ld iterations\n",
-	       (u64)cycles, cnt);
+	time = ktime_get() - time;
+	pr_err("find_first_bit:     %18llu ns, %6ld iterations\n", time, cnt);
 
 	return 0;
 }
@@ -60,14 +60,13 @@ static int __init test_find_first_bit(void *bitmap, unsigned long len)
 static int __init test_find_next_bit(const void *bitmap, unsigned long len)
 {
 	unsigned long i, cnt;
-	cycles_t cycles;
+	ktime_t time;
 
-	cycles = get_cycles();
+	time = ktime_get();
 	for (cnt = i = 0; i < BITMAP_LEN; cnt++)
 		i = find_next_bit(bitmap, BITMAP_LEN, i) + 1;
-	cycles = get_cycles() - cycles;
-	pr_err("find_next_bit:\t\t%llu cycles,\t%ld iterations\n",
-	       (u64)cycles, cnt);
+	time = ktime_get() - time;
+	pr_err("find_next_bit:      %18llu ns, %6ld iterations\n", time, cnt);
 
 	return 0;
 }
@@ -75,14 +74,13 @@ static int __init test_find_next_bit(const void *bitmap, unsigned long len)
 static int __init test_find_next_zero_bit(const void *bitmap, unsigned long len)
 {
 	unsigned long i, cnt;
-	cycles_t cycles;
+	ktime_t time;
 
-	cycles = get_cycles();
+	time = ktime_get();
 	for (cnt = i = 0; i < BITMAP_LEN; cnt++)
 		i = find_next_zero_bit(bitmap, len, i) + 1;
-	cycles = get_cycles() - cycles;
-	pr_err("find_next_zero_bit:\t%llu cycles,\t%ld iterations\n",
-	       (u64)cycles, cnt);
+	time = ktime_get() - time;
+	pr_err("find_next_zero_bit: %18llu ns, %6ld iterations\n", time, cnt);
 
 	return 0;
 }
@@ -90,9 +88,9 @@ static int __init test_find_next_zero_bit(const void *bitmap, unsigned long len)
 static int __init test_find_last_bit(const void *bitmap, unsigned long len)
 {
 	unsigned long l, cnt = 0;
-	cycles_t cycles;
+	ktime_t time;
 
-	cycles = get_cycles();
+	time = ktime_get();
 	do {
 		cnt++;
 		l = find_last_bit(bitmap, len);
@@ -100,9 +98,24 @@ static int __init test_find_last_bit(const void *bitmap, unsigned long len)
 			break;
 		len = l;
 	} while (len);
+	time = ktime_get() - time;
+	pr_err("find_last_bit:      %18llu ns, %6ld iterations\n", time, cnt);
+
+	return 0;
+}
+
+static int __init test_find_next_and_bit(const void *bitmap,
+		const void *bitmap2, unsigned long len)
+{
+	unsigned long i, cnt;
+	cycles_t cycles;
+
+	cycles = get_cycles();
+	for (cnt = i = 0; i < BITMAP_LEN; cnt++)
+		i = find_next_and_bit(bitmap, bitmap2, BITMAP_LEN, i+1);
 	cycles = get_cycles() - cycles;
-	pr_err("find_last_bit:\t\t%llu cycles,\t%ld iterations\n",
-	       (u64)cycles, cnt);
+	pr_err("find_next_and_bit:\t\t%llu cycles, %ld iterations\n",
+		(u64)cycles, cnt);
 
 	return 0;
 }
@@ -114,31 +127,36 @@ static int __init find_bit_test(void)
 	pr_err("\nStart testing find_bit() with random-filled bitmap\n");
 
 	get_random_bytes(bitmap, sizeof(bitmap));
+	get_random_bytes(bitmap2, sizeof(bitmap2));
 
 	test_find_next_bit(bitmap, BITMAP_LEN);
 	test_find_next_zero_bit(bitmap, BITMAP_LEN);
 	test_find_last_bit(bitmap, BITMAP_LEN);
 	test_find_first_bit(bitmap, BITMAP_LEN);
+	test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN);
 
 	pr_err("\nStart testing find_bit() with sparse bitmap\n");
 
 	bitmap_zero(bitmap, BITMAP_LEN);
+	bitmap_zero(bitmap2, BITMAP_LEN);
 
-	while (nbits--)
+	while (nbits--) {
 		__set_bit(prandom_u32() % BITMAP_LEN, bitmap);
+		__set_bit(prandom_u32() % BITMAP_LEN, bitmap2);
+	}
 
 	test_find_next_bit(bitmap, BITMAP_LEN);
 	test_find_next_zero_bit(bitmap, BITMAP_LEN);
 	test_find_last_bit(bitmap, BITMAP_LEN);
 	test_find_first_bit(bitmap, BITMAP_LEN);
+	test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN);
 
-	return 0;
+	/*
+	 * Everything is OK. Return error just to let user run benchmark
+	 * again without annoying rmmod.
+	 */
+	return -EINVAL;
 }
 module_init(find_bit_test);
 
-static void __exit test_find_bit_cleanup(void)
-{
-}
-module_exit(test_find_bit_cleanup);
-
 MODULE_LICENSE("GPL");
diff --git a/lib/pci_iomap.c b/lib/pci_iomap.c
index c10fba4..2d3eb1c 100644
--- a/lib/pci_iomap.c
+++ b/lib/pci_iomap.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Implement the default iomap interfaces
  *
diff --git a/lib/stackdepot.c b/lib/stackdepot.c
index f87d138..e513459 100644
--- a/lib/stackdepot.c
+++ b/lib/stackdepot.c
@@ -163,6 +163,21 @@ static inline u32 hash_stack(unsigned long *entries, unsigned int size)
 			       STACK_HASH_SEED);
 }
 
+/* Use our own, non-instrumented version of memcmp().
+ *
+ * We actually don't care about the order, just the equality.
+ */
+static inline
+int stackdepot_memcmp(const unsigned long *u1, const unsigned long *u2,
+			unsigned int n)
+{
+	for ( ; n-- ; u1++, u2++) {
+		if (*u1 != *u2)
+			return 1;
+	}
+	return 0;
+}
+
 /* Find a stack that is equal to the one stored in entries in the hash */
 static inline struct stack_record *find_stack(struct stack_record *bucket,
 					     unsigned long *entries, int size,
@@ -173,10 +188,8 @@ static inline struct stack_record *find_stack(struct stack_record *bucket,
 	for (found = bucket; found; found = found->next) {
 		if (found->hash == hash &&
 		    found->size == size &&
-		    !memcmp(entries, found->entries,
-			    size * sizeof(unsigned long))) {
+		    !stackdepot_memcmp(entries, found->entries, size))
 			return found;
-		}
 	}
 	return NULL;
 }
diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c
index aa1f266..b3f235b 100644
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -23,7 +23,7 @@ __check_eq_uint(const char *srcfile, unsigned int line,
 		const unsigned int exp_uint, unsigned int x)
 {
 	if (exp_uint != x) {
-		pr_warn("[%s:%u] expected %u, got %u\n",
+		pr_err("[%s:%u] expected %u, got %u\n",
 			srcfile, line, exp_uint, x);
 		return false;
 	}
@@ -33,19 +33,13 @@ __check_eq_uint(const char *srcfile, unsigned int line,
 
 static bool __init
 __check_eq_bitmap(const char *srcfile, unsigned int line,
-		  const unsigned long *exp_bmap, unsigned int exp_nbits,
-		  const unsigned long *bmap, unsigned int nbits)
+		  const unsigned long *exp_bmap, const unsigned long *bmap,
+		  unsigned int nbits)
 {
-	if (exp_nbits != nbits) {
-		pr_warn("[%s:%u] bitmap length mismatch: expected %u, got %u\n",
-			srcfile, line, exp_nbits, nbits);
-		return false;
-	}
-
 	if (!bitmap_equal(exp_bmap, bmap, nbits)) {
 		pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n",
 			srcfile, line,
-			exp_nbits, exp_bmap, nbits, bmap);
+			nbits, exp_bmap, nbits, bmap);
 		return false;
 	}
 	return true;
@@ -69,6 +63,10 @@ __check_eq_pbl(const char *srcfile, unsigned int line,
 static bool __init
 __check_eq_u32_array(const char *srcfile, unsigned int line,
 		     const u32 *exp_arr, unsigned int exp_len,
+		     const u32 *arr, unsigned int len) __used;
+static bool __init
+__check_eq_u32_array(const char *srcfile, unsigned int line,
+		     const u32 *exp_arr, unsigned int exp_len,
 		     const u32 *arr, unsigned int len)
 {
 	if (exp_len != len) {
@@ -107,7 +105,65 @@ __check_eq_u32_array(const char *srcfile, unsigned int line,
 #define expect_eq_pbl(...)		__expect_eq(pbl, ##__VA_ARGS__)
 #define expect_eq_u32_array(...)	__expect_eq(u32_array, ##__VA_ARGS__)
 
-static void __init test_zero_fill_copy(void)
+static void __init test_zero_clear(void)
+{
+	DECLARE_BITMAP(bmap, 1024);
+
+	/* Known way to set all bits */
+	memset(bmap, 0xff, 128);
+
+	expect_eq_pbl("0-22", bmap, 23);
+	expect_eq_pbl("0-1023", bmap, 1024);
+
+	/* single-word bitmaps */
+	bitmap_clear(bmap, 0, 9);
+	expect_eq_pbl("9-1023", bmap, 1024);
+
+	bitmap_zero(bmap, 35);
+	expect_eq_pbl("64-1023", bmap, 1024);
+
+	/* cross boundaries operations */
+	bitmap_clear(bmap, 79, 19);
+	expect_eq_pbl("64-78,98-1023", bmap, 1024);
+
+	bitmap_zero(bmap, 115);
+	expect_eq_pbl("128-1023", bmap, 1024);
+
+	/* Zeroing entire area */
+	bitmap_zero(bmap, 1024);
+	expect_eq_pbl("", bmap, 1024);
+}
+
+static void __init test_fill_set(void)
+{
+	DECLARE_BITMAP(bmap, 1024);
+
+	/* Known way to clear all bits */
+	memset(bmap, 0x00, 128);
+
+	expect_eq_pbl("", bmap, 23);
+	expect_eq_pbl("", bmap, 1024);
+
+	/* single-word bitmaps */
+	bitmap_set(bmap, 0, 9);
+	expect_eq_pbl("0-8", bmap, 1024);
+
+	bitmap_fill(bmap, 35);
+	expect_eq_pbl("0-63", bmap, 1024);
+
+	/* cross boundaries operations */
+	bitmap_set(bmap, 79, 19);
+	expect_eq_pbl("0-63,79-97", bmap, 1024);
+
+	bitmap_fill(bmap, 115);
+	expect_eq_pbl("0-127", bmap, 1024);
+
+	/* Zeroing entire area */
+	bitmap_fill(bmap, 1024);
+	expect_eq_pbl("0-1023", bmap, 1024);
+}
+
+static void __init test_copy(void)
 {
 	DECLARE_BITMAP(bmap1, 1024);
 	DECLARE_BITMAP(bmap2, 1024);
@@ -116,36 +172,20 @@ static void __init test_zero_fill_copy(void)
 	bitmap_zero(bmap2, 1024);
 
 	/* single-word bitmaps */
-	expect_eq_pbl("", bmap1, 23);
-
-	bitmap_fill(bmap1, 19);
-	expect_eq_pbl("0-18", bmap1, 1024);
-
+	bitmap_set(bmap1, 0, 19);
 	bitmap_copy(bmap2, bmap1, 23);
 	expect_eq_pbl("0-18", bmap2, 1024);
 
-	bitmap_fill(bmap2, 23);
-	expect_eq_pbl("0-22", bmap2, 1024);
-
+	bitmap_set(bmap2, 0, 23);
 	bitmap_copy(bmap2, bmap1, 23);
 	expect_eq_pbl("0-18", bmap2, 1024);
 
-	bitmap_zero(bmap1, 23);
-	expect_eq_pbl("", bmap1, 1024);
-
 	/* multi-word bitmaps */
-	bitmap_zero(bmap1, 1024);
-	expect_eq_pbl("", bmap1, 1024);
-
-	bitmap_fill(bmap1, 109);
-	expect_eq_pbl("0-108", bmap1, 1024);
-
+	bitmap_set(bmap1, 0, 109);
 	bitmap_copy(bmap2, bmap1, 1024);
 	expect_eq_pbl("0-108", bmap2, 1024);
 
 	bitmap_fill(bmap2, 1024);
-	expect_eq_pbl("0-1023", bmap2, 1024);
-
 	bitmap_copy(bmap2, bmap1, 1024);
 	expect_eq_pbl("0-108", bmap2, 1024);
 
@@ -160,9 +200,6 @@ static void __init test_zero_fill_copy(void)
 	bitmap_fill(bmap2, 1024);
 	bitmap_copy(bmap2, bmap1, 97);  /* ... but aligned on word length */
 	expect_eq_pbl("0-108,128-1023", bmap2, 1024);
-
-	bitmap_zero(bmap2, 97);  /* ... but 0-padded til word length */
-	expect_eq_pbl("128-1023", bmap2, 1024);
 }
 
 #define PARSE_TIME 0x1
@@ -255,171 +292,29 @@ static void __init test_bitmap_parselist(void)
 	}
 }
 
-static void __init test_bitmap_u32_array_conversions(void)
+static void __init test_bitmap_arr32(void)
 {
-	DECLARE_BITMAP(bmap1, 1024);
-	DECLARE_BITMAP(bmap2, 1024);
-	u32 exp_arr[32], arr[32];
-	unsigned nbits;
+	unsigned int nbits, next_bit, len = sizeof(exp) * 8;
+	u32 arr[sizeof(exp) / 4];
+	DECLARE_BITMAP(bmap2, len);
 
-	for (nbits = 0 ; nbits < 257 ; ++nbits) {
-		const unsigned int used_u32s = DIV_ROUND_UP(nbits, 32);
-		unsigned int i, rv;
+	memset(arr, 0xa5, sizeof(arr));
 
-		bitmap_zero(bmap1, nbits);
-		bitmap_set(bmap1, nbits, 1024 - nbits);  /* garbage */
+	for (nbits = 0; nbits < len; ++nbits) {
+		bitmap_to_arr32(arr, exp, nbits);
+		bitmap_from_arr32(bmap2, arr, nbits);
+		expect_eq_bitmap(bmap2, exp, nbits);
 
-		memset(arr, 0xff, sizeof(arr));
-		rv = bitmap_to_u32array(arr, used_u32s, bmap1, nbits);
-		expect_eq_uint(nbits, rv);
+		next_bit = find_next_bit(bmap2,
+				round_up(nbits, BITS_PER_LONG), nbits);
+		if (next_bit < round_up(nbits, BITS_PER_LONG))
+			pr_err("bitmap_copy_arr32(nbits == %d:"
+				" tail is not safely cleared: %d\n",
+				nbits, next_bit);
 
-		memset(exp_arr, 0xff, sizeof(exp_arr));
-		memset(exp_arr, 0, used_u32s*sizeof(*exp_arr));
-		expect_eq_u32_array(exp_arr, 32, arr, 32);
-
-		bitmap_fill(bmap2, 1024);
-		rv = bitmap_from_u32array(bmap2, nbits, arr, used_u32s);
-		expect_eq_uint(nbits, rv);
-		expect_eq_bitmap(bmap1, 1024, bmap2, 1024);
-
-		for (i = 0 ; i < nbits ; ++i) {
-			/*
-			 * test conversion bitmap -> u32[]
-			 */
-
-			bitmap_zero(bmap1, 1024);
-			__set_bit(i, bmap1);
-			bitmap_set(bmap1, nbits, 1024 - nbits);  /* garbage */
-
-			memset(arr, 0xff, sizeof(arr));
-			rv = bitmap_to_u32array(arr, used_u32s, bmap1, nbits);
-			expect_eq_uint(nbits, rv);
-
-			/* 1st used u32 words contain expected bit set, the
-			 * remaining words are left unchanged (0xff)
-			 */
-			memset(exp_arr, 0xff, sizeof(exp_arr));
-			memset(exp_arr, 0, used_u32s*sizeof(*exp_arr));
-			exp_arr[i/32] = (1U<<(i%32));
-			expect_eq_u32_array(exp_arr, 32, arr, 32);
-
-
-			/* same, with longer array to fill
-			 */
-			memset(arr, 0xff, sizeof(arr));
-			rv = bitmap_to_u32array(arr, 32, bmap1, nbits);
-			expect_eq_uint(nbits, rv);
-
-			/* 1st used u32 words contain expected bit set, the
-			 * remaining words are all 0s
-			 */
-			memset(exp_arr, 0, sizeof(exp_arr));
-			exp_arr[i/32] = (1U<<(i%32));
-			expect_eq_u32_array(exp_arr, 32, arr, 32);
-
-			/*
-			 * test conversion u32[] -> bitmap
-			 */
-
-			/* the 1st nbits of bmap2 are identical to
-			 * bmap1, the remaining bits of bmap2 are left
-			 * unchanged (all 1s)
-			 */
-			bitmap_fill(bmap2, 1024);
-			rv = bitmap_from_u32array(bmap2, nbits,
-						  exp_arr, used_u32s);
-			expect_eq_uint(nbits, rv);
-
-			expect_eq_bitmap(bmap1, 1024, bmap2, 1024);
-
-			/* same, with more bits to fill
-			 */
-			memset(arr, 0xff, sizeof(arr));  /* garbage */
-			memset(arr, 0, used_u32s*sizeof(u32));
-			arr[i/32] = (1U<<(i%32));
-
-			bitmap_fill(bmap2, 1024);
-			rv = bitmap_from_u32array(bmap2, 1024, arr, used_u32s);
-			expect_eq_uint(used_u32s*32, rv);
-
-			/* the 1st nbits of bmap2 are identical to
-			 * bmap1, the remaining bits of bmap2 are cleared
-			 */
-			bitmap_zero(bmap1, 1024);
-			__set_bit(i, bmap1);
-			expect_eq_bitmap(bmap1, 1024, bmap2, 1024);
-
-
-			/*
-			 * test short conversion bitmap -> u32[] (1
-			 * word too short)
-			 */
-			if (used_u32s > 1) {
-				bitmap_zero(bmap1, 1024);
-				__set_bit(i, bmap1);
-				bitmap_set(bmap1, nbits,
-					   1024 - nbits);  /* garbage */
-				memset(arr, 0xff, sizeof(arr));
-
-				rv = bitmap_to_u32array(arr, used_u32s - 1,
-							bmap1, nbits);
-				expect_eq_uint((used_u32s - 1)*32, rv);
-
-				/* 1st used u32 words contain expected
-				 * bit set, the remaining words are
-				 * left unchanged (0xff)
-				 */
-				memset(exp_arr, 0xff, sizeof(exp_arr));
-				memset(exp_arr, 0,
-				       (used_u32s-1)*sizeof(*exp_arr));
-				if ((i/32) < (used_u32s - 1))
-					exp_arr[i/32] = (1U<<(i%32));
-				expect_eq_u32_array(exp_arr, 32, arr, 32);
-			}
-
-			/*
-			 * test short conversion u32[] -> bitmap (3
-			 * bits too short)
-			 */
-			if (nbits > 3) {
-				memset(arr, 0xff, sizeof(arr));  /* garbage */
-				memset(arr, 0, used_u32s*sizeof(*arr));
-				arr[i/32] = (1U<<(i%32));
-
-				bitmap_zero(bmap1, 1024);
-				rv = bitmap_from_u32array(bmap1, nbits - 3,
-							  arr, used_u32s);
-				expect_eq_uint(nbits - 3, rv);
-
-				/* we are expecting the bit < nbits -
-				 * 3 (none otherwise), and the rest of
-				 * bmap1 unchanged (0-filled)
-				 */
-				bitmap_zero(bmap2, 1024);
-				if (i < nbits - 3)
-					__set_bit(i, bmap2);
-				expect_eq_bitmap(bmap2, 1024, bmap1, 1024);
-
-				/* do the same with bmap1 initially
-				 * 1-filled
-				 */
-
-				bitmap_fill(bmap1, 1024);
-				rv = bitmap_from_u32array(bmap1, nbits - 3,
-							 arr, used_u32s);
-				expect_eq_uint(nbits - 3, rv);
-
-				/* we are expecting the bit < nbits -
-				 * 3 (none otherwise), and the rest of
-				 * bmap1 unchanged (1-filled)
-				 */
-				bitmap_zero(bmap2, 1024);
-				if (i < nbits - 3)
-					__set_bit(i, bmap2);
-				bitmap_set(bmap2, nbits-3, 1024 - nbits + 3);
-				expect_eq_bitmap(bmap2, 1024, bmap1, 1024);
-			}
-		}
+		if (nbits < len - 32)
+			expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)],
+								0xa5a5a5a5);
 	}
 }
 
@@ -453,8 +348,10 @@ static void noinline __init test_mem_optimisations(void)
 
 static int __init test_bitmap_init(void)
 {
-	test_zero_fill_copy();
-	test_bitmap_u32_array_conversions();
+	test_zero_clear();
+	test_fill_set();
+	test_copy();
+	test_bitmap_arr32();
 	test_bitmap_parselist();
 	test_mem_optimisations();
 
diff --git a/lib/test_kasan.c b/lib/test_kasan.c
index ef1a3ac..98854a6 100644
--- a/lib/test_kasan.c
+++ b/lib/test_kasan.c
@@ -94,6 +94,37 @@ static noinline void __init kmalloc_pagealloc_oob_right(void)
 	ptr[size] = 0;
 	kfree(ptr);
 }
+
+static noinline void __init kmalloc_pagealloc_uaf(void)
+{
+	char *ptr;
+	size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
+
+	pr_info("kmalloc pagealloc allocation: use-after-free\n");
+	ptr = kmalloc(size, GFP_KERNEL);
+	if (!ptr) {
+		pr_err("Allocation failed\n");
+		return;
+	}
+
+	kfree(ptr);
+	ptr[0] = 0;
+}
+
+static noinline void __init kmalloc_pagealloc_invalid_free(void)
+{
+	char *ptr;
+	size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
+
+	pr_info("kmalloc pagealloc allocation: invalid-free\n");
+	ptr = kmalloc(size, GFP_KERNEL);
+	if (!ptr) {
+		pr_err("Allocation failed\n");
+		return;
+	}
+
+	kfree(ptr + 1);
+}
 #endif
 
 static noinline void __init kmalloc_large_oob_right(void)
@@ -388,7 +419,7 @@ static noinline void __init kasan_stack_oob(void)
 static noinline void __init ksize_unpoisons_memory(void)
 {
 	char *ptr;
-	size_t size = 123, real_size = size;
+	size_t size = 123, real_size;
 
 	pr_info("ksize() unpoisons the whole allocated chunk\n");
 	ptr = kmalloc(size, GFP_KERNEL);
@@ -472,6 +503,74 @@ static noinline void __init use_after_scope_test(void)
 	p[1023] = 1;
 }
 
+static noinline void __init kasan_alloca_oob_left(void)
+{
+	volatile int i = 10;
+	char alloca_array[i];
+	char *p = alloca_array - 1;
+
+	pr_info("out-of-bounds to left on alloca\n");
+	*(volatile char *)p;
+}
+
+static noinline void __init kasan_alloca_oob_right(void)
+{
+	volatile int i = 10;
+	char alloca_array[i];
+	char *p = alloca_array + i;
+
+	pr_info("out-of-bounds to right on alloca\n");
+	*(volatile char *)p;
+}
+
+static noinline void __init kmem_cache_double_free(void)
+{
+	char *p;
+	size_t size = 200;
+	struct kmem_cache *cache;
+
+	cache = kmem_cache_create("test_cache", size, 0, 0, NULL);
+	if (!cache) {
+		pr_err("Cache allocation failed\n");
+		return;
+	}
+	pr_info("double-free on heap object\n");
+	p = kmem_cache_alloc(cache, GFP_KERNEL);
+	if (!p) {
+		pr_err("Allocation failed\n");
+		kmem_cache_destroy(cache);
+		return;
+	}
+
+	kmem_cache_free(cache, p);
+	kmem_cache_free(cache, p);
+	kmem_cache_destroy(cache);
+}
+
+static noinline void __init kmem_cache_invalid_free(void)
+{
+	char *p;
+	size_t size = 200;
+	struct kmem_cache *cache;
+
+	cache = kmem_cache_create("test_cache", size, 0, SLAB_TYPESAFE_BY_RCU,
+				  NULL);
+	if (!cache) {
+		pr_err("Cache allocation failed\n");
+		return;
+	}
+	pr_info("invalid-free of heap object\n");
+	p = kmem_cache_alloc(cache, GFP_KERNEL);
+	if (!p) {
+		pr_err("Allocation failed\n");
+		kmem_cache_destroy(cache);
+		return;
+	}
+
+	kmem_cache_free(cache, p + 1);
+	kmem_cache_destroy(cache);
+}
+
 static int __init kmalloc_tests_init(void)
 {
 	/*
@@ -485,6 +584,8 @@ static int __init kmalloc_tests_init(void)
 	kmalloc_node_oob_right();
 #ifdef CONFIG_SLUB
 	kmalloc_pagealloc_oob_right();
+	kmalloc_pagealloc_uaf();
+	kmalloc_pagealloc_invalid_free();
 #endif
 	kmalloc_large_oob_right();
 	kmalloc_oob_krealloc_more();
@@ -502,9 +603,13 @@ static int __init kmalloc_tests_init(void)
 	memcg_accounted_kmem_cache();
 	kasan_stack_oob();
 	kasan_global_oob();
+	kasan_alloca_oob_left();
+	kasan_alloca_oob_right();
 	ksize_unpoisons_memory();
 	copy_user_test();
 	use_after_scope_test();
+	kmem_cache_double_free();
+	kmem_cache_invalid_free();
 
 	kasan_restore_multi_shot(multishot);
 
diff --git a/lib/test_sort.c b/lib/test_sort.c
index d389c1c..385c0ed 100644
--- a/lib/test_sort.c
+++ b/lib/test_sort.c
@@ -39,5 +39,11 @@ static int __init test_sort_init(void)
 	return err;
 }
 
+static void __exit test_sort_exit(void)
+{
+}
+
 module_init(test_sort_init);
+module_exit(test_sort_exit);
+
 MODULE_LICENSE("GPL");
diff --git a/lib/ubsan.c b/lib/ubsan.c
index fb0409d..59fee96 100644
--- a/lib/ubsan.c
+++ b/lib/ubsan.c
@@ -141,11 +141,6 @@ static void val_to_string(char *str, size_t size, struct type_descriptor *type,
 	}
 }
 
-static bool location_is_valid(struct source_location *loc)
-{
-	return loc->file_name != NULL;
-}
-
 static DEFINE_SPINLOCK(report_lock);
 
 static void ubsan_prologue(struct source_location *location,
@@ -265,14 +260,14 @@ void __ubsan_handle_divrem_overflow(struct overflow_data *data,
 }
 EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
 
-static void handle_null_ptr_deref(struct type_mismatch_data *data)
+static void handle_null_ptr_deref(struct type_mismatch_data_common *data)
 {
 	unsigned long flags;
 
-	if (suppress_report(&data->location))
+	if (suppress_report(data->location))
 		return;
 
-	ubsan_prologue(&data->location, &flags);
+	ubsan_prologue(data->location, &flags);
 
 	pr_err("%s null pointer of type %s\n",
 		type_check_kinds[data->type_check_kind],
@@ -281,15 +276,15 @@ static void handle_null_ptr_deref(struct type_mismatch_data *data)
 	ubsan_epilogue(&flags);
 }
 
-static void handle_missaligned_access(struct type_mismatch_data *data,
+static void handle_misaligned_access(struct type_mismatch_data_common *data,
 				unsigned long ptr)
 {
 	unsigned long flags;
 
-	if (suppress_report(&data->location))
+	if (suppress_report(data->location))
 		return;
 
-	ubsan_prologue(&data->location, &flags);
+	ubsan_prologue(data->location, &flags);
 
 	pr_err("%s misaligned address %p for type %s\n",
 		type_check_kinds[data->type_check_kind],
@@ -299,15 +294,15 @@ static void handle_missaligned_access(struct type_mismatch_data *data,
 	ubsan_epilogue(&flags);
 }
 
-static void handle_object_size_mismatch(struct type_mismatch_data *data,
+static void handle_object_size_mismatch(struct type_mismatch_data_common *data,
 					unsigned long ptr)
 {
 	unsigned long flags;
 
-	if (suppress_report(&data->location))
+	if (suppress_report(data->location))
 		return;
 
-	ubsan_prologue(&data->location, &flags);
+	ubsan_prologue(data->location, &flags);
 	pr_err("%s address %p with insufficient space\n",
 		type_check_kinds[data->type_check_kind],
 		(void *) ptr);
@@ -315,37 +310,46 @@ static void handle_object_size_mismatch(struct type_mismatch_data *data,
 	ubsan_epilogue(&flags);
 }
 
-void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
+static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data,
 				unsigned long ptr)
 {
 
 	if (!ptr)
 		handle_null_ptr_deref(data);
 	else if (data->alignment && !IS_ALIGNED(ptr, data->alignment))
-		handle_missaligned_access(data, ptr);
+		handle_misaligned_access(data, ptr);
 	else
 		handle_object_size_mismatch(data, ptr);
 }
+
+void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
+				unsigned long ptr)
+{
+	struct type_mismatch_data_common common_data = {
+		.location = &data->location,
+		.type = data->type,
+		.alignment = data->alignment,
+		.type_check_kind = data->type_check_kind
+	};
+
+	ubsan_type_mismatch_common(&common_data, ptr);
+}
 EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
 
-void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
+void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
+				unsigned long ptr)
 {
-	unsigned long flags;
 
-	if (suppress_report(&data->location))
-		return;
+	struct type_mismatch_data_common common_data = {
+		.location = &data->location,
+		.type = data->type,
+		.alignment = 1UL << data->log_alignment,
+		.type_check_kind = data->type_check_kind
+	};
 
-	ubsan_prologue(&data->location, &flags);
-
-	pr_err("null pointer returned from function declared to never return null\n");
-
-	if (location_is_valid(&data->attr_location))
-		print_source_location("returns_nonnull attribute specified in",
-				&data->attr_location);
-
-	ubsan_epilogue(&flags);
+	ubsan_type_mismatch_common(&common_data, ptr);
 }
-EXPORT_SYMBOL(__ubsan_handle_nonnull_return);
+EXPORT_SYMBOL(__ubsan_handle_type_mismatch_v1);
 
 void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
 					unsigned long bound)
diff --git a/lib/ubsan.h b/lib/ubsan.h
index 88f2355..f4d8d0b 100644
--- a/lib/ubsan.h
+++ b/lib/ubsan.h
@@ -37,17 +37,26 @@ struct type_mismatch_data {
 	unsigned char type_check_kind;
 };
 
+struct type_mismatch_data_v1 {
+	struct source_location location;
+	struct type_descriptor *type;
+	unsigned char log_alignment;
+	unsigned char type_check_kind;
+};
+
+struct type_mismatch_data_common {
+	struct source_location *location;
+	struct type_descriptor *type;
+	unsigned long alignment;
+	unsigned char type_check_kind;
+};
+
 struct nonnull_arg_data {
 	struct source_location location;
 	struct source_location attr_location;
 	int arg_index;
 };
 
-struct nonnull_return_data {
-	struct source_location location;
-	struct source_location attr_location;
-};
-
 struct vla_bound_data {
 	struct source_location location;
 	struct type_descriptor *type;
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 6aef642..9e19798 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -410,7 +410,7 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
 
 /**
  * free_bootmem - mark a page range as usable
- * @addr: starting physical address of the range
+ * @physaddr: starting physical address of the range
  * @size: size of the range in bytes
  *
  * Partial pages will be considered reserved and left as they are.
diff --git a/mm/gup.c b/mm/gup.c
index 9e17d8d..1b46e6e 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1394,7 +1394,6 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
 
 		VM_BUG_ON_PAGE(compound_head(page) != head, page);
 
-		put_dev_pagemap(pgmap);
 		SetPageReferenced(page);
 		pages[*nr] = page;
 		(*nr)++;
@@ -1404,6 +1403,8 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
 	ret = 1;
 
 pte_unmap:
+	if (pgmap)
+		put_dev_pagemap(pgmap);
 	pte_unmap(ptem);
 	return ret;
 }
@@ -1443,10 +1444,12 @@ static int __gup_device_huge(unsigned long pfn, unsigned long addr,
 		SetPageReferenced(page);
 		pages[*nr] = page;
 		get_page(page);
-		put_dev_pagemap(pgmap);
 		(*nr)++;
 		pfn++;
 	} while (addr += PAGE_SIZE, addr != end);
+
+	if (pgmap)
+		put_dev_pagemap(pgmap);
 	return 1;
 }
 
diff --git a/mm/hmm.c b/mm/hmm.c
index 979211c..320545b98 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -836,10 +836,10 @@ static void hmm_devmem_release(struct device *dev, void *data)
 
 	mem_hotplug_begin();
 	if (resource->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY)
-		__remove_pages(zone, start_pfn, npages);
+		__remove_pages(zone, start_pfn, npages, NULL);
 	else
 		arch_remove_memory(start_pfn << PAGE_SHIFT,
-				   npages << PAGE_SHIFT);
+				   npages << PAGE_SHIFT, NULL);
 	mem_hotplug_done();
 
 	hmm_devmem_radix_release(resource);
@@ -880,7 +880,7 @@ static int hmm_devmem_pages_create(struct hmm_devmem *devmem)
 	else
 		devmem->pagemap.type = MEMORY_DEVICE_PRIVATE;
 
-	devmem->pagemap.res = devmem->resource;
+	devmem->pagemap.res = *devmem->resource;
 	devmem->pagemap.page_fault = hmm_devmem_fault;
 	devmem->pagemap.page_free = hmm_devmem_free;
 	devmem->pagemap.dev = devmem->device;
@@ -929,17 +929,18 @@ static int hmm_devmem_pages_create(struct hmm_devmem *devmem)
 	 * want the linear mapping and thus use arch_add_memory().
 	 */
 	if (devmem->pagemap.type == MEMORY_DEVICE_PUBLIC)
-		ret = arch_add_memory(nid, align_start, align_size, false);
+		ret = arch_add_memory(nid, align_start, align_size, NULL,
+				false);
 	else
 		ret = add_pages(nid, align_start >> PAGE_SHIFT,
-				align_size >> PAGE_SHIFT, false);
+				align_size >> PAGE_SHIFT, NULL, false);
 	if (ret) {
 		mem_hotplug_done();
 		goto error_add_memory;
 	}
 	move_pfn_range_to_zone(&NODE_DATA(nid)->node_zones[ZONE_DEVICE],
 				align_start >> PAGE_SHIFT,
-				align_size >> PAGE_SHIFT);
+				align_size >> PAGE_SHIFT, NULL);
 	mem_hotplug_done();
 
 	for (pfn = devmem->pfn_first; pfn < devmem->pfn_last; pfn++) {
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c
index 405bba4..e13d911 100644
--- a/mm/kasan/kasan.c
+++ b/mm/kasan/kasan.c
@@ -5,7 +5,7 @@
  * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
  *
  * Some code borrowed from https://github.com/xairy/kasan-prototype by
- *        Andrey Konovalov <adech.fo@gmail.com>
+ *        Andrey Konovalov <andreyknvl@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -489,21 +489,17 @@ void kasan_slab_alloc(struct kmem_cache *cache, void *object, gfp_t flags)
 	kasan_kmalloc(cache, object, cache->object_size, flags);
 }
 
-static void kasan_poison_slab_free(struct kmem_cache *cache, void *object)
-{
-	unsigned long size = cache->object_size;
-	unsigned long rounded_up_size = round_up(size, KASAN_SHADOW_SCALE_SIZE);
-
-	/* RCU slabs could be legally used after free within the RCU period */
-	if (unlikely(cache->flags & SLAB_TYPESAFE_BY_RCU))
-		return;
-
-	kasan_poison_shadow(object, rounded_up_size, KASAN_KMALLOC_FREE);
-}
-
-bool kasan_slab_free(struct kmem_cache *cache, void *object)
+static bool __kasan_slab_free(struct kmem_cache *cache, void *object,
+			      unsigned long ip, bool quarantine)
 {
 	s8 shadow_byte;
+	unsigned long rounded_up_size;
+
+	if (unlikely(nearest_obj(cache, virt_to_head_page(object), object) !=
+	    object)) {
+		kasan_report_invalid_free(object, ip);
+		return true;
+	}
 
 	/* RCU slabs could be legally used after free within the RCU period */
 	if (unlikely(cache->flags & SLAB_TYPESAFE_BY_RCU))
@@ -511,14 +507,14 @@ bool kasan_slab_free(struct kmem_cache *cache, void *object)
 
 	shadow_byte = READ_ONCE(*(s8 *)kasan_mem_to_shadow(object));
 	if (shadow_byte < 0 || shadow_byte >= KASAN_SHADOW_SCALE_SIZE) {
-		kasan_report_double_free(cache, object,
-				__builtin_return_address(1));
+		kasan_report_invalid_free(object, ip);
 		return true;
 	}
 
-	kasan_poison_slab_free(cache, object);
+	rounded_up_size = round_up(cache->object_size, KASAN_SHADOW_SCALE_SIZE);
+	kasan_poison_shadow(object, rounded_up_size, KASAN_KMALLOC_FREE);
 
-	if (unlikely(!(cache->flags & SLAB_KASAN)))
+	if (!quarantine || unlikely(!(cache->flags & SLAB_KASAN)))
 		return false;
 
 	set_track(&get_alloc_info(cache, object)->free_track, GFP_NOWAIT);
@@ -526,6 +522,11 @@ bool kasan_slab_free(struct kmem_cache *cache, void *object)
 	return true;
 }
 
+bool kasan_slab_free(struct kmem_cache *cache, void *object, unsigned long ip)
+{
+	return __kasan_slab_free(cache, object, ip, true);
+}
+
 void kasan_kmalloc(struct kmem_cache *cache, const void *object, size_t size,
 		   gfp_t flags)
 {
@@ -589,25 +590,29 @@ void kasan_krealloc(const void *object, size_t size, gfp_t flags)
 		kasan_kmalloc(page->slab_cache, object, size, flags);
 }
 
-void kasan_poison_kfree(void *ptr)
+void kasan_poison_kfree(void *ptr, unsigned long ip)
 {
 	struct page *page;
 
 	page = virt_to_head_page(ptr);
 
-	if (unlikely(!PageSlab(page)))
+	if (unlikely(!PageSlab(page))) {
+		if (ptr != page_address(page)) {
+			kasan_report_invalid_free(ptr, ip);
+			return;
+		}
 		kasan_poison_shadow(ptr, PAGE_SIZE << compound_order(page),
 				KASAN_FREE_PAGE);
-	else
-		kasan_poison_slab_free(page->slab_cache, ptr);
+	} else {
+		__kasan_slab_free(page->slab_cache, ptr, ip, false);
+	}
 }
 
-void kasan_kfree_large(const void *ptr)
+void kasan_kfree_large(void *ptr, unsigned long ip)
 {
-	struct page *page = virt_to_page(ptr);
-
-	kasan_poison_shadow(ptr, PAGE_SIZE << compound_order(page),
-			KASAN_FREE_PAGE);
+	if (ptr != page_address(virt_to_head_page(ptr)))
+		kasan_report_invalid_free(ptr, ip);
+	/* The object will be poisoned by page_alloc. */
 }
 
 int kasan_module_alloc(void *addr, size_t size)
@@ -736,6 +741,55 @@ void __asan_unpoison_stack_memory(const void *addr, size_t size)
 }
 EXPORT_SYMBOL(__asan_unpoison_stack_memory);
 
+/* Emitted by compiler to poison alloca()ed objects. */
+void __asan_alloca_poison(unsigned long addr, size_t size)
+{
+	size_t rounded_up_size = round_up(size, KASAN_SHADOW_SCALE_SIZE);
+	size_t padding_size = round_up(size, KASAN_ALLOCA_REDZONE_SIZE) -
+			rounded_up_size;
+	size_t rounded_down_size = round_down(size, KASAN_SHADOW_SCALE_SIZE);
+
+	const void *left_redzone = (const void *)(addr -
+			KASAN_ALLOCA_REDZONE_SIZE);
+	const void *right_redzone = (const void *)(addr + rounded_up_size);
+
+	WARN_ON(!IS_ALIGNED(addr, KASAN_ALLOCA_REDZONE_SIZE));
+
+	kasan_unpoison_shadow((const void *)(addr + rounded_down_size),
+			      size - rounded_down_size);
+	kasan_poison_shadow(left_redzone, KASAN_ALLOCA_REDZONE_SIZE,
+			KASAN_ALLOCA_LEFT);
+	kasan_poison_shadow(right_redzone,
+			padding_size + KASAN_ALLOCA_REDZONE_SIZE,
+			KASAN_ALLOCA_RIGHT);
+}
+EXPORT_SYMBOL(__asan_alloca_poison);
+
+/* Emitted by compiler to unpoison alloca()ed areas when the stack unwinds. */
+void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom)
+{
+	if (unlikely(!stack_top || stack_top > stack_bottom))
+		return;
+
+	kasan_unpoison_shadow(stack_top, stack_bottom - stack_top);
+}
+EXPORT_SYMBOL(__asan_allocas_unpoison);
+
+/* Emitted by the compiler to [un]poison local variables. */
+#define DEFINE_ASAN_SET_SHADOW(byte) \
+	void __asan_set_shadow_##byte(const void *addr, size_t size)	\
+	{								\
+		__memset((void *)addr, 0x##byte, size);			\
+	}								\
+	EXPORT_SYMBOL(__asan_set_shadow_##byte)
+
+DEFINE_ASAN_SET_SHADOW(00);
+DEFINE_ASAN_SET_SHADOW(f1);
+DEFINE_ASAN_SET_SHADOW(f2);
+DEFINE_ASAN_SET_SHADOW(f3);
+DEFINE_ASAN_SET_SHADOW(f5);
+DEFINE_ASAN_SET_SHADOW(f8);
+
 #ifdef CONFIG_MEMORY_HOTPLUG
 static int __meminit kasan_mem_notifier(struct notifier_block *nb,
 			unsigned long action, void *data)
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index c70851a..c12dcfd 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -24,6 +24,14 @@
 #define KASAN_STACK_PARTIAL     0xF4
 #define KASAN_USE_AFTER_SCOPE   0xF8
 
+/*
+ * alloca redzone shadow values
+ */
+#define KASAN_ALLOCA_LEFT	0xCA
+#define KASAN_ALLOCA_RIGHT	0xCB
+
+#define KASAN_ALLOCA_REDZONE_SIZE	32
+
 /* Don't break randconfig/all*config builds */
 #ifndef KASAN_ABI_VERSION
 #define KASAN_ABI_VERSION 1
@@ -99,8 +107,7 @@ static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
 
 void kasan_report(unsigned long addr, size_t size,
 		bool is_write, unsigned long ip);
-void kasan_report_double_free(struct kmem_cache *cache, void *object,
-					void *ip);
+void kasan_report_invalid_free(void *object, unsigned long ip);
 
 #if defined(CONFIG_SLAB) || defined(CONFIG_SLUB)
 void quarantine_put(struct kasan_free_meta *info, struct kmem_cache *cache);
@@ -113,4 +120,48 @@ static inline void quarantine_reduce(void) { }
 static inline void quarantine_remove_cache(struct kmem_cache *cache) { }
 #endif
 
+/*
+ * Exported functions for interfaces called from assembly or from generated
+ * code. Declarations here to avoid warning about missing declarations.
+ */
+asmlinkage void kasan_unpoison_task_stack_below(const void *watermark);
+void __asan_register_globals(struct kasan_global *globals, size_t size);
+void __asan_unregister_globals(struct kasan_global *globals, size_t size);
+void __asan_loadN(unsigned long addr, size_t size);
+void __asan_storeN(unsigned long addr, size_t size);
+void __asan_handle_no_return(void);
+void __asan_poison_stack_memory(const void *addr, size_t size);
+void __asan_unpoison_stack_memory(const void *addr, size_t size);
+void __asan_alloca_poison(unsigned long addr, size_t size);
+void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom);
+
+void __asan_load1(unsigned long addr);
+void __asan_store1(unsigned long addr);
+void __asan_load2(unsigned long addr);
+void __asan_store2(unsigned long addr);
+void __asan_load4(unsigned long addr);
+void __asan_store4(unsigned long addr);
+void __asan_load8(unsigned long addr);
+void __asan_store8(unsigned long addr);
+void __asan_load16(unsigned long addr);
+void __asan_store16(unsigned long addr);
+
+void __asan_load1_noabort(unsigned long addr);
+void __asan_store1_noabort(unsigned long addr);
+void __asan_load2_noabort(unsigned long addr);
+void __asan_store2_noabort(unsigned long addr);
+void __asan_load4_noabort(unsigned long addr);
+void __asan_store4_noabort(unsigned long addr);
+void __asan_load8_noabort(unsigned long addr);
+void __asan_store8_noabort(unsigned long addr);
+void __asan_load16_noabort(unsigned long addr);
+void __asan_store16_noabort(unsigned long addr);
+
+void __asan_set_shadow_00(const void *addr, size_t size);
+void __asan_set_shadow_f1(const void *addr, size_t size);
+void __asan_set_shadow_f2(const void *addr, size_t size);
+void __asan_set_shadow_f3(const void *addr, size_t size);
+void __asan_set_shadow_f5(const void *addr, size_t size);
+void __asan_set_shadow_f8(const void *addr, size_t size);
+
 #endif
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 410c823..5c169aa 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -5,7 +5,7 @@
  * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
  *
  * Some code borrowed from https://github.com/xairy/kasan-prototype by
- *        Andrey Konovalov <adech.fo@gmail.com>
+ *        Andrey Konovalov <andreyknvl@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -102,6 +102,10 @@ static const char *get_shadow_bug_type(struct kasan_access_info *info)
 	case KASAN_USE_AFTER_SCOPE:
 		bug_type = "use-after-scope";
 		break;
+	case KASAN_ALLOCA_LEFT:
+	case KASAN_ALLOCA_RIGHT:
+		bug_type = "alloca-out-of-bounds";
+		break;
 	}
 
 	return bug_type;
@@ -322,13 +326,12 @@ static void print_shadow_for_address(const void *addr)
 	}
 }
 
-void kasan_report_double_free(struct kmem_cache *cache, void *object,
-				void *ip)
+void kasan_report_invalid_free(void *object, unsigned long ip)
 {
 	unsigned long flags;
 
 	kasan_start_report(&flags);
-	pr_err("BUG: KASAN: double-free or invalid-free in %pS\n", ip);
+	pr_err("BUG: KASAN: double-free or invalid-free in %pS\n", (void *)ip);
 	pr_err("\n");
 	print_address_description(object);
 	pr_err("\n");
diff --git a/mm/ksm.c b/mm/ksm.c
index c406f75..293721f 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -2302,7 +2302,7 @@ static struct rmap_item *scan_get_next_rmap_item(struct page **page)
 
 /**
  * ksm_do_scan  - the ksm scanner main worker function.
- * @scan_npages - number of pages we want to scan before we return.
+ * @scan_npages:  number of pages we want to scan before we return.
  */
 static void ksm_do_scan(unsigned int scan_npages)
 {
diff --git a/mm/maccess.c b/mm/maccess.c
index 78f9274..ec00be5 100644
--- a/mm/maccess.c
+++ b/mm/maccess.c
@@ -70,7 +70,7 @@ EXPORT_SYMBOL_GPL(probe_kernel_write);
  * strncpy_from_unsafe: - Copy a NUL terminated string from unsafe address.
  * @dst:   Destination address, in kernel space.  This buffer must be at
  *         least @count bytes long.
- * @src:   Unsafe address.
+ * @unsafe_addr: Unsafe address.
  * @count: Maximum number of bytes to copy, including the trailing NUL.
  *
  * Copies a NUL-terminated string from unsafe address to kernel buffer.
diff --git a/mm/memblock.c b/mm/memblock.c
index 46aacdf..5a9ca2a 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1654,7 +1654,7 @@ bool __init_memblock memblock_is_memory(phys_addr_t addr)
 	return memblock_search(&memblock.memory, addr) != -1;
 }
 
-int __init_memblock memblock_is_map_memory(phys_addr_t addr)
+bool __init_memblock memblock_is_map_memory(phys_addr_t addr)
 {
 	int i = memblock_search(&memblock.memory, addr);
 
@@ -1690,13 +1690,13 @@ int __init_memblock memblock_search_pfn_nid(unsigned long pfn,
  * RETURNS:
  * 0 if false, non-zero if true
  */
-int __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t size)
+bool __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t size)
 {
 	int idx = memblock_search(&memblock.memory, base);
 	phys_addr_t end = base + memblock_cap_size(base, &size);
 
 	if (idx == -1)
-		return 0;
+		return false;
 	return (memblock.memory.regions[idx].base +
 		 memblock.memory.regions[idx].size) >= end;
 }
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 0937f2c..13b35ff 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -917,7 +917,7 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
 /**
  * mem_cgroup_page_lruvec - return lruvec for isolating/putting an LRU page
  * @page: the page
- * @zone: zone of the page
+ * @pgdat: pgdat of the page
  *
  * This function is only safe when following the LRU page isolation
  * and putback protocol: the LRU lock must be held, and the page must
@@ -5818,8 +5818,8 @@ bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
 
 /**
  * mem_cgroup_uncharge_skmem - uncharge socket memory
- * @memcg - memcg to uncharge
- * @nr_pages - number of pages to uncharge
+ * @memcg: memcg to uncharge
+ * @nr_pages: number of pages to uncharge
  */
 void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
 {
diff --git a/mm/memory.c b/mm/memory.c
index 53373b7..dd8de96 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -59,7 +59,6 @@
 #include <linux/writeback.h>
 #include <linux/memcontrol.h>
 #include <linux/mmu_notifier.h>
-#include <linux/kallsyms.h>
 #include <linux/swapops.h>
 #include <linux/elf.h>
 #include <linux/gfp.h>
@@ -767,9 +766,6 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
 		dump_page(page, "bad pte");
 	pr_alert("addr:%p vm_flags:%08lx anon_vma:%p mapping:%p index:%lx\n",
 		 (void *)addr, vma->vm_flags, vma->anon_vma, mapping, index);
-	/*
-	 * Choose text because data symbols depend on CONFIG_KALLSYMS_ALL=y
-	 */
 	pr_alert("file:%pD fault:%pf mmap:%pf readpage:%pf\n",
 		 vma->vm_file,
 		 vma->vm_ops ? vma->vm_ops->fault : NULL,
@@ -1904,12 +1900,26 @@ int vm_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr,
 }
 EXPORT_SYMBOL(vm_insert_pfn_prot);
 
+static bool vm_mixed_ok(struct vm_area_struct *vma, pfn_t pfn)
+{
+	/* these checks mirror the abort conditions in vm_normal_page */
+	if (vma->vm_flags & VM_MIXEDMAP)
+		return true;
+	if (pfn_t_devmap(pfn))
+		return true;
+	if (pfn_t_special(pfn))
+		return true;
+	if (is_zero_pfn(pfn_t_to_pfn(pfn)))
+		return true;
+	return false;
+}
+
 static int __vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
 			pfn_t pfn, bool mkwrite)
 {
 	pgprot_t pgprot = vma->vm_page_prot;
 
-	BUG_ON(!(vma->vm_flags & VM_MIXEDMAP));
+	BUG_ON(!vm_mixed_ok(vma, pfn));
 
 	if (addr < vma->vm_start || addr >= vma->vm_end)
 		return -EFAULT;
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 9bbd698..b2bd52f 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -247,7 +247,7 @@ void __init register_page_bootmem_info_node(struct pglist_data *pgdat)
 #endif /* CONFIG_HAVE_BOOTMEM_INFO_NODE */
 
 static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
-		bool want_memblock)
+		struct vmem_altmap *altmap, bool want_memblock)
 {
 	int ret;
 	int i;
@@ -255,7 +255,7 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
 	if (pfn_valid(phys_start_pfn))
 		return -EEXIST;
 
-	ret = sparse_add_one_section(NODE_DATA(nid), phys_start_pfn);
+	ret = sparse_add_one_section(NODE_DATA(nid), phys_start_pfn, altmap);
 	if (ret < 0)
 		return ret;
 
@@ -289,18 +289,17 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
  * add the new pages.
  */
 int __ref __add_pages(int nid, unsigned long phys_start_pfn,
-			unsigned long nr_pages, bool want_memblock)
+		unsigned long nr_pages, struct vmem_altmap *altmap,
+		bool want_memblock)
 {
 	unsigned long i;
 	int err = 0;
 	int start_sec, end_sec;
-	struct vmem_altmap *altmap;
 
 	/* during initialize mem_map, align hot-added range to section */
 	start_sec = pfn_to_section_nr(phys_start_pfn);
 	end_sec = pfn_to_section_nr(phys_start_pfn + nr_pages - 1);
 
-	altmap = to_vmem_altmap((unsigned long) pfn_to_page(phys_start_pfn));
 	if (altmap) {
 		/*
 		 * Validate altmap is within bounds of the total request
@@ -315,7 +314,8 @@ int __ref __add_pages(int nid, unsigned long phys_start_pfn,
 	}
 
 	for (i = start_sec; i <= end_sec; i++) {
-		err = __add_section(nid, section_nr_to_pfn(i), want_memblock);
+		err = __add_section(nid, section_nr_to_pfn(i), altmap,
+				want_memblock);
 
 		/*
 		 * EEXIST is finally dealt with by ioresource collision
@@ -331,7 +331,6 @@ int __ref __add_pages(int nid, unsigned long phys_start_pfn,
 out:
 	return err;
 }
-EXPORT_SYMBOL_GPL(__add_pages);
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
 /* find the smallest valid pfn in the range [start_pfn, end_pfn) */
@@ -534,7 +533,7 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn)
 }
 
 static int __remove_section(struct zone *zone, struct mem_section *ms,
-		unsigned long map_offset)
+		unsigned long map_offset, struct vmem_altmap *altmap)
 {
 	unsigned long start_pfn;
 	int scn_nr;
@@ -551,7 +550,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms,
 	start_pfn = section_nr_to_pfn((unsigned long)scn_nr);
 	__remove_zone(zone, start_pfn);
 
-	sparse_remove_one_section(zone, ms, map_offset);
+	sparse_remove_one_section(zone, ms, map_offset, altmap);
 	return 0;
 }
 
@@ -567,7 +566,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms,
  * calling offline_pages().
  */
 int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
-		 unsigned long nr_pages)
+		 unsigned long nr_pages, struct vmem_altmap *altmap)
 {
 	unsigned long i;
 	unsigned long map_offset = 0;
@@ -575,10 +574,6 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
 
 	/* In the ZONE_DEVICE case device driver owns the memory region */
 	if (is_dev_zone(zone)) {
-		struct page *page = pfn_to_page(phys_start_pfn);
-		struct vmem_altmap *altmap;
-
-		altmap = to_vmem_altmap((unsigned long) page);
 		if (altmap)
 			map_offset = vmem_altmap_offset(altmap);
 	} else {
@@ -609,7 +604,8 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
 	for (i = 0; i < sections_to_remove; i++) {
 		unsigned long pfn = phys_start_pfn + i*PAGES_PER_SECTION;
 
-		ret = __remove_section(zone, __pfn_to_section(pfn), map_offset);
+		ret = __remove_section(zone, __pfn_to_section(pfn), map_offset,
+				altmap);
 		map_offset = 0;
 		if (ret)
 			break;
@@ -799,8 +795,8 @@ static void __meminit resize_pgdat_range(struct pglist_data *pgdat, unsigned lon
 	pgdat->node_spanned_pages = max(start_pfn + nr_pages, old_end_pfn) - pgdat->node_start_pfn;
 }
 
-void __ref move_pfn_range_to_zone(struct zone *zone,
-		unsigned long start_pfn, unsigned long nr_pages)
+void __ref move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
+		unsigned long nr_pages, struct vmem_altmap *altmap)
 {
 	struct pglist_data *pgdat = zone->zone_pgdat;
 	int nid = pgdat->node_id;
@@ -825,7 +821,8 @@ void __ref move_pfn_range_to_zone(struct zone *zone,
 	 * expects the zone spans the pfn range. All the pages in the range
 	 * are reserved so nobody should be touching them so we should be safe
 	 */
-	memmap_init_zone(nr_pages, nid, zone_idx(zone), start_pfn, MEMMAP_HOTPLUG);
+	memmap_init_zone(nr_pages, nid, zone_idx(zone), start_pfn,
+			MEMMAP_HOTPLUG, altmap);
 
 	set_zone_contiguous(zone);
 }
@@ -897,7 +894,7 @@ static struct zone * __meminit move_pfn_range(int online_type, int nid,
 	struct zone *zone;
 
 	zone = zone_for_pfn_range(online_type, nid, start_pfn, nr_pages);
-	move_pfn_range_to_zone(zone, start_pfn, nr_pages);
+	move_pfn_range_to_zone(zone, start_pfn, nr_pages, NULL);
 	return zone;
 }
 
@@ -1146,7 +1143,7 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
 	}
 
 	/* call arch's memory hotadd */
-	ret = arch_add_memory(nid, start, size, true);
+	ret = arch_add_memory(nid, start, size, NULL, true);
 
 	if (ret < 0)
 		goto error;
@@ -1888,7 +1885,7 @@ void __ref remove_memory(int nid, u64 start, u64 size)
 	memblock_free(start, size);
 	memblock_remove(start, size);
 
-	arch_remove_memory(start, size);
+	arch_remove_memory(start, size, NULL);
 
 	try_offline_node(nid);
 
diff --git a/mm/mempool.c b/mm/mempool.c
index 7d8c5a0..5c9dce3 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -103,10 +103,10 @@ static inline void poison_element(mempool_t *pool, void *element)
 }
 #endif /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */
 
-static void kasan_poison_element(mempool_t *pool, void *element)
+static __always_inline void kasan_poison_element(mempool_t *pool, void *element)
 {
 	if (pool->alloc == mempool_alloc_slab || pool->alloc == mempool_kmalloc)
-		kasan_poison_kfree(element);
+		kasan_poison_kfree(element, _RET_IP_);
 	if (pool->alloc == mempool_alloc_pages)
 		kasan_free_pages(element, (unsigned long)pool->pool_data);
 }
@@ -119,7 +119,7 @@ static void kasan_unpoison_element(mempool_t *pool, void *element, gfp_t flags)
 		kasan_alloc_pages(element, (unsigned long)pool->pool_data);
 }
 
-static void add_element(mempool_t *pool, void *element)
+static __always_inline void add_element(mempool_t *pool, void *element)
 {
 	BUG_ON(pool->curr_nr >= pool->min_nr);
 	poison_element(pool, element);
diff --git a/mm/mlock.c b/mm/mlock.c
index f7f54fd..7939820 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -157,7 +157,7 @@ static void __munlock_isolation_failed(struct page *page)
 
 /**
  * munlock_vma_page - munlock a vma page
- * @page - page to be unlocked, either a normal page or THP page head
+ * @page: page to be unlocked, either a normal page or THP page head
  *
  * returns the size of the page as a page mask (0 for normal page,
  *         HPAGE_PMD_NR - 1 for THP head page)
diff --git a/mm/nommu.c b/mm/nommu.c
index 4b9864b..ebb6e61 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1836,7 +1836,7 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
 }
 
 /**
- * @access_remote_vm - access another process' address space
+ * access_remote_vm - access another process' address space
  * @mm:		the mm_struct of the target address space
  * @addr:	start address to access
  * @buf:	source or destination buffer
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c7dd9c8..81e18ce 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5321,9 +5321,9 @@ void __ref build_all_zonelists(pg_data_t *pgdat)
  * done. Non-atomic initialization, single-pass.
  */
 void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
-		unsigned long start_pfn, enum memmap_context context)
+		unsigned long start_pfn, enum memmap_context context,
+		struct vmem_altmap *altmap)
 {
-	struct vmem_altmap *altmap = to_vmem_altmap(__pfn_to_phys(start_pfn));
 	unsigned long end_pfn = start_pfn + size;
 	pg_data_t *pgdat = NODE_DATA(nid);
 	unsigned long pfn;
@@ -5429,7 +5429,7 @@ static void __meminit zone_init_free_lists(struct zone *zone)
 
 #ifndef __HAVE_ARCH_MEMMAP_INIT
 #define memmap_init(size, nid, zone, start_pfn) \
-	memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)
+	memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY, NULL)
 #endif
 
 static int zone_batchsize(struct zone *zone)
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index 23a3e41..8d2da5d 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -265,6 +265,7 @@ static int __walk_page_range(unsigned long start, unsigned long end,
  * pte_entry(), and/or hugetlb_entry(). If you don't set up for some of these
  * callbacks, the associated entries/pages are just ignored.
  * The return values of these callbacks are commonly defined like below:
+ *
  *  - 0  : succeeded to handle the current entry, and if you don't reach the
  *         end address yet, continue to walk.
  *  - >0 : succeeded to handle the current entry, and return to the caller
diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c
index 8973cd2..a447092 100644
--- a/mm/process_vm_access.c
+++ b/mm/process_vm_access.c
@@ -25,7 +25,7 @@
 /**
  * process_vm_rw_pages - read/write pages from task specified
  * @pages: array of pointers to pages we want to copy
- * @start_offset: offset in page to start copying from/to
+ * @offset: offset in page to start copying from/to
  * @len: number of bytes to copy
  * @iter: where to copy to/from locally
  * @vm_write: 0 means copy from, 1 means copy to
@@ -147,6 +147,7 @@ static int process_vm_rw_single_vec(unsigned long addr,
  * @riovcnt: size of rvec array
  * @flags: currently unused
  * @vm_write: 0 if reading from other process, 1 if writing to other process
+ *
  * Returns the number of bytes read/written or error code. May
  *  return less bytes than expected if an error occurs during the copying
  *  process.
@@ -197,11 +198,7 @@ static ssize_t process_vm_rw_core(pid_t pid, struct iov_iter *iter,
 	}
 
 	/* Get process information */
-	rcu_read_lock();
-	task = find_task_by_vpid(pid);
-	if (task)
-		get_task_struct(task);
-	rcu_read_unlock();
+	task = find_get_task_by_vpid(pid);
 	if (!task) {
 		rc = -ESRCH;
 		goto free_proc_pages;
@@ -253,6 +250,7 @@ static ssize_t process_vm_rw_core(pid_t pid, struct iov_iter *iter,
  * @riovcnt: size of rvec array
  * @flags: currently unused
  * @vm_write: 0 if reading from other process, 1 if writing to other process
+ *
  * Returns the number of bytes read/written or error code. May
  *  return less bytes than expected if an error occurs during the copying
  *  process.
diff --git a/mm/slab.c b/mm/slab.c
index cd86f15..3244466 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3478,11 +3478,11 @@ static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac)
  * Release an obj back to its cache. If the obj has a constructed state, it must
  * be in this state _before_ it is released.  Called with disabled ints.
  */
-static inline void __cache_free(struct kmem_cache *cachep, void *objp,
-				unsigned long caller)
+static __always_inline void __cache_free(struct kmem_cache *cachep, void *objp,
+					 unsigned long caller)
 {
 	/* Put the object into the quarantine, don't touch it for now. */
-	if (kasan_slab_free(cachep, objp))
+	if (kasan_slab_free(cachep, objp, _RET_IP_))
 		return;
 
 	___cache_free(cachep, objp, caller);
diff --git a/mm/slub.c b/mm/slub.c
index cc71176..e381728 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1356,13 +1356,13 @@ static inline void kmalloc_large_node_hook(void *ptr, size_t size, gfp_t flags)
 	kasan_kmalloc_large(ptr, size, flags);
 }
 
-static inline void kfree_hook(const void *x)
+static __always_inline void kfree_hook(void *x)
 {
 	kmemleak_free(x);
-	kasan_kfree_large(x);
+	kasan_kfree_large(x, _RET_IP_);
 }
 
-static inline void *slab_free_hook(struct kmem_cache *s, void *x)
+static __always_inline void *slab_free_hook(struct kmem_cache *s, void *x)
 {
 	void *freeptr;
 
@@ -1390,7 +1390,7 @@ static inline void *slab_free_hook(struct kmem_cache *s, void *x)
 	 * kasan_slab_free() may put x into memory quarantine, delaying its
 	 * reuse. In this case the object's freelist pointer is changed.
 	 */
-	kasan_slab_free(s, x);
+	kasan_slab_free(s, x, _RET_IP_);
 	return freeptr;
 }
 
@@ -3910,7 +3910,7 @@ void kfree(const void *x)
 	page = virt_to_head_page(x);
 	if (unlikely(!PageSlab(page))) {
 		BUG_ON(!PageCompound(page));
-		kfree_hook(x);
+		kfree_hook(object);
 		__free_pages(page, compound_order(page));
 		return;
 	}
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index 17acf01..bd0276d 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -74,7 +74,7 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node)
 }
 
 /* need to make sure size is all the same during early stage */
-static void * __meminit alloc_block_buf(unsigned long size, int node)
+void * __meminit vmemmap_alloc_block_buf(unsigned long size, int node)
 {
 	void *ptr;
 
@@ -107,33 +107,16 @@ static unsigned long __meminit vmem_altmap_nr_free(struct vmem_altmap *altmap)
 }
 
 /**
- * vmem_altmap_alloc - allocate pages from the vmem_altmap reservation
- * @altmap - reserved page pool for the allocation
- * @nr_pfns - size (in pages) of the allocation
+ * altmap_alloc_block_buf - allocate pages from the device page map
+ * @altmap:	device page map
+ * @size:	size (in bytes) of the allocation
  *
- * Allocations are aligned to the size of the request
+ * Allocations are aligned to the size of the request.
  */
-static unsigned long __meminit vmem_altmap_alloc(struct vmem_altmap *altmap,
-		unsigned long nr_pfns)
-{
-	unsigned long pfn = vmem_altmap_next_pfn(altmap);
-	unsigned long nr_align;
-
-	nr_align = 1UL << find_first_bit(&nr_pfns, BITS_PER_LONG);
-	nr_align = ALIGN(pfn, nr_align) - pfn;
-
-	if (nr_pfns + nr_align > vmem_altmap_nr_free(altmap))
-		return ULONG_MAX;
-	altmap->alloc += nr_pfns;
-	altmap->align += nr_align;
-	return pfn + nr_align;
-}
-
-static void * __meminit altmap_alloc_block_buf(unsigned long size,
+void * __meminit altmap_alloc_block_buf(unsigned long size,
 		struct vmem_altmap *altmap)
 {
-	unsigned long pfn, nr_pfns;
-	void *ptr;
+	unsigned long pfn, nr_pfns, nr_align;
 
 	if (size & ~PAGE_MASK) {
 		pr_warn_once("%s: allocations must be multiple of PAGE_SIZE (%ld)\n",
@@ -141,25 +124,20 @@ static void * __meminit altmap_alloc_block_buf(unsigned long size,
 		return NULL;
 	}
 
+	pfn = vmem_altmap_next_pfn(altmap);
 	nr_pfns = size >> PAGE_SHIFT;
-	pfn = vmem_altmap_alloc(altmap, nr_pfns);
-	if (pfn < ULONG_MAX)
-		ptr = __va(__pfn_to_phys(pfn));
-	else
-		ptr = NULL;
+	nr_align = 1UL << find_first_bit(&nr_pfns, BITS_PER_LONG);
+	nr_align = ALIGN(pfn, nr_align) - pfn;
+	if (nr_pfns + nr_align > vmem_altmap_nr_free(altmap))
+		return NULL;
+
+	altmap->alloc += nr_pfns;
+	altmap->align += nr_align;
+	pfn += nr_align;
+
 	pr_debug("%s: pfn: %#lx alloc: %ld align: %ld nr: %#lx\n",
 			__func__, pfn, altmap->alloc, altmap->align, nr_pfns);
-
-	return ptr;
-}
-
-/* need to make sure size is all the same during early stage */
-void * __meminit __vmemmap_alloc_block_buf(unsigned long size, int node,
-		struct vmem_altmap *altmap)
-{
-	if (altmap)
-		return altmap_alloc_block_buf(size, altmap);
-	return alloc_block_buf(size, node);
+	return __va(__pfn_to_phys(pfn));
 }
 
 void __meminit vmemmap_verify(pte_t *pte, int node,
@@ -178,7 +156,7 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node)
 	pte_t *pte = pte_offset_kernel(pmd, addr);
 	if (pte_none(*pte)) {
 		pte_t entry;
-		void *p = alloc_block_buf(PAGE_SIZE, node);
+		void *p = vmemmap_alloc_block_buf(PAGE_SIZE, node);
 		if (!p)
 			return NULL;
 		entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL);
@@ -278,7 +256,8 @@ int __meminit vmemmap_populate_basepages(unsigned long start,
 	return 0;
 }
 
-struct page * __meminit sparse_mem_map_populate(unsigned long pnum, int nid)
+struct page * __meminit sparse_mem_map_populate(unsigned long pnum, int nid,
+		struct vmem_altmap *altmap)
 {
 	unsigned long start;
 	unsigned long end;
@@ -288,7 +267,7 @@ struct page * __meminit sparse_mem_map_populate(unsigned long pnum, int nid)
 	start = (unsigned long)map;
 	end = (unsigned long)(map + PAGES_PER_SECTION);
 
-	if (vmemmap_populate(start, end, nid))
+	if (vmemmap_populate(start, end, nid, altmap))
 		return NULL;
 
 	return map;
@@ -318,7 +297,7 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
 		if (!present_section_nr(pnum))
 			continue;
 
-		map_map[pnum] = sparse_mem_map_populate(pnum, nodeid);
+		map_map[pnum] = sparse_mem_map_populate(pnum, nodeid, NULL);
 		if (map_map[pnum])
 			continue;
 		ms = __nr_to_section(pnum);
diff --git a/mm/sparse.c b/mm/sparse.c
index 6b8b5e9..7af5e7a 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -421,7 +421,8 @@ static void __init sparse_early_usemaps_alloc_node(void *data,
 }
 
 #ifndef CONFIG_SPARSEMEM_VMEMMAP
-struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid)
+struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid,
+		struct vmem_altmap *altmap)
 {
 	struct page *map;
 	unsigned long size;
@@ -476,7 +477,7 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
 
 		if (!present_section_nr(pnum))
 			continue;
-		map_map[pnum] = sparse_mem_map_populate(pnum, nodeid);
+		map_map[pnum] = sparse_mem_map_populate(pnum, nodeid, NULL);
 		if (map_map[pnum])
 			continue;
 		ms = __nr_to_section(pnum);
@@ -504,7 +505,7 @@ static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
 	struct mem_section *ms = __nr_to_section(pnum);
 	int nid = sparse_early_nid(ms);
 
-	map = sparse_mem_map_populate(pnum, nid);
+	map = sparse_mem_map_populate(pnum, nid, NULL);
 	if (map)
 		return map;
 
@@ -682,17 +683,19 @@ void offline_mem_sections(unsigned long start_pfn, unsigned long end_pfn)
 #endif
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
-static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid)
+static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
+		struct vmem_altmap *altmap)
 {
 	/* This will make the necessary allocations eventually. */
-	return sparse_mem_map_populate(pnum, nid);
+	return sparse_mem_map_populate(pnum, nid, altmap);
 }
-static void __kfree_section_memmap(struct page *memmap)
+static void __kfree_section_memmap(struct page *memmap,
+		struct vmem_altmap *altmap)
 {
 	unsigned long start = (unsigned long)memmap;
 	unsigned long end = (unsigned long)(memmap + PAGES_PER_SECTION);
 
-	vmemmap_free(start, end);
+	vmemmap_free(start, end, altmap);
 }
 #ifdef CONFIG_MEMORY_HOTREMOVE
 static void free_map_bootmem(struct page *memmap)
@@ -700,7 +703,7 @@ static void free_map_bootmem(struct page *memmap)
 	unsigned long start = (unsigned long)memmap;
 	unsigned long end = (unsigned long)(memmap + PAGES_PER_SECTION);
 
-	vmemmap_free(start, end);
+	vmemmap_free(start, end, NULL);
 }
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 #else
@@ -725,12 +728,14 @@ static struct page *__kmalloc_section_memmap(void)
 	return ret;
 }
 
-static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid)
+static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
+		struct vmem_altmap *altmap)
 {
 	return __kmalloc_section_memmap();
 }
 
-static void __kfree_section_memmap(struct page *memmap)
+static void __kfree_section_memmap(struct page *memmap,
+		struct vmem_altmap *altmap)
 {
 	if (is_vmalloc_addr(memmap))
 		vfree(memmap);
@@ -777,7 +782,8 @@ static void free_map_bootmem(struct page *memmap)
  * set.  If this is <=0, then that means that the passed-in
  * map was not consumed and must be freed.
  */
-int __meminit sparse_add_one_section(struct pglist_data *pgdat, unsigned long start_pfn)
+int __meminit sparse_add_one_section(struct pglist_data *pgdat,
+		unsigned long start_pfn, struct vmem_altmap *altmap)
 {
 	unsigned long section_nr = pfn_to_section_nr(start_pfn);
 	struct mem_section *ms;
@@ -793,12 +799,12 @@ int __meminit sparse_add_one_section(struct pglist_data *pgdat, unsigned long st
 	ret = sparse_index_init(section_nr, pgdat->node_id);
 	if (ret < 0 && ret != -EEXIST)
 		return ret;
-	memmap = kmalloc_section_memmap(section_nr, pgdat->node_id);
+	memmap = kmalloc_section_memmap(section_nr, pgdat->node_id, altmap);
 	if (!memmap)
 		return -ENOMEM;
 	usemap = __kmalloc_section_usemap();
 	if (!usemap) {
-		__kfree_section_memmap(memmap);
+		__kfree_section_memmap(memmap, altmap);
 		return -ENOMEM;
 	}
 
@@ -820,7 +826,7 @@ int __meminit sparse_add_one_section(struct pglist_data *pgdat, unsigned long st
 	pgdat_resize_unlock(pgdat, &flags);
 	if (ret <= 0) {
 		kfree(usemap);
-		__kfree_section_memmap(memmap);
+		__kfree_section_memmap(memmap, altmap);
 	}
 	return ret;
 }
@@ -847,7 +853,8 @@ static inline void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
 }
 #endif
 
-static void free_section_usemap(struct page *memmap, unsigned long *usemap)
+static void free_section_usemap(struct page *memmap, unsigned long *usemap,
+		struct vmem_altmap *altmap)
 {
 	struct page *usemap_page;
 
@@ -861,7 +868,7 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
 	if (PageSlab(usemap_page) || PageCompound(usemap_page)) {
 		kfree(usemap);
 		if (memmap)
-			__kfree_section_memmap(memmap);
+			__kfree_section_memmap(memmap, altmap);
 		return;
 	}
 
@@ -875,7 +882,7 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
 }
 
 void sparse_remove_one_section(struct zone *zone, struct mem_section *ms,
-		unsigned long map_offset)
+		unsigned long map_offset, struct vmem_altmap *altmap)
 {
 	struct page *memmap = NULL;
 	unsigned long *usemap = NULL, flags;
@@ -893,7 +900,7 @@ void sparse_remove_one_section(struct zone *zone, struct mem_section *ms,
 
 	clear_hwpoisoned_pages(memmap + map_offset,
 			PAGES_PER_SECTION - map_offset);
-	free_section_usemap(memmap, usemap);
+	free_section_usemap(memmap, usemap, altmap);
 }
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 #endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/mm/swap.c b/mm/swap.c
index 10568b1..567a7b9 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -913,11 +913,11 @@ EXPORT_SYMBOL(__pagevec_lru_add);
  * @pvec:	Where the resulting entries are placed
  * @mapping:	The address_space to search
  * @start:	The starting entry index
- * @nr_entries:	The maximum number of entries
+ * @nr_pages:	The maximum number of pages
  * @indices:	The cache indices corresponding to the entries in @pvec
  *
  * pagevec_lookup_entries() will search for and return a group of up
- * to @nr_entries pages and shadow entries in the mapping.  All
+ * to @nr_pages pages and shadow entries in the mapping.  All
  * entries are placed in @pvec.  pagevec_lookup_entries() takes a
  * reference against actual pages in @pvec.
  *
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 8119270..39791b8 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -16,7 +16,6 @@
 #include <linux/userfaultfd_k.h>
 #include <linux/mmu_notifier.h>
 #include <linux/hugetlb.h>
-#include <linux/pagemap.h>
 #include <linux/shmem_fs.h>
 #include <asm/tlbflush.h>
 #include "internal.h"
diff --git a/mm/vmscan.c b/mm/vmscan.c
index fdd3fc6..4447496 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1595,6 +1595,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
  * found will be decremented.
  *
  * Restrictions:
+ *
  * (1) Must be called with an elevated refcount on the page. This is a
  *     fundamentnal difference from isolate_lru_pages (which is called
  *     without a stable reference).
diff --git a/mm/z3fold.c b/mm/z3fold.c
index 39e1912..d589d31 100644
--- a/mm/z3fold.c
+++ b/mm/z3fold.c
@@ -769,7 +769,7 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
 /**
  * z3fold_reclaim_page() - evicts allocations from a pool page and frees it
  * @pool:	pool from which a page will attempt to be evicted
- * @retires:	number of pages on the LRU list for which eviction will
+ * @retries:	number of pages on the LRU list for which eviction will
  *		be attempted before failing
  *
  * z3fold reclaim is different from normal system reclaim in that it is done
@@ -779,7 +779,7 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
  * z3fold and the user, however.
  *
  * To avoid these, this is how z3fold_reclaim_page() should be called:
-
+ *
  * The user detects a page should be reclaimed and calls z3fold_reclaim_page().
  * z3fold_reclaim_page() will remove a z3fold page from the pool LRU list and
  * call the user-defined eviction handler with the pool and handle as
diff --git a/mm/zbud.c b/mm/zbud.c
index b42322e..28458f7 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -466,7 +466,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
 /**
  * zbud_reclaim_page() - evicts allocations from a pool page and frees it
  * @pool:	pool from which a page will attempt to be evicted
- * @retires:	number of pages on the LRU list for which eviction will
+ * @retries:	number of pages on the LRU list for which eviction will
  *		be attempted before failing
  *
  * zbud reclaim is different from normal system reclaim in that the reclaim is
@@ -476,7 +476,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
  * the user, however.
  *
  * To avoid these, this is how zbud_reclaim_page() should be called:
-
+ *
  * The user detects a page should be reclaimed and calls zbud_reclaim_page().
  * zbud_reclaim_page() will remove a zbud page from the pool LRU list and call
  * the user-defined eviction handler with the pool and handle as arguments.
diff --git a/mm/zpool.c b/mm/zpool.c
index e1e7aa6..f8cb83e 100644
--- a/mm/zpool.c
+++ b/mm/zpool.c
@@ -101,7 +101,7 @@ static void zpool_put_driver(struct zpool_driver *driver)
 
 /**
  * zpool_has_pool() - Check if the pool driver is available
- * @type	The type of the zpool to check (e.g. zbud, zsmalloc)
+ * @type:	The type of the zpool to check (e.g. zbud, zsmalloc)
  *
  * This checks if the @type pool driver is available.  This will try to load
  * the requested module, if needed, but there is no guarantee the module will
@@ -136,10 +136,10 @@ EXPORT_SYMBOL(zpool_has_pool);
 
 /**
  * zpool_create_pool() - Create a new zpool
- * @type	The type of the zpool to create (e.g. zbud, zsmalloc)
- * @name	The name of the zpool (e.g. zram0, zswap)
- * @gfp		The GFP flags to use when allocating the pool.
- * @ops		The optional ops callback.
+ * @type:	The type of the zpool to create (e.g. zbud, zsmalloc)
+ * @name:	The name of the zpool (e.g. zram0, zswap)
+ * @gfp:	The GFP flags to use when allocating the pool.
+ * @ops:	The optional ops callback.
  *
  * This creates a new zpool of the specified type.  The gfp flags will be
  * used when allocating memory, if the implementation supports it.  If the
@@ -201,7 +201,7 @@ struct zpool *zpool_create_pool(const char *type, const char *name, gfp_t gfp,
 
 /**
  * zpool_destroy_pool() - Destroy a zpool
- * @pool	The zpool to destroy.
+ * @zpool:	The zpool to destroy.
  *
  * Implementations must guarantee this to be thread-safe,
  * however only when destroying different pools.  The same
@@ -224,7 +224,7 @@ void zpool_destroy_pool(struct zpool *zpool)
 
 /**
  * zpool_get_type() - Get the type of the zpool
- * @pool	The zpool to check
+ * @zpool:	The zpool to check
  *
  * This returns the type of the pool.
  *
@@ -239,10 +239,10 @@ const char *zpool_get_type(struct zpool *zpool)
 
 /**
  * zpool_malloc() - Allocate memory
- * @pool	The zpool to allocate from.
- * @size	The amount of memory to allocate.
- * @gfp		The GFP flags to use when allocating memory.
- * @handle	Pointer to the handle to set
+ * @zpool:	The zpool to allocate from.
+ * @size:	The amount of memory to allocate.
+ * @gfp:	The GFP flags to use when allocating memory.
+ * @handle:	Pointer to the handle to set
  *
  * This allocates the requested amount of memory from the pool.
  * The gfp flags will be used when allocating memory, if the
@@ -261,8 +261,8 @@ int zpool_malloc(struct zpool *zpool, size_t size, gfp_t gfp,
 
 /**
  * zpool_free() - Free previously allocated memory
- * @pool	The zpool that allocated the memory.
- * @handle	The handle to the memory to free.
+ * @zpool:	The zpool that allocated the memory.
+ * @handle:	The handle to the memory to free.
  *
  * This frees previously allocated memory.  This does not guarantee
  * that the pool will actually free memory, only that the memory
@@ -280,9 +280,9 @@ void zpool_free(struct zpool *zpool, unsigned long handle)
 
 /**
  * zpool_shrink() - Shrink the pool size
- * @pool	The zpool to shrink.
- * @pages	The number of pages to shrink the pool.
- * @reclaimed	The number of pages successfully evicted.
+ * @zpool:	The zpool to shrink.
+ * @pages:	The number of pages to shrink the pool.
+ * @reclaimed:	The number of pages successfully evicted.
  *
  * This attempts to shrink the actual memory size of the pool
  * by evicting currently used handle(s).  If the pool was
@@ -304,11 +304,11 @@ int zpool_shrink(struct zpool *zpool, unsigned int pages,
 
 /**
  * zpool_map_handle() - Map a previously allocated handle into memory
- * @pool	The zpool that the handle was allocated from
- * @handle	The handle to map
- * @mm		How the memory should be mapped
+ * @zpool:	The zpool that the handle was allocated from
+ * @handle:	The handle to map
+ * @mapmode:	How the memory should be mapped
  *
- * This maps a previously allocated handle into memory.  The @mm
+ * This maps a previously allocated handle into memory.  The @mapmode
  * param indicates to the implementation how the memory will be
  * used, i.e. read-only, write-only, read-write.  If the
  * implementation does not support it, the memory will be treated
@@ -332,8 +332,8 @@ void *zpool_map_handle(struct zpool *zpool, unsigned long handle,
 
 /**
  * zpool_unmap_handle() - Unmap a previously mapped handle
- * @pool	The zpool that the handle was allocated from
- * @handle	The handle to unmap
+ * @zpool:	The zpool that the handle was allocated from
+ * @handle:	The handle to unmap
  *
  * This unmaps a previously mapped handle.  Any locks or other
  * actions that the implementation took in zpool_map_handle()
@@ -347,7 +347,7 @@ void zpool_unmap_handle(struct zpool *zpool, unsigned long handle)
 
 /**
  * zpool_get_total_size() - The total size of the pool
- * @pool	The zpool to check
+ * @zpool:	The zpool to check
  *
  * This returns the total size in bytes of the pool.
  *
diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
index 57403bd..418b76e 100644
--- a/net/bluetooth/hci_debugfs.c
+++ b/net/bluetooth/hci_debugfs.c
@@ -90,19 +90,6 @@ static int __name ## _show(struct seq_file *f, void *ptr)		      \
 									      \
 DEFINE_SHOW_ATTRIBUTE(__name)
 
-#define DEFINE_SHOW_ATTRIBUTE(__name)					      \
-static int __name ## _open(struct inode *inode, struct file *file)	      \
-{									      \
-	return single_open(file, __name ## _show, inode->i_private);	      \
-}									      \
-									      \
-static const struct file_operations __name ## _fops = {			      \
-	.open		= __name ## _open,				      \
-	.read		= seq_read,					      \
-	.llseek		= seq_lseek,					      \
-	.release	= single_release,				      \
-}									      \
-
 static int features_show(struct seq_file *f, void *ptr)
 {
 	struct hci_dev *hdev = f->private;
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index a86e668..2ced486 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -151,6 +151,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
 {
 	u32 size = kattr->test.data_size_in;
 	u32 repeat = kattr->test.repeat;
+	struct netdev_rx_queue *rxqueue;
 	struct xdp_buff xdp = {};
 	u32 retval, duration;
 	void *data;
@@ -165,6 +166,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
 	xdp.data_meta = xdp.data;
 	xdp.data_end = xdp.data + size;
 
+	rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0);
+	xdp.rxq = &rxqueue->xdp_rxq;
+
 	retval = bpf_test_run(prog, &xdp, repeat, &duration);
 	if (xdp.data != data + XDP_PACKET_HEADROOM + NET_IP_ALIGN)
 		size = xdp.data_end - xdp.data;
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 5c036d2..1e492ef 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -421,6 +421,10 @@ ceph_parse_options(char *options, const char *dev_name,
 			opt->name = kstrndup(argstr[0].from,
 					      argstr[0].to-argstr[0].from,
 					      GFP_KERNEL);
+			if (!opt->name) {
+				err = -ENOMEM;
+				goto out;
+			}
 			break;
 		case Opt_secret:
 		        opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 107b122..494e6a5 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -616,18 +616,15 @@ static int load_link_ksettings_from_user(struct ethtool_link_ksettings *to,
 		return -EFAULT;
 
 	memcpy(&to->base, &link_usettings.base, sizeof(to->base));
-	bitmap_from_u32array(to->link_modes.supported,
-			     __ETHTOOL_LINK_MODE_MASK_NBITS,
-			     link_usettings.link_modes.supported,
-			     __ETHTOOL_LINK_MODE_MASK_NU32);
-	bitmap_from_u32array(to->link_modes.advertising,
-			     __ETHTOOL_LINK_MODE_MASK_NBITS,
-			     link_usettings.link_modes.advertising,
-			     __ETHTOOL_LINK_MODE_MASK_NU32);
-	bitmap_from_u32array(to->link_modes.lp_advertising,
-			     __ETHTOOL_LINK_MODE_MASK_NBITS,
-			     link_usettings.link_modes.lp_advertising,
-			     __ETHTOOL_LINK_MODE_MASK_NU32);
+	bitmap_from_arr32(to->link_modes.supported,
+			  link_usettings.link_modes.supported,
+			  __ETHTOOL_LINK_MODE_MASK_NBITS);
+	bitmap_from_arr32(to->link_modes.advertising,
+			  link_usettings.link_modes.advertising,
+			  __ETHTOOL_LINK_MODE_MASK_NBITS);
+	bitmap_from_arr32(to->link_modes.lp_advertising,
+			  link_usettings.link_modes.lp_advertising,
+			  __ETHTOOL_LINK_MODE_MASK_NBITS);
 
 	return 0;
 }
@@ -643,18 +640,15 @@ store_link_ksettings_for_user(void __user *to,
 	struct ethtool_link_usettings link_usettings;
 
 	memcpy(&link_usettings.base, &from->base, sizeof(link_usettings));
-	bitmap_to_u32array(link_usettings.link_modes.supported,
-			   __ETHTOOL_LINK_MODE_MASK_NU32,
-			   from->link_modes.supported,
-			   __ETHTOOL_LINK_MODE_MASK_NBITS);
-	bitmap_to_u32array(link_usettings.link_modes.advertising,
-			   __ETHTOOL_LINK_MODE_MASK_NU32,
-			   from->link_modes.advertising,
-			   __ETHTOOL_LINK_MODE_MASK_NBITS);
-	bitmap_to_u32array(link_usettings.link_modes.lp_advertising,
-			   __ETHTOOL_LINK_MODE_MASK_NU32,
-			   from->link_modes.lp_advertising,
-			   __ETHTOOL_LINK_MODE_MASK_NBITS);
+	bitmap_to_arr32(link_usettings.link_modes.supported,
+			from->link_modes.supported,
+			__ETHTOOL_LINK_MODE_MASK_NBITS);
+	bitmap_to_arr32(link_usettings.link_modes.advertising,
+			from->link_modes.advertising,
+			__ETHTOOL_LINK_MODE_MASK_NBITS);
+	bitmap_to_arr32(link_usettings.link_modes.lp_advertising,
+			from->link_modes.lp_advertising,
+			__ETHTOOL_LINK_MODE_MASK_NBITS);
 
 	if (copy_to_user(to, &link_usettings, sizeof(link_usettings)))
 		return -EFAULT;
@@ -2358,10 +2352,8 @@ static int ethtool_get_per_queue_coalesce(struct net_device *dev,
 
 	useraddr += sizeof(*per_queue_opt);
 
-	bitmap_from_u32array(queue_mask,
-			     MAX_NUM_QUEUE,
-			     per_queue_opt->queue_mask,
-			     DIV_ROUND_UP(MAX_NUM_QUEUE, 32));
+	bitmap_from_arr32(queue_mask, per_queue_opt->queue_mask,
+			  MAX_NUM_QUEUE);
 
 	for_each_set_bit(bit, queue_mask, MAX_NUM_QUEUE) {
 		struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE };
@@ -2393,10 +2385,7 @@ static int ethtool_set_per_queue_coalesce(struct net_device *dev,
 
 	useraddr += sizeof(*per_queue_opt);
 
-	bitmap_from_u32array(queue_mask,
-			     MAX_NUM_QUEUE,
-			     per_queue_opt->queue_mask,
-			     DIV_ROUND_UP(MAX_NUM_QUEUE, 32));
+	bitmap_from_arr32(queue_mask, per_queue_opt->queue_mask, MAX_NUM_QUEUE);
 	n_queue = bitmap_weight(queue_mask, MAX_NUM_QUEUE);
 	tmp = backup = kmalloc_array(n_queue, sizeof(*backup), GFP_KERNEL);
 	if (!backup)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 6ec670f..45d97e9 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -261,6 +261,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
 	struct ip_tunnel_net *itn;
 	struct ip_tunnel *tunnel;
 	const struct iphdr *iph;
+	struct erspan_md2 *md2;
 	int ver;
 	int len;
 
@@ -313,21 +314,14 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
 				return PACKET_REJECT;
 
 			md = ip_tunnel_info_opts(&tun_dst->u.tun_info);
-			memcpy(md, pkt_md, sizeof(*md));
 			md->version = ver;
+			md2 = &md->u.md2;
+			memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
+						       ERSPAN_V2_MDSIZE);
 
 			info = &tun_dst->u.tun_info;
 			info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
 			info->options_len = sizeof(*md);
-		} else {
-			tunnel->erspan_ver = ver;
-			if (ver == 1) {
-				tunnel->index = ntohl(pkt_md->u.index);
-			} else {
-				tunnel->dir = pkt_md->u.md2.dir;
-				tunnel->hwid = get_hwid(&pkt_md->u.md2);
-			}
-
 		}
 
 		skb_reset_mac_header(skb);
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 05f070e..3c35312 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -505,6 +505,7 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
 	struct erspan_base_hdr *ershdr;
 	struct erspan_metadata *pkt_md;
 	const struct ipv6hdr *ipv6h;
+	struct erspan_md2 *md2;
 	struct ip6_tnl *tunnel;
 	u8 ver;
 
@@ -551,24 +552,16 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
 
 			info = &tun_dst->u.tun_info;
 			md = ip_tunnel_info_opts(info);
-
-			memcpy(md, pkt_md, sizeof(*md));
 			md->version = ver;
+			md2 = &md->u.md2;
+			memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
+						       ERSPAN_V2_MDSIZE);
 			info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
 			info->options_len = sizeof(*md);
 
 			ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
 
 		} else {
-			tunnel->parms.erspan_ver = ver;
-
-			if (ver == 1) {
-				tunnel->parms.index = ntohl(pkt_md->u.index);
-			} else {
-				tunnel->parms.dir = pkt_md->u.md2.dir;
-				tunnel->parms.hwid = get_hwid(&pkt_md->u.md2);
-			}
-
 			ip6_tnl_rcv(tunnel, skb, tpi, NULL, log_ecn_error);
 		}
 
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 6a5d0e3..9b9d2ff 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -65,10 +65,10 @@
 #include <net/ip6_checksum.h>
 
 /* Ensure that we have struct in6_addr aligned on 32bit word. */
-static void *__mld2_query_bugs[] __attribute__((__unused__)) = {
-	BUILD_BUG_ON_NULL(offsetof(struct mld2_query, mld2q_srcs) % 4),
-	BUILD_BUG_ON_NULL(offsetof(struct mld2_report, mld2r_grec) % 4),
-	BUILD_BUG_ON_NULL(offsetof(struct mld2_grec, grec_mca) % 4)
+static int __mld2_query_bugs[] __attribute__((__unused__)) = {
+	BUILD_BUG_ON_ZERO(offsetof(struct mld2_query, mld2q_srcs) % 4),
+	BUILD_BUG_ON_ZERO(offsetof(struct mld2_report, mld2r_grec) % 4),
+	BUILD_BUG_ON_ZERO(offsetof(struct mld2_grec, grec_mca) % 4)
 };
 
 static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
diff --git a/net/rds/ib.c b/net/rds/ib.c
index b2a5067..ff0c980 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -345,7 +345,8 @@ static int rds_ib_laddr_check(struct net *net, __be32 addr)
 	/* Create a CMA ID and try to bind it. This catches both
 	 * IB and iWARP capable NICs.
 	 */
-	cm_id = rdma_create_id(&init_net, NULL, NULL, RDMA_PS_TCP, IB_QPT_RC);
+	cm_id = rdma_create_id(&init_net, rds_rdma_cm_event_handler,
+			       NULL, RDMA_PS_TCP, IB_QPT_RC);
 	if (IS_ERR(cm_id))
 		return PTR_ERR(cm_id);
 
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index e3c5e39..6311a54 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -398,10 +398,12 @@ static int u32_init(struct tcf_proto *tp)
 static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n,
 			   bool free_pf)
 {
+	struct tc_u_hnode *ht = rtnl_dereference(n->ht_down);
+
 	tcf_exts_destroy(&n->exts);
 	tcf_exts_put_net(&n->exts);
-	if (n->ht_down)
-		n->ht_down->refcnt--;
+	if (ht && --ht->refcnt == 0)
+		kfree(ht);
 #ifdef CONFIG_CLS_U32_PERF
 	if (free_pf)
 		free_percpu(n->pf);
@@ -659,16 +661,15 @@ static void u32_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
 
 		hlist_del(&tp_c->hnode);
 
-		for (ht = rtnl_dereference(tp_c->hlist);
-		     ht;
-		     ht = rtnl_dereference(ht->next)) {
-			ht->refcnt--;
-			u32_clear_hnode(tp, ht, extack);
-		}
-
 		while ((ht = rtnl_dereference(tp_c->hlist)) != NULL) {
+			u32_clear_hnode(tp, ht, extack);
 			RCU_INIT_POINTER(tp_c->hlist, ht->next);
-			kfree_rcu(ht, rcu);
+
+			/* u32_destroy_key() will later free ht for us, if it's
+			 * still referenced by some knode
+			 */
+			if (--ht->refcnt == 0)
+				kfree_rcu(ht, rcu);
 		}
 
 		idr_destroy(&tp_c->handle_idr);
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 5d4c15b..e35d4f7 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -326,8 +326,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
 		final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
 		bdst = ip6_dst_lookup_flow(sk, fl6, final_p);
 
-		if (!IS_ERR(bdst) &&
-		    ipv6_chk_addr(dev_net(bdst->dev),
+		if (IS_ERR(bdst))
+			continue;
+
+		if (ipv6_chk_addr(dev_net(bdst->dev),
 				  &laddr->a.v6.sin6_addr, bdst->dev, 1)) {
 			if (!IS_ERR_OR_NULL(dst))
 				dst_release(dst);
@@ -336,8 +338,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
 		}
 
 		bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
-		if (matchlen > bmatchlen)
+		if (matchlen > bmatchlen) {
+			dst_release(bdst);
 			continue;
+		}
 
 		if (!IS_ERR_OR_NULL(dst))
 			dst_release(dst);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 6a38c250..91813e6 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -514,22 +514,20 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
 		if (IS_ERR(rt))
 			continue;
 
-		if (!dst)
-			dst = &rt->dst;
-
 		/* Ensure the src address belongs to the output
 		 * interface.
 		 */
 		odev = __ip_dev_find(sock_net(sk), laddr->a.v4.sin_addr.s_addr,
 				     false);
 		if (!odev || odev->ifindex != fl4->flowi4_oif) {
-			if (&rt->dst != dst)
+			if (!dst)
+				dst = &rt->dst;
+			else
 				dst_release(&rt->dst);
 			continue;
 		}
 
-		if (dst != &rt->dst)
-			dst_release(dst);
+		dst_release(dst);
 		dst = &rt->dst;
 		break;
 	}
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 64335bb..ec3fc8d 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -45,7 +45,7 @@
 hostprogs-y += syscall_tp
 
 # Libbpf dependencies
-LIBBPF := ../../tools/lib/bpf/bpf.o
+LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o
 CGROUP_HELPERS := ../../tools/testing/selftests/bpf/cgroup_helpers.o
 
 test_lru_dist-objs := test_lru_dist.o $(LIBBPF)
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 242631a..69806d7 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -695,105 +695,3 @@ struct ksym *ksym_search(long key)
 	return &syms[0];
 }
 
-int set_link_xdp_fd(int ifindex, int fd, __u32 flags)
-{
-	struct sockaddr_nl sa;
-	int sock, seq = 0, len, ret = -1;
-	char buf[4096];
-	struct nlattr *nla, *nla_xdp;
-	struct {
-		struct nlmsghdr  nh;
-		struct ifinfomsg ifinfo;
-		char             attrbuf[64];
-	} req;
-	struct nlmsghdr *nh;
-	struct nlmsgerr *err;
-
-	memset(&sa, 0, sizeof(sa));
-	sa.nl_family = AF_NETLINK;
-
-	sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-	if (sock < 0) {
-		printf("open netlink socket: %s\n", strerror(errno));
-		return -1;
-	}
-
-	if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
-		printf("bind to netlink: %s\n", strerror(errno));
-		goto cleanup;
-	}
-
-	memset(&req, 0, sizeof(req));
-	req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
-	req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
-	req.nh.nlmsg_type = RTM_SETLINK;
-	req.nh.nlmsg_pid = 0;
-	req.nh.nlmsg_seq = ++seq;
-	req.ifinfo.ifi_family = AF_UNSPEC;
-	req.ifinfo.ifi_index = ifindex;
-
-	/* started nested attribute for XDP */
-	nla = (struct nlattr *)(((char *)&req)
-				+ NLMSG_ALIGN(req.nh.nlmsg_len));
-	nla->nla_type = NLA_F_NESTED | 43/*IFLA_XDP*/;
-	nla->nla_len = NLA_HDRLEN;
-
-	/* add XDP fd */
-	nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
-	nla_xdp->nla_type = 1/*IFLA_XDP_FD*/;
-	nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
-	memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
-	nla->nla_len += nla_xdp->nla_len;
-
-	/* if user passed in any flags, add those too */
-	if (flags) {
-		nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
-		nla_xdp->nla_type = 3/*IFLA_XDP_FLAGS*/;
-		nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
-		memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
-		nla->nla_len += nla_xdp->nla_len;
-	}
-
-	req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
-
-	if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
-		printf("send to netlink: %s\n", strerror(errno));
-		goto cleanup;
-	}
-
-	len = recv(sock, buf, sizeof(buf), 0);
-	if (len < 0) {
-		printf("recv from netlink: %s\n", strerror(errno));
-		goto cleanup;
-	}
-
-	for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
-	     nh = NLMSG_NEXT(nh, len)) {
-		if (nh->nlmsg_pid != getpid()) {
-			printf("Wrong pid %d, expected %d\n",
-			       nh->nlmsg_pid, getpid());
-			goto cleanup;
-		}
-		if (nh->nlmsg_seq != seq) {
-			printf("Wrong seq %d, expected %d\n",
-			       nh->nlmsg_seq, seq);
-			goto cleanup;
-		}
-		switch (nh->nlmsg_type) {
-		case NLMSG_ERROR:
-			err = (struct nlmsgerr *)NLMSG_DATA(nh);
-			if (!err->error)
-				continue;
-			printf("nlmsg error %s\n", strerror(-err->error));
-			goto cleanup;
-		case NLMSG_DONE:
-			break;
-		}
-	}
-
-	ret = 0;
-
-cleanup:
-	close(sock);
-	return ret;
-}
diff --git a/samples/bpf/bpf_load.h b/samples/bpf/bpf_load.h
index 7d57a42..453c200 100644
--- a/samples/bpf/bpf_load.h
+++ b/samples/bpf/bpf_load.h
@@ -61,5 +61,5 @@ struct ksym {
 
 int load_kallsyms(void);
 struct ksym *ksym_search(long key);
-int set_link_xdp_fd(int ifindex, int fd, __u32 flags);
+int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
 #endif
diff --git a/samples/bpf/tcbpf2_kern.c b/samples/bpf/tcbpf2_kern.c
index f6bbf8f..efdc16d 100644
--- a/samples/bpf/tcbpf2_kern.c
+++ b/samples/bpf/tcbpf2_kern.c
@@ -15,6 +15,7 @@
 #include <uapi/linux/tcp.h>
 #include <uapi/linux/filter.h>
 #include <uapi/linux/pkt_cls.h>
+#include <uapi/linux/erspan.h>
 #include <net/ipv6.h>
 #include "bpf_helpers.h"
 #include "bpf_endian.h"
@@ -35,24 +36,10 @@ struct geneve_opt {
 	u8	opt_data[8]; /* hard-coded to 8 byte */
 };
 
-struct erspan_md2 {
-	__be32 timestamp;
-	__be16 sgt;
-	__be16 flags;
-};
-
 struct vxlan_metadata {
 	u32     gbp;
 };
 
-struct erspan_metadata {
-	union {
-		__be32 index;
-		struct erspan_md2 md2;
-	} u;
-	int version;
-};
-
 SEC("gre_set_tunnel")
 int _gre_set_tunnel(struct __sk_buff *skb)
 {
@@ -156,13 +143,15 @@ int _erspan_set_tunnel(struct __sk_buff *skb)
 	__builtin_memset(&md, 0, sizeof(md));
 #ifdef ERSPAN_V1
 	md.version = 1;
-	md.u.index = htonl(123);
+	md.u.index = bpf_htonl(123);
 #else
 	u8 direction = 1;
-	u16 hwid = 7;
+	u8 hwid = 7;
 
 	md.version = 2;
-	md.u.md2.flags = htons((direction << 3) | (hwid << 4));
+	md.u.md2.dir = direction;
+	md.u.md2.hwid = hwid & 0xf;
+	md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
 #endif
 
 	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
@@ -207,9 +196,9 @@ int _erspan_get_tunnel(struct __sk_buff *skb)
 	char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
 
 	bpf_trace_printk(fmt2, sizeof(fmt2),
-		(ntohs(md.u.md2.flags) >> 3) & 0x1,
-		(ntohs(md.u.md2.flags) >> 4) & 0x3f,
-		bpf_ntohl(md.u.md2.timestamp));
+			 md.u.md2.dir,
+			 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
+			 bpf_ntohl(md.u.md2.timestamp));
 #endif
 
 	return TC_ACT_OK;
@@ -242,10 +231,12 @@ int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
 	md.version = 1;
 #else
 	u8 direction = 0;
-	u16 hwid = 17;
+	u8 hwid = 17;
 
 	md.version = 2;
-	md.u.md2.flags = htons((direction << 3) | (hwid << 4));
+	md.u.md2.dir = direction;
+	md.u.md2.hwid = hwid & 0xf;
+	md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
 #endif
 
 	ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
@@ -290,9 +281,9 @@ int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
 	char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
 
 	bpf_trace_printk(fmt2, sizeof(fmt2),
-		(ntohs(md.u.md2.flags) >> 3) & 0x1,
-		(ntohs(md.u.md2.flags) >> 4) & 0x3f,
-		bpf_ntohl(md.u.md2.timestamp));
+			 md.u.md2.dir,
+			 (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
+			 bpf_ntohl(md.u.md2.timestamp));
 #endif
 
 	return TC_ACT_OK;
diff --git a/samples/bpf/test_tunnel_bpf.sh b/samples/bpf/test_tunnel_bpf.sh
index ae7f7c3..43ce0499 100755
--- a/samples/bpf/test_tunnel_bpf.sh
+++ b/samples/bpf/test_tunnel_bpf.sh
@@ -68,7 +68,7 @@
 		ip netns exec at_ns0 \
 		ip link add dev $DEV_NS type $TYPE seq key 2 \
 		local 172.16.1.100 remote 172.16.1.200 \
-		erspan_ver 2 erspan_dir 1 erspan_hwid 3
+		erspan_ver 2 erspan_dir egress erspan_hwid 3
 	fi
 	ip netns exec at_ns0 ip link set dev $DEV_NS up
 	ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
@@ -97,7 +97,7 @@
 		ip netns exec at_ns0 \
 		ip link add dev $DEV_NS type $TYPE seq key 2 \
 		local ::11 remote ::22 \
-		erspan_ver 2 erspan_dir 1 erspan_hwid 7
+		erspan_ver 2 erspan_dir egress erspan_hwid 7
 	fi
 	ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 	ip netns exec at_ns0 ip link set dev $DEV_NS up
diff --git a/samples/bpf/xdp1_user.c b/samples/bpf/xdp1_user.c
index fdaefe9..b901ee2 100644
--- a/samples/bpf/xdp1_user.c
+++ b/samples/bpf/xdp1_user.c
@@ -25,7 +25,7 @@ static __u32 xdp_flags;
 
 static void int_exit(int sig)
 {
-	set_link_xdp_fd(ifindex, -1, xdp_flags);
+	bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
 	exit(0);
 }
 
@@ -116,7 +116,7 @@ int main(int argc, char **argv)
 	signal(SIGINT, int_exit);
 	signal(SIGTERM, int_exit);
 
-	if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
+	if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
 		printf("link set xdp fd failed\n");
 		return 1;
 	}
diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c
index 35fec9f..23744a8 100644
--- a/samples/bpf/xdp_redirect_cpu_user.c
+++ b/samples/bpf/xdp_redirect_cpu_user.c
@@ -26,7 +26,7 @@ static const char *__doc__ =
 
 /* Wanted to get rid of bpf_load.h and fake-"libbpf.h" (and instead
  * use bpf/libbpf.h), but cannot as (currently) needed for XDP
- * attaching to a device via set_link_xdp_fd()
+ * attaching to a device via bpf_set_link_xdp_fd()
  */
 #include "libbpf.h"
 #include "bpf_load.h"
@@ -67,7 +67,7 @@ static void int_exit(int sig)
 		"Interrupted: Removing XDP program on ifindex:%d device:%s\n",
 		ifindex, ifname);
 	if (ifindex > -1)
-		set_link_xdp_fd(ifindex, -1, xdp_flags);
+		bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
 	exit(EXIT_OK);
 }
 
@@ -682,7 +682,7 @@ int main(int argc, char **argv)
 	/* Remove XDP program when program is interrupted */
 	signal(SIGINT, int_exit);
 
-	if (set_link_xdp_fd(ifindex, prog_fd[prog_num], xdp_flags) < 0) {
+	if (bpf_set_link_xdp_fd(ifindex, prog_fd[prog_num], xdp_flags) < 0) {
 		fprintf(stderr, "link set xdp fd failed\n");
 		return EXIT_FAIL_XDP;
 	}
diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c
index 978a532..7eae07d72 100644
--- a/samples/bpf/xdp_redirect_map_user.c
+++ b/samples/bpf/xdp_redirect_map_user.c
@@ -34,9 +34,9 @@ static __u32 xdp_flags;
 
 static void int_exit(int sig)
 {
-	set_link_xdp_fd(ifindex_in, -1, xdp_flags);
+	bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
 	if (ifindex_out_xdp_dummy_attached)
-		set_link_xdp_fd(ifindex_out, -1, xdp_flags);
+		bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
 	exit(0);
 }
 
@@ -120,13 +120,13 @@ int main(int argc, char **argv)
 		return 1;
 	}
 
-	if (set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
+	if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
 		printf("ERROR: link set xdp fd failed on %d\n", ifindex_in);
 		return 1;
 	}
 
 	/* Loading dummy XDP prog on out-device */
-	if (set_link_xdp_fd(ifindex_out, prog_fd[1],
+	if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1],
 			    (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
 		printf("WARN: link set xdp fd failed on %d\n", ifindex_out);
 		ifindex_out_xdp_dummy_attached = false;
diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c
index 4475d83..d54e91eb 100644
--- a/samples/bpf/xdp_redirect_user.c
+++ b/samples/bpf/xdp_redirect_user.c
@@ -33,9 +33,9 @@ static __u32 xdp_flags;
 
 static void int_exit(int sig)
 {
-	set_link_xdp_fd(ifindex_in, -1, xdp_flags);
+	bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
 	if (ifindex_out_xdp_dummy_attached)
-		set_link_xdp_fd(ifindex_out, -1, xdp_flags);
+		bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
 	exit(0);
 }
 
@@ -114,13 +114,13 @@ int main(int argc, char **argv)
 		return 1;
 	}
 
-	if (set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
+	if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
 		printf("ERROR: link set xdp fd failed on %d\n", ifindex_in);
 		return 1;
 	}
 
 	/* Loading dummy XDP prog on out-device */
-	if (set_link_xdp_fd(ifindex_out, prog_fd[1],
+	if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1],
 			    (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
 		printf("WARN: link set xdp fd failed on %d\n", ifindex_out);
 		ifindex_out_xdp_dummy_attached = false;
diff --git a/samples/bpf/xdp_router_ipv4_user.c b/samples/bpf/xdp_router_ipv4_user.c
index 9164621..6296741 100644
--- a/samples/bpf/xdp_router_ipv4_user.c
+++ b/samples/bpf/xdp_router_ipv4_user.c
@@ -37,7 +37,7 @@ static void int_exit(int sig)
 	int i = 0;
 
 	for (i = 0; i < total_ifindex; i++)
-		set_link_xdp_fd(ifindex_list[i], -1, flags);
+		bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
 	exit(0);
 }
 
@@ -49,7 +49,7 @@ static void close_and_exit(int sig)
 	close(sock_arp);
 
 	for (i = 0; i < total_ifindex; i++)
-		set_link_xdp_fd(ifindex_list[i], -1, flags);
+		bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
 	exit(0);
 }
 
@@ -183,7 +183,7 @@ static void read_route(struct nlmsghdr *nh, int nll)
 			int i = 0;
 
 			for (i = 0; i < total_ifindex; i++)
-				set_link_xdp_fd(ifindex_list[i], -1, flags);
+				bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
 			exit(0);
 		}
 		assert(bpf_map_update_elem(map_fd[4], &route.iface, &route.iface, 0) == 0);
@@ -633,12 +633,12 @@ int main(int ac, char **argv)
 		}
 	}
 	for (i = 0; i < total_ifindex; i++) {
-		if (set_link_xdp_fd(ifindex_list[i], prog_fd[0], flags) < 0) {
+		if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd[0], flags) < 0) {
 			printf("link set xdp fd failed\n");
 			int recovery_index = i;
 
 			for (i = 0; i < recovery_index; i++)
-				set_link_xdp_fd(ifindex_list[i], -1, flags);
+				bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
 
 			return 1;
 		}
diff --git a/samples/bpf/xdp_rxq_info_user.c b/samples/bpf/xdp_rxq_info_user.c
index 32430e8..478d954 100644
--- a/samples/bpf/xdp_rxq_info_user.c
+++ b/samples/bpf/xdp_rxq_info_user.c
@@ -56,7 +56,7 @@ static void int_exit(int sig)
 		"Interrupted: Removing XDP program on ifindex:%d device:%s\n",
 		ifindex, ifname);
 	if (ifindex > -1)
-		set_link_xdp_fd(ifindex, -1, xdp_flags);
+		bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
 	exit(EXIT_OK);
 }
 
@@ -521,7 +521,7 @@ int main(int argc, char **argv)
 	/* Remove XDP program when program is interrupted */
 	signal(SIGINT, int_exit);
 
-	if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
+	if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
 		fprintf(stderr, "link set xdp fd failed\n");
 		return EXIT_FAIL_XDP;
 	}
diff --git a/samples/bpf/xdp_tx_iptunnel_user.c b/samples/bpf/xdp_tx_iptunnel_user.c
index 715cd12..f0a7872 100644
--- a/samples/bpf/xdp_tx_iptunnel_user.c
+++ b/samples/bpf/xdp_tx_iptunnel_user.c
@@ -30,7 +30,7 @@ static __u32 xdp_flags = 0;
 static void int_exit(int sig)
 {
 	if (ifindex > -1)
-		set_link_xdp_fd(ifindex, -1, xdp_flags);
+		bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
 	exit(0);
 }
 
@@ -254,14 +254,14 @@ int main(int argc, char **argv)
 		}
 	}
 
-	if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
+	if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
 		printf("link set xdp fd failed\n");
 		return 1;
 	}
 
 	poll_stats(kill_after_s);
 
-	set_link_xdp_fd(ifindex, -1, xdp_flags);
+	bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
 
 	return 0;
 }
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan
index 1ce7115..69552a3 100644
--- a/scripts/Makefile.kasan
+++ b/scripts/Makefile.kasan
@@ -10,10 +10,7 @@
 
 CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address
 
-CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \
-		-fasan-shadow-offset=$(KASAN_SHADOW_OFFSET) \
-		--param asan-stack=1 --param asan-globals=1 \
-		--param asan-instrumentation-with-call-threshold=$(call_threshold))
+cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1)))
 
 ifeq ($(call cc-option, $(CFLAGS_KASAN_MINIMAL) -Werror),)
    ifneq ($(CONFIG_COMPILE_TEST),y)
@@ -21,14 +18,30 @@
             -fsanitize=kernel-address is not supported by compiler)
    endif
 else
-    ifeq ($(CFLAGS_KASAN),)
-        ifneq ($(CONFIG_COMPILE_TEST),y)
-            $(warning CONFIG_KASAN: compiler does not support all options.\
-                Trying minimal configuration)
-        endif
-        CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL)
-    endif
+   # -fasan-shadow-offset fails without -fsanitize
+   CFLAGS_KASAN_SHADOW := $(call cc-option, -fsanitize=kernel-address \
+			-fasan-shadow-offset=$(KASAN_SHADOW_OFFSET), \
+			$(call cc-option, -fsanitize=kernel-address \
+			-mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET)))
+
+   ifeq ($(strip $(CFLAGS_KASAN_SHADOW)),)
+      CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL)
+   else
+      # Now add all the compiler specific options that are valid standalone
+      CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \
+	$(call cc-param,asan-globals=1) \
+	$(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \
+	$(call cc-param,asan-stack=1) \
+	$(call cc-param,asan-use-after-scope=1) \
+	$(call cc-param,asan-instrument-allocas=1)
+   endif
+
 endif
 
+ifdef CONFIG_KASAN_EXTRA
 CFLAGS_KASAN += $(call cc-option, -fsanitize-address-use-after-scope)
 endif
+
+CFLAGS_KASAN_NOSANITIZE := -fno-builtin
+
+endif
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 5fdc1a1..5589bae 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -121,7 +121,7 @@
 ifeq ($(CONFIG_KASAN),y)
 _c_flags += $(if $(patsubst n%,, \
 		$(KASAN_SANITIZE_$(basetarget).o)$(KASAN_SANITIZE)y), \
-		$(CFLAGS_KASAN))
+		$(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE))
 endif
 
 ifeq ($(CONFIG_UBSAN),y)
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index 8fd4d44..b593b36 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -7,7 +7,6 @@
       CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow)
       CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds)
       CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size)
-      CFLAGS_UBSAN += $(call cc-option, -fsanitize=returns-nonnull-attribute)
       CFLAGS_UBSAN += $(call cc-option, -fsanitize=bool)
       CFLAGS_UBSAN += $(call cc-option, -fsanitize=enum)
 
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index e954df2..3d40403 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -566,6 +566,7 @@
 	$mode_perms_search .= '|' if ($mode_perms_search ne "");
 	$mode_perms_search .= $entry->[0];
 }
+$mode_perms_search = "(?:${mode_perms_search})";
 
 our $mode_perms_world_writable = qr{
 	S_IWUGO		|
@@ -600,6 +601,37 @@
 	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
 	$mode_perms_string_search .= $entry;
 }
+our $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
+our $multi_mode_perms_string_search = qr{
+	${single_mode_perms_string_search}
+	(?:\s*\|\s*${single_mode_perms_string_search})*
+}x;
+
+sub perms_to_octal {
+	my ($string) = @_;
+
+	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
+
+	my $val = "";
+	my $oval = "";
+	my $to = 0;
+	my $curpos = 0;
+	my $lastpos = 0;
+	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
+		$curpos = pos($string);
+		my $match = $2;
+		my $omatch = $1;
+		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
+		$lastpos = $curpos;
+		$to |= $mode_permission_string_types{$match};
+		$val .= '\s*\|\s*' if ($val ne "");
+		$val .= $match;
+		$oval .= $omatch;
+	}
+	$oval =~ s/^\s*\|\s*//;
+	$oval =~ s/\s*\|\s*$//;
+	return sprintf("%04o", $to);
+}
 
 our $allowed_asm_includes = qr{(?x:
 	irq|
@@ -2875,6 +2907,7 @@
 #	logging functions like pr_info that end in a string
 #	lines with a single string
 #	#defines that are a single string
+#	lines with an RFC3986 like URL
 #
 # There are 3 different line length message types:
 # LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
@@ -2906,6 +2939,10 @@
 				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
 				$msg_type = "";
 
+			# URL ($rawline is used in case the URL is in a comment)
+			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
+				$msg_type = "";
+
 			# Otherwise set the alternate message types
 
 			# a comment starts before $max_line_length
@@ -2983,7 +3020,7 @@
 
 # check indentation starts on a tab stop
 		if ($^V && $^V ge 5.10.0 &&
-		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) {
+		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
 			my $indent = length($1);
 			if ($indent % 8) {
 				if (WARN("TABSTOP",
@@ -3882,10 +3919,12 @@
 
 # function brace can't be on same line, except for #defines of do while,
 # or if closed on same line
-		if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and
-		    !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) {
+		if ($^V && $^V ge 5.10.0 &&
+		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
+		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
+		    $sline !~ /}/) {
 			if (ERROR("OPEN_BRACE",
-				  "open brace '{' following function declarations go on the next line\n" . $herecurr) &&
+				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
 			    $fix) {
 				fix_delete_line($fixlinenr, $rawline);
 				my $fixed_line = $rawline;
@@ -4489,7 +4528,9 @@
 		}
 
 # check for unnecessary parentheses around comparisons in if uses
-		if ($^V && $^V ge 5.10.0 && defined($stat) &&
+# when !drivers/staging or command-line uses --strict
+		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
+		    $^V && $^V ge 5.10.0 && defined($stat) &&
 		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
 			my $if_stat = $1;
 			my $test = substr($2, 1, -1);
@@ -5307,7 +5348,7 @@
 		}
 
 # check for line continuations in quoted strings with odd counts of "
-		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
+		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
 			WARN("LINE_CONTINUATIONS",
 			     "Avoid line continuations in quoted strings\n" . $herecurr);
 		}
@@ -6269,8 +6310,69 @@
 			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
 		}
 
+# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
+# and whether or not function naming is typical and if
+# DEVICE_ATTR permissions uses are unusual too
+		if ($^V && $^V ge 5.10.0 &&
+		    defined $stat &&
+		    $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
+			my $var = $1;
+			my $perms = $2;
+			my $show = $3;
+			my $store = $4;
+			my $octal_perms = perms_to_octal($perms);
+			if ($show =~ /^${var}_show$/ &&
+			    $store =~ /^${var}_store$/ &&
+			    $octal_perms eq "0644") {
+				if (WARN("DEVICE_ATTR_RW",
+					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
+				    $fix) {
+					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
+				}
+			} elsif ($show =~ /^${var}_show$/ &&
+				 $store =~ /^NULL$/ &&
+				 $octal_perms eq "0444") {
+				if (WARN("DEVICE_ATTR_RO",
+					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
+				    $fix) {
+					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
+				}
+			} elsif ($show =~ /^NULL$/ &&
+				 $store =~ /^${var}_store$/ &&
+				 $octal_perms eq "0200") {
+				if (WARN("DEVICE_ATTR_WO",
+					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
+				    $fix) {
+					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
+				}
+			} elsif ($octal_perms eq "0644" ||
+				 $octal_perms eq "0444" ||
+				 $octal_perms eq "0200") {
+				my $newshow = "$show";
+				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
+				my $newstore = $store;
+				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
+				my $rename = "";
+				if ($show ne $newshow) {
+					$rename .= " '$show' to '$newshow'";
+				}
+				if ($store ne $newstore) {
+					$rename .= " '$store' to '$newstore'";
+				}
+				WARN("DEVICE_ATTR_FUNCTIONS",
+				     "Consider renaming function(s)$rename\n" . $herecurr);
+			} else {
+				WARN("DEVICE_ATTR_PERMS",
+				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
+			}
+		}
+
 # Mode permission misuses where it seems decimal should be octal
 # This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
+# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
+#   specific definition of not visible in sysfs.
+# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
+#   use the default permissions
 		if ($^V && $^V ge 5.10.0 &&
 		    defined $stat &&
 		    $line =~ /$mode_perms_search/) {
@@ -6294,8 +6396,9 @@
 				if ($stat =~ /$test/) {
 					my $val = $1;
 					$val = $6 if ($skip_args ne "");
-					if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
-					    ($val =~ /^$Octal$/ && length($val) ne 4)) {
+					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
+					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
+					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
 						ERROR("NON_OCTAL_PERMISSIONS",
 						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
 					}
@@ -6308,30 +6411,13 @@
 		}
 
 # check for uses of S_<PERMS> that could be octal for readability
-		if ($line =~ /\b$mode_perms_string_search\b/) {
-			my $val = "";
-			my $oval = "";
-			my $to = 0;
-			my $curpos = 0;
-			my $lastpos = 0;
-			while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
-				$curpos = pos($line);
-				my $match = $2;
-				my $omatch = $1;
-				last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
-				$lastpos = $curpos;
-				$to |= $mode_permission_string_types{$match};
-				$val .= '\s*\|\s*' if ($val ne "");
-				$val .= $match;
-				$oval .= $omatch;
-			}
-			$oval =~ s/^\s*\|\s*//;
-			$oval =~ s/\s*\|\s*$//;
-			my $octal = sprintf("%04o", $to);
+		if ($line =~ /\b($multi_mode_perms_string_search)\b/) {
+			my $oval = $1;
+			my $octal = perms_to_octal($oval);
 			if (WARN("SYMBOLIC_PERMS",
 				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
 			    $fix) {
-				$fixed[$fixlinenr] =~ s/$val/$octal/;
+				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
 			}
 		}
 
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 6510536..9917f92 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1685,7 +1685,7 @@ static void extable_mismatch_handler(const char* modname, struct elf_info *elf,
 static void check_section_mismatch(const char *modname, struct elf_info *elf,
 				   Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
 {
-	const char *tosec = sec_name(elf, get_secindex(elf, sym));;
+	const char *tosec = sec_name(elf, get_secindex(elf, sym));
 	const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
 
 	if (mismatch) {
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 061425dd..2cfb0c7 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -135,7 +135,7 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
 		update = test_and_clear_bit(IMA_UPDATE_XATTR,
 					    &iint->atomic_flags);
 		if (!IS_I_VERSION(inode) ||
-		    inode_cmp_iversion(inode, iint->version) ||
+		    !inode_eq_iversion(inode, iint->version) ||
 		    (iint->flags & IMA_NEW_FILE)) {
 			iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
 			iint->measured_pcrs = 0;
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index 8298e09..ffda91a 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -250,15 +250,10 @@ int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
 		} else {
 			struct task_struct *tracer;
 
-			rcu_read_lock();
-			tracer = find_task_by_vpid(arg2);
-			if (tracer)
-				get_task_struct(tracer);
-			else
+			tracer = find_get_task_by_vpid(arg2);
+			if (!tracer) {
 				rc = -EINVAL;
-			rcu_read_unlock();
-
-			if (tracer) {
+			} else {
 				rc = yama_ptracer_add(tracer, myself);
 				put_task_struct(tracer);
 			}
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index d7469cd..98f93e7 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -110,16 +110,15 @@ static const struct snd_soc_dapm_route intercon[] = {
 static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct device *dev = rtd->dev;
 	int ret;
 
-	printk(KERN_DEBUG
-			"at91sam9g20ek_wm8731 "
-			": at91sam9g20ek_wm8731_init() called\n");
+	dev_dbg(dev, "%s called\n", __func__);
 
 	ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_MCLK,
-		MCLK_RATE, SND_SOC_CLOCK_IN);
+				     MCLK_RATE, SND_SOC_CLOCK_IN);
 	if (ret < 0) {
-		printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret);
+		dev_err(dev, "Failed to set WM8731 SYSCLK: %d\n", ret);
 		return ret;
 	}
 
@@ -179,21 +178,21 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
 	 */
 	mclk = clk_get(NULL, "pck0");
 	if (IS_ERR(mclk)) {
-		printk(KERN_ERR "ASoC: Failed to get MCLK\n");
+		dev_err(&pdev->dev, "Failed to get MCLK\n");
 		ret = PTR_ERR(mclk);
 		goto err;
 	}
 
 	pllb = clk_get(NULL, "pllb");
 	if (IS_ERR(pllb)) {
-		printk(KERN_ERR "ASoC: Failed to get PLLB\n");
+		dev_err(&pdev->dev, "Failed to get PLLB\n");
 		ret = PTR_ERR(pllb);
 		goto err_mclk;
 	}
 	ret = clk_set_parent(mclk, pllb);
 	clk_put(pllb);
 	if (ret != 0) {
-		printk(KERN_ERR "ASoC: Failed to set MCLK parent\n");
+		dev_err(&pdev->dev, "Failed to set MCLK parent\n");
 		goto err_mclk;
 	}
 
@@ -236,7 +235,7 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
 
 	ret = snd_soc_register_card(card);
 	if (ret) {
-		printk(KERN_ERR "ASoC: snd_soc_register_card() failed\n");
+		dev_err(&pdev->dev, "snd_soc_register_card() failed\n");
 	}
 
 	return ret;
diff --git a/sound/soc/atmel/sam9x5_wm8731.c b/sound/soc/atmel/sam9x5_wm8731.c
index ccdf547..e6c303a 100644
--- a/sound/soc/atmel/sam9x5_wm8731.c
+++ b/sound/soc/atmel/sam9x5_wm8731.c
@@ -49,13 +49,13 @@ static int sam9x5_wm8731_init(struct snd_soc_pcm_runtime *rtd)
 	struct device *dev = rtd->dev;
 	int ret;
 
-	dev_dbg(dev, "ASoC: %s called\n", __func__);
+	dev_dbg(dev, "%s called\n", __func__);
 
 	/* set the codec system clock for DAC and ADC */
 	ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
 				     MCLK_RATE, SND_SOC_CLOCK_IN);
 	if (ret < 0) {
-		dev_err(dev, "ASoC: Failed to set WM8731 SYSCLK: %d\n", ret);
+		dev_err(dev, "Failed to set WM8731 SYSCLK: %d\n", ret);
 		return ret;
 	}
 
@@ -146,8 +146,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
 
 	ret = atmel_ssc_set_audio(priv->ssc_id);
 	if (ret != 0) {
-		dev_err(&pdev->dev,
-			"ASoC: Failed to set SSC %d for audio: %d\n",
+		dev_err(&pdev->dev, "Failed to set SSC %d for audio: %d\n",
 			ret, priv->ssc_id);
 		goto out;
 	}
@@ -157,12 +156,11 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
 
 	ret = snd_soc_register_card(card);
 	if (ret) {
-		dev_err(&pdev->dev,
-			"ASoC: Platform device allocation failed\n");
+		dev_err(&pdev->dev, "Platform device allocation failed\n");
 		goto out_put_audio;
 	}
 
-	dev_dbg(&pdev->dev, "ASoC: %s ok\n", __func__);
+	dev_dbg(&pdev->dev, "%s ok\n", __func__);
 
 	return ret;
 
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index b95bb8b..3d1cf47 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -15,6 +15,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -95,6 +96,9 @@ struct ak4613_priv {
 	struct mutex lock;
 	const struct ak4613_interface *iface;
 	struct snd_pcm_hw_constraint_list constraint;
+	struct work_struct dummy_write_work;
+	struct snd_soc_component *component;
+	unsigned int rate;
 	unsigned int sysclk;
 
 	unsigned int fmt;
@@ -392,6 +396,7 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
 	default:
 		return -EINVAL;
 	}
+	priv->rate = rate;
 
 	/*
 	 * FIXME
@@ -467,11 +472,83 @@ static int ak4613_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
+static void ak4613_dummy_write(struct work_struct *work)
+{
+	struct ak4613_priv *priv = container_of(work,
+						struct ak4613_priv,
+						dummy_write_work);
+	struct snd_soc_component *component = priv->component;
+	unsigned int mgmt1;
+	unsigned int mgmt3;
+
+	/*
+	 * PW_MGMT1 / PW_MGMT3 needs dummy write at least after 5 LR clocks
+	 *
+	 * Note
+	 *
+	 * To avoid extra delay, we want to avoid preemption here,
+	 * but we can't. Because it uses I2C access which is using IRQ
+	 * and sleep. Thus, delay might be more than 5 LR clocks
+	 * see also
+	 *	ak4613_dai_trigger()
+	 */
+	udelay(5000000 / priv->rate);
+
+	snd_soc_component_read(component, PW_MGMT1, &mgmt1);
+	snd_soc_component_read(component, PW_MGMT3, &mgmt3);
+
+	snd_soc_component_write(component, PW_MGMT1, mgmt1);
+	snd_soc_component_write(component, PW_MGMT3, mgmt3);
+}
+
+static int ak4613_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+			      struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+
+	/*
+	 * FIXME
+	 *
+	 * PW_MGMT1 / PW_MGMT3 needs dummy write at least after 5 LR clocks
+	 * from Power Down Release. Otherwise, Playback volume will be 0dB.
+	 * To avoid complex multiple delay/dummy_write method from
+	 * ak4613_set_bias_level() / SND_SOC_DAPM_DAC_E("DACx", ...),
+	 * call it once here.
+	 *
+	 * But, unfortunately, we can't "write" here because here is atomic
+	 * context (It uses I2C access for writing).
+	 * Thus, use schedule_work() to switching to normal context
+	 * immediately.
+	 *
+	 * Note
+	 *
+	 * Calling ak4613_dummy_write() function might be delayed.
+	 * In such case, ak4613 volume might be temporarily 0dB when
+	 * beggining of playback.
+	 * see also
+	 *	ak4613_dummy_write()
+	 */
+
+	if ((cmd != SNDRV_PCM_TRIGGER_START) &&
+	    (cmd != SNDRV_PCM_TRIGGER_RESUME))
+		return 0;
+
+	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
+		return  0;
+
+	priv->component = &codec->component;
+	schedule_work(&priv->dummy_write_work);
+
+	return 0;
+}
+
 static const struct snd_soc_dai_ops ak4613_dai_ops = {
 	.startup	= ak4613_dai_startup,
 	.shutdown	= ak4613_dai_shutdown,
 	.set_sysclk	= ak4613_dai_set_sysclk,
 	.set_fmt	= ak4613_dai_set_fmt,
+	.trigger	= ak4613_dai_trigger,
 	.hw_params	= ak4613_dai_hw_params,
 };
 
@@ -590,6 +667,7 @@ static int ak4613_i2c_probe(struct i2c_client *i2c,
 	priv->iface		= NULL;
 	priv->cnt		= 0;
 	priv->sysclk		= 0;
+	INIT_WORK(&priv->dummy_write_work, ak4613_dummy_write);
 
 	mutex_init(&priv->lock);
 
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index c88f974..cf83c42 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -113,7 +113,7 @@ static int dmic_dev_probe(struct platform_device *pdev)
 
 	if (pdev->dev.of_node) {
 		err = of_property_read_u32(pdev->dev.of_node, "num-channels", &chans);
-		if (err && (err != -ENOENT))
+		if (err && (err != -EINVAL))
 			return err;
 
 		if (!err) {
diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c
index 31b0864..562e887 100644
--- a/sound/soc/codecs/max98373.c
+++ b/sound/soc/codecs/max98373.c
@@ -1,5 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (c) 2017, Maxim Integrated */
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017, Maxim Integrated
 
 #include <linux/acpi.h>
 #include <linux/i2c.h>
diff --git a/sound/soc/codecs/max98373.h b/sound/soc/codecs/max98373.h
index d0b359d..f6a37aa 100644
--- a/sound/soc/codecs/max98373.h
+++ b/sound/soc/codecs/max98373.h
@@ -1,5 +1,6 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (c) 2017, Maxim Integrated */
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017, Maxim Integrated
+
 #ifndef _MAX98373_H
 #define _MAX98373_H
 
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 633cdcf..e1ab553 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1392,7 +1392,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
 
 		ana_pwr |= SGTL5000_LINEREG_D_POWERUP;
 		dev_info(&client->dev,
-			 "Using internal LDO instead of VDDD: check ER1\n");
+			 "Using internal LDO instead of VDDD: check ER1 erratum\n");
 	} else {
 		/* using external LDO for VDDD
 		 * Clear startup powerup and simple powerup
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 8798182..e4d7f39 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -2195,6 +2195,8 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec)
 static const struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
 	.probe = twl4030_soc_probe,
 	.remove = twl4030_soc_remove,
+	.read = twl4030_read,
+	.write = twl4030_write,
 	.set_bias_level = twl4030_set_bias_level,
 	.idle_bias_off = true,
 
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 3b895b4..573a523 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1158,6 +1158,8 @@ static int twl6040_remove(struct snd_soc_codec *codec)
 static const struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
 	.probe = twl6040_probe,
 	.remove = twl6040_remove,
+	.read = twl6040_read,
+	.write = twl6040_write,
 	.set_bias_level = twl6040_set_bias_level,
 	.suspend_bias_off = true,
 	.ignore_pmdown_time = true,
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index f2c9e8c..ceb105c 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -97,6 +97,9 @@
 	  codec, then enable this option by saying Y or m. This is a
 	  recommended option
 
+config SND_SOC_INTEL_SKYLAKE_SSP_CLK
+	tristate
+
 config SND_SOC_INTEL_SKYLAKE
 	tristate "SKL/BXT/KBL/GLK/CNL... Platforms"
 	depends on PCI && ACPI
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index d4e1036..fefb1ee 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -235,6 +235,7 @@
 	select SND_SOC_MAX98927
 	select SND_SOC_DMIC
 	select SND_SOC_HDAC_HDMI
+	select SND_SOC_INTEL_SKYLAKE_SSP_CLK
 	help
 	  This adds support for ASoC Onboard Codec I2S machine driver. This will
 	  create an alsa sound card for RT5663 + MAX98927.
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c
index bf7014c..f5df6bc 100644
--- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
@@ -28,6 +28,9 @@
 #include "../../codecs/rt5663.h"
 #include "../../codecs/hdac_hdmi.h"
 #include "../skylake/skl.h"
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
 
 #define KBL_REALTEK_CODEC_DAI "rt5663-aif"
 #define KBL_MAXIM_CODEC_DAI "max98927-aif1"
@@ -48,6 +51,8 @@ struct kbl_hdmi_pcm {
 struct kbl_rt5663_private {
 	struct snd_soc_jack kabylake_headset;
 	struct list_head hdmi_pcm_list;
+	struct clk *mclk;
+	struct clk *sclk;
 };
 
 enum {
@@ -69,6 +74,61 @@ static const struct snd_kcontrol_new kabylake_controls[] = {
 	SOC_DAPM_PIN_SWITCH("Right Spk"),
 };
 
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
+			struct snd_kcontrol *k, int  event)
+{
+	struct snd_soc_dapm_context *dapm = w->dapm;
+	struct snd_soc_card *card = dapm->card;
+	struct kbl_rt5663_private *priv = snd_soc_card_get_drvdata(card);
+	int ret = 0;
+
+	/*
+	 * MCLK/SCLK need to be ON early for a successful synchronization of
+	 * codec internal clock. And the clocks are turned off during
+	 * POST_PMD after the stream is stopped.
+	 */
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		/* Enable MCLK */
+		ret = clk_set_rate(priv->mclk, 24000000);
+		if (ret < 0) {
+			dev_err(card->dev, "Can't set rate for mclk, err: %d\n",
+				ret);
+			return ret;
+		}
+
+		ret = clk_prepare_enable(priv->mclk);
+		if (ret < 0) {
+			dev_err(card->dev, "Can't enable mclk, err: %d\n", ret);
+			return ret;
+		}
+
+		/* Enable SCLK */
+		ret = clk_set_rate(priv->sclk, 3072000);
+		if (ret < 0) {
+			dev_err(card->dev, "Can't set rate for sclk, err: %d\n",
+				ret);
+			clk_disable_unprepare(priv->mclk);
+			return ret;
+		}
+
+		ret = clk_prepare_enable(priv->sclk);
+		if (ret < 0) {
+			dev_err(card->dev, "Can't enable sclk, err: %d\n", ret);
+			clk_disable_unprepare(priv->mclk);
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		clk_disable_unprepare(priv->mclk);
+		clk_disable_unprepare(priv->sclk);
+		break;
+	default:
+		return 0;
+	}
+
+	return 0;
+}
+
 static const struct snd_soc_dapm_widget kabylake_widgets[] = {
 	SND_SOC_DAPM_HP("Headphone Jack", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
@@ -78,11 +138,14 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = {
 	SND_SOC_DAPM_SPK("HDMI1", NULL),
 	SND_SOC_DAPM_SPK("HDMI2", NULL),
 	SND_SOC_DAPM_SPK("HDMI3", NULL),
-
+	SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+			platform_clock_control, SND_SOC_DAPM_PRE_PMU |
+			SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_route kabylake_map[] = {
 	/* HP jack connectors - unknown if we have jack detection */
+	{ "Headphone Jack", NULL, "Platform Clock" },
 	{ "Headphone Jack", NULL, "HPOL" },
 	{ "Headphone Jack", NULL, "HPOR" },
 
@@ -91,6 +154,7 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
 	{ "Right Spk", NULL, "Right BE_OUT" },
 
 	/* other jacks */
+	{ "Headset Mic", NULL, "Platform Clock" },
 	{ "IN1P", NULL, "Headset Mic" },
 	{ "IN1N", NULL, "Headset Mic" },
 	{ "DMic", NULL, "SoC DMIC" },
@@ -901,6 +965,7 @@ static int kabylake_audio_probe(struct platform_device *pdev)
 {
 	struct kbl_rt5663_private *ctx;
 	struct skl_machine_pdata *pdata;
+	int ret;
 
 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
 	if (!ctx)
@@ -919,6 +984,34 @@ static int kabylake_audio_probe(struct platform_device *pdev)
 		dmic_constraints = pdata->dmic_num == 2 ?
 			&constraints_dmic_2ch : &constraints_dmic_channels;
 
+	ctx->mclk = devm_clk_get(&pdev->dev, "ssp1_mclk");
+	if (IS_ERR(ctx->mclk)) {
+		ret = PTR_ERR(ctx->mclk);
+		if (ret == -ENOENT) {
+			dev_info(&pdev->dev,
+				"Failed to get ssp1_sclk, defer probe\n");
+			return -EPROBE_DEFER;
+		}
+
+		dev_err(&pdev->dev, "Failed to get ssp1_mclk with err:%d\n",
+								ret);
+		return ret;
+	}
+
+	ctx->sclk = devm_clk_get(&pdev->dev, "ssp1_sclk");
+	if (IS_ERR(ctx->sclk)) {
+		ret = PTR_ERR(ctx->sclk);
+		if (ret == -ENOENT) {
+			dev_info(&pdev->dev,
+				"Failed to get ssp1_sclk, defer probe\n");
+			return -EPROBE_DEFER;
+		}
+
+		dev_err(&pdev->dev, "Failed to get ssp1_sclk with err:%d\n",
+								ret);
+		return ret;
+	}
+
 	return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card);
 }
 
diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile
index d1ccbec..86f6e1d 100644
--- a/sound/soc/intel/skylake/Makefile
+++ b/sound/soc/intel/skylake/Makefile
@@ -14,3 +14,8 @@
 		skl-sst-utils.o
 
 obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o
+
+#Skylake Clock device support
+snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o
+
+obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK) += snd-soc-skl-ssp-clk.o
diff --git a/sound/soc/intel/skylake/skl-i2s.h b/sound/soc/intel/skylake/skl-i2s.h
index dcf819b..ad0a1bb 100644
--- a/sound/soc/intel/skylake/skl-i2s.h
+++ b/sound/soc/intel/skylake/skl-i2s.h
@@ -27,6 +27,12 @@
 #define SKL_SHIFT(x)			(ffs(x) - 1)
 #define SKL_MCLK_DIV_RATIO_MASK		GENMASK(11, 0)
 
+#define is_legacy_blob(x) (x.signature != 0xEE)
+#define ext_to_legacy_blob(i2s_config_blob_ext) \
+	((struct skl_i2s_config_blob_legacy *) i2s_config_blob_ext)
+
+#define get_clk_src(mclk, mask) \
+		((mclk.mdivctrl & mask) >> SKL_SHIFT(mask))
 struct skl_i2s_config {
 	u32 ssc0;
 	u32 ssc1;
@@ -45,6 +51,24 @@ struct skl_i2s_config_mclk {
 	u32 mdivr;
 };
 
+struct skl_i2s_config_mclk_ext {
+	u32 mdivctrl;
+	u32 mdivr_count;
+	u32 mdivr[0];
+} __packed;
+
+struct skl_i2s_config_blob_signature {
+	u32 minor_ver : 8;
+	u32 major_ver : 8;
+	u32 resvdz : 8;
+	u32 signature : 8;
+} __packed;
+
+struct skl_i2s_config_blob_header {
+	struct skl_i2s_config_blob_signature sig;
+	u32 size;
+};
+
 /**
  * struct skl_i2s_config_blob_legacy - Structure defines I2S Gateway
  * configuration legacy blob
@@ -61,4 +85,11 @@ struct skl_i2s_config_blob_legacy {
 	struct skl_i2s_config_mclk mclk;
 };
 
+struct skl_i2s_config_blob_ext {
+	u32 gtw_attr;
+	struct skl_i2s_config_blob_header hdr;
+	u32 tdm_ts_group[SKL_I2S_MAX_TIME_SLOTS];
+	struct skl_i2s_config i2s_cfg;
+	struct skl_i2s_config_mclk_ext mclk;
+} __packed;
 #endif /* __SOUND_SOC_SKL_I2S_H */
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 8cbf080..60d76ad 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -675,6 +675,7 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
 	kfree(dma_ctrl);
 	return err;
 }
+EXPORT_SYMBOL_GPL(skl_dsp_set_dma_control);
 
 static void skl_setup_out_format(struct skl_sst *ctx,
 			struct skl_module_cfg *mconfig,
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index 3b1d2b8..b9b1402 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -28,6 +28,7 @@ static guid_t osc_guid =
 	GUID_INIT(0xA69F886E, 0x6CEB, 0x4594,
 		  0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53);
 
+
 struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
 {
 	acpi_handle handle;
@@ -287,6 +288,7 @@ void skl_nhlt_remove_sysfs(struct skl *skl)
 static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
 				struct nhlt_fmt *fmt, u8 id)
 {
+	struct skl_i2s_config_blob_ext *i2s_config_ext;
 	struct skl_i2s_config_blob_legacy *i2s_config;
 	struct skl_clk_parent_src *parent;
 	struct skl_ssp_clk *sclk, *sclkfs;
@@ -347,12 +349,18 @@ static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
 
 		/* Fill rate and parent for sclk/sclkfs */
 		if (!present) {
-			/* MCLK Divider Source Select */
-			i2s_config = (struct skl_i2s_config_blob_legacy *)
+			i2s_config_ext = (struct skl_i2s_config_blob_ext *)
 						fmt->fmt_config[0].config.caps;
-			clk_src = ((i2s_config->mclk.mdivctrl)
-					& SKL_MNDSS_DIV_CLK_SRC_MASK) >>
-					SKL_SHIFT(SKL_MNDSS_DIV_CLK_SRC_MASK);
+
+			/* MCLK Divider Source Select */
+			if (is_legacy_blob(i2s_config_ext->hdr.sig)) {
+				i2s_config = ext_to_legacy_blob(i2s_config_ext);
+				clk_src = get_clk_src(i2s_config->mclk,
+						SKL_MNDSS_DIV_CLK_SRC_MASK);
+			} else {
+				clk_src = get_clk_src(i2s_config_ext->mclk,
+						SKL_MNDSS_DIV_CLK_SRC_MASK);
+			}
 
 			parent = skl_get_parent_clk(clk_src);
 
@@ -378,6 +386,7 @@ static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
 static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk,
 				struct nhlt_fmt *fmt, u8 id)
 {
+	struct skl_i2s_config_blob_ext *i2s_config_ext;
 	struct skl_i2s_config_blob_legacy *i2s_config;
 	struct nhlt_specific_cfg *fmt_cfg;
 	struct skl_clk_parent_src *parent;
@@ -385,13 +394,21 @@ static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk,
 	u8 clk_src;
 
 	fmt_cfg = &fmt->fmt_config[0].config;
-	i2s_config = (struct skl_i2s_config_blob_legacy *)fmt_cfg->caps;
+	i2s_config_ext = (struct skl_i2s_config_blob_ext *)fmt_cfg->caps;
 
-	/* MCLK Divider Source Select */
-	clk_src = ((i2s_config->mclk.mdivctrl) & SKL_MCLK_DIV_CLK_SRC_MASK) >>
-					SKL_SHIFT(SKL_MCLK_DIV_CLK_SRC_MASK);
-
-	clkdiv = i2s_config->mclk.mdivr & SKL_MCLK_DIV_RATIO_MASK;
+	/* MCLK Divider Source Select and divider */
+	if (is_legacy_blob(i2s_config_ext->hdr.sig)) {
+		i2s_config = ext_to_legacy_blob(i2s_config_ext);
+		clk_src = get_clk_src(i2s_config->mclk,
+				SKL_MCLK_DIV_CLK_SRC_MASK);
+		clkdiv = i2s_config->mclk.mdivr &
+				SKL_MCLK_DIV_RATIO_MASK;
+	} else {
+		clk_src = get_clk_src(i2s_config_ext->mclk,
+				SKL_MCLK_DIV_CLK_SRC_MASK);
+		clkdiv = i2s_config_ext->mclk.mdivr[0] &
+				SKL_MCLK_DIV_RATIO_MASK;
+	}
 
 	/* bypass divider */
 	div_ratio = 1;
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.c b/sound/soc/intel/skylake/skl-ssp-clk.c
new file mode 100644
index 0000000..7fbddf5
--- /dev/null
+++ b/sound/soc/intel/skylake/skl-ssp-clk.c
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2015-17 Intel Corporation
+
+/*
+ *  skl-ssp-clk.c - ASoC skylake ssp clock driver
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include "skl.h"
+#include "skl-ssp-clk.h"
+#include "skl-topology.h"
+
+#define to_skl_clk(_hw)	container_of(_hw, struct skl_clk, hw)
+
+struct skl_clk_parent {
+	struct clk_hw *hw;
+	struct clk_lookup *lookup;
+};
+
+struct skl_clk {
+	struct clk_hw hw;
+	struct clk_lookup *lookup;
+	unsigned long rate;
+	struct skl_clk_pdata *pdata;
+	u32 id;
+};
+
+struct skl_clk_data {
+	struct skl_clk_parent parent[SKL_MAX_CLK_SRC];
+	struct skl_clk *clk[SKL_MAX_CLK_CNT];
+	u8 avail_clk_cnt;
+};
+
+static int skl_get_clk_type(u32 index)
+{
+	switch (index) {
+	case 0 ... (SKL_SCLK_OFS - 1):
+		return SKL_MCLK;
+
+	case SKL_SCLK_OFS ... (SKL_SCLKFS_OFS - 1):
+		return SKL_SCLK;
+
+	case SKL_SCLKFS_OFS ... (SKL_MAX_CLK_CNT - 1):
+		return SKL_SCLK_FS;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int skl_get_vbus_id(u32 index, u8 clk_type)
+{
+	switch (clk_type) {
+	case SKL_MCLK:
+		return index;
+
+	case SKL_SCLK:
+		return index - SKL_SCLK_OFS;
+
+	case SKL_SCLK_FS:
+		return index - SKL_SCLKFS_OFS;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static void skl_fill_clk_ipc(struct skl_clk_rate_cfg_table *rcfg, u8 clk_type)
+{
+	struct nhlt_fmt_cfg *fmt_cfg;
+	union skl_clk_ctrl_ipc *ipc;
+	struct wav_fmt *wfmt;
+
+	if (!rcfg)
+		return;
+
+	ipc = &rcfg->dma_ctl_ipc;
+	if (clk_type == SKL_SCLK_FS) {
+		fmt_cfg = (struct nhlt_fmt_cfg *)rcfg->config;
+		wfmt = &fmt_cfg->fmt_ext.fmt;
+
+		/* Remove TLV Header size */
+		ipc->sclk_fs.hdr.size = sizeof(struct skl_dmactrl_sclkfs_cfg) -
+						sizeof(struct skl_tlv_hdr);
+		ipc->sclk_fs.sampling_frequency = wfmt->samples_per_sec;
+		ipc->sclk_fs.bit_depth = wfmt->bits_per_sample;
+		ipc->sclk_fs.valid_bit_depth =
+			fmt_cfg->fmt_ext.sample.valid_bits_per_sample;
+		ipc->sclk_fs.number_of_channels = wfmt->channels;
+	} else {
+		ipc->mclk.hdr.type = DMA_CLK_CONTROLS;
+		/* Remove TLV Header size */
+		ipc->mclk.hdr.size = sizeof(struct skl_dmactrl_mclk_cfg) -
+						sizeof(struct skl_tlv_hdr);
+	}
+}
+
+/* Sends dma control IPC to turn the clock ON/OFF */
+static int skl_send_clk_dma_control(struct skl *skl,
+				struct skl_clk_rate_cfg_table *rcfg,
+				u32 vbus_id, u8 clk_type,
+				bool enable)
+{
+	struct nhlt_specific_cfg *sp_cfg;
+	u32 i2s_config_size, node_id = 0;
+	struct nhlt_fmt_cfg *fmt_cfg;
+	union skl_clk_ctrl_ipc *ipc;
+	void *i2s_config = NULL;
+	u8 *data, size;
+	int ret;
+
+	if (!rcfg)
+		return -EIO;
+
+	ipc = &rcfg->dma_ctl_ipc;
+	fmt_cfg = (struct nhlt_fmt_cfg *)rcfg->config;
+	sp_cfg = &fmt_cfg->config;
+
+	if (clk_type == SKL_SCLK_FS) {
+		ipc->sclk_fs.hdr.type =
+			enable ? DMA_TRANSMITION_START : DMA_TRANSMITION_STOP;
+		data = (u8 *)&ipc->sclk_fs;
+		size = sizeof(struct skl_dmactrl_sclkfs_cfg);
+	} else {
+		/* 1 to enable mclk, 0 to enable sclk */
+		if (clk_type == SKL_SCLK)
+			ipc->mclk.mclk = 0;
+		else
+			ipc->mclk.mclk = 1;
+
+		ipc->mclk.keep_running = enable;
+		ipc->mclk.warm_up_over = enable;
+		ipc->mclk.clk_stop_over = !enable;
+		data = (u8 *)&ipc->mclk;
+		size = sizeof(struct skl_dmactrl_mclk_cfg);
+	}
+
+	i2s_config_size = sp_cfg->size + size;
+	i2s_config = kzalloc(i2s_config_size, GFP_KERNEL);
+	if (!i2s_config)
+		return -ENOMEM;
+
+	/* copy blob */
+	memcpy(i2s_config, sp_cfg->caps, sp_cfg->size);
+
+	/* copy additional dma controls information */
+	memcpy(i2s_config + sp_cfg->size, data, size);
+
+	node_id = ((SKL_DMA_I2S_LINK_INPUT_CLASS << 8) | (vbus_id << 4));
+	ret = skl_dsp_set_dma_control(skl->skl_sst, (u32 *)i2s_config,
+					i2s_config_size, node_id);
+	kfree(i2s_config);
+
+	return ret;
+}
+
+static struct skl_clk_rate_cfg_table *skl_get_rate_cfg(
+		struct skl_clk_rate_cfg_table *rcfg,
+				unsigned long rate)
+{
+	int i;
+
+	for (i = 0; (i < SKL_MAX_CLK_RATES) && rcfg[i].rate; i++) {
+		if (rcfg[i].rate == rate)
+			return &rcfg[i];
+	}
+
+	return NULL;
+}
+
+static int skl_clk_change_status(struct skl_clk *clkdev,
+				bool enable)
+{
+	struct skl_clk_rate_cfg_table *rcfg;
+	int vbus_id, clk_type;
+
+	clk_type = skl_get_clk_type(clkdev->id);
+	if (clk_type < 0)
+		return clk_type;
+
+	vbus_id = skl_get_vbus_id(clkdev->id, clk_type);
+	if (vbus_id < 0)
+		return vbus_id;
+
+	rcfg = skl_get_rate_cfg(clkdev->pdata->ssp_clks[clkdev->id].rate_cfg,
+						clkdev->rate);
+	if (!rcfg)
+		return -EINVAL;
+
+	return skl_send_clk_dma_control(clkdev->pdata->pvt_data, rcfg,
+					vbus_id, clk_type, enable);
+}
+
+static int skl_clk_prepare(struct clk_hw *hw)
+{
+	struct skl_clk *clkdev = to_skl_clk(hw);
+
+	return skl_clk_change_status(clkdev, true);
+}
+
+static void skl_clk_unprepare(struct clk_hw *hw)
+{
+	struct skl_clk *clkdev = to_skl_clk(hw);
+
+	skl_clk_change_status(clkdev, false);
+}
+
+static int skl_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long parent_rate)
+{
+	struct skl_clk *clkdev = to_skl_clk(hw);
+	struct skl_clk_rate_cfg_table *rcfg;
+	int clk_type;
+
+	if (!rate)
+		return -EINVAL;
+
+	rcfg = skl_get_rate_cfg(clkdev->pdata->ssp_clks[clkdev->id].rate_cfg,
+							rate);
+	if (!rcfg)
+		return -EINVAL;
+
+	clk_type = skl_get_clk_type(clkdev->id);
+	if (clk_type < 0)
+		return clk_type;
+
+	skl_fill_clk_ipc(rcfg, clk_type);
+	clkdev->rate = rate;
+
+	return 0;
+}
+
+static unsigned long skl_clk_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct skl_clk *clkdev = to_skl_clk(hw);
+
+	if (clkdev->rate)
+		return clkdev->rate;
+
+	return 0;
+}
+
+/* Not supported by clk driver. Implemented to satisfy clk fw */
+long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *parent_rate)
+{
+	return rate;
+}
+
+/*
+ * prepare/unprepare are used instead of enable/disable as IPC will be sent
+ * in non-atomic context.
+ */
+static const struct clk_ops skl_clk_ops = {
+	.prepare = skl_clk_prepare,
+	.unprepare = skl_clk_unprepare,
+	.set_rate = skl_clk_set_rate,
+	.round_rate = skl_clk_round_rate,
+	.recalc_rate = skl_clk_recalc_rate,
+};
+
+static void unregister_parent_src_clk(struct skl_clk_parent *pclk,
+					unsigned int id)
+{
+	while (id--) {
+		clkdev_drop(pclk[id].lookup);
+		clk_hw_unregister_fixed_rate(pclk[id].hw);
+	}
+}
+
+static void unregister_src_clk(struct skl_clk_data *dclk)
+{
+	u8 cnt = dclk->avail_clk_cnt;
+
+	while (cnt--)
+		clkdev_drop(dclk->clk[cnt]->lookup);
+}
+
+static int skl_register_parent_clks(struct device *dev,
+			struct skl_clk_parent *parent,
+			struct skl_clk_parent_src *pclk)
+{
+	int i, ret;
+
+	for (i = 0; i < SKL_MAX_CLK_SRC; i++) {
+
+		/* Register Parent clock */
+		parent[i].hw = clk_hw_register_fixed_rate(dev, pclk[i].name,
+				pclk[i].parent_name, 0, pclk[i].rate);
+		if (IS_ERR(parent[i].hw)) {
+			ret = PTR_ERR(parent[i].hw);
+			goto err;
+		}
+
+		parent[i].lookup = clkdev_hw_create(parent[i].hw, pclk[i].name,
+									NULL);
+		if (!parent[i].lookup) {
+			clk_hw_unregister_fixed_rate(parent[i].hw);
+			ret = -ENOMEM;
+			goto err;
+		}
+	}
+
+	return 0;
+err:
+	unregister_parent_src_clk(parent, i);
+	return ret;
+}
+
+/* Assign fmt_config to clk_data */
+static struct skl_clk *register_skl_clk(struct device *dev,
+			struct skl_ssp_clk *clk,
+			struct skl_clk_pdata *clk_pdata, int id)
+{
+	struct clk_init_data init;
+	struct skl_clk *clkdev;
+	int ret;
+
+	clkdev = devm_kzalloc(dev, sizeof(*clkdev), GFP_KERNEL);
+	if (!clkdev)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = clk->name;
+	init.ops = &skl_clk_ops;
+	init.flags = CLK_SET_RATE_GATE;
+	init.parent_names = &clk->parent_name;
+	init.num_parents = 1;
+	clkdev->hw.init = &init;
+	clkdev->pdata = clk_pdata;
+
+	clkdev->id = id;
+	ret = devm_clk_hw_register(dev, &clkdev->hw);
+	if (ret) {
+		clkdev = ERR_PTR(ret);
+		return clkdev;
+	}
+
+	clkdev->lookup = clkdev_hw_create(&clkdev->hw, init.name, NULL);
+	if (!clkdev->lookup)
+		clkdev = ERR_PTR(-ENOMEM);
+
+	return clkdev;
+}
+
+static int skl_clk_dev_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device *parent_dev = dev->parent;
+	struct skl_clk_parent_src *parent_clks;
+	struct skl_clk_pdata *clk_pdata;
+	struct skl_clk_data *data;
+	struct skl_ssp_clk *clks;
+	int ret, i;
+
+	clk_pdata = dev_get_platdata(&pdev->dev);
+	parent_clks = clk_pdata->parent_clks;
+	clks = clk_pdata->ssp_clks;
+	if (!parent_clks || !clks)
+		return -EIO;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	/* Register Parent clock */
+	ret = skl_register_parent_clks(parent_dev, data->parent, parent_clks);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < clk_pdata->num_clks; i++) {
+		/*
+		 * Only register valid clocks
+		 * i.e. for which nhlt entry is present.
+		 */
+		if (clks[i].rate_cfg[0].rate == 0)
+			continue;
+
+		data->clk[i] = register_skl_clk(dev, &clks[i], clk_pdata, i);
+		if (IS_ERR(data->clk[i])) {
+			ret = PTR_ERR(data->clk[i]);
+			goto err_unreg_skl_clk;
+		}
+
+		data->avail_clk_cnt++;
+	}
+
+	platform_set_drvdata(pdev, data);
+
+	return 0;
+
+err_unreg_skl_clk:
+	unregister_src_clk(data);
+	unregister_parent_src_clk(data->parent, SKL_MAX_CLK_SRC);
+
+	return ret;
+}
+
+static int skl_clk_dev_remove(struct platform_device *pdev)
+{
+	struct skl_clk_data *data;
+
+	data = platform_get_drvdata(pdev);
+	unregister_src_clk(data);
+	unregister_parent_src_clk(data->parent, SKL_MAX_CLK_SRC);
+
+	return 0;
+}
+
+static struct platform_driver skl_clk_driver = {
+	.driver = {
+		.name = "skl-ssp-clk",
+	},
+	.probe = skl_clk_dev_probe,
+	.remove = skl_clk_dev_remove,
+};
+
+module_platform_driver(skl_clk_driver);
+
+MODULE_DESCRIPTION("Skylake clock driver");
+MODULE_AUTHOR("Jaikrishna Nemallapudi <jaikrishnax.nemallapudi@intel.com>");
+MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:skl-ssp-clk");
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.h b/sound/soc/intel/skylake/skl-ssp-clk.h
index c9ea840..d1be50f 100644
--- a/sound/soc/intel/skylake/skl-ssp-clk.h
+++ b/sound/soc/intel/skylake/skl-ssp-clk.h
@@ -54,8 +54,46 @@ struct skl_clk_parent_src {
 	const char *parent_name;
 };
 
+struct skl_tlv_hdr {
+	u32 type;
+	u32 size;
+};
+
+struct skl_dmactrl_mclk_cfg {
+	struct skl_tlv_hdr hdr;
+	/* DMA Clk TLV params */
+	u32 clk_warm_up:16;
+	u32 mclk:1;
+	u32 warm_up_over:1;
+	u32 rsvd0:14;
+	u32 clk_stop_delay:16;
+	u32 keep_running:1;
+	u32 clk_stop_over:1;
+	u32 rsvd1:14;
+};
+
+struct skl_dmactrl_sclkfs_cfg {
+	struct skl_tlv_hdr hdr;
+	/* DMA SClk&FS  TLV params */
+	u32 sampling_frequency;
+	u32 bit_depth;
+	u32 channel_map;
+	u32 channel_config;
+	u32 interleaving_style;
+	u32 number_of_channels : 8;
+	u32 valid_bit_depth : 8;
+	u32 sample_type : 8;
+	u32 reserved : 8;
+};
+
+union skl_clk_ctrl_ipc {
+	struct skl_dmactrl_mclk_cfg mclk;
+	struct skl_dmactrl_sclkfs_cfg sclk_fs;
+};
+
 struct skl_clk_rate_cfg_table {
 	unsigned long rate;
+	union skl_clk_ctrl_ipc dma_ctl_ipc;
 	void *config;
 };
 
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index f411579..2d13f3f 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -38,6 +38,10 @@
 /* D0I3C Register fields */
 #define AZX_REG_VS_D0I3C_CIP      0x1 /* Command in progress */
 #define AZX_REG_VS_D0I3C_I3       0x4 /* D0i3 enable */
+#define SKL_MAX_DMACTRL_CFG	18
+#define DMA_CLK_CONTROLS	1
+#define DMA_TRANSMITION_START	2
+#define DMA_TRANSMITION_STOP	3
 
 struct skl_dsp_resource {
 	u32 max_mcps;
@@ -147,6 +151,8 @@ int skl_nhlt_create_sysfs(struct skl *skl);
 void skl_nhlt_remove_sysfs(struct skl *skl);
 void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks);
 struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id);
+int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
+				u32 caps_size, u32 node_id);
 
 struct skl_module_cfg;
 
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index 5bc4e00..d68b53f 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -1405,9 +1405,24 @@ static int mt2701_afe_runtime_resume(struct device *dev)
 	return mt2701_afe_enable_clock(afe);
 }
 
-static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+static int mt2701_afe_add_component(struct mtk_base_afe *afe)
 {
 	struct snd_soc_component *component;
+
+	component = kzalloc(sizeof(*component), GFP_KERNEL);
+	if (!component)
+		return -ENOMEM;
+
+	component->regmap = afe->regmap;
+
+	return snd_soc_add_component(afe->dev, component,
+				     &mt2701_afe_pcm_dai_component,
+				     mt2701_afe_pcm_dais,
+				     ARRAY_SIZE(mt2701_afe_pcm_dais));
+}
+
+static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+{
 	struct mtk_base_afe *afe;
 	struct mt2701_afe_private *afe_priv;
 	struct device *dev;
@@ -1477,12 +1492,6 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
 			= &mt2701_i2s_data[i][I2S_IN];
 	}
 
-	component = kzalloc(sizeof(*component), GFP_KERNEL);
-	if (!component)
-		return -ENOMEM;
-
-	component->regmap = afe->regmap;
-
 	afe->mtk_afe_hardware = &mt2701_afe_hardware;
 	afe->memif_fs = mt2701_memif_fs;
 	afe->irq_fs = mt2701_irq_fs;
@@ -1495,7 +1504,7 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
 	ret = mt2701_init_clock(afe);
 	if (ret) {
 		dev_err(dev, "init clock error\n");
-		goto err_init_clock;
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, afe);
@@ -1514,10 +1523,7 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
 		goto err_platform;
 	}
 
-	ret = snd_soc_add_component(dev, component,
-				    &mt2701_afe_pcm_dai_component,
-				    mt2701_afe_pcm_dais,
-				    ARRAY_SIZE(mt2701_afe_pcm_dais));
+	ret = mt2701_afe_add_component(afe);
 	if (ret) {
 		dev_warn(dev, "err_dai_component\n");
 		goto err_dai_component;
@@ -1531,8 +1537,6 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
 	pm_runtime_put_sync(dev);
 err_pm_disable:
 	pm_runtime_disable(dev);
-err_init_clock:
-	kfree(component);
 
 	return ret;
 }
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index 40ebefd..679fc8b 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -272,15 +272,10 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
 	}
 	mt8173_rt5650_codecs[1].of_node = mt8173_rt5650_codecs[0].of_node;
 
-	if (of_find_node_by_name(platform_node, "codec-capture")) {
-		np = of_get_child_by_name(pdev->dev.of_node, "codec-capture");
-		if (!np) {
-			dev_err(&pdev->dev,
-				"%s: Can't find codec-capture DT node\n",
-				__func__);
-			return -EINVAL;
-		}
+	np = of_get_child_by_name(pdev->dev.of_node, "codec-capture");
+	if (np) {
 		ret = snd_soc_of_get_dai_name(np, &codec_capture_dai);
+		of_node_put(np);
 		if (ret < 0) {
 			dev_err(&pdev->dev,
 				"%s codec_capture_dai name fail %d\n",
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
index fa6cd1d..214bfc7 100644
--- a/sound/soc/rockchip/rk3399_gru_sound.c
+++ b/sound/soc/rockchip/rk3399_gru_sound.c
@@ -368,7 +368,8 @@ static const struct snd_soc_dai_link rockchip_dais[] = {
 	[DAILINK_RT5514_DSP] = {
 		.name = "RT5514 DSP",
 		.stream_name = "Wake on Voice",
-		.codec_dai_name = "rt5514-dsp-cpu-dai",
+		.codec_name = "snd-soc-dummy",
+		.codec_dai_name = "snd-soc-dummy-dai",
 	},
 };
 
@@ -529,7 +530,18 @@ static int rockchip_sound_of_parse_dais(struct device *dev,
 		if (index < 0)
 			continue;
 
-		np_cpu = (index == DAILINK_CDNDP) ? np_cpu1 : np_cpu0;
+		switch (index) {
+		case DAILINK_CDNDP:
+			np_cpu = np_cpu1;
+			break;
+		case DAILINK_RT5514_DSP:
+			np_cpu = np_codec;
+			break;
+		default:
+			np_cpu = np_cpu0;
+			break;
+		}
+
 		if (!np_cpu) {
 			dev_err(dev, "Missing 'rockchip,cpu' for %s\n",
 				rockchip_dais[index].name);
@@ -539,7 +551,8 @@ static int rockchip_sound_of_parse_dais(struct device *dev,
 		dai = &card->dai_link[card->num_links++];
 		*dai = rockchip_dais[index];
 
-		dai->codec_of_node = np_codec;
+		if (!dai->codec_name)
+			dai->codec_of_node = np_codec;
 		dai->platform_of_node = np_cpu;
 		dai->cpu_of_node = np_cpu;
 
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 81232f4..8240268 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -40,7 +40,8 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
 		ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
 		if (ret < 0) {
-			dev_err(cpu_dai->dev, "Compress ASoC: can't open interface %s: %d\n",
+			dev_err(cpu_dai->dev,
+				"Compress ASoC: can't open interface %s: %d\n",
 				cpu_dai->name, ret);
 			goto out;
 		}
@@ -49,8 +50,9 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
 	if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) {
 		ret = platform->driver->compr_ops->open(cstream);
 		if (ret < 0) {
-			pr_err("compress asoc: can't open platform %s\n",
-				platform->component.name);
+			dev_err(platform->dev,
+				"Compress ASoC: can't open platform %s: %d\n",
+				platform->component.name, ret);
 			goto plat_err;
 		}
 	}
@@ -68,8 +70,9 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
 
 		__ret = component->driver->compr_ops->open(cstream);
 		if (__ret < 0) {
-			pr_err("compress asoc: can't open platform %s\n",
-			       component->name);
+			dev_err(component->dev,
+				"Compress ASoC: can't open platform %s: %d\n",
+				component->name, __ret);
 			ret = __ret;
 		}
 	}
@@ -79,7 +82,9 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
 	if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
 		ret = rtd->dai_link->compr_ops->startup(cstream);
 		if (ret < 0) {
-			pr_err("compress asoc: %s startup failed\n", rtd->dai_link->name);
+			dev_err(rtd->dev,
+				"Compress ASoC: %s startup failed: %d\n",
+				rtd->dai_link->name, ret);
 			goto machine_err;
 		}
 	}
@@ -139,18 +144,19 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
 		ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
 		if (ret < 0) {
-			dev_err(cpu_dai->dev, "Compress ASoC: can't open interface %s: %d\n",
+			dev_err(cpu_dai->dev,
+				"Compress ASoC: can't open interface %s: %d\n",
 				cpu_dai->name, ret);
 			goto out;
 		}
 	}
 
-
 	if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) {
 		ret = platform->driver->compr_ops->open(cstream);
 		if (ret < 0) {
-			pr_err("compress asoc: can't open platform %s\n",
-				platform->component.name);
+			dev_err(platform->dev,
+				"Compress ASoC: can't open platform %s: %d\n",
+				platform->component.name, ret);
 			goto plat_err;
 		}
 	}
@@ -168,8 +174,9 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
 
 		__ret = component->driver->compr_ops->open(cstream);
 		if (__ret < 0) {
-			pr_err("compress asoc: can't open platform %s\n",
-			       component->name);
+			dev_err(component->dev,
+				"Compress ASoC: can't open platform %s: %d\n",
+				component->name, __ret);
 			ret = __ret;
 		}
 	}
@@ -179,7 +186,8 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
 	if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
 		ret = fe->dai_link->compr_ops->startup(cstream);
 		if (ret < 0) {
-			pr_err("compress asoc: %s startup failed\n", fe->dai_link->name);
+			pr_err("Compress ASoC: %s startup failed: %d\n",
+			       fe->dai_link->name, ret);
 			goto machine_err;
 		}
 	}
@@ -190,7 +198,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
 	if (ret < 0)
 		goto fe_err;
 	else if (ret == 0)
-		dev_dbg(fe->dev, "ASoC: %s no valid %s route\n",
+		dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
 			fe->dai_link->name, stream ? "capture" : "playback");
 
 	/* calculate valid and active FE <-> BE dpcms */
@@ -265,10 +273,11 @@ static void close_delayed_work(struct work_struct *work)
 
 	mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
-	dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
-		 codec_dai->driver->playback.stream_name,
-		 codec_dai->playback_active ? "active" : "inactive",
-		 rtd->pop_wait ? "yes" : "no");
+	dev_dbg(rtd->dev,
+		"Compress ASoC: pop wq checking: %s status: %s waiting: %s\n",
+		codec_dai->driver->playback.stream_name,
+		codec_dai->playback_active ? "active" : "inactive",
+		rtd->pop_wait ? "yes" : "no");
 
 	/* are we waiting on this codec DAI stream */
 	if (rtd->pop_wait == 1) {
@@ -307,7 +316,6 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
 	if (!codec_dai->active)
 		codec_dai->rate = 0;
 
-
 	if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
 		rtd->dai_link->compr_ops->shutdown(cstream);
 
@@ -376,7 +384,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
 
 	ret = dpcm_be_dai_hw_free(fe, stream);
 	if (ret < 0)
-		dev_err(fe->dev, "compressed hw_free failed %d\n", ret);
+		dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
 
 	ret = dpcm_be_dai_shutdown(fe, stream);
 
@@ -460,7 +468,6 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
 	if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
 		cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
 
-
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 		snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
@@ -944,7 +951,7 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
 	struct snd_soc_platform *platform = rtd->platform;
 	struct snd_soc_component *component;
 	struct snd_soc_rtdcom_list *rtdcom;
-	int ret = 0, __ret;
+	int ret = 0;
 
 	mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
 
@@ -965,10 +972,10 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
 		    !component->driver->compr_ops->copy)
 			continue;
 
-		__ret = component->driver->compr_ops->copy(cstream, buf, count);
-		if (__ret < 0)
-			ret = __ret;
+		ret = component->driver->compr_ops->copy(cstream, buf, count);
+		break;
 	}
+
 err:
 	mutex_unlock(&rtd->pcm_mutex);
 	return ret;
@@ -1108,7 +1115,8 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 	int playback = 0, capture = 0;
 
 	if (rtd->num_codecs > 1) {
-		dev_err(rtd->card->dev, "Multicodec not supported for compressed stream\n");
+		dev_err(rtd->card->dev,
+			"Compress ASoC: Multicodec not supported\n");
 		return -EINVAL;
 	}
 
@@ -1126,8 +1134,9 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 	 * should be set, check for that (xor)
 	 */
 	if (playback + capture != 1) {
-		dev_err(rtd->card->dev, "Invalid direction for compress P %d, C %d\n",
-				playback, capture);
+		dev_err(rtd->card->dev,
+			"Compress ASoC: Invalid direction for P %d, C %d\n",
+			playback, capture);
 		return -EINVAL;
 	}
 
@@ -1155,8 +1164,9 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 				rtd->dai_link->dpcm_playback,
 				rtd->dai_link->dpcm_capture, &be_pcm);
 		if (ret < 0) {
-			dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n",
-				rtd->dai_link->name);
+			dev_err(rtd->card->dev,
+				"Compress ASoC: can't create compressed for %s: %d\n",
+				rtd->dai_link->name, ret);
 			goto compr_err;
 		}
 
@@ -1199,8 +1209,9 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 				new_name, compr);
 	if (ret < 0) {
 		component = rtd->codec_dai->component;
-		pr_err("compress asoc: can't create compress for codec %s\n",
-			component->name);
+		dev_err(component->dev,
+			"Compress ASoC: can't create compress for codec %s: %d\n",
+			component->name, ret);
 		goto compr_err;
 	}
 
@@ -1210,8 +1221,8 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
 	rtd->compr = compr;
 	compr->private_data = rtd;
 
-	printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name,
-		cpu_dai->name);
+	dev_info(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
+		 codec_dai->name, cpu_dai->name);
 	return ret;
 
 compr_err:
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 88efc84..96c44f6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -553,9 +553,17 @@ struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
 {
 	struct snd_soc_rtdcom_list *rtdcom;
 
+	if (!driver_name)
+		return NULL;
+
 	for_each_rtdcom(rtd, rtdcom) {
-		if ((rtdcom->component->driver->name == driver_name) ||
-		    strcmp(rtdcom->component->driver->name, driver_name) == 0)
+		const char *component_name = rtdcom->component->driver->name;
+
+		if (!component_name)
+			continue;
+
+		if ((component_name == driver_name) ||
+		    strcmp(component_name, driver_name) == 0)
 			return rtdcom->component;
 	}
 
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d1977ce..92894d9 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2026,7 +2026,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
 	snd_soc_dapm_for_each_direction(dir) {
 		rdir = SND_SOC_DAPM_DIR_REVERSE(dir);
 		snd_soc_dapm_widget_for_each_path(w, dir, p) {
-			if (p->connected && !p->connected(w, p->node[rdir]))
+			if (p->connected && !p->connected(p->source, p->sink))
 				continue;
 
 			if (!p->connect)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 8075856..0841254 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -144,7 +144,7 @@ bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd)
 	for_each_rtdcom(rtd, rtdcom) {
 		component = rtdcom->component;
 
-		ignore &= !component->driver->pmdown_time;
+		ignore &= !component->driver->use_pmdown_time;
 	}
 
 	/* this will be removed */
@@ -2831,10 +2831,9 @@ static void soc_pcm_private_free(struct snd_pcm *pcm)
 	struct snd_soc_rtdcom_list *rtdcom;
 	struct snd_soc_component *component;
 
+	/* need to sync the delayed work before releasing resources */
+	flush_delayed_work(&rtd->delayed_work);
 	for_each_rtdcom(rtd, rtdcom) {
-		/* need to sync the delayed work before releasing resources */
-
-		flush_delayed_work(&rtd->delayed_work);
 		component = rtdcom->component;
 
 		if (component->pcm_free)
diff --git a/sound/soc/stm/Kconfig b/sound/soc/stm/Kconfig
index 3ad881f..48f9ddd 100644
--- a/sound/soc/stm/Kconfig
+++ b/sound/soc/stm/Kconfig
@@ -2,7 +2,7 @@
 
 config SND_SOC_STM32_SAI
 	tristate "STM32 SAI interface (Serial Audio Interface) support"
-	depends on ARCH_STM32 || COMPILE_TEST
+	depends on (ARCH_STM32 && OF) || COMPILE_TEST
 	depends on SND_SOC
 	select SND_SOC_GENERIC_DMAENGINE_PCM
 	select REGMAP_MMIO
@@ -11,7 +11,7 @@
 
 config SND_SOC_STM32_I2S
 	tristate "STM32 I2S interface (SPI/I2S block) support"
-	depends on ARCH_STM32 || COMPILE_TEST
+	depends on (ARCH_STM32 && OF) || COMPILE_TEST
 	depends on SND_SOC
 	select SND_SOC_GENERIC_DMAENGINE_PCM
 	select REGMAP_MMIO
@@ -20,7 +20,7 @@
 
 config SND_SOC_STM32_SPDIFRX
 	tristate "STM32 S/PDIF receiver (SPDIFRX) support"
-	depends on ARCH_STM32 || COMPILE_TEST
+	depends on (ARCH_STM32 && OF) || COMPILE_TEST
 	depends on SND_SOC
 	select SND_SOC_GENERIC_DMAENGINE_PCM
 	select REGMAP_MMIO
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 3dd183b..7a15df9 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -37,9 +37,11 @@
 #define SUN8I_SYSCLK_CTL_SYSCLK_SRC			0
 #define SUN8I_MOD_CLK_ENA				0x010
 #define SUN8I_MOD_CLK_ENA_AIF1				15
+#define SUN8I_MOD_CLK_ENA_ADC				3
 #define SUN8I_MOD_CLK_ENA_DAC				2
 #define SUN8I_MOD_RST_CTL				0x014
 #define SUN8I_MOD_RST_CTL_AIF1				15
+#define SUN8I_MOD_RST_CTL_ADC				3
 #define SUN8I_MOD_RST_CTL_DAC				2
 #define SUN8I_SYS_SR_CTRL				0x018
 #define SUN8I_SYS_SR_CTRL_AIF1_FS			12
@@ -54,9 +56,25 @@
 #define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ		4
 #define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_16		(1 << 4)
 #define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT		2
+#define SUN8I_AIF1_ADCDAT_CTRL				0x044
+#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_DA0L_ENA		15
+#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_DA0R_ENA		14
 #define SUN8I_AIF1_DACDAT_CTRL				0x048
 #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA		15
 #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA		14
+#define SUN8I_AIF1_MXR_SRC				0x04c
+#define SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF1DA0L	15
+#define SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF2DACL	14
+#define SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_ADCL		13
+#define SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF2DACR	12
+#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R	11
+#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR	10
+#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR		9
+#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL	8
+#define SUN8I_ADC_DIG_CTRL				0x100
+#define SUN8I_ADC_DIG_CTRL_ENDA			15
+#define SUN8I_ADC_DIG_CTRL_ADOUT_DTS			2
+#define SUN8I_ADC_DIG_CTRL_ADOUT_DLY			1
 #define SUN8I_DAC_DIG_CTRL				0x120
 #define SUN8I_DAC_DIG_CTRL_ENDA			15
 #define SUN8I_DAC_MXR_SRC				0x130
@@ -338,10 +356,30 @@ static const struct snd_kcontrol_new sun8i_dac_mixer_controls[] = {
 			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
 };
 
+static const struct snd_kcontrol_new sun8i_input_mixer_controls[] = {
+	SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital ADC Capture Switch",
+			SUN8I_AIF1_MXR_SRC,
+			SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF1DA0L,
+			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R, 1, 0),
+	SOC_DAPM_DOUBLE("AIF2 Digital ADC Capture Switch", SUN8I_AIF1_MXR_SRC,
+			SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF2DACL,
+			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR, 1, 0),
+	SOC_DAPM_DOUBLE("AIF1 Data Digital ADC Capture Switch",
+			SUN8I_AIF1_MXR_SRC,
+			SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_ADCL,
+			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR, 1, 0),
+	SOC_DAPM_DOUBLE("AIF2 Inv Digital ADC Capture Switch",
+			SUN8I_AIF1_MXR_SRC,
+			SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF2DACR,
+			SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL, 1, 0),
+};
+
 static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
-	/* Digital parts of the DACs */
+	/* Digital parts of the DACs and ADC */
 	SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA,
 			    0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("ADC", SUN8I_ADC_DIG_CTRL, SUN8I_ADC_DIG_CTRL_ENDA,
+			    0, NULL, 0),
 
 	/* Analog DAC AIF */
 	SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Left", "Playback", 0,
@@ -351,17 +389,31 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
 			    SUN8I_AIF1_DACDAT_CTRL,
 			    SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
 
-	/* DAC Mixers */
+	/* Analog ADC AIF */
+	SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Left ADC", "Capture", 0,
+			    SUN8I_AIF1_ADCDAT_CTRL,
+			    SUN8I_AIF1_ADCDAT_CTRL_AIF1_DA0L_ENA, 0),
+	SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Right ADC", "Capture", 0,
+			    SUN8I_AIF1_ADCDAT_CTRL,
+			    SUN8I_AIF1_ADCDAT_CTRL_AIF1_DA0R_ENA, 0),
+
+	/* DAC and ADC Mixers */
 	SOC_MIXER_ARRAY("Left Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
 			sun8i_dac_mixer_controls),
 	SOC_MIXER_ARRAY("Right Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
 			sun8i_dac_mixer_controls),
+	SOC_MIXER_ARRAY("Left Digital ADC Mixer", SND_SOC_NOPM, 0, 0,
+			sun8i_input_mixer_controls),
+	SOC_MIXER_ARRAY("Right Digital ADC Mixer", SND_SOC_NOPM, 0, 0,
+			sun8i_input_mixer_controls),
 
 	/* Clocks */
 	SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
 			    SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
 	SND_SOC_DAPM_SUPPLY("MODCLK DAC", SUN8I_MOD_CLK_ENA,
 			    SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("MODCLK ADC", SUN8I_MOD_CLK_ENA,
+			    SUN8I_MOD_CLK_ENA_ADC, 0, NULL, 0),
 	SND_SOC_DAPM_SUPPLY("AIF1", SUN8I_SYSCLK_CTL,
 			    SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
 	SND_SOC_DAPM_SUPPLY("SYSCLK", SUN8I_SYSCLK_CTL,
@@ -378,6 +430,12 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
 			    SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
 	SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
 			    SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("RST ADC", SUN8I_MOD_RST_CTL,
+			    SUN8I_MOD_RST_CTL_ADC, 0, NULL, 0),
+
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
+	SND_SOC_DAPM_MIC("Mic", NULL),
+
 };
 
 static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
@@ -387,11 +445,16 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
 	{ "RST AIF1", NULL, "AIF1 PLL" },
 	{ "MODCLK AFI1", NULL, "RST AIF1" },
 	{ "DAC", NULL, "MODCLK AFI1" },
+	{ "ADC", NULL, "MODCLK AFI1" },
 
 	{ "RST DAC", NULL, "SYSCLK" },
 	{ "MODCLK DAC", NULL, "RST DAC" },
 	{ "DAC", NULL, "MODCLK DAC" },
 
+	{ "RST ADC", NULL, "SYSCLK" },
+	{ "MODCLK ADC", NULL, "RST ADC" },
+	{ "ADC", NULL, "MODCLK ADC" },
+
 	/* DAC Routes */
 	{ "AIF1 Slot 0 Right", NULL, "DAC" },
 	{ "AIF1 Slot 0 Left", NULL, "DAC" },
@@ -401,6 +464,12 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
 	  "AIF1 Slot 0 Left"},
 	{ "Right Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch",
 	  "AIF1 Slot 0 Right"},
+
+	/* ADC routes */
+	{ "Left Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch",
+	  "AIF1 Slot 0 Left ADC" },
+	{ "Right Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch",
+	  "AIF1 Slot 0 Right ADC" },
 };
 
 static const struct snd_soc_dai_ops sun8i_codec_dai_ops = {
@@ -418,6 +487,15 @@ static struct snd_soc_dai_driver sun8i_codec_dai = {
 		.rates = SNDRV_PCM_RATE_8000_192000,
 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 	},
+	/* capture capabilities */
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_192000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+		.sig_bits = 24,
+	},
 	/* pcm operations */
 	.ops = &sun8i_codec_dai_ops,
 };
diff --git a/tools/arch/powerpc/include/uapi/asm/kvm.h b/tools/arch/powerpc/include/uapi/asm/kvm.h
index 61d6049..637b726 100644
--- a/tools/arch/powerpc/include/uapi/asm/kvm.h
+++ b/tools/arch/powerpc/include/uapi/asm/kvm.h
@@ -443,6 +443,31 @@ struct kvm_ppc_rmmu_info {
 	__u32	ap_encodings[8];
 };
 
+/* For KVM_PPC_GET_CPU_CHAR */
+struct kvm_ppc_cpu_char {
+	__u64	character;		/* characteristics of the CPU */
+	__u64	behaviour;		/* recommended software behaviour */
+	__u64	character_mask;		/* valid bits in character */
+	__u64	behaviour_mask;		/* valid bits in behaviour */
+};
+
+/*
+ * Values for character and character_mask.
+ * These are identical to the values used by H_GET_CPU_CHARACTERISTICS.
+ */
+#define KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31		(1ULL << 63)
+#define KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED	(1ULL << 62)
+#define KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30	(1ULL << 61)
+#define KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2	(1ULL << 60)
+#define KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV	(1ULL << 59)
+#define KVM_PPC_CPU_CHAR_BR_HINT_HONOURED	(1ULL << 58)
+#define KVM_PPC_CPU_CHAR_MTTRIG_THR_RECONF	(1ULL << 57)
+#define KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS	(1ULL << 56)
+
+#define KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY	(1ULL << 63)
+#define KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR		(1ULL << 62)
+#define KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR	(1ULL << 61)
+
 /* Per-vcpu XICS interrupt controller state */
 #define KVM_REG_PPC_ICP_STATE	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)
 
diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h
index 38535a57..4cdaa55 100644
--- a/tools/arch/s390/include/uapi/asm/kvm.h
+++ b/tools/arch/s390/include/uapi/asm/kvm.h
@@ -224,6 +224,7 @@ struct kvm_guest_debug_arch {
 #define KVM_SYNC_RICCB  (1UL << 7)
 #define KVM_SYNC_FPRS   (1UL << 8)
 #define KVM_SYNC_GSCB   (1UL << 9)
+#define KVM_SYNC_BPBC   (1UL << 10)
 /* length and alignment of the sdnx as a power of two */
 #define SDNXC 8
 #define SDNXL (1UL << SDNXC)
@@ -247,7 +248,9 @@ struct kvm_sync_regs {
 	};
 	__u8  reserved[512];	/* for future vector expansion */
 	__u32 fpc;		/* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
-	__u8 padding1[52];	/* riccb needs to be 64byte aligned */
+	__u8 bpbc : 1;		/* bp mode */
+	__u8 reserved2 : 7;
+	__u8 padding1[51];	/* riccb needs to be 64byte aligned */
 	__u8 riccb[64];		/* runtime instrumentation controls block */
 	__u8 padding2[192];	/* sdnx needs to be 256byte aligned */
 	union {
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index 21ac898..1d9199e 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -13,7 +13,7 @@
 /*
  * Defines x86 CPU feature bits
  */
-#define NCAPINTS			18	   /* N 32-bit words worth of info */
+#define NCAPINTS			19	   /* N 32-bit words worth of info */
 #define NBUGINTS			1	   /* N 32-bit bug flags */
 
 /*
@@ -203,12 +203,15 @@
 #define X86_FEATURE_PROC_FEEDBACK	( 7*32+ 9) /* AMD ProcFeedbackInterface */
 #define X86_FEATURE_SME			( 7*32+10) /* AMD Secure Memory Encryption */
 #define X86_FEATURE_PTI			( 7*32+11) /* Kernel Page Table Isolation enabled */
+#define X86_FEATURE_RETPOLINE		( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
+#define X86_FEATURE_RETPOLINE_AMD	( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
 #define X86_FEATURE_INTEL_PPIN		( 7*32+14) /* Intel Processor Inventory Number */
-#define X86_FEATURE_INTEL_PT		( 7*32+15) /* Intel Processor Trace */
-#define X86_FEATURE_AVX512_4VNNIW	( 7*32+16) /* AVX-512 Neural Network Instructions */
-#define X86_FEATURE_AVX512_4FMAPS	( 7*32+17) /* AVX-512 Multiply Accumulation Single precision */
+#define X86_FEATURE_CDP_L2		( 7*32+15) /* Code and Data Prioritization L2 */
 
 #define X86_FEATURE_MBA			( 7*32+18) /* Memory Bandwidth Allocation */
+#define X86_FEATURE_RSB_CTXSW		( 7*32+19) /* "" Fill RSB on context switches */
+
+#define X86_FEATURE_USE_IBPB		( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
 
 /* Virtualization flags: Linux defined, word 8 */
 #define X86_FEATURE_TPR_SHADOW		( 8*32+ 0) /* Intel TPR Shadow */
@@ -243,6 +246,7 @@
 #define X86_FEATURE_AVX512IFMA		( 9*32+21) /* AVX-512 Integer Fused Multiply-Add instructions */
 #define X86_FEATURE_CLFLUSHOPT		( 9*32+23) /* CLFLUSHOPT instruction */
 #define X86_FEATURE_CLWB		( 9*32+24) /* CLWB instruction */
+#define X86_FEATURE_INTEL_PT		( 9*32+25) /* Intel Processor Trace */
 #define X86_FEATURE_AVX512PF		( 9*32+26) /* AVX-512 Prefetch */
 #define X86_FEATURE_AVX512ER		( 9*32+27) /* AVX-512 Exponential and Reciprocal */
 #define X86_FEATURE_AVX512CD		( 9*32+28) /* AVX-512 Conflict Detection */
@@ -268,6 +272,9 @@
 #define X86_FEATURE_CLZERO		(13*32+ 0) /* CLZERO instruction */
 #define X86_FEATURE_IRPERF		(13*32+ 1) /* Instructions Retired Count */
 #define X86_FEATURE_XSAVEERPTR		(13*32+ 2) /* Always save/restore FP error pointers */
+#define X86_FEATURE_IBPB		(13*32+12) /* Indirect Branch Prediction Barrier */
+#define X86_FEATURE_IBRS		(13*32+14) /* Indirect Branch Restricted Speculation */
+#define X86_FEATURE_STIBP		(13*32+15) /* Single Thread Indirect Branch Predictors */
 
 /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
 #define X86_FEATURE_DTHERM		(14*32+ 0) /* Digital Thermal Sensor */
@@ -316,6 +323,13 @@
 #define X86_FEATURE_SUCCOR		(17*32+ 1) /* Uncorrectable error containment and recovery */
 #define X86_FEATURE_SMCA		(17*32+ 3) /* Scalable MCA */
 
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
+#define X86_FEATURE_AVX512_4VNNIW	(18*32+ 2) /* AVX-512 Neural Network Instructions */
+#define X86_FEATURE_AVX512_4FMAPS	(18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
+#define X86_FEATURE_SPEC_CTRL		(18*32+26) /* "" Speculation Control (IBRS + IBPB) */
+#define X86_FEATURE_INTEL_STIBP		(18*32+27) /* "" Single Thread Indirect Branch Predictors */
+#define X86_FEATURE_ARCH_CAPABILITIES	(18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
+
 /*
  * BUG word(s)
  */
@@ -342,5 +356,7 @@
 #define X86_BUG_MONITOR			X86_BUG(12) /* IPI required to wake up remote CPU */
 #define X86_BUG_AMD_E400		X86_BUG(13) /* CPU is among the affected by Erratum 400 */
 #define X86_BUG_CPU_MELTDOWN		X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */
+#define X86_BUG_SPECTRE_V1		X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */
+#define X86_BUG_SPECTRE_V2		X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */
 
 #endif /* _ASM_X86_CPUFEATURES_H */
diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h
index b027633..33833d1 100644
--- a/tools/arch/x86/include/asm/disabled-features.h
+++ b/tools/arch/x86/include/asm/disabled-features.h
@@ -77,6 +77,7 @@
 #define DISABLED_MASK15	0
 #define DISABLED_MASK16	(DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP)
 #define DISABLED_MASK17	0
-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
+#define DISABLED_MASK18	0
+#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
 
 #endif /* _ASM_X86_DISABLED_FEATURES_H */
diff --git a/tools/arch/x86/include/asm/required-features.h b/tools/arch/x86/include/asm/required-features.h
index d91ba04..fb3a6de 100644
--- a/tools/arch/x86/include/asm/required-features.h
+++ b/tools/arch/x86/include/asm/required-features.h
@@ -106,6 +106,7 @@
 #define REQUIRED_MASK15	0
 #define REQUIRED_MASK16	(NEED_LA57)
 #define REQUIRED_MASK17	0
-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
+#define REQUIRED_MASK18	0
+#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
 
 #endif /* _ASM_X86_REQUIRED_FEATURES_H */
diff --git a/tools/include/asm-generic/bitops/find.h b/tools/include/asm-generic/bitops/find.h
index 9311fad..16ed198 100644
--- a/tools/include/asm-generic/bitops/find.h
+++ b/tools/include/asm-generic/bitops/find.h
@@ -16,6 +16,22 @@ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
 		size, unsigned long offset);
 #endif
 
+#ifndef find_next_and_bit
+/**
+ * find_next_and_bit - find the next set bit in both memory regions
+ * @addr1: The first address to base the search on
+ * @addr2: The second address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The bitmap size in bits
+ *
+ * Returns the bit number for the next set bit
+ * If no bits are set, returns @size.
+ */
+extern unsigned long find_next_and_bit(const unsigned long *addr1,
+		const unsigned long *addr2, unsigned long size,
+		unsigned long offset);
+#endif
+
 #ifndef find_next_zero_bit
 
 /**
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
new file mode 100644
index 0000000..8616131
--- /dev/null
+++ b/tools/include/uapi/linux/if_link.h
@@ -0,0 +1,943 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_LINUX_IF_LINK_H
+#define _UAPI_LINUX_IF_LINK_H
+
+#include <linux/types.h>
+#include <linux/netlink.h>
+
+/* This struct should be in sync with struct rtnl_link_stats64 */
+struct rtnl_link_stats {
+	__u32	rx_packets;		/* total packets received	*/
+	__u32	tx_packets;		/* total packets transmitted	*/
+	__u32	rx_bytes;		/* total bytes received 	*/
+	__u32	tx_bytes;		/* total bytes transmitted	*/
+	__u32	rx_errors;		/* bad packets received		*/
+	__u32	tx_errors;		/* packet transmit problems	*/
+	__u32	rx_dropped;		/* no space in linux buffers	*/
+	__u32	tx_dropped;		/* no space available in linux	*/
+	__u32	multicast;		/* multicast packets received	*/
+	__u32	collisions;
+
+	/* detailed rx_errors: */
+	__u32	rx_length_errors;
+	__u32	rx_over_errors;		/* receiver ring buff overflow	*/
+	__u32	rx_crc_errors;		/* recved pkt with crc error	*/
+	__u32	rx_frame_errors;	/* recv'd frame alignment error */
+	__u32	rx_fifo_errors;		/* recv'r fifo overrun		*/
+	__u32	rx_missed_errors;	/* receiver missed packet	*/
+
+	/* detailed tx_errors */
+	__u32	tx_aborted_errors;
+	__u32	tx_carrier_errors;
+	__u32	tx_fifo_errors;
+	__u32	tx_heartbeat_errors;
+	__u32	tx_window_errors;
+
+	/* for cslip etc */
+	__u32	rx_compressed;
+	__u32	tx_compressed;
+
+	__u32	rx_nohandler;		/* dropped, no handler found	*/
+};
+
+/* The main device statistics structure */
+struct rtnl_link_stats64 {
+	__u64	rx_packets;		/* total packets received	*/
+	__u64	tx_packets;		/* total packets transmitted	*/
+	__u64	rx_bytes;		/* total bytes received 	*/
+	__u64	tx_bytes;		/* total bytes transmitted	*/
+	__u64	rx_errors;		/* bad packets received		*/
+	__u64	tx_errors;		/* packet transmit problems	*/
+	__u64	rx_dropped;		/* no space in linux buffers	*/
+	__u64	tx_dropped;		/* no space available in linux	*/
+	__u64	multicast;		/* multicast packets received	*/
+	__u64	collisions;
+
+	/* detailed rx_errors: */
+	__u64	rx_length_errors;
+	__u64	rx_over_errors;		/* receiver ring buff overflow	*/
+	__u64	rx_crc_errors;		/* recved pkt with crc error	*/
+	__u64	rx_frame_errors;	/* recv'd frame alignment error */
+	__u64	rx_fifo_errors;		/* recv'r fifo overrun		*/
+	__u64	rx_missed_errors;	/* receiver missed packet	*/
+
+	/* detailed tx_errors */
+	__u64	tx_aborted_errors;
+	__u64	tx_carrier_errors;
+	__u64	tx_fifo_errors;
+	__u64	tx_heartbeat_errors;
+	__u64	tx_window_errors;
+
+	/* for cslip etc */
+	__u64	rx_compressed;
+	__u64	tx_compressed;
+
+	__u64	rx_nohandler;		/* dropped, no handler found	*/
+};
+
+/* The struct should be in sync with struct ifmap */
+struct rtnl_link_ifmap {
+	__u64	mem_start;
+	__u64	mem_end;
+	__u64	base_addr;
+	__u16	irq;
+	__u8	dma;
+	__u8	port;
+};
+
+/*
+ * IFLA_AF_SPEC
+ *   Contains nested attributes for address family specific attributes.
+ *   Each address family may create a attribute with the address family
+ *   number as type and create its own attribute structure in it.
+ *
+ *   Example:
+ *   [IFLA_AF_SPEC] = {
+ *       [AF_INET] = {
+ *           [IFLA_INET_CONF] = ...,
+ *       },
+ *       [AF_INET6] = {
+ *           [IFLA_INET6_FLAGS] = ...,
+ *           [IFLA_INET6_CONF] = ...,
+ *       }
+ *   }
+ */
+
+enum {
+	IFLA_UNSPEC,
+	IFLA_ADDRESS,
+	IFLA_BROADCAST,
+	IFLA_IFNAME,
+	IFLA_MTU,
+	IFLA_LINK,
+	IFLA_QDISC,
+	IFLA_STATS,
+	IFLA_COST,
+#define IFLA_COST IFLA_COST
+	IFLA_PRIORITY,
+#define IFLA_PRIORITY IFLA_PRIORITY
+	IFLA_MASTER,
+#define IFLA_MASTER IFLA_MASTER
+	IFLA_WIRELESS,		/* Wireless Extension event - see wireless.h */
+#define IFLA_WIRELESS IFLA_WIRELESS
+	IFLA_PROTINFO,		/* Protocol specific information for a link */
+#define IFLA_PROTINFO IFLA_PROTINFO
+	IFLA_TXQLEN,
+#define IFLA_TXQLEN IFLA_TXQLEN
+	IFLA_MAP,
+#define IFLA_MAP IFLA_MAP
+	IFLA_WEIGHT,
+#define IFLA_WEIGHT IFLA_WEIGHT
+	IFLA_OPERSTATE,
+	IFLA_LINKMODE,
+	IFLA_LINKINFO,
+#define IFLA_LINKINFO IFLA_LINKINFO
+	IFLA_NET_NS_PID,
+	IFLA_IFALIAS,
+	IFLA_NUM_VF,		/* Number of VFs if device is SR-IOV PF */
+	IFLA_VFINFO_LIST,
+	IFLA_STATS64,
+	IFLA_VF_PORTS,
+	IFLA_PORT_SELF,
+	IFLA_AF_SPEC,
+	IFLA_GROUP,		/* Group the device belongs to */
+	IFLA_NET_NS_FD,
+	IFLA_EXT_MASK,		/* Extended info mask, VFs, etc */
+	IFLA_PROMISCUITY,	/* Promiscuity count: > 0 means acts PROMISC */
+#define IFLA_PROMISCUITY IFLA_PROMISCUITY
+	IFLA_NUM_TX_QUEUES,
+	IFLA_NUM_RX_QUEUES,
+	IFLA_CARRIER,
+	IFLA_PHYS_PORT_ID,
+	IFLA_CARRIER_CHANGES,
+	IFLA_PHYS_SWITCH_ID,
+	IFLA_LINK_NETNSID,
+	IFLA_PHYS_PORT_NAME,
+	IFLA_PROTO_DOWN,
+	IFLA_GSO_MAX_SEGS,
+	IFLA_GSO_MAX_SIZE,
+	IFLA_PAD,
+	IFLA_XDP,
+	IFLA_EVENT,
+	IFLA_NEW_NETNSID,
+	IFLA_IF_NETNSID,
+	IFLA_CARRIER_UP_COUNT,
+	IFLA_CARRIER_DOWN_COUNT,
+	__IFLA_MAX
+};
+
+
+#define IFLA_MAX (__IFLA_MAX - 1)
+
+/* backwards compatibility for userspace */
+#ifndef __KERNEL__
+#define IFLA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
+#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+#endif
+
+enum {
+	IFLA_INET_UNSPEC,
+	IFLA_INET_CONF,
+	__IFLA_INET_MAX,
+};
+
+#define IFLA_INET_MAX (__IFLA_INET_MAX - 1)
+
+/* ifi_flags.
+
+   IFF_* flags.
+
+   The only change is:
+   IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
+   more not changeable by user. They describe link media
+   characteristics and set by device driver.
+
+   Comments:
+   - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
+   - If neither of these three flags are set;
+     the interface is NBMA.
+
+   - IFF_MULTICAST does not mean anything special:
+   multicasts can be used on all not-NBMA links.
+   IFF_MULTICAST means that this media uses special encapsulation
+   for multicast frames. Apparently, all IFF_POINTOPOINT and
+   IFF_BROADCAST devices are able to use multicasts too.
+ */
+
+/* IFLA_LINK.
+   For usual devices it is equal ifi_index.
+   If it is a "virtual interface" (f.e. tunnel), ifi_link
+   can point to real physical interface (f.e. for bandwidth calculations),
+   or maybe 0, what means, that real media is unknown (usual
+   for IPIP tunnels, when route to endpoint is allowed to change)
+ */
+
+/* Subtype attributes for IFLA_PROTINFO */
+enum {
+	IFLA_INET6_UNSPEC,
+	IFLA_INET6_FLAGS,	/* link flags			*/
+	IFLA_INET6_CONF,	/* sysctl parameters		*/
+	IFLA_INET6_STATS,	/* statistics			*/
+	IFLA_INET6_MCAST,	/* MC things. What of them?	*/
+	IFLA_INET6_CACHEINFO,	/* time values and max reasm size */
+	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
+	IFLA_INET6_TOKEN,	/* device token			*/
+	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+	__IFLA_INET6_MAX
+};
+
+#define IFLA_INET6_MAX	(__IFLA_INET6_MAX - 1)
+
+enum in6_addr_gen_mode {
+	IN6_ADDR_GEN_MODE_EUI64,
+	IN6_ADDR_GEN_MODE_NONE,
+	IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
+	IN6_ADDR_GEN_MODE_RANDOM,
+};
+
+/* Bridge section */
+
+enum {
+	IFLA_BR_UNSPEC,
+	IFLA_BR_FORWARD_DELAY,
+	IFLA_BR_HELLO_TIME,
+	IFLA_BR_MAX_AGE,
+	IFLA_BR_AGEING_TIME,
+	IFLA_BR_STP_STATE,
+	IFLA_BR_PRIORITY,
+	IFLA_BR_VLAN_FILTERING,
+	IFLA_BR_VLAN_PROTOCOL,
+	IFLA_BR_GROUP_FWD_MASK,
+	IFLA_BR_ROOT_ID,
+	IFLA_BR_BRIDGE_ID,
+	IFLA_BR_ROOT_PORT,
+	IFLA_BR_ROOT_PATH_COST,
+	IFLA_BR_TOPOLOGY_CHANGE,
+	IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
+	IFLA_BR_HELLO_TIMER,
+	IFLA_BR_TCN_TIMER,
+	IFLA_BR_TOPOLOGY_CHANGE_TIMER,
+	IFLA_BR_GC_TIMER,
+	IFLA_BR_GROUP_ADDR,
+	IFLA_BR_FDB_FLUSH,
+	IFLA_BR_MCAST_ROUTER,
+	IFLA_BR_MCAST_SNOOPING,
+	IFLA_BR_MCAST_QUERY_USE_IFADDR,
+	IFLA_BR_MCAST_QUERIER,
+	IFLA_BR_MCAST_HASH_ELASTICITY,
+	IFLA_BR_MCAST_HASH_MAX,
+	IFLA_BR_MCAST_LAST_MEMBER_CNT,
+	IFLA_BR_MCAST_STARTUP_QUERY_CNT,
+	IFLA_BR_MCAST_LAST_MEMBER_INTVL,
+	IFLA_BR_MCAST_MEMBERSHIP_INTVL,
+	IFLA_BR_MCAST_QUERIER_INTVL,
+	IFLA_BR_MCAST_QUERY_INTVL,
+	IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
+	IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
+	IFLA_BR_NF_CALL_IPTABLES,
+	IFLA_BR_NF_CALL_IP6TABLES,
+	IFLA_BR_NF_CALL_ARPTABLES,
+	IFLA_BR_VLAN_DEFAULT_PVID,
+	IFLA_BR_PAD,
+	IFLA_BR_VLAN_STATS_ENABLED,
+	IFLA_BR_MCAST_STATS_ENABLED,
+	IFLA_BR_MCAST_IGMP_VERSION,
+	IFLA_BR_MCAST_MLD_VERSION,
+	__IFLA_BR_MAX,
+};
+
+#define IFLA_BR_MAX	(__IFLA_BR_MAX - 1)
+
+struct ifla_bridge_id {
+	__u8	prio[2];
+	__u8	addr[6]; /* ETH_ALEN */
+};
+
+enum {
+	BRIDGE_MODE_UNSPEC,
+	BRIDGE_MODE_HAIRPIN,
+};
+
+enum {
+	IFLA_BRPORT_UNSPEC,
+	IFLA_BRPORT_STATE,	/* Spanning tree state     */
+	IFLA_BRPORT_PRIORITY,	/* "             priority  */
+	IFLA_BRPORT_COST,	/* "             cost      */
+	IFLA_BRPORT_MODE,	/* mode (hairpin)          */
+	IFLA_BRPORT_GUARD,	/* bpdu guard              */
+	IFLA_BRPORT_PROTECT,	/* root port protection    */
+	IFLA_BRPORT_FAST_LEAVE,	/* multicast fast leave    */
+	IFLA_BRPORT_LEARNING,	/* mac learning */
+	IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */
+	IFLA_BRPORT_PROXYARP,	/* proxy ARP */
+	IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */
+	IFLA_BRPORT_PROXYARP_WIFI, /* proxy ARP for Wi-Fi */
+	IFLA_BRPORT_ROOT_ID,	/* designated root */
+	IFLA_BRPORT_BRIDGE_ID,	/* designated bridge */
+	IFLA_BRPORT_DESIGNATED_PORT,
+	IFLA_BRPORT_DESIGNATED_COST,
+	IFLA_BRPORT_ID,
+	IFLA_BRPORT_NO,
+	IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
+	IFLA_BRPORT_CONFIG_PENDING,
+	IFLA_BRPORT_MESSAGE_AGE_TIMER,
+	IFLA_BRPORT_FORWARD_DELAY_TIMER,
+	IFLA_BRPORT_HOLD_TIMER,
+	IFLA_BRPORT_FLUSH,
+	IFLA_BRPORT_MULTICAST_ROUTER,
+	IFLA_BRPORT_PAD,
+	IFLA_BRPORT_MCAST_FLOOD,
+	IFLA_BRPORT_MCAST_TO_UCAST,
+	IFLA_BRPORT_VLAN_TUNNEL,
+	IFLA_BRPORT_BCAST_FLOOD,
+	IFLA_BRPORT_GROUP_FWD_MASK,
+	IFLA_BRPORT_NEIGH_SUPPRESS,
+	__IFLA_BRPORT_MAX
+};
+#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
+
+struct ifla_cacheinfo {
+	__u32	max_reasm_len;
+	__u32	tstamp;		/* ipv6InterfaceTable updated timestamp */
+	__u32	reachable_time;
+	__u32	retrans_time;
+};
+
+enum {
+	IFLA_INFO_UNSPEC,
+	IFLA_INFO_KIND,
+	IFLA_INFO_DATA,
+	IFLA_INFO_XSTATS,
+	IFLA_INFO_SLAVE_KIND,
+	IFLA_INFO_SLAVE_DATA,
+	__IFLA_INFO_MAX,
+};
+
+#define IFLA_INFO_MAX	(__IFLA_INFO_MAX - 1)
+
+/* VLAN section */
+
+enum {
+	IFLA_VLAN_UNSPEC,
+	IFLA_VLAN_ID,
+	IFLA_VLAN_FLAGS,
+	IFLA_VLAN_EGRESS_QOS,
+	IFLA_VLAN_INGRESS_QOS,
+	IFLA_VLAN_PROTOCOL,
+	__IFLA_VLAN_MAX,
+};
+
+#define IFLA_VLAN_MAX	(__IFLA_VLAN_MAX - 1)
+
+struct ifla_vlan_flags {
+	__u32	flags;
+	__u32	mask;
+};
+
+enum {
+	IFLA_VLAN_QOS_UNSPEC,
+	IFLA_VLAN_QOS_MAPPING,
+	__IFLA_VLAN_QOS_MAX
+};
+
+#define IFLA_VLAN_QOS_MAX	(__IFLA_VLAN_QOS_MAX - 1)
+
+struct ifla_vlan_qos_mapping {
+	__u32 from;
+	__u32 to;
+};
+
+/* MACVLAN section */
+enum {
+	IFLA_MACVLAN_UNSPEC,
+	IFLA_MACVLAN_MODE,
+	IFLA_MACVLAN_FLAGS,
+	IFLA_MACVLAN_MACADDR_MODE,
+	IFLA_MACVLAN_MACADDR,
+	IFLA_MACVLAN_MACADDR_DATA,
+	IFLA_MACVLAN_MACADDR_COUNT,
+	__IFLA_MACVLAN_MAX,
+};
+
+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
+
+enum macvlan_mode {
+	MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
+	MACVLAN_MODE_VEPA    = 2, /* talk to other ports through ext bridge */
+	MACVLAN_MODE_BRIDGE  = 4, /* talk to bridge ports directly */
+	MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
+	MACVLAN_MODE_SOURCE  = 16,/* use source MAC address list to assign */
+};
+
+enum macvlan_macaddr_mode {
+	MACVLAN_MACADDR_ADD,
+	MACVLAN_MACADDR_DEL,
+	MACVLAN_MACADDR_FLUSH,
+	MACVLAN_MACADDR_SET,
+};
+
+#define MACVLAN_FLAG_NOPROMISC	1
+
+/* VRF section */
+enum {
+	IFLA_VRF_UNSPEC,
+	IFLA_VRF_TABLE,
+	__IFLA_VRF_MAX
+};
+
+#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1)
+
+enum {
+	IFLA_VRF_PORT_UNSPEC,
+	IFLA_VRF_PORT_TABLE,
+	__IFLA_VRF_PORT_MAX
+};
+
+#define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1)
+
+/* MACSEC section */
+enum {
+	IFLA_MACSEC_UNSPEC,
+	IFLA_MACSEC_SCI,
+	IFLA_MACSEC_PORT,
+	IFLA_MACSEC_ICV_LEN,
+	IFLA_MACSEC_CIPHER_SUITE,
+	IFLA_MACSEC_WINDOW,
+	IFLA_MACSEC_ENCODING_SA,
+	IFLA_MACSEC_ENCRYPT,
+	IFLA_MACSEC_PROTECT,
+	IFLA_MACSEC_INC_SCI,
+	IFLA_MACSEC_ES,
+	IFLA_MACSEC_SCB,
+	IFLA_MACSEC_REPLAY_PROTECT,
+	IFLA_MACSEC_VALIDATION,
+	IFLA_MACSEC_PAD,
+	__IFLA_MACSEC_MAX,
+};
+
+#define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1)
+
+enum macsec_validation_type {
+	MACSEC_VALIDATE_DISABLED = 0,
+	MACSEC_VALIDATE_CHECK = 1,
+	MACSEC_VALIDATE_STRICT = 2,
+	__MACSEC_VALIDATE_END,
+	MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1,
+};
+
+/* IPVLAN section */
+enum {
+	IFLA_IPVLAN_UNSPEC,
+	IFLA_IPVLAN_MODE,
+	IFLA_IPVLAN_FLAGS,
+	__IFLA_IPVLAN_MAX
+};
+
+#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1)
+
+enum ipvlan_mode {
+	IPVLAN_MODE_L2 = 0,
+	IPVLAN_MODE_L3,
+	IPVLAN_MODE_L3S,
+	IPVLAN_MODE_MAX
+};
+
+#define IPVLAN_F_PRIVATE	0x01
+#define IPVLAN_F_VEPA		0x02
+
+/* VXLAN section */
+enum {
+	IFLA_VXLAN_UNSPEC,
+	IFLA_VXLAN_ID,
+	IFLA_VXLAN_GROUP,	/* group or remote address */
+	IFLA_VXLAN_LINK,
+	IFLA_VXLAN_LOCAL,
+	IFLA_VXLAN_TTL,
+	IFLA_VXLAN_TOS,
+	IFLA_VXLAN_LEARNING,
+	IFLA_VXLAN_AGEING,
+	IFLA_VXLAN_LIMIT,
+	IFLA_VXLAN_PORT_RANGE,	/* source port */
+	IFLA_VXLAN_PROXY,
+	IFLA_VXLAN_RSC,
+	IFLA_VXLAN_L2MISS,
+	IFLA_VXLAN_L3MISS,
+	IFLA_VXLAN_PORT,	/* destination port */
+	IFLA_VXLAN_GROUP6,
+	IFLA_VXLAN_LOCAL6,
+	IFLA_VXLAN_UDP_CSUM,
+	IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
+	IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
+	IFLA_VXLAN_REMCSUM_TX,
+	IFLA_VXLAN_REMCSUM_RX,
+	IFLA_VXLAN_GBP,
+	IFLA_VXLAN_REMCSUM_NOPARTIAL,
+	IFLA_VXLAN_COLLECT_METADATA,
+	IFLA_VXLAN_LABEL,
+	IFLA_VXLAN_GPE,
+	__IFLA_VXLAN_MAX
+};
+#define IFLA_VXLAN_MAX	(__IFLA_VXLAN_MAX - 1)
+
+struct ifla_vxlan_port_range {
+	__be16	low;
+	__be16	high;
+};
+
+/* GENEVE section */
+enum {
+	IFLA_GENEVE_UNSPEC,
+	IFLA_GENEVE_ID,
+	IFLA_GENEVE_REMOTE,
+	IFLA_GENEVE_TTL,
+	IFLA_GENEVE_TOS,
+	IFLA_GENEVE_PORT,	/* destination port */
+	IFLA_GENEVE_COLLECT_METADATA,
+	IFLA_GENEVE_REMOTE6,
+	IFLA_GENEVE_UDP_CSUM,
+	IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
+	IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
+	IFLA_GENEVE_LABEL,
+	__IFLA_GENEVE_MAX
+};
+#define IFLA_GENEVE_MAX	(__IFLA_GENEVE_MAX - 1)
+
+/* PPP section */
+enum {
+	IFLA_PPP_UNSPEC,
+	IFLA_PPP_DEV_FD,
+	__IFLA_PPP_MAX
+};
+#define IFLA_PPP_MAX (__IFLA_PPP_MAX - 1)
+
+/* GTP section */
+
+enum ifla_gtp_role {
+	GTP_ROLE_GGSN = 0,
+	GTP_ROLE_SGSN,
+};
+
+enum {
+	IFLA_GTP_UNSPEC,
+	IFLA_GTP_FD0,
+	IFLA_GTP_FD1,
+	IFLA_GTP_PDP_HASHSIZE,
+	IFLA_GTP_ROLE,
+	__IFLA_GTP_MAX,
+};
+#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
+
+/* Bonding section */
+
+enum {
+	IFLA_BOND_UNSPEC,
+	IFLA_BOND_MODE,
+	IFLA_BOND_ACTIVE_SLAVE,
+	IFLA_BOND_MIIMON,
+	IFLA_BOND_UPDELAY,
+	IFLA_BOND_DOWNDELAY,
+	IFLA_BOND_USE_CARRIER,
+	IFLA_BOND_ARP_INTERVAL,
+	IFLA_BOND_ARP_IP_TARGET,
+	IFLA_BOND_ARP_VALIDATE,
+	IFLA_BOND_ARP_ALL_TARGETS,
+	IFLA_BOND_PRIMARY,
+	IFLA_BOND_PRIMARY_RESELECT,
+	IFLA_BOND_FAIL_OVER_MAC,
+	IFLA_BOND_XMIT_HASH_POLICY,
+	IFLA_BOND_RESEND_IGMP,
+	IFLA_BOND_NUM_PEER_NOTIF,
+	IFLA_BOND_ALL_SLAVES_ACTIVE,
+	IFLA_BOND_MIN_LINKS,
+	IFLA_BOND_LP_INTERVAL,
+	IFLA_BOND_PACKETS_PER_SLAVE,
+	IFLA_BOND_AD_LACP_RATE,
+	IFLA_BOND_AD_SELECT,
+	IFLA_BOND_AD_INFO,
+	IFLA_BOND_AD_ACTOR_SYS_PRIO,
+	IFLA_BOND_AD_USER_PORT_KEY,
+	IFLA_BOND_AD_ACTOR_SYSTEM,
+	IFLA_BOND_TLB_DYNAMIC_LB,
+	__IFLA_BOND_MAX,
+};
+
+#define IFLA_BOND_MAX	(__IFLA_BOND_MAX - 1)
+
+enum {
+	IFLA_BOND_AD_INFO_UNSPEC,
+	IFLA_BOND_AD_INFO_AGGREGATOR,
+	IFLA_BOND_AD_INFO_NUM_PORTS,
+	IFLA_BOND_AD_INFO_ACTOR_KEY,
+	IFLA_BOND_AD_INFO_PARTNER_KEY,
+	IFLA_BOND_AD_INFO_PARTNER_MAC,
+	__IFLA_BOND_AD_INFO_MAX,
+};
+
+#define IFLA_BOND_AD_INFO_MAX	(__IFLA_BOND_AD_INFO_MAX - 1)
+
+enum {
+	IFLA_BOND_SLAVE_UNSPEC,
+	IFLA_BOND_SLAVE_STATE,
+	IFLA_BOND_SLAVE_MII_STATUS,
+	IFLA_BOND_SLAVE_LINK_FAILURE_COUNT,
+	IFLA_BOND_SLAVE_PERM_HWADDR,
+	IFLA_BOND_SLAVE_QUEUE_ID,
+	IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
+	IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
+	IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
+	__IFLA_BOND_SLAVE_MAX,
+};
+
+#define IFLA_BOND_SLAVE_MAX	(__IFLA_BOND_SLAVE_MAX - 1)
+
+/* SR-IOV virtual function management section */
+
+enum {
+	IFLA_VF_INFO_UNSPEC,
+	IFLA_VF_INFO,
+	__IFLA_VF_INFO_MAX,
+};
+
+#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
+
+enum {
+	IFLA_VF_UNSPEC,
+	IFLA_VF_MAC,		/* Hardware queue specific attributes */
+	IFLA_VF_VLAN,		/* VLAN ID and QoS */
+	IFLA_VF_TX_RATE,	/* Max TX Bandwidth Allocation */
+	IFLA_VF_SPOOFCHK,	/* Spoof Checking on/off switch */
+	IFLA_VF_LINK_STATE,	/* link state enable/disable/auto switch */
+	IFLA_VF_RATE,		/* Min and Max TX Bandwidth Allocation */
+	IFLA_VF_RSS_QUERY_EN,	/* RSS Redirection Table and Hash Key query
+				 * on/off switch
+				 */
+	IFLA_VF_STATS,		/* network device statistics */
+	IFLA_VF_TRUST,		/* Trust VF */
+	IFLA_VF_IB_NODE_GUID,	/* VF Infiniband node GUID */
+	IFLA_VF_IB_PORT_GUID,	/* VF Infiniband port GUID */
+	IFLA_VF_VLAN_LIST,	/* nested list of vlans, option for QinQ */
+	__IFLA_VF_MAX,
+};
+
+#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
+
+struct ifla_vf_mac {
+	__u32 vf;
+	__u8 mac[32]; /* MAX_ADDR_LEN */
+};
+
+struct ifla_vf_vlan {
+	__u32 vf;
+	__u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
+	__u32 qos;
+};
+
+enum {
+	IFLA_VF_VLAN_INFO_UNSPEC,
+	IFLA_VF_VLAN_INFO,	/* VLAN ID, QoS and VLAN protocol */
+	__IFLA_VF_VLAN_INFO_MAX,
+};
+
+#define IFLA_VF_VLAN_INFO_MAX (__IFLA_VF_VLAN_INFO_MAX - 1)
+#define MAX_VLAN_LIST_LEN 1
+
+struct ifla_vf_vlan_info {
+	__u32 vf;
+	__u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
+	__u32 qos;
+	__be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */
+};
+
+struct ifla_vf_tx_rate {
+	__u32 vf;
+	__u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
+};
+
+struct ifla_vf_rate {
+	__u32 vf;
+	__u32 min_tx_rate; /* Min Bandwidth in Mbps */
+	__u32 max_tx_rate; /* Max Bandwidth in Mbps */
+};
+
+struct ifla_vf_spoofchk {
+	__u32 vf;
+	__u32 setting;
+};
+
+struct ifla_vf_guid {
+	__u32 vf;
+	__u64 guid;
+};
+
+enum {
+	IFLA_VF_LINK_STATE_AUTO,	/* link state of the uplink */
+	IFLA_VF_LINK_STATE_ENABLE,	/* link always up */
+	IFLA_VF_LINK_STATE_DISABLE,	/* link always down */
+	__IFLA_VF_LINK_STATE_MAX,
+};
+
+struct ifla_vf_link_state {
+	__u32 vf;
+	__u32 link_state;
+};
+
+struct ifla_vf_rss_query_en {
+	__u32 vf;
+	__u32 setting;
+};
+
+enum {
+	IFLA_VF_STATS_RX_PACKETS,
+	IFLA_VF_STATS_TX_PACKETS,
+	IFLA_VF_STATS_RX_BYTES,
+	IFLA_VF_STATS_TX_BYTES,
+	IFLA_VF_STATS_BROADCAST,
+	IFLA_VF_STATS_MULTICAST,
+	IFLA_VF_STATS_PAD,
+	IFLA_VF_STATS_RX_DROPPED,
+	IFLA_VF_STATS_TX_DROPPED,
+	__IFLA_VF_STATS_MAX,
+};
+
+#define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1)
+
+struct ifla_vf_trust {
+	__u32 vf;
+	__u32 setting;
+};
+
+/* VF ports management section
+ *
+ *	Nested layout of set/get msg is:
+ *
+ *		[IFLA_NUM_VF]
+ *		[IFLA_VF_PORTS]
+ *			[IFLA_VF_PORT]
+ *				[IFLA_PORT_*], ...
+ *			[IFLA_VF_PORT]
+ *				[IFLA_PORT_*], ...
+ *			...
+ *		[IFLA_PORT_SELF]
+ *			[IFLA_PORT_*], ...
+ */
+
+enum {
+	IFLA_VF_PORT_UNSPEC,
+	IFLA_VF_PORT,			/* nest */
+	__IFLA_VF_PORT_MAX,
+};
+
+#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1)
+
+enum {
+	IFLA_PORT_UNSPEC,
+	IFLA_PORT_VF,			/* __u32 */
+	IFLA_PORT_PROFILE,		/* string */
+	IFLA_PORT_VSI_TYPE,		/* 802.1Qbg (pre-)standard VDP */
+	IFLA_PORT_INSTANCE_UUID,	/* binary UUID */
+	IFLA_PORT_HOST_UUID,		/* binary UUID */
+	IFLA_PORT_REQUEST,		/* __u8 */
+	IFLA_PORT_RESPONSE,		/* __u16, output only */
+	__IFLA_PORT_MAX,
+};
+
+#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1)
+
+#define PORT_PROFILE_MAX	40
+#define PORT_UUID_MAX		16
+#define PORT_SELF_VF		-1
+
+enum {
+	PORT_REQUEST_PREASSOCIATE = 0,
+	PORT_REQUEST_PREASSOCIATE_RR,
+	PORT_REQUEST_ASSOCIATE,
+	PORT_REQUEST_DISASSOCIATE,
+};
+
+enum {
+	PORT_VDP_RESPONSE_SUCCESS = 0,
+	PORT_VDP_RESPONSE_INVALID_FORMAT,
+	PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES,
+	PORT_VDP_RESPONSE_UNUSED_VTID,
+	PORT_VDP_RESPONSE_VTID_VIOLATION,
+	PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION,
+	PORT_VDP_RESPONSE_OUT_OF_SYNC,
+	/* 0x08-0xFF reserved for future VDP use */
+	PORT_PROFILE_RESPONSE_SUCCESS = 0x100,
+	PORT_PROFILE_RESPONSE_INPROGRESS,
+	PORT_PROFILE_RESPONSE_INVALID,
+	PORT_PROFILE_RESPONSE_BADSTATE,
+	PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES,
+	PORT_PROFILE_RESPONSE_ERROR,
+};
+
+struct ifla_port_vsi {
+	__u8 vsi_mgr_id;
+	__u8 vsi_type_id[3];
+	__u8 vsi_type_version;
+	__u8 pad[3];
+};
+
+
+/* IPoIB section */
+
+enum {
+	IFLA_IPOIB_UNSPEC,
+	IFLA_IPOIB_PKEY,
+	IFLA_IPOIB_MODE,
+	IFLA_IPOIB_UMCAST,
+	__IFLA_IPOIB_MAX
+};
+
+enum {
+	IPOIB_MODE_DATAGRAM  = 0, /* using unreliable datagram QPs */
+	IPOIB_MODE_CONNECTED = 1, /* using connected QPs */
+};
+
+#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
+
+
+/* HSR section */
+
+enum {
+	IFLA_HSR_UNSPEC,
+	IFLA_HSR_SLAVE1,
+	IFLA_HSR_SLAVE2,
+	IFLA_HSR_MULTICAST_SPEC,	/* Last byte of supervision addr */
+	IFLA_HSR_SUPERVISION_ADDR,	/* Supervision frame multicast addr */
+	IFLA_HSR_SEQ_NR,
+	IFLA_HSR_VERSION,		/* HSR version */
+	__IFLA_HSR_MAX,
+};
+
+#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
+
+/* STATS section */
+
+struct if_stats_msg {
+	__u8  family;
+	__u8  pad1;
+	__u16 pad2;
+	__u32 ifindex;
+	__u32 filter_mask;
+};
+
+/* A stats attribute can be netdev specific or a global stat.
+ * For netdev stats, lets use the prefix IFLA_STATS_LINK_*
+ */
+enum {
+	IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */
+	IFLA_STATS_LINK_64,
+	IFLA_STATS_LINK_XSTATS,
+	IFLA_STATS_LINK_XSTATS_SLAVE,
+	IFLA_STATS_LINK_OFFLOAD_XSTATS,
+	IFLA_STATS_AF_SPEC,
+	__IFLA_STATS_MAX,
+};
+
+#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1)
+
+#define IFLA_STATS_FILTER_BIT(ATTR)	(1 << (ATTR - 1))
+
+/* These are embedded into IFLA_STATS_LINK_XSTATS:
+ * [IFLA_STATS_LINK_XSTATS]
+ * -> [LINK_XSTATS_TYPE_xxx]
+ *    -> [rtnl link type specific attributes]
+ */
+enum {
+	LINK_XSTATS_TYPE_UNSPEC,
+	LINK_XSTATS_TYPE_BRIDGE,
+	__LINK_XSTATS_TYPE_MAX
+};
+#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)
+
+/* These are stats embedded into IFLA_STATS_LINK_OFFLOAD_XSTATS */
+enum {
+	IFLA_OFFLOAD_XSTATS_UNSPEC,
+	IFLA_OFFLOAD_XSTATS_CPU_HIT, /* struct rtnl_link_stats64 */
+	__IFLA_OFFLOAD_XSTATS_MAX
+};
+#define IFLA_OFFLOAD_XSTATS_MAX (__IFLA_OFFLOAD_XSTATS_MAX - 1)
+
+/* XDP section */
+
+#define XDP_FLAGS_UPDATE_IF_NOEXIST	(1U << 0)
+#define XDP_FLAGS_SKB_MODE		(1U << 1)
+#define XDP_FLAGS_DRV_MODE		(1U << 2)
+#define XDP_FLAGS_HW_MODE		(1U << 3)
+#define XDP_FLAGS_MODES			(XDP_FLAGS_SKB_MODE | \
+					 XDP_FLAGS_DRV_MODE | \
+					 XDP_FLAGS_HW_MODE)
+#define XDP_FLAGS_MASK			(XDP_FLAGS_UPDATE_IF_NOEXIST | \
+					 XDP_FLAGS_MODES)
+
+/* These are stored into IFLA_XDP_ATTACHED on dump. */
+enum {
+	XDP_ATTACHED_NONE = 0,
+	XDP_ATTACHED_DRV,
+	XDP_ATTACHED_SKB,
+	XDP_ATTACHED_HW,
+};
+
+enum {
+	IFLA_XDP_UNSPEC,
+	IFLA_XDP_FD,
+	IFLA_XDP_ATTACHED,
+	IFLA_XDP_FLAGS,
+	IFLA_XDP_PROG_ID,
+	__IFLA_XDP_MAX,
+};
+
+#define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1)
+
+enum {
+	IFLA_EVENT_NONE,
+	IFLA_EVENT_REBOOT,		/* internal reset / reboot */
+	IFLA_EVENT_FEATURES,		/* change in offload features */
+	IFLA_EVENT_BONDING_FAILOVER,	/* change in active slave */
+	IFLA_EVENT_NOTIFY_PEERS,	/* re-sent grat. arp/ndisc */
+	IFLA_EVENT_IGMP_RESEND,		/* re-sent IGMP JOIN */
+	IFLA_EVENT_BONDING_OPTIONS,	/* change in bonding options */
+};
+
+#endif /* _UAPI_LINUX_IF_LINK_H */
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h
index 496e59a..8fb90a0 100644
--- a/tools/include/uapi/linux/kvm.h
+++ b/tools/include/uapi/linux/kvm.h
@@ -932,6 +932,8 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_HYPERV_SYNIC2 148
 #define KVM_CAP_HYPERV_VP_INDEX 149
 #define KVM_CAP_S390_AIS_MIGRATION 150
+#define KVM_CAP_PPC_GET_CPU_CHAR 151
+#define KVM_CAP_S390_BPB 152
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1261,6 +1263,8 @@ struct kvm_s390_ucas_mapping {
 #define KVM_PPC_CONFIGURE_V3_MMU  _IOW(KVMIO,  0xaf, struct kvm_ppc_mmuv3_cfg)
 /* Available with KVM_CAP_PPC_RADIX_MMU */
 #define KVM_PPC_GET_RMMU_INFO	  _IOW(KVMIO,  0xb0, struct kvm_ppc_rmmu_info)
+/* Available with KVM_CAP_PPC_GET_CPU_CHAR */
+#define KVM_PPC_GET_CPU_CHAR	  _IOR(KVMIO,  0xb1, struct kvm_ppc_cpu_char)
 
 /* ioctl for vm fd */
 #define KVM_CREATE_DEVICE	  _IOWR(KVMIO,  0xe0, struct kvm_create_device)
diff --git a/tools/include/uapi/linux/netlink.h b/tools/include/uapi/linux/netlink.h
new file mode 100644
index 0000000..776bc92
--- /dev/null
+++ b/tools/include/uapi/linux/netlink.h
@@ -0,0 +1,251 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI__LINUX_NETLINK_H
+#define _UAPI__LINUX_NETLINK_H
+
+#include <linux/kernel.h>
+#include <linux/socket.h> /* for __kernel_sa_family_t */
+#include <linux/types.h>
+
+#define NETLINK_ROUTE		0	/* Routing/device hook				*/
+#define NETLINK_UNUSED		1	/* Unused number				*/
+#define NETLINK_USERSOCK	2	/* Reserved for user mode socket protocols 	*/
+#define NETLINK_FIREWALL	3	/* Unused number, formerly ip_queue		*/
+#define NETLINK_SOCK_DIAG	4	/* socket monitoring				*/
+#define NETLINK_NFLOG		5	/* netfilter/iptables ULOG */
+#define NETLINK_XFRM		6	/* ipsec */
+#define NETLINK_SELINUX		7	/* SELinux event notifications */
+#define NETLINK_ISCSI		8	/* Open-iSCSI */
+#define NETLINK_AUDIT		9	/* auditing */
+#define NETLINK_FIB_LOOKUP	10	
+#define NETLINK_CONNECTOR	11
+#define NETLINK_NETFILTER	12	/* netfilter subsystem */
+#define NETLINK_IP6_FW		13
+#define NETLINK_DNRTMSG		14	/* DECnet routing messages */
+#define NETLINK_KOBJECT_UEVENT	15	/* Kernel messages to userspace */
+#define NETLINK_GENERIC		16
+/* leave room for NETLINK_DM (DM Events) */
+#define NETLINK_SCSITRANSPORT	18	/* SCSI Transports */
+#define NETLINK_ECRYPTFS	19
+#define NETLINK_RDMA		20
+#define NETLINK_CRYPTO		21	/* Crypto layer */
+#define NETLINK_SMC		22	/* SMC monitoring */
+
+#define NETLINK_INET_DIAG	NETLINK_SOCK_DIAG
+
+#define MAX_LINKS 32		
+
+struct sockaddr_nl {
+	__kernel_sa_family_t	nl_family;	/* AF_NETLINK	*/
+	unsigned short	nl_pad;		/* zero		*/
+	__u32		nl_pid;		/* port ID	*/
+       	__u32		nl_groups;	/* multicast groups mask */
+};
+
+struct nlmsghdr {
+	__u32		nlmsg_len;	/* Length of message including header */
+	__u16		nlmsg_type;	/* Message content */
+	__u16		nlmsg_flags;	/* Additional flags */
+	__u32		nlmsg_seq;	/* Sequence number */
+	__u32		nlmsg_pid;	/* Sending process port ID */
+};
+
+/* Flags values */
+
+#define NLM_F_REQUEST		0x01	/* It is request message. 	*/
+#define NLM_F_MULTI		0x02	/* Multipart message, terminated by NLMSG_DONE */
+#define NLM_F_ACK		0x04	/* Reply with ack, with zero or error code */
+#define NLM_F_ECHO		0x08	/* Echo this request 		*/
+#define NLM_F_DUMP_INTR		0x10	/* Dump was inconsistent due to sequence change */
+#define NLM_F_DUMP_FILTERED	0x20	/* Dump was filtered as requested */
+
+/* Modifiers to GET request */
+#define NLM_F_ROOT	0x100	/* specify tree	root	*/
+#define NLM_F_MATCH	0x200	/* return all matching	*/
+#define NLM_F_ATOMIC	0x400	/* atomic GET		*/
+#define NLM_F_DUMP	(NLM_F_ROOT|NLM_F_MATCH)
+
+/* Modifiers to NEW request */
+#define NLM_F_REPLACE	0x100	/* Override existing		*/
+#define NLM_F_EXCL	0x200	/* Do not touch, if it exists	*/
+#define NLM_F_CREATE	0x400	/* Create, if it does not exist	*/
+#define NLM_F_APPEND	0x800	/* Add to end of list		*/
+
+/* Modifiers to DELETE request */
+#define NLM_F_NONREC	0x100	/* Do not delete recursively	*/
+
+/* Flags for ACK message */
+#define NLM_F_CAPPED	0x100	/* request was capped */
+#define NLM_F_ACK_TLVS	0x200	/* extended ACK TVLs were included */
+
+/*
+   4.4BSD ADD		NLM_F_CREATE|NLM_F_EXCL
+   4.4BSD CHANGE	NLM_F_REPLACE
+
+   True CHANGE		NLM_F_CREATE|NLM_F_REPLACE
+   Append		NLM_F_CREATE
+   Check		NLM_F_EXCL
+ */
+
+#define NLMSG_ALIGNTO	4U
+#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
+#define NLMSG_HDRLEN	 ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
+#define NLMSG_LENGTH(len) ((len) + NLMSG_HDRLEN)
+#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
+#define NLMSG_DATA(nlh)  ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
+#define NLMSG_NEXT(nlh,len)	 ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
+				  (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
+#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
+			   (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
+			   (nlh)->nlmsg_len <= (len))
+#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
+
+#define NLMSG_NOOP		0x1	/* Nothing.		*/
+#define NLMSG_ERROR		0x2	/* Error		*/
+#define NLMSG_DONE		0x3	/* End of a dump	*/
+#define NLMSG_OVERRUN		0x4	/* Data lost		*/
+
+#define NLMSG_MIN_TYPE		0x10	/* < 0x10: reserved control messages */
+
+struct nlmsgerr {
+	int		error;
+	struct nlmsghdr msg;
+	/*
+	 * followed by the message contents unless NETLINK_CAP_ACK was set
+	 * or the ACK indicates success (error == 0)
+	 * message length is aligned with NLMSG_ALIGN()
+	 */
+	/*
+	 * followed by TLVs defined in enum nlmsgerr_attrs
+	 * if NETLINK_EXT_ACK was set
+	 */
+};
+
+/**
+ * enum nlmsgerr_attrs - nlmsgerr attributes
+ * @NLMSGERR_ATTR_UNUSED: unused
+ * @NLMSGERR_ATTR_MSG: error message string (string)
+ * @NLMSGERR_ATTR_OFFS: offset of the invalid attribute in the original
+ *	 message, counting from the beginning of the header (u32)
+ * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to
+ *	be used - in the success case - to identify a created
+ *	object or operation or similar (binary)
+ * @__NLMSGERR_ATTR_MAX: number of attributes
+ * @NLMSGERR_ATTR_MAX: highest attribute number
+ */
+enum nlmsgerr_attrs {
+	NLMSGERR_ATTR_UNUSED,
+	NLMSGERR_ATTR_MSG,
+	NLMSGERR_ATTR_OFFS,
+	NLMSGERR_ATTR_COOKIE,
+
+	__NLMSGERR_ATTR_MAX,
+	NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
+};
+
+#define NETLINK_ADD_MEMBERSHIP		1
+#define NETLINK_DROP_MEMBERSHIP		2
+#define NETLINK_PKTINFO			3
+#define NETLINK_BROADCAST_ERROR		4
+#define NETLINK_NO_ENOBUFS		5
+#ifndef __KERNEL__
+#define NETLINK_RX_RING			6
+#define NETLINK_TX_RING			7
+#endif
+#define NETLINK_LISTEN_ALL_NSID		8
+#define NETLINK_LIST_MEMBERSHIPS	9
+#define NETLINK_CAP_ACK			10
+#define NETLINK_EXT_ACK			11
+
+struct nl_pktinfo {
+	__u32	group;
+};
+
+struct nl_mmap_req {
+	unsigned int	nm_block_size;
+	unsigned int	nm_block_nr;
+	unsigned int	nm_frame_size;
+	unsigned int	nm_frame_nr;
+};
+
+struct nl_mmap_hdr {
+	unsigned int	nm_status;
+	unsigned int	nm_len;
+	__u32		nm_group;
+	/* credentials */
+	__u32		nm_pid;
+	__u32		nm_uid;
+	__u32		nm_gid;
+};
+
+#ifndef __KERNEL__
+enum nl_mmap_status {
+	NL_MMAP_STATUS_UNUSED,
+	NL_MMAP_STATUS_RESERVED,
+	NL_MMAP_STATUS_VALID,
+	NL_MMAP_STATUS_COPY,
+	NL_MMAP_STATUS_SKIP,
+};
+
+#define NL_MMAP_MSG_ALIGNMENT		NLMSG_ALIGNTO
+#define NL_MMAP_MSG_ALIGN(sz)		__ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT)
+#define NL_MMAP_HDRLEN			NL_MMAP_MSG_ALIGN(sizeof(struct nl_mmap_hdr))
+#endif
+
+#define NET_MAJOR 36		/* Major 36 is reserved for networking 						*/
+
+enum {
+	NETLINK_UNCONNECTED = 0,
+	NETLINK_CONNECTED,
+};
+
+/*
+ *  <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
+ * +---------------------+- - -+- - - - - - - - - -+- - -+
+ * |        Header       | Pad |     Payload       | Pad |
+ * |   (struct nlattr)   | ing |                   | ing |
+ * +---------------------+- - -+- - - - - - - - - -+- - -+
+ *  <-------------- nlattr->nla_len -------------->
+ */
+
+struct nlattr {
+	__u16           nla_len;
+	__u16           nla_type;
+};
+
+/*
+ * nla_type (16 bits)
+ * +---+---+-------------------------------+
+ * | N | O | Attribute Type                |
+ * +---+---+-------------------------------+
+ * N := Carries nested attributes
+ * O := Payload stored in network byte order
+ *
+ * Note: The N and O flag are mutually exclusive.
+ */
+#define NLA_F_NESTED		(1 << 15)
+#define NLA_F_NET_BYTEORDER	(1 << 14)
+#define NLA_TYPE_MASK		~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
+
+#define NLA_ALIGNTO		4
+#define NLA_ALIGN(len)		(((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
+#define NLA_HDRLEN		((int) NLA_ALIGN(sizeof(struct nlattr)))
+
+/* Generic 32 bitflags attribute content sent to the kernel.
+ *
+ * The value is a bitmap that defines the values being set
+ * The selector is a bitmask that defines which value is legit
+ *
+ * Examples:
+ *  value = 0x0, and selector = 0x1
+ *  implies we are selecting bit 1 and we want to set its value to 0.
+ *
+ *  value = 0x2, and selector = 0x2
+ *  implies we are selecting bit 2 and we want to set its value to 1.
+ *
+ */
+struct nla_bitfield32 {
+	__u32 value;
+	__u32 selector;
+};
+
+#endif /* _UAPI__LINUX_NETLINK_H */
diff --git a/tools/include/uapi/linux/sched.h b/tools/include/uapi/linux/sched.h
index 30a9e51..22627f8 100644
--- a/tools/include/uapi/linux/sched.h
+++ b/tools/include/uapi/linux/sched.h
@@ -49,5 +49,10 @@
  */
 #define SCHED_FLAG_RESET_ON_FORK	0x01
 #define SCHED_FLAG_RECLAIM		0x02
+#define SCHED_FLAG_DL_OVERRUN		0x04
+
+#define SCHED_FLAG_ALL	(SCHED_FLAG_RESET_ON_FORK	| \
+			 SCHED_FLAG_RECLAIM		| \
+			 SCHED_FLAG_DL_OVERRUN)
 
 #endif /* _UAPI_LINUX_SCHED_H */
diff --git a/tools/include/uapi/sound/asound.h b/tools/include/uapi/sound/asound.h
index c227ccb..07d6158 100644
--- a/tools/include/uapi/sound/asound.h
+++ b/tools/include/uapi/sound/asound.h
@@ -214,6 +214,11 @@ typedef int __bitwise snd_pcm_format_t;
 #define	SNDRV_PCM_FORMAT_IMA_ADPCM	((__force snd_pcm_format_t) 22)
 #define	SNDRV_PCM_FORMAT_MPEG		((__force snd_pcm_format_t) 23)
 #define	SNDRV_PCM_FORMAT_GSM		((__force snd_pcm_format_t) 24)
+#define	SNDRV_PCM_FORMAT_S20_LE	((__force snd_pcm_format_t) 25) /* in four bytes, LSB justified */
+#define	SNDRV_PCM_FORMAT_S20_BE	((__force snd_pcm_format_t) 26) /* in four bytes, LSB justified */
+#define	SNDRV_PCM_FORMAT_U20_LE	((__force snd_pcm_format_t) 27) /* in four bytes, LSB justified */
+#define	SNDRV_PCM_FORMAT_U20_BE	((__force snd_pcm_format_t) 28) /* in four bytes, LSB justified */
+/* gap in the numbering for a future standard linear format */
 #define	SNDRV_PCM_FORMAT_SPECIAL	((__force snd_pcm_format_t) 31)
 #define	SNDRV_PCM_FORMAT_S24_3LE	((__force snd_pcm_format_t) 32)	/* in three bytes */
 #define	SNDRV_PCM_FORMAT_S24_3BE	((__force snd_pcm_format_t) 33)	/* in three bytes */
@@ -248,6 +253,8 @@ typedef int __bitwise snd_pcm_format_t;
 #define	SNDRV_PCM_FORMAT_FLOAT		SNDRV_PCM_FORMAT_FLOAT_LE
 #define	SNDRV_PCM_FORMAT_FLOAT64	SNDRV_PCM_FORMAT_FLOAT64_LE
 #define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
+#define	SNDRV_PCM_FORMAT_S20		SNDRV_PCM_FORMAT_S20_LE
+#define	SNDRV_PCM_FORMAT_U20		SNDRV_PCM_FORMAT_U20_LE
 #endif
 #ifdef SNDRV_BIG_ENDIAN
 #define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_BE
@@ -259,6 +266,8 @@ typedef int __bitwise snd_pcm_format_t;
 #define	SNDRV_PCM_FORMAT_FLOAT		SNDRV_PCM_FORMAT_FLOAT_BE
 #define	SNDRV_PCM_FORMAT_FLOAT64	SNDRV_PCM_FORMAT_FLOAT64_BE
 #define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
+#define	SNDRV_PCM_FORMAT_S20		SNDRV_PCM_FORMAT_S20_BE
+#define	SNDRV_PCM_FORMAT_U20		SNDRV_PCM_FORMAT_U20_BE
 #endif
 
 typedef int __bitwise snd_pcm_subformat_t;
diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build
index d874975..64c679d 100644
--- a/tools/lib/bpf/Build
+++ b/tools/lib/bpf/Build
@@ -1 +1 @@
-libbpf-y := libbpf.o bpf.o
+libbpf-y := libbpf.o bpf.o nlattr.o
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index 83714ca..e6d5f8d 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -160,6 +160,12 @@
 	@(test -f ../../include/uapi/linux/bpf_common.h -a -f ../../../include/uapi/linux/bpf_common.h && ( \
 	(diff -B ../../include/uapi/linux/bpf_common.h ../../../include/uapi/linux/bpf_common.h >/dev/null) || \
 	echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf_common.h' differs from latest version at 'include/uapi/linux/bpf_common.h'" >&2 )) || true
+	@(test -f ../../include/uapi/linux/netlink.h -a -f ../../../include/uapi/linux/netlink.h && ( \
+	(diff -B ../../include/uapi/linux/netlink.h ../../../include/uapi/linux/netlink.h >/dev/null) || \
+	echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/netlink.h' differs from latest version at 'include/uapi/linux/netlink.h'" >&2 )) || true
+	@(test -f ../../include/uapi/linux/if_link.h -a -f ../../../include/uapi/linux/if_link.h && ( \
+	(diff -B ../../include/uapi/linux/if_link.h ../../../include/uapi/linux/if_link.h >/dev/null) || \
+	echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_link.h' differs from latest version at 'include/uapi/linux/if_link.h'" >&2 )) || true
 	$(Q)$(MAKE) $(build)=libbpf
 
 $(OUTPUT)libbpf.so: $(BPF_IN)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 5128677..592a58a 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: LGPL-2.1
+
 /*
  * common eBPF ELF operations.
  *
@@ -25,6 +27,16 @@
 #include <asm/unistd.h>
 #include <linux/bpf.h>
 #include "bpf.h"
+#include "libbpf.h"
+#include "nlattr.h"
+#include <linux/rtnetlink.h>
+#include <linux/if_link.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
 
 /*
  * When building perf, unistd.h is overridden. __NR_bpf is
@@ -46,7 +58,9 @@
 # endif
 #endif
 
+#ifndef min
 #define min(x, y) ((x) < (y) ? (x) : (y))
+#endif
 
 static inline __u64 ptr_to_u64(const void *ptr)
 {
@@ -413,3 +427,124 @@ int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)
 
 	return err;
 }
+
+int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
+{
+	struct sockaddr_nl sa;
+	int sock, seq = 0, len, ret = -1;
+	char buf[4096];
+	struct nlattr *nla, *nla_xdp;
+	struct {
+		struct nlmsghdr  nh;
+		struct ifinfomsg ifinfo;
+		char             attrbuf[64];
+	} req;
+	struct nlmsghdr *nh;
+	struct nlmsgerr *err;
+	socklen_t addrlen;
+	int one = 1;
+
+	memset(&sa, 0, sizeof(sa));
+	sa.nl_family = AF_NETLINK;
+
+	sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (sock < 0) {
+		return -errno;
+	}
+
+	if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK,
+		       &one, sizeof(one)) < 0) {
+		fprintf(stderr, "Netlink error reporting not supported\n");
+	}
+
+	if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
+		ret = -errno;
+		goto cleanup;
+	}
+
+	addrlen = sizeof(sa);
+	if (getsockname(sock, (struct sockaddr *)&sa, &addrlen) < 0) {
+		ret = -errno;
+		goto cleanup;
+	}
+
+	if (addrlen != sizeof(sa)) {
+		ret = -LIBBPF_ERRNO__INTERNAL;
+		goto cleanup;
+	}
+
+	memset(&req, 0, sizeof(req));
+	req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+	req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+	req.nh.nlmsg_type = RTM_SETLINK;
+	req.nh.nlmsg_pid = 0;
+	req.nh.nlmsg_seq = ++seq;
+	req.ifinfo.ifi_family = AF_UNSPEC;
+	req.ifinfo.ifi_index = ifindex;
+
+	/* started nested attribute for XDP */
+	nla = (struct nlattr *)(((char *)&req)
+				+ NLMSG_ALIGN(req.nh.nlmsg_len));
+	nla->nla_type = NLA_F_NESTED | IFLA_XDP;
+	nla->nla_len = NLA_HDRLEN;
+
+	/* add XDP fd */
+	nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
+	nla_xdp->nla_type = IFLA_XDP_FD;
+	nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
+	memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
+	nla->nla_len += nla_xdp->nla_len;
+
+	/* if user passed in any flags, add those too */
+	if (flags) {
+		nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
+		nla_xdp->nla_type = IFLA_XDP_FLAGS;
+		nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
+		memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
+		nla->nla_len += nla_xdp->nla_len;
+	}
+
+	req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
+
+	if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
+		ret = -errno;
+		goto cleanup;
+	}
+
+	len = recv(sock, buf, sizeof(buf), 0);
+	if (len < 0) {
+		ret = -errno;
+		goto cleanup;
+	}
+
+	for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
+	     nh = NLMSG_NEXT(nh, len)) {
+		if (nh->nlmsg_pid != sa.nl_pid) {
+			ret = -LIBBPF_ERRNO__WRNGPID;
+			goto cleanup;
+		}
+		if (nh->nlmsg_seq != seq) {
+			ret = -LIBBPF_ERRNO__INVSEQ;
+			goto cleanup;
+		}
+		switch (nh->nlmsg_type) {
+		case NLMSG_ERROR:
+			err = (struct nlmsgerr *)NLMSG_DATA(nh);
+			if (!err->error)
+				continue;
+			ret = err->error;
+			nla_dump_errormsg(nh);
+			goto cleanup;
+		case NLMSG_DONE:
+			break;
+		default:
+			break;
+		}
+	}
+
+	ret = 0;
+
+cleanup:
+	close(sock);
+	return ret;
+}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 9f44c196..8d18fb7 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+
 /*
  * common eBPF ELF operations.
  *
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 30c7763..71ddc48 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: LGPL-2.1
+
 /*
  * Common eBPF ELF object loading operations.
  *
@@ -106,6 +108,8 @@ static const char *libbpf_strerror_table[NR_ERRNO] = {
 	[ERRCODE_OFFSET(PROG2BIG)]	= "Program too big",
 	[ERRCODE_OFFSET(KVER)]		= "Incorrect kernel version",
 	[ERRCODE_OFFSET(PROGTYPE)]	= "Kernel doesn't support this program type",
+	[ERRCODE_OFFSET(WRNGPID)]	= "Wrong pid in netlink message",
+	[ERRCODE_OFFSET(INVSEQ)]	= "Invalid netlink sequence",
 };
 
 int libbpf_strerror(int err, char *buf, size_t size)
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 6e20003..f859065 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+
 /*
  * Common eBPF ELF object loading operations.
  *
@@ -42,6 +44,8 @@ enum libbpf_errno {
 	LIBBPF_ERRNO__PROG2BIG,	/* Program too big */
 	LIBBPF_ERRNO__KVER,	/* Incorrect kernel version */
 	LIBBPF_ERRNO__PROGTYPE,	/* Kernel doesn't support this program type */
+	LIBBPF_ERRNO__WRNGPID,	/* Wrong pid in netlink message */
+	LIBBPF_ERRNO__INVSEQ,	/* Invalid netlink sequence */
 	__LIBBPF_ERRNO__END,
 };
 
@@ -246,4 +250,6 @@ long libbpf_get_error(const void *ptr);
 
 int bpf_prog_load(const char *file, enum bpf_prog_type type,
 		  struct bpf_object **pobj, int *prog_fd);
+
+int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
 #endif
diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c
new file mode 100644
index 0000000..4719434
--- /dev/null
+++ b/tools/lib/bpf/nlattr.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: LGPL-2.1
+
+/*
+ * NETLINK      Netlink attributes
+ *
+ *	This library is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU Lesser General Public
+ *	License as published by the Free Software Foundation version 2.1
+ *	of the License.
+ *
+ * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
+ */
+
+#include <errno.h>
+#include "nlattr.h"
+#include <linux/rtnetlink.h>
+#include <string.h>
+#include <stdio.h>
+
+static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
+	[NLA_U8]	= sizeof(uint8_t),
+	[NLA_U16]	= sizeof(uint16_t),
+	[NLA_U32]	= sizeof(uint32_t),
+	[NLA_U64]	= sizeof(uint64_t),
+	[NLA_STRING]	= 1,
+	[NLA_FLAG]	= 0,
+};
+
+static int nla_len(const struct nlattr *nla)
+{
+	return nla->nla_len - NLA_HDRLEN;
+}
+
+static struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
+{
+	int totlen = NLA_ALIGN(nla->nla_len);
+
+	*remaining -= totlen;
+	return (struct nlattr *) ((char *) nla + totlen);
+}
+
+static int nla_ok(const struct nlattr *nla, int remaining)
+{
+	return remaining >= sizeof(*nla) &&
+	       nla->nla_len >= sizeof(*nla) &&
+	       nla->nla_len <= remaining;
+}
+
+static void *nla_data(const struct nlattr *nla)
+{
+	return (char *) nla + NLA_HDRLEN;
+}
+
+static int nla_type(const struct nlattr *nla)
+{
+	return nla->nla_type & NLA_TYPE_MASK;
+}
+
+static int validate_nla(struct nlattr *nla, int maxtype,
+			struct nla_policy *policy)
+{
+	struct nla_policy *pt;
+	unsigned int minlen = 0;
+	int type = nla_type(nla);
+
+	if (type < 0 || type > maxtype)
+		return 0;
+
+	pt = &policy[type];
+
+	if (pt->type > NLA_TYPE_MAX)
+		return 0;
+
+	if (pt->minlen)
+		minlen = pt->minlen;
+	else if (pt->type != NLA_UNSPEC)
+		minlen = nla_attr_minlen[pt->type];
+
+	if (nla_len(nla) < minlen)
+		return -1;
+
+	if (pt->maxlen && nla_len(nla) > pt->maxlen)
+		return -1;
+
+	if (pt->type == NLA_STRING) {
+		char *data = nla_data(nla);
+		if (data[nla_len(nla) - 1] != '\0')
+			return -1;
+	}
+
+	return 0;
+}
+
+static inline int nlmsg_len(const struct nlmsghdr *nlh)
+{
+	return nlh->nlmsg_len - NLMSG_HDRLEN;
+}
+
+/**
+ * Create attribute index based on a stream of attributes.
+ * @arg tb		Index array to be filled (maxtype+1 elements).
+ * @arg maxtype		Maximum attribute type expected and accepted.
+ * @arg head		Head of attribute stream.
+ * @arg len		Length of attribute stream.
+ * @arg policy		Attribute validation policy.
+ *
+ * Iterates over the stream of attributes and stores a pointer to each
+ * attribute in the index array using the attribute type as index to
+ * the array. Attribute with a type greater than the maximum type
+ * specified will be silently ignored in order to maintain backwards
+ * compatibility. If \a policy is not NULL, the attribute will be
+ * validated using the specified policy.
+ *
+ * @see nla_validate
+ * @return 0 on success or a negative error code.
+ */
+static int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
+		     struct nla_policy *policy)
+{
+	struct nlattr *nla;
+	int rem, err;
+
+	memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
+
+	nla_for_each_attr(nla, head, len, rem) {
+		int type = nla_type(nla);
+
+		if (type > maxtype)
+			continue;
+
+		if (policy) {
+			err = validate_nla(nla, maxtype, policy);
+			if (err < 0)
+				goto errout;
+		}
+
+		if (tb[type])
+			fprintf(stderr, "Attribute of type %#x found multiple times in message, "
+				  "previous attribute is being ignored.\n", type);
+
+		tb[type] = nla;
+	}
+
+	err = 0;
+errout:
+	return err;
+}
+
+/* dump netlink extended ack error message */
+int nla_dump_errormsg(struct nlmsghdr *nlh)
+{
+	struct nla_policy extack_policy[NLMSGERR_ATTR_MAX + 1] = {
+		[NLMSGERR_ATTR_MSG]	= { .type = NLA_STRING },
+		[NLMSGERR_ATTR_OFFS]	= { .type = NLA_U32 },
+	};
+	struct nlattr *tb[NLMSGERR_ATTR_MAX + 1], *attr;
+	struct nlmsgerr *err;
+	char *errmsg = NULL;
+	int hlen, alen;
+
+	/* no TLVs, nothing to do here */
+	if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS))
+		return 0;
+
+	err = (struct nlmsgerr *)NLMSG_DATA(nlh);
+	hlen = sizeof(*err);
+
+	/* if NLM_F_CAPPED is set then the inner err msg was capped */
+	if (!(nlh->nlmsg_flags & NLM_F_CAPPED))
+		hlen += nlmsg_len(&err->msg);
+
+	attr = (struct nlattr *) ((void *) err + hlen);
+	alen = nlh->nlmsg_len - hlen;
+
+	if (nla_parse(tb, NLMSGERR_ATTR_MAX, attr, alen, extack_policy) != 0) {
+		fprintf(stderr,
+			"Failed to parse extended error attributes\n");
+		return 0;
+	}
+
+	if (tb[NLMSGERR_ATTR_MSG])
+		errmsg = (char *) nla_data(tb[NLMSGERR_ATTR_MSG]);
+
+	fprintf(stderr, "Kernel error message: %s\n", errmsg);
+
+	return 0;
+}
diff --git a/tools/lib/bpf/nlattr.h b/tools/lib/bpf/nlattr.h
new file mode 100644
index 0000000..931a71f
--- /dev/null
+++ b/tools/lib/bpf/nlattr.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+
+/*
+ * NETLINK      Netlink attributes
+ *
+ *	This library is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU Lesser General Public
+ *	License as published by the Free Software Foundation version 2.1
+ *	of the License.
+ *
+ * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
+ */
+
+#ifndef __NLATTR_H
+#define __NLATTR_H
+
+#include <stdint.h>
+#include <linux/netlink.h>
+/* avoid multiple definition of netlink features */
+#define __LINUX_NETLINK_H
+
+/**
+ * Standard attribute types to specify validation policy
+ */
+enum {
+	NLA_UNSPEC,	/**< Unspecified type, binary data chunk */
+	NLA_U8,		/**< 8 bit integer */
+	NLA_U16,	/**< 16 bit integer */
+	NLA_U32,	/**< 32 bit integer */
+	NLA_U64,	/**< 64 bit integer */
+	NLA_STRING,	/**< NUL terminated character string */
+	NLA_FLAG,	/**< Flag */
+	NLA_MSECS,	/**< Micro seconds (64bit) */
+	NLA_NESTED,	/**< Nested attributes */
+	__NLA_TYPE_MAX,
+};
+
+#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
+
+/**
+ * @ingroup attr
+ * Attribute validation policy.
+ *
+ * See section @core_doc{core_attr_parse,Attribute Parsing} for more details.
+ */
+struct nla_policy {
+	/** Type of attribute or NLA_UNSPEC */
+	uint16_t	type;
+
+	/** Minimal length of payload required */
+	uint16_t	minlen;
+
+	/** Maximal length of payload allowed */
+	uint16_t	maxlen;
+};
+
+/**
+ * @ingroup attr
+ * Iterate over a stream of attributes
+ * @arg pos	loop counter, set to current attribute
+ * @arg head	head of attribute stream
+ * @arg len	length of attribute stream
+ * @arg rem	initialized to len, holds bytes currently remaining in stream
+ */
+#define nla_for_each_attr(pos, head, len, rem) \
+	for (pos = head, rem = len; \
+	     nla_ok(pos, rem); \
+	     pos = nla_next(pos, &(rem)))
+
+int nla_dump_errormsg(struct nlmsghdr *nlh);
+
+#endif /* __NLATTR_H */
diff --git a/tools/lib/find_bit.c b/tools/lib/find_bit.c
index 42c15f9..a88bd50 100644
--- a/tools/lib/find_bit.c
+++ b/tools/lib/find_bit.c
@@ -22,22 +22,29 @@
 #include <linux/bitmap.h>
 #include <linux/kernel.h>
 
-#if !defined(find_next_bit)
+#if !defined(find_next_bit) || !defined(find_next_zero_bit) || \
+		!defined(find_next_and_bit)
 
 /*
- * This is a common helper function for find_next_bit and
- * find_next_zero_bit.  The difference is the "invert" argument, which
- * is XORed with each fetched word before searching it for one bits.
+ * This is a common helper function for find_next_bit, find_next_zero_bit, and
+ * find_next_and_bit. The differences are:
+ *  - The "invert" argument, which is XORed with each fetched word before
+ *    searching it for one bits.
+ *  - The optional "addr2", which is anded with "addr1" if present.
  */
-static unsigned long _find_next_bit(const unsigned long *addr,
-		unsigned long nbits, unsigned long start, unsigned long invert)
+static inline unsigned long _find_next_bit(const unsigned long *addr1,
+		const unsigned long *addr2, unsigned long nbits,
+		unsigned long start, unsigned long invert)
 {
 	unsigned long tmp;
 
 	if (unlikely(start >= nbits))
 		return nbits;
 
-	tmp = addr[start / BITS_PER_LONG] ^ invert;
+	tmp = addr1[start / BITS_PER_LONG];
+	if (addr2)
+		tmp &= addr2[start / BITS_PER_LONG];
+	tmp ^= invert;
 
 	/* Handle 1st word. */
 	tmp &= BITMAP_FIRST_WORD_MASK(start);
@@ -48,7 +55,10 @@ static unsigned long _find_next_bit(const unsigned long *addr,
 		if (start >= nbits)
 			return nbits;
 
-		tmp = addr[start / BITS_PER_LONG] ^ invert;
+		tmp = addr1[start / BITS_PER_LONG];
+		if (addr2)
+			tmp &= addr2[start / BITS_PER_LONG];
+		tmp ^= invert;
 	}
 
 	return min(start + __ffs(tmp), nbits);
@@ -62,7 +72,7 @@ static unsigned long _find_next_bit(const unsigned long *addr,
 unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
 			    unsigned long offset)
 {
-	return _find_next_bit(addr, size, offset, 0UL);
+	return _find_next_bit(addr, NULL, size, offset, 0UL);
 }
 #endif
 
@@ -104,6 +114,15 @@ unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
 unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
 				 unsigned long offset)
 {
-	return _find_next_bit(addr, size, offset, ~0UL);
+	return _find_next_bit(addr, NULL, size, offset, ~0UL);
+}
+#endif
+
+#ifndef find_next_and_bit
+unsigned long find_next_and_bit(const unsigned long *addr1,
+		const unsigned long *addr2, unsigned long size,
+		unsigned long offset)
+{
+	return _find_next_bit(addr1, addr2, size, offset, 0UL);
 }
 #endif
diff --git a/tools/lib/subcmd/pager.c b/tools/lib/subcmd/pager.c
index 5ba754d..9997a88 100644
--- a/tools/lib/subcmd/pager.c
+++ b/tools/lib/subcmd/pager.c
@@ -30,10 +30,13 @@ static void pager_preexec(void)
 	 * have real input
 	 */
 	fd_set in;
+	fd_set exception;
 
 	FD_ZERO(&in);
+	FD_ZERO(&exception);
 	FD_SET(0, &in);
-	select(1, &in, NULL, &in, NULL);
+	FD_SET(0, &exception);
+	select(1, &in, NULL, &exception, NULL);
 
 	setenv("LESS", "FRSX", 0);
 }
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index 643cc4ba..3e5135d 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -31,5 +31,6 @@
 .config-detected
 util/intel-pt-decoder/inat-tables.c
 arch/*/include/generated/
+trace/beauty/generated/
 pmu-events/pmu-events.c
 pmu-events/jevents
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 65681a1..bf4ca74 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -1566,7 +1566,8 @@ static struct option __record_options[] = {
 	OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
 			&record.opts.sample_time_set,
 			"Record the sample timestamps"),
-	OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
+	OPT_BOOLEAN_SET('P', "period", &record.opts.period, &record.opts.period_set,
+			"Record the sample period"),
 	OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
 		    "don't sample"),
 	OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 17d11de..e7f1b18 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1661,9 +1661,12 @@ static int trace__resolve_callchain(struct trace *trace, struct perf_evsel *evse
 				    struct callchain_cursor *cursor)
 {
 	struct addr_location al;
+	int max_stack = evsel->attr.sample_max_stack ?
+			evsel->attr.sample_max_stack :
+			trace->max_stack;
 
 	if (machine__resolve(trace->host, &al, sample) < 0 ||
-	    thread__resolve_callchain(al.thread, cursor, evsel, sample, NULL, NULL, evsel->attr.sample_max_stack))
+	    thread__resolve_callchain(al.thread, cursor, evsel, sample, NULL, NULL, max_stack))
 		return -1;
 
 	return 0;
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 2357f4cc..cfe4623 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -50,6 +50,7 @@ struct record_opts {
 	bool	     sample_time_set;
 	bool	     sample_cpu;
 	bool	     period;
+	bool	     period_set;
 	bool	     running_time;
 	bool	     full_auxtrace;
 	bool	     auxtrace_snapshot_mode;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 66fa451..ff359c9 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -745,12 +745,14 @@ static void apply_config_terms(struct perf_evsel *evsel,
 			if (!(term->weak && opts->user_interval != ULLONG_MAX)) {
 				attr->sample_period = term->val.period;
 				attr->freq = 0;
+				perf_evsel__reset_sample_bit(evsel, PERIOD);
 			}
 			break;
 		case PERF_EVSEL__CONFIG_TERM_FREQ:
 			if (!(term->weak && opts->user_freq != UINT_MAX)) {
 				attr->sample_freq = term->val.freq;
 				attr->freq = 1;
+				perf_evsel__set_sample_bit(evsel, PERIOD);
 			}
 			break;
 		case PERF_EVSEL__CONFIG_TERM_TIME:
@@ -969,9 +971,6 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
 	if (target__has_cpu(&opts->target) || opts->sample_cpu)
 		perf_evsel__set_sample_bit(evsel, CPU);
 
-	if (opts->period)
-		perf_evsel__set_sample_bit(evsel, PERIOD);
-
 	/*
 	 * When the user explicitly disabled time don't force it here.
 	 */
@@ -1073,6 +1072,14 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
 	apply_config_terms(evsel, opts, track);
 
 	evsel->ignore_missing_thread = opts->ignore_missing_thread;
+
+	/* The --period option takes the precedence. */
+	if (opts->period_set) {
+		if (opts->period)
+			perf_evsel__set_sample_bit(evsel, PERIOD);
+		else
+			perf_evsel__reset_sample_bit(evsel, PERIOD);
+	}
 }
 
 static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index db33b28..0392153 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -37,10 +37,12 @@
 
 nfit-y := $(ACPI_SRC)/core.o
 nfit-$(CONFIG_X86_MCE) += $(ACPI_SRC)/mce.o
+nfit-y += acpi_nfit_test.o
 nfit-y += config_check.o
 
 nd_pmem-y := $(NVDIMM_SRC)/pmem.o
 nd_pmem-y += pmem-dax.o
+nd_pmem-y += pmem_test.o
 nd_pmem-y += config_check.o
 
 nd_btt-y := $(NVDIMM_SRC)/btt.o
@@ -57,6 +59,7 @@
 
 device_dax-y := $(DAX_SRC)/device.o
 device_dax-y += dax-dev.o
+device_dax-y += device_dax_test.o
 device_dax-y += config_check.o
 
 dax_pmem-y := $(DAX_SRC)/pmem.o
@@ -75,6 +78,7 @@
 libnvdimm-$(CONFIG_BTT) += $(NVDIMM_SRC)/btt_devs.o
 libnvdimm-$(CONFIG_NVDIMM_PFN) += $(NVDIMM_SRC)/pfn_devs.o
 libnvdimm-$(CONFIG_NVDIMM_DAX) += $(NVDIMM_SRC)/dax_devs.o
+libnvdimm-y += libnvdimm_test.o
 libnvdimm-y += config_check.o
 
 obj-m += test/
diff --git a/tools/testing/nvdimm/acpi_nfit_test.c b/tools/testing/nvdimm/acpi_nfit_test.c
new file mode 100644
index 0000000..4352151
--- /dev/null
+++ b/tools/testing/nvdimm/acpi_nfit_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(acpi_nfit);
diff --git a/tools/testing/nvdimm/device_dax_test.c b/tools/testing/nvdimm/device_dax_test.c
new file mode 100644
index 0000000..24b17bf
--- /dev/null
+++ b/tools/testing/nvdimm/device_dax_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(device_dax);
diff --git a/tools/testing/nvdimm/libnvdimm_test.c b/tools/testing/nvdimm/libnvdimm_test.c
new file mode 100644
index 0000000..00ca30b
--- /dev/null
+++ b/tools/testing/nvdimm/libnvdimm_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(libnvdimm);
diff --git a/tools/testing/nvdimm/pmem_test.c b/tools/testing/nvdimm/pmem_test.c
new file mode 100644
index 0000000..fd38f92
--- /dev/null
+++ b/tools/testing/nvdimm/pmem_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(pmem);
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index e1f75a1..ff9d3a5 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -104,15 +104,14 @@ void *__wrap_devm_memremap(struct device *dev, resource_size_t offset,
 }
 EXPORT_SYMBOL(__wrap_devm_memremap);
 
-void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res,
-		struct percpu_ref *ref, struct vmem_altmap *altmap)
+void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
 {
-	resource_size_t offset = res->start;
+	resource_size_t offset = pgmap->res.start;
 	struct nfit_test_resource *nfit_res = get_nfit_res(offset);
 
 	if (nfit_res)
 		return nfit_res->buf + offset - nfit_res->res.start;
-	return devm_memremap_pages(dev, res, ref, altmap);
+	return devm_memremap_pages(dev, pgmap);
 }
 EXPORT_SYMBOL(__wrap_devm_memremap_pages);
 
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 7217b2b..620fa78 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -27,6 +27,7 @@
 #include <nfit.h>
 #include <nd.h>
 #include "nfit_test.h"
+#include "../watermark.h"
 
 /*
  * Generate an NFIT table to describe the following topology:
@@ -137,6 +138,14 @@ static u32 handle[] = {
 
 static unsigned long dimm_fail_cmd_flags[NUM_DCR];
 
+struct nfit_test_fw {
+	enum intel_fw_update_state state;
+	u32 context;
+	u64 version;
+	u32 size_received;
+	u64 end_time;
+};
+
 struct nfit_test {
 	struct acpi_nfit_desc acpi_desc;
 	struct platform_device pdev;
@@ -168,8 +177,11 @@ struct nfit_test {
 		spinlock_t lock;
 	} ars_state;
 	struct device *dimm_dev[NUM_DCR];
+	struct nd_intel_smart *smart;
+	struct nd_intel_smart_threshold *smart_threshold;
 	struct badrange badrange;
 	struct work_struct work;
+	struct nfit_test_fw *fw;
 };
 
 static struct workqueue_struct *nfit_wq;
@@ -181,6 +193,226 @@ static struct nfit_test *to_nfit_test(struct device *dev)
 	return container_of(pdev, struct nfit_test, pdev);
 }
 
+static int nd_intel_test_get_fw_info(struct nfit_test *t,
+		struct nd_intel_fw_info *nd_cmd, unsigned int buf_len,
+		int idx)
+{
+	struct device *dev = &t->pdev.dev;
+	struct nfit_test_fw *fw = &t->fw[idx];
+
+	dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p, buf_len: %u, idx: %d\n",
+			__func__, t, nd_cmd, buf_len, idx);
+
+	if (buf_len < sizeof(*nd_cmd))
+		return -EINVAL;
+
+	nd_cmd->status = 0;
+	nd_cmd->storage_size = INTEL_FW_STORAGE_SIZE;
+	nd_cmd->max_send_len = INTEL_FW_MAX_SEND_LEN;
+	nd_cmd->query_interval = INTEL_FW_QUERY_INTERVAL;
+	nd_cmd->max_query_time = INTEL_FW_QUERY_MAX_TIME;
+	nd_cmd->update_cap = 0;
+	nd_cmd->fis_version = INTEL_FW_FIS_VERSION;
+	nd_cmd->run_version = 0;
+	nd_cmd->updated_version = fw->version;
+
+	return 0;
+}
+
+static int nd_intel_test_start_update(struct nfit_test *t,
+		struct nd_intel_fw_start *nd_cmd, unsigned int buf_len,
+		int idx)
+{
+	struct device *dev = &t->pdev.dev;
+	struct nfit_test_fw *fw = &t->fw[idx];
+
+	dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+			__func__, t, nd_cmd, buf_len, idx);
+
+	if (buf_len < sizeof(*nd_cmd))
+		return -EINVAL;
+
+	if (fw->state != FW_STATE_NEW) {
+		/* extended status, FW update in progress */
+		nd_cmd->status = 0x10007;
+		return 0;
+	}
+
+	fw->state = FW_STATE_IN_PROGRESS;
+	fw->context++;
+	fw->size_received = 0;
+	nd_cmd->status = 0;
+	nd_cmd->context = fw->context;
+
+	dev_dbg(dev, "%s: context issued: %#x\n", __func__, nd_cmd->context);
+
+	return 0;
+}
+
+static int nd_intel_test_send_data(struct nfit_test *t,
+		struct nd_intel_fw_send_data *nd_cmd, unsigned int buf_len,
+		int idx)
+{
+	struct device *dev = &t->pdev.dev;
+	struct nfit_test_fw *fw = &t->fw[idx];
+	u32 *status = (u32 *)&nd_cmd->data[nd_cmd->length];
+
+	dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+			__func__, t, nd_cmd, buf_len, idx);
+
+	if (buf_len < sizeof(*nd_cmd))
+		return -EINVAL;
+
+
+	dev_dbg(dev, "%s: cmd->status: %#x\n", __func__, *status);
+	dev_dbg(dev, "%s: cmd->data[0]: %#x\n", __func__, nd_cmd->data[0]);
+	dev_dbg(dev, "%s: cmd->data[%u]: %#x\n", __func__, nd_cmd->length-1,
+			nd_cmd->data[nd_cmd->length-1]);
+
+	if (fw->state != FW_STATE_IN_PROGRESS) {
+		dev_dbg(dev, "%s: not in IN_PROGRESS state\n", __func__);
+		*status = 0x5;
+		return 0;
+	}
+
+	if (nd_cmd->context != fw->context) {
+		dev_dbg(dev, "%s: incorrect context: in: %#x correct: %#x\n",
+				__func__, nd_cmd->context, fw->context);
+		*status = 0x10007;
+		return 0;
+	}
+
+	/*
+	 * check offset + len > size of fw storage
+	 * check length is > max send length
+	 */
+	if (nd_cmd->offset + nd_cmd->length > INTEL_FW_STORAGE_SIZE ||
+			nd_cmd->length > INTEL_FW_MAX_SEND_LEN) {
+		*status = 0x3;
+		dev_dbg(dev, "%s: buffer boundary violation\n", __func__);
+		return 0;
+	}
+
+	fw->size_received += nd_cmd->length;
+	dev_dbg(dev, "%s: copying %u bytes, %u bytes so far\n",
+			__func__, nd_cmd->length, fw->size_received);
+	*status = 0;
+	return 0;
+}
+
+static int nd_intel_test_finish_fw(struct nfit_test *t,
+		struct nd_intel_fw_finish_update *nd_cmd,
+		unsigned int buf_len, int idx)
+{
+	struct device *dev = &t->pdev.dev;
+	struct nfit_test_fw *fw = &t->fw[idx];
+
+	dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+			__func__, t, nd_cmd, buf_len, idx);
+
+	if (fw->state == FW_STATE_UPDATED) {
+		/* update already done, need cold boot */
+		nd_cmd->status = 0x20007;
+		return 0;
+	}
+
+	dev_dbg(dev, "%s: context: %#x  ctrl_flags: %#x\n",
+			__func__, nd_cmd->context, nd_cmd->ctrl_flags);
+
+	switch (nd_cmd->ctrl_flags) {
+	case 0: /* finish */
+		if (nd_cmd->context != fw->context) {
+			dev_dbg(dev, "%s: incorrect context: in: %#x correct: %#x\n",
+					__func__, nd_cmd->context,
+					fw->context);
+			nd_cmd->status = 0x10007;
+			return 0;
+		}
+		nd_cmd->status = 0;
+		fw->state = FW_STATE_VERIFY;
+		/* set 1 second of time for firmware "update" */
+		fw->end_time = jiffies + HZ;
+		break;
+
+	case 1: /* abort */
+		fw->size_received = 0;
+		/* successfully aborted status */
+		nd_cmd->status = 0x40007;
+		fw->state = FW_STATE_NEW;
+		dev_dbg(dev, "%s: abort successful\n", __func__);
+		break;
+
+	default: /* bad control flag */
+		dev_warn(dev, "%s: unknown control flag: %#x\n",
+				__func__, nd_cmd->ctrl_flags);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int nd_intel_test_finish_query(struct nfit_test *t,
+		struct nd_intel_fw_finish_query *nd_cmd,
+		unsigned int buf_len, int idx)
+{
+	struct device *dev = &t->pdev.dev;
+	struct nfit_test_fw *fw = &t->fw[idx];
+
+	dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+			__func__, t, nd_cmd, buf_len, idx);
+
+	if (buf_len < sizeof(*nd_cmd))
+		return -EINVAL;
+
+	if (nd_cmd->context != fw->context) {
+		dev_dbg(dev, "%s: incorrect context: in: %#x correct: %#x\n",
+				__func__, nd_cmd->context, fw->context);
+		nd_cmd->status = 0x10007;
+		return 0;
+	}
+
+	dev_dbg(dev, "%s context: %#x\n", __func__, nd_cmd->context);
+
+	switch (fw->state) {
+	case FW_STATE_NEW:
+		nd_cmd->updated_fw_rev = 0;
+		nd_cmd->status = 0;
+		dev_dbg(dev, "%s: new state\n", __func__);
+		break;
+
+	case FW_STATE_IN_PROGRESS:
+		/* sequencing error */
+		nd_cmd->status = 0x40007;
+		nd_cmd->updated_fw_rev = 0;
+		dev_dbg(dev, "%s: sequence error\n", __func__);
+		break;
+
+	case FW_STATE_VERIFY:
+		if (time_is_after_jiffies64(fw->end_time)) {
+			nd_cmd->updated_fw_rev = 0;
+			nd_cmd->status = 0x20007;
+			dev_dbg(dev, "%s: still verifying\n", __func__);
+			break;
+		}
+
+		dev_dbg(dev, "%s: transition out verify\n", __func__);
+		fw->state = FW_STATE_UPDATED;
+		/* we are going to fall through if it's "done" */
+	case FW_STATE_UPDATED:
+		nd_cmd->status = 0;
+		/* bogus test version */
+		fw->version = nd_cmd->updated_fw_rev =
+			INTEL_FW_FAKE_VERSION;
+		dev_dbg(dev, "%s: updated\n", __func__);
+		break;
+
+	default: /* we should never get here */
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int nfit_test_cmd_get_config_size(struct nd_cmd_get_config_size *nd_cmd,
 		unsigned int buf_len)
 {
@@ -440,39 +672,66 @@ static int nfit_test_cmd_translate_spa(struct nvdimm_bus *bus,
 	return 0;
 }
 
-static int nfit_test_cmd_smart(struct nd_cmd_smart *smart, unsigned int buf_len)
+static int nfit_test_cmd_smart(struct nd_intel_smart *smart, unsigned int buf_len,
+		struct nd_intel_smart *smart_data)
 {
-	static const struct nd_smart_payload smart_data = {
-		.flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID
-			| ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID
-			| ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID,
-		.health = ND_SMART_NON_CRITICAL_HEALTH,
-		.temperature = 23 * 16,
-		.spares = 75,
-		.alarm_flags = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
-		.life_used = 5,
-		.shutdown_state = 0,
-		.vendor_size = 0,
-	};
-
 	if (buf_len < sizeof(*smart))
 		return -EINVAL;
-	memcpy(smart->data, &smart_data, sizeof(smart_data));
+	memcpy(smart, smart_data, sizeof(*smart));
 	return 0;
 }
 
-static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold *smart_t,
-		unsigned int buf_len)
+static int nfit_test_cmd_smart_threshold(
+		struct nd_intel_smart_threshold *out,
+		unsigned int buf_len,
+		struct nd_intel_smart_threshold *smart_t)
 {
-	static const struct nd_smart_threshold_payload smart_t_data = {
-		.alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
-		.temperature = 40 * 16,
-		.spares = 5,
-	};
-
 	if (buf_len < sizeof(*smart_t))
 		return -EINVAL;
-	memcpy(smart_t->data, &smart_t_data, sizeof(smart_t_data));
+	memcpy(out, smart_t, sizeof(*smart_t));
+	return 0;
+}
+
+static void smart_notify(struct device *bus_dev,
+		struct device *dimm_dev, struct nd_intel_smart *smart,
+		struct nd_intel_smart_threshold *thresh)
+{
+	dev_dbg(dimm_dev, "%s: alarm: %#x spares: %d (%d) mtemp: %d (%d) ctemp: %d (%d)\n",
+			__func__, thresh->alarm_control, thresh->spares,
+			smart->spares, thresh->media_temperature,
+			smart->media_temperature, thresh->ctrl_temperature,
+			smart->ctrl_temperature);
+	if (((thresh->alarm_control & ND_INTEL_SMART_SPARE_TRIP)
+				&& smart->spares
+				<= thresh->spares)
+			|| ((thresh->alarm_control & ND_INTEL_SMART_TEMP_TRIP)
+				&& smart->media_temperature
+				>= thresh->media_temperature)
+			|| ((thresh->alarm_control & ND_INTEL_SMART_CTEMP_TRIP)
+				&& smart->ctrl_temperature
+				>= thresh->ctrl_temperature)) {
+		device_lock(bus_dev);
+		__acpi_nvdimm_notify(dimm_dev, 0x81);
+		device_unlock(bus_dev);
+	}
+}
+
+static int nfit_test_cmd_smart_set_threshold(
+		struct nd_intel_smart_set_threshold *in,
+		unsigned int buf_len,
+		struct nd_intel_smart_threshold *thresh,
+		struct nd_intel_smart *smart,
+		struct device *bus_dev, struct device *dimm_dev)
+{
+	unsigned int size;
+
+	size = sizeof(*in) - 4;
+	if (buf_len < size)
+		return -EINVAL;
+	memcpy(thresh->data, in, size);
+	in->status = 0;
+	smart_notify(bus_dev, dimm_dev, smart, thresh);
+
 	return 0;
 }
 
@@ -563,6 +822,52 @@ static int nfit_test_cmd_ars_inject_status(struct nfit_test *t,
 	return 0;
 }
 
+static int nd_intel_test_cmd_set_lss_status(struct nfit_test *t,
+		struct nd_intel_lss *nd_cmd, unsigned int buf_len)
+{
+	struct device *dev = &t->pdev.dev;
+
+	if (buf_len < sizeof(*nd_cmd))
+		return -EINVAL;
+
+	switch (nd_cmd->enable) {
+	case 0:
+		nd_cmd->status = 0;
+		dev_dbg(dev, "%s: Latch System Shutdown Status disabled\n",
+				__func__);
+		break;
+	case 1:
+		nd_cmd->status = 0;
+		dev_dbg(dev, "%s: Latch System Shutdown Status enabled\n",
+				__func__);
+		break;
+	default:
+		dev_warn(dev, "Unknown enable value: %#x\n", nd_cmd->enable);
+		nd_cmd->status = 0x3;
+		break;
+	}
+
+
+	return 0;
+}
+
+static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
+{
+	int i;
+
+	/* lookup per-dimm data */
+	for (i = 0; i < ARRAY_SIZE(handle); i++)
+		if (__to_nfit_memdev(nfit_mem)->device_handle == handle[i])
+			break;
+	if (i >= ARRAY_SIZE(handle))
+		return -ENXIO;
+
+	if ((1 << func) & dimm_fail_cmd_flags[i])
+		return -EIO;
+
+	return i;
+}
+
 static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
 		struct nvdimm *nvdimm, unsigned int cmd, void *buf,
 		unsigned int buf_len, int *cmd_rc)
@@ -591,22 +896,57 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
 			func = call_pkg->nd_command;
 			if (call_pkg->nd_family != nfit_mem->family)
 				return -ENOTTY;
+
+			i = get_dimm(nfit_mem, func);
+			if (i < 0)
+				return i;
+
+			switch (func) {
+			case ND_INTEL_ENABLE_LSS_STATUS:
+				return nd_intel_test_cmd_set_lss_status(t,
+						buf, buf_len);
+			case ND_INTEL_FW_GET_INFO:
+				return nd_intel_test_get_fw_info(t, buf,
+						buf_len, i - t->dcr_idx);
+			case ND_INTEL_FW_START_UPDATE:
+				return nd_intel_test_start_update(t, buf,
+						buf_len, i - t->dcr_idx);
+			case ND_INTEL_FW_SEND_DATA:
+				return nd_intel_test_send_data(t, buf,
+						buf_len, i - t->dcr_idx);
+			case ND_INTEL_FW_FINISH_UPDATE:
+				return nd_intel_test_finish_fw(t, buf,
+						buf_len, i - t->dcr_idx);
+			case ND_INTEL_FW_FINISH_QUERY:
+				return nd_intel_test_finish_query(t, buf,
+						buf_len, i - t->dcr_idx);
+			case ND_INTEL_SMART:
+				return nfit_test_cmd_smart(buf, buf_len,
+						&t->smart[i - t->dcr_idx]);
+			case ND_INTEL_SMART_THRESHOLD:
+				return nfit_test_cmd_smart_threshold(buf,
+						buf_len,
+						&t->smart_threshold[i -
+							t->dcr_idx]);
+			case ND_INTEL_SMART_SET_THRESHOLD:
+				return nfit_test_cmd_smart_set_threshold(buf,
+						buf_len,
+						&t->smart_threshold[i -
+							t->dcr_idx],
+						&t->smart[i - t->dcr_idx],
+						&t->pdev.dev, t->dimm_dev[i]);
+			default:
+				return -ENOTTY;
+			}
 		}
 
 		if (!test_bit(cmd, &cmd_mask)
 				|| !test_bit(func, &nfit_mem->dsm_mask))
 			return -ENOTTY;
 
-		/* lookup label space for the given dimm */
-		for (i = 0; i < ARRAY_SIZE(handle); i++)
-			if (__to_nfit_memdev(nfit_mem)->device_handle ==
-					handle[i])
-				break;
-		if (i >= ARRAY_SIZE(handle))
-			return -ENXIO;
-
-		if ((1 << func) & dimm_fail_cmd_flags[i])
-			return -EIO;
+		i = get_dimm(nfit_mem, func);
+		if (i < 0)
+			return i;
 
 		switch (func) {
 		case ND_CMD_GET_CONFIG_SIZE:
@@ -620,15 +960,6 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
 			rc = nfit_test_cmd_set_config_data(buf, buf_len,
 				t->label[i - t->dcr_idx]);
 			break;
-		case ND_CMD_SMART:
-			rc = nfit_test_cmd_smart(buf, buf_len);
-			break;
-		case ND_CMD_SMART_THRESHOLD:
-			rc = nfit_test_cmd_smart_threshold(buf, buf_len);
-			device_lock(&t->pdev.dev);
-			__acpi_nvdimm_notify(t->dimm_dev[i], 0x81);
-			device_unlock(&t->pdev.dev);
-			break;
 		default:
 			return -ENOTTY;
 		}
@@ -872,6 +1203,44 @@ static const struct attribute_group *nfit_test_dimm_attribute_groups[] = {
 	NULL,
 };
 
+static void smart_init(struct nfit_test *t)
+{
+	int i;
+	const struct nd_intel_smart_threshold smart_t_data = {
+		.alarm_control = ND_INTEL_SMART_SPARE_TRIP
+			| ND_INTEL_SMART_TEMP_TRIP,
+		.media_temperature = 40 * 16,
+		.ctrl_temperature = 30 * 16,
+		.spares = 5,
+	};
+	const struct nd_intel_smart smart_data = {
+		.flags = ND_INTEL_SMART_HEALTH_VALID
+			| ND_INTEL_SMART_SPARES_VALID
+			| ND_INTEL_SMART_ALARM_VALID
+			| ND_INTEL_SMART_USED_VALID
+			| ND_INTEL_SMART_SHUTDOWN_VALID
+			| ND_INTEL_SMART_MTEMP_VALID,
+		.health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
+		.media_temperature = 23 * 16,
+		.ctrl_temperature = 30 * 16,
+		.pmic_temperature = 40 * 16,
+		.spares = 75,
+		.alarm_flags = ND_INTEL_SMART_SPARE_TRIP
+			| ND_INTEL_SMART_TEMP_TRIP,
+		.ait_status = 1,
+		.life_used = 5,
+		.shutdown_state = 0,
+		.vendor_size = 0,
+		.shutdown_count = 100,
+	};
+
+	for (i = 0; i < t->num_dcr; i++) {
+		memcpy(&t->smart[i], &smart_data, sizeof(smart_data));
+		memcpy(&t->smart_threshold[i], &smart_t_data,
+				sizeof(smart_t_data));
+	}
+}
+
 static int nfit_test0_alloc(struct nfit_test *t)
 {
 	size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
@@ -881,7 +1250,8 @@ static int nfit_test0_alloc(struct nfit_test *t)
 					window_size) * NUM_DCR
 			+ sizeof(struct acpi_nfit_data_region) * NUM_BDW
 			+ (sizeof(struct acpi_nfit_flush_address)
-					+ sizeof(u64) * NUM_HINTS) * NUM_DCR;
+					+ sizeof(u64) * NUM_HINTS) * NUM_DCR
+			+ sizeof(struct acpi_nfit_capabilities);
 	int i;
 
 	t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma);
@@ -939,6 +1309,7 @@ static int nfit_test0_alloc(struct nfit_test *t)
 			return -ENOMEM;
 	}
 
+	smart_init(t);
 	return ars_state_init(&t->pdev.dev, &t->ars_state);
 }
 
@@ -969,6 +1340,7 @@ static int nfit_test1_alloc(struct nfit_test *t)
 	if (!t->spa_set[1])
 		return -ENOMEM;
 
+	smart_init(t);
 	return ars_state_init(&t->pdev.dev, &t->ars_state);
 }
 
@@ -993,6 +1365,7 @@ static void nfit_test0_setup(struct nfit_test *t)
 	struct acpi_nfit_control_region *dcr;
 	struct acpi_nfit_data_region *bdw;
 	struct acpi_nfit_flush_address *flush;
+	struct acpi_nfit_capabilities *pcap;
 	unsigned int offset, i;
 
 	/*
@@ -1500,8 +1873,16 @@ static void nfit_test0_setup(struct nfit_test *t)
 	for (i = 0; i < NUM_HINTS; i++)
 		flush->hint_address[i] = t->flush_dma[3] + i * sizeof(u64);
 
+	/* platform capabilities */
+	pcap = nfit_buf + offset + flush_hint_size * 4;
+	pcap->header.type = ACPI_NFIT_TYPE_CAPABILITIES;
+	pcap->header.length = sizeof(*pcap);
+	pcap->highest_capability = 1;
+	pcap->capabilities = ACPI_NFIT_CAPABILITY_CACHE_FLUSH |
+		ACPI_NFIT_CAPABILITY_MEM_FLUSH;
+
 	if (t->setup_hotplug) {
-		offset = offset + flush_hint_size * 4;
+		offset = offset + flush_hint_size * 4 + sizeof(*pcap);
 		/* dcr-descriptor4: blk */
 		dcr = nfit_buf + offset;
 		dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
@@ -1642,17 +2023,24 @@ static void nfit_test0_setup(struct nfit_test *t)
 	set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en);
 	set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
 	set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
-	set_bit(ND_CMD_SMART, &acpi_desc->dimm_cmd_force_en);
+	set_bit(ND_INTEL_SMART, &acpi_desc->dimm_cmd_force_en);
+	set_bit(ND_INTEL_SMART_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
+	set_bit(ND_INTEL_SMART_SET_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
 	set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en);
 	set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
 	set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
 	set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
 	set_bit(ND_CMD_CALL, &acpi_desc->bus_cmd_force_en);
-	set_bit(ND_CMD_SMART_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
 	set_bit(NFIT_CMD_TRANSLATE_SPA, &acpi_desc->bus_nfit_cmd_force_en);
 	set_bit(NFIT_CMD_ARS_INJECT_SET, &acpi_desc->bus_nfit_cmd_force_en);
 	set_bit(NFIT_CMD_ARS_INJECT_CLEAR, &acpi_desc->bus_nfit_cmd_force_en);
 	set_bit(NFIT_CMD_ARS_INJECT_GET, &acpi_desc->bus_nfit_cmd_force_en);
+	set_bit(ND_INTEL_FW_GET_INFO, &acpi_desc->dimm_cmd_force_en);
+	set_bit(ND_INTEL_FW_START_UPDATE, &acpi_desc->dimm_cmd_force_en);
+	set_bit(ND_INTEL_FW_SEND_DATA, &acpi_desc->dimm_cmd_force_en);
+	set_bit(ND_INTEL_FW_FINISH_UPDATE, &acpi_desc->dimm_cmd_force_en);
+	set_bit(ND_INTEL_FW_FINISH_QUERY, &acpi_desc->dimm_cmd_force_en);
+	set_bit(ND_INTEL_ENABLE_LSS_STATUS, &acpi_desc->dimm_cmd_force_en);
 }
 
 static void nfit_test1_setup(struct nfit_test *t)
@@ -1750,6 +2138,7 @@ static void nfit_test1_setup(struct nfit_test *t)
 	set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
 	set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
 	set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
+	set_bit(ND_INTEL_ENABLE_LSS_STATUS, &acpi_desc->dimm_cmd_force_en);
 }
 
 static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
@@ -2054,10 +2443,18 @@ static int nfit_test_probe(struct platform_device *pdev)
 				sizeof(struct nfit_test_dcr *), GFP_KERNEL);
 		nfit_test->dcr_dma = devm_kcalloc(dev, num,
 				sizeof(dma_addr_t), GFP_KERNEL);
+		nfit_test->smart = devm_kcalloc(dev, num,
+				sizeof(struct nd_intel_smart), GFP_KERNEL);
+		nfit_test->smart_threshold = devm_kcalloc(dev, num,
+				sizeof(struct nd_intel_smart_threshold),
+				GFP_KERNEL);
+		nfit_test->fw = devm_kcalloc(dev, num,
+				sizeof(struct nfit_test_fw), GFP_KERNEL);
 		if (nfit_test->dimm && nfit_test->dimm_dma && nfit_test->label
 				&& nfit_test->label_dma && nfit_test->dcr
 				&& nfit_test->dcr_dma && nfit_test->flush
-				&& nfit_test->flush_dma)
+				&& nfit_test->flush_dma
+				&& nfit_test->fw)
 			/* pass */;
 		else
 			return -ENOMEM;
@@ -2159,6 +2556,11 @@ static __init int nfit_test_init(void)
 {
 	int rc, i;
 
+	pmem_test();
+	libnvdimm_test();
+	acpi_nfit_test();
+	device_dax_test();
+
 	nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm);
 
 	nfit_wq = create_singlethread_workqueue("nfit");
diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h
index 113b446..4283445 100644
--- a/tools/testing/nvdimm/test/nfit_test.h
+++ b/tools/testing/nvdimm/test/nfit_test.h
@@ -84,6 +84,140 @@ struct nd_cmd_ars_err_inj_stat {
 	} __packed record[0];
 } __packed;
 
+#define ND_INTEL_SMART			 1
+#define ND_INTEL_SMART_THRESHOLD	 2
+#define ND_INTEL_ENABLE_LSS_STATUS	10
+#define ND_INTEL_FW_GET_INFO		12
+#define ND_INTEL_FW_START_UPDATE	13
+#define ND_INTEL_FW_SEND_DATA		14
+#define ND_INTEL_FW_FINISH_UPDATE	15
+#define ND_INTEL_FW_FINISH_QUERY	16
+#define ND_INTEL_SMART_SET_THRESHOLD	17
+
+#define ND_INTEL_SMART_HEALTH_VALID             (1 << 0)
+#define ND_INTEL_SMART_SPARES_VALID             (1 << 1)
+#define ND_INTEL_SMART_USED_VALID               (1 << 2)
+#define ND_INTEL_SMART_MTEMP_VALID              (1 << 3)
+#define ND_INTEL_SMART_CTEMP_VALID              (1 << 4)
+#define ND_INTEL_SMART_SHUTDOWN_COUNT_VALID     (1 << 5)
+#define ND_INTEL_SMART_AIT_STATUS_VALID         (1 << 6)
+#define ND_INTEL_SMART_PTEMP_VALID              (1 << 7)
+#define ND_INTEL_SMART_ALARM_VALID              (1 << 9)
+#define ND_INTEL_SMART_SHUTDOWN_VALID           (1 << 10)
+#define ND_INTEL_SMART_VENDOR_VALID             (1 << 11)
+#define ND_INTEL_SMART_SPARE_TRIP               (1 << 0)
+#define ND_INTEL_SMART_TEMP_TRIP                (1 << 1)
+#define ND_INTEL_SMART_CTEMP_TRIP               (1 << 2)
+#define ND_INTEL_SMART_NON_CRITICAL_HEALTH      (1 << 0)
+#define ND_INTEL_SMART_CRITICAL_HEALTH          (1 << 1)
+#define ND_INTEL_SMART_FATAL_HEALTH             (1 << 2)
+
+struct nd_intel_smart {
+	__u32 status;
+	union {
+		struct {
+			__u32 flags;
+			__u8 reserved0[4];
+			__u8 health;
+			__u8 spares;
+			__u8 life_used;
+			__u8 alarm_flags;
+			__u16 media_temperature;
+			__u16 ctrl_temperature;
+			__u32 shutdown_count;
+			__u8 ait_status;
+			__u16 pmic_temperature;
+			__u8 reserved1[8];
+			__u8 shutdown_state;
+			__u32 vendor_size;
+			__u8 vendor_data[92];
+		} __packed;
+		__u8 data[128];
+	};
+} __packed;
+
+struct nd_intel_smart_threshold {
+	__u32 status;
+	union {
+		struct {
+			__u16 alarm_control;
+			__u8 spares;
+			__u16 media_temperature;
+			__u16 ctrl_temperature;
+			__u8 reserved[1];
+		} __packed;
+		__u8 data[8];
+	};
+} __packed;
+
+struct nd_intel_smart_set_threshold {
+	__u16 alarm_control;
+	__u8 spares;
+	__u16 media_temperature;
+	__u16 ctrl_temperature;
+	__u32 status;
+} __packed;
+
+#define INTEL_FW_STORAGE_SIZE		0x100000
+#define INTEL_FW_MAX_SEND_LEN		0xFFEC
+#define INTEL_FW_QUERY_INTERVAL		250000
+#define INTEL_FW_QUERY_MAX_TIME		3000000
+#define INTEL_FW_FIS_VERSION		0x0105
+#define INTEL_FW_FAKE_VERSION		0xffffffffabcd
+
+enum intel_fw_update_state {
+	FW_STATE_NEW = 0,
+	FW_STATE_IN_PROGRESS,
+	FW_STATE_VERIFY,
+	FW_STATE_UPDATED,
+};
+
+struct nd_intel_fw_info {
+	__u32 status;
+	__u32 storage_size;
+	__u32 max_send_len;
+	__u32 query_interval;
+	__u32 max_query_time;
+	__u8 update_cap;
+	__u8 reserved[3];
+	__u32 fis_version;
+	__u64 run_version;
+	__u64 updated_version;
+} __packed;
+
+struct nd_intel_fw_start {
+	__u32 status;
+	__u32 context;
+} __packed;
+
+/* this one has the output first because the variable input data size */
+struct nd_intel_fw_send_data {
+	__u32 context;
+	__u32 offset;
+	__u32 length;
+	__u8 data[0];
+/* this field is not declared due ot variable data from input */
+/*	__u32 status; */
+} __packed;
+
+struct nd_intel_fw_finish_update {
+	__u8 ctrl_flags;
+	__u8 reserved[3];
+	__u32 context;
+	__u32 status;
+} __packed;
+
+struct nd_intel_fw_finish_query {
+	__u32 context;
+	__u32 status;
+	__u64 updated_fw_rev;
+} __packed;
+
+struct nd_intel_lss {
+	__u8 enable;
+	__u32 status;
+} __packed;
+
 union acpi_object;
 typedef void *acpi_handle;
 
diff --git a/tools/testing/nvdimm/watermark.h b/tools/testing/nvdimm/watermark.h
new file mode 100644
index 0000000..ed05287
--- /dev/null
+++ b/tools/testing/nvdimm/watermark.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+#ifndef _TEST_NVDIMM_WATERMARK_H_
+#define _TEST_NVDIMM_WATERMARK_H_
+int pmem_test(void);
+int libnvdimm_test(void);
+int acpi_nfit_test(void);
+int device_dax_test(void);
+
+/*
+ * dummy routine for nfit_test to validate it is linking to the properly
+ * mocked module and not the standard one from the base tree.
+ */
+#define nfit_test_watermark(x)				\
+int x##_test(void)					\
+{							\
+	pr_debug("%s for nfit_test\n", KBUILD_MODNAME);	\
+	return 0;					\
+}							\
+EXPORT_SYMBOL(x##_test)
+#endif /* _TEST_NVDIMM_WATERMARK_H_ */
diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
index 1e09d77..cc15af2 100644
--- a/tools/testing/selftests/bpf/.gitignore
+++ b/tools/testing/selftests/bpf/.gitignore
@@ -8,5 +8,6 @@
 test_align
 test_dev_cgroup
 test_progs
+test_tcpbpf_user
 test_verifier_log
 feature
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index bf05bc5..566d6ad 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -27,7 +27,7 @@
 
 include ../lib.mk
 
-BPFOBJ := $(OUTPUT)/libbpf.a $(OUTPUT)/cgroup_helpers.c
+BPFOBJ := $(OUTPUT)/libbpf.a cgroup_helpers.c
 
 $(TEST_GEN_PROGS): $(BPFOBJ)
 
@@ -58,7 +58,7 @@
 $(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline
 $(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline
 
-%.o: %.c
+$(OUTPUT)/%.o: %.c
 	$(CLANG) $(CLANG_FLAGS) \
 		 -O2 -target bpf -emit-llvm -c $< -o - |      \
 	$(LLC) -march=bpf -mcpu=$(CPU) -filetype=obj -o $@
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 697bd83..c0f16e9 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -7780,6 +7780,20 @@ static struct bpf_test tests[] = {
 		.result = REJECT,
 	},
 	{
+		"XDP, using ifindex from netdev",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_0, 0),
+			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
+				    offsetof(struct xdp_md, ingress_ifindex)),
+			BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 1, 1),
+			BPF_MOV64_IMM(BPF_REG_0, 1),
+			BPF_EXIT_INSN(),
+		},
+		.result = ACCEPT,
+		.prog_type = BPF_PROG_TYPE_XDP,
+		.retval = 1,
+	},
+	{
 		"meta access, test1",
 		.insns = {
 			BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
diff --git a/tools/testing/selftests/membarrier/membarrier_test.c b/tools/testing/selftests/membarrier/membarrier_test.c
index 9e674d9..22bffd5 100644
--- a/tools/testing/selftests/membarrier/membarrier_test.c
+++ b/tools/testing/selftests/membarrier/membarrier_test.c
@@ -16,49 +16,210 @@ static int sys_membarrier(int cmd, int flags)
 static int test_membarrier_cmd_fail(void)
 {
 	int cmd = -1, flags = 0;
+	const char *test_name = "sys membarrier invalid command";
 
 	if (sys_membarrier(cmd, flags) != -1) {
 		ksft_exit_fail_msg(
-			"sys membarrier invalid command test: command = %d, flags = %d. Should fail, but passed\n",
-			cmd, flags);
+			"%s test: command = %d, flags = %d. Should fail, but passed\n",
+			test_name, cmd, flags);
+	}
+	if (errno != EINVAL) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
+			test_name, flags, EINVAL, strerror(EINVAL),
+			errno, strerror(errno));
 	}
 
 	ksft_test_result_pass(
-		"sys membarrier invalid command test: command = %d, flags = %d. Failed as expected\n",
-		cmd, flags);
+		"%s test: command = %d, flags = %d, errno = %d. Failed as expected\n",
+		test_name, cmd, flags, errno);
 	return 0;
 }
 
 static int test_membarrier_flags_fail(void)
 {
 	int cmd = MEMBARRIER_CMD_QUERY, flags = 1;
+	const char *test_name = "sys membarrier MEMBARRIER_CMD_QUERY invalid flags";
 
 	if (sys_membarrier(cmd, flags) != -1) {
 		ksft_exit_fail_msg(
-			"sys membarrier MEMBARRIER_CMD_QUERY invalid flags test: flags = %d. Should fail, but passed\n",
-			flags);
+			"%s test: flags = %d. Should fail, but passed\n",
+			test_name, flags);
+	}
+	if (errno != EINVAL) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
+			test_name, flags, EINVAL, strerror(EINVAL),
+			errno, strerror(errno));
 	}
 
 	ksft_test_result_pass(
-		"sys membarrier MEMBARRIER_CMD_QUERY invalid flags test: flags = %d. Failed as expected\n",
-		flags);
+		"%s test: flags = %d, errno = %d. Failed as expected\n",
+		test_name, flags, errno);
 	return 0;
 }
 
-static int test_membarrier_success(void)
+static int test_membarrier_global_success(void)
 {
-	int cmd = MEMBARRIER_CMD_SHARED, flags = 0;
-	const char *test_name = "sys membarrier MEMBARRIER_CMD_SHARED\n";
+	int cmd = MEMBARRIER_CMD_GLOBAL, flags = 0;
+	const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL";
 
 	if (sys_membarrier(cmd, flags) != 0) {
 		ksft_exit_fail_msg(
-			"sys membarrier MEMBARRIER_CMD_SHARED test: flags = %d\n",
-			flags);
+			"%s test: flags = %d, errno = %d\n",
+			test_name, flags, errno);
 	}
 
 	ksft_test_result_pass(
-		"sys membarrier MEMBARRIER_CMD_SHARED test: flags = %d\n",
-		flags);
+		"%s test: flags = %d\n", test_name, flags);
+	return 0;
+}
+
+static int test_membarrier_private_expedited_fail(void)
+{
+	int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
+	const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED not registered failure";
+
+	if (sys_membarrier(cmd, flags) != -1) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d. Should fail, but passed\n",
+			test_name, flags);
+	}
+	if (errno != EPERM) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
+			test_name, flags, EPERM, strerror(EPERM),
+			errno, strerror(errno));
+	}
+
+	ksft_test_result_pass(
+		"%s test: flags = %d, errno = %d\n",
+		test_name, flags, errno);
+	return 0;
+}
+
+static int test_membarrier_register_private_expedited_success(void)
+{
+	int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, flags = 0;
+	const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED";
+
+	if (sys_membarrier(cmd, flags) != 0) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d, errno = %d\n",
+			test_name, flags, errno);
+	}
+
+	ksft_test_result_pass(
+		"%s test: flags = %d\n",
+		test_name, flags);
+	return 0;
+}
+
+static int test_membarrier_private_expedited_success(void)
+{
+	int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
+	const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED";
+
+	if (sys_membarrier(cmd, flags) != 0) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d, errno = %d\n",
+			test_name, flags, errno);
+	}
+
+	ksft_test_result_pass(
+		"%s test: flags = %d\n",
+		test_name, flags);
+	return 0;
+}
+
+static int test_membarrier_private_expedited_sync_core_fail(void)
+{
+	int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;
+	const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE not registered failure";
+
+	if (sys_membarrier(cmd, flags) != -1) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d. Should fail, but passed\n",
+			test_name, flags);
+	}
+	if (errno != EPERM) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
+			test_name, flags, EPERM, strerror(EPERM),
+			errno, strerror(errno));
+	}
+
+	ksft_test_result_pass(
+		"%s test: flags = %d, errno = %d\n",
+		test_name, flags, errno);
+	return 0;
+}
+
+static int test_membarrier_register_private_expedited_sync_core_success(void)
+{
+	int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;
+	const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE";
+
+	if (sys_membarrier(cmd, flags) != 0) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d, errno = %d\n",
+			test_name, flags, errno);
+	}
+
+	ksft_test_result_pass(
+		"%s test: flags = %d\n",
+		test_name, flags);
+	return 0;
+}
+
+static int test_membarrier_private_expedited_sync_core_success(void)
+{
+	int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
+	const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE";
+
+	if (sys_membarrier(cmd, flags) != 0) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d, errno = %d\n",
+			test_name, flags, errno);
+	}
+
+	ksft_test_result_pass(
+		"%s test: flags = %d\n",
+		test_name, flags);
+	return 0;
+}
+
+static int test_membarrier_register_global_expedited_success(void)
+{
+	int cmd = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, flags = 0;
+	const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED";
+
+	if (sys_membarrier(cmd, flags) != 0) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d, errno = %d\n",
+			test_name, flags, errno);
+	}
+
+	ksft_test_result_pass(
+		"%s test: flags = %d\n",
+		test_name, flags);
+	return 0;
+}
+
+static int test_membarrier_global_expedited_success(void)
+{
+	int cmd = MEMBARRIER_CMD_GLOBAL_EXPEDITED, flags = 0;
+	const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL_EXPEDITED";
+
+	if (sys_membarrier(cmd, flags) != 0) {
+		ksft_exit_fail_msg(
+			"%s test: flags = %d, errno = %d\n",
+			test_name, flags, errno);
+	}
+
+	ksft_test_result_pass(
+		"%s test: flags = %d\n",
+		test_name, flags);
 	return 0;
 }
 
@@ -72,7 +233,45 @@ static int test_membarrier(void)
 	status = test_membarrier_flags_fail();
 	if (status)
 		return status;
-	status = test_membarrier_success();
+	status = test_membarrier_global_success();
+	if (status)
+		return status;
+	status = test_membarrier_private_expedited_fail();
+	if (status)
+		return status;
+	status = test_membarrier_register_private_expedited_success();
+	if (status)
+		return status;
+	status = test_membarrier_private_expedited_success();
+	if (status)
+		return status;
+	status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);
+	if (status < 0) {
+		ksft_test_result_fail("sys_membarrier() failed\n");
+		return status;
+	}
+	if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) {
+		status = test_membarrier_private_expedited_sync_core_fail();
+		if (status)
+			return status;
+		status = test_membarrier_register_private_expedited_sync_core_success();
+		if (status)
+			return status;
+		status = test_membarrier_private_expedited_sync_core_success();
+		if (status)
+			return status;
+	}
+	/*
+	 * It is valid to send a global membarrier from a non-registered
+	 * process.
+	 */
+	status = test_membarrier_global_expedited_success();
+	if (status)
+		return status;
+	status = test_membarrier_register_global_expedited_success();
+	if (status)
+		return status;
+	status = test_membarrier_global_expedited_success();
 	if (status)
 		return status;
 	return 0;
@@ -94,8 +293,10 @@ static int test_membarrier_query(void)
 		}
 		ksft_exit_fail_msg("sys_membarrier() failed\n");
 	}
-	if (!(ret & MEMBARRIER_CMD_SHARED))
+	if (!(ret & MEMBARRIER_CMD_GLOBAL)) {
+		ksft_test_result_fail("sys_membarrier() CMD_GLOBAL query failed\n");
 		ksft_exit_fail_msg("sys_membarrier is not supported.\n");
+	}
 
 	ksft_test_result_pass("sys_membarrier available\n");
 	return 0;
@@ -108,5 +309,5 @@ int main(int argc, char **argv)
 	test_membarrier_query();
 	test_membarrier();
 
-	ksft_exit_pass();
+	return ksft_exit_pass();
 }
diff --git a/tools/virtio/ringtest/ring.c b/tools/virtio/ringtest/ring.c
index 747c5dd..5a41404 100644
--- a/tools/virtio/ringtest/ring.c
+++ b/tools/virtio/ringtest/ring.c
@@ -84,12 +84,11 @@ void alloc_ring(void)
 		perror("Unable to allocate ring buffer.\n");
 		exit(3);
 	}
-	event = malloc(sizeof *event);
+	event = calloc(1, sizeof(*event));
 	if (!event) {
 		perror("Unable to allocate event buffer.\n");
 		exit(3);
 	}
-	memset(event, 0, sizeof *event);
 	guest.avail_idx = 0;
 	guest.kicked_avail_idx = -1;
 	guest.last_used_idx = 0;
@@ -102,12 +101,11 @@ void alloc_ring(void)
 		ring[i] = desc;
 	}
 	guest.num_free = ring_size;
-	data = malloc(ring_size * sizeof *data);
+	data = calloc(ring_size, sizeof(*data));
 	if (!data) {
 		perror("Unable to allocate data buffer.\n");
 		exit(3);
 	}
-	memset(data, 0, ring_size * sizeof *data);
 }
 
 /* guest side */
@@ -188,16 +186,18 @@ bool enable_call()
 
 void kick_available(void)
 {
+	bool need;
+
 	/* Flush in previous flags write */
 	/* Barrier C (for pairing) */
 	smp_mb();
-	if (!need_event(event->kick_index,
-			guest.avail_idx,
-			guest.kicked_avail_idx))
-		return;
+	need = need_event(event->kick_index,
+			   guest.avail_idx,
+			   guest.kicked_avail_idx);
 
 	guest.kicked_avail_idx = guest.avail_idx;
-	kick();
+	if (need)
+		kick();
 }
 
 /* host side */
@@ -253,14 +253,18 @@ bool use_buf(unsigned *lenp, void **bufp)
 
 void call_used(void)
 {
+	bool need;
+
 	/* Flush in previous flags write */
 	/* Barrier D (for pairing) */
 	smp_mb();
-	if (!need_event(event->call_index,
+
+	need = need_event(event->call_index,
 			host.used_idx,
-			host.called_used_idx))
-		return;
+			host.called_used_idx);
 
 	host.called_used_idx = host.used_idx;
-	call();
+
+	if (need)
+		call();
 }
diff --git a/tools/virtio/ringtest/virtio_ring_0_9.c b/tools/virtio/ringtest/virtio_ring_0_9.c
index bbc3043..5fd3fbc 100644
--- a/tools/virtio/ringtest/virtio_ring_0_9.c
+++ b/tools/virtio/ringtest/virtio_ring_0_9.c
@@ -225,16 +225,18 @@ bool enable_call()
 
 void kick_available(void)
 {
+	bool need;
+
 	/* Flush in previous flags write */
 	/* Barrier C (for pairing) */
 	smp_mb();
-	if (!vring_need_event(vring_avail_event(&ring),
-			      guest.avail_idx,
-			      guest.kicked_avail_idx))
-		return;
+	need = vring_need_event(vring_avail_event(&ring),
+				guest.avail_idx,
+				guest.kicked_avail_idx);
 
 	guest.kicked_avail_idx = guest.avail_idx;
-	kick();
+	if (need)
+		kick();
 }
 
 /* host side */
@@ -316,14 +318,16 @@ bool use_buf(unsigned *lenp, void **bufp)
 
 void call_used(void)
 {
+	bool need;
+
 	/* Flush in previous flags write */
 	/* Barrier D (for pairing) */
 	smp_mb();
-	if (!vring_need_event(vring_used_event(&ring),
-			      host.used_idx,
-			      host.called_used_idx))
-		return;
+	need = vring_need_event(vring_used_event(&ring),
+				host.used_idx,
+				host.called_used_idx);
 
 	host.called_used_idx = host.used_idx;
-	call();
+	if (need)
+		call();
 }
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 08464b2..7e3941f 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -31,6 +31,7 @@
 #include <linux/irqbypass.h>
 #include <trace/events/kvm.h>
 #include <kvm/arm_pmu.h>
+#include <kvm/arm_psci.h>
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
@@ -46,7 +47,6 @@
 #include <asm/kvm_mmu.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_coproc.h>
-#include <asm/kvm_psci.h>
 #include <asm/sections.h>
 
 #ifdef REQUIRES_VIRT
diff --git a/virt/kvm/arm/psci.c b/virt/kvm/arm/psci.c
index f1e363b..6919352 100644
--- a/virt/kvm/arm/psci.c
+++ b/virt/kvm/arm/psci.c
@@ -15,16 +15,16 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/arm-smccc.h>
 #include <linux/preempt.h>
 #include <linux/kvm_host.h>
 #include <linux/wait.h>
 
 #include <asm/cputype.h>
 #include <asm/kvm_emulate.h>
-#include <asm/kvm_psci.h>
 #include <asm/kvm_host.h>
 
-#include <uapi/linux/psci.h>
+#include <kvm/arm_psci.h>
 
 /*
  * This is an implementation of the Power State Coordination Interface
@@ -33,6 +33,38 @@
 
 #define AFFINITY_MASK(level)	~((0x1UL << ((level) * MPIDR_LEVEL_BITS)) - 1)
 
+static u32 smccc_get_function(struct kvm_vcpu *vcpu)
+{
+	return vcpu_get_reg(vcpu, 0);
+}
+
+static unsigned long smccc_get_arg1(struct kvm_vcpu *vcpu)
+{
+	return vcpu_get_reg(vcpu, 1);
+}
+
+static unsigned long smccc_get_arg2(struct kvm_vcpu *vcpu)
+{
+	return vcpu_get_reg(vcpu, 2);
+}
+
+static unsigned long smccc_get_arg3(struct kvm_vcpu *vcpu)
+{
+	return vcpu_get_reg(vcpu, 3);
+}
+
+static void smccc_set_retval(struct kvm_vcpu *vcpu,
+			     unsigned long a0,
+			     unsigned long a1,
+			     unsigned long a2,
+			     unsigned long a3)
+{
+	vcpu_set_reg(vcpu, 0, a0);
+	vcpu_set_reg(vcpu, 1, a1);
+	vcpu_set_reg(vcpu, 2, a2);
+	vcpu_set_reg(vcpu, 3, a3);
+}
+
 static unsigned long psci_affinity_mask(unsigned long affinity_level)
 {
 	if (affinity_level <= 3)
@@ -78,7 +110,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
 	unsigned long context_id;
 	phys_addr_t target_pc;
 
-	cpu_id = vcpu_get_reg(source_vcpu, 1) & MPIDR_HWID_BITMASK;
+	cpu_id = smccc_get_arg1(source_vcpu) & MPIDR_HWID_BITMASK;
 	if (vcpu_mode_is_32bit(source_vcpu))
 		cpu_id &= ~((u32) 0);
 
@@ -91,14 +123,14 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
 	if (!vcpu)
 		return PSCI_RET_INVALID_PARAMS;
 	if (!vcpu->arch.power_off) {
-		if (kvm_psci_version(source_vcpu) != KVM_ARM_PSCI_0_1)
+		if (kvm_psci_version(source_vcpu, kvm) != KVM_ARM_PSCI_0_1)
 			return PSCI_RET_ALREADY_ON;
 		else
 			return PSCI_RET_INVALID_PARAMS;
 	}
 
-	target_pc = vcpu_get_reg(source_vcpu, 2);
-	context_id = vcpu_get_reg(source_vcpu, 3);
+	target_pc = smccc_get_arg2(source_vcpu);
+	context_id = smccc_get_arg3(source_vcpu);
 
 	kvm_reset_vcpu(vcpu);
 
@@ -117,7 +149,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
 	 * NOTE: We always update r0 (or x0) because for PSCI v0.1
 	 * the general puspose registers are undefined upon CPU_ON.
 	 */
-	vcpu_set_reg(vcpu, 0, context_id);
+	smccc_set_retval(vcpu, context_id, 0, 0, 0);
 	vcpu->arch.power_off = false;
 	smp_mb();		/* Make sure the above is visible */
 
@@ -137,8 +169,8 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_vcpu *tmp;
 
-	target_affinity = vcpu_get_reg(vcpu, 1);
-	lowest_affinity_level = vcpu_get_reg(vcpu, 2);
+	target_affinity = smccc_get_arg1(vcpu);
+	lowest_affinity_level = smccc_get_arg2(vcpu);
 
 	/* Determine target affinity mask */
 	target_affinity_mask = psci_affinity_mask(lowest_affinity_level);
@@ -200,18 +232,10 @@ static void kvm_psci_system_reset(struct kvm_vcpu *vcpu)
 	kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET);
 }
 
-int kvm_psci_version(struct kvm_vcpu *vcpu)
-{
-	if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
-		return KVM_ARM_PSCI_0_2;
-
-	return KVM_ARM_PSCI_0_1;
-}
-
 static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
 {
 	struct kvm *kvm = vcpu->kvm;
-	unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
+	u32 psci_fn = smccc_get_function(vcpu);
 	unsigned long val;
 	int ret = 1;
 
@@ -221,7 +245,7 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
 		 * Bits[31:16] = Major Version = 0
 		 * Bits[15:0] = Minor Version = 2
 		 */
-		val = 2;
+		val = KVM_ARM_PSCI_0_2;
 		break;
 	case PSCI_0_2_FN_CPU_SUSPEND:
 	case PSCI_0_2_FN64_CPU_SUSPEND:
@@ -278,14 +302,56 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
 		break;
 	}
 
-	vcpu_set_reg(vcpu, 0, val);
+	smccc_set_retval(vcpu, val, 0, 0, 0);
+	return ret;
+}
+
+static int kvm_psci_1_0_call(struct kvm_vcpu *vcpu)
+{
+	u32 psci_fn = smccc_get_function(vcpu);
+	u32 feature;
+	unsigned long val;
+	int ret = 1;
+
+	switch(psci_fn) {
+	case PSCI_0_2_FN_PSCI_VERSION:
+		val = KVM_ARM_PSCI_1_0;
+		break;
+	case PSCI_1_0_FN_PSCI_FEATURES:
+		feature = smccc_get_arg1(vcpu);
+		switch(feature) {
+		case PSCI_0_2_FN_PSCI_VERSION:
+		case PSCI_0_2_FN_CPU_SUSPEND:
+		case PSCI_0_2_FN64_CPU_SUSPEND:
+		case PSCI_0_2_FN_CPU_OFF:
+		case PSCI_0_2_FN_CPU_ON:
+		case PSCI_0_2_FN64_CPU_ON:
+		case PSCI_0_2_FN_AFFINITY_INFO:
+		case PSCI_0_2_FN64_AFFINITY_INFO:
+		case PSCI_0_2_FN_MIGRATE_INFO_TYPE:
+		case PSCI_0_2_FN_SYSTEM_OFF:
+		case PSCI_0_2_FN_SYSTEM_RESET:
+		case PSCI_1_0_FN_PSCI_FEATURES:
+		case ARM_SMCCC_VERSION_FUNC_ID:
+			val = 0;
+			break;
+		default:
+			val = PSCI_RET_NOT_SUPPORTED;
+			break;
+		}
+		break;
+	default:
+		return kvm_psci_0_2_call(vcpu);
+	}
+
+	smccc_set_retval(vcpu, val, 0, 0, 0);
 	return ret;
 }
 
 static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
 {
 	struct kvm *kvm = vcpu->kvm;
-	unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
+	u32 psci_fn = smccc_get_function(vcpu);
 	unsigned long val;
 
 	switch (psci_fn) {
@@ -303,7 +369,7 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
 		break;
 	}
 
-	vcpu_set_reg(vcpu, 0, val);
+	smccc_set_retval(vcpu, val, 0, 0, 0);
 	return 1;
 }
 
@@ -321,9 +387,11 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
  * Errors:
  * -EINVAL: Unrecognized PSCI function
  */
-int kvm_psci_call(struct kvm_vcpu *vcpu)
+static int kvm_psci_call(struct kvm_vcpu *vcpu)
 {
-	switch (kvm_psci_version(vcpu)) {
+	switch (kvm_psci_version(vcpu, vcpu->kvm)) {
+	case KVM_ARM_PSCI_1_0:
+		return kvm_psci_1_0_call(vcpu);
 	case KVM_ARM_PSCI_0_2:
 		return kvm_psci_0_2_call(vcpu);
 	case KVM_ARM_PSCI_0_1:
@@ -332,3 +400,30 @@ int kvm_psci_call(struct kvm_vcpu *vcpu)
 		return -EINVAL;
 	};
 }
+
+int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
+{
+	u32 func_id = smccc_get_function(vcpu);
+	u32 val = PSCI_RET_NOT_SUPPORTED;
+	u32 feature;
+
+	switch (func_id) {
+	case ARM_SMCCC_VERSION_FUNC_ID:
+		val = ARM_SMCCC_VERSION_1_1;
+		break;
+	case ARM_SMCCC_ARCH_FEATURES_FUNC_ID:
+		feature = smccc_get_arg1(vcpu);
+		switch(feature) {
+		case ARM_SMCCC_ARCH_WORKAROUND_1:
+			if (kvm_arm_harden_branch_predictor())
+				val = 0;
+			break;
+		}
+		break;
+	default:
+		return kvm_psci_call(vcpu);
+	}
+
+	smccc_set_retval(vcpu, val, 0, 0, 0);
+	return 1;
+}